Skip to content

Commit c22cdd0

Browse files
committed
feat(sdk-core): add execMode support to txrequests API
Add optional execMode parameter to prebuildTxWithIntent and the wallet prebuildTransaction flow. When set to 'EXEC_UNSPECIFIED', the server defers transaction execution, giving Figure Markets exchange control over the workflow. Defaults to 'EXEC_TRY' when omitted (existing behavior is unchanged). The field is passed as a top-level body param alongside intent, apiVersion, and preview in the POST /wallet/{id}/txrequests call. Ticket: CSHLD-972 Session-Id: caa99360-6177-4227-8aba-5043f8cb453f Task-Id: 49710c31-924d-41fb-b44b-2dc4a10bce34
1 parent 1165435 commit c22cdd0

6 files changed

Lines changed: 107 additions & 0 deletions

File tree

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

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,82 @@ describe('TSS Utils:', async function () {
10291029

10301030
nockedCreateTx.isDone().should.be.true();
10311031
});
1032+
1033+
it('should include execMode in request body when specified', async function () {
1034+
const nockedCreateTx = await nockCreateTxRequest({
1035+
walletId: wallet.id(),
1036+
requestBody: {
1037+
apiVersion: 'lite',
1038+
execMode: 'EXEC_UNSPECIFIED',
1039+
intent: {
1040+
intentType: 'payment',
1041+
recipients: [
1042+
{
1043+
address: {
1044+
address: 'recipient',
1045+
},
1046+
amount: {
1047+
value: '10000',
1048+
symbol: 'tsol',
1049+
},
1050+
},
1051+
],
1052+
},
1053+
},
1054+
response: {},
1055+
});
1056+
1057+
await tssUtils.prebuildTxWithIntent({
1058+
reqId,
1059+
recipients: [
1060+
{
1061+
address: 'recipient',
1062+
amount: '10000',
1063+
},
1064+
],
1065+
intentType: 'payment',
1066+
execMode: 'EXEC_UNSPECIFIED',
1067+
});
1068+
1069+
nockedCreateTx.isDone().should.be.true();
1070+
});
1071+
1072+
it('should not include execMode in request body when not specified', async function () {
1073+
const nockedCreateTx = await nockCreateTxRequest({
1074+
walletId: wallet.id(),
1075+
requestBody: {
1076+
apiVersion: 'lite',
1077+
intent: {
1078+
intentType: 'payment',
1079+
recipients: [
1080+
{
1081+
address: {
1082+
address: 'recipient',
1083+
},
1084+
amount: {
1085+
value: '10000',
1086+
symbol: 'tsol',
1087+
},
1088+
},
1089+
],
1090+
},
1091+
},
1092+
response: {},
1093+
});
1094+
1095+
await tssUtils.prebuildTxWithIntent({
1096+
reqId,
1097+
recipients: [
1098+
{
1099+
address: 'recipient',
1100+
amount: '10000',
1101+
},
1102+
],
1103+
intentType: 'payment',
1104+
});
1105+
1106+
nockedCreateTx.isDone().should.be.true();
1107+
});
10321108
});
10331109

10341110
describe('delete SignatureShare:', async function () {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ export default class BaseTssUtils<KeyShare> extends MpcUtils implements ITssUtil
386386
},
387387
apiVersion: apiVersion,
388388
preview,
389+
...(params.execMode !== undefined && { execMode: params.execMode }),
389390
};
390391

391392
const reqTracer = params.reqId || new RequestTracer();

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { AShare, DShare, SShare } from '../../tss/ecdsa/types';
1212
import { MessageStandardType } from '../messageTypes';
1313

1414
export type TxRequestVersion = 'full' | 'lite';
15+
export type TxRequestExecMode = 'EXEC_TRY' | 'EXEC_UNSPECIFIED';
1516
export interface HopParams {
1617
paymentId?: string;
1718
userReqSig?: string;
@@ -354,6 +355,12 @@ export interface PrebuildTransactionWithIntentOptions extends IntentOptionsBase
354355
feeToken?: string;
355356
/** Canton-specific params for the cantonCommand intent. */
356357
cantonCommandParams?: CantonCommandParams;
358+
/**
359+
* Controls transaction execution mode on the server side.
360+
* Use 'EXEC_UNSPECIFIED' to defer execution (e.g. Figure Markets exchange flow).
361+
* Defaults to 'EXEC_TRY' when omitted.
362+
*/
363+
execMode?: TxRequestExecMode;
357364
}
358365
export interface IntentRecipient {
359366
address: {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ export const BuildParams = t.exact(
135135
feeToken: t.unknown,
136136
// Bridging parameters for cross-chain operations (e.g., BTC to sBTC)
137137
bridgingParams: t.unknown,
138+
execMode: t.unknown,
138139
}),
139140
])
140141
);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ export interface PrebuildTransactionOptions {
296296
* Parameters for executing DAML commands on Canton.
297297
*/
298298
cantonCommandParams?: CantonCommandParams;
299+
/**
300+
* Controls transaction execution mode. Use 'EXEC_UNSPECIFIED' to defer
301+
* execution (e.g. Figure Markets exchange flow). Defaults to 'EXEC_TRY'.
302+
*/
303+
execMode?: 'EXEC_TRY' | 'EXEC_UNSPECIFIED';
299304
}
300305

