@secondlayer/cli 8.6.3 → 8.7.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/README.md CHANGED
@@ -30,8 +30,11 @@ export SL_API_KEY=sk-sl_xxxxxxxx
30
30
  source (and exits non-zero when not logged in). The global `--api-key` /
31
31
  `--api-url` flags (and `SL_API_KEY` / `SL_API_URL`) apply to every command.
32
32
 
33
- During open beta, reads are public (no key needed). Writes — deploying or
34
- managing subgraphs and subscriptions — require a session or an `sk-sl_` key.
33
+ During open beta, reads are public (no key needed) — for subgraphs that means
34
+ **public** subgraphs only (managed deploys default public; BYO deploys and all
35
+ pre-existing subgraphs are private, readable with your key). Writes — deploying,
36
+ publishing, or managing subgraphs and subscriptions — require a session or an
37
+ `sk-sl_` key.
35
38
 
36
39
  ## Quickstart
37
40
 
@@ -86,7 +89,8 @@ scoped reads and cannot mint (403). Minted keys inherit your plan's tier.
86
89
  |---|---|
87
90
  | `sl subgraphs create <name>` | Scaffold a definition file |
88
91
  | `sl subgraphs scaffold <SP...::contract> [-o <path>] [--no-install]` | Generate a subgraph from a deployed contract |
89
- | `sl subgraphs deploy <file> [--start-block <n>]` | Deploy; `--start-block` overrides the definition |
92
+ | `sl subgraphs deploy <file> [--start-block <n>] [--visibility public\|private]` | Deploy; `--start-block` overrides the definition. Managed deploys default `public`, BYO default `private` |
93
+ | `sl subgraphs publish <name>` / `unpublish <name>` | Flip visibility; publish claims the global public name (409 `PUBLIC_NAME_TAKEN` if claimed) |
90
94
  | `sl subgraphs dev <file>` | Watch + hot-redeploy |
91
95
  | `sl subgraphs query <name> <table>` | Query a table with filters, sort, pagination |
92
96
  | `sl subgraphs list` / `status <name>` / `gaps <name>` | Inspect deployments |
package/dist/cli.js CHANGED
@@ -12870,8 +12870,12 @@ class StacksApiClient {
12870
12870
  async getContractInfo(contractId) {
12871
12871
  await this.ensureProxy();
12872
12872
  if (this.useProxy) {
12873
- const url2 = `${this.baseUrl}/api/node/contracts/${contractId}/abi`;
12874
- return this.fetchWithErrorHandling(url2, "Contract", contractId);
12873
+ const url2 = `${this.baseUrl}/v1/contracts/${encodeURIComponent(contractId)}?include=abi`;
12874
+ const { contract } = await this.fetchWithErrorHandling(url2, "Contract", contractId);
12875
+ if (!contract?.abi) {
12876
+ throw new Error(`ABI not available for ${contractId} (status: ${contract?.abi_status ?? "unknown"})`);
12877
+ }
12878
+ return contract.abi;
12875
12879
  }
12876
12880
  const { address, contractName } = parseContractId(contractId);
12877
12881
  const url = `${this.baseUrl}/v2/contracts/interface/${address}/${contractName}`;
@@ -31651,7 +31655,7 @@ Examples:`));
31651
31655
  No .clar files or contract addresses matched the provided inputs`));
31652
31656
  process.exit(1);
31653
31657
  }
31654
- const apiKey = options3.apiKey || process.env.STACKS_NODE_API_KEY || process.env.HIRO_API_KEY;
31658
+ const apiKey = options3.apiKey || process.env.STACKS_NODE_API_KEY;
31655
31659
  config = await buildConfigFromInputs(parsedInputs, options3.out, apiKey);
