@exodus/ethereum-api 7.0.18 → 7.2.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.
Files changed (43) hide show
  1. package/package.json +10 -6
  2. package/src/allowance/constants.js +3 -2
  3. package/src/allowance/index.js +90 -84
  4. package/src/ens/addresses.js +3 -1
  5. package/src/eth-like-util.js +6 -5
  6. package/src/etherscan/account.js +2 -2
  7. package/src/etherscan/index.js +15 -35
  8. package/src/etherscan/proxy.js +3 -3
  9. package/src/etherscan/request.js +1 -1
  10. package/src/etherscan/ws.js +2 -2
  11. package/src/exodus-eth-server/api-coin-nodes.js +4 -3
  12. package/src/exodus-eth-server/api.js +6 -4
  13. package/src/exodus-eth-server/clarity.js +10 -3
  14. package/src/exodus-eth-server/ws.js +13 -1
  15. package/src/fee-monitor/ethereumarbnova.js +4 -1
  16. package/src/fee-monitor/ethereumarbone.js +4 -1
  17. package/src/fee-monitor/ethereumsepolia.js +18 -0
  18. package/src/fee-monitor/index.js +1 -0
  19. package/src/fee-monitor/optimism.js +4 -1
  20. package/src/gas-estimation.js +3 -1
  21. package/src/get-balances.js +2 -1
  22. package/src/simulate-tx/simulate-eth-tx.js +4 -3
  23. package/src/staking/ethereum/api.js +8 -8
  24. package/src/staking/ethereum/service.js +33 -35
  25. package/src/staking/ethereum/staking-utils.js +3 -5
  26. package/src/staking/fantom-staking.js +2 -2
  27. package/src/staking/matic/api.js +2 -3
  28. package/src/staking/matic/service.js +34 -42
  29. package/src/staking/staking-provider-client.js +3 -3
  30. package/src/tx-log/clarity-monitor.js +14 -9
  31. package/src/tx-log/clarity-utils/get-derive-data-needed-for-tick.js +1 -1
  32. package/src/tx-log/clarity-utils/get-log-items-from-server-tx.js +4 -1
  33. package/src/tx-log/ethereum-monitor.js +8 -11
  34. package/src/tx-log/ethereum-no-history-monitor.js +13 -11
  35. package/src/tx-log/monitor-utils/check-pending-transactions.js +2 -0
  36. package/src/tx-log/monitor-utils/exclude-unchanged-token-balances.js +2 -3
  37. package/src/tx-log/monitor-utils/get-derive-data-needed-for-tick.js +1 -1
  38. package/src/tx-log/monitor-utils/get-derive-transactions-to-check.js +2 -1
  39. package/src/tx-log/monitor-utils/get-log-items-from-server-tx.js +5 -2
  40. package/src/tx-log/ws-updates.js +1 -1
  41. package/src/websocket/index.js +5 -4
  42. package/LICENSE.md +0 -0
  43. package/src/tx-log/monitor-utils/types.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/ethereum-api",
3
- "version": "7.0.18",
3
+ "version": "7.2.0",
4
4
  "description": "Ethereum Api",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -19,12 +19,12 @@
19
19
  "lint:fix": "yarn lint --fix"
20
20
  },
21
21
  "dependencies": {
22
- "@exodus/asset-lib": "^3.7.1",
22
+ "@exodus/asset-lib": "^4.1.0",
23
23
  "@exodus/crypto": "^1.0.0-rc.0",
24
24
  "@exodus/currency": "^2.1.3",
25
25
  "@exodus/ethereum-lib": "^4.2.7",
26
26
  "@exodus/ethereum-meta": "^1.2.0",
27
- "@exodus/ethereumjs-util": "^7.1.0-exodus.6",
27
+ "@exodus/ethereumjs-util": "^7.1.0-exodus.7",
28
28
  "@exodus/fetch": "^1.3.0-beta.4",
29
29
  "@exodus/models": "^11.0.0",
30
30
  "@exodus/simple-retry": "^0.0.6",
@@ -41,12 +41,16 @@
41
41
  "ws": "^6.1.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@exodus/assets": "9.1.0",
45
- "@exodus/assets-base": "^8.1.14",
44
+ "@exodus/assets": "^9.1.1",
46
45
  "@exodus/assets-testing": "^1.0.0",
46
+ "@exodus/bsc-meta": "^1.1.2",
47
+ "@exodus/ethereumarbone-meta": "^1.1.5",
48
+ "@exodus/ethereumgoerli-meta": "^1.0.3",
49
+ "@exodus/fantommainnet-meta": "^1.0.5",
50
+ "@exodus/rootstock-meta": "^1.0.5",
47
51
  "bignumber.js": "9.0.1",
48
52
  "cross-fetch": "^3.1.5",
49
53
  "delay": "4.0.1"
50
54
  },
