@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.
- package/package.json +10 -6
- package/src/allowance/constants.js +3 -2
- package/src/allowance/index.js +90 -84
- package/src/ens/addresses.js +3 -1
- package/src/eth-like-util.js +6 -5
- package/src/etherscan/account.js +2 -2
- package/src/etherscan/index.js +15 -35
- package/src/etherscan/proxy.js +3 -3
- package/src/etherscan/request.js +1 -1
- package/src/etherscan/ws.js +2 -2
- package/src/exodus-eth-server/api-coin-nodes.js +4 -3
- package/src/exodus-eth-server/api.js +6 -4
- package/src/exodus-eth-server/clarity.js +10 -3
- package/src/exodus-eth-server/ws.js +13 -1
- package/src/fee-monitor/ethereumarbnova.js +4 -1
- package/src/fee-monitor/ethereumarbone.js +4 -1
- package/src/fee-monitor/ethereumsepolia.js +18 -0
- package/src/fee-monitor/index.js +1 -0
- package/src/fee-monitor/optimism.js +4 -1
- package/src/gas-estimation.js +3 -1
- package/src/get-balances.js +2 -1
- package/src/simulate-tx/simulate-eth-tx.js +4 -3
- package/src/staking/ethereum/api.js +8 -8
- package/src/staking/ethereum/service.js +33 -35
- package/src/staking/ethereum/staking-utils.js +3 -5
- package/src/staking/fantom-staking.js +2 -2
- package/src/staking/matic/api.js +2 -3
- package/src/staking/matic/service.js +34 -42
- package/src/staking/staking-provider-client.js +3 -3
- package/src/tx-log/clarity-monitor.js +14 -9
- package/src/tx-log/clarity-utils/get-derive-data-needed-for-tick.js +1 -1
- package/src/tx-log/clarity-utils/get-log-items-from-server-tx.js +4 -1
- package/src/tx-log/ethereum-monitor.js +8 -11
- package/src/tx-log/ethereum-no-history-monitor.js +13 -11
- package/src/tx-log/monitor-utils/check-pending-transactions.js +2 -0
- package/src/tx-log/monitor-utils/exclude-unchanged-token-balances.js +2 -3
- package/src/tx-log/monitor-utils/get-derive-data-needed-for-tick.js +1 -1
- package/src/tx-log/monitor-utils/get-derive-transactions-to-check.js +2 -1
- package/src/tx-log/monitor-utils/get-log-items-from-server-tx.js +5 -2
- package/src/tx-log/ws-updates.js +1 -1
- package/src/websocket/index.js +5 -4
- package/LICENSE.md +0 -0
- 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
|
+
}
|
package/src/fee-monitor/index.js
CHANGED
|
@@ -9,7 +9,10 @@ export class OptimismFeeMonitor extends EthereumLikeFeeMonitor {
|
|
|
9
9
|
super({
|
|
10
10
|
updateFee,
|
|
11
11
|
assetName,
|
|
12
|
-
getGasPrice: async () =>
|
|
12
|
+
getGasPrice: async () => {
|
|
13
|
+
const fee = await getServerByName(assetName).getFee()
|
|
14
|
+
return fee?.gasPrice
|
|
15
|
+
},
|
|
13
16
|
interval,
|
|
14
17
|
})
|
|
15
18
|
}
|
package/src/gas-estimation.js
CHANGED
|
@@ -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' ?
|
|
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)) {
|
package/src/get-balances.js
CHANGED
|
@@ -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
|
|
145
|
-
|
|
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 (
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
14
|
+
getTelemetryId,
|
|
15
15
|
}) {
|
|
16
16
|
const staking = new EthereumStaking(asset)
|
|
17
|
-
const stakingProvider = stakingProviderClientFactory({
|
|
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
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
|
|
169
|
-
|
|
165
|
+
const { gasPrice, gasLimit, fee } = await estimateTxFee(delegatorAddress, to, null, data)
|
|
166
|
+
return prepareAndSendTx({
|
|
170
167
|
asset,
|
|
171
168
|
walletAccount,
|
|
172
|
-
to
|
|
169
|
+
to,
|
|
173
170
|
txData: data,
|
|
174
171
|
gasPrice,
|
|
175
172
|
gasLimit,
|
|
176
173
|
fee,
|
|
177
174
|
})
|
|
178
|
-
|
|
179
|
-
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return null // -> no withdrawable balance
|
|
180
178
|
}
|
|
181
179
|
|
|
182
180
|
async function estimateDelegateOperation({ walletAccount, operation, args }) {
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
|
108
|
+
throw new TypeError('The lock duration must be an integer.')
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
if (duration > 365 *
|
|
111
|
+
if (duration > 365 * 86_400) {
|
|
112
112
|
throw new Error('The lock duration must be at most 365 days.')
|
|
113
113
|
}
|
|
114
114
|
}
|
package/src/staking/matic/api.js
CHANGED
|
@@ -25,8 +25,7 @@ export class MaticStakingApi {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
buildTxData = (contract, method, ...args) => {
|
|
28
|
-
|
|
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(/[
|
|
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
|
-
|
|
11
|
+
getTelemetryId,
|
|
12
12
|
}) {
|
|
13
13
|
const stakingApi = new MaticStakingApi()
|
|
14
14
|
const assetName = 'ethereum'
|
|
15
|
-
const stakingProvider = stakingProviderClientFactory({
|
|
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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
91
|
+
const { gasPrice, gasLimit, fee } = await estimateTxFee(
|
|
94
92
|
delegatorAddress.toLowerCase(),
|
|
95
93
|
stakingApi.validatorShareContract.address,
|
|
96
94
|
txUndelegateData
|
|
97
95
|
)
|
|
98
|
-
|
|
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
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
114
|
+
const { gasPrice, gasLimit, fee } = await estimateTxFee(
|
|
120
115
|
delegatorAddress,
|
|
121
116
|
stakingApi.validatorShareContract.address,
|
|
122
117
|
txWithdrawRewardsData
|
|
123
118
|
)
|
|
124
|
-
|
|
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
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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 =
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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 (
|
|
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
|
-
}
|
|
268
|
+
})
|
|
265
269
|
return acc
|
|
266
270
|
}, new Set())
|
|
267
|
-
return
|
|
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 && {
|
|
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)
|