Skip to content

Commit e03eecd

Browse files
committed
feat(sdk-coin-vet): add flushtoken txbuilder
COIN-4742 TICKET: COIN-4742
1 parent c8e0b97 commit e03eecd

5 files changed

Lines changed: 114 additions & 16 deletions

File tree

modules/sdk-coin-vet/src/lib/transactionBuilder/flushTokenTransactionBuilder.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import assert from 'assert';
22
import { BaseCoin as CoinConfig } from '@bitgo/statics';
3-
import { TransactionType } from '@bitgo/sdk-core';
3+
import { TransactionType, BuildTransactionError } from '@bitgo/sdk-core';
44
import { decodeFlushTokensData, flushTokensData } from '@bitgo/abstract-eth';
55
import { TransactionClause } from '@vechain/sdk-core';
66

@@ -68,7 +68,7 @@ export class FlushTokenTransactionBuilder extends TransactionBuilder {
6868
return false;
6969
}
7070

71-
const { tokenAddress } = decodeFlushTokensData(clause.data);
71+
const { tokenAddress } = decodeFlushTokensData(clause.data, clause.to);
7272

7373
if (!utils.isValidAddress(tokenAddress as string)) {
7474
return false;
@@ -92,6 +92,15 @@ export class FlushTokenTransactionBuilder extends TransactionBuilder {
9292
return this;
9393
}
9494

95+
forwarderVersion(version: number): this {
96+
if (version < 4) {
97+
throw new BuildTransactionError(`Invalid forwarder version: ${version}`);
98+
}
99+
100+
this.flushTokenTransaction.forwarderVersion = version;
101+
return this;
102+
}
103+
95104
/** @inheritdoc */
96105
validateTransaction(transaction?: FlushTokenTransaction): void {
97106
if (!transaction) {

modules/sdk-coin-vet/src/lib/transactionBuilder/transferBuilder.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,6 @@ export class TransferBuilder extends TransactionBuilder {
1717
return TransactionType.Send;
1818
}
1919

20-
/** @inheritdoc */
21-
protected fromImplementation(rawTransaction: string): Transaction {
22-
const tx = new Transaction(this._coinConfig);
23-
this.validateRawTransaction(rawTransaction);
24-
25-
tx.fromRawTransaction(rawTransaction);
26-
this.initBuilder(tx);
27-
this.validateTransaction(tx);
28-
return this.transaction;
29-
}
30-
3120
protected isValidTransactionClauses(clauses: TransactionClause[]): boolean {
3221
try {
3322
if (!clauses || !Array.isArray(clauses) || clauses.length === 0) {

modules/sdk-coin-vet/test/resources/vet.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@ export const ADDRESS_INITIALIZATION_DATA =
2121
export const ADDRESS_INITIALIZATION_SIGNABLE_PAYLOAD =
2222
'f8952788014ead140e77bbc140f87ef87c9465343e18c376d2fc8c3cf10cd146d63e2e0dc9ef80b86413b2f75c00000000000000000000000055b00b5c807d5696197b48d4affa40bb876df2400000000000000000000000007c87b9ffc6fd6c167c0e4fa9418720f3d659358e000000000000000000000000000000000000000000000000000000000000000181808252088082faf8c0';
2323

24-
export const DEPLOYED_ADDRESS = '0x043fde2fa0ece77c2461a9571f3b1b1c6faca120';
24+
export const FORWARDER_ADDRESS = '0x043fde2fa0ece77c2461a9571f3b1b1c6faca120';
25+
26+
export const FLUSH_TOKEN_TRANSACTION =
27+
'0xf8542788014ead140e77bbc140f83df83b94043fde2fa0ece77c2461a9571f3b1b1c6faca12080a43ef133670000000000000000000000000000000000000000000000000000456e6572677981808252088082faf8c0';
28+
29+
export const FLUSH_TOKEN_DATA = '0x3ef133670000000000000000000000000000000000000000000000000000456e65726779';
30+
31+
export const FLUSH_TOKEN_SIGNABLE_PAYLOAD =
32+
'f8542788014ead140e77bbc140f83df83b94043fde2fa0ece77c2461a9571f3b1b1c6faca12080a43ef133670000000000000000000000000000000000000000000000000000456e6572677981808252088082faf8c0';
2533

2634
export const INVALID_TRANSACTION =
2735
'0xf8bc2788014ea060b5b5997e40e0df94e5f4eec44adf19c4cbeec88016345785d8a000080818082520880830bf84fc101b882418e212a40b29da685a7312829e8d1d3708b654f4ddb4388a7a80f5af3e5423b455451901d9b837fe18501e6ea5ec7d3d2711f00073d553aabe40e0260ec8a6f00da557d0a1af66b82b457324bc6fc86c7f0362e76c15b64432e66b6fa62fca38c7d208a604d1a7ec5356c95fec7bc6f332d16718a91a53e0e99e3a81ae3205ab400';
@@ -91,4 +99,6 @@ export const BASE_ADDRESS = '0x55b00b5c807d5696197b48d4affa40bb876df240';
9199

92100
export const FEE_ADDRESS = '0x7c87b9ffc6fd6c167c0e4fa9418720f3d659358e';
93101

102+
export const TOKEN_ADDRESS = '0x0000000000000000000000000000456E65726779';
103+
94104
export const SALT = '0x1';

modules/sdk-coin-vet/test/transactionBuilder/addressInitializationBuilder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe('Address Initialisation Transaction', () => {
3232
should.equal(tx.clauses[0].to, testData.FORWARDER_FACTORY_ADDRESS);
3333
should.equal(tx.clauses[0].data, testData.ADDRESS_INITIALIZATION_DATA);
3434
should.equal(tx.clauses[0].value, '0x0');
35-
should.equal(tx.deployedAddress, testData.DEPLOYED_ADDRESS);
35+
should.equal(tx.deployedAddress, testData.FORWARDER_ADDRESS);
3636
const rawTx = tx.toBroadcastFormat();
3737
should.equal(txBuilder.isValidRawTransaction(rawTx), true);
3838
rawTx.should.equal(testData.ADDRESS_INITIALIZATION_TRANSACTION);
@@ -80,7 +80,7 @@ describe('Address Initialisation Transaction', () => {
8080
should.equal(toJson.expiration, 64);
8181
should.equal(toJson.data, testData.ADDRESS_INITIALIZATION_DATA);
8282
should.equal(toJson.to, testData.FORWARDER_FACTORY_ADDRESS);
83-
should.equal(toJson.deployedAddress, testData.DEPLOYED_ADDRESS);
83+
should.equal(toJson.deployedAddress, testData.FORWARDER_ADDRESS);
8484
should.equal(toJson.value, '0');
8585
});
8686
});
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { TransactionBuilderFactory } from '../../src';
2+
import { coins } from '@bitgo/statics';
3+
import * as testData from '../resources/vet';
4+
import should from 'should';
5+
import { TransactionType } from '@bitgo/sdk-core';
6+
7+
import { FlushTokenTransaction } from '../../src/lib/transaction/flushTokenTransaction';
8+
9+
describe('Flush Token Transaction', () => {
10+
const factory = new TransactionBuilderFactory(coins.get('tvet'));
11+
12+
describe('Succeed', () => {
13+
it('should build a flush token transaction', async function () {
14+
const transaction = new FlushTokenTransaction(coins.get('tvet'));
15+
const txBuilder = factory.getFlushTokenTransactionBuilder(transaction);
16+
txBuilder.gas(21000);
17+
txBuilder.nonce(64248);
18+
txBuilder.blockRef('0x014ead140e77bbc1');
19+
txBuilder.expiration(64);
20+
txBuilder.gasPriceCoef(128);
21+
txBuilder.contract(testData.FORWARDER_ADDRESS);
22+
txBuilder.tokenAddress(testData.TOKEN_ADDRESS);
23+
txBuilder.forwarderVersion(4);
24+
const tx = (await txBuilder.build()) as FlushTokenTransaction;
25+
should.equal(tx.gas, 21000);
26+
should.equal(tx.nonce, 64248);
27+
should.equal(tx.expiration, 64);
28+
should.equal(tx.type, TransactionType.FlushTokens);
29+
should.equal(tx.blockRef, '0x014ead140e77bbc1');
30+
should.equal(tx.clauses.length, 1);
31+
should.equal(tx.clauses[0].to, testData.FORWARDER_ADDRESS);
32+
should.equal(tx.clauses[0].data, testData.FLUSH_TOKEN_DATA);
33+
should.equal(tx.clauses[0].value, '0x0');
34+
const rawTx = tx.toBroadcastFormat();
35+
should.equal(txBuilder.isValidRawTransaction(rawTx), true);
36+
rawTx.should.equal(testData.FLUSH_TOKEN_TRANSACTION);
37+
});
38+
39+
it('should succeed to validate a valid signablePayload', async function () {
40+
const transaction = new FlushTokenTransaction(coins.get('tvet'));
41+
const txBuilder = factory.getFlushTokenTransactionBuilder(transaction);
42+
txBuilder.gas(21000);
43+
txBuilder.nonce(64248);
44+
txBuilder.blockRef('0x014ead140e77bbc1');
45+
txBuilder.expiration(64);
46+
txBuilder.gasPriceCoef(128);
47+
txBuilder.contract(testData.FORWARDER_ADDRESS);
48+
txBuilder.tokenAddress(testData.TOKEN_ADDRESS);
49+
txBuilder.forwarderVersion(4);
50+
const tx = (await txBuilder.build()) as FlushTokenTransaction;
51+
const signablePayload = tx.signablePayload;
52+
should.equal(signablePayload.toString('hex'), testData.FLUSH_TOKEN_SIGNABLE_PAYLOAD);
53+
});
54+
55+
it('should build a unsigned tx and validate its toJson', async function () {
56+
const transaction = new FlushTokenTransaction(coins.get('tvet'));
57+
const txBuilder = factory.getFlushTokenTransactionBuilder(transaction);
58+
txBuilder.gas(21000);
59+
txBuilder.nonce(64248);
60+
txBuilder.blockRef('0x014ead140e77bbc1');
61+
txBuilder.expiration(64);
62+
txBuilder.gasPriceCoef(128);
63+
txBuilder.contract(testData.FORWARDER_ADDRESS);
64+
txBuilder.tokenAddress(testData.TOKEN_ADDRESS);
65+
txBuilder.forwarderVersion(4);
66+
const tx = (await txBuilder.build()) as FlushTokenTransaction;
67+
68+
const toJson = tx.toJson();
69+
should.equal(toJson.nonce, 64248);
70+
should.equal(toJson.gas, 21000);
71+
should.equal(toJson.gasPriceCoef, 128);
72+
should.equal(toJson.expiration, 64);
73+
should.equal(toJson.data, testData.FLUSH_TOKEN_DATA);
74+
should.equal(toJson.to, testData.FORWARDER_ADDRESS);
75+
should.equal(toJson.tokenAddress, testData.TOKEN_ADDRESS);
76+
should.equal(toJson.value, '0');
77+
});
78+
});
79+
80+
describe('Fail', () => {
81+
it('should fail if invalid params are used to build a tx', async function () {
82+
const transaction = new FlushTokenTransaction(coins.get('tvet'));
83+
const txBuilder = factory.getFlushTokenTransactionBuilder(transaction);
84+
85+
should(() => txBuilder.tokenAddress('randomString')).throwError('Invalid address randomString');
86+
should(() => txBuilder.contract('randomString')).throwError('Invalid address randomString');
87+
should(() => txBuilder.forwarderVersion(3)).throwError('Invalid forwarder version: 3');
88+
});
89+
});
90+
});

0 commit comments

Comments
 (0)