@secondlayer/cli 23.3.0 → 23.4.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
@@ -29357,6 +29357,12 @@ function inspectSourceGitState(absPath) {
29357
29357
  }
29358
29358
  return { kind: "clean" };
29359
29359
  }
29360
+ function uncommittedSourceWarning(state, file) {
29361
+ if (state.kind !== "untracked" && state.kind !== "modified")
29362
+ return;
29363
+ const reason = state.kind === "untracked" ? "not tracked by git" : "modified with uncommitted changes";
29364
+ return `${file} is ${reason}, so this deploy's only copy is the database row. Commit it to keep a copy.`;
29365
+ }
29360
29366
  var init_git_status = () => {};
29361
29367
 
29362
29368
  // src/lib/merge-print-subgraph.ts
@@ -29990,7 +29996,6 @@ import {
29990
29996
  } from "node:fs";
29991
29997
  import { basename, dirname as dirname5, extname, join as join7, relative, resolve as resolve5 } from "node:path";
29992
29998
  import { fileURLToPath as fileURLToPath3 } from "node:url";
29993
- import { confirm as confirm2 } from "@inquirer/prompts";
29994
29999
  import {
29995
30000
  generatePrintPayloadTypes,
29996
30001
  generatePrintSchemaSubgraph as generatePrintSchemaSubgraph2,
@@ -30004,31 +30009,11 @@ import {
30004
30009
  deriveVerification as deriveVerification2,
30005
30010
  isDeterminismViolation
30006
30011
  } from "@secondlayer/subgraphs/verification";
30007
- async function loadSubgraphWithDepCheck(absPath) {
30008
- try {
30009
- return await import(absPath);
30010
- } catch (err) {
30011
- const msg = err instanceof Error ? err.message : String(err);
30012
- const code = err?.code;
30013
- const missingSdk = (code === "ERR_MODULE_NOT_FOUND" || msg.includes("ERR_MODULE_NOT_FOUND")) && msg.includes("@secondlayer/subgraphs");
30014
- if (!missingSdk)
30015
- throw err;
30016
- warn("Missing dependency: @secondlayer/subgraphs");
30017
- const install = await confirm2({
30018
- message: "Install with `bun add @secondlayer/subgraphs`?",
30019
- default: true
30020
- });
30021
- if (!install)
30022
- throw err;
30023
- await new Promise((res, rej) => {
30024
- const child = spawn2("bun", ["add", "@secondlayer/subgraphs"], {
30025
- stdio: "inherit"
30026
- });
30027
- child.on("error", rej);
30028
- child.on("exit", (c) => c === 0 ? res() : rej(new Error(`bun add exit ${c}`)));
30029
- });
30030
- return await import(absPath);
30031
- }
30012
+ async function loadSubgraphDefinition(source, fileName) {
30013
+ const { bundleSubgraphCode } = await import("@secondlayer/bundler");
30014
+ const bundled = await bundleSubgraphCode(source, { fileName });
30015
+ const url = `data:text/javascript;base64,${Buffer.from(bundled.handlerCode, "utf8").toString("base64")}`;
30016
+ return { mod: await import(url), bundled };
30032
30017
  }
30033
30018
  async function typecheckHandler(absPath) {
30034
30019
  await new Promise((res, rej) => {
@@ -30055,6 +30040,15 @@ function parseStartBlockOption(value) {
30055
30040
  }
30056
30041
  return parsed;
30057
30042
  }
30043
+ function genesisWarning(startBlock) {
30044
+ if (startBlock === undefined) {
30045
+ return "No startBlock: the first deploy backfills from genesis.";
30046
+ }
30047
+ if (startBlock <= 1) {
30048
+ return `startBlock ${startBlock}: the first deploy backfills all history from genesis.`;
30049
+ }
30050
+ return null;
30051
+ }
30058
30052
  function collectPinnedPrintSources(sources) {
30059
30053
  const out = [];
30060
30054
  for (const [sourceName, raw] of Object.entries(sources ?? {})) {
@@ -30542,8 +30536,7 @@ Try --trait sip-010 or \`subgraphs scaffold ${opts.fromContract}\` for ABI calls
30542
30536
  if (opts.fromContract) {
30543
30537
  info(`Schema inferred from ${opts.fromContract} print events (${opts.tablePerTopic ? "table per topic" : "single wide table"})`);
30544
30538
  }
30545
- info(`Next: git add subgraphs/${name}.ts && secondlayer subgraphs deploy subgraphs/${name}.ts`);
30546
- note(" deploy refuses an unstaged file unless you pass --allow-uncommitted: a staged copy is the one git can recover.");
30539
+ info(`Next: secondlayer subgraphs deploy subgraphs/${name}.ts`);
30547
30540
  });
30548
30541
  subgraphs.command("add <file>").description("Merge another contract's observed print sources into an existing subgraph file").requiredOption("--from-contract <contractId>", "Contract whose print schema to merge (requires network)").option("--table-per-topic", "One table per print topic instead of a single wide table for the added contract").addHelpText("after", `
30549
30542
  Adds sources/schema/handlers for a second (or Nth) contract into an existing
@@ -30650,10 +30643,10 @@ Stopped watching.`);
30650
30643
  });
30651
30644
  await new Promise(() => {});
30652
30645
  });
30653
- subgraphs.command("deploy <file>").alias("update").description("Deploy a subgraph definition file (alias: update — deploy is create-or-update)").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--tip-first", "Go live at chain tip immediately; history backfills in the background (handlers may only insert, upsert and delete; update, increment and row reads are refused)").option("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").option("--allow-uncommitted", "Deploy even though the source file is not staged or committed in git (the deployed definition will exist only in the database)").addHelpText("after", `
30654
- By default the source file must be staged or committed in git (\`git add <file>\`),
30655
- otherwise the deployed definition's only copy is the row in the database. Pass
30656
- --allow-uncommitted to deploy anyway.
30646
+ subgraphs.command("deploy <file>").alias("update").description("Deploy a subgraph definition file (alias: update — deploy is create-or-update)").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--tip-first", "Go live at chain tip immediately; history backfills in the background (handlers may only insert, upsert and delete; update, increment and row reads are refused)").option("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").option("--allow-uncommitted", "Don't warn when the source file isn't committed in git").addHelpText("after", `
30647
+ If the source file isn't committed in git, deploy warns that the deployed
30648
+ definition's only copy is the row in the database. It never blocks; pass
30649
+ --allow-uncommitted to silence the warning.
30657
30650
 
30658
30651
  Hosted: set SECONDLAYER_API_KEY and SECONDLAYER_API_URL=https://api.secondlayer.tools.
30659
30652
  Hostable sources are event filters and contract_call/contract_deploy; anything else
@@ -30662,28 +30655,10 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
30662
30655
  try {
30663
30656
  const absPath = resolve5(file);
30664
30657
  if (!options.dryRun) {
30665
- if (options.allowUncommitted) {
30666
- info("--allow-uncommitted: skipping the git commit check for the source file.");
30667
- } else {
30668
- const gitState = inspectSourceGitState(absPath);
30669
- if (gitState.kind === "untracked" || gitState.kind === "modified") {
30670
- const reason = gitState.kind === "untracked" ? "not tracked by git" : "modified with uncommitted changes";
30671
- const message = `${file} is ${reason}. Deploy it and the only copy of this definition is a row in the database.`;
30672
- if (process.stdin.isTTY) {
30673
- warn(message);
30674
- const confirmed = await confirm2({
30675
- message: "Deploy anyway?",
30676
- default: false
30677
- });
30678
- if (!confirmed) {
30679
- info("Nothing was deployed.");
30680
- process.exit(0);
30681
- }
30682
- } else {
30683
- error(`${message} Stage it with \`git add ${file}\`, or pass --allow-uncommitted.`);
30684
- process.exit(1);
30685
- }
30686
- }
30658
+ if (!options.allowUncommitted) {
30659
+ const advice = uncommittedSourceWarning(inspectSourceGitState(absPath), file);
30660
+ if (advice)
30661
+ warn(advice);
30687
30662
  }
30688
30663
  }
30689
30664
  const config = await loadConfig2();
@@ -30697,18 +30672,28 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
30697
30672
  await typecheckHandler(absPath);
30698
30673
  }
30699
30674
  info(`Loading subgraph from ${absPath}`);
30700
- const mod = await loadSubgraphWithDepCheck(absPath);
30701
- const def = mod.default ?? mod;
30702
- const effectiveDef = {
30703
- ...startBlock === undefined ? def : { ...def, startBlock },
30704
- ...options.tipFirst ? { backfillMode: "concurrent" } : {}
30705
- };
30706
30675
  const { validateSubgraphDefinition } = await import("@secondlayer/subgraphs/validate");
30707
30676
  const { readFile } = await import("node:fs/promises");
30708
30677
  const derived = config.network !== "local" ? await withDerivedAbis(await readFile(absPath, "utf8")) : undefined;
30709
30678
  for (const name of Object.keys(derived?.abis ?? {})) {
30710
30679
  info(`Using the deployed contract's abi for source "${name}"`);
30711
30680
  }
30681
+ const source = derived?.source ?? await readFile(absPath, "utf8");
30682
+ const { mod, bundled } = await loadSubgraphDefinition(source, relative(process.cwd(), absPath));
30683
+ const def = mod.default ?? mod;
30684
+ const authored = {
30685
+ ...def,
30686
+ sources: Object.fromEntries(Object.entries(def.sources ?? {}).map(([k, v]) => {
30687
+ if (!derived?.abis[k])
30688
+ return [k, v];
30689
+ const { abi: _abi, ...rest } = v;
30690
+ return [k, rest];
30691
+ }))
30692
+ };
30693
+ const effectiveDef = {
30694
+ ...startBlock === undefined ? authored : { ...authored, startBlock },
30695
+ ...options.tipFirst ? { backfillMode: "concurrent" } : {}
30696
+ };
30712
30697
  const validated = validateSubgraphDefinition(derived && Object.keys(derived.abis).length > 0 ? {
30713
30698
  ...effectiveDef,
30714
30699
  sources: Object.fromEntries(Object.entries(effectiveDef.sources).map(([k, v]) => [
@@ -30716,16 +30701,11 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
30716
30701
  derived.abis[k] ? { ...v, abi: derived.abis[k] } : v
30717
30702
  ]))
30718
30703
  } : effectiveDef);
30719
- if ((validated.startBlock ?? 1) <= 1) {
30720
- warn("No startBlock: the first deploy backfills from genesis.");
30721
- }
30704
+ const genesis = genesisWarning(effectiveDef.startBlock);
30705
+ if (genesis)
30706
+ warn(genesis);
30722
30707
  if (config.network !== "local") {
30723
30708
  info(`${dryRun ? "Bundling for remote deploy dry run" : "Bundling for remote deploy"} (${config.network})...`);
30724
- const source = derived?.source ?? await readFile(absPath, "utf8");
30725
- const { bundleSubgraphCode } = await import("@secondlayer/bundler");
30726
- const bundled = await bundleSubgraphCode(source, {
30727
- fileName: relative(process.cwd(), absPath)
30728
- });
30729
30709
  const handlerCode = bundled.handlerCode;
30730
30710
  const localVerification = checkDeterminism(effectiveDef, bundled.findings);
30731
30711
  if (dryRun) {
@@ -30840,16 +30820,7 @@ deploy does not backfill from genesis.`).action(async (file, options) => {
30840
30820
  await printDeployFooter();
30841
30821
  }
30842
30822
  } else {
30843
- let findings;
30844
- try {
30845
- const { bundleSubgraphCode } = await import("@secondlayer/bundler");
30846
- findings = (await bundleSubgraphCode(await readFile(absPath, "utf8"), {
30847
- fileName: relative(process.cwd(), absPath)
30848
- })).findings;
30849
- } catch {
30850
- findings = undefined;
30851
- }
30852
- const verification = findings ? checkDeterminism(effectiveDef, findings) : undefined;
30823
+ const verification = checkDeterminism(effectiveDef, bundled.findings);
30853
30824
  if (dryRun) {
30854
30825
  printSubgraphDeployPreview(createSubgraphDeployPreview(validated), {
30855
30826
  network: config.network,
@@ -31892,7 +31863,7 @@ var {
31892
31863
  // package.json
31893
31864
  var package_default = {
31894
31865
  name: "@secondlayer/cli",
31895
- version: "23.3.0",
31866
+ version: "23.4.1",
31896
31867
  description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
31897
31868
  repository: {
31898
31869
  type: "git",
@@ -31943,8 +31914,8 @@ var package_default = {
31943
31914
  "@secondlayer/scaffold": "^1.6.3",
31944
31915
  "@secondlayer/sdk": "^16.2.0",
31945
31916
  "@secondlayer/shared": "^15.0.1",
31946
- "@secondlayer/stacks": "^6.5.3",
31947
- "@secondlayer/subgraphs": "^8.0.1",
31917
+ "@secondlayer/stacks": "^6.6.0",
31918
+ "@secondlayer/subgraphs": "^8.0.2",
31948
31919
  "@secondlayer/verify": "^0.6.1",
31949
31920
  esbuild: "^0.28.2",
31950
31921
  "smol-toml": "^1.9.1",
@@ -35867,7 +35838,7 @@ is what makes minting possible without Bitcoin.`).action(async (opts) => {
35867
35838
  const txid = await client.callContract({
35868
35839
  contract,
35869
35840
  functionName: "complete-deposit-wrapper",
35870
- functionArgs: [
35841
+ args: [
35871
35842
  Cl.bufferFromHex(depositTxid),
35872
35843
  Cl.uint(0),
35873
35844
  Cl.uint(amount),
@@ -36868,7 +36839,7 @@ init_api_url();
36868
36839
  init_http();
36869
36840
  import { hostname } from "node:os";
36870
36841
  import { createInterface } from "node:readline";
36871
- import { confirm as confirm3, input } from "@inquirer/prompts";
36842
+ import { confirm as confirm2, input } from "@inquirer/prompts";
36872
36843
 
36873
36844
  // src/lib/open-browser.ts
36874
36845
  import { spawn as spawn3 } from "node:child_process";
@@ -36951,7 +36922,7 @@ async function shouldContinueLogin(target, options, deps = defaultLoginCheckDeps
36951
36922
  return false;
36952
36923
  }
36953
36924
  try {
36954
- const proceed = await confirm3({
36925
+ const proceed = await confirm2({
36955
36926
  message: "Log in as a different user?",
36956
36927
  default: false
36957
36928
  });
@@ -37120,18 +37091,24 @@ async function runLogout() {
37120
37091
  info(`Not logged in (${target}).`);
37121
37092
  return;
37122
37093
  }
37123
- try {
37124
- await httpAt(target, "/api/auth/logout", {
37125
- method: "POST",
37126
- bearer: session.token
37127
- });
37128
- } catch (err) {
37129
- if (err instanceof CliHttpError) {
37130
- warn(`Server logout failed (${err.code}); clearing the local session anyway`);
37094
+ const isSession = session.token.startsWith("ss-sl_");
37095
+ if (isSession) {
37096
+ try {
37097
+ await httpAt(target, "/api/auth/logout", {
37098
+ method: "POST",
37099
+ bearer: session.token
37100
+ });
37101
+ } catch (err) {
37102
+ if (err instanceof CliHttpError) {
37103
+ warn(`Server logout failed (${err.code}); clearing the local session anyway`);
37104
+ }
37131
37105
  }
37132
37106
  }
37133
37107
  await clearSession(target);
37134
37108
  success(`Logged out (${target}).`);
37109
+ if (!isSession) {
37110
+ info("Removed the saved key from this machine. The key stays active; revoke it on the Keys tab.");
37111
+ }
37135
37112
  }
37136
37113
  function registerLogoutCommand(program) {
37137
37114
  program.command("logout").description("Sign this machine out of your Secondlayer account").action(() => runLogout());
@@ -37698,8 +37675,7 @@ program.hook("preAction", (thisCommand) => {
37698
37675
  program.addHelpText("after", `
37699
37676
  Quickstart:
37700
37677
  $ secondlayer subgraphs create my-watcher --from-contract SP....my-contract
37701
- $ git add subgraphs/my-watcher.ts
37702
- $ secondlayer subgraphs deploy subgraphs/my-watcher.ts # or --allow-uncommitted
37678
+ $ secondlayer subgraphs deploy subgraphs/my-watcher.ts
37703
37679
 
37704
37680
  Self-host, from docker/oss in a checkout:
37705
37681
  $ secondlayer init --network mainnet
@@ -37737,5 +37713,5 @@ registerCreditsCommand(program);
37737
37713
  registerArchiveCommand(program);
37738
37714
  program.parse();
37739
37715
 
37740
- //# debugId=599D8A8ADF6556BF64756E2164756E21
37716
+ //# debugId=8047E4F45A72C72F64756E2164756E21
37741
37717
  //# sourceMappingURL=cli.js.map