@exodus/ethereum-lib 2.7.4 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -4
- package/src/constants.js +3 -2
- package/src/encode.js +2 -2
- package/src/fee-data/ethereum.js +3 -0
- package/src/fee-data/index.js +0 -1
- package/src/fee-monitor/ethereum-like.js +13 -2
- package/src/index.js +3 -1
- package/src/selectors/get-can-accelerate-tx-factory.js +2 -1
- package/src/unsigned-tx/create-unsigned-tx.js +13 -7
- package/src/unsigned-tx/sign-unsigned-tx.js +32 -6
- package/src/utils/index.js +9 -4
- package/src/fee-data/quorum.js +0 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ethereum-lib",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Ethereum Library",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "Exodus Movement, Inc.",
|
|
@@ -10,12 +10,13 @@
|
|
|
10
10
|
"access": "restricted"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
+
"@ethereumjs/common": "^2.3.1",
|
|
14
|
+
"@ethereumjs/tx": "^3.2.1",
|
|
13
15
|
"@exodus/asset-lib": "^3.4.0",
|
|
14
16
|
"@exodus/models": "^8.5.12",
|
|
15
17
|
"@exodus/solidity-contract": "^0.1.3",
|
|
16
18
|
"base-x": "^3.0.2",
|
|
17
|
-
"ethereumjs-
|
|
18
|
-
"ethereumjs-util": "^5.2.0",
|
|
19
|
+
"ethereumjs-util": "^7.0.10",
|
|
19
20
|
"lodash": "^4.17.15",
|
|
20
21
|
"ms": "^2.1.1",
|
|
21
22
|
"reselect": "~3.0.1"
|
|
@@ -23,5 +24,5 @@
|
|
|
23
24
|
"peerDependencies": {
|
|
24
25
|
"@exodus/assets": "8.0.x"
|
|
25
26
|
},
|
|
26
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "a9971be6cc00557bc1581c6801c90ae8702b4712"
|
|
27
28
|
}
|
package/src/constants.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export const CHAIN_IDS = { ethereum: 1, ethereumclassic: 61,
|
|
1
|
+
export const CHAIN_IDS = { ethereum: 1, ethereumclassic: 61, bsc: 56 }
|
|
2
2
|
export const MIN_GASPRICE = 1e9 // 1 gwei
|
|
3
3
|
export const DEFAULT_FEE_MONITOR_INTERVAL = '1m'
|
|
4
4
|
export const CONFIRMATIONS_NUMBER = {
|
|
5
5
|
ethereum: 30,
|
|
6
6
|
ethereumclassic: 5000,
|
|
7
|
-
quorum: 4,
|
|
8
7
|
bsc: 15,
|
|
9
8
|
}
|
|
9
|
+
export const ETHEREUM_LIKE_ASSETS = ['bsc', 'ethereum', 'ethereumclassic']
|
|
10
|
+
export const ETHEREUM_LIKE_TOKEN_TYPES = ['ETHEREUM_ERC20', 'BSC_BEP20']
|
package/src/encode.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import etherUtil from 'ethereumjs-util'
|
|
1
|
+
import * as etherUtil from 'ethereumjs-util'
|
|
2
2
|
|
|
3
3
|
export function validate(address) {
|
|
4
4
|
if (typeof address !== 'string') return false
|
|
@@ -21,7 +21,7 @@ export function encodePrivate(privKey) {
|
|
|
21
21
|
|
|
22
22
|
export function encodePublic(compressedPubKey) {
|
|
23
23
|
const hash160bits = etherUtil.publicToAddress(compressedPubKey, true)
|
|
24
|
-
return etherUtil.toChecksumAddress(hash160bits.toString('hex'))
|
|
24
|
+
return etherUtil.toChecksumAddress('0x' + hash160bits.toString('hex'))
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export function isValidPrivate(privateKey) {
|
package/src/fee-data/ethereum.js
CHANGED
package/src/fee-data/index.js
CHANGED
|
@@ -7,11 +7,15 @@ export default class EthereumLikeFeeMonitor extends FeeMonitor {
|
|
|
7
7
|
interval = DEFAULT_FEE_MONITOR_INTERVAL,
|
|
8
8
|
assetName,
|
|
9
9
|
getGasPrice,
|
|
10
|
+
getBaseFee,
|
|
11
|
+
eip1559Enabled = false,
|
|
10
12
|
minGasPrice = 0,
|
|
11
13
|
}) {
|
|
12
14
|
super({ updateFee, interval, assetName })
|
|
13
15
|
this.getGasPrice = getGasPrice
|
|
14
16
|
this.minGasPrice = minGasPrice
|
|
17
|
+
this.getBaseFee = getBaseFee
|
|
18
|
+
this.eip1559Enabled = eip1559Enabled
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
async fetchFee() {
|
|
@@ -25,8 +29,15 @@ export default class EthereumLikeFeeMonitor extends FeeMonitor {
|
|
|
25
29
|
gasPrice = this.minGasPrice
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
if (this.asset.name === 'ethereum' && this.eip1559Enabled) {
|
|
33
|
+
const baseFee = parseInt(await this.getBaseFee(), 16)
|
|
34
|
+
return {
|
|
35
|
+
gasPrice: `${gasPrice} wei`,
|
|
36
|
+
baseFee: `${baseFee} wei`,
|
|
37
|
+
eip1559Enabled: this.eip1559Enabled,
|
|
38
|
+
}
|
|
30
39
|
}
|
|
40
|
+
|
|
41
|
+
return { gasPrice: `${gasPrice} wei` }
|
|
31
42
|
}
|
|
32
43
|
}
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import createContract from './create-contract'
|
|
2
2
|
import ABI from './abi'
|
|
3
|
+
import * as feeData from './fee-data'
|
|
4
|
+
|
|
5
|
+
export { createContract, ABI, feeData }
|
|
3
6
|
|
|
4
|
-
export { createContract, ABI }
|
|
5
7
|
export * from './encode'
|
|
6
8
|
export * from './unsigned-tx'
|
|
7
9
|
export * from './utils'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSelector } from 'reselect'
|
|
2
2
|
import ms from 'ms'
|
|
3
|
+
import { isEthereumLike } from '../utils'
|
|
3
4
|
|
|
4
5
|
const MINUTE = ms('1m')
|
|
5
6
|
const BumpType = {
|
|
@@ -122,7 +123,7 @@ export default (
|
|
|
122
123
|
const baseAssetName = assets[assetName].baseAsset.name
|
|
123
124
|
if (!getIsRbfEnabled(assetName))
|
|
124
125
|
return wrapResponseToObject({ errorMessage: 'rbf is disabled' })
|
|
125
|
-
if (![
|
|
126
|
+
if (!isEthereumLike(assets[assetName]))
|
|
126
127
|
return wrapResponseToObject({ errorMessage: `not an ETH/ERC20/BSC/BEP20 asset supplied` })
|
|
127
128
|
if (!tx.pending || !tx.sent)
|
|
128
129
|
return wrapResponseToObject({ errorMessage: 'can not bump a confirmed or received TX' })
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { bufferToHex, privateToAddress, toBuffer } from 'ethereumjs-util'
|
|
2
|
+
import { intToBuffer } from 'ethjs-util'
|
|
3
|
+
|
|
2
4
|
import { isToken, currency2buffer } from '../utils'
|
|
3
5
|
import { CHAIN_IDS } from '../constants'
|
|
4
6
|
|
|
@@ -11,13 +13,15 @@ export default function createUnsignedTx({
|
|
|
11
13
|
nonce,
|
|
12
14
|
txInput,
|
|
13
15
|
gasLimit,
|
|
14
|
-
gasPrice,
|
|
16
|
+
gasPrice, // eip 1559: `maxFeePerGas`
|
|
17
|
+
tipGasPrice, // eip 1559: `maxPriorityPerGas`
|
|
15
18
|
privateKey,
|
|
16
19
|
fromAddress,
|
|
17
20
|
chainId,
|
|
21
|
+
eip1559Enabled,
|
|
18
22
|
}): UnsignedTransaction {
|
|
19
23
|
if (txInput) {
|
|
20
|
-
txInput =
|
|
24
|
+
txInput = toBuffer(txInput) // If txInput is already a Buffer, then it is passed through
|
|
21
25
|
} else {
|
|
22
26
|
txInput = Buffer.alloc(0)
|
|
23
27
|
}
|
|
@@ -34,14 +38,15 @@ export default function createUnsignedTx({
|
|
|
34
38
|
if (value.equals(Buffer.from([0]))) value = Buffer.alloc(0)
|
|
35
39
|
|
|
36
40
|
if (!fromAddress) {
|
|
37
|
-
if (privateKey) fromAddress =
|
|
41
|
+
if (privateKey) fromAddress = bufferToHex(privateToAddress(privateKey))
|
|
38
42
|
else throw new Error('createTx: Must pass fromAddress or privateKey in options')
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
const txData = {
|
|
42
|
-
nonce: nonce === 0 ? Buffer.alloc(0) :
|
|
43
|
-
gasPrice: currency2buffer(gasPrice.toBase()),
|
|
44
|
-
|
|
46
|
+
nonce: nonce === 0 ? Buffer.alloc(0) : intToBuffer(nonce),
|
|
47
|
+
gasPrice: currency2buffer(gasPrice.toBase()),
|
|
48
|
+
tipGasPrice: tipGasPrice ? currency2buffer(tipGasPrice.toBase()) : undefined,
|
|
49
|
+
gasLimit: intToBuffer(gasLimit),
|
|
45
50
|
to,
|
|
46
51
|
value,
|
|
47
52
|
data: txInput,
|
|
@@ -53,6 +58,7 @@ export default function createUnsignedTx({
|
|
|
53
58
|
// TODO: We should move away from putting the PK into txMeta, it is a bad practice. It is a potential PK exposure risk if the wrong PK gets included here.
|
|
54
59
|
privateKey, // Used for importing private key
|
|
55
60
|
fee: baseAsset.currency.baseUnit(gasPrice.toBase().toNumber() * gasLimit),
|
|
61
|
+
eip1559Enabled: !!eip1559Enabled,
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
-
import
|
|
2
|
+
import { Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx'
|
|
3
|
+
import Common from '@ethereumjs/common'
|
|
3
4
|
|
|
4
5
|
import type { UnsignedTransaction, SignedTransaction } from '@exodus/models/lib/types'
|
|
5
6
|
|
|
@@ -7,13 +8,38 @@ export default function signUnsignedTx(
|
|
|
7
8
|
unsignedTx: UnsignedTransaction,
|
|
8
9
|
privateKey: Buffer
|
|
9
10
|
): SignedTransaction {
|
|
10
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
txData: { gasPrice, tipGasPrice: maxPriorityFeePerGas, chainId: chain, ...txData },
|
|
13
|
+
txMeta: { eip1559Enabled },
|
|
14
|
+
} = unsignedTx
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
let tx
|
|
17
|
+
/*
|
|
18
|
+
To assemble an EIP 1559 tx,
|
|
19
|
+
both `tipGasPrice` and `eip` must have been set in the input object used to build `unsignedTx`.
|
|
20
|
+
Whether bsc will support EIP 1559 is unknown.
|
|
21
|
+
So we must prevent building accidentally an EIP1559 tx on bsc if tipGasPrice is set
|
|
22
|
+
`eip` will be set with s corresponding feature flag in the wallet
|
|
23
|
+
*/
|
|
24
|
+
if (maxPriorityFeePerGas && eip1559Enabled) {
|
|
25
|
+
tx = FeeMarketEIP1559Transaction.fromTxData(
|
|
26
|
+
{
|
|
27
|
+
maxFeePerGas: gasPrice,
|
|
28
|
+
maxPriorityFeePerGas,
|
|
29
|
+
type: '0x02', // https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx#gas-fee-market-transactions-eip-1559,
|
|
30
|
+
...txData,
|
|
31
|
+
},
|
|
32
|
+
{ common: new Common({ chain, hardfork: 'london' }) }
|
|
33
|
+
)
|
|
34
|
+
} else {
|
|
35
|
+
// Legacy tx
|
|
36
|
+
tx = Transaction.fromTxData({ gasPrice, ...txData }, { common: new Common({ chain }) })
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const signedTx = tx.sign(privateKey)
|
|
14
40
|
|
|
15
41
|
// serialize and get txId
|
|
16
|
-
const rawTx =
|
|
17
|
-
const txId =
|
|
42
|
+
const rawTx = signedTx.serialize()
|
|
43
|
+
const txId = signedTx.hash().toString('hex')
|
|
18
44
|
return { rawTx, txId }
|
|
19
45
|
}
|
package/src/utils/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import baseX from 'base-x'
|
|
2
2
|
import * as ethUtil from 'ethereumjs-util'
|
|
3
3
|
import assets from '@exodus/assets'
|
|
4
|
+
import { ETHEREUM_LIKE_ASSETS, ETHEREUM_LIKE_TOKEN_TYPES } from '../constants'
|
|
4
5
|
|
|
5
6
|
export { default as calculateExtraEth } from './calculate-extra-eth'
|
|
6
7
|
|
|
@@ -9,9 +10,13 @@ const base16 = baseX('0123456789abcdef')
|
|
|
9
10
|
|
|
10
11
|
export const isEthereumToken = (asset) => asset.assetType === 'ETHEREUM_ERC20'
|
|
11
12
|
export const isBscToken = (asset) => asset.assetType === 'BSC_BEP20'
|
|
12
|
-
|
|
13
|
-
export const
|
|
14
|
-
|
|
13
|
+
// All ethereum-like tokens
|
|
14
|
+
export const isEthereumLikeToken = (asset) => ETHEREUM_LIKE_TOKEN_TYPES.includes(asset.assetType)
|
|
15
|
+
export const isToken = isEthereumLikeToken
|
|
16
|
+
// All ethereum-like assets (native coins)
|
|
17
|
+
export const isEthereumLikeAsset = (asset) => ETHEREUM_LIKE_ASSETS.includes(asset.name)
|
|
18
|
+
// All ethereum-like assets and tokens
|
|
19
|
+
export const isEthereumLike = (asset) => ETHEREUM_LIKE_ASSETS.includes(asset.baseAsset.name)
|
|
15
20
|
|
|
16
21
|
export function buffer2currency({ asset, value }) {
|
|
17
22
|
return asset.currency.baseUnit(base10.encode(value)).toDefault()
|
|
@@ -41,5 +46,5 @@ export function normalizeTxId(txId: string): string {
|
|
|
41
46
|
|
|
42
47
|
export function getBaseAsset(asset) {
|
|
43
48
|
console.log(`calling deprecated function getBaseAsset(${asset.name})`) // Apr. 9th 2021
|
|
44
|
-
return isEthereumToken(asset) ? assets.ethereum :
|
|
49
|
+
return isEthereumToken(asset) ? assets.ethereum : asset
|
|
45
50
|
}
|