@secondlayer/cli 19.2.2 → 19.4.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
@@ -2550,6 +2550,118 @@ var init_output = __esm(() => {
2550
2550
  ANSI_ESCAPE_PATTERN = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
2551
2551
  });
2552
2552
 
2553
+ // src/lib/api-client.ts
2554
+ import { ApiError, SecondLayer } from "@secondlayer/sdk";
2555
+ function nextStepHint(status) {
2556
+ if (status === undefined)
2557
+ return;
2558
+ if (status === 403)
2559
+ return "You may not have access — check your active project with `secondlayer whoami`.";
2560
+ if (status === 404)
2561
+ return "Check the name/slug — run the matching `list` command to see what exists.";
2562
+ if (status === 400 || status === 422)
2563
+ return "Check the command arguments and flags — see `--help` for the expected format.";
2564
+ if (status === 429)
2565
+ return "Rate limited — wait a moment and retry.";
2566
+ if (status >= 500)
2567
+ return "Server error — retry shortly, or check `secondlayer status`.";
2568
+ return;
2569
+ }
2570
+ function handleApiError(err, action) {
2571
+ const status = err instanceof ApiError || err instanceof CliHttpError ? err.status : undefined;
2572
+ if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED" || status === 401) {
2573
+ printError("Authentication required.", {
2574
+ hint: isOssMode() ? "Set INSTANCE_TOKEN from `secondlayer init`." : "Run `secondlayer login` to re-authenticate."
2575
+ });
2576
+ process.exit(1);
2577
+ }
2578
+ const detail = err instanceof Error ? err.message : String(err);
2579
+ printError(`Failed to ${action}: ${detail}`, { hint: nextStepHint(status) });
2580
+ process.exit(1);
2581
+ }
2582
+ function withErrorHandling(fn, options) {
2583
+ return async (...args) => {
2584
+ try {
2585
+ await fn(...args);
2586
+ } catch (err) {
2587
+ if (options?.onError) {
2588
+ options.onError(err);
2589
+ } else {
2590
+ handleApiError(err, options?.action ?? "execute command");
2591
+ }
2592
+ }
2593
+ };
2594
+ }
2595
+ async function getPlatformClient() {
2596
+ const { apiUrl, ephemeralKey } = await resolveHostedAuth();
2597
+ return new SecondLayer({ baseUrl: apiUrl, apiKey: ephemeralKey });
2598
+ }
2599
+ async function listSubgraphsApi() {
2600
+ return (await getPlatformClient()).subgraphs.list();
2601
+ }
2602
+ async function getSubgraphApi(name) {
2603
+ return (await getPlatformClient()).subgraphs.status(name);
2604
+ }
2605
+ async function getSubgraphOpenApi(name, options) {
2606
+ return (await getPlatformClient()).subgraphs.openapi(name, options);
2607
+ }
2608
+ async function getSubgraphAgentSchema(name, options) {
2609
+ return (await getPlatformClient()).subgraphs.schema(name, options);
2610
+ }
2611
+ async function getSubgraphMarkdown(name, options) {
2612
+ return (await getPlatformClient()).subgraphs.markdown(name, options);
2613
+ }
2614
+ async function reindexSubgraphApi(name) {
2615
+ return (await getPlatformClient()).subgraphs.reindex(name);
2616
+ }
2617
+ async function backfillSubgraphApi(name, options) {
2618
+ return (await getPlatformClient()).subgraphs.backfill(name, options);
2619
+ }
2620
+ async function stopSubgraphApi(name) {
2621
+ return (await getPlatformClient()).subgraphs.stop(name);
2622
+ }
2623
+ async function deleteSubgraphApi(name, options) {
2624
+ return (await getPlatformClient()).subgraphs.delete(name, options);
2625
+ }
2626
+ async function deploySubgraphApi(data) {
2627
+ return (await getPlatformClient()).subgraphs.deploy(data);
2628
+ }
2629
+ async function querySubgraphTableRows(name, table, params = {}) {
2630
+ return (await getPlatformClient()).subgraphs.rows(name, table, params);
2631
+ }
2632
+ async function querySubgraphTableCount(name, table, params = {}) {
2633
+ return (await getPlatformClient()).subgraphs.count(name, table, params);
2634
+ }
2635
+ async function getSubgraphGaps(name, opts) {
2636
+ return (await getPlatformClient()).subgraphs.gaps(name, opts);
2637
+ }
2638
+ async function listSubgraphOperationsApi(name) {
2639
+ return (await getPlatformClient()).subgraphs.operations(name);
2640
+ }
2641
+ async function getSubgraphOperationApi(name, operationId) {
2642
+ return (await getPlatformClient()).subgraphs.getOperation(name, operationId);
2643
+ }
2644
+ async function getSubgraphSourceApi(name) {
2645
+ return (await getPlatformClient()).subgraphs.getSource(name);
2646
+ }
2647
+ async function getSubgraphRowsApi(name, table, opts = {}) {
2648
+ return (await getPlatformClient()).subgraphs.rows(name, table, opts);
2649
+ }
2650
+ async function getContractPrintSchema(contractId) {
2651
+ let client;
2652
+ try {
2653
+ client = await getPlatformClient();
2654
+ } catch {
2655
+ client = new SecondLayer({ baseUrl: resolveApiUrl() });
2656
+ }
2657
+ return client.index.printSchema(contractId);
2658
+ }
2659
+ var init_api_client = __esm(() => {
2660
+ init_http();
2661
+ init_output();
2662
+ init_resolve_auth();
2663
+ });
2664
+
2553
2665
  // ../../node_modules/fast-glob/out/utils/array.js
