@secondlayer/sdk 6.19.0 → 6.21.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.
@@ -52,6 +52,16 @@ interface SubgraphOperationStatus {
52
52
  createdAt: string;
53
53
  updatedAt: string;
54
54
  }
55
+ /** /v1 cursor envelope for subgraph table reads. */
56
+ interface SubgraphRowsEnvelope<T = unknown> {
57
+ rows: T[];
58
+ next_cursor: string | null;
59
+ tip: {
60
+ block_height: number
61
+ subgraph_height: number
62
+ blocks_behind: number
63
+ };
64
+ }
55
65
  interface BundleSubgraphResponse {
56
66
  ok: true;
57
67
  name: string;
@@ -94,6 +104,29 @@ declare class Subgraphs extends BaseClient {
94
104
  }): Promise<{
95
105
  message: string
96
106
  }>;
107
+ /**
108
+ * Publish: claim the name in the global public namespace and open anon
109
+ * reads on /v1/subgraphs/:name. 409 PUBLIC_NAME_TAKEN if another account
110
+ * holds the public name.
111
+ */
112
+ publish(name: string): Promise<{
113
+ name: string
114
+ visibility: "public"
115
+ url: string
116
+ }>;
117
+ /** Make reads private again (owning account's bearer key required). */
118
+ unpublish(name: string): Promise<{
119
+ name: string
120
+ visibility: "private"
121
+ }>;
122
+ /**
123
+ * Open /v1 read: cursor-paginated rows. Anon works for public subgraphs;
124
+ * pass an apiKey on the client for private ones. Resume with the returned
125
+ * `next_cursor`.
126
+ */
127
+ rows<T = unknown>(name: string, table: string, params?: Omit<SubgraphQueryParams, "offset" | "sort"> & {
128
+ cursor?: string
129
+ }): Promise<SubgraphRowsEnvelope<T>>;
97
130
  /** Recent reindex/backfill operations for a subgraph, newest first. */
98
131
  operations(name: string): Promise<{
99
132
  operations: SubgraphOperationStatus[]
@@ -240,150 +273,6 @@ declare class Contracts extends BaseClient {
240
273
  includeAbi?: boolean
241
274
  }): Promise<ContractSummary | null>;
242
275
  }
