@exodus/ethereum-lib 5.22.0 → 5.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,30 @@
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.23.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.22.1...@exodus/ethereum-lib@5.23.0) (2026-04-15)
7
+
8
+
9
+ ### Features
10
+
11
+
12
+ * feat: evm duplex transactions (#7688)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+
18
+ * fix: lint failed by ethereum-plugin (#7758)
19
+
20
+
21
+
22
+ ## [5.22.1](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.22.0...@exodus/ethereum-lib@5.22.1) (2026-03-26)
23
+
24
+ **Note:** Version bump only for package @exodus/ethereum-lib
25
+
26
+
27
+
28
+
29
+
6
30
  ## [5.22.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-lib@5.21.2...@exodus/ethereum-lib@5.22.0) (2026-03-12)
7
31
 
8
32
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/ethereum-lib",
3
- "version": "5.22.0",
3
+ "version": "5.23.0",
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",
@@ -27,7 +27,7 @@
27
27
  "@exodus/currency": "^6.0.1",
28
28
  "@exodus/ethereumjs": "^1.6.0",
29
29
  "@exodus/key-utils": "^3.7.0",
30
- "@exodus/models": "^12.13.0",
30
+ "@exodus/models": "^13.0.0",
31
31
  "@exodus/solidity-contract": "^1.1.3",
32
32
  "base-x": "^3.0.2",
33
33
  "lodash": "^4.17.15",
@@ -51,5 +51,5 @@
51
51
  "type": "git",
52
52
  "url": "git+https://github.com/ExodusMovement/assets.git"
53
53
  },
54
- "gitHead": "bdd3658f4f045809a360f53f0fd2027293c00de8"
54
+ "gitHead": "c19a882fd4aca9cd1b2bd4c86b6e60992bd3e2c7"
55
55
  }
@@ -1,3 +1,4 @@
1
+ // eslint-disable-next-line @exodus/import/no-deprecated
1
2
  import { isNumberUnit } from '@exodus/currency'
2
3
  import lodash from 'lodash'
3
4
 
@@ -5,6 +6,7 @@ const { isNumber, isString } = lodash
5
6
 
