MMashDiv

Transaction history providers

Which explorer API reads an EVM chain's transaction history, in what order the platform tries them, which key each one needs, and how to pin one provider to one chain — for example NodeReal for BSC.

3 min readUpdated 1 October 2026providers, explorer, nodereal, ankr, moralis, covalent, etherscan, blockscout, routescan, bsc

A native-coin deposit on an EVM chain (ETH, BNB, POL and so on) leaves no event log behind, so the platform finds it by reading the deposit address's transaction list from an explorer API. The same lists feed the wallet history screens. Token deposits are different: they are read from the chain's Transfer logs over your own RPC endpoint and need none of this.

Seven explorer APIs are built in. The platform tries them one after another until one answers, so a chain keeps working when a provider has an outage, a quota runs out or a key is revoked.

The providers

Provider Key variable Needs a key What it indexes
etherscan ETHERSCAN_API_KEY (per chain: <CHAIN>_EXPLORER_API_KEY, <CHAIN>_ETHERSCAN_API_KEY) Yes Every chain on the Etherscan V2 list. The free tier no longer covers BSC, OP Mainnet, Base or Avalanche
blockscout BLOCKSCOUT_API_KEY (optional) No Chains with a hosted Blockscout instance: ETH, Polygon, Arbitrum, Optimism, Base, Celo and RSK, with their testnets
routescan ROUTESCAN_API_KEY (optional) No Ethereum and Avalanche, mainnet and testnet
ankr ANKR_API_KEY Yes Most mainnets and their main testnets — but not BSC testnet (chain id 97)
moralis MORALIS_API_KEY Yes Major EVM mainnets and testnets, BSC testnet included
covalent COVALENT_API_KEY Yes Major EVM mainnets and testnets, BSC testnet included
nodereal NODEREAL_API_KEY Yes ETH mainnet, BSC mainnet and BSC testnet

Every key variable accepts a comma-separated list of keys. When one key is rejected, exhausted or rate-limited, the next key is tried before the provider is given up on. A chain-scoped variable such as BSC_NODEREAL_API_KEY is tried before the global one, and the global key stays behind it as a spare.

Which provider is tried first

For each chain the order comes from the first of these that is set:

  1. TRANSACTION_PROVIDERS_<CHAIN> — the order for that one chain, for example TRANSACTION_PROVIDERS_BSC.
  2. TRANSACTION_PROVIDERS — one order for every chain.
  3. The built-in default for that chain (below).

Then, unless TRANSACTION_PROVIDERS_STRICT="true", the keyless providers (blockscout, routescan) that can serve the chain are appended to the end, so a chain with a hosted explorer always has a last resort.

While it works through the order, the platform skips a provider that does not index the chain's network or has no key, and skips for a short while one that has just failed. If every provider is in that short cooldown, they are tried anyway rather than failing the lookup.

Setting NODEREAL_API_KEY makes NodeReal able to serve. It does not put NodeReal into a TRANSACTION_PROVIDERS list you wrote yourself. With TRANSACTION_PROVIDERS="ankr" only Ankr is tried — on every chain — and on BSC testnet, which Ankr does not index, every lookup fails.

Built-in defaults

Chain Default order
ETH etherscan, blockscout, routescan, ankr, moralis, covalent, nodereal
POLYGON, ARBITRUM, CELO etherscan, blockscout, ankr, moralis, covalent
BASE, OPTIMISM blockscout, etherscan, ankr, moralis, covalent
BSC nodereal, ankr, moralis, covalent, etherscan
AVAX routescan, ankr, moralis, covalent, etherscan
FTM ankr, moralis, covalent, etherscan
RSK blockscout, etherscan
MO etherscan, blockscout
Anything else etherscan, blockscout, routescan, ankr, moralis, covalent, nodereal

Each default starts with the provider that is free for that chain, so most installs never need to set an order at all.

Use NodeReal for BSC only

Add the per-chain order to .env, keep the NodeReal key, and restart the backend and the scheduler:

NODEREAL_API_KEY="your-nodereal-key"
TRANSACTION_PROVIDERS_BSC="nodereal"
pm2 restart backend cron

Every other chain keeps its own order. If you also set TRANSACTION_PROVIDERS for all chains (for example to lead with Ankr elsewhere), leave it — TRANSACTION_PROVIDERS_BSC wins for BSC. To keep a fallback behind NodeReal, list it too: TRANSACTION_PROVIDERS_BSC="nodereal,moralis".

.env never overrides a value pm2 already holds. pm2 keeps the environment a process was first started with, and the backend reads .env without replacing variables that are already set. So if editing TRANSACTION_PROVIDERS in .env changes nothing after a restart, run pm2 env <id> | grep TRANSACTION_PROVIDERS: a value listed there is the one in force. A per-chain TRANSACTION_PROVIDERS_<CHAIN> that pm2 does not hold is read from .env as expected, which is why the per-chain variable is the dependable way to steer one chain.

Older Ecosystem builds refused BSC testnet (chain id 97) for NodeReal as "mainnet only", and sent NodeReal a block range it now rejects on every network. If the console below shows nodereal as does not index BSC (chainId 97), or its test fails with from must be less than to, update the Ecosystem addon.

Check what a chain will use

Admin → Ecosystem → Blockchain opens the requirements and diagnostics console. For every chain it shows where the order came from (the per-chain variable, the global one or the built-in default), each provider in the order it will be tried, and why any of them is skipped — no key, does not index this network, or cooling down after a failure. Run test probes each provider with the key the runtime would use.

Reading the log

Log line What it means What to do
All transaction providers failed for BSC. Errors: ankr: Ankr does not index chain: BSC (chainId 97) The order for BSC holds only providers that cannot serve BSC testnet Set TRANSACTION_PROVIDERS_BSC="nodereal" (or moralis / covalent) with its key
No usable transaction provider for <CHAIN>. <provider>: no credential — set <KEY> Every provider in the order needs a key and none is set Set a key for one of them, or add a keyless provider that serves the chain
Ignoring unknown tx-history provider "<name>" A name in the order is misspelt Use one of: etherscan, blockscout, routescan, ankr, moralis, covalent, nodereal
<provider> ... Origin not allowed or not allowed to access from this IP The provider's dashboard restricts where the key may be used from Allow the server's outbound IP; a website or domain allowlist can never match a server-side call

All the variables, with their accepted values, are listed in Environment reference.