@exodus/ethereum-api 8.22.4 → 8.23.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 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.23.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.22.5...@exodus/ethereum-api@8.23.0) (2024-12-09)
7
+
8
+
9
+ ### Features
10
+
11
+
12
+ * feat: customFees api (#4653)
13
+
14
+
15
+
16
+ ## [8.22.5](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.22.4...@exodus/ethereum-api@8.22.5) (2024-12-09)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+
22
+ * fix: remove gasPriceEconomicalRate (#4659)
23
+
24
+
25
+
6
26
  ## [8.22.4](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.22.3...@exodus/ethereum-api@8.22.4) (2024-12-09)
7
27
 
8
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/ethereum-api",
3
- "version": "8.22.4",
3
+ "version": "8.23.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",
@@ -28,7 +28,7 @@
28
28
  "@exodus/bip44-constants": "^195.0.0",
29
29
  "@exodus/crypto": "^1.0.0-rc.13",
30
30
  "@exodus/currency": "^6.0.1",
31
- "@exodus/ethereum-lib": "^5.4.0",
31
+ "@exodus/ethereum-lib": "^5.8.1",
32
32
  "@exodus/ethereum-meta": "^2.1.5",
33
33
  "@exodus/ethereumholesky-meta": "^2.0.0",
34
34
  "@exodus/ethereumjs": "^1.0.0",
@@ -64,5 +64,5 @@
64
64
  "type": "git",
65
65
  "url": "git+https://github.com/ExodusMovement/assets.git"
66
66
  },
67
- "gitHead": "9271a07964a668a9903bd4268b893c83ca1118f9"
67
+ "gitHead": "4d505ee7d024c0ae961e2d95e6408b0b251a7d89"
68
68
  }
@@ -22,6 +22,7 @@ import ms from 'ms'
22
22
 
23
23
  import { addressHasHistoryFactory } from './address-has-history.js'
24
24
  import { createTokenFactory } from './create-token-factory.js'
25
+ import { createCustomFeesApi } from './custom-fees.js'
25
26
  import { createEvmServer } from './exodus-eth-server/index.js'
26
27
  import { createFeeData } from './fee-data-factory.js'
27
28
  import { createGetBalanceForAddress } from './get-balance-for-address.js'
