@secondlayer/sdk 6.0.0 → 6.2.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.
@@ -25,6 +25,19 @@ class VersionConflictError extends ApiError {
25
25
 
26
26
  // src/base.ts
27
27
  var DEFAULT_BASE_URL = "https://api.secondlayer.tools";
28
+ function buildQuery(params) {
29
+ const search = new URLSearchParams;
30
+ for (const [name, value] of Object.entries(params)) {
31
+ if (value === undefined || value === null)
32
+ continue;
33
+ const serialized = Array.isArray(value) ? value.join(",") : String(value);
34
+ if (serialized.length === 0)
35
+ continue;
36
+ search.set(name, serialized);
37
+ }
38
+ const query = search.toString();
39
+ return query ? `?${query}` : "";
40
+ }
28
41
 
29
42
  class BaseClient {
30
43
  baseUrl;
@@ -311,12 +324,143 @@ class Subgraphs extends BaseClient {
311
324
  };
312
325
  }
313
326
  }
314
- // src/index-api/client.ts
315
- function appendSearchParam(params, name, value) {
316
- if (value === undefined || value === null)
317
- return;
318
- params.set(name, String(value));
327
+ // src/contracts/client.ts
328
+ class Contracts extends BaseClient {
329
+ constructor(options = {}) {
330
+ super(options);
331
+ }
332
+ list(params) {
333
+ return this.request("GET", `/v1/contracts${buildQuery({
334
+ trait: params.trait,
335
+ conformance: params.conformance,
336
+ include: params.include,
337
+ limit: params.limit,
338
+ cursor: params.cursor
339
+ })}`);
340
+ }
341
+ }
342
+
343
+ // src/datasets/client.ts
344
+ var PARAM_KEYS = {
345
+ fromBlock: "from_block",
346
+ toBlock: "to_block",
347
+ functionName: "function_name",
348
+ delegateTo: "delegate_to",
349
+ signerKey: "signer_key",
350
+ rewardCycle: "reward_cycle",
351
+ eventType: "event_type",
352
+ bnsId: "bns_id"
353
+ };
354
+ var CURSOR_SLUGS = {
355
+ "stx-transfers": { path: "stx-transfers", rowKey: "events" },
356
+ "sbtc-events": { path: "sbtc/events", rowKey: "events" },
357
+ "sbtc-token-events": { path: "sbtc/token-events", rowKey: "events" },
358
+ "pox-4-calls": { path: "pox-4/calls", rowKey: "calls" },
359
+ "burnchain-rewards": { path: "burnchain/rewards", rowKey: "rewards" },
360
+ "burnchain-reward-slots": {
361
+ path: "burnchain/reward-slots",
362
+ rowKey: "slots"
363
+ },
364
+ "bns-events": { path: "bns/events", rowKey: "events" },
365
+ "bns-namespace-events": { path: "bns/namespace-events", rowKey: "events" },
366
+ "bns-marketplace-events": {
367
+ path: "bns/marketplace-events",
368
+ rowKey: "events"
369
+ }
370
+ };
371
+
372
+ class Datasets extends BaseClient {
373
+ constructor(options = {}) {
374
+ super(options);
375
+ }
376
+ listDatasets() {
377
+ return this.request("GET", "/v1/datasets");
378
+ }
379
+ async query(slug, params = {}) {
380
+ const d = CURSOR_SLUGS[slug];
381
+ if (!d) {
382
+ throw new Error(`unknown cursor dataset "${slug}" (use one of: ${Object.keys(CURSOR_SLUGS).join(", ")})`);
383
+ }
384
+ const env = await this.get(d.path, this.paramsToQuery(params));
385
+ return {
386
+ rows: env[d.rowKey] ?? [],
387
+ next_cursor: env.next_cursor ?? null,
388
+ tip: env.tip
389
+ };
390
+ }
391
+ stxTransfers = this.cursorDataset("stx-transfers", "events");
392
+ sbtcEvents = this.cursorDataset("sbtc/events", "events");
393
+ sbtcTokenEvents = this.cursorDataset("sbtc/token-events", "events");
394
+ pox4Calls = this.cursorDataset("pox-4/calls", "calls");
395
+ burnchainRewards = this.cursorDataset("burnchain/rewards", "rewards");
396
+ burnchainRewardSlots = this.cursorDataset("burnchain/reward-slots", "slots");
397
+ bnsEvents = this.cursorDataset("bns/events", "events");
398
+ bnsNamespaceEvents = this.cursorDataset("bns/namespace-events", "events");
399
+ bnsMarketplaceEvents = this.cursorDataset("bns/marketplace-events", "events");
400
+ bnsNames(params = {}) {
401
+ return this.get("bns/names", buildQuery({
402
+ namespace: params.namespace,
403
+ owner: params.owner,
404
+ limit: params.limit,
405
+ offset: params.offset
406
+ }));
407
+ }
408
+ bnsNamespaces() {
409
+ return this.get("bns/namespaces", "");
410
+ }
411
+ bnsResolve(fqn) {
412
+ return this.get("bns/resolve", buildQuery({ fqn }));
413
+ }
414
+ networkHealth() {
415
+ return this.get("network-health/summary", "");
416
+ }
417
+ get(path, query) {
418
+ return this.request("GET", `/v1/datasets/${path}${query}`);
419
+ }
420
+ paramsToQuery(params) {
421
+ const mapped = {};
422
+ for (const [k, v] of Object.entries(params)) {
423
+ if (v === undefined || v === null || k === "batchSize" || k === "signal")
424
+ continue;
425
+ mapped[PARAM_KEYS[k] ?? k] = v;
426
+ }
427
+ return buildQuery(mapped);
428
+ }
429
+ cursorDataset(path, rowKey) {
430
+ const list = async (params = {}) => {
431
+ const envelope = await this.get(path, this.paramsToQuery(params));
432
+ return {
433
+ rows: envelope[rowKey] ?? [],
434
+ next_cursor: envelope.next_cursor ?? null,
435
+ tip: envelope.tip
436
+ };
437
+ };
438
+ const walk = async function* (params = {}) {
439
+ const batchSize = params.batchSize ?? 200;
440
+ let cursor = params.cursor ?? null;
441
+ let first = true;
442
+ while (!params.signal?.aborted) {
443
+ const env = await list({
444
+ ...params,
445
+ limit: batchSize,
446
+ cursor: first ? params.cursor : cursor ?? undefined
447
+ });
448
+ for (const row of env.rows) {
449
+ if (params.signal?.aborted)
450
+ return;
451
+ yield row;
452
+ }
453
+ if (!env.next_cursor || env.next_cursor === cursor || env.rows.length < batchSize)
454
+ return;
455
+ cursor = env.next_cursor;
456
+ first = false;
457
+ }
458
+ }.bind(this);
459
+ return { list, walk };
460
+ }
319
461
  }
462
+
463
+ // src/index-api/client.ts
320
464
  function firstWalkFromHeight(params) {
321
465
  if (params.fromHeight !== undefined)
322
466
  return params.fromHeight;
@@ -346,31 +490,29 @@ class Index extends BaseClient {
346
490
  walk: (params = {}) => this.walkContractCalls(params)
347
491
  };
348
492
  async listFtTransfers(params = {}) {
349
- const searchParams = new URLSearchParams;
350
- appendSearchParam(searchParams, "cursor", params.cursor);
351
- appendSearchParam(searchParams, "from_cursor", params.fromCursor);
352
- appendSearchParam(searchParams, "limit", params.limit);
353
- appendSearchParam(searchParams, "contract_id", params.contractId);
354
- appendSearchParam(searchParams, "sender", params.sender);
355
- appendSearchParam(searchParams, "recipient", params.recipient);
356
- appendSearchParam(searchParams, "from_height", params.fromHeight);
357
- appendSearchParam(searchParams, "to_height", params.toHeight);
358
- const query = searchParams.toString();
359
- return this.request("GET", `/v1/index/ft-transfers${query ? `?${query}` : ""}`);
493
+ return this.request("GET", `/v1/index/ft-transfers${buildQuery({
494
+ cursor: params.cursor,
495
+ from_cursor: params.fromCursor,
496
+ limit: params.limit,
497
+ contract_id: params.contractId,
498
+ sender: params.sender,
499
+ recipient: params.recipient,
500
+ from_height: params.fromHeight,
501
+ to_height: params.toHeight
502
+ })}`);
360
503
  }
361
504
  async listNftTransfers(params = {}) {
362
- const searchParams = new URLSearchParams;
363
- appendSearchParam(searchParams, "cursor", params.cursor);
364
- appendSearchParam(searchParams, "from_cursor", params.fromCursor);
365
- appendSearchParam(searchParams, "limit", params.limit);
366
- appendSearchParam(searchParams, "contract_id", params.contractId);
367
- appendSearchParam(searchParams, "asset_identifier", params.assetIdentifier);
368
- appendSearchParam(searchParams, "sender", params.sender);
369
- appendSearchParam(searchParams, "recipient", params.recipient);
370
- appendSearchParam(searchParams, "from_height", params.fromHeight);
371
- appendSearchParam(searchParams, "to_height", params.toHeight);
372
- const query = searchParams.toString();
373
- return this.request("GET", `/v1/index/nft-transfers${query ? `?${query}` : ""}`);
505
+ return this.request("GET", `/v1/index/nft-transfers${buildQuery({
506
+ cursor: params.cursor,
507
+ from_cursor: params.fromCursor,
508
+ limit: params.limit,
509
+ contract_id: params.contractId,
510
+ asset_identifier: params.assetIdentifier,
511
+ sender: params.sender,
512
+ recipient: params.recipient,
513
+ from_height: params.fromHeight,
514
+ to_height: params.toHeight
515
+ })}`);
374
516
  }
375
517
  async* walkFtTransfers(params = {}) {
376
518
  const batchSize = params.batchSize ?? 200;
@@ -423,18 +565,18 @@ class Index extends BaseClient {
423
565
  }
424
566
  }
425
567
  async listEvents(params) {
426
- const searchParams = new URLSearchParams;
427
- appendSearchParam(searchParams, "event_type", params.eventType);
428
- appendSearchParam(searchParams, "cursor", params.cursor);
429
- appendSearchParam(searchParams, "from_cursor", params.fromCursor);
430
- appendSearchParam(searchParams, "limit", params.limit);
431
- appendSearchParam(searchParams, "contract_id", params.contractId);
432
- appendSearchParam(searchParams, "asset_identifier", params.assetIdentifier);
433
- appendSearchParam(searchParams, "sender", params.sender);
434
- appendSearchParam(searchParams, "recipient", params.recipient);
435
- appendSearchParam(searchParams, "from_height", params.fromHeight);
436
- appendSearchParam(searchParams, "to_height", params.toHeight);
437
- return this.request("GET", `/v1/index/events?${searchParams.toString()}`);
568
+ return this.request("GET", `/v1/index/events${buildQuery({
569
+ event_type: params.eventType,
570
+ cursor: params.cursor,
571
+ from_cursor: params.fromCursor,
572
+ limit: params.limit,
573
+ contract_id: params.contractId,
574
+ asset_identifier: params.assetIdentifier,
575
+ sender: params.sender,
576
+ recipient: params.recipient,
577
+ from_height: params.fromHeight,
578
+ to_height: params.toHeight
579
+ })}`);
438
580
  }
439
581
  async* walkEvents(params) {
440
582
  const batchSize = params.batchSize ?? 200;
@@ -462,17 +604,16 @@ class Index extends BaseClient {
462
604
  }
463
605
  }
464
606
  async listContractCalls(params = {}) {
465
- const searchParams = new URLSearchParams;
466
- appendSearchParam(searchParams, "cursor", params.cursor);
467
- appendSearchParam(searchParams, "from_cursor", params.fromCursor);
468
- appendSearchParam(searchParams, "limit", params.limit);
469
- appendSearchParam(searchParams, "contract_id", params.contractId);
470
- appendSearchParam(searchParams, "function_name", params.functionName);
471
- appendSearchParam(searchParams, "sender", params.sender);
472
- appendSearchParam(searchParams, "from_height", params.fromHeight);
473
- appendSearchParam(searchParams, "to_height", params.toHeight);
474
- const query = searchParams.toString();
475
- return this.request("GET", `/v1/index/contract-calls${query ? `?${query}` : ""}`);
607
+ return this.request("GET", `/v1/index/contract-calls${buildQuery({
608
+ cursor: params.cursor,
609
+ from_cursor: params.fromCursor,
610
+ limit: params.limit,
611
+ contract_id: params.contractId,
612
+ function_name: params.functionName,
613
+ sender: params.sender,
614
+ from_height: params.fromHeight,
615
+ to_height: params.toHeight
616
+ })}`);
476
617
  }
477
618
  async* walkContractCalls(params = {}) {
478
619
  const batchSize = params.batchSize ?? 200;
@@ -504,7 +645,74 @@ class Index extends BaseClient {
504
645
  // src/streams/client.ts
505
646
  import { ed25519 } from "@secondlayer/shared";
506
647
 
648
+ // src/streams/errors.ts
649
+ class AuthError extends Error {
650
+ status = 401;
651
+ constructor(message = "API key invalid or expired.") {
652
+ super(message);
653
+ this.name = "AuthError";
654
+ }
655
+ }
656
+
657
+ class RateLimitError extends Error {
658
+ retryAfter;
659
+ status = 429;
660
+ constructor(message = "Rate limited. Try again later.", retryAfter) {
661
+ super(message);
662
+ this.retryAfter = retryAfter;
663
+ this.name = "RateLimitError";
664
+ }
665
+ }
666
+
667
+ class ValidationError extends Error {
668
+ status;
669
+ body;
670
+ constructor(message, status, body) {
671
+ super(message);
672
+ this.status = status;
673
+ this.body = body;
674
+ this.name = "ValidationError";
675
+ }
676
+ }
677
+
678
+ class StreamsServerError extends Error {
679
+ status;
680
+ body;
681
+ constructor(message, status, body) {
682
+ super(message);
683
+ this.status = status;
684
+ this.body = body;
685
+ this.name = "StreamsServerError";
686
+ }
687
+ }
688
+
689
+ class StreamsSignatureError extends Error {
690
+ constructor(message = "Streams response signature verification failed.") {
691
+ super(message);
692
+ this.name = "StreamsSignatureError";
693
+ }
694
+ }
695
+
696
+ // src/streams/cursor.ts
697
+ var Cursor = {
698
+ atHeight(height) {
699
+ return `${height}:0`;
700
+ },
701
+ parse(cursor) {
702
+ const parts = cursor.split(":");
703
+ const blockHeight = Number(parts[0]);
704
+ const eventIndex = Number(parts[1]);
705
+ if (parts.length !== 2 || !Number.isInteger(blockHeight) || !Number.isInteger(eventIndex)) {
706
+ throw new ValidationError(`Invalid stream cursor "${cursor}"; expected "<block>:<index>" (e.g. "951475:3").`, 400);
707
+ }
708
+ return { blockHeight, eventIndex };
709
+ }
710
+ };
711
+
507
712
  // src/streams/consumer.ts
713
+ function reorgKey(reorg) {
714
+ return `${reorg.detected_at}|${reorg.fork_point_height}|${reorg.new_canonical_tip}`;
715
+ }
508
716
  async function defaultSleep(ms, signal) {
509
717
  if (signal?.aborted)
510
718
  return;
@@ -521,10 +729,12 @@ async function defaultSleep(ms, signal) {
521
729
  async function consumeStreamsEvents(opts) {
522
730
  const sleep = opts.sleep ?? defaultSleep;
523
731
  const mode = opts.mode ?? "tail";
732
+ const finalizedOnly = opts.finalizedOnly ?? false;
524
733
  const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
525
734
  const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
526
735
  const maxEmptyPolls = opts.maxEmptyPolls ?? Number.POSITIVE_INFINITY;
527
736
  let cursor = opts.fromCursor ?? null;
737
+ const handledReorgs = new Set;
528
738
  let pages = 0;
529
739
  let emptyPolls = 0;
530
740
  while (pages < maxPages && emptyPolls < maxEmptyPolls && !opts.signal?.aborted) {
@@ -539,14 +749,32 @@ async function consumeStreamsEvents(opts) {
539
749
  assetIdentifier: opts.assetIdentifier
540
750
  });
541
751
  pages++;
542
- const returnedCursor = await opts.onBatch(envelope.events, envelope);
543
- const nextCursor = returnedCursor ?? envelope.next_cursor;
752
+ if (!finalizedOnly && opts.onReorg) {
753
+ const fresh = envelope.reorgs.filter((reorg) => !handledReorgs.has(reorgKey(reorg))).sort((a, b) => a.fork_point_height - b.fork_point_height);
754
+ if (fresh.length > 0) {
755
+ const forkPoint = Math.min(...fresh.map((reorg) => reorg.fork_point_height));
756
+ const rewind = Cursor.atHeight(forkPoint);
757
+ for (const reorg of fresh) {
758
+ await opts.onReorg(reorg, { cursor: rewind });
759
+ handledReorgs.add(reorgKey(reorg));
760
+ }
761
+ cursor = rewind;
762
+ emptyPolls = 0;
763
+ continue;
764
+ }
765
+ }
766
+ const emitted = finalizedOnly ? envelope.events.filter((event) => event.finalized) : envelope.events;
767
+ const checkpoint = finalizedOnly ? emitted.at(-1)?.cursor ?? cursor : envelope.next_cursor;
768
+ const returnedCursor = await opts.onBatch(emitted, envelope, {
769
+ cursor: checkpoint
770
+ });
771
+ const nextCursor = returnedCursor ?? checkpoint;
544
772
  if (nextCursor && nextCursor !== cursor) {
545
773
  cursor = nextCursor;
546
774
  emptyPolls = 0;
547
775
  continue;
548
776
  }
549
- if (envelope.events.length === 0) {
777
+ if (emitted.length === 0) {
550
778
  emptyPolls++;
551
779
  if (mode === "bounded") {
552
780
  return { cursor, pages, emptyPolls };
@@ -602,56 +830,6 @@ async function* streamStreamsEvents(opts) {
602
830
 
603
831
  // src/streams/dumps.ts
604
832
  import { createHash } from "node:crypto";
605
-
606
- // src/streams/errors.ts
607
- class AuthError extends Error {
608
- status = 401;
609
- constructor(message = "API key invalid or expired.") {
610
- super(message);
611
- this.name = "AuthError";
612
- }
613
- }
614
-
615
- class RateLimitError extends Error {
616
- retryAfter;
617
- status = 429;
618
- constructor(message = "Rate limited. Try again later.", retryAfter) {
619
- super(message);
620
- this.retryAfter = retryAfter;
621
- this.name = "RateLimitError";
622
- }
623
- }
624
-
625
- class ValidationError extends Error {
626
- status;
627
- body;
628
- constructor(message, status, body) {
629
- super(message);
630
- this.status = status;
631
- this.body = body;
632
- this.name = "ValidationError";
633
- }
634
- }
635
-
636
- class StreamsServerError extends Error {
637
- status;
638
- body;
639
- constructor(message, status, body) {
640
- super(message);
641
- this.status = status;
642
- this.body = body;
643
- this.name = "StreamsServerError";
644
- }
645
- }
646
-
647
- class StreamsSignatureError extends Error {
648
- constructor(message = "Streams response signature verification failed.") {
649
- super(message);
650
- this.name = "StreamsSignatureError";
651
- }
652
- }
653
-
654
- // src/streams/dumps.ts
655
833
  function createStreamsDumps(opts) {
656
834
  const baseUrl = opts.baseUrl?.replace(/\/+$/, "");
657
835
  function requireBaseUrl() {
@@ -690,8 +868,12 @@ function createStreamsDumps(opts) {
690
868
  function cursorTuple(cursor) {
691
869
  if (!cursor)
692
870
  return [-1, -1];
693
- const [block, index] = cursor.split(":");
694
- return [Number(block), Number(index)];
871
+ const parts = cursor.split(":");
872
+ const [block, index] = parts.map(Number);
873
+ if (parts.length !== 2 || !Number.isInteger(block) || !Number.isInteger(index)) {
874
+ throw new ValidationError(`Invalid stream cursor "${cursor}"; expected "<block>:<index>" (e.g. "951475:3").`, 400);
875
+ }
876
+ return [block, index];
695
877
  }
696
878
  function maxCursor(a, b) {
697
879
  const [ah, ai] = cursorTuple(a);
@@ -702,18 +884,6 @@ var DEFAULT_STREAMS_BASE_URL = "https://api.secondlayer.tools";
702
884
  function normalizeBaseUrl(baseUrl) {
703
885
  return baseUrl.replace(/\/+$/, "");
704
886
  }
705
- function appendSearchParam2(params, name, value) {
706
- if (value === undefined || value === null)
707
- return;
708
- params.set(name, String(value));
709
- }
710
- function appendListParam(params, name, value) {
711
- if (value === undefined || value === null)
712
- return;
713
- const joined = Array.isArray(value) ? value.join(",") : value;
714
- if (joined.length > 0)
715
- params.set(name, joined);
716
- }
717
887
  async function responseBody(response) {
718
888
  const text = await response.text();
719
889
  if (text.length === 0)
@@ -835,23 +1005,18 @@ function createStreamsClient(options) {
835
1005
  });
836
1006
  };
837
1007
  async function listEvents(params = {}) {
838
- const searchParams = new URLSearchParams;
839
- appendSearchParam2(searchParams, "cursor", params.cursor);
840
- appendSearchParam2(searchParams, "from_height", params.fromHeight);
841
- appendSearchParam2(searchParams, "to_height", params.toHeight);
842
- appendSearchParam2(searchParams, "limit", params.limit);
843
- appendListParam(searchParams, "contract_id", params.contractId);
844
- appendListParam(searchParams, "sender", params.sender);
845
- appendListParam(searchParams, "recipient", params.recipient);
846
- appendSearchParam2(searchParams, "asset_identifier", params.assetIdentifier);
847
- if (params.types?.length) {
848
- searchParams.set("types", params.types.join(","));
849
- }
850
- if (params.notTypes?.length) {
851
- searchParams.set("not_types", params.notTypes.join(","));
852
- }
853
- const query = searchParams.toString();
854
- return request(`/v1/streams/events${query ? `?${query}` : ""}`);
1008
+ return request(`/v1/streams/events${buildQuery({
1009
+ cursor: params.cursor,
1010
+ from_height: params.fromHeight,
1011
+ to_height: params.toHeight,
1012
+ limit: params.limit,
1013
+ contract_id: params.contractId,
1014
+ sender: params.sender,
1015
+ recipient: params.recipient,
1016
+ asset_identifier: params.assetIdentifier,
1017
+ types: params.types,
1018
+ not_types: params.notTypes
1019
+ })}`);
855
1020
  }
856
1021
  return {
857
1022
  events: {
@@ -863,6 +1028,7 @@ function createStreamsClient(options) {
863
1028
  return consumeStreamsEvents({
864
1029
  fromCursor: params.fromCursor,
865
1030
  mode: params.mode,
1031
+ finalizedOnly: params.finalizedOnly,
866
1032
  types: params.types,
867
1033
  notTypes: params.notTypes,
868
1034
  contractId: params.contractId,
@@ -872,6 +1038,7 @@ function createStreamsClient(options) {
872
1038
  batchSize: params.batchSize ?? 100,
873
1039
  fetchEvents,
874
1040
  onBatch: params.onBatch,
1041
+ onReorg: params.onReorg,
875
1042
  emptyBackoffMs: params.emptyBackoffMs,
876
1043
  maxPages: params.maxPages,
877
1044
  maxEmptyPolls: params.maxEmptyPolls,
@@ -926,11 +1093,10 @@ function createStreamsClient(options) {
926
1093
  },
927
1094
  reorgs: {
928
1095
  list(params) {
929
- const searchParams = new URLSearchParams;
930
- appendSearchParam2(searchParams, "since", params.since);
931
- appendSearchParam2(searchParams, "limit", params.limit);
932
- const query = searchParams.toString();
933
- return request(`/v1/streams/reorgs${query ? `?${query}` : ""}`);
1096
+ return request(`/v1/streams/reorgs${buildQuery({
1097
+ since: params.since,
1098
+ limit: params.limit
1099
+ })}`);
934
1100
  }
935
1101
  },
936
1102
  dumps,
@@ -987,6 +1153,8 @@ class Subscriptions extends BaseClient {
987
1153
  class SecondLayer extends BaseClient {
988
1154
  streams;
989
1155
  index;
1156
+ datasets;
1157
+ contracts;
990
1158
  subgraphs;
991
1159
  subscriptions;
992
1160
  constructor(options = {}) {
@@ -997,6 +1165,8 @@ class SecondLayer extends BaseClient {
997
1165
  fetchImpl: options.fetchImpl
998
1166
  });
999
1167
  this.index = new Index(options);
1168
+ this.datasets = new Datasets(options);
1169
+ this.contracts = new Contracts(options);
1000
1170
  this.subgraphs = new Subgraphs(options);
1001
1171
  this.subscriptions = new Subscriptions(options);
1002
1172
  }
@@ -1017,5 +1187,5 @@ export {
1017
1187
  Subgraphs
1018
1188
  };
1019
1189
 
1020
- //# debugId=9589AE42EB31EABA64756E2164756E21
1190
+ //# debugId=9C60733D992A531964756E2164756E21
1021
1191
  //# sourceMappingURL=index.js.map