31656
31660
  } else {
31657
31661
  config = await loadConfig2(options3.config);
@@ -31807,7 +31811,7 @@ var {
31807
31811
  // package.json
31808
31812
  var package_default = {
31809
31813
  name: "@secondlayer/cli",
31810
- version: "8.6.3",
31814
+ version: "8.7.0",
31811
31815
  repository: {
31812
31816
  type: "git",
31813
31817
  url: "git+https://github.com/ryanwaits/secondlayer.git",
@@ -31856,10 +31860,10 @@ var package_default = {
31856
31860
  dependencies: {
31857
31861
  "@inquirer/prompts": "^8.2.0",
31858
31862
  "@secondlayer/bundler": "^0.3.7",
31859
- "@secondlayer/scaffold": "^1.1.0",
31860
- "@secondlayer/sdk": "^6.19.0",
31861
- "@secondlayer/shared": "^6.28.0",
31862
- "@secondlayer/stacks": "^2.4.0",
31863
+ "@secondlayer/scaffold": "^1.2.0",
31864
+ "@secondlayer/sdk": "^6.20.0",
31865
+ "@secondlayer/shared": "^6.29.0",
31866
+ "@secondlayer/stacks": "^2.5.0",
31863
31867
  "@secondlayer/subgraphs": "^3.10.0",
31864
31868
  "@biomejs/js-api": "^0.7.0",
31865
31869
  "@biomejs/wasm-nodejs": "^1.9.0",
@@ -32022,6 +32026,12 @@ async function deleteSubgraphApi(name, options) {
32022
32026
  async function deploySubgraphApi(data) {
32023
32027
  return (await getPlatformClient()).subgraphs.deploy(data);
32024
32028
  }
32029
+ async function publishSubgraphApi(name) {
32030
+ return (await getPlatformClient()).subgraphs.publish(name);
32031
+ }
32032
+ async function unpublishSubgraphApi(name) {
32033
+ return (await getPlatformClient()).subgraphs.unpublish(name);
32034
+ }
32025
32035
  async function querySubgraphTable(name, table, params = {}) {
32026
32036
  return (await getPlatformClient()).subgraphs.queryTable(name, table, params);
32027
32037
  }
@@ -34591,8 +34601,8 @@ function sip010Balances(name) {
34591
34601
  * source filter.
34592
34602
  *
34593
34603
  * Query examples once deployed:
34594
- * GET /api/subgraphs/${name}/balances?_search=SP1...
34595
- * GET /api/subgraphs/${name}/balances?holder=SP1...
34604
+ * GET /v1/subgraphs/${name}/balances?_search=SP1...
34605
+ * GET /v1/subgraphs/${name}/balances?holder=SP1...
34596
34606
  */
34597
34607
  export default defineSubgraph({
34598
34608
  name: "${name}",
@@ -34668,8 +34678,8 @@ function sbtcFlows(name) {
34668
34678
  * Source contract: sbtc-registry (mainnet).
34669
34679
  *
34670
34680
  * Query examples once deployed:
34671
- * GET /api/subgraphs/${name}/flows?topic=completed-deposit
34672
- * GET /api/subgraphs/${name}/flows?topic=withdrawal-create
34681
+ * GET /v1/subgraphs/${name}/flows?topic=completed-deposit
34682
+ * GET /v1/subgraphs/${name}/flows?topic=withdrawal-create
34673
34683
  */
34674
34684
  export default defineSubgraph({
34675
34685
  name: "${name}",
@@ -34739,8 +34749,8 @@ function poxStacking(name) {
34739
34749
  * the dataset shows one possible shape.
34740
34750
  *
34741
34751
  * Query examples once deployed:
34742
- * GET /api/subgraphs/${name}/calls?function_name=stack-stx
34743
- * GET /api/subgraphs/${name}/calls?caller=SP1...
34752
+ * GET /v1/subgraphs/${name}/calls?function_name=stack-stx
34753
+ * GET /v1/subgraphs/${name}/calls?caller=SP1...
34744
34754
  */
34745
34755
  export default defineSubgraph({
34746
34756
  name: "${name}",
@@ -34790,8 +34800,8 @@ function bnsNames(name) {
34790
34800
  * Source: BNS-V2 print events (topic-discriminated payloads).
34791
34801
  *
34792
34802
  * Query examples once deployed:
34793
- * GET /api/subgraphs/${name}/names?owner=SP1...
34794
- * GET /api/subgraphs/${name}/names?_search=alice
34803
+ * GET /v1/subgraphs/${name}/names?owner=SP1...
34804
+ * GET /v1/subgraphs/${name}/names?_search=alice
34795
34805
  */
34796
34806
  export default defineSubgraph({
34797
34807
  name: "${name}",
@@ -34903,6 +34913,13 @@ function parseStartBlockOption(value) {
34903
34913
  }
34904
34914
  return parsed;
34905
34915
  }
34916
+ function parseVisibilityOption(value) {
34917
+ if (value === undefined)
34918
+ return;
34919
+ if (value === "public" || value === "private")
34920
+ return value;
34921
+ throw new Error('--visibility must be "public" or "private"');
34922
+ }
34906
34923
  function parseSubgraphSpecFormat(value) {
34907
34924
  const format = value ?? "openapi";
34908
34925
  if (format === "openapi" || format === "agent" || format === "markdown") {
@@ -35262,7 +35279,7 @@ Stopped watching.`);
35262
35279
  });
35263
35280
  await new Promise(() => {});
35264
35281
  });
35265
- 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("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").option("--database-url <url>", "BYO data plane: write the subgraph's schema/rows to your own Postgres. With --dry-run, prints the DDL + grant script and verifies the connection.").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").action(async (file, options2) => {
35282
+ 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("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").option("--database-url <url>", "BYO data plane: write the subgraph's schema/rows to your own Postgres. With --dry-run, prints the DDL + grant script and verifies the connection.").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").option("--visibility <visibility>", "Read visibility: public (anon /v1 reads, global name claim) or private (your key only). Defaults: managed → public, BYO → private.").action(async (file, options2) => {
35266
35283
  try {
35267
35284
  const absPath = resolve2(file);
35268
35285
  const config = await loadConfig();
@@ -35270,6 +35287,16 @@ Stopped watching.`);
35270
35287
  await requireAuth();
35271
35288
  }
35272
35289
  const dryRun = options2.dryRun;
35290
+ const visibility = parseVisibilityOption(options2.visibility);
35291
+ if (visibility === "public" && options2.databaseUrl && !options2.yes) {
35292
+ const confirmed = await confirm3({
35293
+ message: "⚠ Public BYO subgraph: anonymous reads will query YOUR database. Continue?"
35294
+ });
35295
+ if (!confirmed) {
35296
+ info("Aborted.");
35297
+ process.exit(0);
35298
+ }
35299
+ }
35273
35300
  const startBlock = parseStartBlockOption(options2.startBlock);
35274
35301
  if (startBlock !== undefined) {
35275
35302
  warn(`--start-block ${startBlock} overrides the definition's startBlock for this deploy.`);
@@ -35317,16 +35344,22 @@ Stopped watching.`);
35317
35344
  handlerCode,
35318
35345
  sourceCode: source,
35319
35346
  ...deployStartBlock !== undefined ? { startBlock: deployStartBlock } : {},
35320
- ...options2.databaseUrl ? { databaseUrl: options2.databaseUrl } : {}
35347
+ ...options2.databaseUrl ? { databaseUrl: options2.databaseUrl } : {},
35348
+ ...visibility ? { visibility } : {}
35321
35349
  });
35322
35350
  const printDeployFooter = async () => {
35323
35351
  try {
35324
35352
  const { apiUrl } = await resolveAuth();
35325
35353
  const baseUrl = deriveBaseUrl(apiUrl);
35326
35354
  const firstTable = Object.keys(effectiveDef.schema ?? {})[0];
35355
+ const isPublic = result.visibility === "public";
35327
35356
  info(` Dashboard: ${baseUrl}/platform/subgraphs/${effectiveDef.name}`);
35328
- if (firstTable) {
35357
+ if (isPublic && firstTable) {
35358
+ info(` Read: ${apiUrl}/v1/subgraphs/${effectiveDef.name}/${firstTable}`);
35359
+ info(` Share: ${apiUrl}/v1/subgraphs/${effectiveDef.name} (public — no key needed)`);
35360
+ } else if (firstTable) {
35329
35361
  info(` REST: ${apiUrl}/api/subgraphs/${effectiveDef.name}/${firstTable}`);
35362
+ info(` Publish: sl subgraphs publish ${effectiveDef.name} (open anon /v1 reads)`);
35330
35363
  }
35331
35364
  info(` Watch: sl subgraphs status ${effectiveDef.name}`);
35332
35365
  } catch {}
@@ -35791,6 +35824,33 @@ ${rows.length} row(s)`));
35791
35824
  handleApiError(err, "delete subgraph");
35792
35825
  }
35793
35826
  });
35827
+ subgraphs.command("publish <name>").description("Make a subgraph publicly readable on /v1/subgraphs/<name> (claims the name globally, no key needed to read)").action(async (name) => {
35828
+ try {
35829
+ await requireAuth();
35830
+ const result = await publishSubgraphApi(name);
35831
+ success(`Subgraph "${name}" is now public`);
35832
+ try {
35833
+ const { apiUrl } = await resolveAuth();
35834
+ info(` Share: ${apiUrl}${result.url} (no key needed)`);
35835
+ } catch {}
35836
+ } catch (err) {
35837
+ const status2 = err?.status;
35838
+ if (status2 === 409) {
35839
+ error(`Public name "${name}" is already taken by another account. Rename the subgraph (redeploy under a new name) or keep it private.`);
35840
+ process.exit(1);
35841
+ }
35842
+ handleApiError(err, "publish subgraph");
35843
+ }
35844
+ });
35845
+ subgraphs.command("unpublish <name>").description("Make a subgraph private again — reads require your API key, the public name claim is released").action(async (name) => {
35846
+ try {
35847
+ await requireAuth();
35848
+ await unpublishSubgraphApi(name);
35849
+ success(`Subgraph "${name}" is now private (reads need your key)`);
35850
+ } catch (err) {
35851
+ handleApiError(err, "unpublish subgraph");
35852
+ }
35853
+ });
35794
35854
  subgraphs.command("scaffold [contractAddress]").description("Scaffold a defineSubgraph() file from a contract or trait").option("-o, --output <path>", "Output file path (required)").option("-k, --api-key <key>", "Stacks node API key for direct RPC URLs").option("--functions <names>", "Comma-separated public functions to index as typed contract_call tables").option("--trait <std>", "Scaffold a trait-scoped source (sip-009|sip-010|sip-013) — no contract needed").option("--no-install", "Skip bun install after writing package.json").addHelpText("after", `
35795
35855
  Examples:
35796
35856
  $ sl subgraphs scaffold SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.megapont-ape-club-nft -o subgraphs/apes.ts
@@ -35818,7 +35878,7 @@ Examples:
35818
35878
  } else {
35819
35879
  const address = contractAddress;
35820
35880
  const network = inferNetwork(address) ?? "mainnet";
35821
- const apiKey = options2.apiKey ?? process.env.STACKS_NODE_API_KEY ?? process.env.HIRO_API_KEY;
35881
+ const apiKey = options2.apiKey ?? process.env.STACKS_NODE_API_KEY;
35822
35882
  const client = new StacksApiClient(network, apiKey);
35823
35883
  info(`Fetching ABI for ${address} via ${client.describeContractInfoSource()}...`);
35824
35884
  const contractInfo = await client.getContractInfo(address);
@@ -37912,5 +37972,5 @@ registerAccountCommand(program);
37912
37972
  registerKeysCommand(program);
37913
37973
  program.parse();
37914
37974
 
37915
- //# debugId=FD969C75B9A203B164756E2164756E21
37975
+ //# debugId=5C2D0497F3EEA0AA64756E2164756E21
37916
37976
  //# sourceMappingURL=cli.js.map