diff --git a/docs/packages/connect/methods/cardanoSignTransaction.md b/docs/packages/connect/methods/cardanoSignTransaction.md index ed129ad5f2b1..323bd040befd 100644 --- a/docs/packages/connect/methods/cardanoSignTransaction.md +++ b/docs/packages/connect/methods/cardanoSignTransaction.md @@ -36,6 +36,7 @@ const result = await TrezorConnect.cardanoSignTransaction(params); - `derivationType` — _optional_ `CardanoDerivationType` enum. Determines used derivation type. Default is set to ICARUS_TREZOR=2. - `includeNetworkId` — _optional_ `Boolean`. Determines whether `networkId` should be explicitly serialized into the transaction body. Default is `false`. - `chunkify` — _optional_ `boolean` determines if recipient address will be displayed in chunks of 4 characters. Default is set to `false` +- `tagCborSets` - _optional_ `boolean` determines if CBOR arrays intended to be sets will be encoded with tag 258. Default is set to `false` ### CardanoTxSigningMode diff --git a/packages/connect/e2e/__fixtures__/cardanoSignTransaction.ts b/packages/connect/e2e/__fixtures__/cardanoSignTransaction.ts index 20b0767674b2..2ec661732550 100644 --- a/packages/connect/e2e/__fixtures__/cardanoSignTransaction.ts +++ b/packages/connect/e2e/__fixtures__/cardanoSignTransaction.ts @@ -696,6 +696,7 @@ export default { protocolMagic: PROTOCOL_MAGICS.mainnet, networkId: NETWORK_IDS.mainnet, signingMode: CardanoTxSigningMode.ORDINARY_TRANSACTION, + tagCborSets: false, }, result: { hash: 'e200b2c91f3493a1f3b9cfc8b6c141f70181741025e53941e9d57d22b1470c5c', @@ -720,6 +721,42 @@ export default { legacyResults: [legacyResults.beforeConway], }, + { + description: 'signStakeRegistrationConwayWith258TaggedSets', + params: { + inputs: [SAMPLE_INPUTS.shelley_input], + outputs: [SAMPLE_OUTPUTS.simple_shelley_output], + fee: FEE, + ttl: TTL, + certificates: [SAMPLE_CERTIFICATES.stake_registration_conway], + protocolMagic: PROTOCOL_MAGICS.mainnet, + networkId: NETWORK_IDS.mainnet, + signingMode: CardanoTxSigningMode.ORDINARY_TRANSACTION, + tagCborSets: true, + }, + result: { + hash: '5e27f8fba938603411452a8cb373462fb64305539573b7a9edc9155be5cd6473', + witnesses: [ + { + type: 1, + pubKey: '5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1', + signature: + '13c136487d8048ab7bbb081a324aa6b999e0b3237f956503b5446a4c409ec1062091b82e9e5459dee7ab0ba67ed874692d788872c8bbdb5ad4a3975c465fea09', + chainCode: null, + }, + { + type: 1, + pubKey: 'bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e', + signature: + 'f0674db7194d8e04d7df416af8ad9dcf1b1203ca4b78f14c1e394d47418c8f7e95fd41a8f01c43eeeb39df6264359c865a41621fc1e6b540819b25c7c4df5803', + chainCode: null, + }, + ], + auxiliaryDataSupplement: undefined, + }, + legacyResults: [legacyResults.beforeConway], + }, + { description: 'signStakeRegistrationNoOutputs', params: { @@ -2533,6 +2570,56 @@ export default { legacyResults: [legacyResults.beforePlutus], }, + { + description: 'plutusWithRequiredSignersAndReferenceInputAnd258TaggedSets', + params: { + inputs: [SAMPLE_INPUTS.shelley_input], + outputs: [SAMPLE_OUTPUTS.simple_shelley_output], + fee: FEE, + ttl: TTL, + protocolMagic: PROTOCOL_MAGICS.mainnet, + networkId: NETWORK_IDS.mainnet, + signingMode: CardanoTxSigningMode.PLUTUS_TRANSACTION, + scriptDataHash: SCRIPT_DATA_HASH, + collateralInputs: [SAMPLE_INPUTS.shelley_input_2], + requiredSigners: [ + { keyPath: "m/1852'/1815'/0'/0/0" }, + { keyPath: "m/1854'/1815'/0'/0/0" }, + { keyHash: '3a7f09d3df4cf66a7399c2b05bfa234d5a29560c311fc5db4c490711' }, + ], + referenceInput: [SAMPLE_INPUTS.plutus_input], + tagCborSets: true, + }, + result: { + hash: 'eee852948723773f059bbbc9f4378473e339a62ec518ac3aeb8ecdf27abf8581', + witnesses: [ + { + type: 1, + pubKey: '5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1', + signature: + 'ccf25b4926d4ea953f9330196f881ec6974b3979a05fd679e846eb0fd90f5e5d64cdba51fad9354a50343a29c09dfda8177fd1717ca8d105c9d923a31071b909', + chainCode: null, + }, + { + type: 1, + pubKey: '36a8ef21d5b98fdf23a27325cf643deaac35e912c835e35037f23d1061ae5b16', + signature: + '39231ff0df125987c5a7583f307d74d3bdcb9702baafc8588aa16002d19d595725da64518603bb0617bfba851fe96f0cf75c19d75b0749443e09fdc8aebb4603', + chainCode: null, + }, + { + type: 1, + pubKey: 'b10be5c0d11ad8292bbe69e220ca0cfbe154610b3041a8e72f9d515c226ab3b1', + signature: + 'e78e5a21c07ed5f613d01d20f9684a3b807b30ca211f69a2a0391ab3137d3b1260c51bdf08079e213e2487f3b8c36d6b42d7d15733113cf725ca3f162f030001', + chainCode: null, + }, + ], + auxiliaryDataSupplement: undefined, + }, + legacyResults: [legacyResults.beforeConway], + }, + { description: 'plutusWithManyWitnesses', params: { diff --git a/packages/connect/src/api/cardano/api/cardanoSignTransaction.ts b/packages/connect/src/api/cardano/api/cardanoSignTransaction.ts index c7473916396b..1b68eb759cb3 100644 --- a/packages/connect/src/api/cardano/api/cardanoSignTransaction.ts +++ b/packages/connect/src/api/cardano/api/cardanoSignTransaction.ts @@ -51,6 +51,7 @@ const CardanoSignTransactionFeatures = Object.freeze({ Babbage: ['0', '2.5.2'], CIP36Registration: ['0', '2.5.3'], CIP36RegistrationExternalPaymentAddress: ['0', '2.5.4'], + Conway: ['0', '2.6.4'], }); export type CardanoSignTransactionParams = { @@ -76,6 +77,7 @@ export type CardanoSignTransactionParams = { additionalWitnessRequests: Path[]; derivationType: PROTO.CardanoDerivationType; includeNetworkId?: boolean; + tagCborSets?: boolean; unsignedTx?: { body: string; hash: string }; testnet?: boolean; chunkify?: boolean; @@ -230,6 +232,7 @@ export default class CardanoSignTransaction extends AbstractMethod< ? payload.derivationType : PROTO.CardanoDerivationType.ICARUS_TREZOR, includeNetworkId: payload.includeNetworkId, + tagCborSets: payload.tagCborSets, unsignedTx: 'unsignedTx' in payload ? payload.unsignedTx : undefined, testnet: 'testnet' in payload ? payload.testnet : undefined, chunkify: typeof payload.chunkify === 'boolean' ? payload.chunkify : false, @@ -263,6 +266,13 @@ export default class CardanoSignTransaction extends AbstractMethod< if (certificate.key_hash) { this._ensureFeatureIsSupported('KeyHashStakeCredential'); } + if ( + certificate.type === PROTO.CardanoCertificateType.STAKE_REGISTRATION_CONWAY || + certificate.type === PROTO.CardanoCertificateType.STAKE_DEREGISTRATION_CONWAY || + certificate.type === PROTO.CardanoCertificateType.VOTE_DELEGATION + ) { + this._ensureFeatureIsSupported('Conway'); + } }); params.outputsWithData.forEach(({ output }) => { @@ -292,6 +302,10 @@ export default class CardanoSignTransaction extends AbstractMethod< this._ensureFeatureIsSupported('NetworkIdInTxBody'); } + if (params.tagCborSets) { + this._ensureFeatureIsSupported('Conway'); + } + if (params.scriptDataHash) { this._ensureFeatureIsSupported('ScriptDataHash'); } @@ -371,6 +385,7 @@ export default class CardanoSignTransaction extends AbstractMethod< derivation_type: this.params.derivationType, include_network_id: this.params.includeNetworkId, chunkify: this.params.chunkify, + tag_cbor_sets: this.params.tagCborSets, }; // init diff --git a/packages/connect/src/types/api/__tests__/cardano.ts b/packages/connect/src/types/api/__tests__/cardano.ts index caf38add058c..ab59c6d05bea 100644 --- a/packages/connect/src/types/api/__tests__/cardano.ts +++ b/packages/connect/src/types/api/__tests__/cardano.ts @@ -401,6 +401,7 @@ export const cardanoSignTransaction = async (api: TrezorConnect) => { networkId: 0, signingMode: CardanoTxSigningMode.ORDINARY_TRANSACTION, includeNetworkId: false, + tagCborSets: false, }); if (sign.success) { diff --git a/packages/connect/src/types/api/cardano/index.ts b/packages/connect/src/types/api/cardano/index.ts index d9dd71a36db3..34b07c3f82b7 100644 --- a/packages/connect/src/types/api/cardano/index.ts +++ b/packages/connect/src/types/api/cardano/index.ts @@ -262,6 +262,7 @@ export const CardanoSignTransaction = Type.Object({ derivationType: Type.Optional(PROTO.EnumCardanoDerivationType), includeNetworkId: Type.Optional(Type.Boolean()), chunkify: Type.Optional(Type.Boolean()), + tagCborSets: Type.Optional(Type.Boolean()), }); export type CardanoSignTransactionExtended = Static; diff --git a/packages/protobuf/messages.json b/packages/protobuf/messages.json index 0b4e299b2dfc..803964032be2 100644 --- a/packages/protobuf/messages.json +++ b/packages/protobuf/messages.json @@ -2012,6 +2012,13 @@ "chunkify": { "type": "bool", "id": 22 + }, + "tag_cbor_sets": { + "type": "bool", + "id": 23, + "options": { + "default": false + } } } }, diff --git a/packages/protobuf/src/messages-schema.ts b/packages/protobuf/src/messages-schema.ts index 6dcef889dbee..e9b9570fc157 100644 --- a/packages/protobuf/src/messages-schema.ts +++ b/packages/protobuf/src/messages-schema.ts @@ -864,6 +864,7 @@ export const CardanoSignTxInit = Type.Object({ total_collateral: Type.Optional(Type.Uint()), reference_inputs_count: Type.Optional(Type.Number()), chunkify: Type.Optional(Type.Boolean()), + tag_cbor_sets: Type.Optional(Type.Boolean()), }); export type CardanoTxInput = Static; diff --git a/packages/protobuf/src/messages.ts b/packages/protobuf/src/messages.ts index 23fd1cd90a06..c6cab6e43faa 100644 --- a/packages/protobuf/src/messages.ts +++ b/packages/protobuf/src/messages.ts @@ -776,6 +776,7 @@ export type CardanoSignTxInit = { total_collateral?: UintType; reference_inputs_count?: number; chunkify?: boolean; + tag_cbor_sets?: boolean; }; // CardanoTxInput