Latest — Explore subgraphs is live

Every chain event.
None of the infra.

Build a custom indexer at any altitude — the raw event firehose, decoded queryable rows, or a hosted one-file subgraph. All decoded Stacks data, no node to run.

Read the docs
sBTCbridge + token
PoX-4stacking
BNSnames
SIP-010fungible tokens
SIP-009nfts
Velaramm swaps
Arkadikovaults
ALEXdefi
Zestlending
StackingDAOliquid stacking
sBTCbridge + token
PoX-4stacking
BNSnames
SIP-010fungible tokens
SIP-009nfts
Velaramm swaps
Arkadikovaults
ALEXdefi
Zestlending
StackingDAOliquid stacking
sBTCbridge + token
PoX-4stacking
BNSnames
SIP-010fungible tokens
SIP-009nfts
Velaramm swaps
Arkadikovaults
ALEXdefi
Zestlending
StackingDAOliquid stacking
sBTCbridge + token
PoX-4stacking
BNSnames
SIP-010fungible tokens
SIP-009nfts
Velaramm swaps
Arkadikovaults
ALEXdefi
Zestlending
StackingDAOliquid stacking

Decoded chain data, kept indexed

Every FT and NFT transfer, contract call, and print event — decoded, typed, and cursor-paginated. Read it keyless, or sweep it into your own app index: backfill from genesis, reorgs flagged on every page.

Explore Index
// sweep decoded sBTC transfers into your own table
for await (const t of sl.index.ftTransfers.walk({
  contractId: "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token",
})) {
  await save(t); // typed: sender, recipient, amount
}

// or just read — keyless, by contract or trait
await sl.index.events({ eventType: "ft_transfer", trait: "sip-010" });
ft-transfers · sbtc-tokenquerying…
senderrecipientamountblock

You shape it. We run it.

Define sources, schema, and handlers in one TypeScript file. Deploy it and get typed Postgres tables, a public read API, and a page on Explore — live from the moment you deploy, full genesis history on paid plans.

Explore Subgraphs
export default defineSubgraph({
  name: "sbtc-flows",
  sources: { transfer: { type: "ft_transfer",
    assetIdentifier: "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token" } },
  schema: {
    transfers: { columns: {
      sender:    { type: "principal", indexed: true },
      recipient: { type: "principal", indexed: true },
      amount:    { type: "uint" } } },
    balances: {
      columns: {
        address: { type: "principal" },
        balance: { type: "uint" } },
      uniqueKeys: [["address"]] },
  },
  handlers: { transfer: async (e, ctx) => { /* ... */ } },
});

// query it back — anonymous read on public subgraphs
const { rows } = await sl.subgraphs.rows("sbtc-flows", "transfers", { limit: 3 });
sbtc-flows · creating schemadeploying
transferscreating…
senderprincipalindexed
recipientprincipalindexed
amountuint 
balancescreating…
addressprincipalunique
balanceuint 
+ _id · _block_height · _tx_id on every table

Consume the raw firehose

Every event the chain emits — ordered, cursor-paginated, reorg-aware. Resume from any cursor, replay history from signed bulk dumps, or hold the tip. This is what you'd run a node for — and what Index itself is built on.

Explore Streams
// resume the firehose from your cursor
for await (const batch of sl.streams.consume({ cursor })) {
  await handle(batch.events); // ordered, reorg-aware
}

// or bulk history from signed dumps
const dumps = await sl.streams.dumps.list();
consuming · cursor 7,978,231:420 reorgs
blockeventsreceived

Webhooks when it happens

Subscribe to chain events or your subgraph rows and get signed deliveries with retries and circuit breakers. The push channel for Index and Subgraphs — no polling loop to babysit.

Read the docs
await sl.subscriptions.create({
  name: "whale-alerts",
  triggers: [trigger.ftTransfer({
    assetIdentifier: "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token",
    minAmount: 100_000_000, // ≥ 1 BTC
  })],
  url: "https://hooks.example.com/sbtc",
});
whale-alerts1 trigger matched
On-chain event
event ft_transfer
1.20 sBTC
from SP2J6…X0G
tx 0x9f3c41…
POST · signed
Your endpoint
hooks.example.com/sbtc
status200 OK
verified✓ signature
webhook-signature t=1718…,v1=k38f…delivered · 84ms

The same API, from your shell

Every surface is also a command. Scaffold, deploy, query, tail — pipeable, scriptable, JSON when you ask for it. Local devnet included.

Read the docs
# contract → subgraph in one line
sl subgraphs scaffold SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token -o sbtc.ts

# deploy + watch it sync
sl subgraphs deploy sbtc.ts
sl subgraphs status sbtc-flows

# query from the shell, pipe to jq
sl subgraphs query sbtc-flows transfers --limit 3 --json
$
✓ deployed sbtc-flows (public)
read: /v1/subgraphs/sbtc-flows/transfers
share: secondlayer.tools/subgraphs/explore/sbtc-flows
$

Get started

Run it yourself. Or hand it to your agent.

Reads need no key, deploys need one command — and the whole surface speaks MCP, so the fastest path might be pasting one block into your harness.

In your agent's harness
Claude CodeCursorCodexany MCP client
Ensure setup once, skipping any step already done:
- Skill: `bunx skills add ryanwaits/secondlayer --skill secondlayer -y`
- CLI: `bun add -g @secondlayer/cli`
- Auth: `sl login` then `sl whoami`
- Plan: `sl billing`; if there is no active plan or trial, start one from the Billing page

Subgraphs are declarative SQL tables that auto-index Stacks blockchain activity into queryable Postgres tables. Define named sources, a typed schema, and handlers in TypeScript, then deploy and query.

/secondlayer Help me create a subgraph from a Stacks contract. Ask me for the contract id and the events or function calls I care about. Scaffold with `sl subgraphs scaffold` so the module package and dependencies are prepared, explain the generated named sources and tables, let me review or customize the handlers, deploy with `sl subgraphs deploy`, query recent rows, then ask whether I want a subscription webhook.

Stop rebuilding the indexer.
Start shipping features.

Open data, open SDKs, honest infrastructure — decoded sBTC, PoX, and Clarity calls included.