243
- /**
244
- * Typed client for the Foundation Datasets REST API (`/v1/datasets/*`).
245
- *
246
- * Most datasets are cursor-paginated event lists with a uniform `list`/`walk`
247
- * surface; a few (bns names/namespaces/resolve, network-health) are
248
- * offset/single-object/summary and get bespoke methods. Query params are typed
249
- * per dataset; rows are `DatasetRow` (JSON) in v1 — per-dataset row interfaces
250
- * are a fast-follow.
251
- */
252
- /** A dataset row — flat JSON object. Per-dataset interfaces are a follow-up. */
253
- type DatasetRow = Record<string, unknown>;
254
- /** Filters shared by every cursor-paginated dataset. */
255
- interface CursorListParams {
256
- cursor?: string;
257
- limit?: number;
258
- fromBlock?: number;
259
- toBlock?: number;
260
- }
261
- interface CursorEnvelope {
262
- rows: DatasetRow[];
263
- next_cursor: string | null;
264
- tip?: {
265
- block_height: number
266
- };
267
- }
268
- type RangeFilters = CursorListParams;
269
- type StxTransfersParams = RangeFilters & {
270
- sender?: string
271
- recipient?: string
272
- };
273
- type SbtcEventsParams = RangeFilters & {
274
- topic?: string
275
- address?: string
276
- };
277
- type SbtcTokenEventsParams = RangeFilters & {
278
- eventType?: string
279
- sender?: string
280
- recipient?: string
281
- };
282
- type Pox4CallsParams = RangeFilters & {
283
- functionName?: string
284
- stacker?: string
285
- delegateTo?: string
286
- signerKey?: string
287
- rewardCycle?: number
288
- /** Any-role: matches caller OR stacker OR delegate_to. */
289
- address?: string
290
- };
291
- type BurnchainRewardsParams = RangeFilters & {
292
- /** Filter to one Bitcoin reward address. */
293
- recipient?: string
294
- };
295
- type BurnchainRewardSlotsParams = RangeFilters & {
296
- /** Filter to one reward-set Bitcoin address. */
297
- holder?: string
298
- };
299
- type BnsEventsParams = RangeFilters & {
300
- topic?: string
301
- namespace?: string
302
- name?: string
303
- owner?: string
304
- };
305
- type BnsNamespaceEventsParams = RangeFilters & {
306
- status?: string
307
- namespace?: string
308
- };
309
- type BnsMarketplaceEventsParams = RangeFilters & {
310
- action?: string
311
- bnsId?: string
312
- };
313
- type CursorDataset<P> = {
314
- list: (params?: P) => Promise<CursorEnvelope>
315
- walk: (params?: P & {
316
- batchSize?: number
317
- signal?: AbortSignal
318
- }) => AsyncIterable<DatasetRow>
319
- };
320
- declare class Datasets extends BaseClient {
321
- private catalogPromise?;
322
- constructor(options?: Partial<SecondLayerOptions>);
323
- /** Dataset catalog + freshness (the discovery endpoint). */
324
- listDatasets(): Promise<unknown>;
325
- /**
326
- * Generic read by slug for ANY catalog dataset — cursor or bespoke. Resolves
327
- * the slug against the live `/v1/datasets` catalog (so datasets added
328
- * server-side work with no SDK change), issues the GET, and normalizes the
329
- * response into a uniform `{ rows, next_cursor, tip }` envelope. Single-object
330
- * datasets (bns/resolve, network-health/summary) come back as 0-or-1 rows.
331
- * Accepts both family (`sbtc-events`) and path (`sbtc/events`) slug forms.
332
- * Prefer this over {@link query} unless you specifically need cursor-only
333
- * semantics.
334
- */
335
- get(slug: string, params?: Record<string, unknown>): Promise<CursorEnvelope>;
336
- /**
337
- * Generic cursor query by slug — used by the CLI. Params are passed through as
338
- * REST query keys (snake_case), so callers can use the documented filter names
339
- * directly. Throws for non-cursor (bespoke) datasets — use {@link get} for
340
- * those (and for slugs added to the catalog after this SDK was built).
341
- */
342
- query(slug: string, params?: Record<string, unknown>): Promise<CursorEnvelope>;
343
- readonly stxTransfers: CursorDataset<StxTransfersParams>;
344
- readonly sbtcEvents: CursorDataset<SbtcEventsParams>;
345
- readonly sbtcTokenEvents: CursorDataset<SbtcTokenEventsParams>;
346
- readonly pox4Calls: CursorDataset<Pox4CallsParams>;
347
- readonly burnchainRewards: CursorDataset<BurnchainRewardsParams>;
348
- readonly burnchainRewardSlots: CursorDataset<BurnchainRewardSlotsParams>;
349
- readonly bnsEvents: CursorDataset<BnsEventsParams>;
350
- readonly bnsNamespaceEvents: CursorDataset<BnsNamespaceEventsParams>;
351
- readonly bnsMarketplaceEvents: CursorDataset<BnsMarketplaceEventsParams>;
352
- /** BNS names — offset-paginated. */
353
- bnsNames(params?: {
354
- namespace?: string
355
- owner?: string
356
- limit?: number
357
- offset?: number
358
- }): Promise<{
359
- names: DatasetRow[]
360
- }>;
361
- /** All BNS namespaces (no pagination). */
362
- bnsNamespaces(): Promise<{
363
- namespaces: DatasetRow[]
364
- }>;
365
- /** Resolve a fully-qualified BNS name → single record. */
366
- bnsResolve(fqn: string): Promise<{
367
- name: DatasetRow | null
368
- }>;
369
- /** Network health summary. */
370
- networkHealth(): Promise<{
371
- summary: DatasetRow
372
- }>;
373
- private requestPath;
374
- /** Resolve a slug → relative path + row key. Known cursor slugs take a
375
- * network-free fast path; anything else is matched against the live catalog
376
- * by family name or path tail. */
377
- private resolveDataset;
378
- /** Fetch + cache the catalog families. Caches the in-flight promise so
379
- * concurrent first-calls share one request; no TTL — agent sessions are
380
- * short-lived, and a new client picks up newly added datasets. */
381
- private loadCatalog;
382
- /** Map camelCase filter fields to snake_case query keys (dropping pagination
383
- * controls) and build the canonical query suffix. */
384
- private paramsToQuery;
385
- private cursorDataset;
386
- }
387
276
  import { RewardSet } from "@secondlayer/shared/node/consensus";
