Skip to content

Commit 76960fb

Browse files
committed
docs: audit and fix outdated READMEs across all packages
Remove dead contracts API examples from root, sdk, api, shared READMEs. Fix infra docs: backfill hiro-pg source, raw_tx burnchain ops, sync estimates, zstd archive commands, $COMPOSE consistency. Fix stacks module docs: transport signatures, pox params, action imports, new enum values. Remove dead contracts export from shared package.json.
1 parent 6bc1d94 commit 76960fb

10 files changed

Lines changed: 98 additions & 134 deletions

File tree

README.md

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,6 @@ bun add -g @secondlayer/cli
169169
sl auth login # authenticate via magic link
170170
sl streams list # manage event streams
171171
sl subgraphs list # manage subgraphs
172-
sl contracts search "token" # search indexed contracts by name
173-
sl contracts info SP2J6..token # contract details (deployer, call count, etc.)
174-
sl contracts abi SP2J6..token # fetch + display contract ABI
175172
```
176173

177174
All commands support `--json` for machine-readable output.
@@ -187,32 +184,32 @@ import { SecondLayer } from "@secondlayer/sdk";
187184

188185
const sl = new SecondLayer({ apiKey: "sk-sl_..." });
189186

190-
// Search contracts
191-
const { contracts, total } = await sl.contracts.search("bns", { limit: 10 });
187+
// List streams
188+
const { streams, total } = await sl.streams.list({ status: "active" });
192189

193-
// Get contract detail
194-
const contract = await sl.contracts.get("SP000000000000000000002Q6VF78.bns");
190+
// Create a stream
191+
const { stream, signingSecret } = await sl.streams.create({
192+
name: "my-stream",
193+
endpointUrl: "https://example.com/receive",
194+
filters: { type: "contract_call", contract_id: "SP...token" },
195+
});
195196

196-
// Fetch ABI (lazy-cached from Stacks node)
197-
const abi = await sl.contracts.getAbi("SP000000000000000000002Q6VF78.bns");
197+
// List subgraphs
198+
const { data } = await sl.subgraphs.list();
198199
```
199200

200201
### REST API
201202

202203
Base URL: `https://api.secondlayer.tools`
203204

204205
```bash
205-
# Search contracts
206+
# List streams
206207
curl -H "Authorization: Bearer $TOKEN" \
207-
"https://api.secondlayer.tools/api/contracts?q=bns&limit=20"
208+
"https://api.secondlayer.tools/api/streams"
208209

209-
# Contract detail
210+
# List subgraphs
210211
curl -H "Authorization: Bearer $TOKEN" \
211-
"https://api.secondlayer.tools/api/contracts/SP000000000000000000002Q6VF78.bns"
212-
213-
# Contract ABI (cached, ?refresh=true to force re-fetch)
214-
curl -H "Authorization: Bearer $TOKEN" \
215-
"https://api.secondlayer.tools/api/contracts/SP000000000000000000002Q6VF78.bns/abi"
212+
"https://api.secondlayer.tools/api/subgraphs"
216213
```
217214

218215
See [packages/api/README.md](packages/api/README.md) and [packages/sdk/README.md](packages/sdk/README.md) for full docs.

docker/docs/README.md

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ chown -R 1000:1000 $BITCOIN_DATA_DIR
8181

8282
## Genesis Sync
8383

84-
Full chain sync from block 0. Takes ~4-10 days total. **All steps are manual** — stacks-node does not auto-start.
84+
Full chain sync from block 0. Takes ~10-14 days total. **All steps are manual** — stacks-node does not auto-start.
8585

8686
### Steps
8787

