@secondlayer/cli
v8.12.0
Published
CLI for subgraphs and blockchain indexing on Stacks
Downloads
6,646
Maintainers
Readme
@secondlayer/cli
The Secondlayer CLI — one binary for Stacks indexing, real-time subgraphs, subscriptions, and Clarity code generation.
bun add -g @secondlayer/cli
sl --versionAuth
Two ways to authenticate:
- Interactive (
sl login) — magic-link email → 6-digit code → session written to~/.secondlayer/session.json. Used for day-to-day CLI work. - Machine / CI — set
SL_API_KEYto an API key created in the platform console at https://secondlayer.tools/platform/api-keys. Keys are prefixedsk-sl_. For a persisted headless login:echo "$SL_API_KEY" | sl login --with-token.
# interactive
sl login
# machine / CI
export SL_API_KEY=sk-sl_xxxxxxxxsl whoami shows the active account, the effective API URL, and the credential
source (and exits non-zero when not logged in). The global --api-key /
--api-url flags (and SL_API_KEY / SL_API_URL) apply to every command.
During open beta, reads are public (no key needed) — for subgraphs that means
public subgraphs only (managed deploys default public; BYO deploys and all
pre-existing subgraphs are private, readable with your key). Writes — deploying,
publishing, or managing subgraphs and subscriptions — require a session or an
sk-sl_ key.
Quickstart
bun add -g @secondlayer/cli
sl login
sl projects create my-app
sl projects use my-app
# scaffold + deploy a subgraph from a deployed contract
sl subgraphs scaffold SP1234ABCD.my-contract -o subgraphs/my-contract.ts
sl subgraphs deploy subgraphs/my-contract.ts --start-block <recent-block>
sl subgraphs query my-contract <table> --sort _block_height --order desc
# wire a webhook receiver
sl subscriptions create my-hook \
--runtime node \
--subgraph my-contract \
--table <table> \
--url https://<receiver-host>/webhooksl subgraphs scaffold writes the definition file, creates/updates
package.json, and runs bun install (pass --no-install to skip).
Commands
Auth & project
| Command | What it does |
|---|---|
| sl login / sl logout | Start or revoke a session |
| sl whoami | Print account, credential source, and active project |
| sl keys create --product streams [--name <name>] | Mint a scoped streams/index read key; prints the sk-sl_ key once. Needs an account key in SL_API_KEY |
| sl projects create [name] | Create a project |
| sl projects list | List projects |
| sl projects use <slug> | Bind cwd to a project (writes ./.secondlayer/project) |
| sl projects get | Show resolved project + source file |
| sl projects delete <slug> (alias rm) | Delete a project (-y to skip confirm) |
Project binding is per-directory: .secondlayer/project in cwd takes
precedence over ~/.secondlayer/config.json:defaultProject. The walk-up stops
at .git.
Key products: an account key (dashboard default) grants both streams:read
and index:read and is the only key that can mint; streams/index keys are
scoped reads and cannot mint (403). Minted keys inherit your plan's tier.
Subgraphs
| Command | What it does |
|---|---|
| sl subgraphs create <name> | Scaffold a definition file |
| sl subgraphs scaffold <SP...::contract> [-o <path>] [--no-install] | Generate a subgraph from a deployed contract |
| sl subgraphs deploy <file> [--start-block <n>] [--visibility public\|private] | Deploy; --start-block overrides the definition. Managed deploys default public, BYO default private |
| sl subgraphs publish <name> / unpublish <name> | Flip visibility; publish claims the global public name (409 PUBLIC_NAME_TAKEN if claimed) |
| sl subgraphs dev <file> | Watch + hot-redeploy |
| sl subgraphs query <name> <table> | Query a table with filters, sort, pagination |
| sl subgraphs list / status <name> / gaps <name> | Inspect deployments |
| sl subgraphs spec <nameOrFile> [--format openapi\|agent\|markdown] | Export API docs for a deployed subgraph or a local definition file |
| sl subgraphs deploy <file> --database-url <url> | BYO: write the subgraph's rows to your own Postgres |
| sl subgraphs codegen <file> --target prisma\|drizzle [-o <path>] | Generate an ORM schema for the subgraph's tables (BYO DB) |
| sl subgraphs client <name> -o <path> | Generate a typed query client for a deployed subgraph |
| sl subgraphs reindex/backfill/cancel/delete <name> | Manage processing |
Data products (reads)
| Command | What it does |
|---|---|
| sl index ft-transfers / nft-transfers / events --event-type <t> / contract-calls | Decoded Index layer. Anonymous reads OK; free-tier keys rejected (Build+ for keyed) |
| sl streams tip / events / consume / reorgs / canonical <h> / pull | Raw chain event firehose. Requires SL_API_KEY |
Reads emit JSON to stdout (--json accepted across all read commands); -o/--output is a file path, not a format.
Subscriptions
| Command | What it does |
|---|---|
| sl subscriptions create <name> --runtime <inngest\|trigger\|cloudflare\|node> [--auth-token <token>] [--filter key=value] | Scaffold a receiver wired to a new subscription |
| sl subscriptions list / get <id\|name> | List or show config + delivery state |
| sl subscriptions update <id\|name> --url <url> [--filter key.gte=value] | Patch URL, filter, format, retry, etc. |
| sl subscriptions pause/resume <id\|name> | Stop or restart delivery |
| sl subscriptions rotate-secret <id\|name> | Rotate signing secret (printed once) |
| sl subscriptions deliveries/dead <id\|name> | Recent attempts / dead-letter rows |
| sl subscriptions requeue <id\|name> <outboxId> | Requeue one dead-letter row |
| sl subscriptions replay <id\|name> --from-block <n> --to-block <n> | Enqueue a historical block range |
| sl subscriptions doctor/test <id\|name> | Health check / signed fixture |
Read/action commands support --json. Destructive commands prompt unless
-y / --yes. Filters are schema-aware: unknown tables/columns, bad operators,
and non-scalar columns are rejected before the API call.
Subscriptions are polymorphic — subgraph (fires on a subgraph table's rows)
or chain (fires on raw chain events with no subgraph). sl subscriptions
create makes subgraph subscriptions only (via the --subgraph/--table
flags). Create chain subscriptions — a webhook on a contract / event / function /
trait — via the SDK, REST, or MCP with a triggers array. Every other
sl subscriptions command (list/get/update/pause/resume/delete/doctor/test/
deliveries/...) operates on both kinds.
Other
| Command | What it does |
|---|---|
| sl contracts generate [files...] (alias gen) | Generate TS interfaces from Clarity contracts |
| sl context | Print a headless orientation snapshot — account, Streams + Index tips, your subgraphs, subscriptions, and in-flight reindex operations. CLI counterpart to the MCP secondlayer://context resource |
| sl init | Scaffold secondlayer.config.ts |
| sl doctor / sl status | Reachability + health checks |
| sl account get / sl account update | Show or update display name / bio / slug |
| sl account billing | Show plan, subscription, trial, discounts |
| sl config get/set/reset/delete | Inspect or reset local config |
Environment variables
| Var | Purpose |
|---|---|
| SL_API_KEY | An sk-sl_ API key (or session token) for machine/CI use; bypasses platform resolution |
| SL_API_URL | Point at an OSS or internal API directly, bypassing the platform |
| SL_PLATFORM_API_URL | Override the platform API base (default https://api.secondlayer.tools) |
| STACKS_NETWORK | Default network (also via --network <local\|testnet\|mainnet>) |
| HIRO_API_KEY | Used by sl contracts generate for remote contract fetches |
Code generation (sl contracts generate)
Generate type-safe interfaces, functions, and optional React hooks from Clarity
contracts — local .clar files, deployed contracts (network inferred from
address prefix), or globs.
sl contracts generate ./contracts/token.clar -o ./src/generated.ts
sl contracts generate SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.alex-vault -o ./src/generated.ts
sl contracts generate "./contracts/*.clar" -o ./src/generated.tsConfig-driven:
sl init # creates secondlayer.config.ts
sl contracts generate # regenerates from the config// secondlayer.config.ts
import { defineConfig } from "@secondlayer/cli"
import { clarinet, actions, react } from "@secondlayer/cli/plugins"
export default defineConfig({
out: "src/generated.ts",
plugins: [clarinet(), actions(), react()],
})| Plugin | What it adds |
|---|---|
| clarinet() | Parse local Clarinet project |
| actions() | read.* + write.* helpers per contract |
| react() | Typed React Query hooks |
| testing() | Clarinet SDK test helpers |
import { token } from "./generated/contracts"
// Works with @stacks/transactions directly:
await makeContractCall({
...token.transfer({ amount: 100n, recipient: "SP..." }),
network: "mainnet",
})
// With actions() — read/write helpers + maps/vars/constants:
const balance = await token.read.getBalance({ account: "SP..." })
await token.write.transfer({ amount: 100n, recipient: "SP..." })
const supply = await token.vars.totalSupply.get()Frozen commands
Local-dev periphery: still functional, hidden from sl --help, no further
investment — may be removed in a future major. The hosted dev loop
(sl subgraphs create/deploy) is the supported path.
sl local up/down/start/stop/restart/status/logs— local stack + dev servicessl local node ...— local Stacks node managementsl local db ...— local source DB inspectionsl devnet connect/down/status/logs— Clarinet devnet integration
Docs
Full reference: https://secondlayer.tools/docs
License
MIT
