@exodus/ethereum-lib 5.20.1 → 5.20.3
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,24 @@
|
|
|
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
|
+
## [5.20.3](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.20.2...@exodus/ethereum-lib@5.20.3) (2025-12-22)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @exodus/ethereum-lib
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [5.20.2](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.20.1...@exodus/ethereum-lib@5.20.2) (2025-12-17)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
* fix: prevent acceleration of replaced evm transactions (#6964)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
6
24
|
## [5.20.1](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.20.0...@exodus/ethereum-lib@5.20.1) (2025-12-09)
|
|
7
25
|
|
|
8
26
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ethereum-lib",
|
|
3
|
-
"version": "5.20.
|
|
3
|
+
"version": "5.20.3",
|
|
4
4
|
"description": "Ethereum utils, such as for cryptography, address encoding/decoding, transaction building, etc.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"type": "git",
|
|
52
52
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "5c1f2c3c6c7562c8344fc816d88e44b8f4dd4e8d"
|
|
55
55
|
}
|
package/src/constants.js
CHANGED
|
@@ -12,6 +12,57 @@ const BumpType = {
|
|
|
12
12
|
RBF: 2,
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
// NOTE: If a transaction was successfully included,
|
|
16
|
+
// it is the de-facto highest incentive
|
|
17
|
+
// transaction - irrespective of other
|
|
18
|
+
// attempts for that nonce.
|
|
19
|
+
const getHighestIncentiveTxByNonceForTxLog = ({ nonce, txLog }) => {
|
|
20
|
+
assert(txLog, 'expected txLog')
|
|
21
|
+
|
|
22
|
+
if (txLog.size === 0 || !Number.isInteger(nonce)) return
|
|
23
|
+
|
|
24
|
+
const txLogSendsByFeeAmountDesc = [...txLog]
|
|
25
|
+
.filter((tx) => tx.data.nonce === nonce && tx.sent)
|
|
26
|
+
.sort((a, b) => (a.feeAmount.gt(b.feeAmount) ? -1 : b.feeAmount.gt(a.feeAmount) ? 1 : 0))
|
|
27
|
+
|
|
28
|
+
// If any of the transactions competing for this `nonce`
|
|
29
|
+
// were successful, then we can return this transaction
|
|
30
|
+
// as it effectively had the highest game-theoretical
|
|
31
|
+
// incentive regardless of other (potentially higher fee)
|
|
32
|
+
// transactions that were sent.
|
|
33
|
+
//
|
|
34
|
+
// https://github.com/ExodusMovement/exodus-hydra/blob/e59004097f15974a975d14e1823de5d7b1c28308/features/activity-txs/redux/utils/activity-formatters/format-tx-activity.js#L13
|
|
35
|
+
const maybeConfirmedTx = txLogSendsByFeeAmountDesc.find((tx) => !tx.failed && !tx.pending)
|
|
36
|
+
if (maybeConfirmedTx) return maybeConfirmedTx
|
|
37
|
+
|
|
38
|
+
// https://github.com/ExodusMovement/assets/blob/fbe3702861cba3b21885a65b15f038fcd8541891/shield/asset-lib/src/balances-utils.js#L26
|
|
39
|
+
const isUnconfirmed = (tx) => !tx.failed && tx.pending
|
|
40
|
+
|
|
41
|
+
// NOTE: When trying to find the highest incentive of a
|
|
42
|
+
// transaction, consider those which are still
|
|
43
|
+
// pending.
|
|
44
|
+
return txLogSendsByFeeAmountDesc.find(isUnconfirmed)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Returns the most competitively priced pending
|
|
48
|
+
// transaction from the `TxLog` for a given `nonce`.
|
|
49
|
+
export const getHighestIncentiveTxByNonce = async ({
|
|
50
|
+
assetClientInterface,
|
|
51
|
+
asset,
|
|
52
|
+
nonce,
|
|
53
|
+
walletAccount,
|
|
54
|
+
}) => {
|
|
55
|
+
assert(assetClientInterface, 'expected assetClientInterface')
|
|
56
|
+
assert(asset, 'expected asset')
|
|
57
|
+
assert(Number.isInteger(nonce), 'expected integer nonce')
|
|
58
|
+
assert(walletAccount, 'expected walletAccount')
|
|
59
|
+
|
|
60
|
+
return getHighestIncentiveTxByNonceForTxLog({
|
|
61
|
+
txLog: await assetClientInterface.getTxLog({ assetName: asset.name, walletAccount }),
|
|
62
|
+
nonce,
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
15
66
|
// Legacy compatibility with wallets
|
|
16
67
|
export function getPendingNonExchangeTxs(activeWalletAccount, getTxLog, getIsExchangeTx) {
|
|
17
68
|
console.log('Using deprecated function getPendingNonExchangeTxs()')
|
|
@@ -348,6 +399,20 @@ export const canAccelerateTx = ({
|
|
|
348
399
|
return wrapResponseToObject({ errorMessage: 'there is a stuck TX with lower nonce' })
|
|
349
400
|
}
|
|
350
401
|
|
|
402
|
+
// Check to see if this is the highest incentive transaction for this nonce.
|
|
403
|
+
const maybeHighestIncentiveTxByNonce = getHighestIncentiveTxByNonceForTxLog({
|
|
404
|
+
// TODO: is this the correct way to determine a nonce?
|
|
405
|
+
nonce: tx.data.nonce,
|
|
406
|
+
txLog: getTxLog(baseAssetName, activeWalletAccount),
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
// NOTE: We should only be able to accelerate the highest
|
|
410
|
+
// incentive transaction which is competing for a
|
|
411
|
+
// given `nonce`.
|
|
412
|
+
if (maybeHighestIncentiveTxByNonce && maybeHighestIncentiveTxByNonce.txId !== tx.txId) {
|
|
413
|
+
return wrapResponseToObject({ errorMessage: 'TX was replaced' })
|
|
414
|
+
}
|
|
415
|
+
|
|
351
416
|
const {
|
|
352
417
|
gasPrice: currentGasPrice,
|
|
353
418
|
eip1559Enabled,
|
package/src/selectors/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export {
|
|
|
4
4
|
calculateBumpedGasPriceForFeeData,
|
|
5
5
|
getPendingNonExchangeTxs,
|
|
6
6
|
getAssetPendingNonExchangeTxs,
|
|
7
|
+
getHighestIncentiveTxByNonce,
|
|
7
8
|
} from './get-can-accelerate-tx-factory.js'
|
|
8
9
|
|
|
9
10
|
export { default as getIsEnoughBalanceToAccelerateSelectorFactory } from './get-is-enough-balance-to-accelerate-factory.js'
|