6
7
  function parseBalance({ asset, balance }) {
7
8
  const currency = asset.currency
9
+ // eslint-disable-next-line @exodus/import/no-deprecated
8
10
  if (isNumberUnit(balance)) {
9
11
  if (balance.unitType.equals(currency)) {
10
12
  return balance
@@ -123,7 +123,7 @@ const wrapResponseToObject = ({ bumpType = BumpType.NONE, errorMessage = null }
123
123
  errorMessage,
124
124
  })
125
125
 
126
- const calculateTxGasPrice = (tx) => tx.feeAmount.div(tx.data.gasLimit)
126
+ export const calculateTxGasPrice = (tx) => tx.feeAmount.div(tx.data.gasLimit)
127
127
 
128
128
  const calculateBumpedGasPriceNonEip1559 = ({ currentGasPrice, prevMaxFeePerGas }) => {
129
129
  assert(currentGasPrice, 'currentGasPrice is required')
@@ -1,5 +1,6 @@
1
1
  export {
2
2
  default as getCanAccelerateTxFactory,
3
+ calculateTxGasPrice,
3
4
  calculateBumpedGasPrice,
4
5
  calculateBumpedGasPriceForFeeData,
5
6
  getPendingNonExchangeTxs,
@@ -1,7 +1,24 @@
1
+ import NumberUnit from '@exodus/currency'
1
2
  import { intToBuffer, toBuffer } from '@exodus/ethereumjs/util'
2
3
  import assert from 'minimalistic-assert'
3
4
 
4
- import { currency2buffer, isToken } from '../utils/index.js'
5
+ import { currency2buffer, isEthereumLikeToken, isToken } from '../utils/index.js'
6
+
7
+ export const assertValidTxValue = ({ asset, amount, txValue: providedTxValue }) => {
8
+ if (!providedTxValue && isEthereumLikeToken(asset)) return asset.baseAsset.currency.ZERO
9
+
10
+ if (!providedTxValue) return amount
11
+
12
+ assert(
13
+ providedTxValue instanceof NumberUnit &&
14
+ providedTxValue.unitType.equals(asset.baseAsset.currency),
15
+ 'invalid txValue'
16
+ )
17
+
18
+ assert(asset !== asset.baseAsset || providedTxValue.equals(amount), 'inconsistent txValue')
19
+
20
+ return providedTxValue
21
+ }
5
22
 
6
23
  export default function createUnsignedTxFactory({ chainId }) {
7
24
  assert(typeof chainId === 'number', 'chainId is required')
@@ -11,6 +28,7 @@ export default function createUnsignedTxFactory({ chainId }) {
11
28
  amount,
12
29
  nonce,
13
30
  txInput,
31
+ txValue,
14
32
  gasLimit,
15
33
  gasPrice, // eip 1559: `maxFeePerGas`
16
34
  tipGasPrice, // eip 1559: `maxPriorityPerGas`
@@ -21,6 +39,8 @@ export default function createUnsignedTxFactory({ chainId }) {
21
39
  const baseAsset = asset.baseAsset
22
40
  assert(chainId, 'chainId is required')
23
41
 
42
+ txValue = assertValidTxValue({ asset, amount, txValue })
43
+
24
44
  if (txInput) {
25
45
  txInput = toBuffer(txInput) // If txInput is already a Buffer, then it is passed through
26
46
  } else {
@@ -29,7 +49,7 @@ export default function createUnsignedTxFactory({ chainId }) {
29
49
 
30
50
  const _isToken = isToken(asset)
31
51
  const to = _isToken ? asset.contract.address : address
32
- let value = currency2buffer(_isToken ? baseAsset.currency.ZERO : amount)
52
+ let value = currency2buffer(txValue)
33
53
 
34
54
  // TODO: check: present on desktop missing on mobile. This insures we never have a buffer specifying 0.
35
55
  // In ETH, a buffer of zero length and a buffer specifying 0 imply different things
@@ -1,4 +1,4 @@
1
- export { default as createUnsignedTxFactory } from './create-unsigned-tx.js'
1
+ export { default as createUnsignedTxFactory, assertValidTxValue } from './create-unsigned-tx.js'
2
2
  export { default as parseUnsignedTx } from './parse-unsigned-tx.js'
3
3
  export { default as signUnsignedTx, signUnsignedTxWithSigner } from './sign-unsigned-tx.js'
4
4
  export { default as createAndSignTxFactory } from './create-and-sign-tx.js'
@@ -1,3 +1,4 @@
1
+ // eslint-disable-next-line @exodus/import/no-deprecated
1
2
  import { isNumberUnit } from '@exodus/currency'
2
3
  import { FeeMarketEIP1559Transaction, Transaction } from '@exodus/ethereumjs/tx'
3
4
  import { bufferToInt } from '@exodus/ethereumjs/util'
@@ -74,6 +75,7 @@ function resolveToAmount({ asset, data, value, to: rawTo }) {
74
75
  }
75
76
 
76
77
  function toNumberUnit(asset, amount) {
78
+ // eslint-disable-next-line @exodus/import/no-deprecated
77
79
  if (isNumberUnit(amount)) {
78
80
  return amount
79
81
  }
@@ -92,7 +94,7 @@ export default function parseUnsignedTx({ asset, unsignedTx }) {
92
94
  const baseAsset = asset.baseAsset
93
95
  const txData = unsignedTx.txData
94
96
  const {
95
- to: rawTo,
97
+ to: txToAddress,
96
98
  data,
97
99
  value,
98
100
  gasLimit,
@@ -115,7 +117,7 @@ export default function parseUnsignedTx({ asset, unsignedTx }) {
115
117
  nonce: bufferToInt(txData.nonce),
116
118
  }
117
119
 
118
- const { to, amount: resolvedAmount } = resolveToAmount({ asset, data, value, to: rawTo })
120
+ const { to, amount: resolvedAmount } = resolveToAmount({ asset, data, value, to: txToAddress })
119
121
 
120
122
  // the txMeta.fee may include implicit l1 fees
121
123
  const fee = unsignedTx.txMeta?.fee
@@ -128,15 +130,20 @@ export default function parseUnsignedTx({ asset, unsignedTx }) {
128
130
  : resolvedAmount ?? asset.currency.ZERO
129
131
 
130
132
  return {
131
- to,
133
+ to, // TODO: This should be {address,toAddress}
132
134
  amount,
133
135
  fee,
134
136
  gasLimit,
135
137
  gasPrice,
136
- tipGasPrice,
138
+ // HACK: Backwards compatibility. Where falsy,
139
+ // the `tipGasPrice` should be omitted,
140
+ // rather than declared as a falsy key.
141
+ ...(tipGasPrice ? { tipGasPrice } : null),
137
142
  eip1559Enabled,
138
143
  nonce,
139
144
  from: null, // TODO: how?
140
145
  data,
146
+ value,
147
+ txToAddress,
141
148
  }
142
149
  }