@secondlayer/sdk 6.20.0 → 6.21.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.
@@ -273,150 +273,6 @@ declare class Contracts extends BaseClient {
273
273
  includeAbi?: boolean
274
274
  }): Promise<ContractSummary | null>;
275
275
  }
276
- /**
277
- * Typed client for the Foundation Datasets REST API (`/v1/datasets/*`).
278
- *
279
- * Most datasets are cursor-paginated event lists with a uniform `list`/`walk`
280
- * surface; a few (bns names/namespaces/resolve, network-health) are
281
- * offset/single-object/summary and get bespoke methods. Query params are typed
282
- * per dataset; rows are `DatasetRow` (JSON) in v1 — per-dataset row interfaces
283
- * are a fast-follow.
284
- */
285
- /** A dataset row — flat JSON object. Per-dataset interfaces are a follow-up. */
286
- type DatasetRow = Record<string, unknown>;
287
- /** Filters shared by every cursor-paginated dataset. */
288
- interface CursorListParams {
289
- cursor?: string;
290
- limit?: number;
291
- fromBlock?: number;
292
- toBlock?: number;
293
- }
294
- interface CursorEnvelope {
295
- rows: DatasetRow[];
296
- next_cursor: string | null;
297
- tip?: {
298
- block_height: number
299
- };
300
- }
301
- type RangeFilters = CursorListParams;
302
- type StxTransfersParams = RangeFilters & {
303
- sender?: string
304
- recipient?: string
305
- };
306
- type SbtcEventsParams = RangeFilters & {
307
- topic?: string
308
- address?: string
309
- };
310
- type SbtcTokenEventsParams = RangeFilters & {
311
- eventType?: string
312
- sender?: string
313
- recipient?: string
314
- };
315
- type Pox4CallsParams = RangeFilters & {
316
- functionName?: string
317
- stacker?: string
318
- delegateTo?: string
319
- signerKey?: string
320
- rewardCycle?: number
321
- /** Any-role: matches caller OR stacker OR delegate_to. */
322
- address?: string
323
- };
324
- type BurnchainRewardsParams = RangeFilters & {
325
- /** Filter to one Bitcoin reward address. */
326
- recipient?: string
327
- };
328
- type BurnchainRewardSlotsParams = RangeFilters & {
329
- /** Filter to one reward-set Bitcoin address. */
330
- holder?: string
331
- };
332
- type BnsEventsParams = RangeFilters & {
333
- topic?: string
334
- namespace?: string
335
- name?: string
336
- owner?: string
337
- };
338
- type BnsNamespaceEventsParams = RangeFilters & {
339
- status?: string
340
- namespace?: string
341
- };
342
- type BnsMarketplaceEventsParams = RangeFilters & {
343
- action?: string
344
- bnsId?: string
345
- };
346
- type CursorDataset<P> = {
347
- list: (params?: P) => Promise<CursorEnvelope>
348
- walk: (params?: P & {
349
- batchSize?: number
350
- signal?: AbortSignal
351
- }) => AsyncIterable<DatasetRow>
352
- };
353
- declare class Datasets extends BaseClient {
354
- private catalogPromise?;
355
- constructor(options?: Partial<SecondLayerOptions>);
356
- /** Dataset catalog + freshness (the discovery endpoint). */
357
- listDatasets(): Promise<unknown>;
358
- /**
359
- * Generic read by slug for ANY catalog dataset — cursor or bespoke. Resolves
360
- * the slug against the live `/v1/datasets` catalog (so datasets added
361
- * server-side work with no SDK change), issues the GET, and normalizes the
362
- * response into a uniform `{ rows, next_cursor, tip }` envelope. Single-object
363
- * datasets (bns/resolve, network-health/summary) come back as 0-or-1 rows.
364
- * Accepts both family (`sbtc-events`) and path (`sbtc/events`) slug forms.
365
- * Prefer this over {@link query} unless you specifically need cursor-only
366
- * semantics.
367
- */
368
- get(slug: string, params?: Record<string, unknown>): Promise<CursorEnvelope>;
369
- /**
370
- * Generic cursor query by slug — used by the CLI. Params are passed through as
371
- * REST query keys (snake_case), so callers can use the documented filter names
372
- * directly. Throws for non-cursor (bespoke) datasets — use {@link get} for
373
- * those (and for slugs added to the catalog after this SDK was built).
374
- */
375
- query(slug: string, params?: Record<string, unknown>): Promise<CursorEnvelope>;
376
- readonly stxTransfers: CursorDataset<StxTransfersParams>;
377
- readonly sbtcEvents: CursorDataset<SbtcEventsParams>;
378
- readonly sbtcTokenEvents: CursorDataset<SbtcTokenEventsParams>;
379
- readonly pox4Calls: CursorDataset<Pox4CallsParams>;
380
- readonly burnchainRewards: CursorDataset<BurnchainRewardsParams>;
381
- readonly burnchainRewardSlots: CursorDataset<BurnchainRewardSlotsParams>;
382
- readonly bnsEvents: CursorDataset<BnsEventsParams>;
383
- readonly bnsNamespaceEvents: CursorDataset<BnsNamespaceEventsParams>;
384
- readonly bnsMarketplaceEvents: CursorDataset<BnsMarketplaceEventsParams>;
385
- /** BNS names — offset-paginated. */
386
- bnsNames(params?: {
387
- namespace?: string
388
- owner?: string
389
- limit?: number
390
- offset?: number
391
- }): Promise<{
392
- names: DatasetRow[]
393
- }>;
394
- /** All BNS namespaces (no pagination). */
395
- bnsNamespaces(): Promise<{
396
- namespaces: DatasetRow[]
397
- }>;
398
- /** Resolve a fully-qualified BNS name → single record. */
399
- bnsResolve(fqn: string): Promise<{
400
- name: DatasetRow | null
401
- }>;
402
- /** Network health summary. */
403
- networkHealth(): Promise<{
404
- summary: DatasetRow
405
- }>;
406
- private requestPath;
407
- /** Resolve a slug → relative path + row key. Known cursor slugs take a
408
- * network-free fast path; anything else is matched against the live catalog
409
- * by family name or path tail. */
410
- private resolveDataset;
411
- /** Fetch + cache the catalog families. Caches the in-flight promise so
412
- * concurrent first-calls share one request; no TTL — agent sessions are
413
- * short-lived, and a new client picks up newly added datasets. */
414
- private loadCatalog;
415
- /** Map camelCase filter fields to snake_case query keys (dropping pagination
416
- * controls) and build the canonical query suffix. */
417
- private paramsToQuery;
418
- private cursorDataset;
419
- }
420
276
  import { RewardSet } from "@secondlayer/shared/node/consensus";
