Operate / Devnet

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.toml so the devnet node forwards events to the local indexer (stacks_node_events_observers = ["host.docker.internal:3700"]).
  • Writes .secondlayer/docker-compose.yml for the published OSS images.
  • Brings the stack up with docker compose up -d.
Secondlayer stack up
  api http://localhost:3800
  indexer http://localhost:3700

Patch 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

FlagDefaultPurpose
--project <dir>nearest Clarinet.tomlClarinet project directory
--image-tag <tag>latestPublished image tag to run
--owner <owner>Secondlayer namespaceghcr image owner to pull from
--no-upPatch config + write compose without starting Docker

Start the devnet; it auto-deploys your contracts and streams every block to the indexer.

clarinet devnet start

Point 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.ts

It 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/balances

See Authentication.

secondlayer devnet status
STACK
 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 rows

Add -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 -f
secondlayer devnet down            # stop the stack
secondlayer devnet down --purge    # stop and wipe the local index volumes