Skip to content
Merged
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
49 changes: 49 additions & 0 deletions modules/bitgo/test/v2/unit/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import {
BaseTssUtils,
KeyType,
SendManyOptions,
PopulatedIntent,
TxRequestVersion,
} from '@bitgo/sdk-core';

import { TestBitGo } from '@bitgo/sdk-test';
Expand All @@ -46,6 +48,12 @@ require('should-sinon');

nock.disableNetConnect();

type CreateTxRequestBody = {
intent: PopulatedIntent;
apiversion: TxRequestVersion;
preview?: boolean;
};

describe('V2 Wallet:', function () {
const reqId = new RequestTracer();
const bitgo = TestBitGo.decorate(BitGo, { env: 'test' });
Expand Down Expand Up @@ -4387,5 +4395,46 @@ describe('V2 Wallet:', function () {
sinon.stub(BaseTssUtils.default.prototype, 'sendTxRequest').resolves('sendTxResponse');
await adaWallet.sendMany(sendManyParams);
});

it('Should send senderAddress in payment intent when using sendmany', async function () {
const sendManyParams = {
type: 'transfer',
recipients: [
{
address: 'address',
amount: '1000',
},
],
senderAddress: 'senderAddr1',
};

nock(bgUrl)
.post(`/api/v2/wallet/${adaWallet.id()}/txrequests`)
.reply((url, body: nock.Body) => {
const createTxRequestBody = body as CreateTxRequestBody;
createTxRequestBody.intent.intentType.should.equal('payment');
createTxRequestBody.intent.senderAddress?.should.equal('senderAddr1');

return [
200,
{
apiVersion: 'lite',
unsignedTxs: [
{
unsignedTx: {
serializedTxHex: 'serializedTxHex',
feeInfo: 'fee info',
},
},
],
},
];
});

sinon.stub(adaWallet.baseCoin, 'verifyTransaction').resolves(true);
sinon.stub(adaWallet, 'signTransaction').resolves({ txRequestId: 'txRequestId' });
sinon.stub(BaseTssUtils.default.prototype, 'sendTxRequest').resolves('sendTxResponse');
await adaWallet.sendMany(sendManyParams).should.be.resolved();
});
});
});
8 changes: 8 additions & 0 deletions modules/sdk-coin-ada/src/ada.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
MPCUnsignedTx,
MPCSweepRecoveryOptions,
MPCTxs,
PopulatedIntent,
PrebuildTransactionWithIntentOptions,
} from '@bitgo/sdk-core';
import { KeyPair as AdaKeyPair, Transaction, TransactionBuilderFactory, Utils } from './lib';
import { BaseCoin as StaticsBaseCoin, CoinFamily, coins } from '@bitgo/statics';
Expand Down Expand Up @@ -613,4 +615,10 @@ export class Ada extends BaseCoin {
private getBuilder(): TransactionBuilderFactory {
return new TransactionBuilderFactory(coins.get(this.getBaseChain()));
}

/** inherited doc */
setCoinSpecificFieldsInIntent(intent: PopulatedIntent, params: PrebuildTransactionWithIntentOptions): void {
intent.unspents = params.unspents;
intent.senderAddress = params.senderAddress;
}
}
7 changes: 7 additions & 0 deletions modules/sdk-coin-sui/src/sui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
TransactionExplanation,
TssVerifyAddressOptions,
VerifyTransactionOptions,
PopulatedIntent,
PrebuildTransactionWithIntentOptions,
} from '@bitgo/sdk-core';
import { BaseCoin as StaticsBaseCoin, BaseNetwork, coins, SuiCoin } from '@bitgo/statics';
import BigNumber from 'bignumber.js';
Expand Down Expand Up @@ -791,4 +793,9 @@ export class Sui extends BaseCoin {

return { transactions: consolidationTransactions, lastScanIndex };
}

/** inherited doc */
setCoinSpecificFieldsInIntent(intent: PopulatedIntent, params: PrebuildTransactionWithIntentOptions): void {
intent.unspents = params.unspents;
}
Comment on lines +798 to +800
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just checking, ticket only says ADA; is this expected for SUI too ?

Copy link
Contributor Author

@shivpippal shivpippal Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just refactored it. Earlier, it was part of populateIntent function. WIN-3106
I've also updated the PR description

}
13 changes: 12 additions & 1 deletion modules/sdk-core/src/bitgo/baseCoin/baseCoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
} from './iBaseCoin';
import { IInscriptionBuilder } from '../inscriptionBuilder';
import { Hash } from 'crypto';
import { MPCSweepRecoveryOptions, MPCTxs } from '../utils';
import { MPCSweepRecoveryOptions, MPCTxs, PopulatedIntent, PrebuildTransactionWithIntentOptions } from '../utils';