@@ -109,7 +109,7 @@ cd /opt/secondlayer/docker
109109
# Truncate DB for clean genesis sync
110110
docker exec secondlayer-postgres-1 psql -U secondlayer -d secondlayer \
111111
-c "TRUNCATE blocks, transactions, events, jobs, deliveries, index_progress CASCADE;"
112-
TIP_FOLLOWER_ENABLED=false docker compose -f docker-compose.yml -f docker-compose.hetzner.yml up -d
112+
TIP_FOLLOWER_ENABLED=false $COMPOSE up -d
113113
```
114114

115115
**3. Start stacks-node** — only after bitcoind blocks > 666050
@@ -133,7 +133,7 @@ ssh node-server "cd /opt/secondlayer/docker/node-server && docker compose logs -
133133

134134
# App server
135135
ssh app-server "cd /opt/secondlayer/docker && \
136-
docker compose -f docker-compose.yml -f docker-compose.hetzner.yml logs -f indexer"
136+
$COMPOSE logs -f indexer"
137137
```
138138

139139
**4. After sync completes**
@@ -142,14 +142,13 @@ ssh app-server "cd /opt/secondlayer/docker && \
142142
ssh app-server
143143
cd /opt/secondlayer/docker
144144

145-
# Verify no placeholder transactions
145+
# Check for placeholder transactions (excluding burnchain ops which legitimately have raw_tx = '0x00')
146146
docker exec secondlayer-postgres-1 psql -U secondlayer -d secondlayer \
147-
-c "SELECT COUNT(*) FROM transactions WHERE raw_tx = '0x00';"
148-
# Should be 0
147+
-c "SELECT COUNT(*) FROM transactions WHERE raw_tx = '0x00' AND type_id NOT IN (1,2,3,4,5);"
148+
# Should be 0. ~700 burnchain operations (PoX stacking, STX transfers via BTC) have raw_tx = '0x00' by design.
149149

150150
# Re-enable tip follower
151-
TIP_FOLLOWER_ENABLED=true docker compose -f docker-compose.yml -f docker-compose.hetzner.yml \
152-
up -d --force-recreate indexer
151+
TIP_FOLLOWER_ENABLED=true $COMPOSE up -d --force-recreate indexer
153152
```
154153

155154
### Re-sync from genesis
@@ -392,13 +391,25 @@ docker run -d --name backfill \
392391
-e BACKFILL_BATCH_SIZE=100 \
393392
-e BACKFILL_FROM=2 \
394393
oven/bun:latest bun run packages/indexer/src/bulk-backfill.ts
394+
395+
# Fastest option: backfill from local Hiro Postgres (~150 blocks/sec)
396+
docker run -d --name backfill \
397+
--network secondlayer_default \
398+
-v /opt/secondlayer:/app -w /app \
399+
-e DATABASE_URL=postgres://secondlayer:secondlayer@postgres:5432/secondlayer \
400+
-e HIRO_PG_URL=postgres://hiro_user:password@hiro-postgres:5432/stacks_blockchain_api \
401+
-e BACKFILL_SOURCE=hiro-pg \
402+
-e BACKFILL_CONCURRENCY=20 \
403+
-e BACKFILL_BATCH_SIZE=100 \
404+
-e BACKFILL_FROM=2 \
405+
oven/bun:latest bun run packages/indexer/src/bulk-backfill.ts
395406
```
396407

