Skip to content

Commit b8c0dfc

Browse files
fix: pass isBatch in send API
TICKET: COIN-3387
1 parent b859758 commit b8c0dfc

File tree

4 files changed

+94
-1
lines changed

4 files changed

+94
-1
lines changed

modules/abstract-eth/src/abstractEthLikeNewCoins.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
10311031
expireTime: params.expireTime,
10321032
contractSequenceId: params.txPrebuild.nextContractSequenceId as number,
10331033
sequenceId: params.sequenceId,
1034+
...(params.txPrebuild.isBatch ? { isBatch: params.txPrebuild.isBatch } : {}),
10341035
};
10351036

10361037
return { halfSigned: txParams };

modules/sdk-coin-polygon/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@
4747
"@bitgo/statics": "^51.3.0",
4848
"@ethereumjs/common": "^2.6.5",
4949
"ethereumjs-util": "7.1.5",
50-
"ethers": "^5.1.3"
50+
"ethers": "^5.1.3",
51+
"bignumber.js": "^9.1.2",
52+
"ethereumjs-abi": "^0.6.5"
5153
},
5254
"devDependencies": {
5355
"@bitgo/sdk-api": "^1.61.0",

modules/sdk-coin-polygon/test/unit/polygon.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import BigNumber from 'bignumber.js';
12
import { BitGoAPI } from '@bitgo/sdk-api';
23
import { common, ECDSAMethodTypes, FullySignedTransaction, Recipient, TransactionType, Wallet } from '@bitgo/sdk-core';
34
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
@@ -221,6 +222,94 @@ describe('Polygon', function () {
221222
halfSignedRawTx.halfSigned.eip1559.maxFeePerGas.should.equal('7593123');
222223
halfSignedRawTx.halfSigned.eip1559.maxPriorityFeePerGas.should.equal('150');
223224
});
225+
226+
it('should include isBatch field in halfSigned when signing a native batch transaction', async function () {
227+
const batcherContractAddress = '0xb1b7e7cc1ecafbfd0771a5eb5454ab5b0356980d';
228+
const recipients: Recipient[] = [
229+
{
230+
address: account_2.address,
231+
amount: '500000000000',
232+
},
233+
{
234+
address: '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6',
235+
amount: '500000000000',
236+
},
237+
];
238+
const totalAmount = recipients.reduce(
239+
(sum, recipient) => new BigNumber(sum).plus(recipient.amount).toString(),
240+
'0'
241+
);
242+
const BATCH_METHOD_NAME = 'batch';
243+
const BATCH_METHOD_TYPES = ['address[]', 'uint256[]'];
244+
245+
const addresses = recipients.map((r) => r.address);
246+
const amounts = recipients.map((r) => r.amount);
247+
const batchExecutionInfo = {
248+
values: [addresses, amounts],
249+
totalAmount: totalAmount,
250+
};
251+
252+
const ethAbi = require('ethereumjs-abi');
253+
const ethUtil = require('ethereumjs-util');
254+
255+
const getMethodCallData = (functionName, types, values) => {
256+
return Buffer.concat([
257+
// function signature
258+
ethAbi.methodID(functionName, types),
259+
// function arguments
260+
ethAbi.rawEncode(types, values),
261+
]);
262+
};
263+
264+
const batchData = ethUtil.addHexPrefix(
265+
getMethodCallData(BATCH_METHOD_NAME, BATCH_METHOD_TYPES, batchExecutionInfo.values).toString('hex')
266+
);
267+
268+
const txBuilder = getBuilder('tpolygon') as TransactionBuilder;
269+
txBuilder.fee({
270+
fee: '280000000000',
271+
gasLimit: '7000000',
272+
});
273+
txBuilder.counter(1);
274+
txBuilder.type(TransactionType.Send);
275+
txBuilder.contract(account_1.address);
276+
txBuilder
277+
.transfer()
278+
.amount(totalAmount)
279+
.to(batcherContractAddress)
280+
.data(batchData)
281+
.expirationTime(10000)
282+
.contractSequenceId(1);
283+
284+
const unsignedTx = await txBuilder.build();
285+
const unsignedTxHex = unsignedTx.toBroadcastFormat();
286+
287+
const txPrebuild = {
288+
txHex: unsignedTxHex,
289+
isBatch: true,
290+
recipients: [
291+
{
292+
amount: totalAmount,
293+
address: batcherContractAddress,
294+
},
295+
],
296+
nextContractSequenceId: 1,
297+
gasPrice: 280000000000,
298+
gasLimit: 7000000,
299+
coin: 'tpolygon',
300+
walletId: 'fakeWalletId',
301+
walletContractAddress: account_1.address,
302+
};
303+
304+
const signedTx = await basecoin.signTransaction({
305+
txPrebuild,
306+
prv: account_1.owner_2,
307+
});
308+
309+
should.exist(signedTx);
310+
should.exist(signedTx.halfSigned);
311+
signedTx.halfSigned.should.have.property('isBatch', true);
312+
});
224313
});
225314

226315
describe('Transaction Verification', function () {

modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ export interface HalfSignedTransaction extends HalfSignedAccountTransaction {
360360
contractSequenceId?: number;
361361
sequenceId?: number;
362362
txHex?: never;
363+
isBatch?: boolean;
363364
};
364365
}
365366

0 commit comments

Comments
 (0)