2554
2666
  var require_array = __commonJS(function(exports) {
2555
2667
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -16630,7 +16742,7 @@ var init_dist3 = __esm(() => {
16630
16742
  // ../../node_modules/tinyexec/dist/main.js
16631
16743
  import { createRequire as e } from "module";
16632
16744
  import { spawn as t } from "node:child_process";
16633
- import { delimiter as n2, dirname as r, normalize as i, resolve as a2 } from "node:path";
16745
+ import { delimiter as n3, dirname as r, normalize as i, resolve as a2 } from "node:path";
16634
16746
  import { cwd as o } from "node:process";
16635
16747
  import { PassThrough as s } from "node:stream";
16636
16748
  import c from "node:readline";
@@ -16649,7 +16761,7 @@ function x(e) {
16649
16761
  return b;
16650
16762
  }
16651
16763
  function S(e, t) {
16652
- const i = t.value.split(n2);
16764
+ const i = t.value.split(n3);
16653
16765
  let o = e;
16654
16766
  let s;
16655
16767
  do {
@@ -16659,7 +16771,7 @@ function S(e, t) {
16659
16771
  } while (o !== s);
16660
16772
  return {
16661
16773
  key: t.key,
16662
- value: i.join(n2)
16774
+ value: i.join(n3)
16663
16775
  };
16664
16776
  }
16665
16777
  function C(e, t) {
@@ -23945,19 +24057,19 @@ class c2 {
23945
24057
  }
23946
24058
  }
23947
24059
  function i2() {
23948
- return this[n3].next();
24060
+ return this[n4].next();
23949
24061
  }
23950
24062
  function o2(r) {
23951
- return this[n3].return(r);
24063
+ return this[n4].return(r);
23952
24064
  }
23953
24065
  function h2({ preventCancel: r = false } = {}) {
23954
24066
  const e = this.getReader(), t = new c2(e, r), s = Object.create(u2);
23955
- return s[n3] = t, s;
24067
+ return s[n4] = t, s;
23956
24068
  }
23957
- var a3, n3, u2;
24069
+ var a3, n4, u2;
23958
24070
  var init_asyncIterator = __esm(() => {
23959
24071
  a3 = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {}).prototype);
23960
- n3 = Symbol();
24072
+ n4 = Symbol();
23961
24073
  Object.defineProperty(i2, "name", { value: "next" });
23962
24074
  Object.defineProperty(o2, "name", { value: "return" });
23963
24075
  u2 = Object.create(a3, {
@@ -28890,115 +29002,6 @@ var init_subgraphs = __esm(() => {
28890
29002
  init_format();
28891
29003
  });
28892
29004
 
28893
- // src/lib/api-client.ts
28894
- import { ApiError, SecondLayer as SecondLayer2 } from "@secondlayer/sdk";
28895
- function nextStepHint(status) {
28896
- if (status === undefined)
28897
- return;
28898
- if (status === 403)
28899
- return "You may not have access — check your active project with `secondlayer whoami`.";
28900
- if (status === 404)
28901
- return "Check the name/slug — run the matching `list` command to see what exists.";
28902
- if (status === 400 || status === 422)
28903
- return "Check the command arguments and flags — see `--help` for the expected format.";
28904
- if (status === 429)
28905
- return "Rate limited — wait a moment and retry.";
28906
- if (status >= 500)
28907
- return "Server error — retry shortly, or check `secondlayer status`.";
28908
- return;
28909
- }
28910
- function handleApiError(err, action) {
28911
- const status = err instanceof ApiError || err instanceof CliHttpError ? err.status : undefined;
28912
- if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED" || status === 401) {
28913
- printError("Authentication required.", {
28914
- hint: isOssMode() ? "Set INSTANCE_TOKEN from `secondlayer init`." : "Run `secondlayer login` to re-authenticate."
28915
- });
28916
- process.exit(1);
28917
- }
28918
- const detail = err instanceof Error ? err.message : String(err);
28919
- printError(`Failed to ${action}: ${detail}`, { hint: nextStepHint(status) });
28920
- process.exit(1);
28921
- }
28922
- function withErrorHandling(fn, options) {
28923
- return async (...args) => {
28924
- try {
28925
- await fn(...args);
28926
- } catch (err) {
28927
- if (options?.onError) {
28928
- options.onError(err);
28929
- } else {
28930
- handleApiError(err, options?.action ?? "execute command");
28931
- }
28932
- }
28933
- };
28934
- }
28935
- async function getPlatformClient() {
28936
- const { apiUrl, ephemeralKey } = await resolveHostedAuth();
28937
- return new SecondLayer2({ baseUrl: apiUrl, apiKey: ephemeralKey });
28938
- }
28939
- async function listSubgraphsApi() {
28940
- return (await getPlatformClient()).subgraphs.list();
28941
- }
28942
- async function getSubgraphApi(name) {
28943
- return (await getPlatformClient()).subgraphs.status(name);
28944
- }
28945
- async function getSubgraphOpenApi(name, options) {
28946
- return (await getPlatformClient()).subgraphs.openapi(name, options);
28947
- }
28948
- async function getSubgraphAgentSchema(name, options) {
28949
- return (await getPlatformClient()).subgraphs.schema(name, options);
28950
- }
28951
- async function getSubgraphMarkdown(name, options) {
28952
- return (await getPlatformClient()).subgraphs.markdown(name, options);
28953
- }
28954
- async function reindexSubgraphApi(name) {
28955
- return (await getPlatformClient()).subgraphs.reindex(name);
28956
- }
28957
- async function backfillSubgraphApi(name, options) {
28958
- return (await getPlatformClient()).subgraphs.backfill(name, options);
28959
- }
28960
- async function stopSubgraphApi(name) {
28961
- return (await getPlatformClient()).subgraphs.stop(name);
28962
- }
28963
- async function deleteSubgraphApi(name, options) {
28964
- return (await getPlatformClient()).subgraphs.delete(name, options);
28965
- }
28966
- async function deploySubgraphApi(data) {
28967
- return (await getPlatformClient()).subgraphs.deploy(data);
28968
- }
28969
- async function querySubgraphTableRows(name, table, params = {}) {
28970
- return (await getPlatformClient()).subgraphs.rows(name, table, params);
28971
- }
28972
- async function querySubgraphTableCount(name, table, params = {}) {
28973
- return (await getPlatformClient()).subgraphs.count(name, table, params);
28974
- }
28975
- async function getSubgraphGaps(name, opts) {
28976
- return (await getPlatformClient()).subgraphs.gaps(name, opts);
28977
- }
28978
- async function listSubgraphOperationsApi(name) {
28979
- return (await getPlatformClient()).subgraphs.operations(name);
28980
- }
28981
- async function getSubgraphOperationApi(name, operationId) {
28982
- return (await getPlatformClient()).subgraphs.getOperation(name, operationId);
28983
- }
28984
- async function getSubgraphSourceApi(name) {
28985
- return (await getPlatformClient()).subgraphs.getSource(name);
28986
- }
28987
- async function getContractPrintSchema(contractId) {
28988
- let client;
28989
- try {
28990
- client = await getPlatformClient();
28991
- } catch {
28992
- client = new SecondLayer2({ baseUrl: resolveApiUrl() });
28993
- }
28994
- return client.index.printSchema(contractId);
28995
- }
28996
- var init_api_client = __esm(() => {
28997
- init_http();
28998
- init_output();
28999
- init_resolve_auth();
29000
- });
29001
-
29002
29005
  // src/lib/derive-abi.ts
29003
29006
  import {
29004
29007
  extractSubgraphDefinition,
@@ -29440,7 +29443,7 @@ var init_git_status = () => {};
29440
29443
 
29441
29444
  // ../../node_modules/typescript/lib/typescript.js
29442
29445
  var require_typescript = __commonJS(function(exports, module) {
29443
- var __dirname = "/Users/ryan/projects/secondlayer/.claude/worktrees/agent-a6ba56a9f98cf6ff7/node_modules/typescript/lib", __filename = "/Users/ryan/projects/secondlayer/.claude/worktrees/agent-a6ba56a9f98cf6ff7/node_modules/typescript/lib/typescript.js";
29446
+ var __dirname = "/Users/ryan/projects/secondlayer/.claude/worktrees/agent-a9a35af4d4343442c/node_modules/typescript/lib", __filename = "/Users/ryan/projects/secondlayer/.claude/worktrees/agent-a9a35af4d4343442c/node_modules/typescript/lib/typescript.js";
29444
29447
  /*! *****************************************************************************
29445
29448
  Copyright (c) Microsoft Corporation. All rights reserved.
29446
29449
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use
@@ -198790,7 +198793,7 @@ import {
198790
198793
  watch,
198791
198794
  writeFileSync as writeFileSync3
198792
198795
  } from "node:fs";
198793
- import { basename, dirname as dirname5, extname, join as join7, resolve as resolve5 } from "node:path";
198796
+ import { basename, dirname as dirname5, extname, join as join7, relative, resolve as resolve5 } from "node:path";
198794
198797
  import { fileURLToPath as fileURLToPath3 } from "node:url";
198795
198798
  import { confirm as confirm2 } from "@inquirer/prompts";
198796
198799
  import {
@@ -198802,6 +198805,10 @@ import {
198802
198805
  billingPausedCode
198803
198806
  } from "@secondlayer/shared/schemas";
198804
198807
  import { TRAIT_STANDARDS } from "@secondlayer/stacks/clarity";
198808
+ import {
198809
+ deriveVerification as deriveVerification2,
198810
+ isDeterminismViolation
198811
+ } from "@secondlayer/subgraphs/verification";
198805
198812
  function webhookHint(apiUrl, name, firstTable) {
198806
198813
  if (!firstTable || isMerchantUrl(apiUrl))
198807
198814
  return null;
@@ -199121,6 +199128,36 @@ function createSubgraphDeployPreview(def, options = {}) {
199121
199128
  ...options.bundleBytes !== undefined ? { bundleSize: `${options.bundleBytes} bytes` } : {}
199122
199129
  };
199123
199130
  }
199131
+ function formatVerificationLines(verification, pin) {
199132
+ if (!verification)
199133
+ return [];
199134
+ const head = [
199135
+ verification.level,
199136
+ ...pin ? [`pin ${pin.slice(0, 4)}…${pin.slice(-4)}`] : [],
199137
+ ...verification.reasons
199138
+ ].join(" · ");
199139
+ return [
199140
+ `verification ${head}`,
199141
+ ...verification.unproven.map((u) => `unproven ${u}`)
199142
+ ];
199143
+ }
199144
+ function formatVerificationStatus(verification) {
199145
+ if (!verification)
199146
+ return "unknown (deployed before levels were derived)";
199147
+ const head = [verification.level, ...verification.reasons].join(" · ");
199148
+ return verification.unproven.length > 0 ? `${head} (unproven: ${verification.unproven.join("; ")})` : head;
199149
+ }
199150
+ function checkDeterminism(def, findings) {
199151
+ const verification = deriveVerification2(def, findings);
199152
+ if (isDeterminismViolation(verification)) {
199153
+ error("Nondeterministic handler. This subgraph's sources are provable, so its handlers must give the same rows on every run:");
199154
+ for (const r of verification.reasons)
199155
+ error(` ✗ ${r}`);
199156
+ info("Derive values from event, ctx.block and ctx.tx only (no Date, Math.random, fetch, timers or locale formatting).");
199157
+ process.exit(1);
199158
+ }
199159
+ return verification;
199160
+ }
199124
199161
  function printSubgraphDeployPreview(preview, context) {
199125
199162
  success("Subgraph deploy dry run passed");
199126
199163
  const pairs = [
@@ -199493,8 +199530,11 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
199493
199530
  info(`${dryRun ? "Bundling for remote deploy dry run" : "Bundling for remote deploy"} (${config.network})...`);
199494
199531
  const source = derived?.source ?? await readFile(absPath, "utf8");
199495
199532
  const { bundleSubgraphCode } = await import("@secondlayer/bundler");
199496
- const bundled = await bundleSubgraphCode(source);
199533
+ const bundled = await bundleSubgraphCode(source, {
199534
+ fileName: relative(process.cwd(), absPath)
199535
+ });
199497
199536
  const handlerCode = bundled.handlerCode;
199537
+ const localVerification = checkDeterminism(effectiveDef, bundled.findings);
199498
199538
  if (dryRun) {
199499
199539
  printSubgraphDeployPreview(createSubgraphDeployPreview(validated, {
199500
199540
  bundleBytes: Buffer.byteLength(handlerCode, "utf8")
@@ -199503,6 +199543,9 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
199503
199543
  file: absPath,
199504
199544
  bundled: true
199505
199545
  });
199546
+ for (const line of formatVerificationLines(localVerification)) {
199547
+ info(` ${line}`);
199548
+ }
199506
199549
  return;
199507
199550
  }
199508
199551
  const deployStartBlock = startBlock ?? effectiveDef.startBlock;
@@ -199544,6 +199587,11 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
199544
199587
  });
199545
199588
  for (const w of result.warnings ?? [])
199546
199589
  warn(w);
199590
+ const printVerification = () => {
199591
+ for (const line of formatVerificationLines(result.verification ?? localVerification, result.pin)) {
199592
+ info(` ${line}`);
199593
+ }
199594
+ };
199547
199595
  const printDeployFooter = async () => {
199548
199596
  try {
199549
199597
  const { apiUrl } = await resolveAuth();
@@ -199563,10 +199611,13 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
199563
199611
  };
199564
199612
  if (result.action === "unchanged") {
199565
199613
  info(`Subgraph "${effectiveDef.name}" is up to date (v${result.version} — no changes)`);
199614
+ printVerification();
199566
199615
  } else if (result.action === "handler_updated") {
199567
199616
  success(`Subgraph "${effectiveDef.name}" handler updated (v${result.version} — schema unchanged, no reindex needed)`);
199617
+ printVerification();
199568
199618
  } else if (result.action === "created") {
199569
199619
  success(`Subgraph "${effectiveDef.name}" created → v${result.version}`);
199620
+ printVerification();
199570
199621
  await printDeployFooter();
199571
199622
  } else if (result.action === "reindexed") {
199572
199623
  if (result.diff) {
@@ -199583,6 +199634,7 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
199583
199634
  }
199584
199635
  }
199585
199636
  success(`Subgraph "${effectiveDef.name}" updated → v${result.version} (reindexing)`);
199637
+ printVerification();
199586
199638
  await printDeployFooter();
199587
199639
  } else {
199588
199640
  if (result.diff) {
@@ -199594,22 +199646,37 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
199594
199646
  }
199595
199647
  }
199596
199648
  success(`Subgraph "${effectiveDef.name}" updated → v${result.version}`);
199649
+ printVerification();
199597
199650
  await printDeployFooter();
199598
199651
  }
199599
199652
  } else {
199653
+ let findings;
199654
+ try {
199655
+ const { bundleSubgraphCode } = await import("@secondlayer/bundler");
199656
+ findings = (await bundleSubgraphCode(await readFile(absPath, "utf8"), {
199657
+ fileName: relative(process.cwd(), absPath)
199658
+ })).findings;
199659
+ } catch {
199660
+ findings = undefined;
199661
+ }
199662
+ const verification = findings ? checkDeterminism(effectiveDef, findings) : undefined;
199600
199663
  if (dryRun) {
199601
199664
  printSubgraphDeployPreview(createSubgraphDeployPreview(validated), {
199602
199665
  network: config.network,
199603
199666
  file: absPath,
199604
199667
  bundled: false
199605
199668
  });
199669
+ for (const line of formatVerificationLines(verification)) {
199670
+ info(` ${line}`);
199671
+ }
199606
199672
  return;
199607
199673
  }
199608
199674
  const { deploySchema } = await import("@secondlayer/subgraphs");
199609
199675
  const { getDb, closeDb } = await import("@secondlayer/shared/db");
199610
199676
  const db = getDb();
199611
199677
  const result = await deploySchema(db, effectiveDef, absPath, {
199612
- forceReindex: startBlock !== undefined
199678
+ forceReindex: startBlock !== undefined,
199679
+ verification
199613
199680
  });
199614
199681
  if (result.action === "unchanged") {
199615
199682
  info(`Subgraph "${effectiveDef.name}" is up to date (v${result.version} — no changes)`);
@@ -199622,6 +199689,9 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
199622
199689
  } else {
199623
199690
  success(`Subgraph "${effectiveDef.name}" updated → v${result.version}`);
199624
199691
  }
199692
+ for (const line of formatVerificationLines(verification)) {
199693
+ info(` ${line}`);
199694
+ }
199625
199695
  await closeDb();
199626
199696
  }
199627
199697
  } catch (err) {
@@ -199675,6 +199745,8 @@ ${data.length} subgraph(s) total`));
199675
199745
  console.log(formatKeyValue([
199676
199746
  ["Name", subgraph.name],
199677
199747
  ["Version", subgraph.version],
199748
+ ["Pin", subgraph.pin ?? "none (deployed before pins)"],
199749
+ ["Verification", formatVerificationStatus(subgraph.verification)],
199678
199750
  [
199679
199751
  "Status",
199680
199752
  formatSubgraphStatus(subgraph.status, subgraph.health.lastError)
@@ -202526,7 +202598,7 @@ var {
202526
202598
  // package.json
202527
202599
  var package_default = {
202528
202600
  name: "@secondlayer/cli",
202529
- version: "19.2.2",
202601
+ version: "19.4.0",
202530
202602
  description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
202531
202603
  repository: {
202532
202604
  type: "git",
@@ -202563,13 +202635,13 @@ var package_default = {
202563
202635
  "@biomejs/wasm-nodejs": "^1.9.0",
202564
202636
  "@dsnp/parquetjs": "~1.8.8",
202565
202637
  "@inquirer/prompts": "^8.2.0",
202566
- "@secondlayer/bundler": "^0.6.1",
202638
+ "@secondlayer/bundler": "^0.7.0",
202567
202639
  "@secondlayer/scaffold": "^1.6.1",
202568
- "@secondlayer/sdk": "^14.3.0",
202569
- "@secondlayer/shared": "^11.20.0",
202570
- "@secondlayer/stacks": "^6.1.1",
202571
- "@secondlayer/subgraphs": "^6.3.6",
202572
- "@secondlayer/verify": "^0.2.0",
202640
+ "@secondlayer/sdk": "^14.5.0",
202641
+ "@secondlayer/shared": "^11.23.0",
202642
+ "@secondlayer/stacks": "^6.2.0",
202643
+ "@secondlayer/subgraphs": "^6.5.0",
202644
+ "@secondlayer/verify": "^0.3.0",
202573
202645
  esbuild: "^0.28.2",
202574
202646
  "smol-toml": "^1.8.0",
202575
202647
  zod: "^4.3.6"
@@ -202596,7 +202668,7 @@ var package_default = {
202596
202668
 
202597
202669
  // src/commands/archive.ts
202598
202670
  import {
202599
- SecondLayer,
202671
+ SecondLayer as SecondLayer2,
202600
202672
  resolveAccountKey as resolveAccountKey3
202601
202673
  } from "@secondlayer/sdk";
202602
202674
 
@@ -204021,6 +204093,7 @@ var LINKS = [
204021
204093
  { step: "burn", label: "burn" },
204022
204094
  { step: "signer-set", label: "cycle" },
204023
204095
  { step: "signatures", label: "signatures" },
204096
+ { step: "txs", label: "txs" },
204024
204097
  { step: "witness", label: "state root" },
204025
204098
  { step: "names", label: "diff" },
204026
204099
  { step: "rows", label: "rows" }
@@ -204078,7 +204151,7 @@ function prepareSource(src) {
204078
204151
  };
204079
204152
  return out;
204080
204153
  }
204081
- function linkDetail(step, r, cp, rows) {
204154
+ function linkDetail(step, r, cp) {
204082
204155
  switch (step) {
204083
204156
  case "ancestry": {
204084
204157
  const a = r.ancestry;
@@ -204098,6 +204171,8 @@ function linkDetail(step, r, cp, rows) {
204098
204171
  return r.cycle === cp.stacks.cycle ? `${r.cycle}, the checkpoint's own signer set` : `${r.cycle}, signer set proven forward from checkpoint cycle ${cp.stacks.cycle}`;
204099
204172
  case "signatures":
204100
204173
  return `${n(r.signerWeight ?? 0n)} / ${n(r.totalWeight ?? 0n)} weight signed, threshold ${n(r.threshold ?? 0n)}`;
204174
+ case "txs":
204175
+ return `${n(r.transactions?.length ?? 0)} transactions match the tx merkle root`;
204101
204176
  case "witness":
204102
204177
  return `${r.stateRoot} matches the witness`;
204103
204178
  case "names": {
@@ -204105,7 +204180,7 @@ function linkDetail(step, r, cp, rows) {
204105
204180
  if (!d)
204106
204181
  return "";
204107
204182
  const named = d.writes.filter((w) => w.named).length;
204108
- const written = named ? `${d.writes.length} written (${named} named, ${d.writes.length - named} unnamed)` : `${d.writes.length} written (unnamed${rows ? "" : "; --rows names them"})`;
204183
+ const written = named ? `${d.writes.length} written (${named} named, ${d.writes.length - named} unnamed)` : `${d.writes.length} written (unnamed)`;
204109
204184
  return `${written}, ${d.carried.length} carried, ${d.internal.length} internal`;
204110
204185
  }
204111
204186
  case "rows":
@@ -204137,12 +204212,13 @@ function report(r, cp, rows) {
204137
204212
  writeData(dim(`· ${label} not needed: the block is hash-chained to the checkpoint`));
204138
204213
  else if (link.step === "rows" && r.rowsChecked === undefined)
204139
204214
  writeData(dim(`· ${label} not checked: the source serves no indexed rows`));
204215
+ else if (link.step === "txs" && r.transactions === undefined)
204216
+ writeData(dim(`· ${label} not checked: no transaction bytes (epoch 2.x, or the source served the header only)`));
204140
204217
  else
204141
- writeData(`${green("✓")} ${label} ${linkDetail(link.step, r, cp, rows)}`);
204218
+ writeData(`${green("✓")} ${label} ${linkDetail(link.step, r, cp)}`);
204142
204219
  }
204143
204220
  for (const line of r.notes)
204144
- if (rows || !line.includes("state_writes"))
204145
- note(` note: ${line}`);
204221
+ note(` note: ${line}`);
204146
204222
  if (!first) {
204147
204223
  const from = n(parseNakamotoHeader(unhex(cp.stacks.header)).chainLength);
204148
204224
  writeData(green(`✓ Block ${n(r.height ?? 0)} is proven. Trusted: only the checkpoint (Stacks ${from}, Bitcoin ${n(cp.bitcoin.height)}).`));
@@ -204152,7 +204228,8 @@ function report(r, cp, rows) {
204152
204228
  writeData(red(first.code === "unavailable" ? `✗ Could not check the ${label} link: the source could not serve it.` : `✗ Not proven: the ${label} link is broken.`));
204153
204229
  }
204154
204230
  function verificationJson(r) {
204155
- return JSON.stringify(r, (_k, v) => typeof v === "bigint" ? v.toString() : v, 2);
204231
+ const { transactions, ...rest } = r;
204232
+ return JSON.stringify(transactions ? { ...rest, transactions: transactions.map((t) => t.txid) } : rest, (_k, v) => typeof v === "bigint" ? v.toString() : v, 2);
204156
204233
  }
204157
204234
  function exitCodeOf(r) {
204158
204235
  if (r.ok)
@@ -204181,7 +204258,7 @@ async function runVerifyBlock(ref, opts, deps = {}) {
204181
204258
  return exitCodeOf(result);
204182
204259
  }
204183
204260
  function attachVerifyBlockCommand(verify) {
204184
- return verify.command("block").description("Prove one Stacks block from the checkpoint built into this release, trusting nothing else").argument("<ref>", "block height or index block hash").option("--node <url>", "read blocks and MARF proofs from this Stacks node RPC instead of the API").option("--checkpoint <file>", "trust this checkpoint JSON instead of the one built into this release").option("--rows", "also prove the indexer's rows for the block (state_writes, vm_events) against its state diff").addHelpText("after", `
204261
+ return verify.command("block").description("Prove one Stacks block from the checkpoint built into this release, trusting nothing else").argument("<ref>", "block height or index block hash").option("--node <url>", "read blocks and MARF proofs from this Stacks node RPC instead of the API").option("--checkpoint <file>", "trust this checkpoint JSON instead of the one built into this release").option("--rows", "also prove the Index API's vm_events rows for the block against its state diff (billed as Index rows)").addHelpText("after", `
204185
204262
  What is proven, link by link:
204186
204263
  ancestry below the checkpoint only: the block's id, from the checkpoint by
204187
204264
  parent links or one MARF proof (signer links are then not needed)
@@ -204189,9 +204266,13 @@ What is proven, link by link:
204189
204266
  burn the block's consensus hash commits to that Bitcoin block
204190
204267
  cycle the reward cycle's signer set, proven forward from the checkpoint's set
204191
204268
  signatures signers holding at least 70% of the weight signed the block header
204269
+ txs the block's transactions hash to the tx merkle root in its header
204192
204270
  state root the state witness hashes to the root in the signed header
204193
- diff every leaf the block wrote, carried, or kept as bookkeeping
204194
- rows with --rows: the Index API's rows match that diff
204271
+ diff every leaf the block wrote, carried, or kept as bookkeeping; writes
204272
+ are named from the block's state_writes (free, /v1/proofs/writes)
204273
+ when the source has them, else listed as unnamed with a note
204274
+ rows with --rows: the Index API's vm_events rows match that diff
204275
+ (billed as Index rows; everything else is free)
204195
204276
 
204196
204277
  Nothing is trusted except the checkpoint. Proofs come from the API
204197
204278
  (SECONDLAYER_API_URL, or --api-url) with your account key, or from a node
@@ -204215,13 +204296,242 @@ Exit codes:
204215
204296
  });
204216
204297
  }
204217
204298
 
204299
+ // src/commands/verify-subgraph.ts
204300
+ init_api_client();
204301
+ init_output();
204302
+ import { deriveVerification } from "@secondlayer/subgraphs/verification";
204303
+ import {
204304
+ checkPin,
204305
+ compareRows,
204306
+ loadDeterministicDefinition,
204307
+ replayContracts,
204308
+ replaySubgraph
204309
+ } from "@secondlayer/subgraphs/verify";
204310
+ import {
204311
+ MAINNET_CHECKPOINT as MAINNET_CHECKPOINT2,
204312
+ parseNakamotoHeader as parseNakamotoHeader2,
204313
+ unhex as unhex2
204314
+ } from "@secondlayer/verify";
204315
+ var LINKS2 = [
204316
+ { step: "pin", label: "pin" },
204317
+ { step: "blocks", label: "blocks" },
204318
+ { step: "txs", label: "txs" },
204319
+ { step: "inputs", label: "inputs" },
204320
+ { step: "handlers", label: "handlers" },
204321
+ { step: "rows", label: "rows" }
204322
+ ];
204323
+ var LABEL_WIDTH2 = Math.max(...LINKS2.map((l) => l.label.length));
204324
+ var PROGRESS_EVERY = 100;
204325
+ var PAGE = 1000;
204326
+ var n2 = (v) => v.toLocaleString("en-US");
204327
+ var short = (h) => `${h.slice(0, 4)}…${h.slice(-4)}`;
204328
+
204329
+ class InputError extends Error {
204330
+ }
204331
+ function parseHeight2(raw, flag) {
204332
+ if (raw === undefined)
204333
+ return;
204334
+ if (!/^\d+$/.test(raw) || !Number.isSafeInteger(Number(raw)))
204335
+ throw new InputError(`${flag} must be a block height, got "${raw}"`);
204336
+ return Number(raw);
204337
+ }
204338
+ async function readTable(fetchRows, name, table) {
204339
+ const out = [];
204340
+ let cursor;
204341
+ for (;; ) {
204342
+ const page = await fetchRows(name, table, cursor);
204343
+ out.push(...page.rows);
204344
+ if (!page.next_cursor || page.rows.length === 0)
204345
+ return out;
204346
+ cursor = page.next_cursor;
204347
+ }
204348
+ }
204349
+ function linkLine(step, r) {
204350
+ const res = r.result;
204351
+ switch (step) {
204352
+ case "pin":
204353
+ return `${short(r.pinValue ?? "")} handler, schema and startBlock match the deploy`;
204354
+ case "blocks":
204355
+ return `${n2(res.blocks)} proven from the checkpoint${res.marfProofs ? ` (${n2(res.marfProofs)} MARF proof${res.marfProofs === 1 ? "" : "s"}, then parent links)` : ""}`;
204356
+ case "txs":
204357
+ return `${n2(res.txs)} transactions match their blocks' tx merkle roots`;
204358
+ case "inputs":
204359
+ return `${n2(res.blocks)} diffs fully named; ${n2(res.writes)} writes to ${r.contracts.map((c) => c.split(".")[1] ?? c).join(", ")}`;
204360
+ case "handlers":
204361
+ return `${n2(res.events)} events, ${n2(res.handlerErrors)} handler errors, deterministic realm`;
204362
+ case "rows":
204363
+ return (r.comparison?.tables ?? []).map((t) => `${t.table}: ${n2(t.equal)} equal${t.superseded ? `, ${n2(t.superseded)} superseded after ${n2(res.to)}` : ""} digest ${short(t.digest)}`).join(`
204364
+ ${" ".repeat(LABEL_WIDTH2 + 4)}`);
204365
+ }
204366
+ }
204367
+ function firstFailure(r) {
204368
+ if (r.pin.status === "failed")
204369
+ return r.pin.failure;
204370
+ return r.result?.failures[0] ?? r.comparison?.failures[0];
204371
+ }
204372
+ function report2(r, from, to) {
204373
+ const first = firstFailure(r);
204374
+ const broken = first ? LINKS2.findIndex((l) => l.step === first.step) : LINKS2.length;
204375
+ const inconclusive = !first ? r.result?.inconclusive : undefined;
204376
+ for (const [i, link] of LINKS2.entries()) {
204377
+ const label = link.label.padEnd(LABEL_WIDTH2);
204378
+ if (first && i === broken)
204379
+ writeData(`${red("✗")} ${label} ${first.message}`);
204380
+ else if (i > broken)
204381
+ writeData(dim(`· ${label} not checked: an earlier link is broken`));
204382
+ else if (link.step === "pin" && r.pin.status === "unchecked")
204383
+ writeData(dim(`· ${label} not checked: deployed before pin inputs were stored (redeploy)`));
204384
+ else if (link.step === "rows" && inconclusive)
204385
+ writeData(dim(`· ${label} not checked: ${inconclusive}`));
204386
+ else
204387
+ writeData(`${green("✓")} ${label} ${linkLine(link.step, r)}`);
204388
+ }
204389
+ for (const line of [...r.pin.notes, ...r.result?.notes ?? []])
204390
+ note(` note: ${line}`);
204391
+ if (first) {
204392
+ const label = LINKS2[broken]?.label ?? first.step;
204393
+ writeData(red(first.unavailable ? `✗ Could not check the ${label} link: the source could not serve it.` : `✗ Not proven: the ${label} link is broken.`));
204394
+ return first.unavailable ? VERIFY_EXIT.UNANCHORED : VERIFY_EXIT.DIVERGED;
204395
+ }
204396
+ if (inconclusive) {
204397
+ writeData(dim(`· Inconclusive: ${inconclusive}. Rows were not compared.`));
204398
+ return VERIFY_EXIT.UNANCHORED;
204399
+ }
204400
+ const cp = MAINNET_CHECKPOINT2;
204401
+ const stacks = n2(Number(parseNakamotoHeader2(unhex2(cp.stacks.header)).chainLength));
204402
+ writeData(green(`✓ ${r.name} ${n2(from)}..${n2(to)} recomputed from proven inputs. Trusted: only the checkpoint (Stacks ${stacks}, Bitcoin ${n2(cp.bitcoin.height)}).`));
204403
+ writeData(dim(` unproven, so not compared: ${[...r.unproven, "rows compare declared columns and _block_height only"].join("; ")}`));
204404
+ return VERIFY_EXIT.CLEAN;
204405
+ }
204406
+ function reportJson(r) {
204407
+ const { tables, ...result } = r.result ?? {};
204408
+ return JSON.stringify({
204409
+ pin: r.pin,
204410
+ replay: r.result ? {
204411
+ ...result,
204412
+ tables: Object.fromEntries([...tables ?? new Map].map(([t, rows]) => [t, rows.length]))
204413
+ } : null,
204414
+ comparison: r.comparison ?? null
204415
+ }, (_k, v) => typeof v === "bigint" ? v.toString() : v, 2);
204416
+ }
204417
+ async function runVerifySubgraph(name, opts, deps = {}) {
204418
+ const fetchSubgraph = deps.fetchSubgraph ?? getSubgraphApi;
204419
+ const fetchSource = deps.fetchSource ?? getSubgraphSourceApi;
204420
+ const fetchRows = deps.fetchRows ?? ((n, t, cursor) => getSubgraphRowsApi(n, t, { cursor, limit: PAGE }));
204421
+ try {
204422
+ if (!opts.replay)
204423
+ throw new InputError("pass --replay: the only check today re-runs the handlers over proven blocks");
204424
+ const fromFlag = parseHeight2(opts.from, "--from");
204425
+ const toFlag = parseHeight2(opts.to, "--to");
204426
+ const detail = await fetchSubgraph(name);
204427
+ const level = detail.verification;
204428
+ if (level?.level !== "state")
204429
+ throw new InputError(level ? `${name} is level ${level.level}, not state: ${level.reasons.join("; ")}` : `${name} has no verification level: deployed before levels were derived (redeploy)`);
204430
+ const served = await fetchSource(name);
204431
+ if (!served.handlerCode)
204432
+ throw new InputError(`${name} has no stored handler bundle to replay (a local deploy)`);
204433
+ const def = await loadDeterministicDefinition(served.handlerCode);
204434
+ const pin = checkPin({
204435
+ pin: served.pin ?? null,
204436
+ pinPreimage: served.pinPreimage ?? null,
204437
+ handlerCode: served.handlerCode
204438
+ }, def);
204439
+ const startBlock = typeof detail.definition?.startBlock === "number" ? detail.definition.startBlock : def.startBlock ?? 0;
204440
+ const contracts = replayContracts(def);
204441
+ const tables = Object.keys(def.schema);
204442
+ const first = tables[0] ? await fetchRows(name, tables[0]) : { tip: { subgraph_height: startBlock } };
204443
+ const tip = first.tip.subgraph_height;
204444
+ const from = fromFlag ?? startBlock;
204445
+ const to = toFlag ?? tip;
204446
+ if (to > tip)
204447
+ throw new InputError(`--to ${n2(to)} is past the served subgraph: it is at ${n2(tip)}`);
204448
+ if (from > to)
204449
+ throw new InputError(`--from ${n2(from)} is after --to ${n2(to)}`);
204450
+ const r = {
204451
+ name,
204452
+ pin,
204453
+ pinValue: served.pin ?? null,
204454
+ contracts: Array.isArray(contracts) ? contracts : [],
204455
+ unproven: deriveVerification(def).unproven
204456
+ };
204457
+ if (pin.status !== "failed") {
204458
+ const servedRows = new Map;
204459
+ for (const table of tables)
204460
+ servedRows.set(table, await readTable(fetchRows, name, table));
204461
+ note(`Replaying ${name} ${n2(from)}..${n2(to)} (${n2(to - from + 1)} blocks)`);
204462
+ r.result = await (deps.replay ?? replaySubgraph)({
204463
+ source: deps.source ?? defaultSource(opts.node),
204464
+ handlerCode: served.handlerCode,
204465
+ from,
204466
+ to,
204467
+ startBlock,
204468
+ onProgress: (h) => {
204469
+ const done = h - from + 1;
204470
+ if (done % PROGRESS_EVERY === 0)
204471
+ note(` replayed ${n2(done)} / ${n2(to - from + 1)} blocks`);
204472
+ }
204473
+ });
204474
+ if (r.result.failures.length === 0 && !r.result.inconclusive)
204475
+ r.comparison = compareRows(def.schema, r.result, servedRows);
204476
+ }
204477
+ if (opts.json) {
204478
+ writeData(reportJson(r));
204479
+ const f = firstFailure(r);
204480
+ if (f)
204481
+ return f.unavailable ? VERIFY_EXIT.UNANCHORED : VERIFY_EXIT.DIVERGED;
204482
+ return r.result?.inconclusive ? VERIFY_EXIT.UNANCHORED : VERIFY_EXIT.CLEAN;
204483
+ }
204484
+ return report2(r, from, to);
204485
+ } catch (err) {
204486
+ printError(err instanceof Error ? err.message : String(err));
204487
+ return VERIFY_EXIT.UNANCHORED;
204488
+ }
204489
+ }
204490
+ function attachVerifySubgraphCommand(verify) {
204491
+ return verify.command("subgraph").description("Recompute a state-level subgraph from proven blocks and check its served rows").argument("<name>", "deployed subgraph name").option("--replay", "re-run the handlers over blocks proven from the checkpoint").option("--from <height>", "first block to replay (default: the subgraph's startBlock)").option("--to <height>", "last block to replay (default: the served subgraph's height)").option("--node <url>", "read blocks and MARF proofs from this Stacks node RPC instead of the API").addHelpText("after", `
204492
+ What is proven, link by link:
204493
+ pin the served pin is the sha256 of its preimage, which names the served
204494
+ handler bundle, its schema and startBlock
204495
+ blocks every block in the range, from the checkpoint (signatures above it,
204496
+ parent links and MARF proofs below it)
204497
+ txs each block's transactions hash to its header's tx merkle root
204498
+ inputs each block's writes are named, nothing hidden (state_writes vs witness)
204499
+ handlers the bundle runs in the deterministic realm over those writes
204500
+ rows the served rows equal the recomputed ones (keyed by the first
204501
+ unique key, else as a multiset), with a digest per table
204502
+
204503
+ Starting after startBlock (--from) is inconclusive once a handler reads or
204504
+ merges rows written before the range (findOne, increment, a partial upsert).
204505
+ Not proven, so not compared: which transaction made a write (event.tx,
204506
+ _tx_id) and writes overwritten within one block. Rows compare on their
204507
+ declared columns and _block_height.
204508
+
204509
+ Reads are free: proofs and each block's state writes from /v1/proofs (rate
204510
+ limited; witnesses 2 per second, so 1,000 blocks take 8 minutes or more) and
204511
+ the subgraph's rows from /v1/subgraphs. Nothing bills as Index rows.
204512
+
204513
+ Examples:
204514
+ $ secondlayer verify subgraph pool-reserves --replay
204515
+ $ secondlayer verify subgraph pool-reserves --replay --from 1230000 --to 1231000
204516
+ $ secondlayer verify subgraph pool-reserves --replay --json
204517
+
204518
+ Exit codes:
204519
+ 0 every link holds
204520
+ 1 a link is broken (the first is named)
204521
+ 2 could not check: the source could not serve a link, the replay is
204522
+ inconclusive, the subgraph is not state-level, or bad input`).action(async (name, opts, cmd) => {
204523
+ const json = cmd.optsWithGlobals().json === true;
204524
+ process.exit(await runVerifySubgraph(name, { ...opts, json }));
204525
+ });
204526
+ }
204527
+
204218
204528
  // src/commands/verify.ts
204219
204529
  var VERIFY_EXIT = {
204220
204530
  CLEAN: 0,
204221
204531
  DIVERGED: 1,
204222
204532
  UNANCHORED: 2
204223
204533
  };
204224
- function parseHeight2(value, flag) {
204534
+ function parseHeight3(value, flag) {
204225
204535
  const parsed = Number(value);
204226
204536
  if (!Number.isSafeInteger(parsed) || parsed < 0) {
204227
204537
  throw new Error(`${flag} must be a non-negative integer, got "${value}"`);
@@ -204257,8 +204567,8 @@ Exit codes:
204257
204567
  try {
204258
204568
  const target = parseVerifyTarget(targetArg);
204259
204569
  const mode = opts.deep ? "deep" : opts.anchor ? "anchor" : "quick";
204260
- const fromBlock = opts.fromBlock === undefined ? undefined : parseHeight2(opts.fromBlock, "--from-block");
204261
- const toBlock = opts.toBlock === undefined ? undefined : parseHeight2(opts.toBlock, "--to-block");
204570
+ const fromBlock = opts.fromBlock === undefined ? undefined : parseHeight3(opts.fromBlock, "--from-block");
204571
+ const toBlock = opts.toBlock === undefined ? undefined : parseHeight3(opts.toBlock, "--to-block");
204262
204572
  if (fromBlock !== undefined && toBlock !== undefined && toBlock < fromBlock) {
204263
204573
  throw new Error("--to-block must be >= --from-block");
204264
204574
  }
@@ -204432,13 +204742,14 @@ Exit codes:
204432
204742
  });
204433
204743
  }
204434
204744
  function registerVerifyCommand(program) {
204435
- const verify = attachVerifyCommand(program.command("verify").description("Compare local chain data against a signed archive, or prove one block with `verify block` (read-only)"));
204745
+ const verify = attachVerifyCommand(program.command("verify").description("Compare local chain data against a signed archive, prove one block with `verify block`, or recompute a subgraph with `verify subgraph --replay` (read-only)"));
204436
204746
  attachVerifyBlockCommand(verify);
204747
+ attachVerifySubgraphCommand(verify);
204437
204748
  }
204438
204749
 
204439
204750
  // src/commands/archive.ts
204440
204751
  var ARCHIVE_KEY_HINT = "set SECONDLAYER_API_KEY (sk-sl_*) for archive latest/quote; INSTANCE_TOKEN is the instance";
204441
- function parseHeight3(value, flag) {
204752
+ function parseHeight4(value, flag) {
204442
204753
  const parsed = Number(value);
204443
204754
  if (!Number.isSafeInteger(parsed) || parsed < 0) {
204444
204755
  throw new Error(`${flag} must be a non-negative integer, got "${value}"`);
@@ -204459,7 +204770,7 @@ function requireAccountKey(resolve = resolveAccountKey3) {
204459
204770
  return accountKey;
204460
204771
  }
204461
204772
  function defaultArchive(accountKey) {
204462
- return new SecondLayer({
204773
+ return new SecondLayer2({
204463
204774
  accountKey,
204464
204775
  archiveOpsUrl: resolveArchiveOpsUrl()
204465
204776
  }).archive;
@@ -204500,8 +204811,8 @@ async function runLatest(opts, deps = {}) {
204500
204811
  async function runQuote(opts, deps = {}) {
204501
204812
  const accountKey = requireAccountKey(deps.resolveAccountKey);
204502
204813
  const flow = parseFlow(opts.flow);
204503
- const fromBlock = opts.fromBlock === undefined ? undefined : parseHeight3(opts.fromBlock, "--from-block");
204504
- const toBlock = opts.toBlock === undefined ? undefined : parseHeight3(opts.toBlock, "--to-block");
204814
+ const fromBlock = opts.fromBlock === undefined ? undefined : parseHeight4(opts.fromBlock, "--from-block");
204815
+ const toBlock = opts.toBlock === undefined ? undefined : parseHeight4(opts.toBlock, "--to-block");
204505
204816
  if (fromBlock !== undefined && toBlock !== undefined && toBlock < fromBlock) {
204506
204817
  printError("--to-block must be >= --from-block");
204507
204818
  process.exit(1);
@@ -205301,7 +205612,7 @@ import {
205301
205612
  statSync as statSync2,
205302
205613
  writeFileSync as writeFileSync4
205303
205614
  } from "node:fs";
205304
- import { dirname as dirname6, join as join9, relative, resolve as resolve7 } from "node:path";
205615
+ import { dirname as dirname6, join as join9, relative as relative2, resolve as resolve7 } from "node:path";
205305
205616
  import { fileURLToPath as fileURLToPath4 } from "node:url";
205306
205617
  import { input, select as select3 } from "@inquirer/prompts";
205307
205618
  import { SecondLayer as SecondLayer4 } from "@secondlayer/sdk";
@@ -205483,7 +205794,7 @@ async function createWebhook(name, opts) {
205483
205794
  const targetDir = resolve7(process.cwd(), name);
205484
205795
  if (opts.scaffold !== false) {
205485
205796
  if (existsSync5(targetDir)) {
205486
- error(`Directory already exists: ${relative(process.cwd(), targetDir)}`);
205797
+ error(`Directory already exists: ${relative2(process.cwd(), targetDir)}`);
205487
205798
  process.exit(1);
205488
205799
  }
205489
205800
  const tplRoot = templatesRoot();
@@ -205530,7 +205841,7 @@ async function createWebhook(name, opts) {
205530
205841
  }
205531
205842
  if (signingSecret && opts.scaffold !== false) {
205532
205843
  const envTarget = writeSigningSecretEnv(targetDir, signingSecret);
205533
- success(`Signing secret written to ${relative(process.cwd(), envTarget)}`);
205844
+ success(`Signing secret written to ${relative2(process.cwd(), envTarget)}`);
205534
205845
  } else if (signingSecret && opts.scaffold === false) {
205535
205846
  info(`Signing secret (store securely): ${signingSecret}`);
205536
205847
  }
@@ -206978,7 +207289,7 @@ function consumeHandlers(io) {
206978
207289
  }
206979
207290
  };
206980
207291
  }
206981
- function parseHeight4(value, name) {
207292
+ function parseHeight5(value, name) {
206982
207293
  if (value === undefined)
206983
207294
  return;
206984
207295
  const n = Number.parseInt(value, 10);
@@ -207012,8 +207323,8 @@ Examples:
207012
207323
  sender: parseList(options.sender),
207013
207324
  recipient: parseList(options.recipient),
207014
207325
  cursor: options.cursor,
207015
- fromHeight: parseHeight4(options.fromBlock, "--from-block"),
207016
- toHeight: parseHeight4(options.toBlock, "--to-block"),
207326
+ fromHeight: parseHeight5(options.fromBlock, "--from-block"),
207327
+ toHeight: parseHeight5(options.toBlock, "--to-block"),
207017
207328
  limit: parseLimit(options.limit)
207018
207329
  });
207019
207330
  writeData(JSON.stringify(envelope, null, 2));
@@ -207077,8 +207388,8 @@ Examples:
207077
207388
  });
207078
207389
  const runDumps = async (options) => {
207079
207390
  try {
207080
- const fromBlock = parseHeight4(options.fromBlock, "--from-block");
207081
- const toBlock = parseHeight4(options.toBlock, "--to-block");
207391
+ const fromBlock = parseHeight5(options.fromBlock, "--from-block");
207392
+ const toBlock = parseHeight5(options.toBlock, "--to-block");
207082
207393
  const dumps = dumpsClient(options.dumpsUrl).dumps;
207083
207394
  const manifest = await dumps.list();
207084
207395
  const files = manifest.files.filter((f) => (fromBlock === undefined || f.to_block >= fromBlock) && (toBlock === undefined || f.from_block <= toBlock));
@@ -207109,7 +207420,7 @@ Examples:
207109
207420
  $ secondlayer streams dumps --to ./dump --from-block 150000 --to-block 200000`).action(runDumps);
207110
207421
  streams.command("canonical <height>").description("Canonical block metadata at a given height").option("--json", "Output as JSON (streams always emits JSON)").action(async (heightArg) => {
207111
207422
  try {
207112
- const height = parseHeight4(heightArg, "<height>");
207423
+ const height = parseHeight5(heightArg, "<height>");
207113
207424
  if (height === undefined)
207114
207425
  throw new Error("<height> is required");
207115
207426
  const block = await client2().canonical(height);
@@ -209529,5 +209840,5 @@ registerCreditsCommand(program);
209529
209840
  registerArchiveCommand(program);
209530
209841
  program.parse();
209531
209842
 
209532
- //# debugId=92924A7AE61FB1AF64756E2164756E21
209843
+ //# debugId=F270856631D97EA764756E2164756E21
209533
209844
  //# sourceMappingURL=cli.js.map