From 89ef631f2ab5d3653af7476d6008e3eea1fd7280 Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Thu, 28 Nov 2024 17:15:49 +0800 Subject: [PATCH 1/2] feat: add ada sign tx hash struct and add unit tests --- .../CardanoSignTxHashRequest.test.ts | 53 +++++++++ .../src/CardanoSignTxHashRequest.ts | 107 ++++++++++++++++++ .../ur-registry-cardano/src/RegistryType.ts | 4 + packages/ur-registry-cardano/src/index.ts | 1 + 4 files changed, 165 insertions(+) create mode 100644 packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts create mode 100644 packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts diff --git a/packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts b/packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts new file mode 100644 index 0000000..f6df757 --- /dev/null +++ b/packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts @@ -0,0 +1,53 @@ +// @ts-nocheck +import { CryptoKeypath, PathComponent } from "../src"; +import * as uuid from "uuid"; +import { CardanoSignTxHashRequest } from "../src"; +describe("cardano-sign-tx-hash-request", () => { + it("test should generate cardano-sign-tx-hash-request", () => { + const txHash = + "52a1f5596f31358030f0d9d3a2db2b119b8f766386071684d26d0d37439c144e"; + + const signKeyPath1 = new CryptoKeypath( + [ + new PathComponent({ index: 1852, hardened: true }), + new PathComponent({ index: 1815, hardened: true }), + new PathComponent({ index: 0, hardened: true }), + new PathComponent({ index: 0, hardened: false }), + new PathComponent({ index: 0, hardened: false }), + ], + Buffer.from("1250b6bc", "hex") + ); + + const signKeyPath2 = new CryptoKeypath( + [ + new PathComponent({ index: 1852, hardened: true }), + new PathComponent({ index: 1815, hardened: true }), + new PathComponent({ index: 0, hardened: true }), + new PathComponent({ index: 2, hardened: false }), + new PathComponent({ index: 0, hardened: false }), + ], + Buffer.from("1250b6bc", "hex") + ); + + const requestId = uuid.stringify( + Buffer.from("52090a1c29394842a9adba0bc021a58b", "hex") + ); + + const cardanoSignTxHashRequest = + CardanoSignTxHashRequest.constructCardanoSignTxHashRequest( + txHash, + [signKeyPath1, signKeyPath2], + requestId, + "eternl" + ); + + const cborHex = cardanoSignTxHashRequest.toCBOR().toString("hex"); + expect(cborHex).toBe( + "a401d8255052090a1c29394842a9adba0bc021a58b027840353261316635353936663331333538303330663064396433613264623262313139623866373636333836303731363834643236643064333734333963313434650382d90130a2018a19073cf5190717f500f500f400f4021a1250b6bcd90130a2018a19073cf5190717f500f502f400f4021a1250b6bc0466657465726e6c" + ); + const ur = cardanoSignTxHashRequest.toUREncoder(1000).nextPart(); + expect(ur).toBe( + "ur:cardano-sign-tx-hash-request/oxadtpdagdgmasbkcedtesfdfwptpmrdbdrtclonluaoksfzeceyhsehiyececeseniyeoeheoecetdyeodyiydyieesieeohseyieideyidehehesidetiyemeneneoetendyemeheneteeieeyeniedyieeoemeeeoesiaeheeeeihaxlftaaddyoeadlecfatfnykcfatchykaeykaewkaewkaocybggdrprftaaddyoeadlecfatfnykcfatchykaeykaowkaewkaocybggdrprfaaiyihjyihjpjtjzamaxzmam" + ); + }); +}); diff --git a/packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts b/packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts new file mode 100644 index 0000000..7d70fc0 --- /dev/null +++ b/packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts @@ -0,0 +1,107 @@ +import { + extend, + DataItem, + RegistryItem, + DataItemMap, + CryptoKeypath, +} from "@keystonehq/bc-ur-registry"; +import { ExtendedRegistryTypes } from "./RegistryType"; +import * as uuid from "uuid"; + +const { decodeToDataItem, RegistryTypes } = extend; + +enum Keys { + requestId = 1, + txHash, + paths, + origin, +} + +type CardanoSignTxHashRequestProps = { + requestId?: Buffer; + txHash: string; + paths: CryptoKeypath[]; + origin?: string; +}; + +export class CardanoSignTxHashRequest extends RegistryItem { + private requestId?: Buffer; + private txHash: string; + private paths: CryptoKeypath[]; + private origin?: string; + + getRegistryType = () => ExtendedRegistryTypes.CARDANO_SIGN_TX_HASH_REQUEST; + + constructor(args: CardanoSignTxHashRequestProps) { + super(); + this.requestId = args.requestId; + this.txHash = args.txHash; + this.paths = args.paths; + this.origin = args.origin; + } + + public getRequestId = () => this.requestId; + public getTxHash = () => this.txHash; + public getPaths = () => this.paths; + public getOrigin = () => this.origin; + + public toDataItem = () => { + const map: DataItemMap = {}; + if (this.requestId) { + map[Keys.requestId] = new DataItem( + this.requestId, + RegistryTypes.UUID.getTag() + ); + } + + map[Keys.txHash] = this.txHash; + map[Keys.paths] = this.paths.map((path) => { + const res = path.toDataItem(); + res.setTag(path.getRegistryType().getTag()); + return res; + }); + + if (this.origin) { + map[Keys.origin] = this.origin; + } + return new DataItem(map); + }; + + public static fromDataItem = (dataItem: DataItem) => { + const map = dataItem.getData(); + const txHash = map[Keys.txHash]; + const paths = map[Keys.paths]; + const requestId = map[Keys.requestId] + ? map[Keys.requestId].getData() + : undefined; + const origin = map[Keys.origin] ? map[Keys.origin] : undefined; + + return new CardanoSignTxHashRequest({ + requestId, + txHash, + paths, + origin, + }); + }; + + public static fromCBOR = (_cborPayload: Buffer) => { + const dataItem = decodeToDataItem(_cborPayload); + return CardanoSignTxHashRequest.fromDataItem(dataItem); + }; + + public static constructCardanoSignTxHashRequest( + txHash: string, + paths: CryptoKeypath[], + uuidString?: string, + origin?: string + ) { + return new CardanoSignTxHashRequest({ + requestId: uuidString + ? Buffer.from(uuid.parse(uuidString) as Uint8Array) + : undefined, + txHash, + paths, + origin: origin || undefined, + }); + } +} diff --git a/packages/ur-registry-cardano/src/RegistryType.ts b/packages/ur-registry-cardano/src/RegistryType.ts index c966d24..5a0dcea 100644 --- a/packages/ur-registry-cardano/src/RegistryType.ts +++ b/packages/ur-registry-cardano/src/RegistryType.ts @@ -30,4 +30,8 @@ export const ExtendedRegistryTypes = { "cardano-sign-cip8-data-signature", 2211 ), + CARDANO_SIGN_TX_HASH_REQUEST: new RegistryType( + "cardano-sign-tx-hash-request", + 2212 + ), }; diff --git a/packages/ur-registry-cardano/src/index.ts b/packages/ur-registry-cardano/src/index.ts index 593ad91..6577daf 100644 --- a/packages/ur-registry-cardano/src/index.ts +++ b/packages/ur-registry-cardano/src/index.ts @@ -23,3 +23,4 @@ export { CardanoCatalystSignature } from "./CardanoCatalystSignature"; export { CardanoSignCip8DataRequest } from "./CardanoSignMessageCip8DataRequest"; export { CardanoSignCip8DataSignature } from "./CardanoSignMessageCip8DataSignature"; export { MessageAddressFieldType } from "./CardanoSignMessageCip8DataRequest"; +export { CardanoSignTxHashRequest } from "./CardanoSignTxHashRequest"; From acba4ecacccb190949e4ab7ca48a70d76ee0b9fd Mon Sep 17 00:00:00 2001 From: ZhenQian Date: Tue, 3 Dec 2024 15:49:04 +0800 Subject: [PATCH 2/2] fix: update cardano sign tx hash struct type --- .../__tests__/CardanoSignTxHashRequest.test.ts | 10 +++++++--- .../src/CardanoSignTxHashRequest.ts | 13 ++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts b/packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts index f6df757..5cf79de 100644 --- a/packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts +++ b/packages/ur-registry-cardano/__tests__/CardanoSignTxHashRequest.test.ts @@ -32,22 +32,26 @@ describe("cardano-sign-tx-hash-request", () => { const requestId = uuid.stringify( Buffer.from("52090a1c29394842a9adba0bc021a58b", "hex") ); - + const addressList = [ + "addr1qy8ac7qqy0vtulyl7wntmsxc6wex80gvcyjy33qffrhm7sh927ysx5sftuw0dlft05dz3c7revpf7jx0xnlcjz3g69mq4afdhv", + "addr1qyz85693g4fr8c55mfyxhae8j2u04pydxrgqr73vmwpx3azv4dgkyrgylj5yl2m0jlpdpeswyyzjs0vhwvnl6xg9f7ssrxkz90", + ]; const cardanoSignTxHashRequest = CardanoSignTxHashRequest.constructCardanoSignTxHashRequest( txHash, [signKeyPath1, signKeyPath2], + addressList, requestId, "eternl" ); const cborHex = cardanoSignTxHashRequest.toCBOR().toString("hex"); expect(cborHex).toBe( - "a401d8255052090a1c29394842a9adba0bc021a58b027840353261316635353936663331333538303330663064396433613264623262313139623866373636333836303731363834643236643064333734333963313434650382d90130a2018a19073cf5190717f500f500f400f4021a1250b6bcd90130a2018a19073cf5190717f500f502f400f4021a1250b6bc0466657465726e6c" + "a501d8255052090a1c29394842a9adba0bc021a58b027840353261316635353936663331333538303330663064396433613264623262313139623866373636333836303731363834643236643064333734333963313434650382d90130a2018a19073cf5190717f500f500f400f4021a1250b6bcd90130a2018a19073cf5190717f500f502f400f4021a1250b6bc0466657465726e6c058278676164647231717938616337717179307674756c796c37776e746d737863367765783830677663796a79333371666672686d37736839323779737835736674757730646c66743035647a3363377265767066376a7830786e6c636a7a336736396d713461666468767867616464723171797a383536393367346672386335356d667978686165386a3275303470796478726771723733766d77707833617a763464676b797267796c6a35796c326d306a6c70647065737779797a6a7330766877766e6c367867396637737372786b7a3930" ); const ur = cardanoSignTxHashRequest.toUREncoder(1000).nextPart(); expect(ur).toBe( - "ur:cardano-sign-tx-hash-request/oxadtpdagdgmasbkcedtesfdfwptpmrdbdrtclonluaoksfzeceyhsehiyececeseniyeoeheoecetdyeodyiydyieesieeohseyieideyidehehesidetiyemeneneoetendyemeheneteeieeyeniedyieeoemeeeoesiaeheeeeihaxlftaaddyoeadlecfatfnykcfatchykaeykaewkaewkaocybggdrprftaaddyoeadlecfatfnykcfatchykaeykaowkaewkaocybggdrprfaaiyihjyihjpjtjzamaxzmam" + "ur:cardano-sign-tx-hash-request/onadtpdagdgmasbkcedtesfdfwptpmrdbdrtclonluaoksfzeceyhsehiyececeseniyeoeheoecetdyeodyiydyieesieeohseyieideyidehehesidetiyemeneneoetendyemeheneteeieeyeniedyieeoemeeeoesiaeheeeeihaxlftaaddyoeadlecfatfnykcfatchykaeykaewkaewkaocybggdrprftaaddyoeadlecfatfnykcfatchykaeykaowkaewkaocybggdrprfaaiyihjyihjpjtjzahlfksiohsieiejpehjskkethsiaemjsjskkdykojykpjzkkjzemktjtjyjnjkksiaenktihksetdyiokoiakkimkkeoeojsiyiyjpisjnemjkiseseyemkkjkksecjkiyjykpktdyiejziyjydyeciekneoiaemjpihkojoiyemimksdyksjtjziaimkneoioenesjnjseehsiyieiskoksiohsieiejpehjskkkneteceneseoioeeiyjpetiaececjniykkksishsihetimeykpdyeejokkieksjpiojsjpemeokojnktjokseohsknkoeeieiojekkjpiokkjzimeckkjzeyjndyimjzjoiejoihjkktkkkkknimjkdykoisktkojtjzenksioesiyemjkjkjpksjeknesdyolcxsges" ); }); }); diff --git a/packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts b/packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts index 7d70fc0..2f8c0e7 100644 --- a/packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts +++ b/packages/ur-registry-cardano/src/CardanoSignTxHashRequest.ts @@ -15,6 +15,7 @@ enum Keys { txHash, paths, origin, + address_list, } type CardanoSignTxHashRequestProps = { @@ -22,6 +23,7 @@ type CardanoSignTxHashRequestProps = { txHash: string; paths: CryptoKeypath[]; origin?: string; + addressList: string[]; }; export class CardanoSignTxHashRequest extends RegistryItem { @@ -29,7 +31,7 @@ export class CardanoSignTxHashRequest extends RegistryItem { private txHash: string; private paths: CryptoKeypath[]; private origin?: string; - + private addressList: string[]; getRegistryType = () => ExtendedRegistryTypes.CARDANO_SIGN_TX_HASH_REQUEST; constructor(args: CardanoSignTxHashRequestProps) { @@ -38,13 +40,14 @@ export class CardanoSignTxHashRequest extends RegistryItem { this.txHash = args.txHash; this.paths = args.paths; this.origin = args.origin; + this.addressList = args.addressList; } public getRequestId = () => this.requestId; public getTxHash = () => this.txHash; public getPaths = () => this.paths; public getOrigin = () => this.origin; - + public getAddressList = () => this.addressList; public toDataItem = () => { const map: DataItemMap = {}; if (this.requestId) { @@ -64,6 +67,7 @@ export class CardanoSignTxHashRequest extends RegistryItem { if (this.origin) { map[Keys.origin] = this.origin; } + map[Keys.address_list] = this.addressList; return new DataItem(map); }; @@ -75,12 +79,13 @@ export class CardanoSignTxHashRequest extends RegistryItem { ? map[Keys.requestId].getData() : undefined; const origin = map[Keys.origin] ? map[Keys.origin] : undefined; - + const addressList = map[Keys.address_list] ? map[Keys.address_list] : []; return new CardanoSignTxHashRequest({ requestId, txHash, paths, origin, + addressList, }); }; @@ -92,6 +97,7 @@ export class CardanoSignTxHashRequest extends RegistryItem { public static constructCardanoSignTxHashRequest( txHash: string, paths: CryptoKeypath[], + addressList: string[], uuidString?: string, origin?: string ) { @@ -102,6 +108,7 @@ export class CardanoSignTxHashRequest extends RegistryItem { txHash, paths, origin: origin || undefined, + addressList, }); } }