@exodus/ethereum-api 8.23.2 → 8.24.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/CHANGELOG.md +10 -0
- package/package.json +4 -4
- package/src/staking/ethereum/service.js +15 -18
- package/src/staking/matic/service.js +24 -24
- package/src/watch-tx.js +32 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [8.24.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.23.2...@exodus/ethereum-api@8.24.0) (2024-12-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
* feat: evm staking send simplification (#4681)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
6
16
|
## [8.23.2](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.23.1...@exodus/ethereum-api@8.23.2) (2024-12-17)
|
|
7
17
|
|
|
8
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ethereum-api",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.24.0",
|
|
4
4
|
"description": "Transaction monitors, fee monitors, RPC with the blockchain node, and other networking code for Ethereum and EVM-based blockchains",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"@exodus/solidity-contract": "^1.1.3",
|
|
39
39
|
"@exodus/web3-ethereum-utils": "^3.27.1",
|
|
40
40
|
"bn.js": "^5.2.1",
|
|
41
|
+
"delay": "^4.0.1",
|
|
41
42
|
"events": "^1.1.1",
|
|
42
43
|
"idna-uts46-hx": "^2.3.1",
|
|
43
44
|
"lodash": "^4.17.15",
|
|
@@ -54,8 +55,7 @@
|
|
|
54
55
|
"@exodus/ethereumgoerli-meta": "^2.0.0",
|
|
55
56
|
"@exodus/ethereumsepolia-meta": "^2.0.0",
|
|
56
57
|
"@exodus/fantommainnet-meta": "^2.0.0",
|
|
57
|
-
"@exodus/rootstock-meta": "^2.0.0"
|
|
58
|
-
"delay": "4.0.1"
|
|
58
|
+
"@exodus/rootstock-meta": "^2.0.0"
|
|
59
59
|
},
|
|
60
60
|
"bugs": {
|
|
61
61
|
"url": "https://github.com/ExodusMovement/assets/issues?q=is%3Aissue+is%3Aopen+label%3Aethereum-api"
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"type": "git",
|
|
65
65
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "cb07ad7e423a04b4da350bbf159e55b4490e3eae"
|
|
68
68
|
}
|
|
@@ -3,6 +3,7 @@ import { isNumberUnit } from '@exodus/currency'
|
|
|
3
3
|
import { getServer } from '../../exodus-eth-server/index.js'
|
|
4
4
|
import { estimateGasLimit } from '../../gas-estimation.js'
|
|
5
5
|
import { fromHexToBigInt } from '../../number-utils.js'
|
|
6
|
+
import { createWatchTx as defaultCreateWatch } from '../../watch-tx.js'
|
|
6
7
|
import { stakingProviderClientFactory } from '../staking-provider-client.js'
|
|
7
8
|
import { EthereumStaking } from './api.js'
|
|
8
9
|
|
|
@@ -11,7 +12,7 @@ const extraGasLimit = 20_000 // extra gas Limit to prevent tx failing if somethi
|
|
|
11
12
|
export function createEthereumStakingService({
|
|
12
13
|
asset,
|
|
13
14
|
assetClientInterface,
|
|
14
|
-
|
|
15
|
+
createWatchTx = defaultCreateWatch,
|
|
15
16
|
}) {
|
|
16
17
|
const staking = new EthereumStaking(asset)
|
|
17
18
|
const stakingProvider = stakingProviderClientFactory()
|
|
@@ -33,7 +34,7 @@ export function createEthereumStakingService({
|
|
|
33
34
|
amount,
|
|
34
35
|
})
|
|
35
36
|
|
|
36
|
-
const { gasPrice, gasLimit
|
|
37
|
+
const { gasPrice, gasLimit } = await estimateTxFee(delegatorAddress, to, amount, data)
|
|
37
38
|
|
|
38
39
|
console.log(
|
|
39
40
|
`delegator address ${delegatorAddress} staking ${amount.toDefaultString({
|
|
@@ -48,7 +49,6 @@ export function createEthereumStakingService({
|
|
|
48
49
|
txData: data,
|
|
49
50
|
gasPrice,
|
|
50
51
|
gasLimit,
|
|
51
|
-
fee,
|
|
52
52
|
})
|
|
53
53
|
|
|
54
54
|
// Goerli is not supported
|
|
@@ -226,7 +226,7 @@ export function createEthereumStakingService({
|
|
|
226
226
|
})
|
|
227
227
|
if (withdrawRequest) {
|
|
228
228
|
const { to, data } = withdrawRequest
|
|
229
|
-
const { gasPrice, gasLimit
|
|
229
|
+
const { gasPrice, gasLimit } = await estimateTxFee(delegatorAddress, to, null, data)
|
|
230
230
|
return prepareAndSendTx({
|
|
231
231
|
asset,
|
|
232
232
|
walletAccount,
|
|
@@ -234,7 +234,6 @@ export function createEthereumStakingService({
|
|
|
234
234
|
txData: data,
|
|
235
235
|
gasPrice,
|
|
236
236
|
gasLimit,
|
|
237
|
-
fee,
|
|
238
237
|
})
|
|
239
238
|
}
|
|
240
239
|
}
|
|
@@ -314,7 +313,6 @@ export function createEthereumStakingService({
|
|
|
314
313
|
txData: txInput,
|
|
315
314
|
gasPrice,
|
|
316
315
|
gasLimit,
|
|
317
|
-
fee,
|
|
318
316
|
waitForConfirmation = false,
|
|
319
317
|
} = Object.create(null)
|
|
320
318
|
) {
|
|
@@ -323,28 +321,27 @@ export function createEthereumStakingService({
|
|
|
323
321
|
walletAccount,
|
|
324
322
|
address: to,
|
|
325
323
|
amount: amount || asset.currency.ZERO,
|
|
326
|
-
// unified tx-send param
|
|
327
324
|
shouldLog: true,
|
|
328
|
-
txInput,
|
|
329
|
-
feeAmount: fee,
|
|
330
|
-
feeOpts: {
|
|
331
|
-
gasPrice,
|
|
332
|
-
gasLimit,
|
|
333
|
-
},
|
|
334
|
-
// mobile: tx-send parms
|
|
335
325
|
options: {
|
|
336
326
|
shouldLog: true,
|
|
337
327
|
txInput,
|
|
338
328
|
gasPrice,
|
|
339
329
|
gasLimit,
|
|
340
|
-
feeAmount: fee,
|
|
341
330
|
},
|
|
342
|
-
waitForConfirmation,
|
|
343
331
|
}
|
|
344
332
|
|
|
345
|
-
|
|
333
|
+
const { txId } = await asset.baseAsset.api.sendTx(sendTxArgs)
|
|
346
334
|
|
|
347
|
-
const
|
|
335
|
+
const baseAsset = asset.baseAsset
|
|
336
|
+
if (waitForConfirmation) {
|
|
337
|
+
const getTxLog = (...args) => assetClientInterface.getTxLog(...args)
|
|
338
|
+
const watchTx = createWatchTx({
|
|
339
|
+
walletAccount,
|
|
340
|
+
getTxLog,
|
|
341
|
+
baseAsset,
|
|
342
|
+
})
|
|
343
|
+
await watchTx(txId)
|
|
344
|
+
}
|
|
348
345
|
|
|
349
346
|
return txId
|
|
350
347
|
}
|
|
@@ -3,10 +3,14 @@ import BN from 'bn.js'
|
|
|
3
3
|
|
|
4
4
|
import { getServer } from '../../exodus-eth-server/index.js'
|
|
5
5
|
import { estimateGasLimit } from '../../gas-estimation.js'
|
|
6
|
+
import { createWatchTx as defaultCreateWatch } from '../../watch-tx.js'
|
|
6
7
|
import { stakingProviderClientFactory } from '../staking-provider-client.js'
|
|
7
8
|
import { MaticStakingApi } from './api.js'
|
|
8
9
|
|
|
9
|
-
export function createPolygonStakingService({
|
|
10
|
+
export function createPolygonStakingService({
|
|
11
|
+
assetClientInterface,
|
|
12
|
+
createWatchTx = defaultCreateWatch,
|
|
13
|
+
}) {
|
|
10
14
|
const stakingApi = new MaticStakingApi()
|
|
11
15
|
const assetName = 'ethereum'
|
|
12
16
|
const stakingProvider = stakingProviderClientFactory()
|
|
@@ -33,7 +37,7 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
33
37
|
amount = amountToCurrency({ asset, amount })
|
|
34
38
|
|
|
35
39
|
const txApproveData = await stakingApi.approveStakeManager(amount)
|
|
36
|
-
let { gasPrice, gasLimit
|
|
40
|
+
let { gasPrice, gasLimit } = await estimateTxFee(
|
|
37
41
|
delegatorAddress,
|
|
38
42
|
stakingApi.polygonContract.address,
|
|
39
43
|
txApproveData
|
|
@@ -45,11 +49,10 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
45
49
|
txData: txApproveData,
|
|
46
50
|
gasPrice,
|
|
47
51
|
gasLimit,
|
|
48
|
-
fee,
|
|
49
52
|
})
|
|
50
53
|
|
|
51
54
|
const txDelegateData = await stakingApi.delegate({ amount })
|
|
52
|
-
;({ gasPrice, gasLimit
|
|
55
|
+
;({ gasPrice, gasLimit } = await estimateTxFee(
|
|
53
56
|
delegatorAddress,
|
|
54
57
|
stakingApi.validatorShareContract.address,
|
|
55
58
|
txDelegateData
|
|
@@ -61,7 +64,6 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
61
64
|
txData: txDelegateData,
|
|
62
65
|
gasPrice,
|
|
63
66
|
gasLimit,
|
|
64
|
-
fee,
|
|
65
67
|
})
|
|
66
68
|
|
|
67
69
|
await stakingProvider.notifyStaking({
|
|
@@ -85,7 +87,7 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
85
87
|
amount = amountToCurrency({ asset, amount })
|
|
86
88
|
|
|
87
89
|
const txUndelegateData = await stakingApi.undelegate({ amount })
|
|
88
|
-
const { gasPrice, gasLimit
|
|
90
|
+
const { gasPrice, gasLimit } = await estimateTxFee(
|
|
89
91
|
delegatorAddress.toLowerCase(),
|
|
90
92
|
stakingApi.validatorShareContract.address,
|
|
91
93
|
txUndelegateData
|
|
@@ -96,7 +98,6 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
96
98
|
txData: txUndelegateData,
|
|
97
99
|
gasPrice,
|
|
98
100
|
gasLimit,
|
|
99
|
-
fee,
|
|
100
101
|
})
|
|
101
102
|
}
|
|
102
103
|
|
|
@@ -108,7 +109,7 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
108
109
|
const delegatorAddress = address.toLowerCase()
|
|
109
110
|
|
|
110
111
|
const txWithdrawRewardsData = await stakingApi.withdrawRewards()
|
|
111
|
-
const { gasPrice, gasLimit
|
|
112
|
+
const { gasPrice, gasLimit } = await estimateTxFee(
|
|
112
113
|
delegatorAddress,
|
|
113
114
|
stakingApi.validatorShareContract.address,
|
|
114
115
|
txWithdrawRewardsData
|
|
@@ -119,7 +120,6 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
119
120
|
txData: txWithdrawRewardsData,
|
|
120
121
|
gasPrice,
|
|
121
122
|
gasLimit,
|
|
122
|
-
fee,
|
|
123
123
|
})
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -267,37 +267,37 @@ export function createPolygonStakingService({ assetClientInterface, createAndBro
|
|
|
267
267
|
txData: txInput,
|
|
268
268
|
gasPrice,
|
|
269
269
|
gasLimit,
|
|
270
|
-
fee,
|
|
271
270
|
waitForConfirmation = false,
|
|
272
271
|
} = {}) {
|
|
273
|
-
const { ethereum } = await assetClientInterface.getAssetsForNetwork({
|
|
272
|
+
const { ethereum: asset } = await assetClientInterface.getAssetsForNetwork({
|
|
274
273
|
baseAssetName: 'ethereum',
|
|
275
274
|
})
|
|
276
275
|
const sendTxArgs = {
|
|
277
|
-
asset
|
|
276
|
+
asset,
|
|
278
277
|
walletAccount,
|
|
279
278
|
address: to,
|
|
280
|
-
amount:
|
|
281
|
-
// unified tx-send param
|
|
282
|
-
shouldLog: true,
|
|
283
|
-
txInput,
|
|
284
|
-
feeAmount: fee,
|
|
285
|
-
feeOpts: {
|
|
286
|
-
gasPrice,
|
|
287
|
-
gasLimit,
|
|
288
|
-
},
|
|
289
|
-
// mobile: tx-send parms
|
|
279
|
+
amount: asset.currency.ZERO,
|
|
290
280
|
options: {
|
|
291
281
|
shouldLog: true,
|
|
292
282
|
txInput,
|
|
293
283
|
gasPrice,
|
|
294
284
|
gasLimit,
|
|
295
|
-
feeAmount: fee,
|
|
296
285
|
},
|
|
297
286
|
waitForConfirmation,
|
|
298
287
|
}
|
|
299
288
|
|
|
300
|
-
const { txId } = await
|
|
289
|
+
const { txId } = await asset.baseAsset.api.sendTx(sendTxArgs)
|
|
290
|
+
|
|
291
|
+
const baseAsset = asset.baseAsset
|
|
292
|
+
if (waitForConfirmation) {
|
|
293
|
+
const getTxLog = (...args) => assetClientInterface.getTxLog(...args)
|
|
294
|
+
const watchTx = createWatchTx({
|
|
295
|
+
walletAccount,
|
|
296
|
+
getTxLog,
|
|
297
|
+
baseAsset,
|
|
298
|
+
})
|
|
299
|
+
await watchTx(txId)
|
|
300
|
+
}
|
|
301
301
|
|
|
302
302
|
return txId
|
|
303
303
|
}
|
package/src/watch-tx.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import delay from 'delay'
|
|
2
|
+
import ms from 'ms'
|
|
3
|
+
|
|
4
|
+
const WATCH_TX_DELAY = ms('5s')
|
|
5
|
+
const WATCH_TX_TIMEOUT = ms('5m')
|
|
6
|
+
|
|
7
|
+
// this could go to asset-lib
|
|
8
|
+
export const createWatchTx =
|
|
9
|
+
({
|
|
10
|
+
walletAccount,
|
|
11
|
+
getTxLog,
|
|
12
|
+
baseAsset,
|
|
13
|
+
watchTxDelay = WATCH_TX_DELAY,
|
|
14
|
+
watchTxTimeout = WATCH_TX_TIMEOUT,
|
|
15
|
+
}) =>
|
|
16
|
+
async (txId) => {
|
|
17
|
+
const start = Date.now()
|
|
18
|
+
let txConfirmed = false
|
|
19
|
+
let hasTimedOut = false
|
|
20
|
+
|
|
21
|
+
while (!hasTimedOut && !txConfirmed) {
|
|
22
|
+
await delay(watchTxDelay)
|
|
23
|
+
const baseAssetTxLog = await getTxLog({
|
|
24
|
+
assetName: baseAsset.name,
|
|
25
|
+
walletAccount,
|
|
26
|
+
})
|
|
27
|
+
txConfirmed = baseAssetTxLog.get(txId)?.confirmed
|
|
28
|
+
hasTimedOut = Date.now() - start > watchTxTimeout
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return { txId, confirmed: txConfirmed, hasTimedOut }
|
|
32
|
+
}
|