@exodus/ethereum-api 2.1.7 → 2.2.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/ethereum-api",
3
- "version": "2.1.7",
3
+ "version": "2.2.1",
4
4
  "description": "Ethereum Api",
5
5
  "main": "src/index.js",
6
6
  "author": "Exodus Movement, Inc.",
@@ -10,7 +10,7 @@
10
10
  "access": "restricted"
11
11
  },
12
12
  "dependencies": {
13
- "@exodus/ethereum-lib": "^2.4.0",
13
+ "@exodus/ethereum-lib": "^2.4.1",
14
14
  "@exodus/simple-retry": "^0.0.6",
15
15
  "fetchival": "0.3.3",
16
16
  "lodash": "^4.17.11",
@@ -20,5 +20,5 @@
20
20
  "url-join": "4.0.0",
21
21
  "ws": "6.1.0"
22
22
  },
23
- "gitHead": "719a498fd869276a64d17569a2f37325c60ddfb3"
23
+ "gitHead": "124d585074d888dda100311f7fa15063fae3357d"
24
24
  }
@@ -1,58 +1,63 @@
1
1
  import { get } from 'lodash'
2
- import { eth, etc, quorum } from './exodus-eth-server'
3
-
4
- export async function isContract(assetName, address) {
5
- const server = assetName === 'ethereumclassic' ? etc : assetName === 'quorum' ? quorum : eth
2
+ import { normalizeTxId } from '@exodus/ethereum-lib'
3
+ import { eth, serverMap, getServer } from './exodus-eth-server'
4
+
5
+ // Mobile only.
6
+ // Behavior is buggy, because the default server used is ethereum.
7
+ // We should refactor mobile to pass 'asset' instead of 'assetName' so that we can use 'isContractAddress'. But that would touch many assets.
8
+ export async function isContract(baseAssetName, address) {
9
+ const server = serverMap[baseAssetName] || eth
6
10
  return server.isContract(address)
7
11
  }
8
12
 
9
- export async function getNonce({ asset, address, tag = 'latest' }) {
10
- if (!['ethereum', 'ethereumclassic', 'quorum'].includes(asset.name)) return
11
- const server = asset.name === 'ethereumclassic' ? etc : asset.name === 'quorum' ? quorum : eth
12
- const nonce = await server.getTransactionCount(address, tag)
13
- return parseInt(nonce, 16)
14
- }
15
-
16
- export async function estimateGas({ asset, ...args }) {
17
- const server = asset.name === 'ethereumclassic' ? etc : asset.name === 'quorum' ? quorum : eth
18
- return server.estimateGas(args)
13
+ export async function isContractAddress({ asset, address }) {
14
+ return getServer(asset).isContract(address)
19
15
  }
20
16
 
21
- const fetchEthereumBalance = async (address, balanceField = 'value') => {
22
- const balances = await eth.getBalance(address)
23
- return get(balances, ['confirmed', balanceField], '0')
17
+ export async function isForwarderContract({ asset, address }) {
18
+ const contractCode = await getServer(asset).getCode(address)
19
+ return (
20
+ contractCode ===
21
+ '0x5836818037808036817364b29dc43e817817cf77468c8dda63d98ce08fb25af43d91908282803e602b57fd5bf3'
22
+ )
24
23
  }
25
24
 
26
- const fetchEthereumClassicBalance = async (address) => {
27
- const balances = await etc.getBalance(address)
28
- return get(balances, 'confirmed.value', '0')
25
+ export async function getNonce({ asset, address, tag = 'latest' }) {
26
+ const server = getServer(asset)
27
+ const nonce = await server.getTransactionCount(address, tag)
28
+ return parseInt(nonce, 16)
29
29
  }
30
30
 
31
- const fetchQuorumBalance = async (address, balanceField = 'value') => {
32
- const balances = await quorum.getBalance(address)
33
- return get(balances, ['confirmed', balanceField], '0')
31
+ export async function estimateGas({ asset, ...args }) {
32
+ return getServer(asset).estimateGas(args)
34
33
  }
35
34
 
36
35
  // Only Ethereum and Ethereumclassic, not ERC20
37
36
  export async function getBalance({ asset, address }) {
38
- const _getBalance =
39
- asset.name === 'ethereumclassic'
40
- ? fetchEthereumClassicBalance
41
- : asset.name === 'quorum'
42
- ? fetchQuorumBalance
43
- : fetchEthereumBalance
44
- return _getBalance(address)
37
+ if (!['ethereum', 'ethereumclassic', 'quorum'].includes(asset.name))
38
+ throw new Error(`unsupported asset ${asset.name}`)
39
+ const server = getServer(asset)
40
+ const balances = await server.getBalance(address)
41
+ return get(balances, ['confirmed', 'value'], '0')
45
42
  }
46
43
 
47
44
  // Only Ethereum ERC20, not Ethereumclassic
48
45
  export async function getTokenBalance({ asset, address }) {
49
- return asset.name === 'quorum'
50
- ? fetchQuorumBalance(address, asset.contract.address.toLowerCase())
51
- : fetchEthereumBalance(address, asset.contract.address.toLowerCase())
46
+ if (!['ethereum', 'quorum'].includes(asset.baseAsset.name))
47
+ throw new Error(`unsupported base asset ${asset.baseAsset.name}`)
48
+ const server = getServer(asset)
49
+ const balances = await server.getBalance(address)
50
+ return get(balances, ['confirmed', asset.contract.address.toLowerCase()], '0')
52
51
  }
53
52
 
54
53
  // Returns function for supplied asset
55
54
  export function sendRawTransaction(asset) {
56
- const server = asset.name === 'ethereumclassic' ? etc : asset.name === 'quorum' ? quorum : eth
57
- return server.sendRawTransaction
55
+ return getServer(asset).sendRawTransaction
56
+ }
57
+
58
+ export async function transactionExists({ asset, txId }) {
59
+ const server = getServer(asset)
60
+ txId = normalizeTxId(txId)
61
+ const txResult = await server.getTransactionByHash(txId)
62
+ return txResult && txResult.hash === txId
58
63
  }
@@ -9,3 +9,17 @@ const EXODUS_QUORUM_SERVER_URL = 'https://geth-quorum.a.exodus.io/wallet/v1'
9
9
  export const eth = create(EXODUS_ETH_SERVER_URL)
10
10
  export const etc = create(EXODUS_ETC_SERVER_URL)
11
11
  export const quorum = create(EXODUS_QUORUM_SERVER_URL)
12
+
13
+ // exported for in-library use only.
14
+ export const serverMap = {
15
+ ethereum: eth,
16
+ ethereumclassic: etc,
17
+ quorum,
18
+ }
19
+
20
+ export function getServer(asset) {
21
+ const baseAssetName = asset.baseAsset.name
22
+ const server = serverMap[baseAssetName]
23
+ if (!server) throw new Error(`unsupported base asset ${baseAssetName}`)
24
+ return server
25
+ }
@@ -1,7 +1,7 @@
1
1
  import BN from 'bn.js'
2
2
  import * as ethUtil from 'ethereumjs-util'
3
- import { currency2buffer, isEthereumToken, getBaseAsset } from '@exodus/ethereum-lib'
4
- import { estimateGas, isContract as _isContract } from './eth-like-util'
3
+ import { currency2buffer, isEthereumToken } from '@exodus/ethereum-lib'
4
+ import { estimateGas, isContractAddress } from './eth-like-util'
5
5
 
6
6
  const EXTRA_PERCENTAGE = 20
7
7
 
@@ -46,17 +46,18 @@ export async function fetchGasLimit({
46
46
  extraPercentage,
47
47
  }) {
48
48
  if (!amount) amount = asset.currency.ZERO
49
- if (!feeData.gasPrice) feeData.gasPrice = getBaseAsset(asset).currency.ZERO
49
+ if (!feeData.gasPrice) feeData.gasPrice = asset.baseAsset.currency.ZERO
50
50
 
51
51
  const isToken = isEthereumToken(asset)
52
52
  if (isToken) {
53
53
  txInput = ethUtil.bufferToHex(
54
54
  asset.contract.transfer.build(toAddress, amount.toBase().toNumberString())
55
55
  )
56
- amount = getBaseAsset(asset).currency.ZERO
56
+ amount = asset.baseAsset.currency.ZERO
57
57
  toAddress = asset.contract.address
58
58
  } else if (!isContract) {
59
- if (isContract === undefined) isContract = await _isContract(asset.name, toAddress)
59
+ if (isContract === undefined)
60
+ isContract = await isContractAddress({ asset, address: toAddress })
60
61
  if (!isContract) return asset.gasLimit
61
62
  }
62
63