388
277
  import { MerkleProofStep } from "@secondlayer/shared/node/nakamoto";
389
278
  /**
@@ -920,6 +809,30 @@ type MempoolWalkParams = Omit<MempoolListParams, "limit"> & {
920
809
  batchSize?: number
921
810
  signal?: AbortSignal
922
811
  };
812
+ /**
813
+ * `index.ftTransfers` — callable shorthand for `.list()`, with `.list`/`.walk`
814
+ * still available: `await sl.index.ftTransfers({ contractId })`.
815
+ *
816
+ * The API accepts `contract_id`/`sender`/`recipient` equality filters only —
817
+ * no amount filtering and no asset-slug resolution on /v1/index/ft-transfers.
818
+ */
819
+ interface FtTransfersResource {
820
+ (params?: FtTransfersListParams): Promise<FtTransfersEnvelope>;
821
+ list(params?: FtTransfersListParams): Promise<FtTransfersEnvelope>;
822
+ walk(params?: FtTransfersWalkParams): AsyncIterable<FtTransfer>;
823
+ }
824
+ /** `index.nftTransfers` — callable shorthand for `.list()` (see {@link FtTransfersResource}). */
825
+ interface NftTransfersResource {
826
+ (params?: NftTransfersListParams): Promise<NftTransfersEnvelope>;
827
+ list(params?: NftTransfersListParams): Promise<NftTransfersEnvelope>;
828
+ walk(params?: NftTransfersWalkParams): AsyncIterable<NftTransfer>;
829
+ }
830
+ /** `index.events` — callable shorthand for `.list()`; `eventType` is required. */
831
+ interface IndexEventsResource {
832
+ (params: EventsListParams): Promise<EventsEnvelope>;
833
+ list(params: EventsListParams): Promise<EventsEnvelope>;
834
+ walk(params: EventsWalkParams): AsyncIterable<IndexEvent>;
835
+ }
923
836
  /** Per-event-type filter vocabulary in the {@link IndexDiscovery} doc. */
