Skip to content

Commit

Permalink
Merge pull request #4030 from BitGo/WIN-1021-move-txbuilder-abstracteth
Browse files Browse the repository at this point in the history
refactor(abstract-eth): move txBuilder to abstract-eth
  • Loading branch information
gianchandania authored Nov 2, 2023
2 parents afc1671 + 286ccfd commit 20e4cf4
Show file tree
Hide file tree
Showing 66 changed files with 2,693 additions and 1,215 deletions.
10 changes: 8 additions & 2 deletions modules/abstract-eth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,16 @@
]
},
"dependencies": {
"@bitgo/sdk-coin-eth": "^4.10.0",
"@bitgo/sdk-core": "^8.26.0",
"@bitgo/statics": "^29.0.0",
"@bitgo/utxo-lib": "^9.16.0",
"bignumber.js": "^8.0.1"
"bignumber.js": "^9.1.1",
"ethers": "^5.1.3",
"ethereumjs-util": "7.1.5",
"@ethereumjs/common": "^2.6.5",
"@ethereumjs/tx": "^3.3.0",
"ethereumjs-abi": "^0.6.5",
"bn.js": "^5.2.1",
"debug": "^3.1.0"
}
}
7 changes: 3 additions & 4 deletions modules/abstract-eth/src/abstractEthLikeCoin.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/**
* @prettier
*/
import { isValidEthAddress, KeyPair as EthKeyPair, TransactionBuilder } from '@bitgo/sdk-coin-eth';
import { CoinFamily, BaseCoin as StaticsBaseCoin } from '@bitgo/statics';
import { bip32 } from '@bitgo/utxo-lib';
import { randomBytes } from 'crypto';

