@secondlayer/cli 5.0.1 → 5.1.0

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.0",
32447
32447
  description: "CLI for subgraphs and blockchain indexing on Stacks",
32448
32448
  type: "module",
32449
32449
  bin: {
@@ -35919,6 +35919,152 @@ async function stackStop(options2) {
35919
35919
  success("Stack stopped");
35920
35920
  console.log("");
35921
35921
  }
35922
+ // src/commands/streams.ts
35923
+ init_output();
35924
+ import { createStreamsClient } from "@secondlayer/sdk";
35925
+ var DEFAULT_BASE_URL = "https://api.secondlayer.tools";
35926
+ var VALID_TYPES = [
35927
+ "stx_transfer",
35928
+ "stx_mint",
35929
+ "stx_burn",
35930
+ "stx_lock",
35931
+ "ft_transfer",
35932
+ "ft_mint",
35933
+ "ft_burn",
35934
+ "nft_transfer",
35935
+ "nft_mint",
35936
+ "nft_burn",
35937
+ "print"
35938
+ ];
35939
+ function readApiKey() {
35940
+ const key = process.env.SL_STREAMS_API_KEY;
35941
+ if (!key) {
35942
+ error("SL_STREAMS_API_KEY env var not set. Issue a key at https://www.secondlayer.tools/platform/api-keys (product: Streams).");
35943
+ process.exit(1);
35944
+ }
35945
+ return key;
35946
+ }
35947
+ function client() {
35948
+ return createStreamsClient({
35949
+ baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL,
35950
+ apiKey: readApiKey()
35951
+ });
35952
+ }
35953
+ function parseTypes(value) {
35954
+ if (!value)
35955
+ return;
35956
+ const parts = value.split(",").map((s) => s.trim());
35957
+ for (const p of parts) {
35958
+ if (!VALID_TYPES.includes(p)) {
35959
+ throw new Error(`invalid --types value "${p}"; expected one of: ${VALID_TYPES.join(", ")}`);
35960
+ }
35961
+ }
35962
+ return parts;
35963
+ }
35964
+ function parseLimit(value) {
35965
+ if (value === undefined)
35966
+ return;
35967
+ const n = Number.parseInt(value, 10);
35968
+ if (!Number.isFinite(n) || n < 1 || n > 1000) {
35969
+ throw new Error("--limit must be an integer between 1 and 1000");
35970
+ }
35971
+ return n;
35972
+ }
35973
+ function parseHeight(value, name) {
35974
+ if (value === undefined)
35975
+ return;
35976
+ const n = Number.parseInt(value, 10);
35977
+ if (!Number.isFinite(n) || n < 0) {
35978
+ throw new Error(`${name} must be a non-negative integer`);
35979
+ }
35980
+ return n;
35981
+ }
35982
+ function registerStreamsCommand(program2) {
35983
+ const streams = program2.command("streams").description("Read raw chain events from Streams (requires SL_STREAMS_API_KEY)");
35984
+ streams.command("tip").description("Print current canonical tip").action(async () => {
35985
+ try {
35986
+ const tip = await client().tip();
35987
+ process.stdout.write(`${JSON.stringify(tip, null, 2)}
35988
+ `);
35989
+ } catch (err) {
35990
+ error(err instanceof Error ? err.message : String(err));
35991
+ process.exit(1);
35992
+ }
35993
+ });
35994
+ 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) => {
35995
+ try {
35996
+ const envelope = await client().events.list({
35997
+ types: parseTypes(options2.types),
35998
+ contractId: options2.contractId,
35999
+ cursor: options2.cursor,
36000
+ fromHeight: parseHeight(options2.fromHeight, "--from-height"),
36001
+ toHeight: parseHeight(options2.toHeight, "--to-height"),
36002
+ limit: parseLimit(options2.limit)
36003
+ });
36004
+ process.stdout.write(`${JSON.stringify(envelope, null, 2)}
36005
+ `);
36006
+ } catch (err) {
36007
+ error(err instanceof Error ? err.message : String(err));
36008
+ process.exit(1);
36009
+ }
36010
+ });
36011
+ 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) => {
36012
+ try {
36013
+ const types6 = parseTypes(options2.types);
36014
+ const batchSize = parseLimit(options2.batchSize) ?? 100;
36015
+ const maxPages = options2.maxPages ? Number.parseInt(options2.maxPages, 10) : undefined;
36016
+ info(dim("# streaming events to stdout (jsonl); next_cursor printed to stderr"));
36017
+ await client().events.consume({
36018
+ fromCursor: options2.cursor,
36019
+ types: types6,
36020
+ contractId: options2.contractId,
36021
+ batchSize,
36022
+ mode: "tail",
36023
+ maxPages,
36024
+ onBatch: (events, envelope) => {
36025
+ for (const e of events) {
36026
+ process.stdout.write(`${JSON.stringify(e)}
36027
+ `);
36028
+ }
36029
+ if (envelope.next_cursor) {
36030
+ process.stderr.write(`# next_cursor=${envelope.next_cursor}
36031
+ `);
36032
+ }
36033
+ return envelope.next_cursor;
36034
+ }
36035
+ });
36036
+ } catch (err) {
36037
+ error(err instanceof Error ? err.message : String(err));
36038
+ process.exit(1);
36039
+ }
36040
+ });
36041
+ 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) => {
36042
+ try {
36043
+ const envelope = await client().reorgs.list({
36044
+ since: options2.since,
36045
+ limit: parseLimit(options2.limit)
36046
+ });
36047
+ process.stdout.write(`${JSON.stringify(envelope, null, 2)}
36048
+ `);
36049
+ } catch (err) {
36050
+ error(err instanceof Error ? err.message : String(err));
36051
+ process.exit(1);
36052
+ }
36053
+ });
36054
+ streams.command("canonical <height>").description("Canonical block metadata at a given height").action(async (heightArg) => {
36055
+ try {
36056
+ const height = parseHeight(heightArg, "<height>");
36057
+ if (height === undefined)
36058
+ throw new Error("<height> is required");
36059
+ const block = await client().canonical(height);
36060
+ process.stdout.write(`${JSON.stringify(block, null, 2)}
36061
+ `);
36062
+ } catch (err) {
36063
+ error(err instanceof Error ? err.message : String(err));
36064
+ process.exit(1);
36065
+ }
36066
+ });
36067
+ }
35922
36068
  // src/commands/doctor.ts
35923
36069
  init_config();
35924
36070
 
@@ -37130,6 +37276,7 @@ registerInstanceCommand(program);
37130
37276
  registerSubgraphsCommand(program);
37131
37277
  registerCreateCommand(program);
37132
37278
  registerSubscriptionsCommand(program);
37279
+ registerStreamsCommand(program);
37133
37280
  registerStatusCommand(program);
37134
37281
  registerStackCommand(program);
37135
37282
  registerDbCommand(program);
@@ -37139,5 +37286,5 @@ registerLocalCommand(program);
37139
37286
  registerAccountCommand(program);
37140
37287
  program.parse();
37141
37288
 
37142
- //# debugId=40B4A90A59C890CE64756E2164756E21
37289
+ //# debugId=CEAA7239644824A064756E2164756E21
37143
37290
  //# sourceMappingURL=cli.js.map