@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.
- package/dist/index.d.ts +230 -125
- package/dist/index.js +376 -404
- package/dist/index.js.map +17 -15
- package/dist/streams/index.d.ts +62 -2
- package/dist/streams/index.js +310 -226
- package/dist/streams/index.js.map +12 -9
- package/dist/subgraphs/index.d.ts +208 -1
- package/dist/subgraphs/index.js +311 -141
- package/dist/subgraphs/index.js.map +13 -10
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -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/
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
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
|
-
|
|
543
|
-
|
|
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 (
|
|
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
|
|
694
|
-
|
|
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
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
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
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
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
|
}
|
|
@@ -1012,127 +1182,8 @@ function getSubgraph(def, options = {}) {
|
|
|
1012
1182
|
}
|
|
1013
1183
|
return new Subgraphs(options).typed(def);
|
|
1014
1184
|
}
|
|
1015
|
-
// src/streams/ft-transfer.ts
|
|
1016
|
-
function requireString(payload, field) {
|
|
1017
|
-
const value = payload[field];
|
|
1018
|
-
if (typeof value !== "string" || value.length === 0) {
|
|
1019
|
-
throw new Error(`ft_transfer payload missing ${field}`);
|
|
1020
|
-
}
|
|
1021
|
-
return value;
|
|
1022
|
-
}
|
|
1023
|
-
function parseAssetIdentifier(assetIdentifier) {
|
|
1024
|
-
const [contractId, tokenName] = assetIdentifier.split("::");
|
|
1025
|
-
if (!contractId) {
|
|
1026
|
-
throw new Error("ft_transfer payload has malformed asset_identifier");
|
|
1027
|
-
}
|
|
1028
|
-
return {
|
|
1029
|
-
contract_id: contractId,
|
|
1030
|
-
token_name: tokenName && tokenName.length > 0 ? tokenName : null
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
function isFtTransfer(event) {
|
|
1034
|
-
return event.event_type === "ft_transfer";
|
|
1035
|
-
}
|
|
1036
|
-
function decodeFtTransfer(event) {
|
|
1037
|
-
if (!isFtTransfer(event)) {
|
|
1038
|
-
throw new Error(`Expected ft_transfer event, got ${event.event_type}`);
|
|
1039
|
-
}
|
|
1040
|
-
const payload = event.payload;
|
|
1041
|
-
const assetIdentifier = requireString(payload, "asset_identifier");
|
|
1042
|
-
const sender = requireString(payload, "sender");
|
|
1043
|
-
const recipient = requireString(payload, "recipient");
|
|
1044
|
-
const amount = requireString(payload, "amount");
|
|
1045
|
-
if (!/^(0|[1-9]\d*)$/.test(amount)) {
|
|
1046
|
-
throw new Error("ft_transfer payload has malformed amount");
|
|
1047
|
-
}
|
|
1048
|
-
const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier);
|
|
1049
|
-
return {
|
|
1050
|
-
cursor: event.cursor,
|
|
1051
|
-
block_height: event.block_height,
|
|
1052
|
-
tx_id: event.tx_id,
|
|
1053
|
-
tx_index: event.tx_index,
|
|
1054
|
-
event_index: event.event_index,
|
|
1055
|
-
event_type: event.event_type,
|
|
1056
|
-
decoded_payload: {
|
|
1057
|
-
asset_identifier: assetIdentifier,
|
|
1058
|
-
contract_id: event.contract_id ?? contract_id,
|
|
1059
|
-
token_name,
|
|
1060
|
-
sender,
|
|
1061
|
-
recipient,
|
|
1062
|
-
amount
|
|
1063
|
-
},
|
|
1064
|
-
source_cursor: event.cursor
|
|
1065
|
-
};
|
|
1066
|
-
}
|
|
1067
|
-
// src/streams/nft-transfer.ts
|
|
1068
|
-
function requireString2(payload, field) {
|
|
1069
|
-
const value = payload[field];
|
|
1070
|
-
if (typeof value !== "string" || value.length === 0) {
|
|
1071
|
-
throw new Error(`nft_transfer payload missing ${field}`);
|
|
1072
|
-
}
|
|
1073
|
-
return value;
|
|
1074
|
-
}
|
|
1075
|
-
function requireHexValue(payload) {
|
|
1076
|
-
const rawValue = payload.raw_value;
|
|
1077
|
-
if (typeof rawValue === "string") {
|
|
1078
|
-
if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
|
|
1079
|
-
throw new Error("nft_transfer payload has malformed value");
|
|
1080
|
-
}
|
|
1081
|
-
return rawValue;
|
|
1082
|
-
}
|
|
1083
|
-
const value = payload.value;
|
|
1084
|
-
const hex = typeof value === "string" ? value : value && typeof value === "object" && typeof value.hex === "string" ? value.hex : null;
|
|
1085
|
-
if (!hex) {
|
|
1086
|
-
throw new Error("nft_transfer payload missing value");
|
|
1087
|
-
}
|
|
1088
|
-
if (!/^0x[0-9a-fA-F]*$/.test(hex)) {
|
|
1089
|
-
throw new Error("nft_transfer payload has malformed value");
|
|
1090
|
-
}
|
|
1091
|
-
return hex;
|
|
1092
|
-
}
|
|
1093
|
-
function parseAssetIdentifier2(assetIdentifier) {
|
|
1094
|
-
const [contractId, tokenName] = assetIdentifier.split("::");
|
|
1095
|
-
if (!contractId) {
|
|
1096
|
-
throw new Error("nft_transfer payload has malformed asset_identifier");
|
|
1097
|
-
}
|
|
1098
|
-
return {
|
|
1099
|
-
contract_id: contractId,
|
|
1100
|
-
token_name: tokenName && tokenName.length > 0 ? tokenName : null
|
|
1101
|
-
};
|
|
1102
|
-
}
|
|
1103
|
-
function isNftTransfer(event) {
|
|
1104
|
-
return event.event_type === "nft_transfer";
|
|
1105
|
-
}
|
|
1106
|
-
function decodeNftTransfer(event) {
|
|
1107
|
-
if (!isNftTransfer(event)) {
|
|
1108
|
-
throw new Error(`Expected nft_transfer event, got ${event.event_type}`);
|
|
1109
|
-
}
|
|
1110
|
-
const payload = event.payload;
|
|
1111
|
-
const assetIdentifier = requireString2(payload, "asset_identifier");
|
|
1112
|
-
const sender = requireString2(payload, "sender");
|
|
1113
|
-
const recipient = requireString2(payload, "recipient");
|
|
1114
|
-
const value = requireHexValue(payload);
|
|
1115
|
-
const { contract_id, token_name } = parseAssetIdentifier2(assetIdentifier);
|
|
1116
|
-
return {
|
|
1117
|
-
cursor: event.cursor,
|
|
1118
|
-
block_height: event.block_height,
|
|
1119
|
-
tx_id: event.tx_id,
|
|
1120
|
-
tx_index: event.tx_index,
|
|
1121
|
-
event_index: event.event_index,
|
|
1122
|
-
event_type: event.event_type,
|
|
1123
|
-
decoded_payload: {
|
|
1124
|
-
asset_identifier: assetIdentifier,
|
|
1125
|
-
contract_id: event.contract_id ?? contract_id,
|
|
1126
|
-
token_name,
|
|
1127
|
-
sender,
|
|
1128
|
-
recipient,
|
|
1129
|
-
value
|
|
1130
|
-
},
|
|
1131
|
-
source_cursor: event.cursor
|
|
1132
|
-
};
|
|
1133
|
-
}
|
|
1134
1185
|
// src/streams/_payload.ts
|
|
1135
|
-
function
|
|
1186
|
+
function requireString(payload, field, eventType) {
|
|
1136
1187
|
const value = payload[field];
|
|
1137
1188
|
if (typeof value !== "string" || value.length === 0) {
|
|
1138
1189
|
throw new Error(`${eventType} payload missing ${field}`);
|
|
@@ -1143,7 +1194,7 @@ function optionalString(value) {
|
|
|
1143
1194
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1144
1195
|
}
|
|
1145
1196
|
function requireAmountField(payload, field, eventType) {
|
|
1146
|
-
const amount =
|
|
1197
|
+
const amount = requireString(payload, field, eventType);
|
|
1147
1198
|
if (!/^(0|[1-9]\d*)$/.test(amount)) {
|
|
1148
1199
|
throw new Error(`${eventType} payload has malformed ${field}`);
|
|
1149
1200
|
}
|
|
@@ -1152,7 +1203,7 @@ function requireAmountField(payload, field, eventType) {
|
|
|
1152
1203
|
function requireAmount(payload, eventType) {
|
|
1153
1204
|
return requireAmountField(payload, "amount", eventType);
|
|
1154
1205
|
}
|
|
1155
|
-
function
|
|
1206
|
+
function parseAssetIdentifier(assetIdentifier, eventType) {
|
|
1156
1207
|
const [contractId, tokenName] = assetIdentifier.split("::");
|
|
1157
1208
|
if (!contractId) {
|
|
1158
1209
|
throw new Error(`${eventType} payload has malformed asset_identifier`);
|
|
@@ -1162,7 +1213,7 @@ function parseAssetIdentifier3(assetIdentifier, eventType) {
|
|
|
1162
1213
|
token_name: tokenName && tokenName.length > 0 ? tokenName : null
|
|
1163
1214
|
};
|
|
1164
1215
|
}
|
|
1165
|
-
function
|
|
1216
|
+
function requireHexValue(payload, eventType) {
|
|
1166
1217
|
const rawValue = payload.raw_value;
|
|
1167
1218
|
if (typeof rawValue === "string") {
|
|
1168
1219
|
if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
|
|
@@ -1193,6 +1244,52 @@ function decodedRow(event, eventType, decoded_payload) {
|
|
|
1193
1244
|
};
|
|
1194
1245
|
}
|
|
1195
1246
|
|
|
1247
|
+
// src/streams/ft-transfer.ts
|
|
1248
|
+
function isFtTransfer(event) {
|
|
1249
|
+
return event.event_type === "ft_transfer";
|
|
1250
|
+
}
|
|
1251
|
+
function decodeFtTransfer(event) {
|
|
1252
|
+
if (!isFtTransfer(event)) {
|
|
1253
|
+
throw new Error(`Expected ft_transfer event, got ${event.event_type}`);
|
|
1254
|
+
}
|
|
1255
|
+
const payload = event.payload;
|
|
1256
|
+
const assetIdentifier = requireString(payload, "asset_identifier", "ft_transfer");
|
|
1257
|
+
const sender = requireString(payload, "sender", "ft_transfer");
|
|
1258
|
+
const recipient = requireString(payload, "recipient", "ft_transfer");
|
|
1259
|
+
const amount = requireAmount(payload, "ft_transfer");
|
|
1260
|
+
const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, "ft_transfer");
|
|
1261
|
+
return decodedRow(event, "ft_transfer", {
|
|
1262
|
+
asset_identifier: assetIdentifier,
|
|
1263
|
+
contract_id: event.contract_id ?? contract_id,
|
|
1264
|
+
token_name,
|
|
1265
|
+
sender,
|
|
1266
|
+
recipient,
|
|
1267
|
+
amount
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
// src/streams/nft-transfer.ts
|
|
1271
|
+
function isNftTransfer(event) {
|
|
1272
|
+
return event.event_type === "nft_transfer";
|
|
1273
|
+
}
|
|
1274
|
+
function decodeNftTransfer(event) {
|
|
1275
|
+
if (!isNftTransfer(event)) {
|
|
1276
|
+
throw new Error(`Expected nft_transfer event, got ${event.event_type}`);
|
|
1277
|
+
}
|
|
1278
|
+
const payload = event.payload;
|
|
1279
|
+
const assetIdentifier = requireString(payload, "asset_identifier", "nft_transfer");
|
|
1280
|
+
const sender = requireString(payload, "sender", "nft_transfer");
|
|
1281
|
+
const recipient = requireString(payload, "recipient", "nft_transfer");
|
|
1282
|
+
const value = requireHexValue(payload, "nft_transfer");
|
|
1283
|
+
const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, "nft_transfer");
|
|
1284
|
+
return decodedRow(event, "nft_transfer", {
|
|
1285
|
+
asset_identifier: assetIdentifier,
|
|
1286
|
+
contract_id: event.contract_id ?? contract_id,
|
|
1287
|
+
token_name,
|
|
1288
|
+
sender,
|
|
1289
|
+
recipient,
|
|
1290
|
+
value
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1196
1293
|
// src/streams/stx-events.ts
|
|
1197
1294
|
function isStxTransfer(event) {
|
|
1198
1295
|
return event.event_type === "stx_transfer";
|
|
@@ -1203,8 +1300,8 @@ function decodeStxTransfer(event) {
|
|
|
1203
1300
|
}
|
|
1204
1301
|
const payload = event.payload;
|
|
1205
1302
|
return decodedRow(event, "stx_transfer", {
|
|
1206
|
-
sender:
|
|
1207
|
-
recipient:
|
|
1303
|
+
sender: requireString(payload, "sender", "stx_transfer"),
|
|
1304
|
+
recipient: requireString(payload, "recipient", "stx_transfer"),
|
|
1208
1305
|
amount: requireAmount(payload, "stx_transfer"),
|
|
1209
1306
|
memo: optionalString(payload.memo)
|
|
1210
1307
|
});
|
|
@@ -1218,7 +1315,7 @@ function decodeStxMint(event) {
|
|
|
1218
1315
|
}
|
|
1219
1316
|
const payload = event.payload;
|
|
1220
1317
|
return decodedRow(event, "stx_mint", {
|
|
1221
|
-
recipient:
|
|
1318
|
+
recipient: requireString(payload, "recipient", "stx_mint"),
|
|
1222
1319
|
amount: requireAmount(payload, "stx_mint")
|
|
1223
1320
|
});
|
|
1224
1321
|
}
|
|
@@ -1231,7 +1328,7 @@ function decodeStxBurn(event) {
|
|
|
1231
1328
|
}
|
|
1232
1329
|
const payload = event.payload;
|
|
1233
1330
|
return decodedRow(event, "stx_burn", {
|
|
1234
|
-
sender:
|
|
1331
|
+
sender: requireString(payload, "sender", "stx_burn"),
|
|
1235
1332
|
amount: requireAmount(payload, "stx_burn")
|
|
1236
1333
|
});
|
|
1237
1334
|
}
|
|
@@ -1244,15 +1341,15 @@ function decodeStxLock(event) {
|
|
|
1244
1341
|
}
|
|
1245
1342
|
const payload = event.payload;
|
|
1246
1343
|
return decodedRow(event, "stx_lock", {
|
|
1247
|
-
sender:
|
|
1344
|
+
sender: requireString(payload, "locked_address", "stx_lock"),
|
|
1248
1345
|
amount: requireAmountField(payload, "locked_amount", "stx_lock"),
|
|
1249
1346
|
payload: { unlock_height: optionalString(payload.unlock_height) }
|
|
1250
1347
|
});
|
|
1251
1348
|
}
|
|
1252
1349
|
// src/streams/token-mint-burn.ts
|
|
1253
1350
|
function assetFields(event, eventType) {
|
|
1254
|
-
const assetIdentifier =
|
|
1255
|
-
const { contract_id, token_name } =
|
|
1351
|
+
const assetIdentifier = requireString(event.payload, "asset_identifier", eventType);
|
|
1352
|
+
const { contract_id, token_name } = parseAssetIdentifier(assetIdentifier, eventType);
|
|
1256
1353
|
return {
|
|
1257
1354
|
asset_identifier: assetIdentifier,
|
|
1258
1355
|
contract_id: event.contract_id ?? contract_id,
|
|
@@ -1268,7 +1365,7 @@ function decodeFtMint(event) {
|
|
|
1268
1365
|
}
|
|
1269
1366
|
return decodedRow(event, "ft_mint", {
|
|
1270
1367
|
...assetFields(event, "ft_mint"),
|
|
1271
|
-
recipient:
|
|
1368
|
+
recipient: requireString(event.payload, "recipient", "ft_mint"),
|
|
1272
1369
|
amount: requireAmount(event.payload, "ft_mint")
|
|
1273
1370
|
});
|
|
1274
1371
|
}
|
|
@@ -1281,7 +1378,7 @@ function decodeFtBurn(event) {
|
|
|
1281
1378
|
}
|
|
1282
1379
|
return decodedRow(event, "ft_burn", {
|
|
1283
1380
|
...assetFields(event, "ft_burn"),
|
|
1284
|
-
sender:
|
|
1381
|
+
sender: requireString(event.payload, "sender", "ft_burn"),
|
|
1285
1382
|
amount: requireAmount(event.payload, "ft_burn")
|
|
1286
1383
|
});
|
|
1287
1384
|
}
|
|
@@ -1294,8 +1391,8 @@ function decodeNftMint(event) {
|
|
|
1294
1391
|
}
|
|
1295
1392
|
return decodedRow(event, "nft_mint", {
|
|
1296
1393
|
...assetFields(event, "nft_mint"),
|
|
1297
|
-
recipient:
|
|
1298
|
-
value:
|
|
1394
|
+
recipient: requireString(event.payload, "recipient", "nft_mint"),
|
|
1395
|
+
value: requireHexValue(event.payload, "nft_mint")
|
|
1299
1396
|
});
|
|
1300
1397
|
}
|
|
1301
1398
|
function isNftBurn(event) {
|
|
@@ -1307,8 +1404,8 @@ function decodeNftBurn(event) {
|
|
|
1307
1404
|
}
|
|
1308
1405
|
return decodedRow(event, "nft_burn", {
|
|
1309
1406
|
...assetFields(event, "nft_burn"),
|
|
1310
|
-
sender:
|
|
1311
|
-
value:
|
|
1407
|
+
sender: requireString(event.payload, "sender", "nft_burn"),
|
|
1408
|
+
value: requireHexValue(event.payload, "nft_burn")
|
|
1312
1409
|
});
|
|
1313
1410
|
}
|
|
1314
1411
|
// src/clarity.ts
|
|
@@ -1378,133 +1475,6 @@ var STREAMS_EVENT_TYPES = [
|
|
|
1378
1475
|
"nft_burn",
|
|
1379
1476
|
"print"
|
|
1380
1477
|
];
|
|
1381
|
-
// src/datasets/client.ts
|
|
1382
|
-
function appendParam(params, name, value) {
|
|
1383
|
-
if (value === undefined || value === null)
|
|
1384
|
-
return;
|
|
1385
|
-
params.set(name, String(value));
|
|
1386
|
-
}
|
|
1387
|
-
var PARAM_KEYS = {
|
|
1388
|
-
fromBlock: "from_block",
|
|
1389
|
-
toBlock: "to_block",
|
|
1390
|
-
functionName: "function_name",
|
|
1391
|
-
delegateTo: "delegate_to",
|
|
1392
|
-
signerKey: "signer_key",
|
|
1393
|
-
rewardCycle: "reward_cycle",
|
|
1394
|
-
eventType: "event_type",
|
|
1395
|
-
bnsId: "bns_id"
|
|
1396
|
-
};
|
|
1397
|
-
var CURSOR_SLUGS = {
|
|
1398
|
-
"stx-transfers": { path: "stx-transfers", rowKey: "events" },
|
|
1399
|
-
"sbtc-events": { path: "sbtc/events", rowKey: "events" },
|
|
1400
|
-
"sbtc-token-events": { path: "sbtc/token-events", rowKey: "events" },
|
|
1401
|
-
"pox-4-calls": { path: "pox-4/calls", rowKey: "calls" },
|
|
1402
|
-
"burnchain-rewards": { path: "burnchain/rewards", rowKey: "rewards" },
|
|
1403
|
-
"burnchain-reward-slots": {
|
|
1404
|
-
path: "burnchain/reward-slots",
|
|
1405
|
-
rowKey: "slots"
|
|
1406
|
-
},
|
|
1407
|
-
"bns-events": { path: "bns/events", rowKey: "events" },
|
|
1408
|
-
"bns-namespace-events": { path: "bns/namespace-events", rowKey: "events" },
|
|
1409
|
-
"bns-marketplace-events": {
|
|
1410
|
-
path: "bns/marketplace-events",
|
|
1411
|
-
rowKey: "events"
|
|
1412
|
-
}
|
|
1413
|
-
};
|
|
1414
|
-
|
|
1415
|
-
class Datasets extends BaseClient {
|
|
1416
|
-
constructor(options = {}) {
|
|
1417
|
-
super(options);
|
|
1418
|
-
}
|
|
1419
|
-
listDatasets() {
|
|
1420
|
-
return this.request("GET", "/v1/datasets");
|
|
1421
|
-
}
|
|
1422
|
-
async query(slug, params = {}) {
|
|
1423
|
-
const d = CURSOR_SLUGS[slug];
|
|
1424
|
-
if (!d) {
|
|
1425
|
-
throw new Error(`unknown cursor dataset "${slug}" (use one of: ${Object.keys(CURSOR_SLUGS).join(", ")})`);
|
|
1426
|
-
}
|
|
1427
|
-
const env = await this.get(d.path, this.buildParams(params));
|
|
1428
|
-
return {
|
|
1429
|
-
rows: env[d.rowKey] ?? [],
|
|
1430
|
-
next_cursor: env.next_cursor ?? null,
|
|
1431
|
-
tip: env.tip
|
|
1432
|
-
};
|
|
1433
|
-
}
|
|
1434
|
-
stxTransfers = this.cursorDataset("stx-transfers", "events");
|
|
1435
|
-
sbtcEvents = this.cursorDataset("sbtc/events", "events");
|
|
1436
|
-
sbtcTokenEvents = this.cursorDataset("sbtc/token-events", "events");
|
|
1437
|
-
pox4Calls = this.cursorDataset("pox-4/calls", "calls");
|
|
1438
|
-
burnchainRewards = this.cursorDataset("burnchain/rewards", "rewards");
|
|
1439
|
-
burnchainRewardSlots = this.cursorDataset("burnchain/reward-slots", "slots");
|
|
1440
|
-
bnsEvents = this.cursorDataset("bns/events", "events");
|
|
1441
|
-
bnsNamespaceEvents = this.cursorDataset("bns/namespace-events", "events");
|
|
1442
|
-
bnsMarketplaceEvents = this.cursorDataset("bns/marketplace-events", "events");
|
|
1443
|
-
bnsNames(params = {}) {
|
|
1444
|
-
const sp = new URLSearchParams;
|
|
1445
|
-
appendParam(sp, "namespace", params.namespace);
|
|
1446
|
-
appendParam(sp, "owner", params.owner);
|
|
1447
|
-
appendParam(sp, "limit", params.limit);
|
|
1448
|
-
appendParam(sp, "offset", params.offset);
|
|
1449
|
-
return this.get("bns/names", sp);
|
|
1450
|
-
}
|
|
1451
|
-
bnsNamespaces() {
|
|
1452
|
-
return this.get("bns/namespaces", new URLSearchParams);
|
|
1453
|
-
}
|
|
1454
|
-
bnsResolve(fqn) {
|
|
1455
|
-
const sp = new URLSearchParams;
|
|
1456
|
-
sp.set("fqn", fqn);
|
|
1457
|
-
return this.get("bns/resolve", sp);
|
|
1458
|
-
}
|
|
1459
|
-
networkHealth() {
|
|
1460
|
-
return this.get("network-health/summary", new URLSearchParams);
|
|
1461
|
-
}
|
|
1462
|
-
get(path, sp) {
|
|
1463
|
-
const qs = sp.toString();
|
|
1464
|
-
return this.request("GET", `/v1/datasets/${path}${qs ? `?${qs}` : ""}`);
|
|
1465
|
-
}
|
|
1466
|
-
buildParams(params) {
|
|
1467
|
-
const sp = new URLSearchParams;
|
|
1468
|
-
for (const [k, v] of Object.entries(params)) {
|
|
1469
|
-
if (v === undefined || v === null || k === "batchSize" || k === "signal")
|
|
1470
|
-
continue;
|
|
1471
|
-
appendParam(sp, PARAM_KEYS[k] ?? k, v);
|
|
1472
|
-
}
|
|
1473
|
-
return sp;
|
|
1474
|
-
}
|
|
1475
|
-
cursorDataset(path, rowKey) {
|
|
1476
|
-
const list = async (params = {}) => {
|
|
1477
|
-
const envelope = await this.get(path, this.buildParams(params));
|
|
1478
|
-
return {
|
|
1479
|
-
rows: envelope[rowKey] ?? [],
|
|
1480
|
-
next_cursor: envelope.next_cursor ?? null,
|
|
1481
|
-
tip: envelope.tip
|
|
1482
|
-
};
|
|
1483
|
-
};
|
|
1484
|
-
const walk = async function* (params = {}) {
|
|
1485
|
-
const batchSize = params.batchSize ?? 200;
|
|
1486
|
-
let cursor = params.cursor ?? null;
|
|
1487
|
-
let first = true;
|
|
1488
|
-
while (!params.signal?.aborted) {
|
|
1489
|
-
const env = await list({
|
|
1490
|
-
...params,
|
|
1491
|
-
limit: batchSize,
|
|
1492
|
-
cursor: first ? params.cursor : cursor ?? undefined
|
|
1493
|
-
});
|
|
1494
|
-
for (const row of env.rows) {
|
|
1495
|
-
if (params.signal?.aborted)
|
|
1496
|
-
return;
|
|
1497
|
-
yield row;
|
|
1498
|
-
}
|
|
1499
|
-
if (!env.next_cursor || env.next_cursor === cursor || env.rows.length < batchSize)
|
|
1500
|
-
return;
|
|
1501
|
-
cursor = env.next_cursor;
|
|
1502
|
-
first = false;
|
|
1503
|
-
}
|
|
1504
|
-
}.bind(this);
|
|
1505
|
-
return { list, walk };
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
1478
|
// src/webhooks.ts
|
|
1509
1479
|
import {
|
|
1510
1480
|
verify
|
|
@@ -1586,10 +1556,12 @@ export {
|
|
|
1586
1556
|
RateLimitError,
|
|
1587
1557
|
Index,
|
|
1588
1558
|
Datasets,
|
|
1559
|
+
Cursor,
|
|
1560
|
+
Contracts,
|
|
1589
1561
|
CURSOR_SLUGS,
|
|
1590
1562
|
AuthError,
|
|
1591
1563
|
ApiError
|
|
1592
1564
|
};
|
|
1593
1565
|
|
|
1594
|
-
//# debugId=
|
|
1566
|
+
//# debugId=C7330C1F713D815864756E2164756E21
|
|
1595
1567
|
//# sourceMappingURL=index.js.map
|