@exodus/ethereum-api 8.48.0 → 8.50.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.50.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.49.0...@exodus/ethereum-api@8.50.0) (2025-09-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
* feat: replace deprecated apis with exodus/crypto/hash (#6483)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## [8.49.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.48.0...@exodus/ethereum-api@8.49.0) (2025-09-16)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
* feat: improve RPC error visibility (#6067)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
6
26
|
## [8.48.0](https://github.com/ExodusMovement/assets/compare/@exodus/ethereum-api@8.47.1...@exodus/ethereum-api@8.48.0) (2025-09-10)
|
|
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.50.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",
|
|
@@ -26,16 +26,17 @@
|
|
|
26
26
|
"@exodus/assets": "^11.4.0",
|
|
27
27
|
"@exodus/basic-utils": "^3.0.1",
|
|
28
28
|
"@exodus/bip44-constants": "^195.0.0",
|
|
29
|
-
"@exodus/crypto": "^1.0.0-rc.
|
|
29
|
+
"@exodus/crypto": "^1.0.0-rc.26",
|
|
30
30
|
"@exodus/currency": "^6.0.1",
|
|
31
31
|
"@exodus/ethereum-lib": "^5.17.0",
|
|
32
32
|
"@exodus/ethereum-meta": "^2.9.1",
|
|
33
33
|
"@exodus/ethereumholesky-meta": "^2.0.5",
|
|
34
|
-
"@exodus/ethereumjs": "^1.
|
|
34
|
+
"@exodus/ethereumjs": "^1.8.0",
|
|
35
35
|
"@exodus/fetch": "^1.3.0",
|
|
36
36
|
"@exodus/models": "^12.13.0",
|
|
37
|
+
"@exodus/safe-string": "^1.2.0",
|
|
37
38
|
"@exodus/simple-retry": "^0.0.6",
|
|
38
|
-
"@exodus/solidity-contract": "^1.
|
|
39
|
+
"@exodus/solidity-contract": "^1.3.0",
|
|
39
40
|
"@exodus/web3-ethereum-utils": "^4.2.1",
|
|
40
41
|
"bn.js": "^5.2.1",
|
|
41
42
|
"delay": "^4.0.1",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@exodus/assets-testing": "^1.0.0",
|
|
54
55
|
"@exodus/bsc-meta": "^2.5.1",
|
|
56
|
+
"@exodus/errors": "^3.3.0",
|
|
55
57
|
"@exodus/ethereumarbone-meta": "^2.1.2",
|
|
56
58
|
"@exodus/fantommainnet-meta": "^2.0.5",
|
|
57
59
|
"@exodus/matic-meta": "^2.2.7",
|
|
@@ -64,5 +66,5 @@
|
|
|
64
66
|
"type": "git",
|
|
65
67
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
66
68
|
},
|
|
67
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "05a8eb8fc2b399e3497825462f429970f559b8cc"
|
|
68
70
|
}
|
package/src/ens/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hashSync } from '@exodus/crypto/hash'
|
|
2
2
|
import { ABI } from '@exodus/ethereum-lib'
|
|
3
3
|
import SolidityContract from '@exodus/solidity-contract'
|
|
4
4
|
import idna from 'idna-uts46-hx'
|
|
@@ -24,7 +24,7 @@ function namehash(inputName) {
|
|
|
24
24
|
const name = normalize(inputName)
|
|
25
25
|
if (name) {
|
|
26
26
|
for (const label of name.split('.').reverse()) {
|
|
27
|
-
node = keccak256
|
|
27
|
+
node = hashSync('keccak256', [node, hashSync('keccak256', label, 'uint8')], 'buffer')
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { bufferToHex } from '@exodus/ethereumjs/util'
|
|
2
|
+
import { safeString } from '@exodus/safe-string'
|
|
2
3
|
import SolidityContract from '@exodus/solidity-contract'
|
|
3
4
|
import EventEmitter from 'events/events.js'
|
|
4
5
|
import lodash from 'lodash'
|
|
5
6
|
|
|
6
7
|
import { fromHexToString } from '../number-utils.js'
|
|
8
|
+
import { errorMessageToSafeHint } from './errors.js'
|
|
7
9
|
|
|
8
10
|
const { isEmpty } = lodash
|
|
9
11
|
|
|
@@ -52,8 +54,11 @@ export default class ApiCoinNodesServer extends EventEmitter {
|
|
|
52
54
|
const result = response?.result
|
|
53
55
|
const error = response?.error
|
|
54
56
|
if (error || result === undefined) {
|
|
55
|
-
const message = error?.message || error?.code ||
|
|
56
|
-
|
|
57
|
+
const message = error?.message || error?.code || safeString`no result`
|
|
58
|
+
|
|
59
|
+
const revisedError = new Error(`Bad rpc response: ${message}`)
|
|
60
|
+
revisedError.hint = safeString`Bad rpc response: ${errorMessageToSafeHint(message)}`
|
|
61
|
+
throw revisedError
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
return result
|
|
@@ -66,9 +66,6 @@ const fetchHttpRequest = ({ baseApiPath, path, method, body }) => {
|
|
|
66
66
|
return fetchJson(url, fetchOptions)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const fetchRpcHttpRequest = ({ baseApiPath, body }) =>
|
|
70
|
-
fetchHttpRequest({ baseApiPath, path: '/rpc', method: 'POST', body })
|
|
71
|
-
|
|
72
69
|
async function fetchJsonRetry(url, fetchOptions) {
|
|
73
70
|
const waitTimes = ['3s']
|
|
74
71
|
const fetchWithRetry = retry(fetchJson, { delayTimesMs: waitTimes })
|
|
@@ -187,6 +184,9 @@ export default class ClarityServerV2 extends ClarityServer {
|
|
|
187
184
|
}
|
|
188
185
|
}
|
|
189
186
|
|
|
187
|
+
fetchRpcHttpRequest = ({ baseApiPath, body }) =>
|
|
188
|
+
fetchHttpRequest({ baseApiPath, path: '/rpc', method: 'POST', body })
|
|
189
|
+
|
|
190
190
|
async sendRpcRequest(rpcRequest) {
|
|
191
191
|
try {
|
|
192
192
|
return await super.sendRpcRequest(rpcRequest)
|
|
@@ -196,20 +196,24 @@ export default class ClarityServerV2 extends ClarityServer {
|
|
|
196
196
|
if (err.message !== RPC_REQUEST_TIMEOUT) throw err
|
|
197
197
|
|
|
198
198
|
const { baseApiPath } = this
|
|
199
|
-
return fetchRpcHttpRequest({ baseApiPath, body: rpcRequest })
|
|
199
|
+
return this.fetchRpcHttpRequest({ baseApiPath, body: rpcRequest })
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
async sendRawTransaction(...params) {
|
|
204
204
|
const { baseApiPath } = this
|
|
205
205
|
const request = this.sendRawTransactionRequest(...params)
|
|
206
|
-
return this.handleJsonRPCResponse(
|
|
206
|
+
return this.handleJsonRPCResponse(
|
|
207
|
+
await this.fetchRpcHttpRequest({ baseApiPath, body: request })
|
|
208
|
+
)
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
async getTransactionCount(...params) {
|
|
210
212
|
// nonce is called during tx send, use it in rest api
|
|
211
213
|
const { baseApiPath } = this
|
|
212
214
|
const request = this.getTransactionCountRequest(...params)
|
|
213
|
-
return this.handleJsonRPCResponse(
|
|
215
|
+
return this.handleJsonRPCResponse(
|
|
216
|
+
await this.fetchRpcHttpRequest({ baseApiPath, body: request })
|
|
217
|
+
)
|
|
214
218
|
}
|
|
215
219
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { bufferToHex } from '@exodus/ethereumjs/util'
|
|
2
|
+
import { safeString } from '@exodus/safe-string'
|
|
2
3
|
import SolidityContract from '@exodus/solidity-contract'
|
|
3
4
|
import EventEmitter from 'events/events.js'
|
|
4
5
|
import io from 'socket.io-client'
|
|
5
6
|
|
|
6
7
|
import { fromHexToString } from '../number-utils.js'
|
|
8
|
+
import { errorMessageToSafeHint } from './errors.js'
|
|
7
9
|
|
|
8
10
|
export const RPC_REQUEST_TIMEOUT = 'RPC_REQUEST_TIMEOUT'
|
|
9
11
|
|
|
@@ -94,8 +96,11 @@ export default class ClarityServer extends EventEmitter {
|
|
|
94
96
|
const result = response?.result
|
|
95
97
|
const error = response?.error
|
|
96
98
|
if (error || result === undefined) {
|
|
97
|
-
const message = error?.message || error?.code ||
|
|
98
|
-
|
|
99
|
+
const message = error?.message || error?.code || safeString`no result`
|
|
100
|
+
|
|
101
|
+
const revisedError = new Error(`Bad rpc response: ${message}`)
|
|
102
|
+
revisedError.hint = safeString`Bad rpc response: ${errorMessageToSafeHint(message)}`
|
|
103
|
+
throw revisedError
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
return result
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { safeString } from '@exodus/safe-string'
|
|
2
|
+
|
|
3
|
+
// Transplated from: https://github.com/ethereum/go-ethereum/blob/master/core/txpool/errors.go.
|
|
4
|
+
const TxPoolErrors = {
|
|
5
|
+
ALREADY_KNOWN: safeString`already known`,
|
|
6
|
+
INVALID_SENDER: safeString`invalid sender`,
|
|
7
|
+
UNDERPRICED: safeString`transaction underpriced`,
|
|
8
|
+
REPLACE_UNDERPRICED: safeString`replacement transaction underpriced`,
|
|
9
|
+
TX_GAS_PRICE_TOO_LOW: safeString`transaction gas price below minimum`,
|
|
10
|
+
ACCOUNT_LIMIT_EXCEEDED: safeString`account limit exceeded`,
|
|
11
|
+
GAS_LIMIT: safeString`exceeds block gas limit`,
|
|
12
|
+
NEGATIVE_VALUE: safeString`negative value`,
|
|
13
|
+
OVERSIZED_DATA: safeString`oversized data`,
|
|
14
|
+
TX_BLOB_LIMIT_EXCEEDED: safeString`transaction blob limit exceeded`,
|
|
15
|
+
ALREADY_RESERVED: safeString`address already reserved`,
|
|
16
|
+
INFLIGHT_TX_LIMIT_REACHED: safeString`in-flight transaction limit reached for delegated accounts`,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DYNAMIC_RPC_ERRORS = {
|
|
20
|
+
TRANSACTION_TYPE_NOT_SUPPORTED: safeString`transaction type not supported`,
|
|
21
|
+
ONLY_REPLAY_PROTECTED_TRANSACTIONS: safeString`only replay-protected (EIP-155) transactions allowed over RPC`,
|
|
22
|
+
TRANSACTION_GAS_PRICE_BELOW_MINIMUM: safeString`transaction gas price below minimum`,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const KNOWN_RPC_ERRORS = { ...TxPoolErrors, ...DYNAMIC_RPC_ERRORS }
|
|
26
|
+
|
|
27
|
+
export const tryMappingToRpcErrors = (errorMessage) => {
|
|
28
|
+
if (typeof errorMessage !== 'string') return
|
|
29
|
+
|
|
30
|
+
return Object.values(KNOWN_RPC_ERRORS)
|
|
31
|
+
.sort((a, b) => b.length - a.length)
|
|
32
|
+
.find((knownRpcError) => errorMessage.includes(knownRpcError))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const errorMessageToSafeHint = (messageOrCode) =>
|
|
36
|
+
tryMappingToRpcErrors(messageOrCode) || messageOrCode
|