@secondlayer/sdk 10.6.0 → 12.0.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
@@ -412,7 +412,9 @@ Exported types: `TransactionProof`, `TransactionProofVerifyResult`, `RewardSet`.
412
412
 
413
413
  Deploy and query app-specific tables.
414
414
 
415
- Subgraphs and webhooks live on the instance API alongside Streams and Index. Everything here except `rows` and the typed `subscribe` calls `/api`, which needs `INSTANCE_TOKEN` once one is configured (init always configures one), loopback included.
415
+ Subgraphs and webhooks live on the instance API alongside Streams and Index. Reads (`rows`, `count`, `aggregate`, typed `findMany`/`count`/`aggregate`, and `subscribe`) all hit the open `/v1` surface — keyless on loopback, `INSTANCE_TOKEN` once the API is bound beyond it. Everything else here (deploy, status, ops) calls `/api`, which needs `INSTANCE_TOKEN` once one is configured (init always configures one), loopback included.
416
+
417
+ `/v1` paginates by cursor, not offset: `rows`/`count`/`aggregate` take no `offset` param — pass the previous page's `next_cursor` back as `cursor` to resume.
416
418
 
417
419
  ```typescript
418
420
  // List
@@ -421,25 +423,18 @@ const { data } = await sl.subgraphs.list();
421
423
  // Get
422
424
  const subgraph = await sl.subgraphs.status("my-subgraph");
423
425
 
424
- // Open read (/v1): keyless on loopback; needs the token once the API is bound beyond it
426
+ // Untyped row read (/v1)
425
427
  const { rows, next_cursor, tip } = await sl.subgraphs.rows("my-subgraph", "transfers", {
428
+ sort: "block_height",
426
429
  order: "desc",
427
430
  limit: 50,
428
431
  // cursor: next_cursor — pass back to resume
429
432
  });
430
433
 
431
- // Authed control-plane query (/api)
432
- const page = await sl.subgraphs.queryTable("my-subgraph", "transfers", {
433
- sort: "block_height",
434
- order: "desc",
435
- limit: 50,
434
+ const { count } = await sl.subgraphs.count("my-subgraph", "transfers", {
435
+ filters: { status: "active" },
436
436
  });
437
437
 
438
- const { count } = await sl.subgraphs.queryTableCount(
439
- "my-subgraph",
440
- "transfers",
441
- );
442
-
443
438
  const spec = await sl.subgraphs.openapi("my-subgraph");
444
439
  const source = await sl.subgraphs.getSource("my-subgraph");
445
440
  const gaps = await sl.subgraphs.gaps("my-subgraph");
@@ -455,11 +450,22 @@ system column only when your table declares no column of that name; a declared
455
450
  `id` column is always your `id`.
456
451
 
457
452
  Stream rows live with the typed client — each table exposes `subscribe`
458
- alongside `findMany`/`count`:
453
+ alongside `findMany`/`count`/`aggregate`:
459
454
 
460
455
  ```typescript
461
456
  const subgraph = sl.subgraphs.typed(myDefinition); // { transfers, ... }
462
457
 
