Index a Stacks contract into Postgres with TypeScript
One file says which contract to watch and which rows to keep, and the table appears with a REST API over it. You write no indexer and no API. One file, one command:
A source picks the events, the schema declares the table, and the handler writes one row per event. Handlers covers the rest of what a handler can do.
Run your handler against real chain events before you deploy. Start in a project that has the package:
The test writes nothing to your hosted stack (it saves a cassette in cassettes/) and fails if events arrive but no rows come out.
sBTC is busy: 459 events in 100 blocks. That is why the file sets startBlock, so the first run backfills a bounded range and not all history.
Create a key at /account/keys and set the two variables from the Introduction. In a git repo the file must be staged first, so a copy exists outside the database; pass --allow-uncommitted to skip that check, as in a script.
git addthe file, then run the deploy command above.- Add
--dry-runto validate and preview the tables with no changes. - Rows serve while the backfill drains (Check status).
The table is served as a paged API. From a terminal, newest first:
Over HTTP it is /v1/subgraphs/sbtc-transfers/transfers. The SDK call, the response envelope, sorting, filters and live streams are under Read your table.
Change the source to watch a different contract. A token or NFT contract is an assetIdentifier; a contract that prints is scaffolded from its history.
- The scaffold reads the contract's indexed prints and writes a typed source per topic (Typed print payloads).
- The scaffold sets no
startBlock: set one before you deploy, or the first run backfills all history. - Preview with
secondlayer subgraphs deploy <file> --dry-run.
A hosted subgraph runs on your hosted stack, with a $10 a month minimum while it runs. Its indexing bills the event and transaction rows it reads, and reading your own subgraph tables is free (What it costs). The tables are Postgres, but hosted serves them over REST and streams, not as a connection string; for direct SQL, self-host.
Every route: List subgraph rows. The full file format and what runs hosted: Subgraphs.
Edit on GitHub