397408
> Block 1 (genesis) has 330K events. Always set `BACKFILL_FROM=2`.
398409
399410
| Variable | Default | Description |
400411
|----------|---------|-------------|
401-
| `BACKFILL_SOURCE` | `hiro` | `hiro` = Hiro API, `local` = own Postgres |
412+
| `BACKFILL_SOURCE` | `hiro` | `hiro` = Hiro API, `local` = own Postgres, `hiro-pg` = direct PG queries against local Hiro API database (fastest, ~150 blocks/sec) |
402413
| `BACKFILL_FROM` | `2` | Start height |
403414
| `BACKFILL_TO` | auto | End height (auto-detects chain tip) |
404415
| `BACKFILL_CONCURRENCY` | `20` | Parallel fetches |
@@ -419,16 +430,18 @@ Bootstrap stacks-node from Hiro's archive (~800-900 GB) instead of syncing from
419430
```bash
420431
# Stream to disk (node server)
421432
ssh node-server
422-
wget -qO- https://archive.hiro.so/mainnet/stacks-blockchain/mainnet-stacks-blockchain-latest.tar.gz \
423-
| tar xzf - -C /data/stacks
433+
wget -qO- https://archive.hiro.so/mainnet/stacks-blockchain/mainnet-stacks-blockchain-latest.tar.zst \
434+
| tar --zstd -xf - -C /data/stacks
424435

425436
# With resume support
426-
curl --continue-at - -L -o /tmp/snapshot.tar.gz \
427-
https://archive.hiro.so/mainnet/stacks-blockchain/mainnet-stacks-blockchain-latest.tar.gz
428-
tar -xzf /tmp/snapshot.tar.gz -C /data/stacks
429-
rm /tmp/snapshot.tar.gz
437+
curl --continue-at - -L -o /tmp/snapshot.tar.zst \
438+
https://archive.hiro.so/mainnet/stacks-blockchain/mainnet-stacks-blockchain-latest.tar.zst
439+
tar --zstd -xf /tmp/snapshot.tar.zst -C /data/stacks
440+
rm /tmp/snapshot.tar.zst
430441
```
431442

443+
> The archive may contain empty sqlite files. Stacks-node regenerates them on first boot — expect a longer initial startup.
444+
432445
---
433446

434447
## Troubleshooting

packages/api/README.md

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @secondlayer/api
22

3-
REST API for Second Layer — streams, subgraphs, and contract discovery.
3+
REST API for Second Layer — streams and subgraphs.
44

55
Base URL: `https://api.secondlayer.tools`
66

@@ -9,60 +9,11 @@ Base URL: `https://api.secondlayer.tools`
99
All endpoints require a Bearer token (session token or API key):
1010

1111
```bash
12-
curl -H "Authorization: Bearer ss-sl_..." https://api.secondlayer.tools/api/contracts?q=bns
12+
curl -H "Authorization: Bearer ss-sl_..." https://api.secondlayer.tools/api/streams
1313
```
1414

1515
Get a session token via the CLI: `sl auth login`
1616

17-
## Contracts
18-
19-
### Search
20-
21-
```
22-
GET /api/contracts?q=<query>&limit=20&offset=0
23-
```
24-
25-
| Param | Required | Default | Description |
26-
|-------|----------|---------|-------------|
27-
| `q` | yes || Search term (matches name and contract_id via ILIKE) |
28-
| `limit` | no | 20 | Max results (1-100) |
29-
| `offset` | no | 0 | Pagination offset |
30-
31-
Response:
32-
```json
33-
{
34-
"contracts": [
35-
{
36-
"contractId": "SP000000000000000000002Q6VF78.pox",
37-
"name": "pox",
38-
"deployer": "SP000000000000000000002Q6VF78",
39-
"deployBlock": 0,
40-
"callCount": 20,
41-
"lastCalledAt": "2026-03-09T19:56:12.000Z",
42-
"createdAt": "2026-03-09T18:00:00.000Z"
43-
}
44-
],
45-
"total": 1
46-
}
47-
```
48-
49-
### Get Contract
50-
51-
```
52-
GET /api/contracts/:contractId
53-
```
54-
55-
Returns `ContractDetail` (summary + `deployTxId`, `abi`, `updatedAt`). 404 if not found.
56-
57-
### Get ABI
58-
59-
```
60-
GET /api/contracts/:contractId/abi
61-
GET /api/contracts/:contractId/abi?refresh=true
62-
```
63-
64-
Returns the contract's Clarity ABI as JSON. On first request, fetches from the Stacks node and caches in the database. Subsequent requests serve from cache. Pass `?refresh=true` to force re-fetch (useful for upgraded contracts).
65-
6617
## Streams
6718

6819
```

packages/sdk/README.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,6 @@ const sl = new SecondLayer({
1919
});
2020
```
2121