export abstract class BaseCoin implements IBaseCoin {
protected readonly bitgo: BitGoBase;
Expand Down Expand Up @@ -551,4 +551,15 @@ export abstract class BaseCoin implements IBaseCoin {
async createBroadcastableSweepTransaction(params: MPCSweepRecoveryOptions): Promise<MPCTxs> {
throw new NotImplementedError('createBroadcastableSweepTransaction is not supported for this coin');
}

/**
* Sets coinspecific fields in intent from input params.
* This method should be overridden in coin-specific classes
* to configure these fields in the intent
* @param intent - intent in which coinspecific fields are to be set
* @param params
*/
setCoinSpecificFieldsInIntent(intent: PopulatedIntent, params: PrebuildTransactionWithIntentOptions): void {
return;
}
}
5 changes: 3 additions & 2 deletions modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { IMarkets } from '../market';
import { IPendingApprovals } from '../pendingApproval';
import { InitiateRecoveryOptions } from '../recovery';
import { EcdsaMPCv2Utils, EcdsaUtils } from '../utils/tss/ecdsa';
import EddsaUtils, { TxRequest } from '../utils/tss/eddsa';
import EddsaUtils, { PrebuildTransactionWithIntentOptions, TxRequest } from '../utils/tss/eddsa';
import { CustomSigningFunction, IWallet, IWallets, Wallet, WalletData } from '../wallet';

import { IWebhooks } from '../webhook/iWebhooks';
import { TransactionType } from '../../account-lib';
import { IInscriptionBuilder } from '../inscriptionBuilder';
import { Hash } from 'crypto';
import { MPCTx } from '../utils';
import { MPCTx, PopulatedIntent } from '../utils';

export interface Output extends ITransactionRecipient {
address: string;
Expand Down Expand Up @@ -537,4 +537,5 @@ export interface IBaseCoin {
buildNftTransferData(params: BuildNftTransferDataOptions): string;
getHashFunction(): Hash;
broadcastTransaction(params: BaseBroadcastTransactionOptions): Promise<BaseBroadcastTransactionResult>;
setCoinSpecificFieldsInIntent(intent: PopulatedIntent, params: PrebuildTransactionWithIntentOptions): void;
}
4 changes: 1 addition & 3 deletions modules/sdk-core/src/bitgo/utils/mpcUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,7 @@ export abstract class MpcUtils {
}
}

if (['ada', 'sui'].includes(baseCoin.getFamily()) && params.unspents) {
baseIntent.unspents = params.unspents;
}
this.baseCoin.setCoinSpecificFieldsInIntent(baseIntent, params);

if (params.feeOptions !== undefined) {
return {
Expand Down
10 changes: 10 additions & 0 deletions modules/sdk-core/src/bitgo/utils/tss/baseTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ export interface PrebuildTransactionWithIntentOptions extends IntentOptionsBase
custodianTransactionId?: string;
receiveAddress?: string;
unspents?: string[];
/**
* The receive address from which funds will be withdrawn.
* This feature is supported only for specific coins, like ADA.
*/
senderAddress?: string;
}
export interface IntentRecipient {
address: {
Expand Down Expand Up @@ -233,6 +238,11 @@ export interface PopulatedIntent extends PopulatedIntentBase {
token?: string;
enableTokens?: TokenEnablement[];
unspents?: string[];
/**
* The receive address from which funds will be withdrawn.
* This feature is supported only for specific coins, like ADA.
*/
senderAddress?: string;
// ETH & ETH-like params
selfSend?: boolean;
feeOptions?: FeeOption | EIP1559FeeOptions;
Expand Down
5 changes: 5 additions & 0 deletions modules/sdk-core/src/bitgo/wallet/iWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ export interface PrebuildTransactionOptions {
gasPrice?: number;
noSplitChange?: boolean;
unspents?: any[];
/**
* The receive address from which funds will be withdrawn.
* This feature is supported only for specific coins, like ADA.
*/
senderAddress?: string;
changeAddress?: string;
allowExternalChangeAddress?: boolean;
type?: string;
Expand Down
1 change: 1 addition & 0 deletions modules/sdk-core/src/bitgo/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3135,6 +3135,7 @@ export class Wallet implements IWallet {
feeOptions,
custodianTransactionId: params.custodianTransactionId,
unspents: params.unspents,
senderAddress: params.senderAddress,
},
apiVersion,
params.preview
Expand Down