Skip to content

Fix Avalanche transaction history sync - #1085

Open
j0ntz wants to merge 1 commit into
masterfrom
jon/avax-tx-history-routescan
Open

Fix Avalanche transaction history sync#1085
j0ntz wants to merge 1 commit into
masterfrom
jon/avax-tx-history-routescan

Conversation

@j0ntz

@j0ntz j0ntz commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Asana task

Asana: https://app.asana.com/1/9976422036640/project/1200382638405084/task/1216409263474102

AVAX wallets show balances and send fine, but transaction history never syncs. The RPC adapter covers balance, nonce, block height and broadcast, so a wallet looks healthy while its history stays blank; only the evmscan adapter fetches transactions, and all three servers configured for Avalanche have stopped answering.

Verified live against a real C-Chain address, using the AVAX key from env.json AVALANCHE_INIT:

configured server response
https://api.etherscan.io (V2, chainid=43114) status 0 NOTOK — "Free API access is not supported for this chain. Please upgrade your api plan for full chain coverage."
https://api.avascan.info/v2/network/mainnet/evm/43114/etherscan DNS dead. Its CNAME target d3rhlnpz39fui8.cloudfront.net has no records.
https://api.snowscan.xyz status 0 NOTOK — "You are using a deprecated V1 endpoint, switch to Etherscan API V2".

Replaced with Routescan's etherscan-compatible endpoint, which this repo already uses for Botanix (chain 3637) and HyperEVM (999). It needs no API key and answers every action EvmScanAdapter issues: txlist, txlistinternal, tokentx, proxy/eth_blockNumber, proxy/eth_getTransactionCount, account/balance. Its path contains etherscan, so the server.includes('etherscan') guards in fetchBlockheight and fetchNonce pass.

gastrackerSupport is dropped in the same change. Routescan's gastracker/gasoracle reports gas in wei (SafeGasPrice 57,699,304 against an RPC eth_gasPrice of 53,313,756 wei), while fetchFeesFromEvmScan assumes Etherscan's gwei and multiplies by WEI_MULTIPLIER. Today the flag is inert because every server throws, so EthereumEngine.updateNetworkFees falls through to fetchFeesFromRpc. A working evmscan server would let the evmScan provider win that loop's break and write a 1e9x-inflated gasPrice, which becomes maxFeePerGas on this EIP-1559 chain. Leaving the flag off preserves today's effective fee behavior.

Production note (needs a separate operator action)

This change fixes the plugin default, but it does not by itself fix existing installs. EthereumTools.updateInfoPayload runs mergeDeeply(networkInfo, infoPayload), and mergeDeeply replaces arrays rather than merging them, so the info server's networkAdapterConfigs wins outright. The live payload the app fetches (/v2/coreRollup?appId=edge&...) currently serves Avalanche exactly the two dead servers:

[
  { "type": "rpc", "servers": ["https://api.avax.network/ext/bc/C/rpc", "..."], "ethBalCheckerContract": "0xd023d153a0dfa485130ecfde2faa7e612ef94818" },
  { "type": "evmscan", "gastrackerSupport": true, "servers": ["https://api.etherscan.io"] },
  { "type": "evmscan", "gastrackerSupport": true, "servers": ["https://api.avascan.info/v2/network/mainnet/evm/43114/etherscan"] }
]

That value lives in the corePluginsInternal2 CouchDB document in the info server's info_data database, which syncedDocument reads from Couch. The repo's defaultJson/dbInfo/corePluginsInternal2.json is empty and only seeds a fresh database, so no edge-info-server PR reaches production. Someone with info-server access needs to replace that Avalanche entry's two evmscan configs with:

{ "type": "evmscan", "servers": ["https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan"] }

Until then every existing Edge install keeps querying the dead servers regardless of which plugin version it ships.

Testing

  • verify-repo.sh passes (CHANGELOG check, install, prepare, eslint on changed files, npm test).
  • Drove the real EvmScanAdapter against the live network with the shipped Avalanche networkInfo: fetchBlockheight → 92496927, fetchNonce → 173624, and fetchTxs paged roughly 200 pages of real txlist data through processEvmScanTransaction.
  • In-app on the iOS simulator: resynced an AVAX wallet (which clears transactionList/txIdList/txIdMap) on a build carrying this change, and its transaction history repopulated from the network. Reaching that state required a local, uncommitted hack to drop the info server's networkAdapterConfigs so the plugin default under test was what ran; the hack is reverted and the branch is clean.

Known limitation, unchanged by this PR

An address with more than 10,000 transactions still fails to page: Routescan answers Result window is too large, PageNo x Offset size must be less than or equal to 10000. Etherscan V2 returns the identical error at the same boundary, so this is a pre-existing EvmScanAdapter pagination limit affecting every EVM chain, not a Routescan regression.


Note

Medium Risk
Changes only default network adapter config for history sync and fee-source selection; wrong gas-oracle handling was explicitly avoided, but production still depends on info-server payload overrides for many users.

Overview
Avalanche C-Chain transaction history was broken because every configured evmscan indexer failed (paid Etherscan V2 for chain 43114, dead Avascan DNS, Snowscan on retired V1), while RPC still handled balance, nonce, and broadcast—so wallets looked fine with empty history.

The plugin default in avalancheInfo.ts now points EvmScanAdapter at Routescan’s etherscan-compatible API (same pattern as Botanix and HyperEVM). gastrackerSupport is removed so a working evmscan source cannot feed gas-oracle values in wei through code that expects Etherscan gwei and would inflate EIP-1559 fees; fees stay on the RPC path.

CHANGELOG documents the fix. Existing installs may still use dead servers until the info server’s networkAdapterConfigs is updated separately (array merge replaces plugin defaults).

Reviewed by Cursor Bugbot for commit b15ed5a. Bugbot is set up for automated code reviews on this repo. Configure here.

@j0ntz

j0ntz commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

📸🪓 Test evidence

🪓 Hack-forced evidence: dropped the info server's networkAdapterConfigs in EthereumTools.updateInfoPayload so the plugin's own Routescan server list was what ran; reverted, branch clean. Temporary uncommitted edit, reverted before commit; the marked frames prove the rendering, not the trigger.

avax wallet search

avax wallet search

🪓 HACK-FORCED: avax tx history after resync

🪓 HACK-FORCED: avax tx history after resync

Captured by the agent's in-app test run (build-and-test).

All three evmscan servers configured for Avalanche had stopped
answering, so txlist, txlistinternal and tokentx never returned.
The RPC adapter still served balances, nonce, block height and
broadcast, so wallets looked healthy while history stayed blank.

Point the evmscan adapter at Routescan, already used for Botanix and
HyperEVM. Leave gastracker off, since Routescan reports gas in wei
while fetchFeesFromEvmScan assumes Etherscan's gwei and multiplies
by 1e9.
@j0ntz
j0ntz marked this pull request as ready for review August 10, 2026 20:54
@j0ntz
j0ntz force-pushed the jon/avax-tx-history-routescan branch from 2e73419 to b15ed5a Compare August 10, 2026 20:54
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant