Index a bounded Mainnet range
Index 1,000 Ethereum Mainnet blocks and query the last Uniswap V2 pool-reserve observation in each hour. This uses public Xatu data, needs no API key, and stops after a finite range.
First install from source so leani and
LEANI_SOURCE are available in your terminal. The commands below copy a complete
configuration into a fresh temporary directory:
LEANI_HISTORY_DIR="$(mktemp -d)"cp "$LEANI_SOURCE/config/modes/windowed.toml" "$LEANI_HISTORY_DIR/leani.toml"cd "$LEANI_HISTORY_DIR"leani doctor --jsonleani backfill \ --processor uniswap-v2-sync-30d --from 17000000 --to 17000999leani servedoctor should report valid: true. The backfill report should show continuous
coverage from 17000000 through 17000999. Leave serve running and query it
from another terminal:
curl -s \ 'http://127.0.0.1:8080/v1/processors/uniswap-v2-sync-30d/collections/uniswap_v2.sync_hourly/entities?limit=3'curl -s \ 'http://127.0.0.1:8080/v1/processors/uniswap-v2-sync-30d/status'Expect five hourly entities for this range; limit=3 returns only the first
page. Follow nextCursor to read the rest. Entities are ordered by their keys,
so sort by bucketStartTimestamp when drawing a time series.
Each entity contains values.reserve0 (USDC, six decimals) and
values.reserve1 (WETH, eighteen decimals). These are exact integer strings.
The processor retains the last Sync observation per hourly bucket; it does
not return every swap or an hourly average price.
Check coverage
The status response’s available intervals should cover the entire requested
range. A high processedThrough alone does not prove that earlier blocks were
indexed. Xatu’s finalized label is a dataset assertion; this profile has
independent finality verification disabled.
Try an explicit range query, then one outside your indexed interval:
curl -s 'http://127.0.0.1:8080/v1/processors/uniswap-v2-sync-30d/collections/uniswap_v2.sync_hourly/entities?fromBlock=17000000&toBlock=17000999'curl -s 'http://127.0.0.1:8080/v1/processors/uniswap-v2-sync-30d/collections/uniswap_v2.sync_hourly/entities?fromBlock=17001000&toBlock=17001999'The first should return retained entities with complete requested coverage.
The second should return range_incomplete, rather than an empty success.
An indexed range whose output was subsequently pruned returns output_not_retained.
Decode a different contract event
The configuration’s processors.settings selects the contract address and
Solidity event ABI. For a small WETH transfer example, use the complete config
at examples/weth-transfers/node.toml:
LEANI_EVENTS_DIR="$(mktemp -d)"cp "$LEANI_SOURCE/examples/weth-transfers/node.toml" "$LEANI_EVENTS_DIR/leani.toml"cd "$LEANI_EVENTS_DIR"leani doctor --jsonleani backfill --processor weth-transfers --from 17000000 --to 17000009leani serveThis example uses API port 8081 so it can run beside the Uniswap node. Query:
curl -s 'http://127.0.0.1:8081/v1/processors/weth-transfers/collections/weth.transfers/entities?limit=100'Expect 205 transfers across three pages. Each entity’s values contains from,
to, and value; WETH uses 18 decimals. Change the address, ABI, collection,
instance name, and block range for your contract. Keep
history_mode = "on_demand" for explicit backfills, and use a fresh data
directory when changing processor identity or schema.
For a transformation beyond static event decoding, build your own processor with the Rust library.