Skip to content

Commit 02cd6e3

Browse files
Merge pull request #8840 from BitGo/SI-679
fix(sdk-coin-flrp): handle missing txParams.type in verifyTransaction…
2 parents 1257bb5 + d1dba5d commit 02cd6e3

3 files changed

Lines changed: 34 additions & 3 deletions

File tree

modules/sdk-coin-flrp/src/flrp.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ export class Flrp extends BaseCoin {
9696
// so the TransactionType enum lookup succeeds.
9797
const normalizedType = type === 'stake' ? 'AddPermissionlessDelegator' : type;
9898

99-
if (!normalizedType || (normalizedType !== 'ImportToC' && explainedTx.type !== TransactionType[normalizedType])) {
99+
// When type is provided, verify it matches the parsed transaction.
100+
// When type is not provided (MPC/TSS intent flow where buildParams are unavailable),
101+
// skip the type match check and rely on explainedTx.type from the parsed hex —
102+
// the transaction was built by wallet-platform and the hex is the source of truth.
103+
if (normalizedType && normalizedType !== 'ImportToC' && explainedTx.type !== TransactionType[normalizedType]) {
100104
throw new Error('Tx type does not match with expected txParams type');
101105
}
102106

@@ -126,8 +130,9 @@ export class Flrp extends BaseCoin {
126130
}
127131
break;
128132
case TransactionType.AddPermissionlessDelegator:
129-
// Validate delegation transaction against both txParams and explainedTx
130-
this.validateDelegationTx(params.txParams, explainedTx);
133+
if (params.txParams.stakingOptions) {
134+
this.validateDelegationTx(params.txParams, explainedTx);
135+
}
131136
break;
132137
default:
133138
throw new Error('Tx type is not supported yet');

modules/sdk-coin-flrp/test/resources/transactionData/multisigDelegationTx.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,12 @@ export const MULTISIG_ADDRESS_SORTING = {
9898
{ role: 'bitgo', originalIndex: 1, sortedIndex: 1 },
9999
],
100100
};
101+
102+
/**
103+
* MPC/TSS delegation transaction hex (single signer, built by wallet-platform via buildTransactionWithIntent).
104+
* From txRequest b5f89e8b-2273-4e29-80bd-60bd488e172f on Coston2 testnet.
105+
* This is the serializedTxHex that verifyTransaction receives during MPC signing,
106+
* where txParams has no type and no stakingOptions (only { recipients: [] }).
107+
*/
108+
export const MPC_DELEGATION_UNSIGNED_TX_HEX =
109+
'00000000001a0000007200000000000000000000000000000000000000000000000000000000000000000000000158734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd000000070000000253e0efe80000000000000000000000010000000184fa441f981fce7cd63189d5071802376ad6676e000000022ebd7484b5704be67db0344abd9d2223d5c7100795f68c7a6a4a77888dccb9820000000158734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd0000000500002d79883d20000000000100000000933f844e2d35c52963abd7912ec39faa71ed5994a52c584d9bf1f6bd480c976c0000000058734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd0000000500000002540be400000000010000000000000000664b4924a25af8be5f07052b2c2e582f7c10a654000000006a1192a4000000006a2407a400002d79883d200000000000000000000000000000000000000000000000000000000000000000000000000158734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd0000000700002d79883d20000000000000000000000000010000000184fa441f981fce7cd63189d5071802376ad6676e0000000b00000000000000000000000100000001243f65fbcc8458492e09d7693c3966a734c0a30f00000002000000090000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084fa441f981fce7cd63189d5071802376ad6676e000000090000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084fa441f981fce7cd63189d5071802376ad6676ee5e72aa5';

modules/sdk-coin-flrp/test/unit/flrp.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { IMPORT_IN_C } from '../resources/transactionData/importInC';
1212
import {
1313
MULTISIG_DELEGATION_FULLY_SIGNED_TX_HEX,
1414
MULTISIG_DELEGATION_PARAMS,
15+
MPC_DELEGATION_UNSIGNED_TX_HEX,
1516
} from '../resources/transactionData/multisigDelegationTx';
1617
import { HalfSignedAccountTransaction, TransactionType, MPCAlgorithm } from '@bitgo/sdk-core';
1718
import { secp256k1 } from '@flarenetwork/flarejs';
@@ -978,6 +979,22 @@ describe('Flrp test cases', function () {
978979
const isVerified = await basecoin.verifyTransaction({ txParams, txPrebuild });
979980
isVerified.should.equal(true);
980981
});
982+
983+
it('should verify delegation transaction when txParams.type is undefined (MPC intent flow)', async () => {
984+
// In the MPC/TSS staking flow, the txRequest is created by staking-service (not the UI).
985+
// The UI only has txRequestId — no buildParams. The SDK falls back to { recipients: [] }
986+
// with no type and no stakingOptions. verifyTransaction must still pass because the
987+
// parsed hex (explainedTx.type) is the source of truth built by wallet-platform.
988+
const txPrebuild = { txHex: MPC_DELEGATION_UNSIGNED_TX_HEX, txInfo: {} };
989+
const txParams = {
990+
recipients: [],
991+
// no type — simulates MPC staking flow where buildParams is unavailable
992+
// no stakingOptions — not passed through in the MPC intent flow
993+
};
994+
995+
const isVerified = await basecoin.verifyTransaction({ txParams, txPrebuild });
996+
isVerified.should.equal(true);
997+
});
981998
});
982999

9831000
describe('verifyTransaction with TSS wallet (Avalanche atomic)', () => {

0 commit comments

Comments
 (0)