@exodus/ethereum-api 8.64.5 → 8.64.6
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 +2 -2
- package/src/exodus-eth-server/api-coin-nodes.js +5 -0
- package/src/exodus-eth-server/api.js +5 -0
- package/src/exodus-eth-server/clarity.js +5 -0
- package/src/exodus-eth-server/utils.js +31 -0
- package/src/fee-utils.js +0 -9
- package/src/server-based-fee-monitor.js +2 -10
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.64.6](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.64.5...@exodus/ethereum-api@8.64.6) (2026-02-23)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
* fix: avoid race conditions resulting in a `tipGasPrice` of `0` where possible (#7458)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
6
16
|
## [8.64.5](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.64.4...@exodus/ethereum-api@8.64.5) (2026-02-11)
|
|
7
17
|
|
|
8
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ethereum-api",
|
|
3
|
-
"version": "8.64.
|
|
3
|
+
"version": "8.64.6",
|
|
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",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"type": "git",
|
|
68
68
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "05a14c42a3963199e2b0b11d0a643884ebae8e46"
|
|
71
71
|
}
|
|
@@ -6,6 +6,7 @@ import lodash from 'lodash'
|
|
|
6
6
|
|
|
7
7
|
import { fromHexToString } from '../number-utils.js'
|
|
8
8
|
import { errorMessageToSafeHint } from './errors.js'
|
|
9
|
+
import { getFallbackGasPriceEstimation } from './utils.js'
|
|
9
10
|
|
|
10
11
|
const { isEmpty } = lodash
|
|
11
12
|
|
|
@@ -166,6 +167,10 @@ export default class ApiCoinNodesServer extends EventEmitter {
|
|
|
166
167
|
return this.sendRequest(request)
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
async getGasPriceEstimation() {
|
|
171
|
+
return getFallbackGasPriceEstimation({ server: this })
|
|
172
|
+
}
|
|
173
|
+
|
|
169
174
|
// for fee monitor
|
|
170
175
|
getGasPrice = this.gasPrice
|
|
171
176
|
|
|
@@ -6,6 +6,7 @@ import SolidityContract from '@exodus/solidity-contract'
|
|
|
6
6
|
import ms from 'ms'
|
|
7
7
|
|
|
8
8
|
import { fromHexToString } from '../number-utils.js'
|
|
9
|
+
import { getFallbackGasPriceEstimation } from './utils.js'
|
|
9
10
|
import createWebSocket from './ws.js'
|
|
10
11
|
|
|
11
12
|
const RETRY_DELAYS = ['10s']
|
|
@@ -120,6 +121,10 @@ export function create(defaultURL, ensAssetName) {
|
|
|
120
121
|
return requestWithRetry('proxy', { method: 'eth_gasPrice' })
|
|
121
122
|
},
|
|
122
123
|
|
|
124
|
+
async getGasPriceEstimation() {
|
|
125
|
+
return getFallbackGasPriceEstimation({ server: this })
|
|
126
|
+
},
|
|
127
|
+
|
|
123
128
|
// for fee monitor
|
|
124
129
|
async getGasPrice() {
|
|
125
130
|
return requestWithRetry('proxy', { method: 'eth_gasPrice' })
|
|
@@ -6,6 +6,7 @@ import io from 'socket.io-client'
|
|
|
6
6
|
|
|
7
7
|
import { fromHexToString } from '../number-utils.js'
|
|
8
8
|
import { errorMessageToSafeHint } from './errors.js'
|
|
9
|
+
import { getFallbackGasPriceEstimation } from './utils.js'
|
|
9
10
|
|
|
10
11
|
export const RPC_REQUEST_TIMEOUT = 'RPC_REQUEST_TIMEOUT'
|
|
11
12
|
|
|
@@ -174,6 +175,10 @@ export default class ClarityServer extends EventEmitter {
|
|
|
174
175
|
return fee?.gasPrice
|
|
175
176
|
}
|
|
176
177
|
|
|
178
|
+
async getGasPriceEstimation() {
|
|
179
|
+
return getFallbackGasPriceEstimation({ server: this })
|
|
180
|
+
}
|
|
181
|
+
|
|
177
182
|
async sendRpcRequest(rpcRequest) {
|
|
178
183
|
const rpcSocket = this.connectRpc()
|
|
179
184
|
return new Promise((resolve, reject) => {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import assert from 'minimalistic-assert'
|
|
2
|
+
|
|
3
|
+
const desc = (a, b) => (a > b ? -1 : b > a ? 1 : 0)
|
|
4
|
+
|
|
5
|
+
export const getFallbackGasPriceEstimation = async ({ server }) => {
|
|
6
|
+
const [latestBlock, gasPrice] = await Promise.all([server.getLatestBlock(), server.getGasPrice()])
|
|
7
|
+
|
|
8
|
+
assert(latestBlock, 'expected latestBlock')
|
|
9
|
+
assert(gasPrice, 'expected gasPrice')
|
|
10
|
+
|
|
11
|
+
const baseFeePerGas = latestBlock.baseFeePerGas
|
|
12
|
+
if (!baseFeePerGas) return { gasPrice }
|
|
13
|
+
|
|
14
|
+
const [max, min] = [BigInt(gasPrice), BigInt(baseFeePerGas)].sort(desc)
|
|
15
|
+
|
|
16
|
+
const toHex = (b) => `0x${b.toString(16)}`
|
|
17
|
+
|
|
18
|
+
// TODO: Use `eth_feeHistory` or `eth_maxPriorityFeePerGas`
|
|
19
|
+
// instead (requires allowlist at the RPC).
|
|
20
|
+
// HACK: Infer the RPC's implicit `tipGasPrice`:
|
|
21
|
+
// https://github.com/ethereum/go-ethereum/blob/d3dd48e59db28ea04bd92e4337cdd488ccb8fbec/internal/ethapi/api.go#L69C1-L79C2
|
|
22
|
+
const maxPriorityFeePerGas50Percentile = max - min
|
|
23
|
+
|
|
24
|
+
const rewardPercentiles = {
|
|
25
|
+
25: toHex(maxPriorityFeePerGas50Percentile / BigInt(2)),
|
|
26
|
+
50: toHex(maxPriorityFeePerGas50Percentile),
|
|
27
|
+
75: toHex((maxPriorityFeePerGas50Percentile * BigInt(3)) / BigInt(2)),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return { gasPrice, baseFeePerGas, rewardPercentiles }
|
|
31
|
+
}
|
package/src/fee-utils.js
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
import assert from 'minimalistic-assert'
|
|
2
2
|
|
|
3
|
-
export const shouldFetchEthLikeFallbackGasPrices = async ({ eip1559Enabled, server }) => {
|
|
4
|
-
const [gasPrice, baseFeePerGas] = await Promise.all([
|
|
5
|
-
server.getGasPrice(),
|
|
6
|
-
eip1559Enabled ? server.getBaseFeePerGas() : undefined,
|
|
7
|
-
])
|
|
8
|
-
|
|
9
|
-
return { gasPrice, baseFeePerGas }
|
|
10
|
-
}
|
|
11
|
-
|
|
12
3
|
export const applyMultiplierToPrice = ({ feeAsset, gasPriceMultiplier, price }) => {
|
|
13
4
|
assert(typeof price === 'string', 'price should be a string')
|
|
14
5
|
return feeAsset.currency
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { FeeMonitor } from '@exodus/asset-lib'
|
|
2
2
|
import assert from 'minimalistic-assert'
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
calculateEthLikeFeeMonitorUpdate,
|
|
6
|
-
shouldFetchEthLikeFallbackGasPrices,
|
|
7
|
-
} from './fee-utils.js'
|
|
4
|
+
import { calculateEthLikeFeeMonitorUpdate } from './fee-utils.js'
|
|
8
5
|
|
|
9
6
|
/**
|
|
10
7
|
* Generic eth server based fee monitor.
|
|
@@ -25,11 +22,6 @@ export const serverBasedFeeMonitorFactoryFactory = ({ asset, interval, server, a
|
|
|
25
22
|
assert(server, 'server is required')
|
|
26
23
|
assert(aci, 'aci is required')
|
|
27
24
|
|
|
28
|
-
const shouldFetchGasPrices = async () => {
|
|
29
|
-
const { eip1559Enabled } = await aci.getFeeConfig({ assetName: asset.name })
|
|
30
|
-
return shouldFetchEthLikeFallbackGasPrices({ eip1559Enabled, server })
|
|
31
|
-
}
|
|
32
|
-
|
|
33
25
|
const FeeMonitorClass = class ServerBaseEthereumFeeMonitor extends FeeMonitor {
|
|
34
26
|
constructor({ updateFee }) {
|
|
35
27
|
assert(updateFee, 'updateFee is required')
|
|
@@ -44,7 +36,7 @@ export const serverBasedFeeMonitorFactoryFactory = ({ asset, interval, server, a
|
|
|
44
36
|
return calculateEthLikeFeeMonitorUpdate({
|
|
45
37
|
assetClientInterface: aci,
|
|
46
38
|
feeAsset: asset,
|
|
47
|
-
fetchedGasPrices: await
|
|
39
|
+
fetchedGasPrices: await server.getGasPriceEstimation(),
|
|
48
40
|
})
|
|
49
41
|
}
|
|
50
42
|
}
|