diff --git a/modules/bitgo/test/v2/unit/wallet.ts b/modules/bitgo/test/v2/unit/wallet.ts index ac95b2c1fe..a266cfb021 100644 --- a/modules/bitgo/test/v2/unit/wallet.ts +++ b/modules/bitgo/test/v2/unit/wallet.ts @@ -1786,6 +1786,28 @@ describe('V2 Wallet:', function () { txPrebuild.recipients[0].amount.should.equal('1000000000000000'); }); + it('should pass isTestTransaction parameter through for multisig wallets', async function () { + const recipients = [ + { + address: 'aaa', + amount: '1000', + }, + ]; + const isTestTransaction = true; + const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`; + const response = nock(bgUrl) + .post(path, _.matches({ recipients, isTestTransaction })) // use _.matches to do a partial match on request body object instead of strict matching + .reply(200); + try { + await wallet.prebuildTransaction({ recipients, isTestTransaction }); + } catch (e) { + // the prebuildTransaction method will probably throw an exception for not having all of the correct nocks + // we only care about /tx/build and whether isTestTransaction is an allowed parameter + } + + response.isDone().should.be.true(); + }); + it('should pass unspent reservation parameter through when building transactions', async function () { const reservation = { expireTime: '2029-08-12', @@ -2362,6 +2384,50 @@ describe('V2 Wallet:', function () { }); }); + it('should build a transfer transaction with isTestTransaction flag', async function () { + const recipients = [ + { + address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah', + amount: '1000', + }, + ]; + + const prebuildTxWithIntent = sandbox.stub(TssUtils.prototype, 'prebuildTxWithIntent'); + prebuildTxWithIntent.resolves(txRequest); + + const txPrebuild = await tssSolWallet.prebuildTransaction({ + reqId, + recipients, + type: 'transfer', + isTestTransaction: true, + }); + + // Verify isTestTransaction is passed to prebuildTxWithIntent + sinon.assert.calledOnce(prebuildTxWithIntent); + const callArgs = prebuildTxWithIntent.getCall(0).args[0]; + callArgs.should.have.property('isTestTransaction', true); + callArgs.should.have.property('intentType', 'payment'); + callArgs.should.have.property('recipients'); + should.exist(callArgs.recipients); + callArgs.recipients!.should.deepEqual(recipients); + + txPrebuild.should.deepEqual({ + walletId: tssSolWallet.id(), + wallet: tssSolWallet, + txRequestId: 'id', + txHex: 'ababcdcd', + buildParams: { + recipients, + type: 'transfer', + isTestTransaction: true, + }, + feeInfo: { + fee: 5000, + feeString: '5000', + }, + }); + }); + it('should build an enable token transaction', async function () { const recipients = []; const tokenName = 'tcoin:tokenName'; @@ -3909,6 +3975,35 @@ describe('V2 Wallet:', function () { setRequestTracerSpy.restore(); }); + it('should pass isTestTransaction through sendMany to prebuildAndSignTransaction', async function () { + const signedTransaction = { + txRequestId: 'txRequestId', + }; + + const sendManyInputWithTestFlag = { + ...sendManyInput, + type: 'transfer', + isTestTransaction: true, + }; + + const prebuildAndSignTransaction = sandbox.stub(tssSolWallet, 'prebuildAndSignTransaction'); + prebuildAndSignTransaction.resolves(signedTransaction); + + const sendTxRequest = sandbox.stub(TssUtils.prototype, 'sendTxRequest'); + sendTxRequest.resolves('sendTxResponse'); + + const sendMany = await tssSolWallet.sendMany(sendManyInputWithTestFlag); + + // Verify prebuildAndSignTransaction was called with isTestTransaction + sinon.assert.calledOnce(prebuildAndSignTransaction); + const callArgs = prebuildAndSignTransaction.getCall(0).args[0]; + should.exist(callArgs); + callArgs!.should.have.property('isTestTransaction', true); + callArgs!.should.have.property('type', 'transfer'); + + sendMany.should.deepEqual('sendTxResponse'); + }); + it('should return transfer from sendMany for apiVersion=full', async function () { const wallet = new Wallet(bitgo, tsol, { ...walletData, diff --git a/modules/sdk-core/src/bitgo/utils/mpcUtils.ts b/modules/sdk-core/src/bitgo/utils/mpcUtils.ts index d1ac23294c..0b4932c1e8 100644 --- a/modules/sdk-core/src/bitgo/utils/mpcUtils.ts +++ b/modules/sdk-core/src/bitgo/utils/mpcUtils.ts @@ -188,6 +188,7 @@ export abstract class MpcUtils { nonce: params.nonce, recipients: intentRecipients, tokenName: params.tokenName, + isTestTransaction: params.isTestTransaction, }; if (baseCoin.getFamily() === 'eth' || baseCoin.getFamily() === 'polygon' || baseCoin.getFamily() === 'bsc') { diff --git a/modules/sdk-core/src/bitgo/utils/tss/baseTypes.ts b/modules/sdk-core/src/bitgo/utils/tss/baseTypes.ts index 38e31d4399..ba2f3b6d46 100644 --- a/modules/sdk-core/src/bitgo/utils/tss/baseTypes.ts +++ b/modules/sdk-core/src/bitgo/utils/tss/baseTypes.ts @@ -269,6 +269,7 @@ export interface PrebuildTransactionWithIntentOptions extends IntentOptionsBase abi?: any; }; txRequestId?: string; + isTestTransaction?: boolean; } export interface IntentRecipient { address: { @@ -338,6 +339,7 @@ export interface PopulatedIntent extends PopulatedIntentBase { */ aptosCustomTransactionParams?: aptosCustomTransactionParams; txRequestId?: string; + isTestTransaction?: boolean; } export type TxRequestState = diff --git a/modules/sdk-core/src/bitgo/wallet/BuildParams.ts b/modules/sdk-core/src/bitgo/wallet/BuildParams.ts index 12e02967fc..93a497c82d 100644 --- a/modules/sdk-core/src/bitgo/wallet/BuildParams.ts +++ b/modules/sdk-core/src/bitgo/wallet/BuildParams.ts @@ -116,6 +116,7 @@ export const BuildParams = t.exact( solVersionedTransactionData: t.unknown, // Aptos custom transaction parameters for smart contract calls aptosCustomTransactionParams: t.unknown, + isTestTransaction: t.unknown, }), ]) ); diff --git a/modules/sdk-core/src/bitgo/wallet/iWallet.ts b/modules/sdk-core/src/bitgo/wallet/iWallet.ts index 4ed62f2d3d..71f58ca54b 100644 --- a/modules/sdk-core/src/bitgo/wallet/iWallet.ts +++ b/modules/sdk-core/src/bitgo/wallet/iWallet.ts @@ -217,6 +217,7 @@ export interface PrebuildTransactionOptions { abi?: any; }; txRequestId?: string; + isTestTransaction?: boolean; } export interface PrebuildAndSignTransactionOptions extends PrebuildTransactionOptions, WalletSignTransactionOptions { diff --git a/modules/sdk-core/src/bitgo/wallet/wallet.ts b/modules/sdk-core/src/bitgo/wallet/wallet.ts index 710c807ca5..6730c134d0 100644 --- a/modules/sdk-core/src/bitgo/wallet/wallet.ts +++ b/modules/sdk-core/src/bitgo/wallet/wallet.ts @@ -3434,6 +3434,7 @@ export class Wallet implements IWallet { custodianTransactionId: params.custodianTransactionId, unspents: params.unspents, senderAddress: params.senderAddress, + isTestTransaction: params.isTestTransaction, }, apiVersion, params.preview