Event Indexing
SellPolia has no “submit order” button — the chain is the source of truth. A deposit becomes a queue order, and a payment becomes a filled buy, purely by the backend watching contract events. Every chain is indexed the same way, with two paths that funnel into one idempotent processor (so a log seen by both is handled exactly once).
1. WebSocket subscription (real-time)
A low-latency eth_subscribe("logs", …) subscription (viem watchEvent with
poll: false) streams matching logs for the contract as they happen. This path is
stateless and reconnects with exponential backoff if the socket drops.
2. HTTP getLogs sweep (backstop)
A periodic sweep re-scans from a stored cursor up to head − confirmations in
batches (500 blocks at a time). It runs immediately at startup to backfill any
downtime, then repeats on a per-chain interval. The sweep owns the cursor; the
WebSocket path just accelerates delivery.
Together they give real-time updates with a self-healing backstop — if the socket misses a log, the next sweep catches it.
What gets indexed
| Contract | Events consumed |
|---|---|
| SethVault (Sepolia) | SethReceived → queue order · PayoutAddressChanged · SellerTierOverrideChanged |
| PaymentCollector (payment chains) | SethPurchased → buyer order + fill |
Idempotency
- Vault deposits are keyed by
(blockNumber, logIndex). - Purchases are keyed by
chainId:txHash:buyer:recipient— deliberately not log-index based, so the key is stable even if a reorg reshuffles logs.
You can read listener/sweep health from
/api/listener/status.