Skip to content

Commit abb73a8

Browse files
authored
Merge pull request #8720 from BitGo/WCI-156/stitch-signrequestbase-signtransactiontss-v2
fix(sdk-core): route EdDSA MPCv2 hot wallets to full apiVersion
2 parents 36d81ee + 7bf0b12 commit abb73a8

4 files changed

Lines changed: 96 additions & 4 deletions

File tree

modules/bitgo/test/v2/unit/internal/tssUtils/eddsa.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
common,
1616
createSharedDataProof,
1717
Ed25519BIP32,
18+
EDDSAUtils,
1819
Eddsa,
1920
EncryptedSignerShareType,
2021
ExchangeCommitmentResponse,
@@ -1130,11 +1131,24 @@ describe('TSS Utils:', async function () {
11301131
coldWalletTssUtils.supportedTxRequestVersions().should.deepEqual(['full']);
11311132
});
11321133
it('should return full and lite for hot wallets', async function () {
1133-
const hotWallet = new Wallet(bitgo, baseCoin, { multisigType: 'tss', type: 'hot' });
1134+
const hotWallet = new Wallet(bitgo, baseCoin, {
1135+
multisigType: 'tss',
1136+
multisigTypeVersion: undefined,
1137+
type: 'hot',
1138+
});
11341139
const hotTssUtils = new TssUtils(bitgo, baseCoin, hotWallet);
11351140
const supportedTxRequestVersions = hotTssUtils.supportedTxRequestVersions();
11361141
supportedTxRequestVersions.should.deepEqual(['lite', 'full']);
11371142
});
1143+
it('should return only full for hot MPCv2 wallets', function () {
1144+
const hotMPCv2Wallet = new Wallet(bitgo, baseCoin, {
1145+
multisigType: 'tss',
1146+
multisigTypeVersion: 'MPCv2',
1147+
type: 'hot',
1148+
});
1149+
const mpcv2TssUtils = new EDDSAUtils.EddsaMPCv2Utils(bitgo, baseCoin, hotMPCv2Wallet);
1150+
mpcv2TssUtils.supportedTxRequestVersions().should.deepEqual(['full']);
1151+
});
11381152
it('should return empty for trading wallets', function () {
11391153
const tradingWallets = new Wallet(bitgo, baseCoin, { multisigType: 'tss', type: 'trading' });
11401154
const tradingWalletTssUtils = new TssUtils(bitgo, baseCoin, tradingWallets);

modules/sdk-core/src/bitgo/utils/tss/baseTSSUtils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,9 @@ export default class BaseTssUtils<KeyShare> extends MpcUtils implements ITssUtil
632632
} else if (this._wallet.baseCoin.getMPCAlgorithm() === 'ecdsa') {
633633
return ['full'];
634634
} else if (this._wallet.baseCoin.getMPCAlgorithm() === 'eddsa' && this._wallet.type() === 'hot') {
635+
if (this._wallet.multisigTypeVersion() === 'MPCv2') {
636+
return ['full'];
637+
}
635638
return ['lite', 'full'];
636639
} else {
637640
return ['full'];

modules/sdk-core/src/bitgo/utils/txRequest.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ export function validateTxRequestApiVersion(wallet: IWallet, requestedApiVersion
77
return;
88
}
99
if (wallet.baseCoin.getMPCAlgorithm() === 'ecdsa') {
10-
// ecdsa wallets can only use full, even if they are hot wallets
1110
assert(requestedApiVersion === 'full', 'For ECDSA tss wallets, parameter `apiVersion` must be `full`.');
11+
} else if (wallet.multisigTypeVersion() === 'MPCv2') {
12+
assert(requestedApiVersion === 'full', 'For EdDSA MPCv2 tss wallets, parameter `apiVersion` must be `full`.');
1213
} else if (wallet.type() !== 'hot') {
1314
// all other cases should use full!
1415
assert(
@@ -30,10 +31,10 @@ export function getTxRequestApiVersion(wallet: IWallet, requestedApiVersion?: Ap
3031
validateTxRequestApiVersion(wallet, requestedApiVersion);
3132
return requestedApiVersion;
3233
}
33-
if (wallet.baseCoin.getMPCAlgorithm() === 'ecdsa') {
34+
if (wallet.baseCoin.getMPCAlgorithm() === 'ecdsa' || wallet.multisigTypeVersion() === 'MPCv2') {
3435
return 'full';
3536
} else if (wallet.type() === 'hot') {
36-
// default to lite for hot eddsa tss wallets
37+
// default to lite for hot eddsa tss wallets (v1 only)
3738
return 'lite';
3839
} else {
3940
// default to full for all other wallet types

modules/sdk-core/test/unit/bitgo/utils/txRequest.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ describe('txRequest utils', () => {
1010
baseCoin: { getMPCAlgorithm: () => 'ecdsa' },
1111
type: () => 'hot',
1212
multisigType: () => 'tss',
13+
multisigTypeVersion: () => undefined,
1314
} as any as IWallet,
1415
requestedApiVersion: 'lite',
1516
expectedApiVersion: '',
@@ -20,6 +21,7 @@ describe('txRequest utils', () => {
2021
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
2122
type: () => 'cold',
2223
multisigType: () => 'tss',
24+
multisigTypeVersion: () => undefined,
2325
} as any as IWallet,
2426
requestedApiVersion: 'lite',
2527
expectedApiVersion: '',
@@ -30,17 +32,41 @@ describe('txRequest utils', () => {
3032
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
3133
type: () => 'hot',
3234
multisigType: () => 'tss',
35+
multisigTypeVersion: () => undefined,
3336
} as any as IWallet,
3437
requestedApiVersion: undefined,
3538
expectedApiVersion: 'lite',
3639
expectedErrorMessage: '',
3740
},
41+
{
42+
wallet: {
43+
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
44+
type: () => 'hot',
45+
multisigType: () => 'tss',
46+
multisigTypeVersion: () => 'MPCv2',
47+
} as any as IWallet,
48+
requestedApiVersion: 'lite' as ApiVersion,
49+
expectedApiVersion: '',
50+
expectedErrorMessage: 'For EdDSA MPCv2 tss wallets, parameter `apiVersion` must be `full`.',
51+
},
52+
{
53+
wallet: {
54+
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
55+
type: () => 'hot',
56+
multisigType: () => 'tss',
57+
multisigTypeVersion: () => 'MPCv2',
58+
} as any as IWallet,
59+
requestedApiVersion: undefined,
60+
expectedApiVersion: 'full',
61+
expectedErrorMessage: '',
62+
},
3863
...['hot', 'cold', 'custodial', 'backing'].map((walletType) => {
3964
return {
4065
wallet: {
4166
baseCoin: { getMPCAlgorithm: () => 'ecdsa' },
4267
type: () => walletType,
4368
multisigType: () => 'tss',
69+
multisigTypeVersion: () => undefined,
4470
} as any as IWallet,
4571
requestedApiVersion: 'full',
4672
expectedApiVersion: 'full',
@@ -54,6 +80,7 @@ describe('txRequest utils', () => {
5480
baseCoin: { getMPCAlgorithm: () => 'ecdsa' },
5581
type: () => walletType,
5682
multisigType: () => 'tss',
83+
multisigTypeVersion: () => undefined,
5784
} as any as IWallet,
5885
requestedApiVersion: undefined,
5986
expectedApiVersion: 'full',
@@ -67,6 +94,7 @@ describe('txRequest utils', () => {
6794
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
6895
type: () => walletType,
6996
multisigType: () => 'tss',
97+
multisigTypeVersion: () => undefined,
7098
} as any as IWallet,
7199
requestedApiVersion: 'full',
72100
expectedApiVersion: 'full',
@@ -80,13 +108,59 @@ describe('txRequest utils', () => {
80108
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
81109
type: () => walletType,
82110
multisigType: () => 'tss',
111+
multisigTypeVersion: () => undefined,
83112
} as any as IWallet,
84113
requestedApiVersion: undefined,
85114
expectedApiVersion: 'full',
86115
expectedErrorMessage: '',
87116
shouldThrow: false,
88117
};
89118
}),
119+
// EdDSA MPCv2: all wallet types + 'full' explicitly → returns 'full'
120+
...['hot', 'cold', 'custodial', 'backing'].map((walletType) => {
121+
return {
122+
wallet: {
123+
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
124+
type: () => walletType,
125+
multisigType: () => 'tss',
126+
multisigTypeVersion: () => 'MPCv2',
127+
} as any as IWallet,
128+
requestedApiVersion: 'full' as ApiVersion,
129+
expectedApiVersion: 'full',
130+
expectedErrorMessage: '',
131+
shouldThrow: false,
132+
};
133+
}),
134+
// EdDSA MPCv2: non-hot wallet types + undefined → defaults to 'full'
135+
...['cold', 'custodial', 'backing'].map((walletType) => {
136+
return {
137+
wallet: {
138+
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
139+
type: () => walletType,
140+
multisigType: () => 'tss',
141+
multisigTypeVersion: () => 'MPCv2',
142+
} as any as IWallet,
143+
requestedApiVersion: undefined,
144+
expectedApiVersion: 'full',
145+
expectedErrorMessage: '',
146+
shouldThrow: false,
147+
};
148+
}),
149+
// EdDSA MPCv2: non-hot wallet types + 'lite' → throws EdDSA MPCv2 error
150+
...['cold', 'custodial', 'backing'].map((walletType) => {
151+
return {
152+
wallet: {
153+
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
154+
type: () => walletType,
155+
multisigType: () => 'tss',
156+
multisigTypeVersion: () => 'MPCv2',
157+
} as any as IWallet,
158+
requestedApiVersion: 'lite' as ApiVersion,
159+
expectedApiVersion: '',
160+
expectedErrorMessage: 'For EdDSA MPCv2 tss wallets, parameter `apiVersion` must be `full`.',
161+
shouldThrow: true,
162+
};
163+
}),
90164
];
91165

92166
testCases.forEach((testCase) => {

0 commit comments

Comments
 (0)