@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
@@ -0,0 +1,18 @@
1
+ import { EthereumLikeFeeMonitor } from '@exodus/ethereum-lib'
2
+ import { getServerByName } from '../exodus-eth-server'
3
+
4
+ const assetName = 'ethereumsepolia'
5
+
6
+ // @deprecated use ./server-based-fee-monitor.js
7
+ export class EthereumSepoliaFeeMonitor extends EthereumLikeFeeMonitor {
8
+ constructor({ updateFee, interval }) {
9
+ const server = getServerByName(assetName)
10
+ const getGasPrice = (...args) => server.gasPrice(...args)
11
+ super({
12
+ updateFee,
13
+ assetName,
14
+ getGasPrice,
15
+ interval,
16
+ })
17
+ }
18
+ }
@@ -4,6 +4,7 @@ export * from './ethereum'
4
4
  export * from './ethereumclassic'
5
5
  export * from './ethereumgoerli'
6
6
  export * from './ethereumholesky'
7
+ export * from './ethereumsepolia'
7
8
  export * from './bsc'
8
9
  export * from './polygon'
9
10
  export * from './avalanchec'
@@ -9,7 +9,10 @@ export class OptimismFeeMonitor 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
  }
@@ -51,9 +51,10 @@ export async function fetchGasLimit({
51
51
  extraPercentage,
52
52
  }) {
53
53
  if (bip70?.bitpay?.data && bip70?.bitpay?.gasPrice)
54
- return asset.name === 'ethereum' ? 65000 : 130000 // from on chain stats https://dune.xyz/queries/189123
54
+ return asset.name === 'ethereum' ? 65_000 : 130_000 // from on chain stats https://dune.xyz/queries/189123
55
55
 
56
56
  if (!amount) amount = asset.currency.ZERO
57
+ // eslint-disable-next-line @exodus/mutable/no-param-reassign-prop-only
57
58
  if (!feeData.gasPrice) feeData.gasPrice = asset.baseAsset.currency.ZERO
58
59
 
59
60
  const defaultGasLimit = () =>
@@ -67,6 +68,7 @@ export async function fetchGasLimit({
67
68
  asset.contract.transfer.build(toAddress.toLowerCase(), amount.toBaseString())
68
69
  )
69
70
  }
71
+
70
72
  amount = asset.baseAsset.currency.ZERO
71
73
  toAddress = asset.contract.address
72
74
  } else if (!isContract && !['ethereumarbone', 'ethereumarbnova'].includes(asset.name)) {
@@ -13,6 +13,7 @@ const fixBalance = ({ txLog, balance }) => {
13
13
  }
14
14
  }
15
15
  }
16
+
16
17
  return balance
17
18
  }
18
19
 