import {
BaseCoin,
BitGoBase,
Expand All @@ -22,9 +20,10 @@ import {
TransactionRecipient as Recipient,
VerifyTransactionOptions,
} from '@bitgo/sdk-core';

import BigNumber from 'bignumber.js';

import { isValidEthAddress, KeyPair as EthKeyPair, TransactionBuilder } from './lib';

export interface EthSignTransactionOptions extends SignTransactionOptions {
txPrebuild: TransactionPrebuild;
prv: string;
Expand All @@ -36,7 +35,7 @@ export interface TxInfo {
txid: string;
}

export interface TransactionPrebuild extends BaseTransactionPrebuild {
interface TransactionPrebuild extends BaseTransactionPrebuild {
txHex: string;
txInfo: TxInfo;
feeInfo: EthTransactionFee;
Expand Down
17 changes: 0 additions & 17 deletions modules/abstract-eth/src/abstractEthLikeMPCCoin.ts

This file was deleted.

203 changes: 203 additions & 0 deletions modules/abstract-eth/src/abstractEthLikeNewCoins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/**
* @prettier
*/
import debugLib from 'debug';
import { bip32 } from '@bitgo/utxo-lib';
import {
BitGoBase,
EthereumLibraryUnavailableError,
Recipient,
TransactionRecipient,
TransactionPrebuild as BaseTransactionPrebuild,
} from '@bitgo/sdk-core';
import { BaseCoin as StaticsBaseCoin, CoinFamily, EthereumNetwork as EthLikeNetwork } from '@bitgo/statics';
import type * as EthLikeTxLib from '@ethereumjs/tx';
import type * as EthLikeCommon from '@ethereumjs/common';

import { AbstractEthLikeCoin } from './abstractEthLikeCoin';

/**
* The prebuilt hop transaction returned from the HSM
*/
interface HopPrebuild {
tx: string;
id: string;
signature: string;
paymentId: string;
gasPrice: number;
gasLimit: number;
amount: number;
recipient: string;
nonce: number;
userReqSig: string;
gasPriceMax: number;
}

export interface TransactionPrebuild extends BaseTransactionPrebuild {
hopTransaction?: HopPrebuild;
buildParams: {
recipients: Recipient[];
};
recipients: TransactionRecipient[];
nextContractSequenceId: string;
gasPrice: number;
gasLimit: number;
isBatch: boolean;
coin: string;
token?: string;
}

const debug = debugLib('bitgo:v2:ethlike');

export const optionalDeps = {
get ethAbi() {
try {
return require('ethereumjs-abi');
} catch (e) {
debug('unable to load ethereumjs-abi:');
debug(e.stack);
throw new EthereumLibraryUnavailableError(`ethereumjs-abi`);
}
},

get ethUtil() {
try {
return require('ethereumjs-util');
} catch (e) {
debug('unable to load ethereumjs-util:');
debug(e.stack);
throw new EthereumLibraryUnavailableError(`ethereumjs-util`);
}
},

get EthTx(): typeof EthLikeTxLib {
try {
return require('@ethereumjs/tx');
} catch (e) {
debug('unable to load @ethereumjs/tx');
debug(e.stack);
throw new EthereumLibraryUnavailableError(`@ethereumjs/tx`);
}
},

get EthCommon(): typeof EthLikeCommon {
try {
return require('@ethereumjs/common');
} catch (e) {
debug('unable to load @ethereumjs/common:');
debug(e.stack);
throw new EthereumLibraryUnavailableError(`@ethereumjs/common`);
}
},
};

export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
protected readonly sendMethodName: 'sendMultiSig' | 'sendMultiSigToken';

protected readonly _staticsCoin: Readonly<StaticsBaseCoin>;
private static _ethLikeCoin: Readonly<StaticsBaseCoin>;

protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly<StaticsBaseCoin>) {
super(bitgo, staticsCoin);

if (!staticsCoin) {
throw new Error('missing required constructor parameter staticsCoin');
}

this._staticsCoin = staticsCoin;
AbstractEthLikeNewCoins._ethLikeCoin = staticsCoin;
this.sendMethodName = 'sendMultiSig';
}

readonly staticsCoin?: Readonly<StaticsBaseCoin>;

getChain() {
return this._staticsCoin.name;
}

/**
* Get the base chain that the coin exists on.
*/
getBaseChain() {
return this.getChain();
}

getFamily(): CoinFamily {
return this._staticsCoin.family;
}

getNetwork(): EthLikeNetwork | undefined {
return this._staticsCoin?.network as EthLikeNetwork;
}

getFullName() {
return this._staticsCoin.fullName;
}

getBaseFactor() {
return Math.pow(10, this._staticsCoin.decimalPlaces);
}

/** @inheritDoc */
isEVM(): boolean {
return true;
}

valuelessTransferAllowed(): boolean {
return true;
}

/**
* Evaluates whether an address string is valid for this coin
* @param address
*/
isValidAddress(address: string): boolean {
return optionalDeps.ethUtil.isValidAddress(optionalDeps.ethUtil.addHexPrefix(address));
}

/**
* Return boolean indicating whether input is valid public key for the coin.
*
* @param {String} pub the pub to be checked
* @returns {Boolean} is it valid?
*/
isValidPub(pub: string): boolean {
try {
return bip32.fromBase58(pub).isNeutered();
} catch (e) {
return false;
}
}

/**
* Flag for sending data along with transactions
* @returns {boolean} True if okay to send tx data (ETH), false otherwise
*/
transactionDataAllowed() {
return true;
}

/**
* Default gas price from platform
* @returns {BigNumber}
*/
getRecoveryGasPrice(): any {
return new optionalDeps.ethUtil.BN('20000000000');
}

/**
* Default gas limit from platform
* @returns {BigNumber}
*/
getRecoveryGasLimit(): any {
return new optionalDeps.ethUtil.BN('500000');
}

/**
* Default expire time for a contract call (1 week)
* @returns {number} Time in seconds
*/
getDefaultExpireTime(): number {
return Math.floor(new Date().getTime() / 1000) + 60 * 60 * 24 * 7;
}
}
17 changes: 0 additions & 17 deletions modules/abstract-eth/src/ethLikeMPCToken.ts

This file was deleted.

15 changes: 10 additions & 5 deletions modules/abstract-eth/src/ethLikeToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { coins, EthLikeTokenConfig, tokens } from '@bitgo/statics';

import { BitGoBase, CoinConstructor, NamedCoinConstructor } from '@bitgo/sdk-core';
import { AbstractEthLikeCoin } from './abstractEthLikeCoin';
import { TransactionBuilder as EthTransactionBuilder, TransactionPrebuild } from '@bitgo/sdk-coin-eth';
import { TransactionBuilder as EthLikeTransactionBuilder } from './lib';
import { TransactionPrebuild } from './abstractEthLikeNewCoins';

export type CoinNames = {
[network: string]: string;
Expand Down Expand Up @@ -35,10 +36,6 @@ export class EthLikeToken extends AbstractEthLikeCoin {
return tokensCtors;
}

protected getTransactionBuilder(): EthTransactionBuilder {
return new EthTransactionBuilder(coins.get(this.getBaseChain()));
}

get type(): string {
return this.tokenConfig.type;
}
Expand Down Expand Up @@ -102,4 +99,12 @@ export class EthLikeToken extends AbstractEthLikeCoin {
verifyCoin(txPrebuild: TransactionPrebuild): boolean {
return txPrebuild.coin === this.tokenConfig.coin && txPrebuild.token === this.tokenConfig.type;
}

/**
* Create a new transaction builder for the current chain
* @return a new transaction builder
*/
protected getTransactionBuilder(): EthLikeTransactionBuilder {
throw new Error('Method not implemented');
}
}
4 changes: 2 additions & 2 deletions modules/abstract-eth/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './abstractEthLikeCoin';
export * from './ethLikeToken';
export * from './abstractEthLikeMPCCoin';
export * from './ethLikeMPCToken';
export * from './lib';
export * from './abstractEthLikeNewCoins';
File renamed without changes.
17 changes: 17 additions & 0 deletions modules/abstract-eth/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export * from './contractCall';
export * from './iface';
export * from './keyPair';
export * from './transaction';
export * from './transactionBuilder';
export * from './transferBuilder';
export * from './transferBuilders';
export * from './transferBuilder';
export * from './types';
export * from './utils';
export * from './walletUtil';

// for Backwards Compatibility
import * as Interface from './iface';
import * as Utils from './utils';

export { Interface, Utils };
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 20e4cf4

Please sign in to comment.