Skip to content

Commit 836a5e4

Browse files
authored
Merge pull request #7112 from BitGo/SC-3303
fix(sdk-core): fix TransactionType check
2 parents 4a8b2be + 85dd4d0 commit 836a5e4

File tree

5 files changed

+133
-107
lines changed

5 files changed

+133
-107
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
export const updatedStakingRequest = {
2+
id: '52676686-0d86-4ae6-8216-3465cb228615',
3+
stakingRequestId: '75de4133-6bea-4507-841a-b19f7672e1f7',
4+
delegationId: '27d726f9-3061-4f73-b40c-703962449b24',
5+
createdDate: '2025-03-25T13:43:07.942063Z',
6+
transactionType: 'delegate',
7+
status: 'READY',
8+
statusModifiedDate: '2025-03-25T13:43:07.942063Z',
9+
amount: '1260000000',
10+
buildParams: {
11+
type: 'AddPermissionlessValidator',
12+
stakingOptions: {
13+
nodeID: 'NodeID-Hj5HbEgZU51cQXKzg6NScAhcgqPmA4Bd4',
14+
blsPublicKey:
15+
'0xad9e9476b701edec88e53b1c314456053b3cf846a1192117872e41455f440c074d6ee89530d45e88f79ac0eda06f2887',
16+
blsSignature:
17+
'0xa94d6182edbd953516b262f17565a65d98f5741549cd70d2423abff750bb4b8d982d482376b189142ff8aa4705615fee14be6174610860e9c003aa4aeaa613b1732abf3cd0c9c42fa5856345644068c0d1f9fa1d9af32e20b14fca02983260bc',
18+
amount: '1260000000',
19+
delegationFeeRate: 2,
20+
durationSeconds: '86400',
21+
},
22+
},
23+
};
24+
25+
export const unsignedStakingTransaction = {
26+
txHex:
27+
'0x000000000019000000050000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000000df28e80000000000000000000000002000000033c21b92ba7e44eb0c7e1b9616fe5e759305285c74375e5b8deda05808c72b104500560061c38fc2bc07fd92fb1deaf9e6136ac4b60f6d16d79f1d1d700000002107e156978c655c09751b159cb1a7b5aaf0d72dda88ecff279865fd6db35ab38000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000001d9f9e400000000200000000000000011a6a5e9b720f9eb30ee25fc6bd5b9e82e0b4e37ae94394c6699792bf3fbe1e98000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000003b6d034000000002000000000000000100000000b7770f8cb7f68e67a2f555129f21bb85628a35720000000066105d10000000006611ae90000000004b1a130000000000000000000000000000000000000000000000000000000000000000000000001cad9e9476b701edec88e53b1c314456053b3cf846a1192117872e41455f440c074d6ee89530d45e88f79ac0eda06f2887a94d6182edbd953516b262f17565a65d98f5741549cd70d2423abff750bb4b8d982d482376b189142ff8aa4705615fee14be6174610860e9c003aa4aeaa613b1732abf3cd0c9c42fa5856345644068c0d1f9fa1d9af32e20b14fca02983260bc000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000004b1a1300000000000000000000000002000000033c21b92ba7e44eb0c7e1b9616fe5e759305285c74375e5b8deda05808c72b104500560061c38fc2bc07fd92fb1deaf9e6136ac4b60f6d16d79f1d1d70000000b000000000000000000000002000000033c21b92ba7e44eb0c7e1b9616fe5e759305285c74375e5b8deda05808c72b104500560061c38fc2bc07fd92fb1deaf9e6136ac4b60f6d16d79f1d1d70000000b000000000000000000000002000000033c21b92ba7e44eb0c7e1b9616fe5e759305285c74375e5b8deda05808c72b104500560061c38fc2bc07fd92fb1deaf9e6136ac4b60f6d16d79f1d1d700004e200000000200000009000000022d890d61be44a625929c5978869af170b9af025ff71fc319e6000fd6640a1da234801497ba23c58f80a6f025c92a0433accd1279457d9d9dc5643bdc340d831d01238536ee684fddedd8d9dbc6afe35dfa3c9634ef22a5060df998bdff84e27b962010e760c655a676576a5e503703ba7153fcc86862c96db06393e77c15cc28170000000009000000022d890d61be44a625929c5978869af170b9af025ff71fc319e6000fd6640a1da234801497ba23c58f80a6f025c92a0433accd1279457d9d9dc5643bdc340d831d01238536ee684fddedd8d9dbc6afe35dfa3c9634ef22a5060df998bdff84e27b962010e760c655a676576a5e503703ba7153fcc86862c96db06393e77c15cc2817003b5e792a',
28+
recipients: [
29+
{
30+
amount: '1260000000',
31+
address: 'NodeID-Hj5HbEgZU51cQXKzg6NScAhcgqPmA4Bd4',
32+
},
33+
],
34+
buildParams: {
35+
type: 'AddPermissionlessValidator',
36+
stakingOptions: {
37+
nodeID: 'NodeID-Hj5HbEgZU51cQXKzg6NScAhcgqPmA4Bd4',
38+
blsPublicKey:
39+
'0xad9e9476b701edec88e53b1c314456053b3cf846a1192117872e41455f440c074d6ee89530d45e88f79ac0eda06f2887',
40+
blsSignature:
41+
'0xa94d6182edbd953516b262f17565a65d98f5741549cd70d2423abff750bb4b8d982d482376b189142ff8aa4705615fee14be6174610860e9c003aa4aeaa613b1732abf3cd0c9c42fa5856345644068c0d1f9fa1d9af32e20b14fca02983260bc',
42+
amount: '1260000000',
43+
delegationFeeRate: 2,
44+
durationSeconds: '86400',
45+
},
46+
},
47+
stakingParams: {
48+
requestId: '75de4133-6bea-4507-841a-b19f7672e1f7',
49+
amount: '1260000000',
50+
coin: 'tavaxp',
51+
validator: 'NodeID-Hj5HbEgZU51cQXKzg6NScAhcgqPmA4Bd4',
52+
actionType: 'DELEGATE',
53+
},
54+
coin: 'tavaxp',
55+
};

