> For the complete documentation index, see [llms.txt](https://svpchain.gitbook.io/svpchain-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://svpchain.gitbook.io/svpchain-docs/build/indexing-and-events.md).

# Indexing & events

Read chain data — logs, events, and state — without missing or duplicating anything.

There are two parallel jobs in any indexer: **backfill** (catch up from a known height to chain head) and **realtime** (stay at the head). SVPChain's instant finality removes the worst class of indexer bugs — there are no reorgs to undo — but the rest of the discipline still applies: durable cursor, dedupe, retries.

{% hint style="info" %}
**No reorgs to handle.** SVPChain finalizes every block in a single round. If `eth_getBlockByNumber` returns block `N`, that block is permanent. You don't need a confirmation buffer.
{% endhint %}

### Sources

| Source                                               | Use when                                                                                                                    |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **JSON-RPC** (`eth_getLogs`, `eth_getBlockByNumber`) | Backfilling a range of blocks; canonical state queries.                                                                     |
| **WebSocket** (`eth_subscribe`)                      | Realtime feed of new heads and matching logs.                                                                               |
| **Cosmos REST / gRPC**                               | Cosmos-side state — staking, governance, native CLOB module data. See [API overview](/svpchain-docs/build/api-overview.md). |
| **Blockscout API**                                   | Convenient pre-decoded events and addresses; not authoritative — verify against RPC for production.                         |

### Backfill pattern

Walk forward in fixed-size block ranges, persisting the cursor after each chunk. Keep the range small — most public RPCs cap a single `eth_getLogs` call at a few thousand blocks.

```ts
import { createPublicClient, http, parseAbiItem } from "viem";

const client = createPublicClient({
  transport: http("https://svp-dataseeds-testnet.svpchain.org"),
});

const event = parseAbiItem(
  "event Transfer(address indexed from, address indexed to, uint256 value)"
);

const STEP = 1_000n;

async function backfill(from: bigint, to: bigint, contract: `0x${string}`) {
  for (let start = from; start <= to; start += STEP) {
    const end = start + STEP - 1n > to ? to : start + STEP - 1n;
    const logs = await client.getLogs({
      address: contract,
      event,
      fromBlock: start,
      toBlock: end,
    });
    await persist(logs);             // your DB write
    await saveCursor(end);           // durable cursor
  }
}
```

### Realtime pattern

Subscribe to new heads, then pull the events you care about for each new block. `eth_subscribe("logs", ...)` works too, but pulling per-block keeps the dedupe key (block number) explicit.

```ts
import { createPublicClient, webSocket } from "viem";

const ws = createPublicClient({
  transport: webSocket("wss://svp-dataseeds-testnet.svpchain.org/ws"),
});

ws.watchBlockNumber({
  onBlockNumber: async (n) => {
    const logs = await ws.getLogs({
      address: contract,
      event,
      fromBlock: n,
      toBlock: n,
    });
    await persist(logs);
    await saveCursor(n);
  },
});
```

On reconnect, read your durable cursor and call `backfill(cursor + 1, currentHead)` before resuming the stream.

### Dedupe and idempotency

Use `(blockNumber, transactionIndex, logIndex)` as the natural key for log events. With instant finality this triple is permanent and unique — make your DB upsert key match.

### Native CLOB events

The on-chain order book is a Cosmos SDK module, so its events live in **Cosmos tx events**, not in EVM logs. To index CLOB activity, listen to CometBFT block events through the gRPC / WebSocket Cosmos endpoints. Detailed schema and event types: TODO.

### Operational notes

* Always set request timeouts (5–10s for `eth_getLogs`, 1s for `eth_blockNumber`).
* Retry idempotent reads with exponential backoff.
* Keep a "last seen height" alert — if the cursor stops advancing for more than a few seconds, your stream is dead even if the WS connection looks fine.

### Next steps

<table data-view="cards"><thead><tr><th>Reference</th><th data-card-target data-type="content-ref">Link</th></tr></thead><tbody><tr><td>RPC methods you'll use</td><td><a href="/svpchain-docs/build/json-rpc.md">JSON-RPC</a></td></tr><tr><td>WebSocket subscriptions</td><td><a href="/svpchain-docs/build/websocket.md">WebSocket</a></td></tr><tr><td>Run your own RPC node</td><td><a href="/svpchain-docs/chain/run-a-node.md">Run a node</a></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://svpchain.gitbook.io/svpchain-docs/build/indexing-and-events.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
