Skip to content

Commit fc87d88

Browse files
feat(sdk-core): add bridgeFunds intent support for HyperEVM TSS wallets
Add support for the bridgeFunds intent type in the TSS prebuildTransaction flow, enabling bridging assets from HyperCore to HyperEVM. Unlike payment intents that use recipients, bridgeFunds uses a top-level amount field (value + symbol) since the bridge destination is implicit. Ticket: CECHO-103
1 parent bfd23b4 commit fc87d88

File tree

5 files changed

+82
-0
lines changed

5 files changed

+82
-0
lines changed

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)