modules/bitgo/test/v2/fixtures/staking/topethStakingFixtures.ts

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,3 @@
1-
export const newStakingRequest = {
2-
id: '75de4133-6bea-4507-841a-b19f7672e1f7',
3-
requestingUserId: '5cb525d7e1b1328103076788fd6a07f9',
4-
type: 'STAKE',
5-
enterpriseId: '61c0ff41174c4e0007ae78b2a0bea1ec',
6-
walletId: '674f61528414869237480e6997ea7954',
7-
walletType: 'hot',
8-
withdrawalAddress: '0x1d1a245741bd7d603747a23d30f4c91682a29926',
9-
coin: 'topeth:wct',
10-
status: 'NEW',
11-
statusModifiedDate: '2025-03-25T13:43:07.808717Z',
12-
createdDate: '2025-03-25T13:43:07.808708Z',
13-
delegations: [],
14-
transactions: [],
15-
totalStaked: '0',
16-
amount: '1000000000000000000',
17-
durationSeconds: '1209600',
18-
};
19-
20-
export const stakingReadyToSign = {
21-
id: '75de4133-6bea-4507-841a-b19f7672e1f7',
22-
requestingUserId: '5cb525d7e1b1328103076788fd6a07f9',
23-
type: 'STAKE',
24-
enterpriseId: '61c0ff41174c4e0007ae78b2a0bea1ec',
25-
walletId: '674f61528414869237480e6997ea7954',
26-
walletType: 'hot',
27-
withdrawalAddress: '0x1d1a245741bd7d603747a23d30f4c91682a29926',
28-
coin: 'topeth:wct',
29-
status: 'READY',
30-
statusModifiedDate: '2025-03-25T13:43:08.883527Z',
31-
createdDate: '2025-03-25T13:43:07.808708Z',
32-
delegations: [
33-
{
34-
id: '27d726f9-3061-4f73-b40c-703962449b24',
35-
delegationAddress: '0x1d1a245741bd7d603747a23d30f4c91682a29926',
36-
provider: 'Unknown',
37-
withdrawalAddress: '0x1d1a245741bd7d603747a23d30f4c91682a29926',
38-
delegated: '0',
39-
coin: 'topeth:wct',
40-
walletId: '674f61528414869237480e6997ea7954',
41-
properties: {
42-
type: 'WCT',
43-
},
44-
status: 'PENDING',
45-
rewards: '0',
46-
lockedRewards: '0',
47-
pendingUnstake: '0',
48-
pendingStake: '1000000000000000000',
49-
reserved: '0',
50-
pendingReserved: '0',
51-
apy: '0',
52-
unstakeable: false,
53-
pendingClaimRewards: '0',
54-
permissionAttributes: {
55-
staking: {
56-
enabled: false,
57-
disabledReason: 'Delegation is not active.',
58-
allowClientToUseOwnValidator: false,
59-
},
60-
unstaking: {
61-
enabled: false,
62-
disabledReason: 'Delegation is not active.',
63-
},
64-
},
65-
},
66-
],
67-
transactions: [
68-
{
69-
id: '52676686-0d86-4ae6-8216-3465cb228615',
70-
stakingRequestId: '75de4133-6bea-4507-841a-b19f7672e1f7',
71-
delegationId: '27d726f9-3061-4f73-b40c-703962449b24',
72-
createdDate: '2025-03-25T13:43:07.942063Z',
73-
transactionType: 'authorize',
74-
status: 'READY',
75-
statusModifiedDate: '2025-03-25T13:43:07.942063Z',
76-
amount: '1000000000000000000',
77-
},
78-
{
79-
id: 'ac56e1fc-3077-487f-a4f4-78061aa74300',
80-
stakingRequestId: '75de4133-6bea-4507-841a-b19f7672e1f7',
81-
delegationId: '27d726f9-3061-4f73-b40c-703962449b24',
82-
createdDate: '2025-03-25T13:43:07.942138Z',
83-
transactionType: 'delegate',
84-
status: 'WAITING',
85-
statusModifiedDate: '2025-03-25T13:43:07.942138Z',
86-
amount: '1000000000000000000',
87-
},
88-
],
89-
totalStaked: '0',
90-
amount: '1000000000000000000',
91-
durationSeconds: '1209600',
92-
fiatValue: 20.63776884676185,
93-
};
94-
951
export const updatedStakingRequest = {
962
id: '52676686-0d86-4ae6-8216-3465cb228615',
973
stakingRequestId: '75de4133-6bea-4507-841a-b19f7672e1f7',

modules/bitgo/test/v2/unit/staking/stakingWalletNonTSS.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as _ from 'lodash';
33
import nock = require('nock');
44
import fixtures from '../../fixtures/staking/stakingWallet';
55
import * as opethFixtures from '../../fixtures/staking/topethStakingFixtures';
6+
import * as avaxpStakingFixtures from '../../fixtures/staking/tavaxpStakingFixtures';
67

78
import {
89
Enterprise,
@@ -27,15 +28,18 @@ describe('non-TSS Staking Wallet', function () {
2728
let maticBaseCoin;
2829
let btcBaseCoin;
2930
let topethWctBaseCoin;
31+
let tavaxpBaseCoin;
3032
let enterprise;
3133
let ethWalletData: any;
3234
let btcWalletData: any;
3335
let topethWctStakingWalletData: WalletData;
36+
let tavaxpStakingWalletData: WalletData;
3437
let btcDescriptorWalletData: any;
3538
let ethStakingWallet: StakingWallet;
3639
let maticStakingWallet: StakingWallet;
3740
let btcStakingWallet: StakingWallet;
3841
let topethWctStakingWallet: StakingWallet;
42+
let tavaxpStakingWallet: StakingWallet;
3943

4044
before(function () {
4145
bitgo = TestBitGo.decorate(BitGo, { env: 'mock', microservicesUri } as any);
@@ -47,6 +51,7 @@ describe('non-TSS Staking Wallet', function () {
4751
btcBaseCoin = bitgo.coin('btc');
4852
btcBaseCoin.keychains();
4953
topethWctBaseCoin = bitgo.coin('topeth:wct');
54+
tavaxpBaseCoin = bitgo.coin('tavaxp');
5055

5156
enterprise = new Enterprise(bitgo, ethBaseCoin, {
5257
id: '5cf940949449412d00f53b3d92dbcaa3',
@@ -98,10 +103,29 @@ describe('non-TSS Staking Wallet', function () {
98103
enterprise: enterprise.id,
99104
};
100105

106+
tavaxpStakingWalletData = {
107+
approvalsRequired: 0,
108+
balance: 0,
109+
balanceString: '',
110+
coinSpecific: {} as WalletCoinSpecific,
111+
confirmedBalance: 0,
112+
confirmedBalanceString: '',
113+
keys: [],
114+
label: '',
115+
multisigType: 'onchain',
116+
pendingApprovals: [],
117+
spendableBalance: 0,
118+
spendableBalanceString: '',
119+
id: 'tavaxpStakingWalletId',
120+
coin: 'tavaxp',
121+
enterprise: enterprise.id,
122+
};
123+
101124
const ethWallet = new Wallet(bitgo, ethBaseCoin, ethWalletData);
102125
const maticWallet = new Wallet(bitgo, maticBaseCoin, maticWalletData);
103126
const btcWallet = new Wallet(bitgo, btcBaseCoin, btcWalletData);
104127
topethWctStakingWallet = new Wallet(bitgo, topethWctBaseCoin, topethWctStakingWalletData).toStakingWallet();
128+
tavaxpStakingWallet = new Wallet(bitgo, tavaxpBaseCoin, tavaxpStakingWalletData).toStakingWallet();
105129

106130
ethStakingWallet = ethWallet.toStakingWallet();
107131
maticStakingWallet = maticWallet.toStakingWallet();
@@ -434,4 +458,34 @@ describe('non-TSS Staking Wallet', function () {
434458
.should.be.rejectedWith(expectedErrorMessage);
435459
});
436460
});
461+
462+
describe('TAVAXP Staking', function () {
463+
it('should build and validate transaction', async function () {
464+
const unsignedTransaction: PrebuildTransactionResult = {
465+
walletId: tavaxpStakingWallet.walletId,
466+
...avaxpStakingFixtures.unsignedStakingTransaction,
467+
} as PrebuildTransactionResult;
468+
const stakingTransaction: StakingTransaction = avaxpStakingFixtures.updatedStakingRequest;
469+
470+
nock(microservicesUri)
471+
.get(
472+
`/api/staking/v1/${tavaxpStakingWallet.coin}/wallets/${tavaxpStakingWallet.walletId}/requests/${stakingTransaction.stakingRequestId}/transactions/${stakingTransaction.id}`
473+
)
474+
.query({ expandBuildParams: true })
475+
.reply(200, stakingTransaction);
476+
477+
nock(microservicesUri)
478+
.get(`/api/v2/tavaxp/wallet/${tavaxpStakingWallet.walletId}`)
479+
.reply(200, tavaxpStakingWalletData);
480+
481+
nock(microservicesUri)
482+
.post(`/api/v2/tavaxp/wallet/${tavaxpStakingWallet.walletId}/tx/build`)
483+
.reply(200, unsignedTransaction);
484+
485+
// tx validation happens before signing, so we can skip it
486+
sinon.stub(tavaxpStakingWallet, 'sign').resolves();
487+
488+
await tavaxpStakingWallet.buildAndSign({ walletPassphrase: 'passphrase' }, stakingTransaction);
489+
});
490+
});
437491
});

modules/sdk-core/src/account-lib/baseCoin/enum.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,24 @@ export enum TransactionType {
8787
FlushERC721,
8888
// Flush ERC1155 tokens from a forwarder address to base address
8989
FlushERC1155,
90+
91+
// trx
92+
FREEZE,
93+
VOTE,
94+
UNFREEZE,
95+
WITHDRAW_EXPIRE_UNFREEZE,
96+
CLAIM_REWARDS,
97+
98+
// cspr and stx
99+
stakingLock,
100+
// stx
101+
'self-stack',
102+
103+
// btc,
104+
staking,
105+
106+
// cspr
107+
stakingUnlock,
90108
}
91109

92110
/**

modules/sdk-core/src/bitgo/staking/stakingWallet.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { ITssUtils, RequestTracer, TssUtils } from '../utils';
2828
import assert from 'assert';
2929
import { transactionRecipientsMatch } from '../utils/transactionUtils';
3030
import debug from 'debug';
31+
import { TransactionType } from '../../account-lib';
3132

3233
export class StakingWallet implements IStakingWallet {
3334
private readonly bitgo: BitGoBase;
@@ -442,7 +443,11 @@ export class StakingWallet implements IStakingWallet {
442443
);
443444
}
444445

445-
if (buildParams?.type && (explainedTransaction as any).type !== buildParams.type) {
446+
if (
447+
buildParams?.type &&
448+
(explainedTransaction as any).type !== undefined &&
449+
TransactionType[buildParams.type] !== (explainedTransaction as any).type
450+
) {
446451
mismatchErrors.push(
447452
`Transaction type mismatch. Expected: '${buildParams.type}', Got: '${(explainedTransaction as any).type}'`
448453
);
@@ -458,18 +463,6 @@ export class StakingWallet implements IStakingWallet {
458463
}
459464
}
460465

461-
if (buildParams?.aptosCustomTransactionParams) {
462-
if (
463-
!isEqual((explainedTransaction as any).aptosCustomTransactionParams, buildParams.aptosCustomTransactionParams)
464-
) {
465-
mismatchErrors.push(
466-
`Aptos custom transaction parameters mismatch. Expected: ${JSON.stringify(
467-
buildParams.aptosCustomTransactionParams
468-
)}, Got: ${JSON.stringify((explainedTransaction as any).aptosCustomTransactionParams)}`
469-
);
470-
}
471-
}
472-
473466
if (mismatchErrors.length > 0) {
474467
const errorMessage = `Staking transaction validation failed before signing: ${mismatchErrors.join('; ')}`;
475468
debug(errorMessage);

0 commit comments

Comments
 (0)