301306
export interface PrebuildAndSignTransactionOptions extends PrebuildTransactionOptions, WalletSignTransactionOptions {

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4153,6 +4153,7 @@ export class Wallet implements IWallet {
41534153
unspents: params.unspents,
41544154
senderAddress: params.senderAddress,
41554155
isTestTransaction: params.isTestTransaction,
4156+
execMode: params.execMode,
41564157
},
41574158
apiVersion,
41584159
params.preview
@@ -4170,6 +4171,7 @@ export class Wallet implements IWallet {
41704171
feeToken: params.feeToken,
41714172
unspents: params.unspents,
41724173
sequenceId: params.sequenceId,
4174+
execMode: params.execMode,
41734175
},
41744176
apiVersion,
41754177
params.preview
@@ -4183,6 +4185,7 @@ export class Wallet implements IWallet {
41834185
recipients: params.recipients || [],
41844186
enableTokens: params.enableTokens,
41854187
memo: params.memo,
4188+
execMode: params.execMode,
41864189
},
41874190
apiVersion,
41884191
params.preview
@@ -4195,6 +4198,7 @@ export class Wallet implements IWallet {
41954198
intentType: 'closeAssociatedTokenAccount',
41964199
recipients: params.recipients || [],
41974200
memo: params.memo,
4201+
execMode: params.execMode,
41984202
},
41994203
apiVersion,
42004204
params.preview
@@ -4210,6 +4214,7 @@ export class Wallet implements IWallet {
42104214
receiveAddress: params.receiveAddress,
42114215
feeOptions,
42124216
feeToken: params.feeToken,
4217+
execMode: params.execMode,
42134218
},
42144219
apiVersion,
42154220
params.preview
@@ -4225,6 +4230,7 @@ export class Wallet implements IWallet {
42254230
receiveAddress: params.receiveAddress,
42264231
feeOptions,
42274232
feeToken: params.feeToken,
4233+
execMode: params.execMode,
42284234
},
42294235
apiVersion,
42304236
params.preview
@@ -4237,6 +4243,7 @@ export class Wallet implements IWallet {
42374243
intentType: 'tokenApproval',
42384244
tokenName: params.tokenName,
42394245
feeToken: params.feeToken,
4246+
execMode: params.execMode,
42404247
},
42414248
apiVersion,
42424249
params.preview
@@ -4248,6 +4255,7 @@ export class Wallet implements IWallet {
42484255
reqId,
42494256
intentType: 'createAccount',
42504257
recipients: params.recipients || [],
4258+
execMode: params.execMode,
42514259
},
42524260
apiVersion,
42534261
params.preview
@@ -4260,6 +4268,7 @@ export class Wallet implements IWallet {
42604268
intentType: 'transferAccept',
42614269
txRequestId: params.txRequestId,
42624270
sequenceId: params.txRequestId,
4271+
execMode: params.execMode,
42634272
},
42644273
apiVersion,
42654274
params.preview
@@ -4273,6 +4282,7 @@ export class Wallet implements IWallet {
42734282
intentType: 'transferReject',
42744283
txRequestId: params.txRequestId,
42754284
sequenceId: params.txRequestId,
4285+
execMode: params.execMode,
42764286
},
42774287
apiVersion,
42784288
params.preview
@@ -4286,6 +4296,7 @@ export class Wallet implements IWallet {
42864296
intentType: 'transferOfferWithdrawn',
42874297
transferOfferId: params.transferOfferId,
42884298
sequenceId: params.transferOfferId,
4299+
execMode: params.execMode,
42894300
},
42904301
apiVersion,
42914302
params.preview
@@ -4303,6 +4314,7 @@ export class Wallet implements IWallet {
43034314
cantonCommandParams: params.cantonCommandParams,
43044315
sequenceId: params.sequenceId,
43054316
comment: params.comment,
4317+
execMode: params.execMode,
43064318
},
43074319
apiVersion,
43084320
params.preview
@@ -4323,6 +4335,7 @@ export class Wallet implements IWallet {
43234335
nonce: params.nonce,
43244336
memo: params.memo,
43254337
feeOptions,
4338+
execMode: params.execMode,
43264339
},
43274340
apiVersion,
43284341
params.preview
@@ -4339,6 +4352,7 @@ export class Wallet implements IWallet {
43394352
nonce: params.nonce,
43404353
feeOptions,
43414354
feeToken: params.feeToken,
4355+
execMode: params.execMode,
43424356
},
43434357
apiVersion,
43444358
params.preview
@@ -4355,6 +4369,7 @@ export class Wallet implements IWallet {
43554369
nonce: params.nonce,
43564370
feeOptions,
43574371
feeToken: params.feeToken,
4372+
execMode: params.execMode,
43584373
},
43594374
apiVersion,
43604375
params.preview
@@ -4368,6 +4383,7 @@ export class Wallet implements IWallet {
43684383
sequenceId: params.sequenceId,
43694384
comment: params.comment,
43704385
recipients: params.recipients || [],
4386+
execMode: params.execMode,
43714387
},
43724388
apiVersion,
43734389
params.preview
@@ -4381,6 +4397,7 @@ export class Wallet implements IWallet {
43814397
sequenceId: params.sequenceId,
43824398
comment: params.comment,
43834399
recipients: params.recipients || [],
4400+
execMode: params.execMode,
43844401
},
43854402
apiVersion,
43864403
params.preview

0 commit comments

Comments
 (0)