@exodus/ethereum-api 9.0.0-alpha.3 → 9.0.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 +2121 -0
- package/LICENSE +7 -0
- package/README.md +124 -0
- package/package.json +34 -33
- package/src/address-has-history.js +6 -2
- package/src/allowance/constants.js +4 -5
- package/src/allowance/index.js +159 -40
- package/src/check-tx/create-assess-transaction.js +23 -0
- package/src/check-tx/create-check-tx.js +104 -0
- package/src/check-tx/index.js +1 -0
- package/src/create-asset-plugin-factory.js +115 -0
- package/src/create-asset-utils.js +520 -0
- package/src/create-asset.js +272 -97
- package/src/create-token-factory.js +47 -17
- package/src/custom-fees.js +57 -0
- package/src/eip7702-whitelist.js +62 -0
- package/src/ens/index.js +12 -17
- package/src/error-wrapper.js +383 -0
- package/src/eth-like-util.js +172 -33
- package/src/exodus-eth-server/api-coin-nodes.js +27 -196
- package/src/exodus-eth-server/api.js +23 -14
- package/src/exodus-eth-server/clarity-v2.js +255 -0
- package/src/exodus-eth-server/clarity.js +67 -265
- package/src/exodus-eth-server/errors.js +40 -0
- package/src/exodus-eth-server/eth-like-server.js +385 -0
- package/src/exodus-eth-server/fetch-json.js +48 -0
- package/src/exodus-eth-server/index.js +77 -0
- package/src/exodus-eth-server/utils.js +31 -0
- package/src/exodus-eth-server/ws-gateway.js +306 -0
- package/src/exodus-eth-server/ws.js +1 -2
- package/src/fee-data/EthLikeFeeData.js +81 -0
- package/src/fee-data/index.js +54 -0
- package/src/fee-utils.js +229 -0
- package/src/gas-estimation.js +183 -66
- package/src/get-balance-for-address.js +1 -1
- package/src/get-balances.js +285 -27
- package/src/get-fee.js +92 -56
- package/src/get-historical-balance.js +58 -0
- package/src/hooks/index.js +1 -1
- package/src/hooks/monitor.js +182 -43
- package/src/hooks/staking-freshness.js +58 -0
- package/src/index.js +118 -12
- package/src/move-funds.js +153 -0
- package/src/multicall3/index.js +212 -0
- package/src/multisig-address.js +146 -0
- package/src/nft-utils.js +60 -0
- package/src/number-utils.js +34 -2
- package/src/optimism-gas/index.js +13 -5
- package/src/send-validations.js +58 -0
- package/src/server-based-fee-monitor.js +12 -19
- package/src/simulate-tx/fetch-tx-preview.js +0 -2
- package/src/simulate-tx/index.js +2 -2
- package/src/simulate-tx/simulate-eth-tx.js +24 -11
- package/src/simulation/common.js +34 -0
- package/src/simulation/create-simulate-message.js +49 -0
- package/src/simulation/create-simulate-transactions.js +108 -0
- package/src/simulation/estimate-fee.js +14 -0
- package/src/simulation/estimate-simple-transfer.js +15 -0
- package/src/simulation/get-message-type.js +18 -0
- package/src/simulation/simulate-message-api.js +68 -0
- package/src/simulation/simulate-transactions-api.js +266 -0
- package/src/simulation/simulate-transactions.js +16 -0
- package/src/simulation/transactions.js +52 -0
- package/src/simulation/try-estimating-changes-locally.js +26 -0
- package/src/staking/api/index.js +43 -0
- package/src/staking/cached-read.js +33 -0
- package/src/staking/ethereum/api.js +166 -34
- package/src/staking/ethereum/deps.js +37 -0
- package/src/staking/ethereum/everstake.js +113 -0
- package/src/staking/ethereum/index.js +4 -3
- package/src/staking/ethereum/service.js +682 -181
- package/src/staking/ethereum/staking-utils.js +275 -4
- package/src/staking/fantom-staking.js +9 -9
- package/src/staking/index.js +4 -4
- package/src/staking/matic/addresses.js +2 -0
- package/src/staking/matic/api.js +69 -49
- package/src/staking/matic/index.js +3 -3
- package/src/staking/matic/matic-staking-utils.js +243 -5
- package/src/staking/matic/matic-staking.md +53 -0
- package/src/staking/staking-provider-client.js +1 -1
- package/src/staking/utils/index.js +39 -0
- package/src/tx-create.js +666 -0
- package/src/tx-log/clarity-monitor.js +273 -103
- package/src/tx-log/clarity-truncated-history-monitor.js +109 -0
- package/src/tx-log/clarity-truncated-history-monitor.md +219 -0
- package/src/tx-log/clarity-utils/absolute.js +96 -0
- package/src/tx-log/clarity-utils/get-log-items-from-server-tx.js +94 -31
- package/src/tx-log/clarity-utils/get-names-of-tokens-transferred-by-server-tx.js +3 -2
- package/src/tx-log/clarity-utils/index.js +9 -3
- package/src/tx-log/clarity-utils/is-spam-pending-tx.js +13 -0
- package/src/tx-log/clarity-utils/normalize-transactions-response.js +65 -0
- package/src/tx-log/ethereum-monitor.js +93 -47
- package/src/tx-log/ethereum-no-history-monitor.js +52 -41
- package/src/tx-log/get-optimistic-txlog-effects.js +379 -0
- package/src/tx-log/index.js +5 -3
- package/src/tx-log/monitor-utils/check-pending-transactions.js +14 -5
- package/src/tx-log/monitor-utils/exclude-unchanged-token-balances.js +1 -1
- package/src/tx-log/monitor-utils/extract-balance-from-clarity-account-info.js +108 -0
- package/src/tx-log/monitor-utils/get-balance-updates.js +44 -0
- package/src/tx-log/monitor-utils/get-batched-rpc-balances.js +47 -0
- package/src/tx-log/monitor-utils/get-current-blacklist-status.js +38 -0
- package/src/tx-log/monitor-utils/get-current-eip7702-delegation.js +79 -0
- package/src/tx-log/monitor-utils/get-derive-transactions-to-check.js +10 -5
- package/src/tx-log/monitor-utils/get-fee-amount.js +1 -1
- package/src/tx-log/monitor-utils/get-history-from-server.js +1 -1
- package/src/tx-log/monitor-utils/get-log-items-from-server-tx.js +75 -33
- package/src/tx-log/monitor-utils/get-names-of-tokens-transferred-by-server-tx.js +3 -2
- package/src/tx-log/monitor-utils/get-raw-transfer-amount.js +29 -0
- package/src/tx-log/monitor-utils/get-transfers-by-token-name.js +3 -2
- package/src/tx-log/monitor-utils/get-value-of-transfers.js +10 -12
- package/src/tx-log/monitor-utils/index.js +12 -7
- package/src/tx-log/monitor-utils/is-unverifiable-pending-tx-expired.js +19 -0
- package/src/tx-log/monitor-utils/verify-pending-tx-status-rpc.js +90 -0
- package/src/tx-log-staking-processor/asset-staking-tx-data.js +82 -24
- package/src/tx-log-staking-processor/index.js +28 -14
- package/src/tx-log-staking-processor/utils.js +21 -20
- package/src/tx-send/broadcast-error-handler.js +63 -0
- package/src/tx-send/index.js +1 -2
- package/src/tx-send/nonce-utils.js +97 -0
- package/src/tx-send/tx-send.js +94 -288
- package/src/tx-sign/index.js +17 -0
- package/src/tx-type/index.js +280 -0
- package/src/watch-tx.js +36 -0
- package/src/web3/createSimulateMessage.js +3 -2
- package/src/web3/createSimulateTransactions.js +11 -0
- package/src/web3/index.js +3 -1
- package/src/etherscan/account.js +0 -49
- package/src/etherscan/index.js +0 -28
- package/src/etherscan/logs.js +0 -16
- package/src/etherscan/proxy.js +0 -47
- package/src/etherscan/request.js +0 -26
- package/src/etherscan/ws.js +0 -88
- package/src/exodus-eth-server/server-factory.js +0 -28
- package/src/exodus-eth-server/server-map.js +0 -21
- package/src/get-fee-async.js +0 -97
- package/src/staking/matic/service.js +0 -437
- package/src/staking-api.js +0 -5
- package/src/tx-log/clarity-utils/get-derive-data-needed-for-tick.js +0 -12
- package/src/tx-log-staking-processor/get-asset-tx-amount.js +0 -26
- package/src/tx-send/get-fee-info.js +0 -41
- package/src/websocket/index.android.js +0 -2
- package/src/websocket/index.ios.js +0 -2
- package/src/websocket/index.js +0 -21
|
@@ -1,27 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getPolygonUndelegateTxInEthereumTxLog } from '../staking/matic/matic-staking-utils.js'
|
|
2
|
+
import { assetStakingTxProps } from './asset-staking-tx-data.js'
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
4
|
+
const getAssetExpandedTxLog = async ({ assetName, aci, txs, walletAccount }) => {
|
|
5
|
+
const additionalTxs = []
|
|
6
|
+
if (assetName === 'polygon') {
|
|
7
|
+
const ethereumTxLog = await aci.getTxLog({ walletAccount, assetName: 'ethereum' })
|
|
8
|
+
const polygonUndelegateTxs = getPolygonUndelegateTxInEthereumTxLog(ethereumTxLog)
|
|
9
|
+
|
|
10
|
+
for (const tx of polygonUndelegateTxs) {
|
|
11
|
+
if (txs.has(tx.txId)) continue
|
|
12
|
+
|
|
13
|
+
additionalTxs.push(tx)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return additionalTxs
|
|
6
18
|
}
|
|
7
19
|
|
|
8
|
-
const processTxLog = async ({ asset, assetClientInterface: aci, walletAccount, batch
|
|
20
|
+
const processTxLog = async ({ asset, assetClientInterface: aci, walletAccount, batch }) => {
|
|
9
21
|
const { name: assetName, currency } = asset
|
|
10
22
|
const txs = await aci.getTxLog({ assetName, walletAccount })
|
|
11
23
|
|
|
12
24
|
const newTxs = []
|
|
13
25
|
for (const tx of txs) {
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
26
|
+
const stakingProps = assetStakingTxProps[assetName]?.({ tx, currency })
|
|
27
|
+
if (!stakingProps) continue
|
|
28
|
+
|
|
29
|
+
newTxs.push({
|
|
30
|
+
...tx,
|
|
31
|
+
...stakingProps,
|
|
32
|
+
data: { ...tx.data, ...stakingProps.data },
|
|
33
|
+
})
|
|
23
34
|
}
|
|
24
35
|
|
|
36
|
+
const expandedTxs = await getAssetExpandedTxLog({ assetName, aci, txs, walletAccount })
|
|
37
|
+
newTxs.push(...expandedTxs)
|
|
38
|
+
|
|
25
39
|
if (newTxs.length > 0) {
|
|
26
40
|
aci.updateTxLogAndNotifyBatch({ assetName, walletAccount, txs: newTxs, batch })
|
|
27
41
|
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
import { EthereumStaking, isEthereumStakingTx, MaticStakingApi } from '../staking'
|
|
2
1
|
import { asset as ethereum } from '@exodus/ethereum-meta'
|
|
3
|
-
import { asset as ethereumholesky } from '@exodus/ethereumholesky-meta'
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import { EthereumStaking } from '../staking/ethereum/api.js'
|
|
4
|
+
import { isEthereumStakingTx } from '../staking/ethereum/staking-utils.js'
|
|
5
|
+
import { MaticStakingApi } from '../staking/matic/api.js'
|
|
6
|
+
|
|
7
|
+
const polygonStakingApi = new MaticStakingApi()
|
|
8
|
+
const ethereumStakingApi = new EthereumStaking(
|
|
9
|
+
ethereum.name,
|
|
10
|
+
ethereum.currency,
|
|
11
|
+
undefined,
|
|
12
|
+
undefined
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
export const decodePolygonStakingTxInputAmount = (tx) => {
|
|
7
16
|
const {
|
|
8
17
|
data: { data: txInput },
|
|
9
18
|
} = tx
|
|
@@ -15,43 +24,35 @@ export const decodePolygonStakingTxInputAmount = ({ tx, server }) => {
|
|
|
15
24
|
return amount
|
|
16
25
|
}
|
|
17
26
|
|
|
18
|
-
export const
|
|
19
|
-
const stakedAmount = currency.baseUnit(decodePolygonStakingTxInputAmount(
|
|
20
|
-
const {
|
|
27
|
+
export const calculateRewardsFromStakeTx = ({ tx, currency }) => {
|
|
28
|
+
const stakedAmount = currency.baseUnit(decodePolygonStakingTxInputAmount(tx))
|
|
29
|
+
const { rewards } = tx.data
|
|
21
30
|
// stake tx might have rewards in it,
|
|
22
31
|
// i.e: https://etherscan.io/tx/0x0a81d266109034a3a70c6f1b9601c105d8caebbd0de652a0619344f9559ae4fa
|
|
23
32
|
// thus reward = txInputAmount(amount to stake) - tx.coinAmount
|
|
24
33
|
// tx.coinAmount is already computed from monitor; incoming - outgoing ERC20 token txs
|
|
25
34
|
const stakeTxContainsReward = !stakedAmount.equals(tx.coinAmount.abs())
|
|
26
35
|
|
|
27
|
-
if (
|
|
36
|
+
if (rewards) {
|
|
28
37
|
// cache rewards
|
|
29
|
-
return
|
|
38
|
+
return rewards
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
if (stakeTxContainsReward) {
|
|
33
42
|
const txAmount = stakedAmount.sub(tx.coinAmount.abs()).abs()
|
|
34
|
-
// eslint-disable-next-line @exodus/
|
|
35
|
-
|
|
36
|
-
return txAmount
|
|
43
|
+
// eslint-disable-next-line @exodus/hydra/no-param-reassign-prop-only -- TODO: Fix this the next time the file is edited.
|
|
44
|
+
return txAmount.toDefaultString()
|
|
37
45
|
}
|
|
38
|
-
|
|
39
|
-
// no rewards, set stake tx amount to ZERO
|
|
40
|
-
return currency.ZERO
|
|
41
46
|
}
|
|
42
47
|
|
|
43
|
-
export const decodeEthLikeStakingTxInputAmount = (
|
|
48
|
+
export const decodeEthLikeStakingTxInputAmount = (tx) => {
|
|
44
49
|
const {
|
|
45
50
|
data: { data: txInput },
|
|
46
51
|
coinName: assetName,
|
|
47
52
|
} = tx
|
|
48
53
|
|
|
49
|
-
const ethereumStakingApi = new EthereumStaking({ asset: ethereum, server })
|
|
50
|
-
const ethereumHoleskyStakingApi = new EthereumStaking({ asset: ethereumholesky, server })
|
|
51
|
-
|
|
52
54
|
const ethereumLikeContracts = {
|
|
53
55
|
ethereum: ethereumStakingApi,
|
|
54
|
-
ethereumholesky: ethereumHoleskyStakingApi,
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
const ethLikeContract = ethereumLikeContracts[assetName]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EthLikeError, EVM_ERROR_REASONS, getEvmErrorReason } from '../error-wrapper.js'
|
|
2
|
+
import { transactionExists } from '../eth-like-util.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Handles broadcast errors by parsing the error message and either throwing
|
|
6
|
+
* an appropriate EthLikeError or returning info for retry logic.
|
|
7
|
+
*
|
|
8
|
+
* @param {Error} err - The error from broadcastTx.
|
|
9
|
+
* @param {Object} options - Context for error handling.
|
|
10
|
+
* @param {Object} options.asset - The asset.
|
|
11
|
+
* @param {string} options.txId - The transaction ID.
|
|
12
|
+
* @param {boolean} options.isHardware - Whether this is a hardware wallet.
|
|
13
|
+
* @param {string} options.hint - Hint for the error.
|
|
14
|
+
* @param {boolean} options.isBumpTx - Whether the occur occured whilst bumping a Tx.
|
|
15
|
+
* @param {boolean} options.isRetryNonceTx - If the error occurred during a nonce bump.
|
|
16
|
+
* @returns {Promise<{ shouldRetry: boolean }>} - Returns if nonce too low and can retry.
|
|
17
|
+
* @throws {EthLikeError} - Throws for all other error cases.
|
|
18
|
+
*/
|
|
19
|
+
export const handleBroadcastError = async (
|
|
20
|
+
err,
|
|
21
|
+
{ asset, txId, isHardware, hint, isBumpTx, isRetryNonceTx }
|
|
22
|
+
) => {
|
|
23
|
+
const message = err.message
|
|
24
|
+
|
|
25
|
+
const errorInfo = getEvmErrorReason(message) || EVM_ERROR_REASONS.broadcastTxFailed
|
|
26
|
+
|
|
27
|
+
const isNonceTooLow = errorInfo.reason === EVM_ERROR_REASONS.nonceTooLow.reason
|
|
28
|
+
const isAmbiguousError =
|
|
29
|
+
isNonceTooLow || errorInfo.reason === EVM_ERROR_REASONS.transactionUnderpriced.reason
|
|
30
|
+
|
|
31
|
+
if (errorInfo.reason === EVM_ERROR_REASONS.alreadyKnown.reason) {
|
|
32
|
+
console.debug('tx already broadcast')
|
|
33
|
+
return { shouldRetry: false }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let txAlreadyExists = false
|
|
37
|
+
if (isAmbiguousError) {
|
|
38
|
+
try {
|
|
39
|
+
txAlreadyExists = await transactionExists({ asset, txId })
|
|
40
|
+
} catch (verifyErr) {
|
|
41
|
+
// Can't verify - fall through to original error handling
|
|
42
|
+
console.warn('Could not verify tx existence:', verifyErr.message)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (txAlreadyExists) {
|
|
47
|
+
console.debug('tx already broadcast')
|
|
48
|
+
return { shouldRetry: false }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// NOTE: Don't auto-retry nonce repair for bump/replacement txs.
|
|
52
|
+
// A replacement must keep the *same nonce* as the tx it's replacing.
|
|
53
|
+
// If we "fix" a bump tx by advancing the nonce, we create a brand-new tx instead of replacing the pending one.
|
|
54
|
+
if (isNonceTooLow && !isHardware && !isBumpTx && !isRetryNonceTx) return { shouldRetry: true }
|
|
55
|
+
|
|
56
|
+
throw new EthLikeError({
|
|
57
|
+
message: err.message,
|
|
58
|
+
errorReasonInfo: errorInfo,
|
|
59
|
+
hint,
|
|
60
|
+
traceId: err.traceId,
|
|
61
|
+
baseAssetName: asset.baseAsset.name,
|
|
62
|
+
})
|
|
63
|
+
}
|
package/src/tx-send/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export { default as txSendFactory } from './tx-send'
|
|
2
|
-
export { default as getFeeInfo } from './get-fee-info'
|
|
1
|
+
export { default as txSendFactory } from './tx-send.js'
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import assert from 'minimalistic-assert'
|
|
2
|
+
|
|
3
|
+
import { getNonce } from '../eth-like-util.js'
|
|
4
|
+
import { getLatestCanonicalAbsoluteNonceTx } from '../tx-log/clarity-utils/absolute.js'
|
|
5
|
+
|
|
6
|
+
export const BLOCK_TAG_LATEST = 'latest'
|
|
7
|
+
export const BLOCK_TAG_PENDING = 'pending'
|
|
8
|
+
|
|
9
|
+
const VALID_BLOCK_TAGS = new Set([BLOCK_TAG_LATEST, BLOCK_TAG_PENDING])
|
|
10
|
+
|
|
11
|
+
// NOTE: We do not yet support tags at arbitrary block heights.
|
|
12
|
+
const assertValidBlockTag = (tag) => assert(VALID_BLOCK_TAGS.has(tag), `invalid tag "${tag}"`)
|
|
13
|
+
|
|
14
|
+
export const resolveNonce = async ({
|
|
15
|
+
asset,
|
|
16
|
+
forceFromNode,
|
|
17
|
+
fromAddress,
|
|
18
|
+
txLog, // TxSet expected. Array only for testing purposes.
|
|
19
|
+
accountState,
|
|
20
|
+
tag = BLOCK_TAG_LATEST,
|
|
21
|
+
useAbsoluteNonce,
|
|
22
|
+
}) => {
|
|
23
|
+
assertValidBlockTag(tag)
|
|
24
|
+
|
|
25
|
+
if (asset.baseAsset?.api?.features?.noHistory || forceFromNode) {
|
|
26
|
+
return getNonce({ asset: asset.baseAsset, address: fromAddress, tag })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const nonceFromTxLog = getNonceFromTxLog({ txLog, useAbsoluteNonce, tag })
|
|
30
|
+
|
|
31
|
+
// `accountState.nonce` is the single source of truth — clarity-truncated-history
|
|
32
|
+
// collapses both `account_balance` and `truncated` source nonces into this field.
|
|
33
|
+
const nonceFromAccountState = accountState?.nonce || 0
|
|
34
|
+
|
|
35
|
+
return Math.max(nonceFromTxLog, nonceFromAccountState)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const getLatestTxWithNonceChange = ({ reversedTxLog }) => {
|
|
39
|
+
assert(reversedTxLog, 'expected reversedTxLog')
|
|
40
|
+
|
|
41
|
+
const maybeLatestAbsoluteNonceTx = getLatestCanonicalAbsoluteNonceTx({
|
|
42
|
+
reversedTxLog,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
if (maybeLatestAbsoluteNonceTx) return maybeLatestAbsoluteNonceTx
|
|
46
|
+
|
|
47
|
+
for (const tx of reversedTxLog) {
|
|
48
|
+
if (tx.data.nonceChange) {
|
|
49
|
+
return tx
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Computes the next nonce from the given `txLog`.
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} options
|
|
58
|
+
* @param {import('@exodus/models').TxSet} options.txLog - A `TxSet` from
|
|
59
|
+
* `@exodus/models`, NOT a plain `Array`.
|
|
60
|
+
* @param {boolean} [options.useAbsoluteNonce]
|
|
61
|
+
* @param {string} [options.tag]
|
|
62
|
+
* @returns {number}
|
|
63
|
+
*/
|
|
64
|
+
const getNonceFromTxLog = ({ txLog, useAbsoluteNonce, tag }) => {
|
|
65
|
+
if (!txLog || txLog.size === 0) return 0
|
|
66
|
+
|
|
67
|
+
let absoluteNonce = 0
|
|
68
|
+
|
|
69
|
+
if (useAbsoluteNonce) {
|
|
70
|
+
// NOTE: `TxSet#reverse()` returns a one-shot iterable yielding txs
|
|
71
|
+
// in reverse order — it is NOT an in-place reversal like
|
|
72
|
+
// `Array.prototype.reverse()`, so the caller's `txLog` is
|
|
73
|
+
// left untouched.
|
|
74
|
+
const reversedTxLog = txLog.reverse()
|
|
75
|
+
const maybeLatestTxWithNonceChange = getLatestTxWithNonceChange({ reversedTxLog })
|
|
76
|
+
|
|
77
|
+
if (maybeLatestTxWithNonceChange) {
|
|
78
|
+
// NOTE: This is the latest nonce currently confirmed by
|
|
79
|
+
// Clarity, which lags behind `CLARITY_MIN_CONFIRMS`
|
|
80
|
+
// depth:
|
|
81
|
+
//
|
|
82
|
+
// https://github.com/ExodusMovement/clarity/blob/4a6ea30fce33246d1ef1440e61b0a84b876900d6/deployment/eth-clarity-indexer/values.yaml#L34
|
|
83
|
+
absoluteNonce = parseInt(maybeLatestTxWithNonceChange.data.nonceChange.to, 10)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// TODO: can't we iterate in reverse up to the first (few) nonce(s)?
|
|
88
|
+
const nonceFromLog = [...txLog]
|
|
89
|
+
.filter((tx) => tx.sent && !tx.dropped && tx.data.nonce != null)
|
|
90
|
+
// NOTE: If we're only considering the `'latest'` block `tag`,
|
|
91
|
+
// then we should not take into account unconfirmed
|
|
92
|
+
// transactions when computing the `nonce`.
|
|
93
|
+
.filter((tx) => tag !== BLOCK_TAG_LATEST || !tx.pending)
|
|
94
|
+
.reduce((nonce, tx) => Math.max(tx.data.nonce + 1, nonce), 0)
|
|
95
|
+
|
|
96
|
+
return Math.max(absoluteNonce, nonceFromLog)
|
|
97
|
+
}
|