diff --git a/packages/connect/package.json b/packages/connect/package.json index b1613e60117..a2d36983fa1 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -72,7 +72,7 @@ "@babel/preset-typescript": "^7.24.7", "@ethereumjs/common": "^4.3.0", "@ethereumjs/tx": "^5.3.0", - "@fivebinaries/coin-selection": "2.2.1", + "@fivebinaries/coin-selection": "3.0.0-beta.0", "@trezor/blockchain-link": "workspace:*", "@trezor/blockchain-link-types": "workspace:*", "@trezor/connect-analytics": "workspace:*", diff --git a/packages/connect/src/api/cardano/api/cardanoComposeTransaction.ts b/packages/connect/src/api/cardano/api/cardanoComposeTransaction.ts index 886ae423d08..705b48a7a92 100644 --- a/packages/connect/src/api/cardano/api/cardanoComposeTransaction.ts +++ b/packages/connect/src/api/cardano/api/cardanoComposeTransaction.ts @@ -60,7 +60,7 @@ export default class CardanoComposeTransaction extends AbstractMethod< withdrawals, changeAddress.address, !!testnet, - { feeParams: feePerUnit ? { a: feePerUnit } : undefined }, + { feeParams: feePerUnit ? { a: feePerUnit } : undefined, debug: true }, // TMP: disable debug ); return { diff --git a/packages/connect/src/api/cardano/cardanoUtils.ts b/packages/connect/src/api/cardano/cardanoUtils.ts index 60b62331c0d..99827469e6d 100644 --- a/packages/connect/src/api/cardano/cardanoUtils.ts +++ b/packages/connect/src/api/cardano/cardanoUtils.ts @@ -47,7 +47,36 @@ export const prepareCertificates = (certs: CardanoCertificate[]) => { convertedCerts.push({ type: cert.type, }); - // TODO conway certificates not supported by coin-selection lib yet + break; + case PROTO.CardanoCertificateType.VOTE_DELEGATION: + if ( + cert.dRep?.type === PROTO.CardanoDRepType.ABSTAIN || + cert.dRep?.type === PROTO.CardanoDRepType.NO_CONFIDENCE + ) { + convertedCerts.push({ + type: cert.type, + dRep: { + type: cert.dRep!.type, + }, + }); + } else if (cert.dRep?.type === PROTO.CardanoDRepType.KEY_HASH) { + convertedCerts.push({ + type: cert.type, + dRep: { + type: cert.dRep!.type, + keyHash: cert.dRep.keyHash!, + }, + }); + } else if (cert.dRep?.type === PROTO.CardanoDRepType.SCRIPT_HASH) { + convertedCerts.push({ + type: cert.type, + dRep: { + type: cert.dRep!.type, + scriptHash: cert.dRep!.scriptHash!, + }, + }); + } + // TODO not all conway certificates not supported by coin-selection lib yet break; // no default } diff --git a/packages/suite/src/hooks/wallet/useCardanoStaking.ts b/packages/suite/src/hooks/wallet/useCardanoStaking.ts index 6c94c855fc8..9260bd7354d 100644 --- a/packages/suite/src/hooks/wallet/useCardanoStaking.ts +++ b/packages/suite/src/hooks/wallet/useCardanoStaking.ts @@ -8,6 +8,7 @@ import { getNetworkId, getUnusedChangeAddress, getDelegationCertificates, + getVotingCertificates, isPoolOverSaturated, getStakePoolForDelegation, getAddressParameters, @@ -125,6 +126,29 @@ export const useCardanoStaking = (): CardanoStaking => { ] : []; + // TODO: If no dRep has been selected for the account, display a modal prompting the user + // to make a selection before proceeding with the withdrawal. + if (action === 'withdrawal') { + // Add correct dRep type based on user choice + // User has either choice to delegate votes to Trezor dRep or abstain + + // Trezor Drep chosen + certificates.push( + ...getVotingCertificates(stakingPath, { + type: PROTO.CardanoDRepType.KEY_HASH, + // TODO: use trezor dRep hex fetched from /api/v0/drep (same logic as for CARDANO_STAKE_POOL_MAINNET_URL) + keyHash: 'dRep_hex', + }), + ); + + // User does not wish to participate in governance + // certificates.push( + // ...getVotingCertificates(stakingPath, { + // type: PROTO.CardanoDRepType.ABSTAIN, + // }), + // ); + } + const response = await trezorConnect.cardanoComposeTransaction({ account: { addresses: account.addresses, @@ -207,6 +231,7 @@ export const useCardanoStaking = (): CardanoStaking => { protocolMagic: getProtocolMagic(account.symbol), networkId: getNetworkId(account.symbol), derivationType: getDerivationType(account.accountType), + tagCborSets: true, ttl: txPlan.ttl?.toString(), ...(certificates.length > 0 ? { certificates } : {}), ...(withdrawals.length > 0 ? { withdrawals } : {}), diff --git a/suite-common/wallet-core/src/send/sendFormCardanoThunks.ts b/suite-common/wallet-core/src/send/sendFormCardanoThunks.ts index d8c386665f6..6193b2e0d39 100644 --- a/suite-common/wallet-core/src/send/sendFormCardanoThunks.ts +++ b/suite-common/wallet-core/src/send/sendFormCardanoThunks.ts @@ -167,6 +167,7 @@ export const signCardanoSendFormTransactionThunk = createThunk< inputs: precomposedTransaction.inputs, outputs: precomposedTransaction.outputs, unsignedTx: precomposedTransaction.unsignedTx, + tagCborSets: true, testnet: isTestnet(symbol), protocolMagic: getProtocolMagic(symbol), networkId: getNetworkId(symbol), diff --git a/suite-common/wallet-utils/src/cardanoUtils.ts b/suite-common/wallet-utils/src/cardanoUtils.ts index 1bc665441fb..045384d2f81 100644 --- a/suite-common/wallet-utils/src/cardanoUtils.ts +++ b/suite-common/wallet-utils/src/cardanoUtils.ts @@ -133,6 +133,26 @@ export const getDelegationCertificates = ( return result; }; +export const getVotingCertificates = ( + stakingPath: string, + dRep: { keyHash?: string; type: PROTO.CardanoDRepType }, +) => { + const result: CardanoCertificate[] = [ + { + type: PROTO.CardanoCertificateType.VOTE_DELEGATION, + path: stakingPath, + dRep: { + keyHash: dRep.type === PROTO.CardanoDRepType.KEY_HASH ? dRep.keyHash : undefined, + scriptHash: + dRep.type === PROTO.CardanoDRepType.SCRIPT_HASH ? dRep.keyHash : undefined, + type: dRep.type, + }, + }, + ]; + + return result; +}; + export const isPoolOverSaturated = (pool: StakePool, additionalStake?: string) => new BigNumber(pool.live_stake) .plus(additionalStake ?? '0') diff --git a/yarn.lock b/yarn.lock index 717d634f2c5..e635d491d85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2667,17 +2667,17 @@ __metadata: languageName: node linkType: hard -"@emurgo/cardano-serialization-lib-browser@npm:^11.5.0": - version: 11.5.0 - resolution: "@emurgo/cardano-serialization-lib-browser@npm:11.5.0" - checksum: 10/e4d74d20a59ebc20671363fa357c526c10f2f13c9f36fd34b2d269f1c6f3d637be62fe31ea89641cd90a1410aaf5f9613dfe7f3e616cff606ea8f63a7296ecb3 +"@emurgo/cardano-serialization-lib-browser@npm:^13.2.0": + version: 13.2.0 + resolution: "@emurgo/cardano-serialization-lib-browser@npm:13.2.0" + checksum: 10/f60f47b7df9e1e783302921d9f225696d09e01b124a75dd8672effae17acdd42779da66a068c923261aabead52ac7aae9426ef13c875f48b5ef7b9d629b8b993 languageName: node linkType: hard -"@emurgo/cardano-serialization-lib-nodejs@npm:11.5.0": - version: 11.5.0 - resolution: "@emurgo/cardano-serialization-lib-nodejs@npm:11.5.0" - checksum: 10/3fff8448001c6d70807ef8e1a80a663ef60381e55bfd26c0f1b644e096895da7298fb991ac86670d4c5aee2e3e417e44ac80ab59080f7af107d8fa89906f9075 +"@emurgo/cardano-serialization-lib-nodejs@npm:13.2.0": + version: 13.2.0 + resolution: "@emurgo/cardano-serialization-lib-nodejs@npm:13.2.0" + checksum: 10/b8483dd74ec902da607f0ee00259674ba1794784fafd322948043dd4dfdbddecc81f6546fc98c9a57810639f91110cf76be7755a138a3506af6233954cfe449e languageName: node linkType: hard @@ -4173,13 +4173,13 @@ __metadata: languageName: node linkType: hard -"@fivebinaries/coin-selection@npm:2.2.1": - version: 2.2.1 - resolution: "@fivebinaries/coin-selection@npm:2.2.1" +"@fivebinaries/coin-selection@npm:3.0.0-beta.0": + version: 3.0.0-beta.0 + resolution: "@fivebinaries/coin-selection@npm:3.0.0-beta.0" dependencies: - "@emurgo/cardano-serialization-lib-browser": "npm:^11.5.0" - "@emurgo/cardano-serialization-lib-nodejs": "npm:11.5.0" - checksum: 10/3b5a45c9cf978978f96b781a994faf3e09d3cfe88f4f337205385caa1ba11f117d67fc059f09674a2a8064ccdde66bed69a2cb1182686bf83cbb9bdb13365d47 + "@emurgo/cardano-serialization-lib-browser": "npm:^13.2.0" + "@emurgo/cardano-serialization-lib-nodejs": "npm:13.2.0" + checksum: 10/01da56a7d5577953ca0357ef45606b69099bdcc245e225b242535eda35e884cb9f9fb8f355576ae288c0521b8aadd2a7963b55a6c49b9c1c4e8a014569b39974 languageName: node linkType: hard @@ -11574,7 +11574,7 @@ __metadata: "@babel/preset-typescript": "npm:^7.24.7" "@ethereumjs/common": "npm:^4.3.0" "@ethereumjs/tx": "npm:^5.3.0" - "@fivebinaries/coin-selection": "npm:2.2.1" + "@fivebinaries/coin-selection": "npm:3.0.0-beta.0" "@trezor/blockchain-link": "workspace:*" "@trezor/blockchain-link-types": "workspace:*" "@trezor/connect-analytics": "workspace:*"