421
277
  import { MerkleProofStep } from "@secondlayer/shared/node/nakamoto";
422
278
  /**
@@ -1643,7 +1499,6 @@ interface ContextSnapshot {
1643
1499
  declare class SecondLayer extends BaseClient {
1644
1500
  readonly streams: StreamsClient;
1645
1501
  readonly index: Index;
1646
- readonly datasets: Datasets;
1647
1502
  readonly contracts: Contracts;
1648
1503
  readonly subgraphs: Subgraphs;
1649
1504
  readonly subscriptions: Subscriptions;
@@ -1655,6 +1510,21 @@ declare class SecondLayer extends BaseClient {
1655
1510
  * from `secondlayer://context`, but available to any SDK/CLI consumer. Reads
1656
1511
  * run concurrently and degrade to `null` per field on failure.
1657
1512
  */
1513
+ /**
1514
+ * Up to 10 public reads in one round trip (`POST /v1/batch`). Each item
1515
+ * keeps its own auth/quota/x402 semantics; forwarded credentials (API key,
1516
+ * PAYMENT-BALANCE/SESSION) apply to every item.
1517
+ */
1518
+ batch(requests: Array<{
1519
+ path: string
1520
+ params?: Record<string, string | number | boolean>
1521
+ }>): Promise<{
1522
+ results: Array<{
1523
+ path: string | null
1524
+ status: number
1525
+ body: unknown
1526
+ }>
1527
+ }>;
1658
1528
  context(): Promise<ContextSnapshot>;
1659
1529
  }
