Skip to main content
Elysium can make a block every 100 ms. An app written for a 2-second or 12-second chain, such as a wallet, a trading bot or a front end that waits for confirmations, either falls behind or spends most of its requests on empty blocks. This guide shows how such an app can follow Elysium over Edge RPC with two requests per poll, whatever the number of new blocks.
To write chain data into a database, use a Turbo pipeline instead of a polling loop. The pipeline handles backfills, reorgs and retries, and writes to your sink.

What changes on Elysium

Elysium makes a block only when it has transactions to include, at most one every 100 ms, so the block rate follows traffic. Three things follow:
  • One request per block costs up to 10 requests per second before your application does anything with the data. Reading log ranges costs the same two requests whether 1 block or 1,000 blocks arrived since the last poll.
  • Block timestamps are not unique. A timestamp has a resolution of one second, so many blocks share one. Order and deduplicate by block number and log index.
  • Client defaults are set for slow chains. viem polls every 4 seconds by default, which is about 40 Elysium blocks.
Edge RPC is HTTPS only, so eth_subscribe is not available (Edge RPC introduction). Polling is the way to follow the chain head.

Define the chain

viem has no built-in Elysium chain yet, so define one. Set blockTime so that viem’s default polling interval and cache time follow the chain:
For Elysium Testnet, use chain ID 99801 and /evm/99801 in the URL. Replace <your_edge_api_key> with an Edge API key from the dashboard.

Read log ranges, not blocks

Keep a cursor at the last block you processed. On each poll, ask for the head, then fetch every matching log from the cursor to the head in one eth_getLogs call:
The 20,000-block cap is at least 33 minutes of Elysium blocks. If your process is down for longer, the loop above catches up in 20,000-block steps. See eth_getLogs limits.

Order by block number, not timestamp

Many Elysium blocks can share one timestamp, so a timestamp can’t tell you which of two events happened first. Use these instead:
  • Ordering: (blockNumber, logIndex) for logs and (blockNumber, transactionIndex) for transactions.
  • Cursors and checkpoints: the block number. A timestamp cursor either skips or repeats the blocks that share it.
  • Time windows: filter on timestamp if you need to, but expect one second to hold many blocks.

Wait for receipts

waitForTransactionReceipt checks for the receipt once per pollingInterval. With the 250 ms setting above, it checks about every two or three blocks:
Without pollingInterval, viem uses half of blockTime but never less than 500 ms. If the chain has no blockTime, viem waits 4 seconds between checks.

Polling or an indexed store

Polling sees a block as soon as Edge serves it, plus at most one polling interval, which you control. A Turbo pipeline, a subgraph or Feeds first ingests, transforms and writes each block, so its data lands a little later. Poll when your app must react within a block or two, to a few contracts or its own transactions. Use an indexed store when it needs history, aggregates or many addresses. Polling works well to follow the head from an app. For history, or to load chain data into a database, use a Turbo pipeline with the curated Elysium datasets, such as elysium_mainnet.raw_logs. For examples, see Stream Elysium wallet activity and Track Elysium bridge flows.

Getting help

Can’t find what you’re looking for? Reach out to us at support@goldsky.com for help.