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.
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:
TRANSACTION_PROVIDERS_<CHAIN>— the order for that one chain, for exampleTRANSACTION_PROVIDERS_BSC.TRANSACTION_PROVIDERS— one order for every chain.- 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 cronEvery 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.