From 69e06063032f72f49c3d8b1dc06c9acd67e250d0 Mon Sep 17 00:00:00 2001 From: Alla Gopi Karath Date: Tue, 18 Nov 2025 15:45:29 +0530 Subject: [PATCH] feat(sdk-coin-dot): add verify transaction function WIN-7596 TICKET: WIN-7596 --- modules/sdk-coin-dot/src/dot.ts | 35 +++++++++++++++- modules/sdk-coin-dot/test/unit/dot.ts | 59 ++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/modules/sdk-coin-dot/src/dot.ts b/modules/sdk-coin-dot/src/dot.ts index 3066f3fa26..3112215fde 100644 --- a/modules/sdk-coin-dot/src/dot.ts +++ b/modules/sdk-coin-dot/src/dot.ts @@ -651,12 +651,45 @@ export class Dot extends BaseCoin { } async verifyTransaction(params: VerifyTransactionOptions): Promise { - const { txParams } = params; + const { txPrebuild, txParams } = params; + if (!txParams) { + throw new Error('missing txParams'); + } + + if (!txPrebuild) { + throw new Error('missing txPrebuild'); + } + + if (!txPrebuild.txHex) { + throw new Error('missing txHex in txPrebuild'); + } + + if (!txParams.recipients || txParams.recipients.length === 0) { + throw new Error('missing recipients in txParams'); + } + + const factory = this.getBuilder(); + const txBuilder = factory.from(txPrebuild.txHex) as any; + if (Array.isArray(txParams.recipients) && txParams.recipients.length > 1) { throw new Error( `${this.getChain()} doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.` ); } + + // validate recipient is same as txBuilder._to + if (txParams.recipients[0].address !== txBuilder._to) { + throw new Error( + `Recipient address ${txParams.recipients[0].address} does not match transaction destination address ${txBuilder._to}` + ); + } + + // and amount is same as txBuilder._amount + if (txParams.recipients[0].amount !== txBuilder._amount) { + throw new Error( + `Recipient amount ${txParams.recipients[0].amount} does not match transaction amount ${txBuilder._amount}` + ); + } return true; } diff --git a/modules/sdk-coin-dot/test/unit/dot.ts b/modules/sdk-coin-dot/test/unit/dot.ts index 21a618e538..dbbbad51fc 100644 --- a/modules/sdk-coin-dot/test/unit/dot.ts +++ b/modules/sdk-coin-dot/test/unit/dot.ts @@ -664,12 +664,69 @@ describe('DOT:', function () { walletPassphrase: 'fakeWalletPassphrase', }; + const txPrebuild = { + txHex: + '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300', + }; + await basecoin - .verifyTransaction({ txParams }) + .verifyTransaction({ txPrebuild, txParams }) .should.be.rejectedWith( `tdot doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.` ); }); + + it('should reject a txPrebuild with more than invalid amount', async function () { + const wallet = new Wallet(bitgo, basecoin, {}); + const txParams = { + recipients: [{ amount: '20000000000', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }], + wallet: wallet, + walletPassphrase: 'fakeWalletPassphrase', + }; + const txPrebuild = { + txHex: + '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300', + }; + + await basecoin + .verifyTransaction({ txPrebuild, txParams }) + .should.be.rejectedWith(`Recipient amount 20000000000 does not match transaction amount 2000000000000`); + }); + + it('should reject a txPrebuild with more than invalid recipient', async function () { + const wallet = new Wallet(bitgo, basecoin, {}); + const txParams = { + recipients: [{ amount: '2000000000000', address: '5CZh773vKGwKFCUjGc31AwXCbf7TPkavduk2XoujJMjbBD' }], + wallet: wallet, + walletPassphrase: 'fakeWalletPassphrase', + }; + const txPrebuild = { + txHex: + '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300', + }; + + await basecoin + .verifyTransaction({ txPrebuild, txParams }) + .should.be.rejectedWith( + `Recipient address 5CZh773vKGwKFCUjGc31AwXCbf7TPkavduk2XoujJMjbBD does not match transaction destination address 5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD` + ); + }); + + it('should accept a txPrebuild with more than valid recipient and amount', async function () { + const wallet = new Wallet(bitgo, basecoin, {}); + const txParams = { + recipients: [{ amount: '2000000000000', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }], + wallet: wallet, + walletPassphrase: 'fakeWalletPassphrase', + }; + const txPrebuild = { + txHex: + '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300', + }; + + const result = await basecoin.verifyTransaction({ txPrebuild, txParams }); + assert.strictEqual(result, true); + }); }); describe('isWalletAddress', () => {