@@ -36,7 +37,7 @@ const getBalance = ({ asset, accountState, txLog }) => {
36
37
 
37
38
  const shouldFixBalance = isRpcBalanceAsset(asset)
38
39
 
39
- if (['ethereum', 'ethereumgoerli', 'ethereumholesky'].includes(asset.name)) {
40
+ if (['ethereum', 'ethereumgoerli', 'ethereumholesky', 'ethereumsepolia'].includes(asset.name)) {
40
41
  const { balance: ethereumBalance } = getEthereumBalances({
41
42
  asset,
42
43
  liquidBalance: balance,
@@ -141,8 +141,8 @@ async function tryToDecodeApprovalTransaction(transaction, asset) {
141
141
 
142
142
  const [grantedTo, balance] = decodedInput.values
143
143
 
144
- const symbol =
145
- (await getAssetSymbolFromContract(transaction.to, asset))?.toUpperCase() || 'Unknown Token'
144
+ const symbolFromContract = await getAssetSymbolFromContract(transaction.to, asset)
145
+ const symbol = symbolFromContract?.toUpperCase() || 'Unknown Token'
146
146
 
147
147
  return [{ grantedTo, balance, symbol, decimals: undefined }] // ToDo: Return 'decimals' in the future once we support changing the approval amount.
148
148
  } catch (e) {
@@ -215,12 +215,13 @@ export async function retrieveSideEffects({ transaction, asset, shouldSimulate =
215
215
  title: `${assetData.title || assetData.symbol} #${delta}`,
216
216
  }
217
217
  }
218
+
218
219
  willReceive.push(account)
219
220
  }
220
221
  }
221
222
  }
222
223
 
223
- if (!willSend.length) {
224
+ if (willSend.length === 0) {
224
225
  willSend.push({
225
226
  symbol: 'ETH',
226
227
  balance: `-${ethHexToInt(transaction.value)}`,
@@ -21,6 +21,7 @@ export class EthereumStaking {
21
21
  EVERSTAKE_ADDRESS_CONTRACT_POOL: '0xAFA848357154a6a624686b348303EF9a13F63264',
22
22
  },
23
23
  }
24
+
24
25
  static METHODS_IDS = {
25
26
  DELEGATE: '0x3a29dbae', // stake(uint256 source)
26
27
  UNSTAKE: '0x76ec871c', // unstake(uint256 amount)
@@ -45,8 +46,7 @@ export class EthereumStaking {
45
46
  }
46
47
 
47
48
  buildTxData = (contract, method, ...args) => {
48
- const txData = contract[method].build(...args)
49
- return txData
49
+ return contract[method].build(...args)
50
50
  }
51
51
 
52
52
  callReadFunctionContract = (contract, method, ...args) => {
@@ -152,9 +152,9 @@ export class EthereumStaking {
152
152
  amount,
153
153
  data: bufferToHex(this.buildTxData(this.contractPool, 'stake', source)), // tx data field
154
154
  }
155
- } else {
156
- throw new Error(`Min Amount ${this.minAmount}`)
157
155
  }
156
+
157
+ throw new Error(`Min Amount ${this.minAmount}`)
158
158
  }
159
159
 
160
160
  /* Unstake funds that are staked into the validator. Once unstaked they need to be claimed (once ready to withdraw) */
@@ -170,9 +170,9 @@ export class EthereumStaking {
170
170
  this.buildTxData(this.contractPool, 'unstake', amountWei, allowedInterchangeNum, source)
171
171
  ),
172
172
  }
173
- } else {
174
- throw new Error(`Max Amount for unstake ${balance}`)
175
173
  }
174
+
175
+ throw new Error(`Max Amount for unstake ${balance}`)
176
176
  }
177
177
 
178
178
  /** Claim funds requested by unstake (in withdraw state) */
@@ -185,9 +185,9 @@ export class EthereumStaking {
185
185
  amount: this.asset.currency.ZERO,
186
186
  data: bufferToHex(this.buildTxData(this.contractAccounting, 'claimWithdrawRequest')),
187
187
  }
188
- } else {
189
- return null // no amount to withdraw
190
188
  }
189
+
190
+ return null // no amount to withdraw
191
191
  } catch (error) {
192
192
  throw new Error(error)
193
193
  }
@@ -5,28 +5,27 @@ import BN from 'bn.js'
5
5
  import { stakingProviderClientFactory } from '../staking-provider-client'
6
6
  import { EthereumStaking } from './api'
7
7
 
8
- const extraGasLimit = 20000 // extra gas Limit to prevent tx failing if something change on pool state (till tx is in mempool)
8
+ const extraGasLimit = 20_000 // extra gas Limit to prevent tx failing if something change on pool state (till tx is in mempool)
9
9
 
10
10
  export function createEthereumStakingService({
11
11
  asset,
12
12
  assetClientInterface,
13
13
  createAndBroadcastTX,
14
- telemetryId,
14
+ getTelemetryId,
15
15
  }) {
16
16
  const staking = new EthereumStaking(asset)
17
- const stakingProvider = stakingProviderClientFactory({ telemetryId })
17
+ const stakingProvider = stakingProviderClientFactory({ getTelemetryId })
18
18
 
19
19
  function amountToCurrency({ asset, amount }) {
20
20
  return isNumberUnit(amount) ? amount : asset.currency.parse(amount)
21
21
  }
22
22
 
23
23
  async function delegate({ walletAccount, amount } = {}) {
24
- const delegatorAddress = (
25
- await assetClientInterface.getReceiveAddress({
26
- assetName: asset.name,
27
- walletAccount,
28
- })
29
- ).toLowerCase()
24
+ const address = await assetClientInterface.getReceiveAddress({
25
+ assetName: asset.name,
26
+ walletAccount,
27
+ })
28
+ const delegatorAddress = address.toLowerCase()
30
29
  amount = amountToCurrency({ asset, amount })
31
30
 
32
31
  const { to, data } = await staking.stake({
@@ -71,12 +70,11 @@ export function createEthereumStakingService({
71
70
  */
72
71
  amount = amountToCurrency({ asset, amount })
73
72
 
74
- const delegatorAddress = (
75
- await assetClientInterface.getReceiveAddress({
76
- assetName: asset.name,
77
- walletAccount,
78
- })
79
- ).toLowerCase()
73
+ const address = await assetClientInterface.getReceiveAddress({
74
+ assetName: asset.name,
75
+ walletAccount,
76
+ })
77
+ const delegatorAddress = address.toLowerCase()
80
78
 
81
79
  const pendingAmount = await staking.pendingBalanceOf(delegatorAddress)
82
80
 
@@ -102,7 +100,7 @@ export function createEthereumStakingService({
102
100
  amount: inactiveAmountToUnstake,
103
101
  })
104
102
 
105
- let { gasPrice, gasLimit, fee } = await estimateTxFee(
103
+ const { gasPrice, gasLimit, fee } = await estimateTxFee(
106
104
  delegatorAddress.toLowerCase(),
107
105
  to,
108
106
  null,
@@ -111,7 +109,7 @@ export function createEthereumStakingService({
111
109
  txId = await prepareAndSendTx({
112
110
  asset,
113
111
  walletAccount,
114
- to: to,
112
+ to,
115
113
  txData: data,
116
114
  gasPrice,
117
115
  gasLimit,
@@ -127,7 +125,7 @@ export function createEthereumStakingService({
127
125
  amount: activeAmountToUnstake,
128
126
  })
129
127
 
130
- let { gasPrice, gasLimit, fee } = await estimateTxFee(delegatorAddress, to, null, data)
128
+ const { gasPrice, gasLimit, fee } = await estimateTxFee(delegatorAddress, to, null, data)
131
129
  txId = await prepareAndSendTx({
132
130
  asset,
133
131
  walletAccount,
@@ -153,39 +151,38 @@ export function createEthereumStakingService({
153
151
 
154
152
  async function claimUndelegatedBalance({ walletAccount } = {}) {
155
153
  // withdraw withdrawable balance (of a previous unstake)
156
- const delegatorAddress = (
157
- await assetClientInterface.getReceiveAddress({
158
- assetName: asset.name,
159
- walletAccount,
160
- })
161
- ).toLowerCase()
154
+ const address = await assetClientInterface.getReceiveAddress({
155
+ assetName: asset.name,
156
+ walletAccount,
157
+ })
158
+ const delegatorAddress = address.toLowerCase()
162
159
 
163
160
  const withdrawRequest = await staking.claimWithdrawRequest({
164
161
  address: delegatorAddress,
165
162
  })
166
163
  if (withdrawRequest) {
167
164
  const { to, data } = withdrawRequest
168
- let { gasPrice, gasLimit, fee } = await estimateTxFee(delegatorAddress, to, null, data)
169
- const txId = await prepareAndSendTx({
165
+ const { gasPrice, gasLimit, fee } = await estimateTxFee(delegatorAddress, to, null, data)
166
+ return prepareAndSendTx({
170
167
  asset,
171
168
  walletAccount,
172
- to: to,
169
+ to,
173
170
  txData: data,
174
171
  gasPrice,
175
172
  gasLimit,
176
173
  fee,
177
174
  })
178
- return txId
179
- } else return null // -> no withdrawable balance
175
+ }
176
+
177
+ return null // -> no withdrawable balance
180
178
  }
181
179
 
182
180
  async function estimateDelegateOperation({ walletAccount, operation, args }) {
183
- const delegatorAddress = (
184
- await assetClientInterface.getReceiveAddress({
185
- assetName: asset.name,
186
- walletAccount,
187
- })
188
- ).toLowerCase()
181
+ const address = await assetClientInterface.getReceiveAddress({
182
+ assetName: asset.name,
183
+ walletAccount,
184
+ })
185
+ const delegatorAddress = address.toLowerCase()
189
186
 
190
187
  const NAMING_MAP = {
191
188
  delegate: 'stake',
@@ -198,6 +195,7 @@ export function createEthereumStakingService({
198
195
  return
199
196
  }
200
197
 
198
+ // eslint-disable-next-line @exodus/mutable/no-param-reassign-prop-only
201
199
  if (args.amount) args.amount = amountToCurrency({ asset, amount: args.amount })
202
200
 
203
201
  let amount, data, fee
@@ -2,18 +2,16 @@ import { EthereumStaking } from './api'
2
2
 
3
3
  const { DELEGATE, UNSTAKE, UNSTAKE_PENDING, CLAIM_UNSTAKE } = EthereumStaking.METHODS_IDS
4
4
 
5
- const STAKING_MANAGER_CONTRACTS = [
5
+ const STAKING_MANAGER_CONTRACTS = new Set([
6
6
  EthereumStaking.addresses.ethereum.EVERSTAKE_ADDRESS_CONTRACT_POOL.toLowerCase(),
7
7
  EthereumStaking.addresses.ethereumgoerli.EVERSTAKE_ADDRESS_CONTRACT_POOL.toLowerCase(),
8
8
  EthereumStaking.addresses.ethereumholesky.EVERSTAKE_ADDRESS_CONTRACT_POOL.toLowerCase(),
9
- ]
9
+ ])
10
10
 
11
11
  export const isEthereumStakingTx = ({ coinName }) =>
12
12
  ['ethereum', 'ethereumgoerli', 'ethereumholesky'].includes(coinName)
13
13
  export const isEthereumDelegate = (tx) =>
14
- isEthereumStakingTx(tx) &&
15
- STAKING_MANAGER_CONTRACTS.includes(tx.to) &&
16
- tx.data?.methodId === DELEGATE
14
+ isEthereumStakingTx(tx) && STAKING_MANAGER_CONTRACTS.has(tx.to) && tx.data?.methodId === DELEGATE
17
15
  export const isEthereumUndelegatePending = (tx) =>
18
16
  isEthereumStakingTx(tx) && tx.data?.methodId === UNSTAKE_PENDING
19
17
  export const isEthereumUndelegate = (tx) =>
@@ -105,10 +105,10 @@ export class FantomStaking {
105
105
 
106
106
  #validateDuration = (duration) => {
107
107
  if (!Number.isInteger(duration)) {
108
- throw new Error('The lock duration must be an integer.')
108
+ throw new TypeError('The lock duration must be an integer.')
109
109
  }
110
110
 
111
- if (duration > 365 * 86400) {
111
+ if (duration > 365 * 86_400) {
112
112
  throw new Error('The lock duration must be at most 365 days.')
113
113
  }
114
114
  }
@@ -25,8 +25,7 @@ export class MaticStakingApi {
25
25
  }
26
26
 
27
27
  buildTxData = (contract, method, ...args) => {
28
- const txData = contract[method].build(...args)
29
- return txData
28
+ return contract[method].build(...args)
30
29
  }
31
30
 
32
31
  callReadFunctionContract = (contract, method, ...args) => {
@@ -183,7 +182,7 @@ export class MaticStakingApi {
183
182
 
184
183
  // see arguments encoding standard (padded 32 bytes)
185
184
  // https://docs.soliditylang.org/en/v0.8.15/abi-spec.html?highlight=abi.encode#function-selector-and-argument-encoding
186
- const splitIn32BytesArray = (output) => removeHexPrefix(output).match(/[0-9a-f]{1,64}/gi) || []
185
+ const splitIn32BytesArray = (output) => removeHexPrefix(output).match(/[\da-f]{1,64}/gi) || []
187
186
 
188
187
  const toBN = (str) => new BN(removeLeadingZeroes(removeHexPrefix(str)), 16)
189
188
 
@@ -8,11 +8,11 @@ import { isNumberUnit } from '@exodus/currency'
8
8
  export function createPolygonStakingService({
9
9
  assetClientInterface,
10
10
  createAndBroadcastTX,
11
- telemetryId,
11
+ getTelemetryId,
12
12
  }) {
13
13
  const stakingApi = new MaticStakingApi()
14
14
  const assetName = 'ethereum'
15
- const stakingProvider = stakingProviderClientFactory({ telemetryId })
15
+ const stakingProvider = stakingProviderClientFactory({ getTelemetryId })
16
16
 
17
17
  async function getStakeAssets() {
18
18
  const { polygon: asset, ethereum: feeAsset } = await assetClientInterface.getAssetsForNetwork({
@@ -26,12 +26,11 @@ export function createPolygonStakingService({
26
26
  }
27
27
 
28
28
  async function delegate({ walletAccount, amount } = {}) {
29
- const delegatorAddress = (
30
- await assetClientInterface.getReceiveAddress({
31
- assetName,
32
- walletAccount,
33
- })
34
- ).toLowerCase()
29
+ const address = await assetClientInterface.getReceiveAddress({
30
+ assetName,
31
+ walletAccount,
32
+ })
33
+ const delegatorAddress = address.toLowerCase()
35
34
 
36
35
  const { asset } = await getStakeAssets()
37
36
  amount = amountToCurrency({ asset, amount })
@@ -79,23 +78,22 @@ export function createPolygonStakingService({
79
78
  }
80
79
 
81
80
  async function undelegate({ walletAccount, amount } = {}) {
82
- const delegatorAddress = (
83
- await assetClientInterface.getReceiveAddress({
84
- assetName,
85
- walletAccount,
86
- })
87
- ).toLowerCase()
81
+ const address = await assetClientInterface.getReceiveAddress({
82
+ assetName,
83
+ walletAccount,
84
+ })
85
+ const delegatorAddress = address.toLowerCase()
88
86
 
89
87
  const { asset } = await getStakeAssets()
90
88
  amount = amountToCurrency({ asset, amount })
91
89
 
92
90
  const txUndelegateData = await stakingApi.undelegate({ amount })
93
- let { gasPrice, gasLimit, fee } = await estimateTxFee(
91
+ const { gasPrice, gasLimit, fee } = await estimateTxFee(
94
92
  delegatorAddress.toLowerCase(),
95
93
  stakingApi.validatorShareContract.address,
96
94
  txUndelegateData
97
95
  )
98
- const txId = await prepareAndSendTx({
96
+ return prepareAndSendTx({
99
97
  walletAccount,
100
98
  to: stakingApi.validatorShareContract.address,
101
99
  txData: txUndelegateData,
@@ -103,25 +101,22 @@ export function createPolygonStakingService({
103
101
  gasLimit,
104
102
  fee,
105
103
  })
106
-
107
- return txId
108
104
  }
109
105
 
110
106
  async function claimRewards({ walletAccount } = {}) {
111
- const delegatorAddress = (
112
- await assetClientInterface.getReceiveAddress({
113
- assetName,
114
- walletAccount,
115
- })
116
- ).toLowerCase()
107
+ const address = await assetClientInterface.getReceiveAddress({
108
+ assetName,
109
+ walletAccount,
110
+ })
111
+ const delegatorAddress = address.toLowerCase()
117
112
 
118
113
  const txWithdrawRewardsData = await stakingApi.withdrawRewards()
119
- let { gasPrice, gasLimit, fee } = await estimateTxFee(
114
+ const { gasPrice, gasLimit, fee } = await estimateTxFee(
120
115
  delegatorAddress,
121
116
  stakingApi.validatorShareContract.address,
122
117
  txWithdrawRewardsData
123
118
  )
124
- const txId = await prepareAndSendTx({
119
+ return prepareAndSendTx({
125
120
  walletAccount,
126
121
  to: stakingApi.validatorShareContract.address,
127
122
  txData: txWithdrawRewardsData,
@@ -129,17 +124,14 @@ export function createPolygonStakingService({
129
124
  gasLimit,
130
125
  fee,
131
126
  })
132
-
133
- return txId
134
127
  }
135
128
 
136
129
  async function claimUndelegatedBalance({ walletAccount, unbondNonce } = {}) {
137
- const delegatorAddress = (
138
- await assetClientInterface.getReceiveAddress({
139
- assetName,
140
- walletAccount,
141
- })
142
- ).toLowerCase()
130
+ const address = await assetClientInterface.getReceiveAddress({
131
+ assetName,
132
+ walletAccount,
133
+ })
134
+ const delegatorAddress = address.toLowerCase()
143
135
 
144
136
  const { asset } = await getStakeAssets()
145
137
  const { currency } = asset
@@ -156,7 +148,7 @@ export function createPolygonStakingService({
156
148
  })
157
149
 
158
150
  const txClaimUndelegatedData = await stakingApi.claimUndelegatedBalance({ unbondNonce })
159
- let { gasPrice, gasLimit, fee } = await estimateTxFee(
151
+ const { gasPrice, gasLimit, fee } = await estimateTxFee(
160
152
  delegatorAddress,
161
153
  stakingApi.validatorShareContract.address,
162
154
  txClaimUndelegatedData
@@ -186,12 +178,12 @@ export function createPolygonStakingService({
186
178
  if (!delegateOperation) {
187
179
  return
188
180
  }
189
- const delegatorAddress = (
190
- await assetClientInterface.getReceiveAddress({
191
- assetName,
192
- walletAccount,
193
- })
194
- ).toLowerCase()
181
+
182
+ const address = await assetClientInterface.getReceiveAddress({
183
+ assetName,
184
+ walletAccount,
185
+ })
186
+ const delegatorAddress = address.toLowerCase()
195
187
 
196
188
  const { amount } = args
197
189
  if (amount) {
@@ -225,7 +217,7 @@ export function createPolygonStakingService({
225
217
  baseAssetName: 'ethereum',
226
218
  })
227
219
  const erc20ApproveGas = 4900
228
- const delegateGas = 240000
220
+ const delegateGas = 240_000
229
221
  const gasPrice = parseInt(await getServer(ethereum).gasPrice(), 16)
230
222
  const extraPercentage = 20
231
223
 
@@ -7,7 +7,7 @@ const HTTP_POST_TIMEOUT = ms('30s')
7
7
 
8
8
  export const stakingProviderClientFactory = ({
9
9
  defaultStakingUrl = DEFAULT_STAKING_URL,
10
- telemetryId,
10
+ getTelemetryId,
11
11
  } = {}) => {
12
12
  assert(defaultStakingUrl, '"defaultStakingUrl" must be provided')
13
13
 
@@ -22,9 +22,9 @@ export const stakingProviderClientFactory = ({
22
22
  stakingUrl = new URL(newStakingUrl || defaultStakingUrl)
23
23
  }
24
24
 
25
- const stakingRequest = ({ asset, data }) => {
25
+ const stakingRequest = async ({ asset, data }) => {
26
26
  const headers = {}
27
- if (telemetryId) headers.telemetryId = telemetryId
27
+ if (typeof getTelemetryId === 'function') headers.telemetryId = await getTelemetryId()
28
28
  return fetchival(stakingUrl, {
29
29
  timeout: HTTP_POST_TIMEOUT,
30
30
  headers,
@@ -29,6 +29,7 @@ export class ClarityMonitor extends BaseMonitor {
29
29
  if (!config?.server || config.server === this.server.uri) {
30
30
  return
31
31
  }
32
+
32
33
  this.server.setURI(config.server)
33
34
  this.subscribeWalletAddresses()
34
35
  if (this.config.GAS_PRICE_FROM_WEBSOCKET) {
@@ -57,10 +58,8 @@ export class ClarityMonitor extends BaseMonitor {
57
58
 
58
59
  // eslint-disable-next-line no-undef
59
60
  async checkPendingTransactions(params) {
60
- const {
61
- pendingTransactionsToCheck,
62
- pendingTransactionsGroupedByAddressAndNonce,
63
- } = checkPendingTransactions(params)
61
+ const { pendingTransactionsToCheck, pendingTransactionsGroupedByAddressAndNonce } =
62
+ checkPendingTransactions(params)
64
63
  const txsToRemove = []
65
64
  const { walletAccount } = params
66
65
 
@@ -190,6 +189,7 @@ export class ClarityMonitor extends BaseMonitor {
190
189
  const balance = balances[asset.name]
191
190
  newAccountState.balance = asset.currency.baseUnit(balance)
192
191
  }
192
+
193
193
  const tokenBalancePairs = Object.entries(balances).filter((entry) => entry[0] !== asset.name)
194
194
  const tokenBalanceEntries = tokenBalancePairs
195
195
  .map((pair) => {
@@ -197,7 +197,7 @@ export class ClarityMonitor extends BaseMonitor {
197
197
  const value = token.currency.baseUnit(pair[1] || 0)
198
198
  return [token.name, value]
199
199
  })
200
- .filter((pair) => pair)
200
+ .filter(Boolean)
201
201
 
202
202
  const tokenBalances = excludeUnchangedTokenBalances(currentTokenBalances, tokenBalanceEntries)
203
203
  if (!isEmpty(tokenBalances)) newAccountState.tokenBalances = tokenBalances
@@ -214,13 +214,14 @@ export class ClarityMonitor extends BaseMonitor {
214
214
  useCache: true,
215
215
  })
216
216
  }
217
+
217
218
  return addressesByAccount
218
219
  }
219
220
 
220
221
  async subscribeWalletAddresses() {
221
222
  const addressesByWalletAccount = await this.getReceiveAddressesByWalletAccount()
222
223
  Object.entries(addressesByWalletAccount).forEach(([walletAccount, addresses]) => {
223
- const address = String(Array.from(addresses)[0]).toLowerCase() // Only check m/0/0
224
+ const address = String([...addresses][0]).toLowerCase() // Only check m/0/0
224
225
  this.server.connectTransactions({ walletAccount, address })
225
226
  })
226
227
  }
@@ -231,16 +232,19 @@ export class ClarityMonitor extends BaseMonitor {
231
232
  const request = this.server.getBalanceRequest(ourWalletAddress)
232
233
  batch[this.asset.name] = request
233
234
  }
235
+
234
236
  for (const token of tokens) {
235
237
  if (isRpcBalanceAsset(token) && token.contract.address) {
236
238
  const request = this.server.balanceOfRequest(ourWalletAddress, token.contract.address)
237
239
  batch[token.name] = request
238
240
  }
239
241
  }
242
+
240
243
  const pairs = Object.entries(batch)
241
- if (!pairs.length) {
244
+ if (pairs.length === 0) {
242
245
  return {}
243
246
  }
247
+
244
248
  const requests = pairs.map((pair) => pair[1])
245
249
  const responses = await this.server.sendBatchRequest(requests)
246
250
  const entries = pairs.map((pair, idx) => {
@@ -261,10 +265,10 @@ export class ClarityMonitor extends BaseMonitor {
261
265
  if (!tokensByAddress.has(addr)) {
262
266
  acc.add(addr)
263
267
  }
264
- }, acc)
268
+ })
265
269
  return acc
266
270
  }, new Set())
267
- return Array.from(set)
271
+ return [...set]
268
272
  }
269
273
 
270
274
  async updateGasPrice({ gasPrice, baseFeePerGas }) {
@@ -300,6 +304,7 @@ export class ClarityMonitor extends BaseMonitor {
300
304
  if (this.config.GAS_PRICE_FROM_WEBSOCKET) {
301
305
  this.server.connectFee()
302
306
  }
307
+
303
308
  return this.subscribeWalletAddresses()
304
309
  }
305
310
 
@@ -1,7 +1,7 @@
1
1
  // A super-selector that returns all the current data needed for a tick of the ETH monitor.
2
2
 
3
3
  export default function getDeriveDataNeededForTick(aci) {
4
- return async function({ assetName, walletAccount }) {
4
+ return async function ({ assetName, walletAccount }) {
5
5
  const receiveAddress = await aci.getReceiveAddress({ assetName, walletAccount, useCache: true })
6
6
  const currentAccountState = await aci.getAccountState({ assetName, walletAccount })
7
7
  return {
@@ -31,7 +31,9 @@ export default function getLogItemsFromServerTx({
31
31
  const toAddress = tryFindExternalRecipient(ethereumTransfers, ourWalletAddress)
32
32
  const ourWalletWasSender = serverTx.from === ourWalletAddress
33
33
  const METHOD_ID_LENGTH = 10
34
- const methodId = serverTx.input && { methodId: serverTx.input.substring(0, METHOD_ID_LENGTH) }
34
+ const methodId = serverTx.input && {
35
+ methodId: serverTx.input.slice(0, Math.max(0, METHOD_ID_LENGTH)),
36
+ }
35
37
 
36
38
  const logItemCommonProperties = {
37
39
  confirmations,
@@ -87,6 +89,7 @@ export default function getLogItemsFromServerTx({
87
89
  ])
88
90
  }
89
91
  }
92
+
90
93
  // handle erc20
91
94
  Object.entries(tokenTransfersByTokenName).forEach(([tokenName, tokenTransfers]) => {
92
95
  const sendingTransferPresent = tokenTransfers.some(({ from }) => from === ourWalletAddress)