51
- "gitHead": "fc74398662718e696baca062122c3e6908672504"
55
+ "gitHead": "4c4d7567f9c6d24acf3b48d2b23e0c23b15b45aa"
52
56
  }
@@ -8,7 +8,8 @@ export const ZERO_ALLOWANCE_ASSETS = [
8
8
  'decentraland',
9
9
  'dent',
10
10
  'lidodao',
11
+ 'enjincoin',
11
12
  ]
12
13
 
13
- export const APPROVAL_GAS_LIMIT = 60000
14
- export const ALLOWANCE_TX_TIMEOUT = 60000 * 5
14
+ export const APPROVAL_GAS_LIMIT = 60_000
15
+ export const ALLOWANCE_TX_TIMEOUT = 60_000 * 5
@@ -1,8 +1,7 @@
1
- import { fetchGasLimit, getServer } from '../'
1
+ import { fetchGasLimit } from '../gas-estimation'
2
+ import { getServer } from '../exodus-eth-server'
2
3
  import { ALLOWANCE_TX_TIMEOUT, APPROVAL_GAS_LIMIT, ZERO_ALLOWANCE_ASSETS } from './constants'
3
4
 
4
- export { APPROVAL_GAS_LIMIT, ZERO_ALLOWANCE_ASSETS }
5
-
6
5
  export const isZeroAllowanceAsset = (assetName) => ZERO_ALLOWANCE_ASSETS.includes(assetName)
7
6
 