22-
## Contracts
23-
24-
Search, inspect, and fetch ABIs for on-chain contracts.
25-
26-
```typescript
27-
// Search by name
28-
const { contracts, total } = await sl.contracts.search("bns", { limit: 10, offset: 0 });
29-
30-
// Get contract detail
31-
const contract = await sl.contracts.get("SP000000000000000000002Q6VF78.bns");
32-
// { contractId, name, deployer, deployBlock, deployTxId, callCount, lastCalledAt, abi, ... }
33-
34-
// Fetch ABI (lazy-cached from Stacks node)
35-
const abi = await sl.contracts.getAbi("SP000000000000000000002Q6VF78.bns");
36-
// { functions: [...], maps: [...], variables: [...], ... }
37-
```
38-
3922
## Streams
4023

4124
Manage real-time event streams with endpoint delivery.
@@ -85,7 +68,7 @@ const result = await sl.subgraphs.deploy({ name, sources, schema, handlerCode })
8568
import { ApiError } from "@secondlayer/sdk";
8669

8770
try {
88-
await sl.contracts.get("nonexistent");
71+
await sl.streams.get("nonexistent");
8972
} catch (err) {
9073
if (err instanceof ApiError) {
9174
console.log(err.status); // 404

packages/shared/README.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,25 @@ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/streams_test bun test
1818
DATABASE_URL=... bun run migrate
1919
```
2020

21-
## Contracts
22-
23-
Query helpers for the `contracts` table:
24-
25-
```typescript
26-
import { searchContracts, getContract, cacheContractAbi } from "@secondlayer/shared/db/queries/contracts";
27-
28-
// Search by name or contract_id (uses pg_trgm for fast ILIKE)
29-
const { contracts, total } = await searchContracts(db, "bns", 20, 0);
30-
31-
// Get single contract by ID
32-
const contract = await getContract(db, "SP000000000000000000002Q6VF78.bns");
33-
34-
// Cache ABI fetched from Stacks node
35-
await cacheContractAbi(db, "SP000000000000000000002Q6VF78.bns", abiJson);
36-
```
37-
38-
Response schemas (`@secondlayer/shared/schemas`):
39-
40-
- `ContractSummary` — contractId, name, deployer, deployBlock, callCount, lastCalledAt, createdAt
41-
- `ContractDetail` — extends summary with deployTxId, abi, updatedAt
42-
- `SearchContractsResponse` — { contracts: ContractSummary[], total: number }
21+
## Exports
22+
23+
| Path | Description |
24+
|------|-------------|
25+
| `@secondlayer/shared` | Core utilities |
26+
| `@secondlayer/shared/db` | Kysely database layer |
27+
| `@secondlayer/shared/db/queries/*` | Query helpers (integrity, metrics, accounts, usage, subgraphs) |
28+
| `@secondlayer/shared/db/schema` | Database schema |
29+
| `@secondlayer/shared/db/jsonb` | JSONB helpers |
30+
| `@secondlayer/shared/schemas` | Zod schemas |
31+
| `@secondlayer/shared/schemas/filters` | Stream filter schemas |
32+
| `@secondlayer/shared/schemas/subgraphs` | Subgraph schemas |
33+
| `@secondlayer/shared/types` | Shared TypeScript types |
34+
| `@secondlayer/shared/queue` | Job queue |
35+
| `@secondlayer/shared/queue/listener` | Queue listener |
36+
| `@secondlayer/shared/queue/recovery` | Queue recovery |
37+
| `@secondlayer/shared/env` | Environment config |
38+
| `@secondlayer/shared/logger` | Logger |
39+
| `@secondlayer/shared/errors` | Error types |
40+
| `@secondlayer/shared/crypto` | HMAC signing |
41+
| `@secondlayer/shared/node` | Stacks node client |
42+
| `@secondlayer/shared/lib/plans` | Plan definitions |

packages/shared/package.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@
3333
"types": "./dist/src/db/queries/subgraphs.d.ts",
3434
"import": "./dist/src/db/queries/subgraphs.js"
3535
},
36-
"./db/queries/contracts": {
37-
"types": "./dist/src/db/queries/contracts.d.ts",
38-
"import": "./dist/src/db/queries/contracts.js"
39-
},
4036
"./db/jsonb": {
4137
"types": "./dist/src/db/jsonb.d.ts",
4238
"import": "./dist/src/db/jsonb.js"

packages/stacks/src/actions/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Standalone action functions for tree-shakeable imports. These are the same funct
55
## Public (Read-Only) Actions
66

77
```typescript
8-
import { getBalance, getNonce, readContract, getBlock } from "@secondlayer/stacks/actions";
8+
import { getBalance, getNonce, readContract, getBlock, getBlockHeight } from "@secondlayer/stacks/actions";
99

1010
const balance = await getBalance(client, { address: "SP2J6..." });
1111
const nonce = await getNonce(client, { address: "SP2J6..." });

packages/stacks/src/pox/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ await wallet.pox.stackStx({
5050
amount: 100_000_000_000n, // 100k STX in microSTX
5151
btcAddress: "bc1q...", // BTC reward address
5252
lockPeriod: 12, // 1-12 cycles
53+
startBurnHeight: 850_000n, // burn height at which stacking begins
5354
signerSig: signature, // signer signature (buff 65)
5455
signerKey: publicKey, // signer public key (buff 33)
5556
maxAmount: 100_000_000_000n,

packages/stacks/src/transactions/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,30 @@ const originSigned = signTransaction(tx, originKey);
116116
const fullySigned = signSponsor(originSigned, sponsorKey);
117117
```
118118

119+
## Enums
120+
121+
### ClarityVersion
122+
123+
| Name | Value |
124+
|------|-------|
125+
| `Clarity1` | 1 |
126+
| `Clarity2` | 2 |
127+
| `Clarity3` | 3 |
128+
| `Clarity4` | 4 |
129+
| `Clarity5` | 5 |
130+
131+
### TenureChangeCause
132+
133+
| Name | Value |
134+
|------|-------|
135+
| `BlockFound` | 0x00 |
136+
| `Extended` | 0x01 |
137+
| `ExtendedRuntime` | 0x02 |
138+
| `ExtendedReadCount` | 0x03 |
139+
| `ExtendedReadLength` | 0x04 |
140+
| `ExtendedWriteCount` | 0x05 |
141+
| `ExtendedWriteLength` | 0x06 |
142+
119143
## Wire Format
120144

121145
```typescript

packages/stacks/src/transports/README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ import { http } from "@secondlayer/stacks";
1111
const transport = http();
1212

1313
// Custom URL
14-
const transport = http({ url: "https://my-node.example.com" });
14+
const transport = http("https://my-node.example.com");
1515

1616
// With options
17-
const transport = http({
18-
url: "https://my-node.example.com",
17+
const transport = http("https://my-node.example.com", {
1918
apiKey: "my-api-key",
2019
timeout: 30_000,
2120
retryCount: 3,
@@ -31,7 +30,7 @@ import { webSocket } from "@secondlayer/stacks";
3130
const transport = webSocket();
3231

3332
// Custom URL
34-
const transport = webSocket({ url: "wss://my-node.example.com" });
33+
const transport = webSocket("wss://my-node.example.com");
3534
```
3635

3736
## Fallback
@@ -42,8 +41,8 @@ Tries transports in order, falls back on failure.
4241
import { fallback, http } from "@secondlayer/stacks";
4342

4443
const transport = fallback([
45-
http({ url: "https://primary-node.com" }),
46-
http({ url: "https://backup-node.com" }),
44+
http("https://primary-node.com"),
45+
http("https://backup-node.com"),
4746
]);
4847
```
4948

0 commit comments

Comments
 (0)