Skip to content

Commit 3e55481

Browse files
feat(sdk-core): add bridgeFunds intent support for HyperEVM TSS wallets
Ticket: CECHO-103
1 parent ba9875b commit 3e55481

5 files changed

Lines changed: 82 additions & 0 deletions

File tree

modules/bitgo/test/v2/unit/wallet.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3462,6 +3462,32 @@ describe('V2 Wallet:', function () {
34623462
args[1]!.should.equal('full');
34633463
});
34643464

3465+
it('should call prebuildTxWithIntent with the correct params for bridgeFunds', async function () {
3466+
const intentAmount = { value: '1000000', symbol: 'thypeevm' };
3467+
const feeOptions = {
3468+
maxFeePerGas: 3000000000,
3469+
maxPriorityFeePerGas: 2000000000,
3470+
};
3471+
3472+
const prebuildTxWithIntent = sandbox.stub(ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
3473+
prebuildTxWithIntent.resolves(txRequestFull);
3474+
3475+
await tssEthWallet.prebuildTransaction({
3476+
reqId,
3477+
type: 'bridgeFunds',
3478+
intentAmount,
3479+
feeOptions,
3480+
});
3481+
3482+
sinon.assert.calledOnce(prebuildTxWithIntent);
3483+
const args = prebuildTxWithIntent.args[0];
3484+
args[0]!.intentType.should.equal('bridgeFunds');
3485+
args[0]!.amount!.should.deepEqual(intentAmount);
3486+
args[0]!.feeOptions!.should.deepEqual(feeOptions);
3487+
args[0]!.should.not.have.property('recipients');
3488+
args[1]!.should.equal('full');
3489+
});
3490+
34653491
it('should call prebuildTxWithIntent with the correct feeOptions when passing using the legacy format', async function () {
34663492
const recipients = [
34673493
{
@@ -3722,6 +3748,27 @@ describe('V2 Wallet:', function () {
37223748
intent.intentType.should.equal('fillNonce');
37233749
});
37243750

3751+
it('populate intent should return valid bridgeFunds intent', async function () {
3752+
const mpcUtils = new ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('hteth'));
3753+
const amount = { value: '1000000', symbol: 'thypeevm' };
3754+
const feeOptions = {
3755+
maxFeePerGas: 3000000000,
3756+
maxPriorityFeePerGas: 2000000000,
3757+
};
3758+
3759+
const intent = mpcUtils.populateIntent(bitgo.coin('hteth'), {
3760+
reqId,
3761+
intentType: 'bridgeFunds',
3762+
amount,
3763+
feeOptions,
3764+
});
3765+
3766+
intent.intentType.should.equal('bridgeFunds');
3767+
intent.amount!.should.deepEqual(amount);
3768+
intent.feeOptions!.should.deepEqual(feeOptions);
3769+
intent.should.have.property('recipients', undefined);
3770+
});
3771+
37253772
it('should build a single recipient transfer transaction providing apiVersion parameter as "full" ', async function () {
37263773
const recipients = [
37273774
{

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export abstract class MpcUtils {
155155
'transferAccept',
156156
'transferReject',
157157
'transferOfferWithdrawn',
158+
'bridgeFunds',
158159
].includes(params.intentType)
159160
) {
160161
assert(params.recipients, `'recipients' is a required parameter for ${params.intentType} intent`);
@@ -224,6 +225,12 @@ export abstract class MpcUtils {
224225
tokenName: params.tokenName,
225226
feeOptions: params.feeOptions,
226227
};
228+
case 'bridgeFunds':
229+
return {
230+
...baseIntent,
231+
amount: params.amount,
232+
feeOptions: params.feeOptions,
233+
};
227234
default:
228235
throw new Error(`Unsupported intent type ${params.intentType}`);
229236
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ export interface PrebuildTransactionWithIntentOptions extends IntentOptionsBase
271271
txRequestId?: string;
272272
isTestTransaction?: boolean;
273273
contractId?: string;
274+
/**
275+
* Amount for intents that use a top-level amount instead of recipients (e.g. bridgeFunds).
276+
*/
277+
amount?: { value: string; symbol: string };
274278
}
275279
export interface IntentRecipient {
276280
address: {
@@ -342,6 +346,10 @@ export interface PopulatedIntent extends PopulatedIntentBase {
342346
txRequestId?: string;
343347
isTestTransaction?: boolean;
344348
contractId?: string;
349+
/**
350+
* Amount for intents that use a top-level amount instead of recipients (e.g. bridgeFunds).
351+
*/
352+
amount?: { value: string; symbol: string };
345353
}
346354

347355
export type TxRequestState =

modules/sdk-core/src/bitgo/wallet/iWallet.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ export interface PrebuildTransactionOptions {
219219
txRequestId?: string;
220220
isTestTransaction?: boolean;
221221
contractId?: string;
222+
/**
223+
* Amount for intents that use a top-level amount instead of recipients (e.g. bridgeFunds).
224+
* Named intentAmount to avoid collision with SendOptions.amount which is string | number.
225+
*/
226+
intentAmount?: { value: string; symbol: string };
222227
}
223228

224229
export interface PrebuildAndSignTransactionOptions extends PrebuildTransactionOptions, WalletSignTransactionOptions {

modules/sdk-core/src/bitgo/wallet/wallet.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3746,6 +3746,21 @@ export class Wallet implements IWallet {
37463746
params.preview
37473747
);
37483748
break;
3749+
case 'bridgeFunds':
3750+
txRequest = await this.tssUtils!.prebuildTxWithIntent(
3751+
{
3752+
reqId,
3753+
intentType: 'bridgeFunds',
3754+
sequenceId: params.sequenceId,
3755+
comment: params.comment,
3756+
amount: params.intentAmount,
3757+
nonce: params.nonce,
3758+
feeOptions,
3759+
},
3760+
apiVersion,
3761+
params.preview
3762+
);
3763+
break;
37493764
default:
37503765
throw new Error(`transaction type not supported: ${params.type}`);
37513766
}

0 commit comments

Comments
 (0)