Skip to main content
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

All active streams:
StreamSourceDestination table
predict::PositionMintedDeepBook Predict packagefills
predict::PositionRedeemedDeepBook Predict packageredemptions
predict::oracle::*DeepBook Predict packageoracles, oracle_strikes
darkpool::oo_resolution::ProposalCreated etc.DarkPool packageoo_proposals, oo_votes
darkpool::agent::AgentRegisteredDarkPool packageagents
darkpool::dark_pool::VaultCreated etc.DarkPool packagedark_pool_vaults, dark_pool_deposits, dark_pool_settlements, dark_pool_redemptions
binary::<slug>::settlement::Redeemedper-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

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

[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:
pnpm --filter @darkpool/server db:migrate
The migrate Docker service runs this as a one-shot at compose-up.

Inspection

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.