924
837
  type IndexEventTypeFilters = {
925
838
  columns?: string[]
@@ -944,19 +857,13 @@ declare class Index extends BaseClient {
944
857
  * learn what's queryable (and which types accept `trait`) instead of hardcoding.
945
858
  */
946
859
  discover(): Promise<IndexDiscovery>;
947
- readonly ftTransfers: {
948
- list: (params?: FtTransfersListParams) => Promise<FtTransfersEnvelope>
949
- walk: (params?: FtTransfersWalkParams) => AsyncIterable<FtTransfer>
950
- };
951
- readonly nftTransfers: {
952
- list: (params?: NftTransfersListParams) => Promise<NftTransfersEnvelope>
953
- walk: (params?: NftTransfersWalkParams) => AsyncIterable<NftTransfer>
954
- };
955
- /** Generic decoded events by `event_type` (the full /v1/index/events surface). */
956
- readonly events: {
957
- list: (params: EventsListParams) => Promise<EventsEnvelope>
958
- walk: (params: EventsWalkParams) => AsyncIterable<IndexEvent>
959
- };
860
+ /** Callable: `index.ftTransfers(params)` ≡ `index.ftTransfers.list(params)`. */
861
+ readonly ftTransfers: FtTransfersResource;
862
+ /** Callable: `index.nftTransfers(params)` ≡ `index.nftTransfers.list(params)`. */
863
+ readonly nftTransfers: NftTransfersResource;
864
+ /** Generic decoded events by `event_type` (the full /v1/index/events surface).
865
+ * Callable: `index.events(params)` ≡ `index.events.list(params)`. */
866
+ readonly events: IndexEventsResource;
960
867
  readonly contractCalls: {
961
868
  list: (params?: ContractCallsListParams) => Promise<ContractCallsEnvelope>
962
869
  walk: (params?: ContractCallsWalkParams) => AsyncIterable<IndexContractCall>
@@ -1338,6 +1245,36 @@ type StreamsEventsConsumeParams = {
1338
1245
  maxEmptyPolls?: number
1339
1246
  signal?: AbortSignal
1340
1247
  };
1248
+ /**
1249
+ * One yielded page from {@link StreamsClient.consume} — the
1250
+ * `GET /v1/streams/events` envelope verbatim, with `next_cursor` renamed to
1251
+ * `cursor` (the checkpoint to persist and resume from).
1252
+ */
1253
+ type StreamsBatch = {
1254
+ /** Canonical events of this page, in cursor order. */
1255
+ events: StreamsEvent[]
1256
+ /** Checkpoint after this page — pass back as `consume({ cursor })` to resume. */
1257
+ cursor: string | null
1258
+ tip: StreamsTip
1259
+ /** Chain reorgs reported alongside this page; empty when none. */
1260
+ reorgs: StreamsReorg[]
1261
+ };
1262
+ type StreamsConsumeParams = {
1263
+ /** Resume strictly after this cursor; omit to start from the oldest seekable page. */
1264
+ cursor?: string | null
1265
+ types?: readonly StreamsEventType[]
1266
+ notTypes?: readonly StreamsEventType[]
1267
+ contractId?: StreamsFilterValue
1268
+ sender?: StreamsFilterValue
1269
+ recipient?: StreamsFilterValue
1270
+ assetIdentifier?: string
1271
+ /** Events per page (the `limit` query param). Default 100. */
1272
+ batchSize?: number
1273
+ /** Poll interval while caught up at the tip, in ms. Default 2000. */
1274
+ intervalMs?: number
1275
+ /** Abort to end the iteration. */
1276
+ signal?: AbortSignal
1277
+ };
1341
1278
  type StreamsEventsConsumeResult = {
1342
1279
  cursor: string | null
1343
1280
  pages: number
@@ -1405,6 +1342,21 @@ type StreamsDumps = {
1405
1342
  download(file: StreamsDumpFile): Promise<Uint8Array>
1406
1343
  };
1407
1344
  type StreamsClient = {
1345
+ /**
1346
+ * Follow Streams as an async iterator of page batches.
1347
+ *
1348
+ * Yields one {@link StreamsBatch} per `GET /v1/streams/events` page — the
1349
+ * existing envelope (`events`, `next_cursor` → `cursor`, `tip`, `reorgs`)
1350
+ * with zero extra API calls. Batches are chosen over per-block groupings
1351
+ * because the envelope is page-keyed, so every yield is exactly one fetch.
1352
+ * Empty pages are skipped; at the tip the iterator re-polls every
1353
+ * `intervalMs` (default 2000) until aborted via `signal`.
1354
+ *
1355
+ * Reorgs are surfaced on the batch (`batch.reorgs`) but the cursor is not
1356
+ * rewound automatically — use `events.consume` with `onReorg` for managed
1357
+ * rollback semantics.
1358
+ */
1359
+ consume(params?: StreamsConsumeParams): AsyncIterableIterator<StreamsBatch>
1408
1360
  events: {
1409
1361
  list(params?: StreamsEventsListParams): Promise<StreamsEventsEnvelope>
1410
1362
  byTxId(txId: string): Promise<StreamsEventsListEnvelope>
@@ -1547,7 +1499,6 @@ interface ContextSnapshot {
1547
1499
  declare class SecondLayer extends BaseClient {
1548
1500
  readonly streams: StreamsClient;
1549
1501
  readonly index: Index;
1550
- readonly datasets: Datasets;
1551
1502
  readonly contracts: Contracts;
1552
1503
  readonly subgraphs: Subgraphs;
1553
1504
  readonly subscriptions: Subscriptions;
@@ -1559,6 +1510,21 @@ declare class SecondLayer extends BaseClient {
1559
1510
  * from `secondlayer://context`, but available to any SDK/CLI consumer. Reads
1560
1511
  * run concurrently and degrade to `null` per field on failure.
1561
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
+ }>;
1562
1528
  context(): Promise<ContextSnapshot>;
1563
1529
  }
1564
1530
  /**
@@ -281,6 +281,19 @@ class Subgraphs extends BaseClient {
281
281
  const qs = options?.force ? "?force=true" : "";
282
282
  return this.request("DELETE", `/api/subgraphs/${name}${qs}`);
283
283
  }
284
+ async publish(name) {
285
+ return this.request("POST", `/api/subgraphs/${name}/publish`);
286
+ }
287
+ async unpublish(name) {
288
+ return this.request("POST", `/api/subgraphs/${name}/unpublish`);
289
+ }
290
+ async rows(name, table, params = {}) {
291
+ const { cursor, ...rest } = params;
292
+ const qs = buildSubgraphQueryString(rest);
293
+ const sep = qs ? "&" : "?";
294
+ const cursorQs = cursor ? `${sep}cursor=${encodeURIComponent(cursor)}` : "";
295
+ return this.request("GET", `/v1/subgraphs/${name}/${table}${qs}${cursorQs}`);
296
+ }
284
297
  async operations(name) {
285
298
  return this.request("GET", `/api/subgraphs/${name}/operations`);
286
299
  }
@@ -429,164 +442,6 @@ class Contracts extends BaseClient {
429
442
  }
430
443
  }
431
444
 
432
- // src/datasets/client.ts
433
- var PARAM_KEYS = {
434
- fromBlock: "from_block",
435
- toBlock: "to_block",
436
- functionName: "function_name",
437
- delegateTo: "delegate_to",
438
- signerKey: "signer_key",
439
- rewardCycle: "reward_cycle",
440
- eventType: "event_type",
441
- bnsId: "bns_id"
442
- };
443
- var CURSOR_SLUGS = {
444
- "stx-transfers": { path: "stx-transfers", rowKey: "events" },
445
- "sbtc-events": { path: "sbtc/events", rowKey: "events" },
446
- "sbtc-token-events": { path: "sbtc/token-events", rowKey: "events" },
447
- "pox-4-calls": { path: "pox-4/calls", rowKey: "calls" },
448
- "burnchain-rewards": { path: "burnchain/rewards", rowKey: "rewards" },
449
- "burnchain-reward-slots": {
450
- path: "burnchain/reward-slots",
451
- rowKey: "slots"
452
- },
453
- "bns-events": { path: "bns/events", rowKey: "events" },
454
- "bns-namespace-events": { path: "bns/namespace-events", rowKey: "events" },
455
- "bns-marketplace-events": {
456
- path: "bns/marketplace-events",
457
- rowKey: "events"
458
- }
459
- };
460
- function catalogPathTail(path) {
461
- return path.replace(/^\/?v1\/datasets\//, "").replace(/^\/+/, "");
462
- }
463
-
464
- class Datasets extends BaseClient {
465
- catalogPromise;
466
- constructor(options = {}) {
467
- super(options);
468
- }
469
- listDatasets() {
470
- return this.request("GET", "/v1/datasets");
471
- }
472
- async get(slug, params = {}) {
473
- const { path, rowKey } = await this.resolveDataset(slug);
474
- const env = await this.requestPath(path, this.paramsToQuery(params));
475
- const value = env[rowKey];
476
- const rows = Array.isArray(value) ? value : value == null ? [] : [value];
477
- return {
478
- rows,
479
- next_cursor: env.next_cursor ?? null,
480
- tip: env.tip
481
- };
482
- }
483
- async query(slug, params = {}) {
484
- const d = CURSOR_SLUGS[slug];
485
- if (!d) {
486
- throw new Error(`unknown cursor dataset "${slug}" (use one of: ${Object.keys(CURSOR_SLUGS).join(", ")})`);
487
- }
488
- const env = await this.requestPath(d.path, this.paramsToQuery(params));
489
- return {
490
- rows: env[d.rowKey] ?? [],
491
- next_cursor: env.next_cursor ?? null,
492
- tip: env.tip
493
- };
494
- }
495
- stxTransfers = this.cursorDataset("stx-transfers", "events");
496
- sbtcEvents = this.cursorDataset("sbtc/events", "events");
497
- sbtcTokenEvents = this.cursorDataset("sbtc/token-events", "events");
498
- pox4Calls = this.cursorDataset("pox-4/calls", "calls");
499
- burnchainRewards = this.cursorDataset("burnchain/rewards", "rewards");
500
- burnchainRewardSlots = this.cursorDataset("burnchain/reward-slots", "slots");
501
- bnsEvents = this.cursorDataset("bns/events", "events");
502
- bnsNamespaceEvents = this.cursorDataset("bns/namespace-events", "events");
503
- bnsMarketplaceEvents = this.cursorDataset("bns/marketplace-events", "events");
504
- bnsNames(params = {}) {
505
- return this.requestPath("bns/names", buildQuery({
506
- namespace: params.namespace,
507
- owner: params.owner,
508
- limit: params.limit,
509
- offset: params.offset
510
- }));
511
- }
512
- bnsNamespaces() {
513
- return this.requestPath("bns/namespaces", "");
514
- }
515
- bnsResolve(fqn) {
516
- return this.requestPath("bns/resolve", buildQuery({ fqn }));
517
- }
518
- networkHealth() {
519
- return this.requestPath("network-health/summary", "");
520
- }
521
- requestPath(path, query) {
522
- return this.request("GET", `/v1/datasets/${path}${query}`);
523
- }
524
- async resolveDataset(slug) {
525
- const cursor = CURSOR_SLUGS[slug];
526
- if (cursor)
527
- return { path: cursor.path, rowKey: cursor.rowKey };
528
- const families = await this.loadCatalog();
529
- const tail = catalogPathTail(slug);
530
- const match = families.find((f) => f.family === slug || catalogPathTail(f.path) === tail);
531
- if (!match) {
532
- throw new Error(`unknown dataset "${slug}" (available: ${families.map((f) => f.family).join(", ")})`);
533
- }
534
- return { path: catalogPathTail(match.path), rowKey: match.row_key };
535
- }
536
- loadCatalog() {
537
- this.catalogPromise ??= (async () => {
538
- const raw = await this.listDatasets();
539
- const families = raw.families;
540
- if (!Array.isArray(families)) {
541
- throw new Error("dataset catalog response missing families[]");
542
- }
543
- return families;
544
- })();
545
- return this.catalogPromise;
546
- }
547
- paramsToQuery(params) {
548
- const mapped = {};
549
- for (const [k, v] of Object.entries(params)) {
550
- if (v === undefined || v === null || k === "batchSize" || k === "signal")
551
- continue;
552
- mapped[PARAM_KEYS[k] ?? k] = v;
553
- }
554
- return buildQuery(mapped);
555
- }
556
- cursorDataset(path, rowKey) {
557
- const list = async (params = {}) => {
558
- const envelope = await this.requestPath(path, this.paramsToQuery(params));
559
- return {
560
- rows: envelope[rowKey] ?? [],
561
- next_cursor: envelope.next_cursor ?? null,
562
- tip: envelope.tip
563
- };
564
- };
565
- const walk = async function* (params = {}) {
566
- const batchSize = params.batchSize ?? 200;
567
- let cursor = params.cursor ?? null;
568
- let first = true;
569
- while (!params.signal?.aborted) {
570
- const env = await list({
571
- ...params,
572
- limit: batchSize,
573
- cursor: first ? params.cursor : cursor ?? undefined
574
- });
575
- for (const row of env.rows) {
576
- if (params.signal?.aborted)
577
- return;
578
- yield row;
579
- }
580
- if (!env.next_cursor || env.next_cursor === cursor || env.rows.length < batchSize)
581
- return;
582
- cursor = env.next_cursor;
583
- first = false;
584
- }
585
- }.bind(this);
586
- return { list, walk };
587
- }
588
- }
589
-
590
445
  // src/index-api/client.ts
591
446
  function firstWalkFromHeight(params) {
592
447
  if (params.fromHeight !== undefined)
@@ -606,18 +461,18 @@ class Index extends BaseClient {
606
461
  discover() {
607
462
  return this.request("GET", "/v1/index");
608
463
  }
609
- ftTransfers = {
464
+ ftTransfers = Object.assign((params = {}) => this.listFtTransfers(params), {
610
465
  list: (params = {}) => this.listFtTransfers(params),
611
466
  walk: (params = {}) => this.walkFtTransfers(params)
612
- };
613
- nftTransfers = {
467
+ });
468
+ nftTransfers = Object.assign((params = {}) => this.listNftTransfers(params), {
614
469
  list: (params = {}) => this.listNftTransfers(params),
615
470
  walk: (params = {}) => this.walkNftTransfers(params)
616
- };
617
- events = {
471
+ });
472
+ events = Object.assign((params) => this.listEvents(params), {
618
473
  list: (params) => this.listEvents(params),
619
474
  walk: (params) => this.walkEvents(params)
620
- };
475
+ });
621
476
  contractCalls = {
622
477
  list: (params = {}) => this.listContractCalls(params),
623
478
  walk: (params = {}) => this.walkContractCalls(params)
@@ -1182,6 +1037,38 @@ async function consumeStreamsEvents(opts) {
1182
1037
  }
1183
1038
  return { cursor, pages, emptyPolls };
1184
1039
  }
1040
+ async function* iterateStreamsBatches(opts) {
1041
+ const sleep = opts.sleep ?? defaultSleep;
1042
+ let cursor = opts.fromCursor ?? null;
1043
+ while (!opts.signal?.aborted) {
1044
+ const envelope = await opts.fetchEvents({
1045
+ cursor,
1046
+ limit: opts.batchSize,
1047
+ types: opts.types,
1048
+ notTypes: opts.notTypes,
1049
+ contractId: opts.contractId,
1050
+ sender: opts.sender,
1051
+ recipient: opts.recipient,
1052
+ assetIdentifier: opts.assetIdentifier
1053
+ });
1054
+ const checkpoint = envelope.next_cursor ?? cursor;
1055
+ if (envelope.events.length > 0 || envelope.reorgs.length > 0) {
1056
+ yield {
1057
+ events: envelope.events,
1058
+ cursor: checkpoint,
1059
+ tip: envelope.tip,
1060
+ reorgs: envelope.reorgs
1061
+ };
1062
+ }
1063
+ const advanced = checkpoint !== null && checkpoint !== cursor;
1064
+ cursor = checkpoint;
1065
+ if (!advanced && envelope.events.length === 0) {
1066
+ if (opts.signal?.aborted)
1067
+ return;
1068
+ await sleep(opts.intervalMs, opts.signal);
1069
+ }
1070
+ }
1071
+ }
1185
1072
  async function* streamStreamsEvents(opts) {
1186
1073
  const sleep = opts.sleep ?? defaultSleep;
1187
1074
  const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
@@ -1559,6 +1446,21 @@ function createStreamsClient(options) {
1559
1446
  })}`);
1560
1447
  }
1561
1448
  return {
1449
+ consume(params = {}) {
1450
+ return iterateStreamsBatches({
1451
+ fromCursor: params.cursor,
1452
+ batchSize: params.batchSize ?? 100,
1453
+ intervalMs: params.intervalMs ?? 2000,
1454
+ types: params.types,
1455
+ notTypes: params.notTypes,
1456
+ contractId: params.contractId,
1457
+ sender: params.sender,
1458
+ recipient: params.recipient,
1459
+ assetIdentifier: params.assetIdentifier,
1460
+ signal: params.signal,
1461
+ fetchEvents
1462
+ });
1463
+ },
1562
1464
  events: {
1563
1465
  list: listEvents,
1564
1466
  byTxId(txId) {
@@ -1711,7 +1613,6 @@ class Subscriptions extends BaseClient {
1711
1613
  class SecondLayer extends BaseClient {
1712
1614
  streams;
1713
1615
  index;
1714
- datasets;
1715
1616
  contracts;
1716
1617
  subgraphs;
1717
1618
  subscriptions;
@@ -1726,13 +1627,15 @@ class SecondLayer extends BaseClient {
1726
1627
  dumpsBaseUrl: options.dumpsBaseUrl
1727
1628
  });
1728
1629
  this.index = new Index(options);
1729
- this.datasets = new Datasets(options);
1730
1630
  this.contracts = new Contracts(options);
1731
1631
  this.subgraphs = new Subgraphs(options);
1732
1632
  this.subscriptions = new Subscriptions(options);
1733
1633
  this.apiKeys = new ApiKeys(options);
1734
1634
  this.projects = new Projects(options);
1735
1635
  }
1636
+ async batch(requests) {
1637
+ return this.request("POST", "/v1/batch", { requests });
1638
+ }
1736
1639
  async context() {
1737
1640
  const safe = (p) => p.then((v) => v).catch(() => null);
1738
1641
  const [
@@ -1815,5 +1718,5 @@ export {
1815
1718
  Subgraphs
1816
1719
  };
1817
1720
 
1818
- //# debugId=7ABB6E8514AEA9F664756E2164756E21
1721
+ //# debugId=0E36F58DBAA5692064756E2164756E21
1819
1722
  //# sourceMappingURL=index.js.map