458
+ // findMany returns a page, not a bare array — `nextCursor` resumes it.
459
+ // `orderBy` sorts one column only (the /v1 keyset cursor pairs it with `_id`
460
+ // as a tiebreaker); a second key throws.
461
+ const page = await subgraph.transfers.findMany({
462
+ where: { amount: { gte: "1000000" } },
463
+ orderBy: { blockHeight: "desc" },
464
+ limit: 50,
465
+ // cursor: page.nextCursor — pass back to resume
466
+ });
467
+ // page.rows, page.nextCursor, page.tip
468
+
463
469
  const unsubscribe = subgraph.transfers.subscribe(
464
470
  (row) => console.log(row),
465
471
  {
package/dist/index.d.ts CHANGED
@@ -234,8 +234,7 @@ declare function resolveBaseUrl(explicit?: string): string;
234
234
  * env vars. Guarded for browsers and edge runtimes. */
235
235
  declare function resolveApiKey(apiKey?: string): string | undefined;
236
236
  /** Resolve the hosted account key for archive quote/fetch/credits.
237
- * Precedence: explicit `accountKey` → `SECONDLAYER_API_KEY` → `SL_API_KEY` /
238
- * `SL_ARCHIVE_API_KEY` (one-release warn-fallbacks). Does not read
237
+ * Precedence: explicit `accountKey` → `SECONDLAYER_API_KEY`. Does not read
239
238
  * `INSTANCE_TOKEN`. */
240
239
  declare function resolveAccountKey(accountKey?: string): string | undefined;
241
240
  declare abstract class BaseClient {
@@ -2589,7 +2588,7 @@ declare class Subgraphs extends BaseClient {
2589
2588
  * pass an apiKey on the client where reads are closed. Resume with the
2590
2589
  * returned `next_cursor`.
2591
2590
  */
2592
- rows<T = unknown>(name: string, table: string, params?: Omit<SubgraphQueryParams, "offset" | "sort"> & {
2591
+ rows<T = unknown>(name: string, table: string, params?: Omit<SubgraphQueryParams, "offset"> & {
2593
2592
  cursor?: string;
2594
2593
  }): Promise<SubgraphRowsEnvelope<T>>;
2595
2594
  /** Recent reindex/backfill operations for a subgraph, newest first. */
@@ -2611,11 +2610,14 @@ declare class Subgraphs extends BaseClient {
2611
2610
  bundle(data: {
2612
2611
  code: string;
2613
2612
  }): Promise<BundleSubgraphResponse>;
2614
- queryTable(name: string, table: string, params?: SubgraphQueryParams): Promise<unknown[]>;
2615
- queryTableCount(name: string, table: string, params?: SubgraphQueryParams): Promise<{
2613
+ /** Open /v1 read: exact row count for a filtered set. Same auth posture as
2614
+ * {@link rows}. */
2615
+ count(name: string, table: string, params?: Pick<SubgraphQueryParams, "filters">): Promise<{
2616
2616
  count: number;
2617
2617
  }>;
2618
- queryTableAggregate(name: string, table: string, params?: SubgraphAggregateParams): Promise<SubgraphAggregateResponse>;
2618
+ /** Open /v1 read: scalar aggregates over a filtered set. Same auth posture
2619
+ * as {@link rows}. */
2620
+ aggregate(name: string, table: string, params?: SubgraphAggregateParams): Promise<SubgraphAggregateResponse>;
2619
2621
  /**
2620
2622
  * Returns a typed client for a subgraph defined with `defineSubgraph()`.
2621
2623
  * Row types are inferred from the subgraph's schema literal types.
@@ -2624,8 +2626,9 @@ declare class Subgraphs extends BaseClient {
2624
2626
  * ```ts
2625
2627
  * import mySubgraph from './subgraphs/my-token-subgraph'
2626
2628
  * const client = sl.subgraphs.typed(mySubgraph)
2627
- * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })
2628
- * // rows: InferTableRow<typeof mySubgraph.schema.transfers>[]
2629
+ * const page = await client.transfers.findMany({ where: { sender: 'SP...' } })
2630
+ * // page.rows: InferTableRow<typeof mySubgraph.schema.transfers>[]
2631
+ * // page.nextCursor: string | null — pass back as `cursor` to resume
2629
2632
  * ```
2630
2633
  */
2631
2634
  typed<T extends {
@@ -2777,7 +2780,7 @@ import { InferSubgraphClient as InferSubgraphClient2 } from "@secondlayer/subgra
2777
2780
  * import { getSubgraph } from '@secondlayer/sdk'
2778
2781
  *
2779
2782
  * const client = getSubgraph(mySubgraph, { apiKey: 'sl_...' })
2780
- * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })
2783
+ * const page = await client.transfers.findMany({ where: { sender: 'SP...' } })
2781
2784
  * ```
2782
2785
  */
2783
2786
  declare function getSubgraph<T extends {
package/dist/index.js CHANGED
@@ -205,7 +205,6 @@ function raceAbort(promise, signal) {
205
205
  var LOCAL_API_URL = "http://127.0.0.1:3800";
206
206
  var INSTANCE_TOKEN_ENV = "INSTANCE_TOKEN";
207
207
  var ACCOUNT_KEY_ENV = "SECONDLAYER_API_KEY";
208
- var warnedUrlAlias = false;
209
208
  function resolveBaseUrl(explicit) {
210
209
  if (explicit && explicit.length > 0)
211
210
  return explicit.replace(/\/+$/, "");
@@ -213,14 +212,6 @@ function resolveBaseUrl(explicit) {
213
212
  const primary = process.env?.SECONDLAYER_API_URL || undefined;
214
213
  if (primary)
215
214
  return primary.replace(/\/+$/, "");
216
- const legacy = process.env?.SL_API_URL || undefined;
217
- if (legacy) {
218
- if (!warnedUrlAlias) {
219
- warnedUrlAlias = true;
220
- console.warn("[secondlayer] SL_API_URL is a legacy alias of SECONDLAYER_API_URL; using the alias this once.");
221
- }
222
- return legacy.replace(/\/+$/, "");
223
- }
224
215
  }
225
216
  return LOCAL_API_URL;
226
217
  }
@@ -232,26 +223,12 @@ function resolveApiKey(apiKey) {
232
223
  const token = process.env?.INSTANCE_TOKEN || undefined;
233
224
  return token;
234
225
  }
235
- var warnedArchiveAlias = false;
236
226
  function resolveAccountKey(accountKey) {
237
227
  if (accountKey !== undefined)
238
228
  return accountKey;
239
229
  if (typeof process === "undefined")
240
230
  return;
241
- const primary = process.env?.SECONDLAYER_API_KEY || undefined;
242
- const slAlias = process.env?.SL_API_KEY || undefined;
243
- const archiveAlias = process.env?.SL_ARCHIVE_API_KEY || undefined;
244
- if (primary)
245
- return primary;
246
- const legacy = slAlias ?? archiveAlias;
247
- if (legacy) {
248
- if (!warnedArchiveAlias) {
249
- warnedArchiveAlias = true;
250
- console.warn("[secondlayer] SL_API_KEY / SL_ARCHIVE_API_KEY are legacy aliases of SECONDLAYER_API_KEY; using the alias this once.");
251
- }
252
- return legacy;
253
- }
254
- return;
231
+ return process.env?.SECONDLAYER_API_KEY || undefined;
255
232
  }
256
233
  function seg(value) {
257
234
  return encodeURIComponent(String(value));
@@ -2317,7 +2294,6 @@ function buildSubgraphQueryString(params) {
2317
2294
  _sort: params.sort,
2318
2295
  _order: params.order,
2319
2296
  _limit: params.limit,
2320
- _offset: params.offset,
2321
2297
  _fields: params.fields,
2322
2298
  ...params.filters
2323
2299
  });
@@ -2395,15 +2371,11 @@ class Subgraphs extends BaseClient {
2395
2371
  async bundle(data) {
2396
2372
  return this.request("POST", "/api/subgraphs/bundle", data);
2397
2373
  }
2398
- async queryTable(name, table, params = {}) {
2399
- const result = await this.request("GET", `/api/subgraphs/${seg(name)}/${seg(table)}${buildSubgraphQueryString(params)}`);
2400
- return Array.isArray(result) ? result : result.data;
2401
- }
2402
- async queryTableCount(name, table, params = {}) {
2403
- return this.request("GET", `/api/subgraphs/${seg(name)}/${seg(table)}/count${buildSubgraphQueryString(params)}`);
2374
+ async count(name, table, params = {}) {
2375
+ return this.request("GET", `/v1/subgraphs/${seg(name)}/${seg(table)}/count${buildSubgraphQueryString(params)}`);
2404
2376
  }
2405
- async queryTableAggregate(name, table, params = {}) {
2406
- return this.request("GET", `/api/subgraphs/${seg(name)}/${seg(table)}/aggregate${buildAggregateQueryString(params)}`);
2377
+ async aggregate(name, table, params = {}) {
2378
+ return this.request("GET", `/v1/subgraphs/${seg(name)}/${seg(table)}/aggregate${buildAggregateQueryString(params)}`);
2407
2379
  }
2408
2380
  typed(def) {
2409
2381
  const result = {};
@@ -2420,32 +2392,41 @@ class Subgraphs extends BaseClient {
2420
2392
  let sort;
2421
2393
  let order;
2422
2394
  if (options.orderBy) {
2423
- const entries = Array.isArray(options.orderBy) ? options.orderBy : Object.entries(options.orderBy);
2424
- if (entries.length > 0) {
2425
- sort = entries.map(([col]) => resolveOrderByColumn(col, columns)).join(",");
2426
- order = entries.map(([, dir]) => dir ?? "asc").join(",");
2395
+ const entries = Object.entries(options.orderBy);
2396
+ if (entries.length > 1) {
2397
+ throw new Error(`findMany orderBy accepts a single column; got ${entries.length}: ${entries.map(([col]) => col).join(", ")}. Sort one column — the cursor pairs it with _id as a tiebreaker.`);
2398
+ }
2399
+ const entry = entries[0];
2400
+ if (entry) {
2401
+ const [col, dir] = entry;
2402
+ sort = resolveOrderByColumn(col, columns);
2403
+ order = dir ?? "asc";
2427
2404
  }
2428
2405
  }
2429
- const params = {
2406
+ const result = await self.rows(subgraphName, tableName, {
2430
2407
  sort,
2431
2408
  order,
2432
2409
  limit: options.limit,
2433
- offset: options.offset,
2434
2410
  fields: options.fields?.join(","),
2435
- filters
2411
+ filters,
2412
+ cursor: options.cursor
2413
+ });
2414
+ return {
2415
+ rows: result.rows,
2416
+ nextCursor: result.next_cursor,
2417
+ tip: result.tip
2436
2418
  };
2437
- return self.queryTable(subgraphName, tableName, params);
2438
2419
  },
2439
2420
  async count(where) {
2440
2421
  const filters = where ? serializeWhere(where, columns) : undefined;
2441
- const result = await self.queryTableCount(subgraphName, tableName, {
2422
+ const result = await self.count(subgraphName, tableName, {
2442
2423
  filters
2443
2424
  });
2444
2425
  return result.count;
2445
2426
  },
2446
2427
  async aggregate(spec) {
2447
2428
  const filters = spec.where ? serializeWhere(spec.where, columns) : undefined;
2448
- const result = await self.queryTableAggregate(subgraphName, tableName, {
2429
+ const result = await self.aggregate(subgraphName, tableName, {
2449
2430
  filters,
2450
2431
  count: spec.count,
2451
2432
  countDistinct: spec.countDistinct,
@@ -2982,5 +2963,5 @@ export {
2982
2963
  verifyWebhookSignature
2983
2964
  };
2984
2965
 
2985
- //# debugId=92280D2ABC3CFA6364756E2164756E21
2966
+ //# debugId=758CC74B9A5D6A8064756E2164756E21
2986
2967
  //# sourceMappingURL=index.js.map