1660
1530
  /**
@@ -442,164 +442,6 @@ class Contracts extends BaseClient {
442
442
  }
443
443
  }
444
444
 
445
- // src/datasets/client.ts
446
- var PARAM_KEYS = {
447
- fromBlock: "from_block",
448
- toBlock: "to_block",
449
- functionName: "function_name",
450
- delegateTo: "delegate_to",
451
- signerKey: "signer_key",
452
- rewardCycle: "reward_cycle",
453
- eventType: "event_type",
454
- bnsId: "bns_id"
455
- };
456
- var CURSOR_SLUGS = {
457
- "stx-transfers": { path: "stx-transfers", rowKey: "events" },
458
- "sbtc-events": { path: "sbtc/events", rowKey: "events" },
459
- "sbtc-token-events": { path: "sbtc/token-events", rowKey: "events" },
460
- "pox-4-calls": { path: "pox-4/calls", rowKey: "calls" },
461
- "burnchain-rewards": { path: "burnchain/rewards", rowKey: "rewards" },
462
- "burnchain-reward-slots": {
463
- path: "burnchain/reward-slots",
464
- rowKey: "slots"
465
- },
466
- "bns-events": { path: "bns/events", rowKey: "events" },
467
- "bns-namespace-events": { path: "bns/namespace-events", rowKey: "events" },
468
- "bns-marketplace-events": {
469
- path: "bns/marketplace-events",
470
- rowKey: "events"
471
- }
472
- };
473
- function catalogPathTail(path) {
474
- return path.replace(/^\/?v1\/datasets\//, "").replace(/^\/+/, "");
475
- }
476
-
477
- class Datasets extends BaseClient {
478
- catalogPromise;
479
- constructor(options = {}) {
480
- super(options);
481
- }
482
- listDatasets() {
483
- return this.request("GET", "/v1/datasets");
484
- }
485
- async get(slug, params = {}) {
486
- const { path, rowKey } = await this.resolveDataset(slug);
487
- const env = await this.requestPath(path, this.paramsToQuery(params));
488
- const value = env[rowKey];
489
- const rows = Array.isArray(value) ? value : value == null ? [] : [value];
490
- return {
491
- rows,
492
- next_cursor: env.next_cursor ?? null,
493
- tip: env.tip
494
- };
495
- }
496
- async query(slug, params = {}) {
497
- const d = CURSOR_SLUGS[slug];
498
- if (!d) {
499
- throw new Error(`unknown cursor dataset "${slug}" (use one of: ${Object.keys(CURSOR_SLUGS).join(", ")})`);
500
- }
501
- const env = await this.requestPath(d.path, this.paramsToQuery(params));
502
- return {
503
- rows: env[d.rowKey] ?? [],
504
- next_cursor: env.next_cursor ?? null,
505
- tip: env.tip
506
- };
507
- }
508
- stxTransfers = this.cursorDataset("stx-transfers", "events");
509
- sbtcEvents = this.cursorDataset("sbtc/events", "events");
510
- sbtcTokenEvents = this.cursorDataset("sbtc/token-events", "events");
511
- pox4Calls = this.cursorDataset("pox-4/calls", "calls");
512
- burnchainRewards = this.cursorDataset("burnchain/rewards", "rewards");
513
- burnchainRewardSlots = this.cursorDataset("burnchain/reward-slots", "slots");
514
- bnsEvents = this.cursorDataset("bns/events", "events");
515
- bnsNamespaceEvents = this.cursorDataset("bns/namespace-events", "events");
516
- bnsMarketplaceEvents = this.cursorDataset("bns/marketplace-events", "events");
517
- bnsNames(params = {}) {
518
- return this.requestPath("bns/names", buildQuery({
519
- namespace: params.namespace,
520
- owner: params.owner,
521
- limit: params.limit,
522
- offset: params.offset
523
- }));
524
- }
525
- bnsNamespaces() {
526
- return this.requestPath("bns/namespaces", "");
527
- }
528
- bnsResolve(fqn) {
529
- return this.requestPath("bns/resolve", buildQuery({ fqn }));
530
- }
531
- networkHealth() {
532
- return this.requestPath("network-health/summary", "");
533
- }
534
- requestPath(path, query) {
535
- return this.request("GET", `/v1/datasets/${path}${query}`);
536
- }
537
- async resolveDataset(slug) {
538
- const cursor = CURSOR_SLUGS[slug];
539
- if (cursor)
540
- return { path: cursor.path, rowKey: cursor.rowKey };
541
- const families = await this.loadCatalog();
542
- const tail = catalogPathTail(slug);
543
- const match = families.find((f) => f.family === slug || catalogPathTail(f.path) === tail);
544
- if (!match) {
545
- throw new Error(`unknown dataset "${slug}" (available: ${families.map((f) => f.family).join(", ")})`);
546
- }
547
- return { path: catalogPathTail(match.path), rowKey: match.row_key };
548
- }
549
- loadCatalog() {
550
- this.catalogPromise ??= (async () => {
551
- const raw = await this.listDatasets();
552
- const families = raw.families;
553
- if (!Array.isArray(families)) {
554
- throw new Error("dataset catalog response missing families[]");
555
- }
556
- return families;
557
- })();
558
- return this.catalogPromise;
559
- }
560
- paramsToQuery(params) {
561
- const mapped = {};
562
- for (const [k, v] of Object.entries(params)) {
563
- if (v === undefined || v === null || k === "batchSize" || k === "signal")
564
- continue;
565
- mapped[PARAM_KEYS[k] ?? k] = v;
566
- }
567
- return buildQuery(mapped);
568
- }
569
- cursorDataset(path, rowKey) {
570
- const list = async (params = {}) => {
571
- const envelope = await this.requestPath(path, this.paramsToQuery(params));
572
- return {
573
- rows: envelope[rowKey] ?? [],
574
- next_cursor: envelope.next_cursor ?? null,
575
- tip: envelope.tip
576
- };
577
- };
578
- const walk = async function* (params = {}) {
579
- const batchSize = params.batchSize ?? 200;
580
- let cursor = params.cursor ?? null;
581
- let first = true;
582
- while (!params.signal?.aborted) {
583
- const env = await list({
584
- ...params,
585
- limit: batchSize,
586
- cursor: first ? params.cursor : cursor ?? undefined
587
- });
588
- for (const row of env.rows) {
589
- if (params.signal?.aborted)
590
- return;
591
- yield row;
592
- }
593
- if (!env.next_cursor || env.next_cursor === cursor || env.rows.length < batchSize)
594
- return;
595
- cursor = env.next_cursor;
596
- first = false;
597
- }
598
- }.bind(this);
599
- return { list, walk };
600
- }
601
- }
602
-
603
445
  // src/index-api/client.ts
604
446
  function firstWalkFromHeight(params) {
605
447
  if (params.fromHeight !== undefined)
@@ -1771,7 +1613,6 @@ class Subscriptions extends BaseClient {
1771
1613
  class SecondLayer extends BaseClient {
1772
1614
  streams;
1773
1615
  index;
1774
- datasets;
1775
1616
  contracts;
1776
1617
  subgraphs;
1777
1618
  subscriptions;
@@ -1786,13 +1627,15 @@ class SecondLayer extends BaseClient {
1786
1627
  dumpsBaseUrl: options.dumpsBaseUrl
1787
1628
  });
1788
1629
  this.index = new Index(options);
1789
- this.datasets = new Datasets(options);
1790
1630
  this.contracts = new Contracts(options);
1791
1631
  this.subgraphs = new Subgraphs(options);
1792
1632
  this.subscriptions = new Subscriptions(options);
1793
1633
  this.apiKeys = new ApiKeys(options);
1794
1634
  this.projects = new Projects(options);
1795
1635
  }
1636
+ async batch(requests) {
1637
+ return this.request("POST", "/v1/batch", { requests });
1638
+ }
1796
1639
  async context() {
1797
1640
  const safe = (p) => p.then((v) => v).catch(() => null);
1798
1641
  const [
@@ -1875,5 +1718,5 @@ export {
1875
1718
  Subgraphs
1876
1719
  };
1877
1720
 
1878
- //# debugId=DD9EE9C3CECE53B564756E2164756E21
1721
+ //# debugId=0E36F58DBAA5692064756E2164756E21
1879
1722
  //# sourceMappingURL=index.js.map