> ## Documentation Index
> Fetch the complete documentation index at: https://docs.darkpool.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# Indexer

> Sui event poller to Postgres via Drizzle, with persisted cursors.

The indexer is one of three `@darkpool/server` processes. It polls Sui events on a configurable interval (`INDEXER_POLL_MS`, default 4000ms) and writes them to Postgres via Drizzle. Cursor state is persisted in the `indexer_cursors` table so restarts resume cleanly.

## Streams

<Frame caption="One indexer process owns several event streams, each scoped to a different package. Cursor state is persisted per stream so restarts resume cleanly.">
  <img src="https://mintcdn.com/dp-550c5f99/jpKwLJ-DlSavdO_D/images/indexer-streams.png?fit=max&auto=format&n=jpKwLJ-DlSavdO_D&q=85&s=67ffd5c11046dacaa002f1ed8d04128c" alt="Indexer streams diagram. Sui RPC queryEvents feeds the indexer process. The indexer process owns seven event streams: predict::PositionMinted to the fills table, predict::PositionRedeemed to the redemptions table, predict::oracle::* to the oracles + strikes tables, darkpool::oo_resolution::* to the oo_proposals + votes tables, darkpool::agent::* to the agents table, darkpool::dark_pool::* to the dark_pool_vaults + deposits + settlements tables, binary by slug settlement Redeemed to the redemptions table. The indexer process persists per-stream cursor state in the indexer_cursors table." width="1774" height="887" data-path="images/indexer-streams.png" />
</Frame>

All active streams:

| Stream                                          | Source                                | Destination table                                                                          |
| ----------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------ |
| `predict::PositionMinted`                       | DeepBook Predict package              | `fills`                                                                                    |
| `predict::PositionRedeemed`                     | DeepBook Predict package              | `redemptions`                                                                              |
| `predict::oracle::*`                            | DeepBook Predict package              | `oracles`, `oracle_strikes`                                                                |
| `darkpool::oo_resolution::ProposalCreated` etc. | DarkPool package                      | `oo_proposals`, `oo_votes`                                                                 |
| `darkpool::agent::AgentRegistered`              | DarkPool package                      | `agents`                                                                                   |
| `darkpool::dark_pool::VaultCreated` etc.        | DarkPool package                      | `dark_pool_vaults`, `dark_pool_deposits`, `dark_pool_settlements`, `dark_pool_redemptions` |
| `binary::<slug>::settlement::Redeemed`          | per-market binary packages (registry) | `redemptions` (source = "binary")                                                          |

One `binary::<slug>` stream is created per `.binary-markets/registry.json` entry at startup. **New markets need an indexer restart before their event stream exists.**

## Cursors

```sql theme={"system"}
CREATE TABLE indexer_cursors (
  stream TEXT PRIMARY KEY,
  tx_digest TEXT,
  event_seq BIGINT,
  updated_at TIMESTAMPTZ
);
```

Each poll uses `sui.queryEvents({ MoveEventType: … })` with the stored cursor; on success the new tail cursor is upserted in the same transaction.

## Logs

```text theme={"system"}
[indexer] {"level":"info","stream":"predict::PositionMinted","processed":2,"cursor":{…},"msg":"indexed events"}
```

## Database schema

Drizzle schema lives in `packages/server/src/db/schema.ts`. Migrations under `packages/server/src/db/migrations/`. Run:

```bash theme={"system"}
pnpm --filter @darkpool/server db:migrate
```

The `migrate` Docker service runs this as a one-shot at compose-up.

## Inspection

```bash theme={"system"}
psql postgresql://darkpool:darkpool@localhost:5433/darkpool -c "SELECT count(*) FROM fills;"
psql postgresql://darkpool:darkpool@localhost:5433/darkpool -c "SELECT id, label, final_outcome FROM dark_pool_vaults;"
```

## What's not indexed yet (v0.4 follow-ups)

* `binary::<slug>::settlement::MarketCreated` / `PairMinted` / `MarketResolved` are not indexed. `/v1/binary-markets` reads chain state directly, which is fine at this scale.
* `predict_facade::*` attribution events are not indexed. The router relies on the underlying `predict::*` events instead.
* Pause / resume of agents is not indexed (no events emitted by Move). The UI reads `is_active` live via `sui.getObject`.
