@secondlayer/sdk 10.1.1 → 10.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/README.md +30 -0
- package/dist/index.d.ts +187 -1
- package/dist/index.js +299 -6
- package/dist/index.js.map +8 -6
- package/dist/sinks/bun-sqlite.js +34 -1
- package/dist/sinks/bun-sqlite.js.map +3 -3
- package/dist/sinks/core.js +34 -1
- package/dist/sinks/core.js.map +3 -3
- package/dist/sinks/drizzle.js +34 -1
- package/dist/sinks/drizzle.js.map +3 -3
- package/dist/sinks/kysely.js +34 -1
- package/dist/sinks/kysely.js.map +3 -3
- package/dist/streams/index.js +34 -1
- package/dist/streams/index.js.map +4 -4
- package/dist/subgraphs/index.d.ts +159 -0
- package/dist/subgraphs/index.js +294 -6
- package/dist/subgraphs/index.js.map +8 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -234,6 +234,36 @@ await streams.events.replay({
|
|
|
234
234
|
});
|
|
235
235
|
```
|
|
236
236
|
|
|
237
|
+
Archive.
|
|
238
|
+
|
|
239
|
+
Signed canonical partitions (`blocks` / `transactions` / `events`), distinct
|
|
240
|
+
from Streams dumps. `latest` follows `latest.json` and verifies the ed25519
|
|
241
|
+
manifest (default on). `quote` and `fetch` need an account key (`sk-sl_*`)
|
|
242
|
+
against `api.secondlayer.tools`, not the instance `baseUrl`. `download`
|
|
243
|
+
returns sha256-verified bytes; it does not decode parquet. Verify, repair,
|
|
244
|
+
and bootstrap remain CLI.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const sl = new SecondLayer({
|
|
248
|
+
apiKey: process.env.SL_API_KEY, // account key sk-sl_* for quote/fetch/credits
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const ref = await sl.archive.latest();
|
|
252
|
+
const partitions = sl.archive.partitions(ref, { dataset: "blocks" });
|
|
253
|
+
const quote = await sl.archive.quote({
|
|
254
|
+
paths: partitions.map((p) => p.path),
|
|
255
|
+
flow: "bootstrap",
|
|
256
|
+
});
|
|
257
|
+
const fetched = await sl.archive.fetch({
|
|
258
|
+
paths: partitions.map((p) => p.path),
|
|
259
|
+
flow: "bootstrap",
|
|
260
|
+
});
|
|
261
|
+
for (const item of fetched.urls) {
|
|
262
|
+
const partition = partitions.find((p) => p.path === item.path)!;
|
|
263
|
+
const bytes = await sl.archive.download(partition, { url: item.url });
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
237
267
|
Decoder helper.
|
|
238
268
|
|
|
239
269
|
```typescript
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,12 @@ interface SecondLayerOptions {
|
|
|
14
14
|
* Required for `streams.dumps.*`; without it the dumps client falls back to
|
|
15
15
|
* its built-in default. */
|
|
16
16
|
dumpsBaseUrl?: string;
|
|
17
|
+
/** Public base URL for the signed canonical archive tree. Defaults to
|
|
18
|
+
* `https://archive.secondlayer.tools`. Reaches `sl.archive`. */
|
|
19
|
+
archiveBaseUrl?: string;
|
|
20
|
+
/** Credits and fetch-gate API. Defaults to `https://api.secondlayer.tools`,
|
|
21
|
+
* not `baseUrl`. Reaches `sl.archive` quote/fetch/credits. */
|
|
22
|
+
archiveOpsUrl?: string;
|
|
17
23
|
/** Deploy origin label sent as `x-sl-origin` (telemetry). Defaults to `cli`. */
|
|
18
24
|
origin?: "cli" | "mcp" | "session";
|
|
19
25
|
/** Check the ed25519 signature on every Streams read. Omit for lenient
|
|
@@ -238,7 +244,156 @@ declare class Subgraphs extends BaseClient {
|
|
|
238
244
|
private createTableClient;
|
|
239
245
|
}
|
|
240
246
|
import { InferSubgraphClient as InferSubgraphClient2 } from "@secondlayer/subgraphs";
|
|
247
|
+
import { InstanceDiagnosis as InstanceDiagnosis2 } from "@secondlayer/shared/archive/instance-diagnosis";
|
|
241
248
|
import { SubgraphSummary as SubgraphSummary2 } from "@secondlayer/shared/schemas";
|
|
249
|
+
import { InstanceDiagnosis, PublicStatus } from "@secondlayer/shared/archive/instance-diagnosis";
|
|
250
|
+
/** Structural `/public/status` payload. Extra fields are ignored by diagnosis. */
|
|
251
|
+
type InstanceStatus = PublicStatus;
|
|
252
|
+
type InstanceClient = {
|
|
253
|
+
status(): Promise<InstanceStatus>;
|
|
254
|
+
diagnose(): Promise<InstanceDiagnosis>;
|
|
255
|
+
};
|
|
256
|
+
type ArchiveVerifyInput = {
|
|
257
|
+
against: string;
|
|
258
|
+
target?: string;
|
|
259
|
+
fromBlock?: number;
|
|
260
|
+
toBlock?: number;
|
|
261
|
+
insecure?: boolean;
|
|
262
|
+
publicKeyPem?: string;
|
|
263
|
+
};
|
|
264
|
+
type ArchiveVerifyRangeStatus = "match" | "digest-mismatch" | "count-mismatch" | "missing";
|
|
265
|
+
type ArchiveVerifyResult = {
|
|
266
|
+
status: "clean" | "diverged" | "unanchored";
|
|
267
|
+
target: string;
|
|
268
|
+
against: string;
|
|
269
|
+
signature: {
|
|
270
|
+
verified: boolean;
|
|
271
|
+
reason?: string;
|
|
272
|
+
};
|
|
273
|
+
coverage?: {
|
|
274
|
+
from_block: number;
|
|
275
|
+
to_block: number;
|
|
276
|
+
};
|
|
277
|
+
ranges: Array<{
|
|
278
|
+
dataset: string;
|
|
279
|
+
from_block: number;
|
|
280
|
+
to_block: number;
|
|
281
|
+
status: ArchiveVerifyRangeStatus;
|
|
282
|
+
expected_digest: string | null;
|
|
283
|
+
actual_digest: string | null;
|
|
284
|
+
}>;
|
|
285
|
+
reason?: string;
|
|
286
|
+
};
|
|
287
|
+
import { RangeDigest } from "@secondlayer/shared/archive/range-digest";
|
|
288
|
+
type ArchiveDataset = "blocks" | "transactions" | "events";
|
|
289
|
+
type ArchiveFlow = "bootstrap" | "repair";
|
|
290
|
+
type ArchivePartition = {
|
|
291
|
+
dataset: string;
|
|
292
|
+
from_block: number;
|
|
293
|
+
to_block: number;
|
|
294
|
+
path: string;
|
|
295
|
+
row_count: number;
|
|
296
|
+
byte_size: number;
|
|
297
|
+
sha256: string;
|
|
298
|
+
};
|
|
299
|
+
type ArchiveManifest = {
|
|
300
|
+
network?: string;
|
|
301
|
+
coverage?: {
|
|
302
|
+
from_block: number;
|
|
303
|
+
to_block: number;
|
|
304
|
+
};
|
|
305
|
+
partition_size_blocks?: number;
|
|
306
|
+
range_digests?: RangeDigest[];
|
|
307
|
+
partitions?: ArchivePartition[];
|
|
308
|
+
signature?: string;
|
|
309
|
+
key_id?: string;
|
|
310
|
+
[key: string]: unknown;
|
|
311
|
+
};
|
|
312
|
+
type LoadedArchive = {
|
|
313
|
+
manifest: ArchiveManifest;
|
|
314
|
+
origin: string;
|
|
315
|
+
root: string;
|
|
316
|
+
isRemote: boolean;
|
|
317
|
+
signature: {
|
|
318
|
+
verified: boolean;
|
|
319
|
+
reason?: string;
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
type ArchiveQuote = {
|
|
323
|
+
partitions: number;
|
|
324
|
+
bundles: number;
|
|
325
|
+
usdMicros: number;
|
|
326
|
+
usd: string;
|
|
327
|
+
freeAllowanceAppliedMicros: number;
|
|
328
|
+
allowanceRemainingBundles: number;
|
|
329
|
+
balanceUsdMicros: number;
|
|
330
|
+
sufficient: boolean;
|
|
331
|
+
};
|
|
332
|
+
type ArchiveFetchItem = {
|
|
333
|
+
path: string;
|
|
334
|
+
url: string;
|
|
335
|
+
expiresAt: string;
|
|
336
|
+
chargedUsdMicros: number;
|
|
337
|
+
};
|
|
338
|
+
type ArchiveFetchResult = {
|
|
339
|
+
urls: ArchiveFetchItem[];
|
|
340
|
+
chargedTotalUsdMicros: number;
|
|
341
|
+
balanceAfterUsdMicros: number;
|
|
342
|
+
};
|
|
343
|
+
type ArchiveCreditsBalance = {
|
|
344
|
+
creditsUsdMicros: string;
|
|
345
|
+
refill: {
|
|
346
|
+
belowUsd: number | null;
|
|
347
|
+
packUsd: number | null;
|
|
348
|
+
lastAt: string | null;
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
type ArchiveLoadOptions = {
|
|
352
|
+
insecure?: boolean;
|
|
353
|
+
};
|
|
354
|
+
type ArchiveClient = {
|
|
355
|
+
latest(against?: string, opts?: ArchiveLoadOptions): Promise<LoadedArchive>;
|
|
356
|
+
load(against: string, opts?: ArchiveLoadOptions): Promise<LoadedArchive>;
|
|
357
|
+
status(): Promise<unknown>;
|
|
358
|
+
partitions(ref: LoadedArchive, filter?: {
|
|
359
|
+
dataset?: ArchiveDataset;
|
|
360
|
+
fromBlock?: number;
|
|
361
|
+
toBlock?: number;
|
|
362
|
+
}): ArchivePartition[];
|
|
363
|
+
quote(input: {
|
|
364
|
+
paths: string[];
|
|
365
|
+
flow: ArchiveFlow;
|
|
366
|
+
}): Promise<ArchiveQuote>;
|
|
367
|
+
fetch(input: {
|
|
368
|
+
paths: string[];
|
|
369
|
+
flow: ArchiveFlow;
|
|
370
|
+
}): Promise<ArchiveFetchResult>;
|
|
371
|
+
download(partition: ArchivePartition, opts?: {
|
|
372
|
+
url?: string;
|
|
373
|
+
}): Promise<Uint8Array>;
|
|
374
|
+
credits: {
|
|
375
|
+
balance(): Promise<ArchiveCreditsBalance>;
|
|
376
|
+
checkout(input: {
|
|
377
|
+
email: string;
|
|
378
|
+
pack: 10 | 25 | 50 | 100;
|
|
379
|
+
}): Promise<{
|
|
380
|
+
url: string;
|
|
381
|
+
}>;
|
|
382
|
+
refill(input: {
|
|
383
|
+
belowUsd: number;
|
|
384
|
+
packUsd: 10 | 25 | 50 | 100;
|
|
385
|
+
} | {
|
|
386
|
+
off: true;
|
|
387
|
+
}): Promise<{
|
|
388
|
+
belowUsd: number | null;
|
|
389
|
+
packUsd: number | null;
|
|
390
|
+
}>;
|
|
391
|
+
};
|
|
392
|
+
};
|
|
393
|
+
/** Hosted archive client plus instance `verify`. `status()` is still the public archive tree. */
|
|
394
|
+
type SecondLayerArchive = ArchiveClient & {
|
|
395
|
+
verify(input: ArchiveVerifyInput): Promise<ArchiveVerifyResult>;
|
|
396
|
+
};
|
|
242
397
|
/**
|
|
243
398
|
* Typed client for the contract-discovery API (`GET /v1/contracts`).
|
|
244
399
|
*
|
|
@@ -2501,6 +2656,8 @@ interface ContextSnapshot {
|
|
|
2501
2656
|
}>;
|
|
2502
2657
|
/** In-flight reindex operations (bounded to subgraphs reporting `reindexing`). */
|
|
2503
2658
|
activeOperations: ContextField<ActiveSubgraphOperation[]>;
|
|
2659
|
+
/** Decoder lag / empty-index from `GET /public/status`. */
|
|
2660
|
+
instance: ContextField<InstanceDiagnosis2>;
|
|
2504
2661
|
}
|
|
2505
2662
|
/** Fold one read into a {@link ContextField}: the value, or `null` with the
|
|
2506
2663
|
* failure described. Exported for callers that assemble their own snapshot
|
|
@@ -2512,6 +2669,8 @@ declare class SecondLayer extends BaseClient {
|
|
|
2512
2669
|
readonly contracts: Contracts;
|
|
2513
2670
|
readonly subgraphs: Subgraphs;
|
|
2514
2671
|
readonly subscriptions: Subscriptions;
|
|
2672
|
+
readonly archive: SecondLayerArchive;
|
|
2673
|
+
readonly instance: InstanceClient;
|
|
2515
2674
|
constructor(options?: Partial<SecondLayerOptions>);
|
|
2516
2675
|
/**
|
|
2517
2676
|
* Up to 10 public reads in one round trip (`POST /v1/batch`). Each item
|
|
@@ -2705,6 +2864,23 @@ declare class RateLimitError extends ApiError {
|
|
|
2705
2864
|
declare class ValidationError extends ApiError {
|
|
2706
2865
|
constructor(message: string, status: number, body?: unknown, code?: string);
|
|
2707
2866
|
}
|
|
2867
|
+
/** Thrown when an archive manifest signature is missing or does not verify. */
|
|
2868
|
+
declare class ArchiveSignatureError extends SecondLayerError {
|
|
2869
|
+
constructor(message?: string);
|
|
2870
|
+
}
|
|
2871
|
+
/** Thrown on a 401 from the archive ops host (quote/fetch/credits). */
|
|
2872
|
+
declare class ArchiveAuthError extends SecondLayerError {
|
|
2873
|
+
constructor(message?: string);
|
|
2874
|
+
}
|
|
2875
|
+
/** Thrown on a 402 from archive fetch — prepaid credits do not cover the quote. */
|
|
2876
|
+
declare class InsufficientArchiveCreditsError extends SecondLayerError {
|
|
2877
|
+
shortfallUsdMicros?: number;
|
|
2878
|
+
constructor(message?: string, shortfallUsdMicros?: number);
|
|
2879
|
+
}
|
|
2880
|
+
/** Thrown on a 503 when the archive fetch gate is unconfigured. */
|
|
2881
|
+
declare class ArchiveGateNotConfiguredError extends SecondLayerError {
|
|
2882
|
+
constructor(message?: string);
|
|
2883
|
+
}
|
|
2708
2884
|
/** Parse a `Retry-After` header: delta-seconds or an HTTP-date. */
|
|
2709
2885
|
declare function parseRetryAfter(value?: string | null): number | undefined;
|
|
2710
2886
|
/** Thrown on a 5xx from the Streams API, and on a failed signing-key fetch.
|
|
@@ -2755,6 +2931,7 @@ declare const Cursor: {
|
|
|
2755
2931
|
eventIndex: number;
|
|
2756
2932
|
};
|
|
2757
2933
|
};
|
|
2934
|
+
import { InstanceDiagnosis as InstanceDiagnosis3, InstanceIssue, InstanceState, PublicStatus as PublicStatus2 } from "@secondlayer/shared/archive/instance-diagnosis";
|
|
2758
2935
|
import { SubgraphAgentSchema as SubgraphAgentSchema3, SubgraphSpecFormat as SubgraphSpecFormat2, SubgraphSpecOptions as SubgraphSpecOptions3 } from "@secondlayer/shared/subgraphs/spec";
|
|
2759
2936
|
/**
|
|
2760
2937
|
* The two pieces every "deploy a consumer" guide leaves out, packaged:
|
|
@@ -2797,6 +2974,15 @@ declare function consumerHealth(options?: {
|
|
|
2797
2974
|
declare function shutdownSignal(options?: {
|
|
2798
2975
|
signals?: readonly ("SIGTERM" | "SIGINT")[];
|
|
2799
2976
|
}): AbortSignal;
|
|
2977
|
+
type CreateArchiveClientOptions = {
|
|
2978
|
+
apiKey?: string;
|
|
2979
|
+
fetchImpl?: FetchLike;
|
|
2980
|
+
archiveBaseUrl?: string;
|
|
2981
|
+
archiveOpsUrl?: string;
|
|
2982
|
+
verifyManifest?: boolean;
|
|
2983
|
+
publicKeyPem?: string;
|
|
2984
|
+
};
|
|
2985
|
+
declare function createArchiveClient(options?: CreateArchiveClientOptions): ArchiveClient;
|
|
2800
2986
|
import { ChainWebhookDelivery } from "@secondlayer/shared";
|
|
2801
2987
|
import { StandardWebhooksHeaders } from "@secondlayer/shared/crypto/standard-webhooks";
|
|
2802
2988
|
import { StandardWebhooksHeaders as StandardWebhooksHeaders2, verify } from "@secondlayer/shared/crypto/standard-webhooks";
|
|
@@ -2955,4 +3141,4 @@ declare function verifySecondlayerSignature(rawBody: string, headers: WebhookHea
|
|
|
2955
3141
|
declare function decodeChainWebhook(rawBody: string): ChainWebhookDelivery;
|
|
2956
3142
|
import { RewardSet as RewardSet2 } from "@secondlayer/shared/node/consensus";
|
|
2957
3143
|
import { decodeClarityValue, toJsonSafe } from "@secondlayer/shared/streams-rows";
|
|
2958
|
-
export { verifyWebhookSignature, verifyTransactionProof, verify as verifyStandardWebhooksHeaders, verifySecondlayerSignature, trigger, toJsonSafe, shutdownSignal, resolveBaseUrl, resolveApiKey, parseRetryAfter, isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, getSubgraph, fetchRewardSet, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decodeClarityValue, decodeChainWebhook, decode, createStreamsClient, contextField, consumerHealth, consumeIndexFeed, WithSinkTx, WebhookHeaderInput, WalkOptions, ValidationError, UpdateSubscriptionRequest2 as UpdateSubscriptionRequest, TransactionsWalkParams, TransactionsListParams, TransactionsEnvelope, TransactionProofVerifyResult, TransactionProof, TransactionEnvelope, Subscriptions, SubscriptionSummary2 as SubscriptionSummary, SubscriptionStatus, SubscriptionRuntime, SubscriptionKind, SubscriptionFormat, SubscriptionDetail2 as SubscriptionDetail, Subgraphs, SubgraphSpecOptions3 as SubgraphSpecOptions, SubgraphSpecFormat2 as SubgraphSpecFormat, SubgraphOperationStatus, SubgraphAgentSchema3 as SubgraphAgentSchema, StreamsTip, StreamsSubscription, StreamsSignatureError, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorgContext, StreamsReorg, StreamsEventsSubscribeParams, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsDumpsManifest, StreamsDumps, StreamsDumpFile, StreamsConsumeParams, StreamsClient, StreamsCanonicalBlock, StreamsBatchContext, StreamsBatch, StandardWebhooksHeaders2 as StandardWebhooksHeaders, StackingWalkParams, StackingListParams, StackingEnvelope, SinkTx, SecondLayerOptions, SecondLayerErrorOptions, SecondLayerError, SecondLayer, SbtcWithdrawalsWalkParams, SbtcWithdrawalsListParams, SbtcWithdrawalsEnvelope, SbtcWithdrawalSweptConfirmedEvent, SbtcWithdrawalStatus, SbtcWithdrawalEvent, SbtcWithdrawalEnvelope, SbtcSummaryEnvelope, SbtcResource, SbtcEventsWalkParams, SbtcEventsListParams, SbtcEventsEnvelope, SbtcEventsConsumeParams, SbtcEventTopic2 as SbtcEventTopic, SbtcDepositsWalkParams, SbtcDepositsListParams, SbtcDepositsEnvelope, SbtcDepositsConsumeParams, SbtcDepositEvent, SbtcDepositEnvelope, RotateSecretResponse2 as RotateSecretResponse, RewardSet2 as RewardSet, RequestOptions, ReplayResult2 as ReplayResult, RateLimitError, PrintSchemaResponse, PoxResource, PoxCyclesWalkParams, PoxCyclesListParams, PoxCyclesEnvelope, PoxCycleEnvelope, Pox5Resource, Pox5EventsWalkParams, Pox5EventsListParams, Pox5EventsEnvelope, NftTransfersWalkParams, NftTransfersResource, NftTransfersListParams, NftTransfersEnvelope, NftTransferPayload2 as NftTransferPayload, NftTransferEvent, NftTransfer, MempoolWalkParams, MempoolTransactionEnvelope, MempoolListParams, MempoolEnvelope, LOCAL_API_URL, IndexTransaction, IndexTip, IndexStxTransfer, IndexStxMint, IndexStxLock, IndexStxBurn, IndexStackingAction, IndexSbtcWithdrawalPhase, IndexSbtcWithdrawalDetail, IndexSbtcWithdrawal, IndexSbtcSummary, IndexSbtcEvent, IndexSbtcDepositDetail, IndexSbtcDeposit, IndexReorg, IndexPrint, IndexPoxFunctionCount, IndexPoxCycle, IndexPox5EventTopic, IndexPox5Event, IndexPostCondition, IndexNftTransfer, IndexNftMint, IndexNftBurn, IndexMempoolTransaction, IndexFtTransfer, IndexFtMint, IndexFtBurn, IndexFeedItem, IndexFeedFetcher, IndexFeedEnvelope, IndexEventsResource, IndexEventTypeFilters, IndexEventType, IndexEventOf, IndexEventFields, IndexEvent, IndexDiscovery, IndexContractCall, IndexConsumeOptions, IndexCanonicalBlock, IndexBlock, IndexAlwaysFields, Index, INDEX_MAX_PAGE_SIZE, FtTransfersWalkParams, FtTransfersResource, FtTransfersListParams, FtTransfersEnvelope, FtTransferPayload2 as FtTransferPayload, FtTransferEvent, FtTransfer, FetchLike2 as FetchLike, EventsWalkParams, EventsListParams, EventsEnvelope, EventsConsumeParams, DeliveryRow2 as DeliveryRow, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, DeadRow2 as DeadRow, DEFAULT_REQUEST_TIMEOUT_MS, Cursor, CreateSubscriptionResponse2 as CreateSubscriptionResponse, CreateSubscriptionRequest2 as CreateSubscriptionRequest, ContractsListParams, ContractsEnvelope, Contracts, ContractSummary, ContractConformance, ContractCallsWalkParams, ContractCallsListParams, ContractCallsEnvelope, ContractCallsConsumeParams, ContextSnapshot, ContextFieldError, ContextField, ContextAccount, ConsumerSink, ConsumerHealth, ConsumerBatchContext, ChainWebhookEnvelope, ChainWebhookDelivery2 as ChainWebhookDelivery, ChainTxLevelEvent, ChainTriggerType, ChainTrigger, ChainTestDelivery, ChainStxTransferData, ChainStxMintData, ChainStxLockData, ChainStxBurnData, ChainReorgRollbackEnvelope, ChainReorgRollbackDelivery, ChainReorgOrphanedEntry, ChainPrintEventData, ChainNftTransferData, ChainNftMintData, ChainNftBurnData, ChainFtTransferData, ChainFtMintData, ChainFtBurnData, ChainEventEnvelope, ChainApplyEnvelopeOf, ChainApplyEnvelope, ChainApplyDeliveryOf, CanonicalWalkParams, CanonicalListParams, CanonicalEnvelope, CREDENTIAL_ENV_VARS, BlocksWalkParams, BlocksListParams, BlocksEnvelope, BlockEnvelope, AuthError, ApiError, ActiveSubgraphOperation };
|
|
3144
|
+
export { verifyWebhookSignature, verifyTransactionProof, verify as verifyStandardWebhooksHeaders, verifySecondlayerSignature, trigger, toJsonSafe, shutdownSignal, resolveBaseUrl, resolveApiKey, parseRetryAfter, isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, getSubgraph, fetchRewardSet, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decodeClarityValue, decodeChainWebhook, decode, createStreamsClient, createArchiveClient, contextField, consumerHealth, consumeIndexFeed, WithSinkTx, WebhookHeaderInput, WalkOptions, ValidationError, UpdateSubscriptionRequest2 as UpdateSubscriptionRequest, TransactionsWalkParams, TransactionsListParams, TransactionsEnvelope, TransactionProofVerifyResult, TransactionProof, TransactionEnvelope, Subscriptions, SubscriptionSummary2 as SubscriptionSummary, SubscriptionStatus, SubscriptionRuntime, SubscriptionKind, SubscriptionFormat, SubscriptionDetail2 as SubscriptionDetail, Subgraphs, SubgraphSpecOptions3 as SubgraphSpecOptions, SubgraphSpecFormat2 as SubgraphSpecFormat, SubgraphOperationStatus, SubgraphAgentSchema3 as SubgraphAgentSchema, StreamsTip, StreamsSubscription, StreamsSignatureError, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorgContext, StreamsReorg, StreamsEventsSubscribeParams, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsDumpsManifest, StreamsDumps, StreamsDumpFile, StreamsConsumeParams, StreamsClient, StreamsCanonicalBlock, StreamsBatchContext, StreamsBatch, StandardWebhooksHeaders2 as StandardWebhooksHeaders, StackingWalkParams, StackingListParams, StackingEnvelope, SinkTx, SecondLayerOptions, SecondLayerErrorOptions, SecondLayerError, SecondLayerArchive, SecondLayer, SbtcWithdrawalsWalkParams, SbtcWithdrawalsListParams, SbtcWithdrawalsEnvelope, SbtcWithdrawalSweptConfirmedEvent, SbtcWithdrawalStatus, SbtcWithdrawalEvent, SbtcWithdrawalEnvelope, SbtcSummaryEnvelope, SbtcResource, SbtcEventsWalkParams, SbtcEventsListParams, SbtcEventsEnvelope, SbtcEventsConsumeParams, SbtcEventTopic2 as SbtcEventTopic, SbtcDepositsWalkParams, SbtcDepositsListParams, SbtcDepositsEnvelope, SbtcDepositsConsumeParams, SbtcDepositEvent, SbtcDepositEnvelope, RotateSecretResponse2 as RotateSecretResponse, RewardSet2 as RewardSet, RequestOptions, ReplayResult2 as ReplayResult, RateLimitError, PublicStatus2 as PublicStatus, PrintSchemaResponse, PoxResource, PoxCyclesWalkParams, PoxCyclesListParams, PoxCyclesEnvelope, PoxCycleEnvelope, Pox5Resource, Pox5EventsWalkParams, Pox5EventsListParams, Pox5EventsEnvelope, NftTransfersWalkParams, NftTransfersResource, NftTransfersListParams, NftTransfersEnvelope, NftTransferPayload2 as NftTransferPayload, NftTransferEvent, NftTransfer, MempoolWalkParams, MempoolTransactionEnvelope, MempoolListParams, MempoolEnvelope, LoadedArchive, LOCAL_API_URL, InsufficientArchiveCreditsError, InstanceStatus, InstanceState, InstanceIssue, InstanceDiagnosis3 as InstanceDiagnosis, InstanceClient, IndexTransaction, IndexTip, IndexStxTransfer, IndexStxMint, IndexStxLock, IndexStxBurn, IndexStackingAction, IndexSbtcWithdrawalPhase, IndexSbtcWithdrawalDetail, IndexSbtcWithdrawal, IndexSbtcSummary, IndexSbtcEvent, IndexSbtcDepositDetail, IndexSbtcDeposit, IndexReorg, IndexPrint, IndexPoxFunctionCount, IndexPoxCycle, IndexPox5EventTopic, IndexPox5Event, IndexPostCondition, IndexNftTransfer, IndexNftMint, IndexNftBurn, IndexMempoolTransaction, IndexFtTransfer, IndexFtMint, IndexFtBurn, IndexFeedItem, IndexFeedFetcher, IndexFeedEnvelope, IndexEventsResource, IndexEventTypeFilters, IndexEventType, IndexEventOf, IndexEventFields, IndexEvent, IndexDiscovery, IndexContractCall, IndexConsumeOptions, IndexCanonicalBlock, IndexBlock, IndexAlwaysFields, Index, INDEX_MAX_PAGE_SIZE, FtTransfersWalkParams, FtTransfersResource, FtTransfersListParams, FtTransfersEnvelope, FtTransferPayload2 as FtTransferPayload, FtTransferEvent, FtTransfer, FetchLike2 as FetchLike, EventsWalkParams, EventsListParams, EventsEnvelope, EventsConsumeParams, DeliveryRow2 as DeliveryRow, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, DeadRow2 as DeadRow, DEFAULT_REQUEST_TIMEOUT_MS, Cursor, CreateSubscriptionResponse2 as CreateSubscriptionResponse, CreateSubscriptionRequest2 as CreateSubscriptionRequest, CreateArchiveClientOptions, ContractsListParams, ContractsEnvelope, Contracts, ContractSummary, ContractConformance, ContractCallsWalkParams, ContractCallsListParams, ContractCallsEnvelope, ContractCallsConsumeParams, ContextSnapshot, ContextFieldError, ContextField, ContextAccount, ConsumerSink, ConsumerHealth, ConsumerBatchContext, ChainWebhookEnvelope, ChainWebhookDelivery2 as ChainWebhookDelivery, ChainTxLevelEvent, ChainTriggerType, ChainTrigger, ChainTestDelivery, ChainStxTransferData, ChainStxMintData, ChainStxLockData, ChainStxBurnData, ChainReorgRollbackEnvelope, ChainReorgRollbackDelivery, ChainReorgOrphanedEntry, ChainPrintEventData, ChainNftTransferData, ChainNftMintData, ChainNftBurnData, ChainFtTransferData, ChainFtMintData, ChainFtBurnData, ChainEventEnvelope, ChainApplyEnvelopeOf, ChainApplyEnvelope, ChainApplyDeliveryOf, CanonicalWalkParams, CanonicalListParams, CanonicalEnvelope, CREDENTIAL_ENV_VARS, BlocksWalkParams, BlocksListParams, BlocksEnvelope, BlockEnvelope, AuthError, ArchiveVerifyResult, ArchiveVerifyRangeStatus, ArchiveVerifyInput, ArchiveSignatureError, ArchiveQuote, ArchivePartition, ArchiveManifest, ArchiveLoadOptions, ArchiveGateNotConfiguredError, ArchiveFlow, ArchiveFetchResult, ArchiveFetchItem, ArchiveDataset, ArchiveCreditsBalance, ArchiveClient, ArchiveAuthError, ApiError, ActiveSubgraphOperation };
|
package/dist/index.js
CHANGED
|
@@ -110,6 +110,39 @@ class ValidationError extends ApiError {
|
|
|
110
110
|
this.name = "ValidationError";
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
+
|
|
114
|
+
class ArchiveSignatureError extends SecondLayerError {
|
|
115
|
+
constructor(message = "Archive manifest signature is missing or invalid.") {
|
|
116
|
+
super(message, { code: "ARCHIVE_SIGNATURE", retryable: false });
|
|
117
|
+
this.name = "ArchiveSignatureError";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
class ArchiveAuthError extends SecondLayerError {
|
|
122
|
+
constructor(message = "Archive ops request was not authenticated.") {
|
|
123
|
+
super(message, { code: "ARCHIVE_AUTH", retryable: false });
|
|
124
|
+
this.name = "ArchiveAuthError";
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
class InsufficientArchiveCreditsError extends SecondLayerError {
|
|
129
|
+
shortfallUsdMicros;
|
|
130
|
+
constructor(message = "Insufficient archive credits.", shortfallUsdMicros) {
|
|
131
|
+
super(message, {
|
|
132
|
+
code: "INSUFFICIENT_ARCHIVE_CREDITS",
|
|
133
|
+
retryable: false
|
|
134
|
+
});
|
|
135
|
+
this.name = "InsufficientArchiveCreditsError";
|
|
136
|
+
this.shortfallUsdMicros = shortfallUsdMicros;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
class ArchiveGateNotConfiguredError extends SecondLayerError {
|
|
141
|
+
constructor(message = "The archive gate is not configured on the server.") {
|
|
142
|
+
super(message, { code: "ARCHIVE_GATE_NOT_CONFIGURED", retryable: false });
|
|
143
|
+
this.name = "ArchiveGateNotConfiguredError";
|
|
144
|
+
}
|
|
145
|
+
}
|
|
113
146
|
function parseRetryAfter(value) {
|
|
114
147
|
if (!value)
|
|
115
148
|
return;
|
|
@@ -814,6 +847,239 @@ class Subgraphs extends BaseClient {
|
|
|
814
847
|
};
|
|
815
848
|
}
|
|
816
849
|
}
|
|
850
|
+
// src/archive/client.ts
|
|
851
|
+
import { createHash } from "node:crypto";
|
|
852
|
+
import {
|
|
853
|
+
checkSignature,
|
|
854
|
+
loadReference
|
|
855
|
+
} from "@secondlayer/shared/archive/reference";
|
|
856
|
+
var OFFICIAL_ARCHIVE_HOST = "archive.secondlayer.tools";
|
|
857
|
+
var DEFAULT_ARCHIVE_BASE_URL = "https://archive.secondlayer.tools";
|
|
858
|
+
var DEFAULT_ARCHIVE_OPS_URL = "https://api.secondlayer.tools";
|
|
859
|
+
var MAX_FETCH_BATCH = 64;
|
|
860
|
+
function quoteFromBody(body) {
|
|
861
|
+
return {
|
|
862
|
+
partitions: body.partitions,
|
|
863
|
+
bundles: body.bundles,
|
|
864
|
+
usdMicros: body.usd_micros,
|
|
865
|
+
usd: body.usd,
|
|
866
|
+
freeAllowanceAppliedMicros: body.free_allowance_applied_micros,
|
|
867
|
+
allowanceRemainingBundles: body.allowance_remaining_bundles,
|
|
868
|
+
balanceUsdMicros: body.balance_usd_micros,
|
|
869
|
+
sufficient: body.sufficient
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
function stripSlash(url) {
|
|
873
|
+
return url.replace(/\/+$/, "");
|
|
874
|
+
}
|
|
875
|
+
function createArchiveClient(options = {}) {
|
|
876
|
+
const apiKey = resolveApiKey(options.apiKey);
|
|
877
|
+
const fetchImpl = options.fetchImpl ?? ((input, init) => fetch(input, init));
|
|
878
|
+
const archiveBaseUrl = stripSlash(options.archiveBaseUrl ?? DEFAULT_ARCHIVE_BASE_URL);
|
|
879
|
+
const archiveOpsUrl = stripSlash(options.archiveOpsUrl ?? DEFAULT_ARCHIVE_OPS_URL);
|
|
880
|
+
const verifyManifest = options.verifyManifest ?? true;
|
|
881
|
+
const pinnedPem = options.publicKeyPem;
|
|
882
|
+
let keyPromise = null;
|
|
883
|
+
async function fetchSigningKey() {
|
|
884
|
+
if (pinnedPem)
|
|
885
|
+
return pinnedPem;
|
|
886
|
+
if (keyPromise)
|
|
887
|
+
return keyPromise;
|
|
888
|
+
const pending = (async () => {
|
|
889
|
+
const res = await fetchImpl(`${archiveOpsUrl}/public/streams/signing-key`);
|
|
890
|
+
if (!res.ok) {
|
|
891
|
+
throw new ArchiveSignatureError(`Could not fetch archive signing key (${res.status}).`);
|
|
892
|
+
}
|
|
893
|
+
const body = await res.json();
|
|
894
|
+
if (typeof body.public_key_pem !== "string") {
|
|
895
|
+
throw new ArchiveSignatureError("Signing key response missing key.");
|
|
896
|
+
}
|
|
897
|
+
return body.public_key_pem;
|
|
898
|
+
})();
|
|
899
|
+
keyPromise = pending;
|
|
900
|
+
pending.catch(() => {
|
|
901
|
+
if (keyPromise === pending)
|
|
902
|
+
keyPromise = null;
|
|
903
|
+
});
|
|
904
|
+
return pending;
|
|
905
|
+
}
|
|
906
|
+
async function throwOpsError(response) {
|
|
907
|
+
const envelope = parseErrorEnvelope(await response.text());
|
|
908
|
+
if (response.status === 401) {
|
|
909
|
+
throw new ArchiveAuthError(envelope.message ?? "Archive ops request was not authenticated.");
|
|
910
|
+
}
|
|
911
|
+
if (response.status === 402) {
|
|
912
|
+
const raw = envelope.body && typeof envelope.body === "object" && "shortfall_usd_micros" in envelope.body ? Number(envelope.body.shortfall_usd_micros) : undefined;
|
|
913
|
+
throw new InsufficientArchiveCreditsError(envelope.message ?? "Insufficient archive credits.", Number.isFinite(raw) ? raw : undefined);
|
|
914
|
+
}
|
|
915
|
+
if (response.status === 503) {
|
|
916
|
+
throw new ArchiveGateNotConfiguredError(envelope.message ?? "The archive gate is not configured on the server.");
|
|
917
|
+
}
|
|
918
|
+
throw new ApiError(response.status, envelope.message ?? `Archive ops returned ${response.status}.`, envelope.body, envelope.code);
|
|
919
|
+
}
|
|
920
|
+
async function opsRequest(method, path, body, authed = true) {
|
|
921
|
+
const headers = {
|
|
922
|
+
"Content-Type": "application/json"
|
|
923
|
+
};
|
|
924
|
+
if (authed && apiKey)
|
|
925
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
926
|
+
const response = await fetchImpl(`${archiveOpsUrl}${path}`, {
|
|
927
|
+
method,
|
|
928
|
+
headers,
|
|
929
|
+
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
930
|
+
});
|
|
931
|
+
if (!response.ok)
|
|
932
|
+
await throwOpsError(response);
|
|
933
|
+
return await response.json();
|
|
934
|
+
}
|
|
935
|
+
async function load(against, opts = {}) {
|
|
936
|
+
if (!/^https?:\/\//i.test(against)) {
|
|
937
|
+
throw new ValidationError("archive.load() accepts only http(s) URLs; local paths stay on the CLI.", 400);
|
|
938
|
+
}
|
|
939
|
+
const insecure = opts.insecure === true;
|
|
940
|
+
const publicKeyPem = pinnedPem ?? (verifyManifest && !insecure ? await fetchSigningKey() : undefined);
|
|
941
|
+
const ref = await loadReference(against, {
|
|
942
|
+
publicKeyPem,
|
|
943
|
+
fetchImpl
|
|
944
|
+
});
|
|
945
|
+
const signature = checkSignature(ref.manifest, publicKeyPem, insecure);
|
|
946
|
+
if (verifyManifest && !insecure && !signature.verified) {
|
|
947
|
+
throw new ArchiveSignatureError(signature.reason ?? "Archive manifest signature is missing or invalid.");
|
|
948
|
+
}
|
|
949
|
+
return { ...ref, signature };
|
|
950
|
+
}
|
|
951
|
+
async function latest(against, opts = {}) {
|
|
952
|
+
return load(against ?? `${archiveBaseUrl}/latest.json`, opts);
|
|
953
|
+
}
|
|
954
|
+
async function status() {
|
|
955
|
+
const response = await fetchImpl(`${archiveBaseUrl}/status.json`);
|
|
956
|
+
if (!response.ok) {
|
|
957
|
+
throw new ApiError(response.status, `Could not fetch archive status (${response.status}).`);
|
|
958
|
+
}
|
|
959
|
+
return response.json();
|
|
960
|
+
}
|
|
961
|
+
function partitions(ref, filter) {
|
|
962
|
+
let list = ref.manifest.partitions ?? [];
|
|
963
|
+
if (!filter)
|
|
964
|
+
return list;
|
|
965
|
+
if (filter.dataset) {
|
|
966
|
+
list = list.filter((p) => p.dataset === filter.dataset);
|
|
967
|
+
}
|
|
968
|
+
const fromBlock = filter.fromBlock;
|
|
969
|
+
if (fromBlock !== undefined) {
|
|
970
|
+
list = list.filter((p) => p.to_block >= fromBlock);
|
|
971
|
+
}
|
|
972
|
+
const toBlock = filter.toBlock;
|
|
973
|
+
if (toBlock !== undefined) {
|
|
974
|
+
list = list.filter((p) => p.from_block <= toBlock);
|
|
975
|
+
}
|
|
976
|
+
return list;
|
|
977
|
+
}
|
|
978
|
+
async function quote(input) {
|
|
979
|
+
const body = await opsRequest("POST", "/api/archive/quote", { paths: input.paths, flow: input.flow });
|
|
980
|
+
return quoteFromBody(body);
|
|
981
|
+
}
|
|
982
|
+
async function fetchPartitions(input) {
|
|
983
|
+
const urls = [];
|
|
984
|
+
let chargedTotalUsdMicros = 0;
|
|
985
|
+
let balanceAfterUsdMicros = 0;
|
|
986
|
+
for (let i = 0;i < input.paths.length; i += MAX_FETCH_BATCH) {
|
|
987
|
+
const chunk = input.paths.slice(i, i + MAX_FETCH_BATCH);
|
|
988
|
+
const body = await opsRequest("POST", "/api/archive/fetch", { paths: chunk, flow: input.flow });
|
|
989
|
+
for (const item of body.urls) {
|
|
990
|
+
urls.push({
|
|
991
|
+
path: item.path,
|
|
992
|
+
url: item.url,
|
|
993
|
+
expiresAt: item.expires_at,
|
|
994
|
+
chargedUsdMicros: item.charged_usd_micros
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
chargedTotalUsdMicros += body.charged_total_usd_micros;
|
|
998
|
+
balanceAfterUsdMicros = body.balance_after_usd_micros;
|
|
999
|
+
}
|
|
1000
|
+
return { urls, chargedTotalUsdMicros, balanceAfterUsdMicros };
|
|
1001
|
+
}
|
|
1002
|
+
async function download(partition, opts) {
|
|
1003
|
+
let url = opts?.url;
|
|
1004
|
+
if (!url) {
|
|
1005
|
+
let official = false;
|
|
1006
|
+
try {
|
|
1007
|
+
official = new URL(archiveBaseUrl).hostname === OFFICIAL_ARCHIVE_HOST;
|
|
1008
|
+
} catch {
|
|
1009
|
+
official = false;
|
|
1010
|
+
}
|
|
1011
|
+
if (official) {
|
|
1012
|
+
throw new ValidationError("Official archive host requires a presigned URL from archive.fetch() before download.", 400);
|
|
1013
|
+
}
|
|
1014
|
+
url = `${archiveBaseUrl}/${partition.path.replace(/^\/+/, "")}`;
|
|
1015
|
+
}
|
|
1016
|
+
const response = await fetchImpl(url);
|
|
1017
|
+
if (!response.ok) {
|
|
1018
|
+
throw new ApiError(response.status, `Could not download ${partition.path} (${response.status}).`);
|
|
1019
|
+
}
|
|
1020
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
1021
|
+
const digest = createHash("sha256").update(bytes).digest("hex");
|
|
1022
|
+
if (digest !== partition.sha256) {
|
|
1023
|
+
throw new ArchiveSignatureError(`${partition.path} sha256 mismatch (expected ${partition.sha256}, got ${digest}).`);
|
|
1024
|
+
}
|
|
1025
|
+
return bytes;
|
|
1026
|
+
}
|
|
1027
|
+
return {
|
|
1028
|
+
latest,
|
|
1029
|
+
load,
|
|
1030
|
+
status,
|
|
1031
|
+
partitions,
|
|
1032
|
+
quote,
|
|
1033
|
+
fetch: fetchPartitions,
|
|
1034
|
+
download,
|
|
1035
|
+
credits: {
|
|
1036
|
+
async balance() {
|
|
1037
|
+
const body = await opsRequest("GET", "/api/billing/status");
|
|
1038
|
+
return {
|
|
1039
|
+
creditsUsdMicros: body.creditsUsdMicros,
|
|
1040
|
+
refill: body.refill
|
|
1041
|
+
};
|
|
1042
|
+
},
|
|
1043
|
+
async checkout(input) {
|
|
1044
|
+
const body = await opsRequest("POST", "/api/public/credits/checkout", { email: input.email, amount: input.pack }, false);
|
|
1045
|
+
return { url: body.url };
|
|
1046
|
+
},
|
|
1047
|
+
async refill(input) {
|
|
1048
|
+
const payload = "off" in input && input.off ? { belowUsd: null } : {
|
|
1049
|
+
belowUsd: input.belowUsd,
|
|
1050
|
+
packUsd: input.packUsd
|
|
1051
|
+
};
|
|
1052
|
+
const body = await opsRequest("POST", "/api/billing/refill", payload);
|
|
1053
|
+
return { belowUsd: body.belowUsd, packUsd: body.packUsd };
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/archive/instance.ts
|
|
1060
|
+
import {
|
|
1061
|
+
diagnoseInstanceStatus
|
|
1062
|
+
} from "@secondlayer/shared/archive/instance-diagnosis";
|
|
1063
|
+
function createArchiveVerify(request) {
|
|
1064
|
+
return (input) => request("POST", "/v1/archive/verify", {
|
|
1065
|
+
against: input.against,
|
|
1066
|
+
target: input.target ?? "raw",
|
|
1067
|
+
from_block: input.fromBlock,
|
|
1068
|
+
to_block: input.toBlock,
|
|
1069
|
+
insecure: input.insecure,
|
|
1070
|
+
public_key_pem: input.publicKeyPem
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
function createInstanceClient(request) {
|
|
1074
|
+
async function status() {
|
|
1075
|
+
return request("GET", "/public/status");
|
|
1076
|
+
}
|
|
1077
|
+
async function diagnose() {
|
|
1078
|
+
return diagnoseInstanceStatus(await status());
|
|
1079
|
+
}
|
|
1080
|
+
return { status, diagnose };
|
|
1081
|
+
}
|
|
1082
|
+
|
|
817
1083
|
// src/contracts/client.ts
|
|
818
1084
|
class Contracts extends BaseClient {
|
|
819
1085
|
constructor(options = {}) {
|
|
@@ -1786,7 +2052,7 @@ function decode(event) {
|
|
|
1786
2052
|
}
|
|
1787
2053
|
|
|
1788
2054
|
// src/streams/dumps.ts
|
|
1789
|
-
import { createHash } from "node:crypto";
|
|
2055
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
1790
2056
|
import { verifyStreamsBulkManifestSignature } from "@secondlayer/shared/streams-bulk-manifest";
|
|
1791
2057
|
function createStreamsDumps(opts) {
|
|
1792
2058
|
const baseUrl = opts.baseUrl?.replace(/\/+$/, "");
|
|
@@ -1838,7 +2104,7 @@ function createStreamsDumps(opts) {
|
|
|
1838
2104
|
if (!res.body) {
|
|
1839
2105
|
throw new StreamsServerError(`Dump ${file.path} response has no body.`, 0);
|
|
1840
2106
|
}
|
|
1841
|
-
const hash =
|
|
2107
|
+
const hash = createHash2("sha256");
|
|
1842
2108
|
const chunks = [];
|
|
1843
2109
|
let total = 0;
|
|
1844
2110
|
const reader = res.body.getReader();
|
|
@@ -2232,6 +2498,8 @@ class SecondLayer extends BaseClient {
|
|
|
2232
2498
|
contracts;
|
|
2233
2499
|
subgraphs;
|
|
2234
2500
|
subscriptions;
|
|
2501
|
+
archive;
|
|
2502
|
+
instance;
|
|
2235
2503
|
constructor(options = {}) {
|
|
2236
2504
|
super(options);
|
|
2237
2505
|
this.streams = createStreamsClient({
|
|
@@ -2247,17 +2515,36 @@ class SecondLayer extends BaseClient {
|
|
|
2247
2515
|
this.contracts = new Contracts(options);
|
|
2248
2516
|
this.subgraphs = new Subgraphs(options);
|
|
2249
2517
|
this.subscriptions = new Subscriptions(options);
|
|
2518
|
+
const request = (method, path, body) => this.request(method, path, body);
|
|
2519
|
+
this.archive = {
|
|
2520
|
+
...createArchiveClient({
|
|
2521
|
+
apiKey: this.apiKey,
|
|
2522
|
+
fetchImpl: options.fetchImpl,
|
|
2523
|
+
archiveBaseUrl: options.archiveBaseUrl,
|
|
2524
|
+
archiveOpsUrl: options.archiveOpsUrl
|
|
2525
|
+
}),
|
|
2526
|
+
verify: createArchiveVerify(request)
|
|
2527
|
+
};
|
|
2528
|
+
this.instance = createInstanceClient(request);
|
|
2250
2529
|
}
|
|
2251
2530
|
async batch(requests) {
|
|
2252
2531
|
return this.request("POST", "/v1/batch", { requests });
|
|
2253
2532
|
}
|
|
2254
2533
|
async context() {
|
|
2255
|
-
const [
|
|
2534
|
+
const [
|
|
2535
|
+
account,
|
|
2536
|
+
streamsTip,
|
|
2537
|
+
indexEnv,
|
|
2538
|
+
subgraphsRes,
|
|
2539
|
+
subscriptionsRes,
|
|
2540
|
+
instance
|
|
2541
|
+
] = await Promise.all([
|
|
2256
2542
|
contextField(this.request("GET", "/api/accounts/me")),
|
|
2257
2543
|
contextField(this.streams.tip()),
|
|
2258
2544
|
contextField(this.index.canonical.list({ limit: 1 })),
|
|
2259
2545
|
contextField(this.subgraphs.list()),
|
|
2260
|
-
contextField(this.subscriptions.list())
|
|
2546
|
+
contextField(this.subscriptions.list()),
|
|
2547
|
+
contextField(this.instance.diagnose())
|
|
2261
2548
|
]);
|
|
2262
2549
|
const subgraphs = {
|
|
2263
2550
|
value: subgraphsRes.value?.data ?? null,
|
|
@@ -2309,7 +2596,8 @@ class SecondLayer extends BaseClient {
|
|
|
2309
2596
|
},
|
|
2310
2597
|
subgraphs,
|
|
2311
2598
|
subscriptions,
|
|
2312
|
-
activeOperations
|
|
2599
|
+
activeOperations,
|
|
2600
|
+
instance
|
|
2313
2601
|
};
|
|
2314
2602
|
}
|
|
2315
2603
|
}
|
|
@@ -2591,6 +2879,7 @@ export {
|
|
|
2591
2879
|
decodeChainWebhook,
|
|
2592
2880
|
decode,
|
|
2593
2881
|
createStreamsClient,
|
|
2882
|
+
createArchiveClient,
|
|
2594
2883
|
contextField,
|
|
2595
2884
|
consumerHealth,
|
|
2596
2885
|
consumeIndexFeed,
|
|
@@ -2603,6 +2892,7 @@ export {
|
|
|
2603
2892
|
SecondLayer,
|
|
2604
2893
|
RateLimitError,
|
|
2605
2894
|
LOCAL_API_URL,
|
|
2895
|
+
InsufficientArchiveCreditsError,
|
|
2606
2896
|
Index,
|
|
2607
2897
|
INDEX_MAX_PAGE_SIZE,
|
|
2608
2898
|
DEFAULT_REQUEST_TIMEOUT_MS,
|
|
@@ -2610,8 +2900,11 @@ export {
|
|
|
2610
2900
|
Contracts,
|
|
2611
2901
|
CREDENTIAL_ENV_VARS,
|
|
2612
2902
|
AuthError,
|
|
2903
|
+
ArchiveSignatureError,
|
|
2904
|
+
ArchiveGateNotConfiguredError,
|
|
2905
|
+
ArchiveAuthError,
|
|
2613
2906
|
ApiError
|
|
2614
2907
|
};
|
|
2615
2908
|
|
|
2616
|
-
//# debugId=
|
|
2909
|
+
//# debugId=ACBBAC86B270FAEA64756E2164756E21
|
|
2617
2910
|
//# sourceMappingURL=index.js.map
|