@secondlayer/cli 5.0.1 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -32443,7 +32443,7 @@ var {
32443
32443
  // package.json
32444
32444
  var package_default = {
32445
32445
  name: "@secondlayer/cli",
32446
- version: "5.0.1",
32446
+ version: "5.1.1",
32447
32447
  description: "CLI for subgraphs and blockchain indexing on Stacks",
32448
32448
  type: "module",
32449
32449
  bin: {
@@ -34631,18 +34631,42 @@ var SUBGRAPH_TEMPLATE_DESCRIPTIONS = {
34631
34631
  "bns-names": "BNS-V2 name ownership and lifecycle"
34632
34632
  };
34633
34633
  function generateSubgraphTemplate(name, slug = "basic") {
34634
- switch (slug) {
34635
- case "sip-010-balances":
34636
- return sip010Balances(name);
34637
- case "sbtc-flows":
34638
- return sbtcFlows(name);
34639
- case "pox-stacking":
34640
- return poxStacking(name);
34641
- case "bns-names":
34642
- return bnsNames(name);
34643
- default:
34644
- return basic(name);
34645
- }
34634
+ const body = (() => {
34635
+ switch (slug) {
34636
+ case "sip-010-balances":
34637
+ return sip010Balances(name);
34638
+ case "sbtc-flows":
34639
+ return sbtcFlows(name);
34640
+ case "pox-stacking":
34641
+ return poxStacking(name);
34642
+ case "bns-names":
34643
+ return bnsNames(name);
34644
+ default:
34645
+ return basic(name);
34646
+ }
34647
+ })();
34648
+ return `${nextStepsHeader(name)}
34649
+ ${body}`;
34650
+ }
34651
+ function nextStepsHeader(name) {
34652
+ return `// ───────────────────────────────────────────────────────────────────
34653
+ // What to do next
34654
+ //
34655
+ // 1. Edit the source filter + schema below to match what you want to track.
34656
+ // 2. Edit the handler at the bottom — it runs once per matching event.
34657
+ // 3. Deploy: sl subgraphs deploy ${name}.ts
34658
+ // (You'll be prompted to log in if this is your first remote deploy.)
34659
+ // 4. Wait for sync: sl subgraphs status ${name}
34660
+ // Mainnet backfill from genesis can take an hour or more depending on
34661
+ // your filter scope. Use --start-block to skip ahead.
34662
+ // 5. Query: sl subgraphs query ${name} <table-name>
34663
+ // Or hit the auto-generated REST endpoint listed in the deploy output.
34664
+ //
34665
+ // Bind a typed Subscription to any table you write here — see
34666
+ // https://www.secondlayer.tools/docs/subscriptions
34667
+ // ───────────────────────────────────────────────────────────────────
34668
+
34669
+ `;
34646
34670
  }
34647
34671
  function basic(name) {
34648
34672
  return `import { defineSubgraph } from "@secondlayer/subgraphs";
@@ -35919,6 +35943,152 @@ async function stackStop(options2) {
35919
35943
  success("Stack stopped");
35920
35944
  console.log("");
35921
35945
  }
35946
+ // src/commands/streams.ts
35947
+ init_output();
35948
+ import { createStreamsClient } from "@secondlayer/sdk";
35949
+ var DEFAULT_BASE_URL = "https://api.secondlayer.tools";
35950
+ var VALID_TYPES = [
35951
+ "stx_transfer",
35952
+ "stx_mint",
35953
+ "stx_burn",
35954
+ "stx_lock",
35955
+ "ft_transfer",
35956
+ "ft_mint",
35957
+ "ft_burn",
35958
+ "nft_transfer",
35959
+ "nft_mint",
35960
+ "nft_burn",
35961
+ "print"
35962
+ ];
35963
+ function readApiKey() {
35964
+ const key = process.env.SL_STREAMS_API_KEY;
35965
+ if (!key) {
35966
+ error("SL_STREAMS_API_KEY env var not set. Issue a key at https://www.secondlayer.tools/platform/api-keys (product: Streams).");
35967
+ process.exit(1);
35968
+ }
35969
+ return key;
35970
+ }
35971
+ function client() {
35972
+ return createStreamsClient({
35973
+ baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL,
35974
+ apiKey: readApiKey()
35975
+ });
35976
+ }
35977
+ function parseTypes(value) {
35978
+ if (!value)
35979
+ return;
35980
+ const parts = value.split(",").map((s) => s.trim());
35981
+ for (const p of parts) {
35982
+ if (!VALID_TYPES.includes(p)) {
35983
+ throw new Error(`invalid --types value "${p}"; expected one of: ${VALID_TYPES.join(", ")}`);
35984
+ }
35985
+ }
35986
+ return parts;
35987
+ }
35988
+ function parseLimit(value) {
35989
+ if (value === undefined)
35990
+ return;
35991
+ const n = Number.parseInt(value, 10);
35992
+ if (!Number.isFinite(n) || n < 1 || n > 1000) {
35993
+ throw new Error("--limit must be an integer between 1 and 1000");
35994
+ }
35995
+ return n;
35996
+ }
35997
+ function parseHeight(value, name) {
35998
+ if (value === undefined)
35999
+ return;
36000
+ const n = Number.parseInt(value, 10);
36001
+ if (!Number.isFinite(n) || n < 0) {
36002
+ throw new Error(`${name} must be a non-negative integer`);
36003
+ }
36004
+ return n;
36005
+ }
36006
+ function registerStreamsCommand(program2) {
36007
+ const streams = program2.command("streams").description("Read raw chain events from Streams (requires SL_STREAMS_API_KEY)");
36008
+ streams.command("tip").description("Print current canonical tip").action(async () => {
36009
+ try {
36010
+ const tip = await client().tip();
36011
+ process.stdout.write(`${JSON.stringify(tip, null, 2)}
36012
+ `);
36013
+ } catch (err) {
36014
+ error(err instanceof Error ? err.message : String(err));
36015
+ process.exit(1);
36016
+ }
36017
+ });
36018
+ streams.command("events").description("List events (cursor-paginated; one page per call)").option("--types <types>", `comma-separated event types (${VALID_TYPES.join(", ")})`).option("--contract-id <id>", "filter to a single contract identifier").option("--cursor <cursor>", "start cursor (block_height:event_index)").option("--from-height <n>", "filter to blocks >= n").option("--to-height <n>", "filter to blocks <= n").option("--limit <n>", "page size (1-1000, default 100)", "100").action(async (options2) => {
36019
+ try {
36020
+ const envelope = await client().events.list({
36021
+ types: parseTypes(options2.types),
36022
+ contractId: options2.contractId,
36023
+ cursor: options2.cursor,
36024
+ fromHeight: parseHeight(options2.fromHeight, "--from-height"),
36025
+ toHeight: parseHeight(options2.toHeight, "--to-height"),
36026
+ limit: parseLimit(options2.limit)
36027
+ });
36028
+ process.stdout.write(`${JSON.stringify(envelope, null, 2)}
36029
+ `);
36030
+ } catch (err) {
36031
+ error(err instanceof Error ? err.message : String(err));
36032
+ process.exit(1);
36033
+ }
36034
+ });
36035
+ streams.command("consume").description("Long-running pull from a cursor; emits one event per line (jsonl) until SIGINT or --max-pages").option("--types <types>", `comma-separated event types (${VALID_TYPES.join(", ")})`).option("--contract-id <id>", "filter to a single contract identifier").option("--cursor <cursor>", "start cursor (block_height:event_index)").option("--batch-size <n>", "events per batch (1-1000, default 100)", "100").option("--max-pages <n>", "stop after N pages (default: run until SIGINT)").action(async (options2) => {
36036
+ try {
36037
+ const types6 = parseTypes(options2.types);
36038
+ const batchSize = parseLimit(options2.batchSize) ?? 100;
36039
+ const maxPages = options2.maxPages ? Number.parseInt(options2.maxPages, 10) : undefined;
36040
+ info(dim("# streaming events to stdout (jsonl); next_cursor printed to stderr"));
36041
+ await client().events.consume({
36042
+ fromCursor: options2.cursor,
36043
+ types: types6,
36044
+ contractId: options2.contractId,
36045
+ batchSize,
36046
+ mode: "tail",
36047
+ maxPages,
36048
+ onBatch: (events, envelope) => {
36049
+ for (const e of events) {
36050
+ process.stdout.write(`${JSON.stringify(e)}
36051
+ `);
36052
+ }
36053
+ if (envelope.next_cursor) {
36054
+ process.stderr.write(`# next_cursor=${envelope.next_cursor}
36055
+ `);
36056
+ }
36057
+ return envelope.next_cursor;
36058
+ }
36059
+ });
36060
+ } catch (err) {
36061
+ error(err instanceof Error ? err.message : String(err));
36062
+ process.exit(1);
36063
+ }
36064
+ });
36065
+ streams.command("reorgs").description("List recent reorgs (cursor-paginated)").requiredOption("--since <cursor>", "start cursor (block_height:event_index)").option("--limit <n>", "page size (default 100)", "100").action(async (options2) => {
36066
+ try {
36067
+ const envelope = await client().reorgs.list({
36068
+ since: options2.since,
36069
+ limit: parseLimit(options2.limit)
36070
+ });
36071
+ process.stdout.write(`${JSON.stringify(envelope, null, 2)}
36072
+ `);
36073
+ } catch (err) {
36074
+ error(err instanceof Error ? err.message : String(err));
36075
+ process.exit(1);
36076
+ }
36077
+ });
36078
+ streams.command("canonical <height>").description("Canonical block metadata at a given height").action(async (heightArg) => {
36079
+ try {
36080
+ const height = parseHeight(heightArg, "<height>");
36081
+ if (height === undefined)
36082
+ throw new Error("<height> is required");
36083
+ const block = await client().canonical(height);
36084
+ process.stdout.write(`${JSON.stringify(block, null, 2)}
36085
+ `);
36086
+ } catch (err) {
36087
+ error(err instanceof Error ? err.message : String(err));
36088
+ process.exit(1);
36089
+ }
36090
+ });
36091
+ }
35922
36092
  // src/commands/doctor.ts
35923
36093
  init_config();
35924
36094
 
@@ -37130,6 +37300,7 @@ registerInstanceCommand(program);
37130
37300
  registerSubgraphsCommand(program);
37131
37301
  registerCreateCommand(program);
37132
37302
  registerSubscriptionsCommand(program);
37303
+ registerStreamsCommand(program);
37133
37304
  registerStatusCommand(program);
37134
37305
  registerStackCommand(program);
37135
37306
  registerDbCommand(program);
@@ -37139,5 +37310,5 @@ registerLocalCommand(program);
37139
37310
  registerAccountCommand(program);
37140
37311
  program.parse();
37141
37312
 
37142
- //# debugId=40B4A90A59C890CE64756E2164756E21
37313
+ //# debugId=7C4F9780AD65C38D64756E2164756E21
37143
37314
  //# sourceMappingURL=cli.js.map