The feed
Price sources
Each source is a tick producer feeding one scriptable publisher. Add a source and it inherits history, the σ window, calc & guard scripts, and the sanity guard for free.
Exchange & Lazer
binance · bybit
Top-of-book best bid/ask over WebSocket → mid = (bid+ask)/2, confidence = half-spread, as a fixed-point mantissa. Dashboard-managed feed sets.
lazer
Pyth Lazer: one WS multiplexes subscriptions; publishes raw prices and, for evm subscriptions, the signed blob the pyth pusher forwards.
binance_futures
Perp mids into a shared series the CEX calc reads as etx_perp_ret_2s/10s — the toxic-flow signal. Inert when unconfigured.
On-chain sources
Two generic, config-driven sources put chain data onto the same bus. Anything past a linear
scale — inversion, cross rates, sqrtPriceX96 — belongs in a calc script,
not the source config.
evm_events — contract logs
eth_subscribe("logs") on the shared WS runner, or eth_getLogs polling from
the last seen block. A feed names the emitting address, the event signature (with indexed
markers), the price field and a scale.
[[evm_events]]
name = "base-events"
ws_url = "wss://…" # or http_url = "https://…" for getLogs polling
[[evm_events.feeds]]
symbol = "eth"
address = "0x…"
event = "AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)"
price_field = "current" # named param — must be uint*/int*
scale = 1e-8 # real_price = decoded * scale
evm_calls — Multicall3 batch
One eth_call per poll to Multicall3 aggregate3, batching every configured
zero-arg view call. allowFailure is set per call, so a reverting target skips only its
own symbol — never the batch.
[[evm_calls]]
name = "base-calls"
rpc_url = "https://…" # multicall3 defaults to the canonical address
[[evm_calls.feeds]]
symbol = "steth"
address = "0x…"
call = "latestRoundData()" # zero-arg; use `calldata = "0x…"` for args
returns = "uint80,int256,uint256,uint256,uint80"
price_field = 1 # tuple index — must be uint*/int*
scale = 1e-8
aggregate3 shape) are hand-rolled in Rust and mirrored on ethers v6 in the twin —
with both test suites pinning the identical hex vectors, so the encoders are proven equivalent.What every source publishes
A tick becomes {prefix}:{name}:{symbol} with the price mantissa, exponent, the
script's confidence and spreads, and a history entry. On-chain sources use spread = 0
and take confidence from their calc script, exactly like a CEX feed.