8
7
  export async function getSpendingAllowance({ asset, fromAddress, spenderAddress }) {
@@ -28,94 +27,101 @@ export async function isSpendingApprovalRequired({
28
27
  return tokenAmount.gt(allowance)
29
28
  }
30
29
 
31
- export const createApprove = ({ sendTx }) => async ({
32
- walletAccount,
33
- fromAddress,
34
- spenderAddress,
35
- asset,
36
- feeData,
37
- feeAmount,
38
- approveAmount,
39
- gasLimit,
40
- txInput: preTxInput,
41
- }) => {
42
- const baseAsset = asset.baseAsset
43
- const txInput =
44
- preTxInput ?? asset.contract.approve.build(spenderAddress, approveAmount.toBaseString())
45
-
46
- const toAddress = asset.contract.address
47
- const gasLimitOptions = {
48
- asset: baseAsset,
49
- amount: baseAsset.currency.ZERO,
30
+ export const createApprove =
31
+ ({ sendTx }) =>
32
+ async ({
33
+ walletAccount,
50
34
  fromAddress,
51
- toAddress,
52
- txInput,
35
+ spenderAddress,
36
+ asset,
53
37
  feeData,
54
- isContract: true,
55
- }
56
-
57
- gasLimit = gasLimit || (await fetchGasLimit(gasLimitOptions))
58
-
59
- const txData = await sendTx({
60
- asset: baseAsset.name,
61
- walletAccount,
62
- receiver: {
63
- address: toAddress,
64
- amount: baseAsset.currency.ZERO,
65
- },
66
- txInput,
67
- gasPrice: feeData.gasPrice,
68
- gasLimit,
69
38
  feeAmount,
70
- silent: true,
71
- })
39
+ approveAmount,
40
+ gasLimit,
41
+ txInput: preTxInput,
42
+ }) => {
43
+ const baseAsset = asset.baseAsset
44
+ const txInput =
45
+ preTxInput ?? asset.contract.approve.build(spenderAddress, approveAmount.toBaseString())
46
+
47
+ const toAddress = asset.contract.address
48
+ const gasLimitOptions = {
49
+ asset: baseAsset,
50
+ amount: baseAsset.currency.ZERO,
51
+ fromAddress,
52
+ toAddress,
53
+ txInput,
54
+ feeData,
55
+ isContract: true,
56
+ }
57
+
58
+ gasLimit = gasLimit || (await fetchGasLimit(gasLimitOptions))
59
+
60
+ const txData = await sendTx({
61
+ asset: baseAsset.name,
62
+ walletAccount,
63
+ receiver: {
64
+ address: toAddress,
65
+ amount: baseAsset.currency.ZERO,
66
+ },
67
+ txInput,
68
+ gasPrice: feeData.gasPrice,
69
+ gasLimit,
70
+ feeAmount,
71
+ silent: true,
72
+ })
72
73
 
73
- if (!txData || !txData.txId) {
74
- throw new Error(`Failed to approve ${asset.displayTicker} - ${spenderAddress}`)
75
- }
74
+ if (!txData || !txData.txId) {
75
+ throw new Error(`Failed to approve ${asset.displayTicker} - ${spenderAddress}`)
76
+ }
76
77
 
77
- return txData
78
- }
78
+ return txData
79
+ }
79
80
 
80
- const createSendApprovalAndWatchConfirmation = ({ sendTx, watchTxConfirmation }) => async (
81
- data
82
- ) => {
83
- // To change the approve amount you first have to reduce the addresses`
84
- // allowance to zero by calling `approve(_spender, 0)` if it is not
85
- // already 0 to mitigate the race condition described here:
86
- // see: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
87
- // see: https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code
88
- const approve = createApprove({ sendTx })
89
- const { txId } = await approve(data)
90
- await watchTxConfirmation(
91
- { asset: data.asset.baseAsset.name, walletAccount: data.walletAccount },
92
- txId,
93
- ALLOWANCE_TX_TIMEOUT
94
- )
95
-
96
- return txId
97
- }
81
+ const createSendApprovalAndWatchConfirmation =
82
+ ({ sendTx, watchTxConfirmation }) =>
83
+ async (data) => {
84
+ // To change the approve amount you first have to reduce the addresses`
85
+ // allowance to zero by calling `approve(_spender, 0)` if it is not
86
+ // already 0 to mitigate the race condition described here:
87
+ // see: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
88
+ // see: https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code
89
+ const approve = createApprove({ sendTx })
90
+ const { txId } = await approve(data)
91
+ await watchTxConfirmation(
92
+ { asset: data.asset.baseAsset.name, walletAccount: data.walletAccount },
93
+ txId,
94
+ ALLOWANCE_TX_TIMEOUT
95
+ )
96
+
97
+ return txId
98
+ }
98
99
 
99
- export const createApproveSpendingTokens = ({ sendTx, watchTxConfirmation }) => async (data) => {
100
- const txIds = []
101
- const sendApprovalAndWatchConfirmation = createSendApprovalAndWatchConfirmation({
102
- sendTx,
103
- watchTxConfirmation,
104
- })
105
- if (ZERO_ALLOWANCE_ASSETS.includes(data.asset.name) && !data.approveAmount.isZero) {
106
- const revokeTokenApprovalTxId = await sendApprovalAndWatchConfirmation({
107
- ...data,
108
- txInput: undefined,
109
- approveAmount: data.asset.currency.ZERO,
100
+ export const createApproveSpendingTokens =
101
+ ({ sendTx, watchTxConfirmation }) =>
102
+ async (data) => {
103
+ const txIds = []
104
+ const sendApprovalAndWatchConfirmation = createSendApprovalAndWatchConfirmation({
105
+ sendTx,
106
+ watchTxConfirmation,
110
107
  })
111
-
112
- txIds.push(revokeTokenApprovalTxId)
113
- // Hardcoded min gas limit. Otherwise `fetchGasLimit` will fail since `approve(_spender, 0)` is not yet confirmed
114
- data.gasLimit = Math.max(data.gasLimit || 0, APPROVAL_GAS_LIMIT)
108
+ if (ZERO_ALLOWANCE_ASSETS.includes(data.asset.name) && !data.approveAmount.isZero) {
109
+ const revokeTokenApprovalTxId = await sendApprovalAndWatchConfirmation({
110
+ ...data,
111
+ txInput: undefined,
112
+ approveAmount: data.asset.currency.ZERO,
113
+ })
114
+
115
+ txIds.push(revokeTokenApprovalTxId)
116
+ // Hardcoded min gas limit. Otherwise `fetchGasLimit` will fail since `approve(_spender, 0)` is not yet confirmed
117
+ // eslint-disable-next-line @exodus/mutable/no-param-reassign-prop-only
118
+ data.gasLimit = Math.max(data.gasLimit || 0, APPROVAL_GAS_LIMIT)
119
+ }
120
+
121
+ const tokenApprovalTxId = await sendApprovalAndWatchConfirmation({ ...data, sendTx })
122
+ txIds.push(tokenApprovalTxId)
123
+
124
+ return txIds
115
125
  }
116
126
 
117
- const tokenApprovalTxId = await sendApprovalAndWatchConfirmation({ ...data, sendTx })
118
- txIds.push(tokenApprovalTxId)
119
-
120
- return txIds
121
- }
127
+ export { APPROVAL_GAS_LIMIT, ZERO_ALLOWANCE_ASSETS } from './constants'
@@ -1,4 +1,4 @@
1
- export default {
1
+ const addresses = {
2
2
  ethereum: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
3
3
  // TODO: add other networks if/when available
4
4
  // 'avalanchec': '',
@@ -6,3 +6,5 @@ export default {
6
6
  // 'fantommainnet': '',
7
7
  // 'matic': '',
8
8
  }
9
+
10
+ export default addresses
@@ -3,6 +3,7 @@ import { normalizeTxId, isEthereumLikeAsset, isEthereumLikeToken, ABI } from '@e
3
3
  import { memoizeLruCache } from '@exodus/asset-lib'
4
4
  import SolidityContract from '@exodus/solidity-contract'
5
5
  import { getServerByName, getServer } from './exodus-eth-server'
6
+ import BN from 'bn.js'
6
7
 
7
8
  export async function isContract(baseAssetName, address) {
8
9
  return getServerByName(baseAssetName).isContract(address)
@@ -41,9 +42,9 @@ export async function getBalance({ asset, address }) {
41
42
  // Only base assets, not tokens
42
43
  export async function getBalanceProxied({ asset, address, tag = 'latest' }) {
43
44
  if (!isEthereumLikeAsset(asset)) throw new Error(`unsupported asset ${asset.name}`)
44
- const server = getServer(asset)
45
- const balanceHex = await server.getBalanceProxied(address, tag)
46
- return parseInt(balanceHex, 16)
45
+ const result = await getServer(asset).getBalanceProxied(address)
46
+ const hex = result.startsWith('0x') ? result.slice(2) : result
47
+ return new BN(hex, 'hex').toString()
47
48
  }
48
49
 
49
50
  // Only ETH-like assets with token support
@@ -110,12 +111,12 @@ export const getERC20Params = async ({ asset, address, paramNames = DEFAULT_PARA
110
111
  callResponse = await server.ethCall({ to: address, data: ERC20[method].methodId })
111
112
  } catch (err) {
112
113
  if (err.message === 'execution reverted') {
113
- throw Error(
114
+ throw new Error(
114
115
  `Can't find parameters for contract with address ${address}. Are you sure it is a valid ERC20 contract?`
115
116
  )
116
117
  }
117
118
 
118
- throw Error(err.message)
119
+ throw new Error(err.message)
119
120
  }
120
121
 
121
122
  if (method === 'decimals') return parseInt(callResponse)
@@ -8,7 +8,7 @@ const _request = async (...args) => request(isValidResponseCheck, 'account', ...
8
8
  export async function fetchBalance(address) {
9
9
  const balance = await _request('balance', { address })
10
10
 
11
- const isValid = /^[0-9]+$/.test(balance)
11
+ const isValid = /^\d+$/.test(balance)
12
12
  if (!isValid) throw new RangeError(`Invalid balance: ${balance}`)
13
13
 
14
14
  return balance
@@ -42,7 +42,7 @@ export async function tokenBalance(token, address) {
42
42
  }
43
43
  const balance = await _request('tokenbalance', params)
44
44
 
45
- const isValid = /^[0-9]+$/.test(balance)
45
+ const isValid = /^\d+$/.test(balance)
46
46
  if (!isValid) throw new RangeError(`Invalid balance: ${balance}`)
47
47
 
48
48
  return balance
@@ -1,44 +1,9 @@
1
- import {
2
- fetchBalance as _fetchBalance,
3
- fetchTxlist as _fetchTxlist,
4
- fetchTxlistinternal as _fetchTxlistinternal,
5
- tokenBalance as _tokenBalance,
6
- } from './account'
7
- import {
8
- sendRawTransaction as _sendRawTransaction,
9
- getTransactionCount as _getTransactionCount,
10
- getTransactionReceipt as _getTransactionReceipt,
11
- estimateGas as _estimateGas,
12
- getCode as _getCode,
13
- gasPrice as _gasPrice,
14
- ethCall as _ethCall,
15
- } from './proxy'
16
- import { setEtherscanApiKey } from './request'
17
- import { getLogs as _getLogs } from './logs'
18
1
  import createWebSocket from './ws'
19
2
 
20
3
  export const ETHERSCAN_WS_URL = 'wss://socket.etherscan.io/wshandler'
21
4
 
22
- export const fetchBalance = _fetchBalance
23
- export const fetchTxlist = _fetchTxlist
24
- export const fetchTxlistinternal = _fetchTxlistinternal
25
- export const tokenBalance = _tokenBalance
26
-
27
- export const sendRawTransaction = _sendRawTransaction
28
- export const getTransactionCount = _getTransactionCount
29
- export const getTransactionReceipt = _getTransactionReceipt
30
- export const estimateGas = _estimateGas
31
- export const getCode = _getCode
32
- export const gasPrice = _gasPrice
33
-
34
- export const getLogs = _getLogs
35
-
36
- export const setApiKey = setEtherscanApiKey
37
-
38
5
  export const ws = createWebSocket(ETHERSCAN_WS_URL)
39
6
 
40
- export const ethCall = _ethCall
41
-
42
7
  export function filterTxsSent(addr, etherscanTxs) {
43
8
  return etherscanTxs.filter((tx) => tx.from.toLowerCase() === addr.toLowerCase())
44
9
  }
@@ -46,3 +11,18 @@ export function filterTxsSent(addr, etherscanTxs) {
46
11
  export function filterTxsReceived(addr, etherscanTxs) {
47
12
  return etherscanTxs.filter((tx) => tx.to.toLowerCase() === addr.toLowerCase())
48
13
  }
14
+
15
+ export { fetchBalance, fetchTxlistinternal, fetchTxlist, tokenBalance } from './account'
16
+ export {
17
+ sendRawTransaction,
18
+ getTransactionCount,
19
+ estimateGas,
20
+ getTransactionReceipt,
21
+ getCode,
22
+ ethCall,
23
+ gasPrice,
24
+ } from './proxy'
25
+
26
+ export { setEtherscanApiKey as setApiKey } from './request'
27
+
28
+ export { getLogs } from './logs'
@@ -6,7 +6,7 @@ const _request = async (...args) => request(isValidResponseCheck, 'proxy', ...ar
6
6
  export async function sendRawTransaction(data) {
7
7
  const txhash = await _request('eth_sendRawTransaction', { hex: '0x' + data })
8
8
 
9
- const isValidTxHash = /^0x[0-9a-fA-F]{64}$/.test(txhash)
9
+ const isValidTxHash = /^0x[\dA-Fa-f]{64}$/.test(txhash)
10
10
  if (!isValidTxHash) throw new Error(`Invalid tx hash: ${txhash}`)
11
11
 
12
12
  return txhash.slice(2)
@@ -27,7 +27,7 @@ export async function estimateGas(data) {
27
27
  export async function getCode(address) {
28
28
  const code = await _request('eth_getCode', { address })
29
29
 
30
- const isValidCode = /^0x[0-9a-fA-F]*$/.test(code) && code.length % 2 === 0
30
+ const isValidCode = /^0x[\dA-Fa-f]*$/.test(code) && code.length % 2 === 0
31
31
  if (!isValidCode) throw new Error(`Invalid address code: ${code}`)
32
32
 
33
33
  return code
@@ -36,7 +36,7 @@ export async function getCode(address) {
36
36
  export async function gasPrice() {
37
37
  const price = await _request('eth_gasPrice')
38
38
 
39
- const isValidPrice = /^0x[0-9a-fA-F]+$/.test(price)
39
+ const isValidPrice = /^0x[\dA-Fa-f]+$/.test(price)
40
40
  if (!isValidPrice) throw new Error(`Invalid price: ${price}`)
41
41
 
42
42
  return price
@@ -12,7 +12,7 @@ export function setEtherscanApiKey(apiKey) {
12
12
  }
13
13
 
14
14
  export default makeConcurrent(
15
- async function(isValidResponseCheck, module, action, params = {}) {
15
+ async function (isValidResponseCheck, module, action, params = {}) {
16
16
  const data = await fetchival(new URL(ETHERSCAN_API_URL), { timeout: ms('15s') }).get({
17
17
  ...params,
18
18
  module,
@@ -28,7 +28,7 @@ export default function createWebSocket(url) {
28
28
  break
29
29
 
30
30
  case 'subscribe-txlist':
31
- const match = data.message.toLowerCase().match(/0x[0-9a-f]{40}/)
31
+ const match = data.message.toLowerCase().match(/0x[\da-f]{40}/)
32
32
  if (match && data.status === '1') events.emit(`address-${match[0]}-subscribed`)
33
33
  else ws.close()
34
34
  break
@@ -49,7 +49,7 @@ export default function createWebSocket(url) {
49
49
  ws.on('message', (data) => {
50
50
  try {
51
51
  onMessage(data)
52
- } catch (err) {}
52
+ } catch {}
53
53
  })
54
54
  ws.once('open', () => {
55
55
  for (const address of addresses.values()) subscribeAddress(address)
@@ -3,6 +3,7 @@ import { bufferToHex } from '@exodus/ethereumjs-util'
3
3
  import SolidityContract from '@exodus/solidity-contract'
4
4
  import EventEmitter from 'events'
5
5
  import { isEmpty } from 'lodash'
6
+ import { fetch } from '@exodus/fetch'
6
7
 
7
8
  export default class ApiCoinNodesServer extends EventEmitter {
8
9
  constructor({ uri }) {
@@ -23,9 +24,7 @@ export default class ApiCoinNodesServer extends EventEmitter {
23
24
  }
24
25
 
25
26
  const response = await fetch(this.uri, options)
26
- const data = await response.json()
27
-
28
- return data
27
+ return response.json()
29
28
  }
30
29
 
31
30
  async sendBatchRequest(batch) {
@@ -37,6 +36,7 @@ export default class ApiCoinNodesServer extends EventEmitter {
37
36
  if (responses.length !== batch.length || !isValid) {
38
37
  throw new Error('Bad rpc batch response')
39
38
  }
39
+
40
40
  const keyed = responses.reduce((acc, response) => {
41
41
  return { ...acc, [`${response.id}`]: response.result }
42
42
  }, Object.create(null))
@@ -52,6 +52,7 @@ export default class ApiCoinNodesServer extends EventEmitter {
52
52
  const message = error?.message || error?.code || 'no result'
53
53
  throw new Error(`Bad rpc response: ${message}`)
54
54
  }
55
+
55
56
  return result
56
57
  }
57
58
 
@@ -34,7 +34,8 @@ export function create(defaultURL, ensAssetName) {
34
34
  const data = await err.response.json()
35
35
  const msg = data.error.replace(/^RPC error \(code: -\d+\): /, '')
36
36
  nerr = new Error(msg)
37
- } catch (err) {}
37
+ } catch {}
38
+
38
39
  nerr.finalError = true
39
40
  }
40
41
 
@@ -45,7 +46,7 @@ export function create(defaultURL, ensAssetName) {
45
46
  // Default retry function
46
47
  const requestWithRetry = retry(request, { delayTimesMs: RETRY_DELAYS })
47
48
 
48
- const api = {
49
+ return {
49
50
  getURL() {
50
51
  return API_URL
51
52
  },
@@ -243,13 +244,14 @@ export function create(defaultURL, ensAssetName) {
243
244
  },
244
245
 
245
246
  async proxyToCoinNode(requestData) {
247
+ // eslint-disable-next-line @exodus/mutable/no-param-reassign-prop-only
246
248
  if (!requestData.jsonrpc) requestData.jsonrpc = '2.0'
249
+ // eslint-disable-next-line @exodus/mutable/no-param-reassign-prop-only
247
250
  if (!requestData.id) requestData.id = randomUUID()
251
+ // eslint-disable-next-line @exodus/mutable/no-param-reassign-prop-only
248
252
  if (!requestData.params) requestData.params = []
249
253
 
250
254
  return request('proxy', requestData, { version: 'v2', method: 'post' })
251
255
  },
252
256
  }
253
-
254
- return api
255
257
  }
@@ -27,6 +27,7 @@ export default class ClarityServer extends EventEmitter {
27
27
  this.emit('transaction', { walletAccount, isPending, transaction })
28
28
  })
29
29
  }
30
+
30
31
  return this.sockets[namespace]
31
32
  }
32
33
 
@@ -35,6 +36,7 @@ export default class ClarityServer extends EventEmitter {
35
36
  if (!this.sockets[namespace]) {
36
37
  this.sockets[namespace] = this.createSocket(namespace)
37
38
  }
39
+
38
40
  return this.sockets[namespace]
39
41
  }
40
42
 
@@ -44,6 +46,7 @@ export default class ClarityServer extends EventEmitter {
44
46
  this.sockets[namespace] = this.createSocket(namespace)
45
47
  this.sockets[namespace].on('feeUpdated', (fee) => this.emit('feeUpdated', fee))
46
48
  }
49
+
47
50
  return this.sockets[namespace]
48
51
  }
49
52
 
@@ -103,9 +106,10 @@ export default class ClarityServer extends EventEmitter {
103
106
  onChunk(isPending, chunk)
104
107
  callback()
105
108
  }
109
+
106
110
  socket.on('transactionsChunk', listener)
107
111
  return new Promise((resolve, reject) => {
108
- const timeout = setTimeout(() => reject(new Error('Transactions Timeout')), 300000)
112
+ const timeout = setTimeout(() => reject(new Error('Transactions Timeout')), 300_000)
109
113
  socket.emit('getTransactions', cursor, (nextCursor) => {
110
114
  clearTimeout(timeout)
111
115
  const uintArray = new Uint8Array(nextCursor)
@@ -119,13 +123,14 @@ export default class ClarityServer extends EventEmitter {
119
123
  async getFee() {
120
124
  const socket = this.connectFee()
121
125
  return new Promise((resolve, reject) => {
122
- const timeout = setTimeout(() => reject(new Error('Fee Timeout')), 30000)
126
+ const timeout = setTimeout(() => reject(new Error('Fee Timeout')), 30_000)
123
127
  socket.emit('getFee', (fee) => {
124
128
  clearTimeout(timeout)
125
129
  if (!fee) {
126
130
  const error = new Error('Unable to get fee')
127
131
  return reject(error)
128
132
  }
133
+
129
134
  resolve(fee)
130
135
  })
131
136
  })
@@ -140,7 +145,7 @@ export default class ClarityServer extends EventEmitter {
140
145
  async sendRpcRequest(rpcRequest) {
141
146
  const rpcSocket = this.connectRpc()
142
147
  return new Promise((resolve, reject) => {
143
- const timeout = setTimeout(() => reject(new Error('Rpc Timeout')), 30000)
148
+ const timeout = setTimeout(() => reject(new Error('Rpc Timeout')), 30_000)
144
149
  rpcSocket.emit('request', rpcRequest, (response) => {
145
150
  clearTimeout(timeout)
146
151
  resolve(response)
@@ -157,6 +162,7 @@ export default class ClarityServer extends EventEmitter {
157
162
  if (responses.length !== batch.length || !isValid) {
158
163
  throw new Error('Bad Response')
159
164
  }
165
+
160
166
  const keyed = responses.reduce((acc, response) => {
161
167
  return { ...acc, [`${response.id}`]: response.result }
162
168
  }, Object.create(null))
@@ -171,6 +177,7 @@ export default class ClarityServer extends EventEmitter {
171
177
  const message = error?.message || error?.code || 'no result'
172
178
  throw new Error(`Bad rpc response: ${message}`)
173
179
  }
180
+
174
181
  return result
175
182
  }
176
183
 
@@ -48,12 +48,16 @@ export default function createWebSocket(getURL) {
48
48
  if (ws) return
49
49
 
50
50
  ws = new WebSocket(getURL())
51
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
51
52
  ws.onerror = (e) => {}
53
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
52
54
  ws.onmessage = (e) => {
53
55
  try {
54
56
  onMessage(e.data)
55
- } catch (err) {}
57
+ } catch {}
56
58
  }
59
+
60
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
57
61
  ws.onopen = () => {
58
62
  for (const address of addresses.values()) subscribeAddress(address)
59
63
  subscribeGasPrice()
@@ -62,9 +66,12 @@ export default function createWebSocket(getURL) {
62
66
  } else {
63
67
  console.warn('Client side ping not available')
64
68
  }
69
+
65
70
  isWSOpened = true
66
71
  events.emit('open')
67
72
  }
73
+
74
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
68
75
  ws.onclose = () => {
69
76
  ws = null
70
77
  isWSOpened = false
@@ -72,6 +79,7 @@ export default function createWebSocket(getURL) {
72
79
  if (opened) {
73
80
  openTimeoutId = setTimeout(open, reconnectDelay())
74
81
  }
82
+
75
83
  events.emit('close')
76
84
  }
77
85
  }
@@ -81,9 +89,13 @@ export default function createWebSocket(getURL) {
81
89
  isWSOpened = false
82
90
  clearTimeout(openTimeoutId)
83
91
  if (!ws) return
92
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
84
93
  ws.onerror = null
94
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
85
95
  ws.onmessage = null
96
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
86
97
  ws.onopen = null
98
+ // eslint-disable-next-line unicorn/prefer-add-event-listener
87
99
  ws.onclose = null
88
100
  try {
89
101
  ws.close()
@@ -9,7 +9,10 @@ export class EthereumArbnovaFeeMonitor extends EthereumLikeFeeMonitor {
9
9
  super({
10
10
  updateFee,
11
11
  assetName,
12
- getGasPrice: async () => (await getServerByName(assetName).getFee())?.gasPrice,
12
+ getGasPrice: async () => {
13
+ const fee = await getServerByName(assetName).getFee()
14
+ return fee?.gasPrice
15
+ },
13
16
  interval,
14
17
  })
15
18
  }
@@ -9,7 +9,10 @@ export class EthereumArboneFeeMonitor extends EthereumLikeFeeMonitor {
9
9
  super({
10
10
  updateFee,
11
11
  assetName,
12
- getGasPrice: async () => (await getServerByName(assetName).getFee())?.gasPrice,
12
+ getGasPrice: async () => {
13
+ const fee = await getServerByName(assetName).getFee()
14
+ return fee?.gasPrice
15
+ },
13
16
  interval,
14
17
  })
15
18
  }