@exodus/ethereum-api 8.46.0 → 8.47.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 +20 -0
- package/package.json +2 -2
- package/src/create-asset.js +2 -3
- package/src/fee-data/EthLikeFeeData.js +81 -0
- package/src/{fee-data-factory.js → fee-data/index.js} +5 -7
- package/src/tx-create.js +15 -6
- package/src/tx-send/tx-send.js +0 -15
- package/src/get-fee-async.js +0 -29
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
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.47.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.46.1...@exodus/ethereum-api@8.47.0) (2025-09-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
* feat: add `EthLikeFeeData` to respect `min`, `max` and `multiplier` for EIP-1559 transactions (#6254)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## [8.46.1](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.46.0...@exodus/ethereum-api@8.46.1) (2025-09-03)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
* fix: tx-create simplification (#6310)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
6
26
|
## [8.46.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.45.6...@exodus/ethereum-api@8.46.0) (2025-08-21)
|
|
7
27
|
|
|
8
28
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ethereum-api",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.47.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",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"type": "git",
|
|
65
65
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "e0dac028c1eb8ad919ce437b88f7f8549eea6f88"
|
|
68
68
|
}
|
package/src/create-asset.js
CHANGED
|
@@ -29,11 +29,10 @@ import {
|
|
|
29
29
|
import { createTokenFactory } from './create-token-factory.js'
|
|
30
30
|
import { createCustomFeesApi } from './custom-fees.js'
|
|
31
31
|
import { createEvmServer } from './exodus-eth-server/index.js'
|
|
32
|
-
import { createFeeData } from './fee-data
|
|
32
|
+
import { createFeeData } from './fee-data/index.js'
|
|
33
33
|
import { createGetBalanceForAddress } from './get-balance-for-address.js'
|
|
34
34
|
import { getBalancesFactory } from './get-balances.js'
|
|
35
35
|
import { getFeeFactory } from './get-fee.js'
|
|
36
|
-
import getFeeAsyncFactory from './get-fee-async.js'
|
|
37
36
|
import { estimateL1DataFeeFactory, getL1GetFeeFactory } from './optimism-gas/index.js'
|
|
38
37
|
import { serverBasedFeeMonitorFactoryFactory } from './server-based-fee-monitor.js'
|
|
39
38
|
import { createStakingApi } from './staking-api.js'
|
|
@@ -258,7 +257,7 @@ export const createAssetFactory = ({
|
|
|
258
257
|
getBalanceForAddress: createGetBalanceForAddress({ asset, server }),
|
|
259
258
|
getConfirmationsNumber: () => confirmationsNumber,
|
|
260
259
|
getDefaultAddressPath: () => defaultAddressPath,
|
|
261
|
-
getFeeAsync:
|
|
260
|
+
getFeeAsync: createTx, // createTx alias, remove me when possible
|
|
262
261
|
getFee,
|
|
263
262
|
getFeeData: () => feeData,
|
|
264
263
|
getKeyIdentifier: createGetKeyIdentifier({
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { FeeData } from '@exodus/asset-lib'
|
|
2
|
+
import {
|
|
3
|
+
mapCurrency as defaultMapCurrency,
|
|
4
|
+
modelToJSON,
|
|
5
|
+
} from '@exodus/asset-lib/src/utils/index.js'
|
|
6
|
+
import { isNumberUnit } from '@exodus/currency'
|
|
7
|
+
import lodash from 'lodash'
|
|
8
|
+
|
|
9
|
+
const { isEmpty, isEqual } = lodash
|
|
10
|
+
|
|
11
|
+
const PRE_EIP1559_UNIT_KEYS_GUARD = ['gasPrice']
|
|
12
|
+
const EIP1559_UNIT_KEYS_GUARD = ['gasPrice', 'baseFeePerGas']
|
|
13
|
+
|
|
14
|
+
export const bound = ({ val, multiplier, max, min }) => {
|
|
15
|
+
if (!isNumberUnit(val)) return val
|
|
16
|
+
|
|
17
|
+
if (multiplier) {
|
|
18
|
+
val = val.mul(multiplier)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (max) {
|
|
22
|
+
val = val.lte(max) ? val : max
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (min) {
|
|
26
|
+
val = val.gte(min) ? val : min
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return val
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const mapCurrency = ({ currency, config }) => {
|
|
33
|
+
const { eip1559Enabled } = config
|
|
34
|
+
return defaultMapCurrency(
|
|
35
|
+
config,
|
|
36
|
+
[currency],
|
|
37
|
+
eip1559Enabled ? EIP1559_UNIT_KEYS_GUARD : PRE_EIP1559_UNIT_KEYS_GUARD
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const boundFactory =
|
|
42
|
+
({ config }) =>
|
|
43
|
+
(val) => {
|
|
44
|
+
const { multiplier, max, min } = config
|
|
45
|
+
return bound({ val, multiplier, max, min })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class EthLikeFeeData extends FeeData {
|
|
49
|
+
constructor({ currency, config }) {
|
|
50
|
+
super({ currency, config, mainKey: 'gasPrice' })
|
|
51
|
+
Object.assign(this, mapCurrency({ currency, config }))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
update(config = {}) {
|
|
55
|
+
if (isEmpty(config)) return this
|
|
56
|
+
|
|
57
|
+
config = super.update(config)
|
|
58
|
+
|
|
59
|
+
if (config.eip1559Enabled) {
|
|
60
|
+
const bound = boundFactory({ config })
|
|
61
|
+
|
|
62
|
+
const { baseFeePerGas, tipGasPrice = this.currency.ZERO } = config
|
|
63
|
+
|
|
64
|
+
const enforcedEffectiveGasPrice = bound(baseFeePerGas.add(tipGasPrice))
|
|
65
|
+
|
|
66
|
+
// When the `effectiveGasPrice` is lower, we'll increase the
|
|
67
|
+
// `tipGasPrice` to ensure we meet the `enforcedEffectiveGasPrice`.
|
|
68
|
+
//
|
|
69
|
+
// Conversely, when the `effectiveGasPrice` is too high, we'll
|
|
70
|
+
// try to reduce the `tipGasPrice` where possible, but whilst
|
|
71
|
+
// maintaining the `baseFeePerGas`, since this is the minimum
|
|
72
|
+
// for the current network.
|
|
73
|
+
Object.assign(config, {
|
|
74
|
+
tipGasPrice: enforcedEffectiveGasPrice.sub(baseFeePerGas).clampLowerZero(),
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (isEqual(this.toJSON(), modelToJSON({ ...config }))) return this
|
|
79
|
+
return new this.constructor({ config, currency: this.currency })
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { FeeData } from '@exodus/asset-lib'
|
|
2
1
|
import assert from 'minimalistic-assert'
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { EthLikeFeeData } from './EthLikeFeeData.js'
|
|
4
|
+
|
|
5
|
+
export const createFeeDataConfigDefaults = ({ currency, feeDataConfig }) => {
|
|
5
6
|
const shared = {
|
|
6
7
|
tipGasPrice: '0 Gwei',
|
|
7
8
|
fuelThreshold: '0 Gwei',
|
|
@@ -48,9 +49,6 @@ const createFeeDataConfigDefaults = ({ currency, feeDataConfig }) => {
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
export const createFeeData = ({ currency, feeDataConfig }) => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
mainKey: 'gasPrice',
|
|
54
|
-
currency,
|
|
55
|
-
})
|
|
52
|
+
const config = createFeeDataConfigDefaults({ currency, feeDataConfig })
|
|
53
|
+
return new EthLikeFeeData({ config, currency })
|
|
56
54
|
}
|
package/src/tx-create.js
CHANGED
|
@@ -6,7 +6,7 @@ import * as ErrorWrapper from './error-wrapper.js'
|
|
|
6
6
|
import { isContractAddressCached } from './eth-like-util.js'
|
|
7
7
|
import { ensureSaneEip1559GasPriceForTipGasPrice } from './fee-utils.js'
|
|
8
8
|
import { ARBITRARY_ADDRESS, fetchGasLimit, resolveDefaultTxInput } from './gas-estimation.js'
|
|
9
|
-
import { getFeeFactoryGasPrices } from './get-fee.js'
|
|
9
|
+
import { getExtraFeeData, getFeeFactoryGasPrices } from './get-fee.js'
|
|
10
10
|
import { getNftArguments } from './nft-utils.js'
|
|
11
11
|
|
|
12
12
|
async function createUnsignedTxWithFees({
|
|
@@ -66,7 +66,7 @@ async function createUnsignedTxWithFees({
|
|
|
66
66
|
: asset.baseAsset.currency.ZERO
|
|
67
67
|
|
|
68
68
|
const fee = baseFee.add(l1DataFee)
|
|
69
|
-
|
|
69
|
+
const extraFeeData = getExtraFeeData({ asset, amount: coinAmount })
|
|
70
70
|
const unsignedTx = {
|
|
71
71
|
txData: { transactionBuffer, chainId },
|
|
72
72
|
txMeta: {
|
|
@@ -81,6 +81,8 @@ async function createUnsignedTxWithFees({
|
|
|
81
81
|
}
|
|
82
82
|
return {
|
|
83
83
|
unsignedTx,
|
|
84
|
+
fee,
|
|
85
|
+
extraFeeData,
|
|
84
86
|
// exhcange compatibility until the use usignedTx, remove me!
|
|
85
87
|
gasPrice,
|
|
86
88
|
tipGasPrice,
|
|
@@ -195,7 +197,6 @@ export const createTxFactory = ({ chainId, assetClientInterface, useAbsoluteNonc
|
|
|
195
197
|
return async ({
|
|
196
198
|
asset,
|
|
197
199
|
walletAccount,
|
|
198
|
-
feeData,
|
|
199
200
|
nft, // when sending nfts
|
|
200
201
|
fromAddress: providedFromAddress, // wallet from address
|
|
201
202
|
toAddress: providedToAddress, // user's to address, not the token or the dex contract
|
|
@@ -213,8 +214,16 @@ export const createTxFactory = ({ chainId, assetClientInterface, useAbsoluteNonc
|
|
|
213
214
|
keepTxInput, // @deprecated this flag is used by swaps when swapping a token via DEX. The asset is token but the tx TO address is not the token address. Update swap to use `contractAddress`
|
|
214
215
|
}) => {
|
|
215
216
|
assert(asset, 'asset is required')
|
|
216
|
-
assert(
|
|
217
|
-
|
|
217
|
+
assert(walletAccount, 'walletAccount is required')
|
|
218
|
+
|
|
219
|
+
const feeData = await assetClientInterface.getFeeConfig({ assetName: asset.baseAsset.name })
|
|
220
|
+
|
|
221
|
+
const fromAddress =
|
|
222
|
+
providedFromAddress ??
|
|
223
|
+
(await assetClientInterface.getReceiveAddress({
|
|
224
|
+
assetName: asset.baseAsset.name,
|
|
225
|
+
walletAccount,
|
|
226
|
+
}))
|
|
218
227
|
|
|
219
228
|
const baseAssetTxLog = await assetClientInterface.getTxLog({
|
|
220
229
|
assetName: asset.baseAsset.name,
|
|
@@ -320,7 +329,7 @@ export const createTxFactory = ({ chainId, assetClientInterface, useAbsoluteNonc
|
|
|
320
329
|
(await fetchGasLimit({
|
|
321
330
|
asset,
|
|
322
331
|
feeData,
|
|
323
|
-
fromAddress
|
|
332
|
+
fromAddress,
|
|
324
333
|
toAddress: providedToAddress,
|
|
325
334
|
txInput: providedTxInput,
|
|
326
335
|
contractAddress: txToAddress,
|
package/src/tx-send/tx-send.js
CHANGED
|
@@ -33,24 +33,9 @@ const txSendFactory = ({ assetClientInterface, createTx }) => {
|
|
|
33
33
|
return { unsignedTx: providedUnsignedTx }
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const feeData =
|
|
37
|
-
legacyParams.feeData ??
|
|
38
|
-
(await assetClientInterface.getFeeData({
|
|
39
|
-
assetName: baseAsset.name,
|
|
40
|
-
}))
|
|
41
|
-
|
|
42
|
-
const fromAddress =
|
|
43
|
-
legacyParams.fromAddress ??
|
|
44
|
-
(await assetClientInterface.getReceiveAddress({
|
|
45
|
-
assetName: baseAsset.name,
|
|
46
|
-
walletAccount,
|
|
47
|
-
}))
|
|
48
|
-
|
|
49
36
|
return createTx({
|
|
50
37
|
asset,
|
|
51
38
|
walletAccount,
|
|
52
|
-
feeData,
|
|
53
|
-
fromAddress,
|
|
54
39
|
toAddress: legacyParams.address,
|
|
55
40
|
...legacyParams,
|
|
56
41
|
...legacyParams.options,
|
package/src/get-fee-async.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import assert from 'minimalistic-assert'
|
|
2
|
-
|
|
3
|
-
import { getExtraFeeData } from './get-fee.js'
|
|
4
|
-
|
|
5
|
-
const getFeeAsyncFactory = ({ assetClientInterface, createTx }) => {
|
|
6
|
-
assert(assetClientInterface, 'assetClientInterface is required')
|
|
7
|
-
assert(createTx, 'createTx is required')
|
|
8
|
-
|
|
9
|
-
return async (params) => {
|
|
10
|
-
const { asset } = params
|
|
11
|
-
const { unsignedTx, gasPrice, tipGasPrice, gasLimit } = params.unsignedTx
|
|
12
|
-
? params
|
|
13
|
-
: await createTx(params)
|
|
14
|
-
const fee = asset.feeAsset.currency.parse(unsignedTx.txMeta.fee)
|
|
15
|
-
const coinAmount = asset.currency.parse(unsignedTx.txMeta.amount)
|
|
16
|
-
const extraFeeData = getExtraFeeData({ asset, amount: coinAmount })
|
|
17
|
-
return {
|
|
18
|
-
fee,
|
|
19
|
-
extraFeeData,
|
|
20
|
-
unsignedTx,
|
|
21
|
-
// deprecated, exchanges uses these params to recreate the tx during send. It should just use unsignedTx...
|
|
22
|
-
gasPrice,
|
|
23
|
-
tipGasPrice,
|
|
24
|
-
gasLimit,
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default getFeeAsyncFactory
|