@@ -62,6 +63,7 @@ export const createAssetFactory = ({
62
63
  stakingConfiguration = {},
63
64
  useEip1191ChainIdChecksum = false,
64
65
  forceGasLimitEstimation = false,
66
+ supportsCustomFees: defaultSupportsCustomFees = false,
65
67
  }) => {
66
68
  assert(assetsList, 'assetsList is required')
67
69
  assert(providedFeeData || feeDataConfig, 'feeData or feeDataConfig is required')
@@ -81,6 +83,7 @@ export const createAssetFactory = ({
81
83
  const defaultConfig = {
82
84
  allowMetaMaskCompat: false,
83
85
  supportsStaking: false,
86
+ supportsCustomFees: defaultSupportsCustomFees,
84
87
  nfts: defaultNfts,
85
88
  customTokens: defaultCustomTokens,
86
89
  }
@@ -93,7 +96,7 @@ export const createAssetFactory = ({
93
96
  ) => {
94
97
  const assets = connectAssetsList(assetsList)
95
98
 
96
- const { allowMetaMaskCompat, supportsStaking, nfts, customTokens } = {
99
+ const { allowMetaMaskCompat, supportsStaking, nfts, customTokens, supportsCustomFees } = {
97
100
  ...defaultConfig,
98
101
  ...config,
99
102
  }
@@ -156,6 +159,7 @@ export const createAssetFactory = ({
156
159
  noHistory: monitorType === 'no-history',
157
160
  signWithSigner: true,
158
161
  signMessageWithSigner: true,
162
+ supportsCustomFees,
159
163
  ...(supportsStaking && { staking: {} }),
160
164
  }
161
165
 
@@ -246,6 +250,7 @@ export const createAssetFactory = ({
246
250
  createHistoryMonitor,
247
251
  createToken,
248
252
  createUnsignedTx,
253
+ customFees: createCustomFeesApi({ baseAsset: asset }),
249
254
  defaultAddressPath,
250
255
  features,
251
256
  getBalances,
@@ -263,7 +268,7 @@ export const createAssetFactory = ({
263
268
  getSupportedPurposes: () => [44],
264
269
  getTokens,
265
270
  hasFeature: (feature) => !!features[feature], // @deprecated use api.features instead
266
- privateKeyEncodingDefinition: { encoding: 'hex', prefix: '0x' },
271
+ privateKeyEncodingDefinition: { encoding: 'hex' },
267
272
  sendTx,
268
273
  signTx: ({ unsignedTx, privateKey, signer }) =>
269
274
  signer
@@ -0,0 +1,26 @@
1
+ import NumberUnit from '@exodus/currency'
2
+
3
+ export const createCustomFeesApi = ({ baseAsset }) => {
4
+ const Gwei = baseAsset.currency.units.Gwei
5
+ return {
6
+ getRecommendedMinMaxFeeUnitPrices: ({ feeData }) => {
7
+ const { gasPrice, gasPriceMinimumRate, gasPriceMaximumRate } = feeData
8
+
9
+ const calculateFeeUnitPrice = (
10
+ feeUnitPrice,
11
+ multiplier = 1,
12
+ toAdd = baseAsset.currency.ZERO
13
+ ) => feeUnitPrice.to('Gwei').mul(multiplier).add(toAdd).toNumber(Gwei)
14
+
15
+ return {
16
+ recommended: calculateFeeUnitPrice(gasPrice),
17
+ min: calculateFeeUnitPrice(gasPrice, gasPriceMinimumRate),
18
+ max: calculateFeeUnitPrice(gasPrice, gasPriceMaximumRate),
19
+ }
20
+ },
21
+ unit: 'gwei/gas',
22
+ feeUnitPriceToNumber: (feeNumberUnit) => feeNumberUnit.toNumber(Gwei),
23
+ numberToFeeUnitPrice: (value) => new NumberUnit(value, Gwei),
24
+ isEnabled: ({ feeData }) => Boolean(feeData.rbfEnabled),
25
+ }
26
+ }
@@ -5,7 +5,6 @@ const createFeeDataConfigDefaults = ({ currency, feeDataConfig }) => {
5
5
  const shared = {
6
6
  tipGasPrice: '0 Gwei',
7
7
  fuelThreshold: '0 Gwei',
8
- gasPriceEconomicalRate: 0.8,
9
8
  gasPriceMinimumRate: 0.6,
10
9
  gasPriceMaximumRate: 1.3,
11
10
  }
package/src/get-fee.js CHANGED
@@ -1,27 +1,10 @@
1
- import { calculateBumpedGasPrice, calculateExtraEth, isEthereumLike } from '@exodus/ethereum-lib'
1
+ import { calculateBumpedGasPrice, calculateExtraEth } from '@exodus/ethereum-lib'
2
2
 
3
3
  // Move to meta?
4
4
  const taxes = {
5
5
  paxgold: 0.0002,
6
6
  }
7
7
 
8
- const getGasPriceMultiplier = ({ asset, feeData, isExchange, isSendAll, isRbfAllowed }) => {
9
- // exchanges quotes expire, do not risk having a stuck tx
10
-
11
- const gasPriceMultiplier = feeData.gasPriceMultiplier || 1
12
-
13
- if (isExchange) return gasPriceMultiplier
14
-
15
- // if eip1559 enabled, do not risk not leaving enough ETH to cover base fee (applies only for native asset)
16
- // (gasPrice difference will be reimbursed anyway: users do not overpay)
17
- if (isSendAll && isEthereumLike(asset) && feeData.eip1559Enabled) return gasPriceMultiplier
18
-
19
- // do not risk having a stuck tx if we're not able to accelerate it
20
- if (!isRbfAllowed || !feeData.rbfEnabled) return gasPriceMultiplier
21
-
22
- return feeData.gasPriceEconomicalRate || gasPriceMultiplier
23
- }
24
-
25
8
  const getExtraFeeData = ({ asset, amount }) => {
26
9
  const tax = taxes[asset.name]
27
10
  if (!amount || !tax || amount.isZero) {
@@ -51,13 +34,7 @@ export const getFeeFactory =
51
34
  }) => {
52
35
  const { gasPrice: feeDataGasPrice, eip1559Enabled, baseFeePerGas, tipGasPrice } = feeData
53
36
 
54
- const gasPriceMultiplier = getGasPriceMultiplier({
55
- asset,
56
- isRbfAllowed,
57
- feeData,
58
- isExchange,
59
- isSendAll,
60
- })
37
+ const gasPriceMultiplier = feeData.gasPriceMultiplier || 1
61
38
 
62
39
  const gasPrice = customFee || feeDataGasPrice.mul(gasPriceMultiplier)
63
40
 
@@ -14,7 +14,7 @@ const txSendFactory = ({ assetClientInterface, createUnsignedTx }) => {
14
14
  assert(createUnsignedTx, 'createUnsignedTx is required')
15
15
  return async ({ asset, walletAccount, address, amount, options = {} }) => {
16
16
  const { nft, bumpTxId, nonce: providedNonce, customFee, keepTxInput, isSendAll } = options
17
- let { txInput, feeAmount } = options // avoid let!
17
+ let { txInput } = options // avoid let!
18
18
 
19
19
  const feeOpts = {
20
20
  gasPrice: options.gasPrice,
@@ -27,12 +27,6 @@ const txSendFactory = ({ assetClientInterface, createUnsignedTx }) => {
27
27
 
28
28
  const assets = await assetClientInterface.getAssetsForNetwork({ baseAssetName: baseAsset.name })
29
29
 
30
- // Using a default zero value to not break code relying on the `tx.feeAmount` property.
31
- // For example, some exchange providers don't supply this.
32
- if (!feeAmount) {
33
- feeAmount = asset.baseAsset.currency.ZERO
34
- }
35
-
36
30
  const fromAddress = await assetClientInterface.getReceiveAddress({
37
31
  assetName: baseAsset.name,
38
32
  walletAccount,
@@ -95,7 +89,6 @@ const txSendFactory = ({ assetClientInterface, createUnsignedTx }) => {
95
89
  eip1559Enabled = feeData.eip1559Enabled && feeOpts.tipGasPrice
96
90
  bumpNonce = replacedTx.data.nonce
97
91
  txInput = replacedTokenTx ? null : replacedTx.data.data || '0x'
98
- feeAmount = feeOpts.gasPrice.mul(feeOpts.gasLimit)
99
92
  if (bumpNonce === undefined) {
100
93
  throw new Error(`Cannot bump transaction ${bumpTxId}: data object seems to be corrupted`)
101
94
  }
@@ -121,7 +114,9 @@ const txSendFactory = ({ assetClientInterface, createUnsignedTx }) => {
121
114
  isSendAll,
122
115
  createUnsignedTx,
123
116
  }
124
- let { txId, rawTx, nonce, gasLimit, tipGasPrice } = await createTx(createTxParams)
117
+ let { txId, rawTx, nonce, gasLimit, tipGasPrice, gasPrice } = await createTx(createTxParams)
118
+
119
+ const feeAmount = gasPrice.mul(gasLimit)
125
120
 
126
121
  try {
127
122
  await baseAsset.api.broadcastTx(rawTx.toString('hex'))