@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.
- package/README.md +61 -4
- package/dist/index.d.ts +281 -164
- package/dist/index.js +294 -169
- package/dist/index.js.map +10 -10
- package/dist/streams/index.d.ts +46 -1
- package/dist/streams/index.js +48 -1
- package/dist/streams/index.js.map +5 -5
- package/dist/subgraphs/index.d.ts +124 -158
- package/dist/subgraphs/index.js +70 -167
- package/dist/subgraphs/index.js.map +8 -9
- package/dist/x402.d.ts +159 -0
- package/dist/x402.js +230 -0
- package/dist/x402.js.map +10 -0
- package/package.json +8 -4
|
@@ -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
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
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
|
/**
|
package/dist/subgraphs/index.js
CHANGED
|
@@ -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=
|
|
1721
|
+
//# debugId=0E36F58DBAA5692064756E2164756E21
|
|
1819
1722
|
//# sourceMappingURL=index.js.map
|