Devnet
Run the full Secondlayer stack (Postgres, indexer, API, subgraph processor) against your local Clarinet devnet. No cloud, no accounts, no key to read your data.
Coming from Chainhook?
This is the local path; map your predicates over with Migrating from Chainhook.
- Clarinet and a Clarinet project (a directory with
Clarinet.toml). - Docker (Docker Desktop or OrbStack on macOS).
- The CLI:
bun add -g @secondlayer/cli.
From inside your Clarinet project:
secondlayer devnet connect- Patches
settings/Devnet.tomlso the devnet node forwards events to the local indexer (stacks_node_events_observers = ["host.docker.internal:3700"]). - Writes
.secondlayer/docker-compose.ymlfor the published OSS images. - Brings the stack up with
docker compose up -d.
Secondlayer stack up
api → http://localhost:3800
indexer → http://localhost:3700Patch config without starting Docker
Pass --no-up to write settings/Devnet.toml and the compose file without starting containers, then bring it up yourself with docker compose -f .secondlayer/docker-compose.yml up -d.
Options
| Flag | Default | Purpose |
|---|---|---|
--project <dir> | nearest Clarinet.toml | Clarinet project directory |
--image-tag <tag> | latest | Published image tag to run |
--owner <owner> | Secondlayer namespace | ghcr image owner to pull from |
--no-up | — | Patch config + write compose without starting Docker |
Start the devnet; it auto-deploys your contracts and streams every block to the indexer.
clarinet devnet startPoint the CLI at the local API. There is no login: a deploy is a write, and the generated stack ships a fixed local token, dev-instance-token, for exactly that:
SL_API_URL=http://localhost:3800 \
INSTANCE_TOKEN=dev-instance-token \
secondlayer subgraphs deploy ./subgraph.tsIt is a local-dev value, not a secret; a real instance gets its own from secondlayer init.
Fire a contract call in your devnet and the matching rows land in your subgraph's tables. Reading them back takes no credential at all — the compose publishes the API on 127.0.0.1 only, and /v1 reads are keyless whenever the API is reachable from this box alone:
curl http://localhost:3800/v1/subgraphs/my-app/balancesSee Authentication.
secondlayer devnet statusSTACK
● indexer healthy :3700
● api healthy :3800
INGEST
chain tip 142 indexed 142 lag caught up last block 2s ago
SUBGRAPHS
my-balances active block 142 balances · 37 rowsAdd -w to refresh every 2s, or --limit <n> to change how many recent rows show.
Tail logs for the whole stack or one service (indexer, api, subgraph-processor, postgres):
secondlayer devnet logs indexer -fsecondlayer devnet down # stop the stack
secondlayer devnet down --purge # stop and wipe the local index volumes