@exodus/ethereum-lib 5.16.1 → 5.17.1
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 +4 -4
- package/src/create-contract/index.js +1 -0
- package/src/selectors/get-can-accelerate-tx-factory.js +33 -44
- package/src/selectors/index.js +0 -2
- package/src/unsigned-tx/create-ethereumjs-tx.js +3 -1
- package/src/unsigned-tx/parse-unsigned-tx.js +2 -1
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
|
+
## [5.17.1](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.17.0...@exodus/ethereum-lib@5.17.1) (2025-08-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
* fix: wait 1 minute before allowing acceleration (#6286)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## [5.17.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.16.1...@exodus/ethereum-lib@5.17.0) (2025-08-04)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
* feat: demote batch of ETH tokens (#6159)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
6
26
|
## [5.16.1](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.16.0...@exodus/ethereum-lib@5.16.1) (2025-07-15)
|
|
7
27
|
|
|
8
28
|
**Note:** Version bump only for package @exodus/ethereum-lib
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ethereum-lib",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.17.1",
|
|
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",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"reselect": "^3.0.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@exodus/assets": "^11.
|
|
38
|
+
"@exodus/assets": "^11.4.0",
|
|
39
39
|
"@exodus/bitcoin-meta": "^2.0.0",
|
|
40
40
|
"@exodus/bsc-meta": "^2.3.0",
|
|
41
|
-
"@exodus/ethereum-meta": "^2.
|
|
41
|
+
"@exodus/ethereum-meta": "^2.9.0",
|
|
42
42
|
"@exodus/ethereumclassic-meta": "^2.0.0",
|
|
43
43
|
"@exodus/fantommainnet-meta": "^2.0.0",
|
|
44
44
|
"@exodus/matic-meta": "^2.0.0"
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"type": "git",
|
|
51
51
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "73ae94b56198ed572b7d7dbc302b24f8ac8ed290"
|
|
54
54
|
}
|
|
@@ -20,6 +20,7 @@ export default function createContract(address, contractName) {
|
|
|
20
20
|
case 'loomv2Swap':
|
|
21
21
|
return new SolidityContract(ABI.loomv2Swap, address, true)
|
|
22
22
|
case 'kyberv2':
|
|
23
|
+
case 'knc_ethereum_1be97263':
|
|
23
24
|
return new SolidityContract(ABI.kyberv2, address, true)
|
|
24
25
|
case 'maticValidatorShare':
|
|
25
26
|
return new SolidityContract(ABI.maticValidatorShare, address, true)
|
|
@@ -12,40 +12,7 @@ const BumpType = {
|
|
|
12
12
|
RBF: 2,
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
export function getPendingNonExchangeTxs(activeWalletAccount, getTxLog, getIsExchangeTx) {
|
|
17
|
-
console.log('Using deprecated function getPendingNonExchangeTxs()')
|
|
18
|
-
return getAssetPendingNonExchangeTxs('ethereum', activeWalletAccount, getTxLog, getIsExchangeTx)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function getAssetPendingNonExchangeTxs(
|
|
22
|
-
baseAssetName,
|
|
23
|
-
activeWalletAccount,
|
|
24
|
-
getTxLog,
|
|
25
|
-
getIsExchangeTx
|
|
26
|
-
) {
|
|
27
|
-
// check if the tx log even has pending transactions
|
|
28
|
-
const result = isQueuedPendingTx(
|
|
29
|
-
{ data: { nonce: Number.MAX_SAFE_INTEGER } },
|
|
30
|
-
baseAssetName,
|
|
31
|
-
activeWalletAccount,
|
|
32
|
-
getTxLog
|
|
33
|
-
)
|
|
34
|
-
if (!result) return []
|
|
35
|
-
|
|
36
|
-
const txLog = getTxLog(baseAssetName, activeWalletAccount)
|
|
37
|
-
const pendingNonExchangeTxs = []
|
|
38
|
-
for (let index = isQueuedPendingTx.minIndex; index < txLog.size; index++) {
|
|
39
|
-
const _tx = txLog.getAt(index)
|
|
40
|
-
if (_tx.pending && _tx.sent && !getIsExchangeTx(_tx.txId)) {
|
|
41
|
-
pendingNonExchangeTxs.push(_tx)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return pendingNonExchangeTxs
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function isQueuedPendingTx(tx, baseAssetName, activeWalletAccount, getTxLog) {
|
|
15
|
+
function isQueuedPendingTx(tx, baseAssetName, activeWalletAccount, getTxLog, now) {
|
|
49
16
|
const txLog = getTxLog(baseAssetName, activeWalletAccount)
|
|
50
17
|
if (!txLog || txLog.size === 0) return false
|
|
51
18
|
|
|
@@ -63,7 +30,7 @@ function isQueuedPendingTx(tx, baseAssetName, activeWalletAccount, getTxLog) {
|
|
|
63
30
|
if (nonce === undefined) continue
|
|
64
31
|
|
|
65
32
|
// ignore nonce of a TX that just replaced an another tx
|
|
66
|
-
if (_tx.data.replacedTxId &&
|
|
33
|
+
if (_tx.data.replacedTxId && now - _tx.date < MINUTE) continue
|
|
67
34
|
if (_tx.sent && nonce < minPendingNonce) {
|
|
68
35
|
minPendingNonce = nonce
|
|
69
36
|
isQueuedPendingTx.minIndex = index
|
|
@@ -220,11 +187,12 @@ export const calculateBumpedGasPrice = ({
|
|
|
220
187
|
// `gasPrice` of the previous transaction).
|
|
221
188
|
const prevMaxFeePerGas = calculateTxGasPrice(tx)
|
|
222
189
|
|
|
223
|
-
if (!eip1559Enabled)
|
|
190
|
+
if (!eip1559Enabled) {
|
|
224
191
|
return calculateBumpedGasPriceNonEip1559({
|
|
225
192
|
currentGasPrice,
|
|
226
193
|
prevMaxFeePerGas,
|
|
227
194
|
})
|
|
195
|
+
}
|
|
228
196
|
|
|
229
197
|
if (!currentBaseFee) {
|
|
230
198
|
// NOTE: This can result in differences between predicted and realized fees.
|
|
@@ -260,24 +228,40 @@ export const canAccelerateTx = ({
|
|
|
260
228
|
getIsEnoughBalanceToAccelerate,
|
|
261
229
|
getTxLog,
|
|
262
230
|
getIsExchangeTx,
|
|
231
|
+
now,
|
|
263
232
|
}) => {
|
|
264
233
|
const assetName = tx.coinName
|
|
265
234
|
const baseAsset = assets[assetName].baseAsset
|
|
266
235
|
const baseAssetName = baseAsset.name
|
|
236
|
+
|
|
267
237
|
if (!getIsRbfEnabled(assetName)) return wrapResponseToObject({ errorMessage: 'rbf is disabled' })
|
|
268
|
-
if (!isEthereumLike(assets[assetName]))
|
|
238
|
+
if (!isEthereumLike(assets[assetName])) {
|
|
269
239
|
return wrapResponseToObject({ errorMessage: `not an ETH/ERC20/BSC/BEP20 asset supplied` })
|
|
270
|
-
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!tx.pending || !tx.sent) {
|
|
271
243
|
return wrapResponseToObject({ errorMessage: 'can not bump a confirmed or received TX' })
|
|
272
|
-
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (!tx.data || !(tx.data.gasLimit || tx.data.tipGasPrice)) {
|
|
273
247
|
return wrapResponseToObject({ errorMessage: 'data object is missing or corrupted' })
|
|
248
|
+
}
|
|
249
|
+
|
|
274
250
|
const isExchangeTx = getIsExchangeTx(tx.txId)
|
|
275
251
|
if (isExchangeTx) return wrapResponseToObject({ errorMessage: 'can not bump an exchange TX' })
|
|
252
|
+
|
|
253
|
+
if (now - tx.date < MINUTE) {
|
|
254
|
+
return wrapResponseToObject({ errorMessage: 'wait before allowing acceleration' })
|
|
255
|
+
}
|
|
256
|
+
|
|
276
257
|
const personalNote = getPersonalNoteByTxId(tx.txId)
|
|
277
|
-
if (personalNote && personalNote.dapp)
|
|
258
|
+
if (personalNote && personalNote.dapp) {
|
|
278
259
|
return wrapResponseToObject({ errorMessage: 'can not bump a dapp TX' })
|
|
279
|
-
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (isQueuedPendingTx(tx, baseAssetName, activeWalletAccount, getTxLog, now)) {
|
|
280
263
|
return wrapResponseToObject({ errorMessage: 'there is a stuck TX with lower nonce' })
|
|
264
|
+
}
|
|
281
265
|
|
|
282
266
|
const {
|
|
283
267
|
gasPrice: currentGasPrice,
|
|
@@ -298,8 +282,9 @@ export const canAccelerateTx = ({
|
|
|
298
282
|
|
|
299
283
|
const extraEthNeeded = replacementFee.sub(tx.feeAmount)
|
|
300
284
|
|
|
301
|
-
if (!getIsEnoughBalanceToAccelerate(activeWalletAccount, baseAssetName, extraEthNeeded))
|
|
285
|
+
if (!getIsEnoughBalanceToAccelerate(activeWalletAccount, baseAssetName, extraEthNeeded)) {
|
|
302
286
|
return wrapResponseToObject({ errorMessage: 'insufficient funds' })
|
|
287
|
+
}
|
|
303
288
|
|
|
304
289
|
return wrapResponseToObject({ bumpType: BumpType.RBF })
|
|
305
290
|
}
|
|
@@ -313,7 +298,8 @@ const getCanAccelerateTxFactory = (
|
|
|
313
298
|
getIsEnoughBalanceToAccelerateSelector,
|
|
314
299
|
getTxLogSelector,
|
|
315
300
|
getIsExchangeTxSelector,
|
|
316
|
-
assetsSelector
|
|
301
|
+
assetsSelector,
|
|
302
|
+
timeSelector
|
|
317
303
|
) =>
|
|
318
304
|
createSelector(
|
|
319
305
|
getFeeDataSelector,
|
|
@@ -325,6 +311,7 @@ const getCanAccelerateTxFactory = (
|
|
|
325
311
|
getTxLogSelector,
|
|
326
312
|
getIsExchangeTxSelector,
|
|
327
313
|
assetsSelector,
|
|
314
|
+
timeSelector,
|
|
328
315
|
(
|
|
329
316
|
getFeeData,
|
|
330
317
|
getFee,
|
|
@@ -334,7 +321,8 @@ const getCanAccelerateTxFactory = (
|
|
|
334
321
|
getIsEnoughBalanceToAccelerate,
|
|
335
322
|
getTxLog,
|
|
336
323
|
getIsExchangeTx,
|
|
337
|
-
assets
|
|
324
|
+
assets,
|
|
325
|
+
now
|
|
338
326
|
) =>
|
|
339
327
|
(tx) =>
|
|
340
328
|
canAccelerateTx({
|
|
@@ -348,6 +336,7 @@ const getCanAccelerateTxFactory = (
|
|
|
348
336
|
getIsEnoughBalanceToAccelerate,
|
|
349
337
|
getTxLog,
|
|
350
338
|
getIsExchangeTx,
|
|
339
|
+
now,
|
|
351
340
|
})
|
|
352
341
|
)
|
|
353
342
|
|
package/src/selectors/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export {
|
|
2
2
|
default as getCanAccelerateTxFactory,
|
|
3
3
|
calculateBumpedGasPrice,
|
|
4
|
-
getPendingNonExchangeTxs,
|
|
5
|
-
getAssetPendingNonExchangeTxs,
|
|
6
4
|
} from './get-can-accelerate-tx-factory.js'
|
|
7
5
|
|
|
8
6
|
export { default as getIsEnoughBalanceToAccelerateSelectorFactory } from './get-is-enough-balance-to-accelerate-factory.js'
|
|
@@ -13,7 +13,7 @@ const parseBufferToJsTx = (unsignedTx) => {
|
|
|
13
13
|
'Cannot create ethereum js tx when transactionBuffer and other fields are provided!'
|
|
14
14
|
)
|
|
15
15
|
assert(chainId, 'chainId must be provided when parsing from transaction buffer!!!')
|
|
16
|
-
if (FeeMarketEIP1559Transaction.isEip1559SerializedTx(transactionBuffer))
|
|
16
|
+
if (FeeMarketEIP1559Transaction.isEip1559SerializedTx(transactionBuffer)) {
|
|
17
17
|
return FeeMarketEIP1559Transaction.fromSerializedTx(transactionBuffer, {
|
|
18
18
|
common: Common.custom(
|
|
19
19
|
{
|
|
@@ -22,6 +22,8 @@ const parseBufferToJsTx = (unsignedTx) => {
|
|
|
22
22
|
{ hardfork: Hardfork.London }
|
|
23
23
|
),
|
|
24
24
|
})
|
|
25
|
+
}
|
|
26
|
+
|
|
25
27
|
return Transaction.fromSerializedTx(transactionBuffer, {
|
|
26
28
|
common: Common.custom({
|
|
27
29
|
chainId,
|
|
@@ -48,11 +48,12 @@ function resolveToAmount({ asset, data, value, to: rawTo }) {
|
|
|
48
48
|
|
|
49
49
|
if (_isToken) {
|
|
50
50
|
const { method, values } = asset.contract.decodeInput(data)
|
|
51
|
-
if (method === 'transfer' || method === 'approve')
|
|
51
|
+
if (method === 'transfer' || method === 'approve') {
|
|
52
52
|
return {
|
|
53
53
|
to: values[0],
|
|
54
54
|
amount: asset.currency.baseUnit(values[1]),
|
|
55
55
|
}
|
|
56
|
+
}
|
|
56
57
|
|
|
57
58
|
return { to: values[0], amount: asset.currency.ZERO }
|
|
58
59
|
}
|