Skip to content

Commit 35171a2

Browse files
Merge pull request #5090 from BitGo/COIN-2046-support-eip1559-for-celo
feat(sdk-coin-celo): support eip1559 for celo
2 parents 62eb275 + 3a7a64d commit 35171a2

File tree

11 files changed

+122
-86
lines changed

11 files changed

+122
-86
lines changed

modules/account-lib/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ const coinBuilderMap = {
157157
rbtc: Rbtc.TransactionBuilder,
158158
trbtc: Rbtc.TransactionBuilder,
159159
celo: Celo.TransactionBuilder,
160-
tcelo: Celo.TransactionBuilder,
160+
tcelo: Celo.TestnetTransactionBuilder,
161161
avaxc: AvaxC.TransactionBuilder,
162162
tavaxc: AvaxC.TransactionBuilder,
163163
bsc: Bsc.TransactionBuilder,

modules/sdk-coin-celo/src/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export { KeyPair, Interface } from '@bitgo/sdk-coin-eth';
22
export { Transaction } from './transaction';
33
export { TransactionBuilder } from './transactionBuilder';
4+
export { TestnetTransactionBuilder } from './testnetTransactionBuilder';
45
export { TransferBuilder } from './transferBuilder';
56

67
import * as Utils from './utils';

modules/sdk-coin-celo/src/lib/resources.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,23 @@ import EthereumCommon from '@ethereumjs/common';
44
/**
55
* A Common object defining the chain and the hardfork for CELO Testnet
66
*/
7-
export const testnetCommon = EthereumCommon.forCustomChain(
8-
'mainnet', // It's a test net based on the main ethereum net
7+
export const testnetCommon = EthereumCommon.custom(
98
{
109
name: 'alfajores',
1110
networkId: (coins.get('tcelo').network as EthereumNetwork).chainId,
1211
chainId: (coins.get('tcelo').network as EthereumNetwork).chainId,
1312
},
14-
'petersburg'
13+
{ hardfork: 'london' }
1514
);
1615

1716
/**
1817
* A Common object defining the chain and the hardfork for CELO Mainnet
1918
*/
20-
export const mainnetCommon = EthereumCommon.forCustomChain(
21-
'mainnet',
19+
export const mainnetCommon = EthereumCommon.custom(
2220
{
2321
name: 'rc1',
2422
networkId: (coins.get('celo').network as EthereumNetwork).chainId,
2523
chainId: (coins.get('celo').network as EthereumNetwork).chainId,
2624
},
27-
'petersburg'
25+
{ hardfork: 'petersburg' }
2826
);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as ethUtil from 'ethereumjs-util';
2+
import { Transaction } from '@bitgo/abstract-eth';
3+
import { BaseCoin as CoinConfig } from '@bitgo/statics';
4+
import { TransactionBuilder } from './transactionBuilder';
5+
6+
export class TestnetTransactionBuilder extends TransactionBuilder {
7+
constructor(_coinConfig: Readonly<CoinConfig>) {
8+
super(_coinConfig);
9+
this.transaction = new Transaction(_coinConfig, this._common);
10+
}
11+
12+
/**
13+
* Get the final v value. Final v is described in EIP-155.
14+
*
15+
* @protected for internal use when the enableFinalVField flag is true.
16+
*/
17+
protected getFinalV(): string {
18+
return ethUtil.addHexPrefix(this._common.chainIdBN().muln(2).addn(35).toString(16));
19+
}
20+
21+
/** @inheritdoc */
22+
protected fromImplementation(rawTransaction: string): Transaction {
23+
let tx: Transaction;
24+
if (/^0x?[0-9a-f]{1,}$/.test(rawTransaction.toLowerCase())) {
25+
tx = Transaction.fromSerialized(this._coinConfig, this._common, rawTransaction);
26+
this.loadBuilderInput(tx.toJson());
27+
} else {
28+
const txData = JSON.parse(rawTransaction);
29+
tx = new Transaction(this._coinConfig, txData);
30+
}
31+
return tx;
32+
}
33+
}

modules/sdk-coin-celo/src/lib/transactionBuilder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { BaseCoin as CoinConfig } from '@bitgo/statics';
22
import EthereumAbi from 'ethereumjs-abi';
3+
import { addHexPrefix } from 'ethereumjs-util';
34
import { TransactionBuilder as EthTransactionBuilder, TxData, walletSimpleConstructor } from '@bitgo/sdk-coin-eth';
45
import { BuildTransactionError, TransactionType, StakingOperationTypes } from '@bitgo/sdk-core';
56
import { Transaction } from './transaction';
67
import { StakingBuilder } from './stakingBuilder';
78
import { StakingCall } from './stakingCall';
89
import { getCommon, walletSimpleByteCode } from './utils';
910
import { TransferBuilder } from './transferBuilder';
10-
import { addHexPrefix } from 'ethereumjs-util';
1111
import BigNumber from 'bignumber.js';
1212

1313
export class TransactionBuilder extends EthTransactionBuilder {

modules/sdk-coin-celo/src/tcelo.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
* @prettier
33
*/
44
import { BaseCoin, BitGoBase } from '@bitgo/sdk-core';
5-
import { BaseCoin as StaticsBaseCoin } from '@bitgo/statics';
5+
import { BaseCoin as StaticsBaseCoin, coins } from '@bitgo/statics';
66
import { Celo } from './celo';
7+
import { TestnetTransactionBuilder } from './lib';
78

89
export class Tcelo extends Celo {
910
protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly<StaticsBaseCoin>) {
@@ -13,4 +14,8 @@ export class Tcelo extends Celo {
1314
static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly<StaticsBaseCoin>): BaseCoin {
1415
return new Tcelo(bitgo, staticsCoin);
1516
}
17+
18+
protected getTransactionBuilder(): TestnetTransactionBuilder {
19+
return new TestnetTransactionBuilder(coins.get(this.getBaseChain()));
20+
}
1621
}

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

Lines changed: 13 additions & 13 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { TransactionBuilder } from '../../src';
1+
import { TestnetTransactionBuilder, TransactionBuilder } from '../../src';
22
import { coins } from '@bitgo/statics';
33

4-
export const getBuilder = (coin: string): TransactionBuilder => {
5-
return new TransactionBuilder(coins.get(coin));
4+
export const getBuilder = (coin: string): TestnetTransactionBuilder | TransactionBuilder => {
5+
return coin === 'celo' ? new TransactionBuilder(coins.get(coin)) : new TestnetTransactionBuilder(coins.get(coin));
66
};

modules/sdk-coin-celo/test/unit/transaction.ts

Lines changed: 0 additions & 57 deletions
This file was deleted.

modules/sdk-coin-celo/test/unit/transactionBuilder/send.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,60 @@ describe('Send transaction', function () {
167167
should.equal(txJson.from, undefined);
168168
});
169169

170+
it('should build txn with eip1559', async function () {
171+
const txBuilder = getBuilder('tcelo') as TransactionBuilder;
172+
txBuilder.fee({
173+
fee: '1000000000',
174+
gasLimit: '12100000',
175+
eip1559: {
176+
maxFeePerGas: '7593123',
177+
maxPriorityFeePerGas: '150',
178+
},
179+
});
180+
txBuilder.counter(2);
181+
txBuilder.type(TransactionType.Send);
182+
txBuilder.contract('0x8f977e912ef500548a0c3be6ddde9899f1199b81');
183+
txBuilder
184+
.transfer()
185+
.coin('tcusd')
186+
.amount('1000000000')
187+
.to('0x19645032c7f1533395d44a629462e751084d3e4c')
188+
.expirationTime(1590066728)
189+
.contractSequenceId(5)
190+
.key(key);
191+
txBuilder.sign({ key: testData.PRIVATE_KEY });
192+
const tx = await txBuilder.build();
193+
const txJson = tx.toJson();
194+
should.equal(txJson.gasLimit, '12100000');
195+
should.equal(txJson._type, 'EIP1559');
196+
should.equal(txJson.maxFeePerGas, '7593123');
197+
should.equal(txJson.maxPriorityFeePerGas, '150');
198+
});
199+
200+
it('should build legacy txn for celo', async function () {
201+
const txBuilder = getBuilder('celo') as TransactionBuilder;
202+
txBuilder.fee({
203+
fee: '1000000000',
204+
gasLimit: '12100000',
205+
});
206+
txBuilder.counter(2);
207+
txBuilder.type(TransactionType.Send);
208+
txBuilder.contract('0x8f977e912ef500548a0c3be6ddde9899f1199b81');
209+
txBuilder
210+
.transfer()
211+
.coin('celo')
212+
.amount('1000000000')
213+
.to('0x19645032c7f1533395d44a629462e751084d3e4c')
214+
.expirationTime(1590066728)
215+
.contractSequenceId(5)
216+
.key(key);
217+
const tx = await txBuilder.build();
218+
const txJson = tx.toJson();
219+
should.equal(txJson.gasLimit, '12100000');
220+
should.equal(txJson._type, 'Legacy');
221+
should.equal(txJson.v, '0xa4ec');
222+
});
223+
170224
it('a send token transaction without final v', async () => {
171225
const recipient = '0x19645032c7f1533395d44a629462e751084d3e4c';
172226
const contractAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
@@ -183,7 +237,7 @@ describe('Send transaction', function () {
183237
.key(key);
184238
const tx = await txBuilder.build();
185239
const txJson = tx.toJson();
186-
should.equal(txJson.v, '0xaef3');
240+
should.equal(txJson.v, '0x015e09');
187241
});
188242
});
189243

0 commit comments

Comments
 (0)