Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion modules/bitgo/test/v2/unit/internal/tssUtils/eddsa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
common,
createSharedDataProof,
Ed25519BIP32,
EDDSAUtils,
Eddsa,
EncryptedSignerShareType,
ExchangeCommitmentResponse,
Expand Down Expand Up @@ -1130,11 +1131,24 @@ describe('TSS Utils:', async function () {
coldWalletTssUtils.supportedTxRequestVersions().should.deepEqual(['full']);
});
it('should return full and lite for hot wallets', async function () {
const hotWallet = new Wallet(bitgo, baseCoin, { multisigType: 'tss', type: 'hot' });
const hotWallet = new Wallet(bitgo, baseCoin, {
multisigType: 'tss',
multisigTypeVersion: undefined,
type: 'hot',
});
const hotTssUtils = new TssUtils(bitgo, baseCoin, hotWallet);
const supportedTxRequestVersions = hotTssUtils.supportedTxRequestVersions();
supportedTxRequestVersions.should.deepEqual(['lite', 'full']);
});
it('should return only full for hot MPCv2 wallets', function () {
const hotMPCv2Wallet = new Wallet(bitgo, baseCoin, {
multisigType: 'tss',
multisigTypeVersion: 'MPCv2',
type: 'hot',
});
const mpcv2TssUtils = new EDDSAUtils.EddsaMPCv2Utils(bitgo, baseCoin, hotMPCv2Wallet);
mpcv2TssUtils.supportedTxRequestVersions().should.deepEqual(['full']);
});
it('should return empty for trading wallets', function () {
const tradingWallets = new Wallet(bitgo, baseCoin, { multisigType: 'tss', type: 'trading' });
const tradingWalletTssUtils = new TssUtils(bitgo, baseCoin, tradingWallets);
Expand Down
3 changes: 3 additions & 0 deletions modules/sdk-core/src/bitgo/utils/tss/baseTSSUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,9 @@ export default class BaseTssUtils<KeyShare> extends MpcUtils implements ITssUtil
} else if (this._wallet.baseCoin.getMPCAlgorithm() === 'ecdsa') {
return ['full'];
} else if (this._wallet.baseCoin.getMPCAlgorithm() === 'eddsa' && this._wallet.type() === 'hot') {
if (this._wallet.multisigTypeVersion() === 'MPCv2') {
return ['full'];
}
return ['lite', 'full'];
} else {
return ['full'];
Expand Down
7 changes: 4 additions & 3 deletions modules/sdk-core/src/bitgo/utils/txRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export function validateTxRequestApiVersion(wallet: IWallet, requestedApiVersion
return;
}
if (wallet.baseCoin.getMPCAlgorithm() === 'ecdsa') {
// ecdsa wallets can only use full, even if they are hot wallets
assert(requestedApiVersion === 'full', 'For ECDSA tss wallets, parameter `apiVersion` must be `full`.');
} else if (wallet.multisigTypeVersion() === 'MPCv2') {
assert(requestedApiVersion === 'full', 'For EdDSA MPCv2 tss wallets, parameter `apiVersion` must be `full`.');
} else if (wallet.type() !== 'hot') {
// all other cases should use full!
assert(
Expand All @@ -30,10 +31,10 @@ export function getTxRequestApiVersion(wallet: IWallet, requestedApiVersion?: Ap
validateTxRequestApiVersion(wallet, requestedApiVersion);
return requestedApiVersion;
}
if (wallet.baseCoin.getMPCAlgorithm() === 'ecdsa') {
if (wallet.baseCoin.getMPCAlgorithm() === 'ecdsa' || wallet.multisigTypeVersion() === 'MPCv2') {
return 'full';
} else if (wallet.type() === 'hot') {
// default to lite for hot eddsa tss wallets
// default to lite for hot eddsa tss wallets (v1 only)
return 'lite';
} else {
// default to full for all other wallet types
Expand Down
74 changes: 74 additions & 0 deletions modules/sdk-core/test/unit/bitgo/utils/txRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe('txRequest utils', () => {
baseCoin: { getMPCAlgorithm: () => 'ecdsa' },
type: () => 'hot',
multisigType: () => 'tss',
multisigTypeVersion: () => undefined,
} as any as IWallet,
requestedApiVersion: 'lite',
expectedApiVersion: '',
Expand All @@ -20,6 +21,7 @@ describe('txRequest utils', () => {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => 'cold',
multisigType: () => 'tss',
multisigTypeVersion: () => undefined,
} as any as IWallet,
requestedApiVersion: 'lite',
expectedApiVersion: '',
Expand All @@ -30,17 +32,41 @@ describe('txRequest utils', () => {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => 'hot',
multisigType: () => 'tss',
multisigTypeVersion: () => undefined,
} as any as IWallet,
requestedApiVersion: undefined,
expectedApiVersion: 'lite',
expectedErrorMessage: '',
},
{
wallet: {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => 'hot',
multisigType: () => 'tss',
multisigTypeVersion: () => 'MPCv2',
} as any as IWallet,
requestedApiVersion: 'lite' as ApiVersion,
expectedApiVersion: '',
expectedErrorMessage: 'For EdDSA MPCv2 tss wallets, parameter `apiVersion` must be `full`.',
},
{
wallet: {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => 'hot',
multisigType: () => 'tss',
multisigTypeVersion: () => 'MPCv2',
} as any as IWallet,
requestedApiVersion: undefined,
expectedApiVersion: 'full',
expectedErrorMessage: '',
},
...['hot', 'cold', 'custodial', 'backing'].map((walletType) => {
return {
wallet: {
baseCoin: { getMPCAlgorithm: () => 'ecdsa' },
type: () => walletType,
multisigType: () => 'tss',
multisigTypeVersion: () => undefined,
} as any as IWallet,
requestedApiVersion: 'full',
expectedApiVersion: 'full',
Expand All @@ -54,6 +80,7 @@ describe('txRequest utils', () => {
baseCoin: { getMPCAlgorithm: () => 'ecdsa' },
type: () => walletType,
multisigType: () => 'tss',
multisigTypeVersion: () => undefined,
} as any as IWallet,
requestedApiVersion: undefined,
expectedApiVersion: 'full',
Expand All @@ -67,6 +94,7 @@ describe('txRequest utils', () => {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => walletType,
multisigType: () => 'tss',
multisigTypeVersion: () => undefined,
} as any as IWallet,
requestedApiVersion: 'full',
expectedApiVersion: 'full',
Expand All @@ -80,13 +108,59 @@ describe('txRequest utils', () => {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => walletType,
multisigType: () => 'tss',
multisigTypeVersion: () => undefined,
} as any as IWallet,
requestedApiVersion: undefined,
expectedApiVersion: 'full',
expectedErrorMessage: '',
shouldThrow: false,
};
}),
// EdDSA MPCv2: all wallet types + 'full' explicitly → returns 'full'
...['hot', 'cold', 'custodial', 'backing'].map((walletType) => {
return {
wallet: {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => walletType,
multisigType: () => 'tss',
multisigTypeVersion: () => 'MPCv2',
} as any as IWallet,
requestedApiVersion: 'full' as ApiVersion,
expectedApiVersion: 'full',
expectedErrorMessage: '',
shouldThrow: false,
};
}),
// EdDSA MPCv2: non-hot wallet types + undefined → defaults to 'full'
...['cold', 'custodial', 'backing'].map((walletType) => {
return {
wallet: {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => walletType,
multisigType: () => 'tss',
multisigTypeVersion: () => 'MPCv2',
} as any as IWallet,
requestedApiVersion: undefined,
expectedApiVersion: 'full',
expectedErrorMessage: '',
shouldThrow: false,
};
}),
// EdDSA MPCv2: non-hot wallet types + 'lite' → throws EdDSA MPCv2 error
...['cold', 'custodial', 'backing'].map((walletType) => {
return {
wallet: {
baseCoin: { getMPCAlgorithm: () => 'eddsa' },
type: () => walletType,
multisigType: () => 'tss',
multisigTypeVersion: () => 'MPCv2',
} as any as IWallet,
requestedApiVersion: 'lite' as ApiVersion,
expectedApiVersion: '',
expectedErrorMessage: 'For EdDSA MPCv2 tss wallets, parameter `apiVersion` must be `full`.',
shouldThrow: true,
};
}),
];

testCases.forEach((testCase) => {
Expand Down
Loading