.md

sl.archive

Load a signed archive manifest, verify your data against it, and price and fetch what you are missing.

@secondlayer/sdk@15.5.011 methodsfrom source with openpkgArchive guide
latest(against, opts)LoadedArchiveLoad the latest signed archive manifest.
load(against, opts)LoadedArchiveLoad an archive manifest from a URL.
status()ArchiveStatusGet the archive's current operational state.
partitions(ref, filter)ArchivePartition[]List a loaded archive's partitions, optionally filtered.
quote(input)ArchiveQuotePrice a fetch against your balance before you pay for it.
fetch(input)ArchiveFetchResultGet presigned download URLs for archive partitions.
download(partition, opts)Uint8ArrayDownload a partition's bytes and verify them.
credits.balance()ArchiveCreditsBalanceGet your archive credit balance.
credits.checkout(input){ url: string }Start a card checkout for a credit pack.
credits.refill(input){ belowUsd: number | null; packUsd:…Set or turn off automatic credit refill.
verify(input)ArchiveVerifyResultCheck your instance's data against a signed archive.

Load the latest signed archive manifest.

Reads <archive>/latest.json unless against names another manifest URL. The manifest's ed25519 signature is checked against the archive signing key, and a missing or invalid one throws ArchiveSignatureError. insecure: true skips the check; signature.verified on the result says whether it held.

sl.archive.latest(against?: string, opts?: ArchiveLoadOptions): Promise<LoadedArchive>

Parameters

hover a row to find it in the code

Options

againststring
opts.insecureboolean
Returns Promise<LoadedArchive>
manifest
ArchiveManifest
origin
string
root
string
isRemote
boolean
signature
{ verified: boolean; reason?: string }

Load an archive manifest from a URL.

Takes http(s) URLs only; a local path throws a ValidationError and stays on the CLI. The signature check is the same as latest.

sl.archive.load(against: string, opts?: ArchiveLoadOptions): Promise<LoadedArchive>

Parameters

hover a row to find it in the code

Required

againstrequiredstring

Options

opts.insecureboolean
Returns Promise<LoadedArchive>
manifest
ArchiveManifest
origin
string
root
string
isRemote
boolean
signature
{ verified: boolean; reason?: string }

Get the archive's current operational state.

Reads the public status.json: fresh, lagging, stale, gap, failed-audit, or source-unavailable, plus how far the last signed publish reaches.

sl.archive.status(): Promise<ArchiveStatus>
Returns Promise<ArchiveStatus>
schema_version
1
network
string
state
ArchiveState
detail
Human-facing one-liner explaining the state, including WHY.
generated_at
string
archive
{ snapshot_digest: string | null; coverage_to_block: number | null; promoted_at…
source
{ tip_height: number | null; finalized_height: number | null; decoder_head: num…
lag
{ blocks_behind_finalized: number | null; blocks_behind_tip: number | null; sec…
audit
{ complete: boolean; checked_at: string; } | null
signature
string
key_id
string

List a loaded archive's partitions, optionally filtered.

Runs locally on the manifest you already loaded and makes no request. Filter by dataset (blocks, transactions, events, or state_writes when the archive publishes it) and a block range.

sl.archive.partitions(
ref: LoadedArchive,
filter?: { dataset?: ArchiveDataset; fromBlock?: number; toBlock?: number },
): ArchivePartition[]

Parameters

hover a row to find it in the code

Required

ref.manifestrequiredArchiveManifest
ref.originrequiredstring
ref.rootrequiredstring
ref.isRemoterequiredboolean
ref.signaturerequired{ verified: boolean; reason?: string }

Options

filter.datasetArchiveDataset
filter.fromBlocknumber
filter.toBlocknumber
Returns ArchivePartition[]
dataset
string
from_block
number
to_block
number
path
string
row_count
number
byte_size
number
sha256
string

Price a fetch against your balance before you pay for it.

Nothing is charged. flow is bootstrap or repair. The quote has the bundle count, the price in USD, the free repair allowance applied, your balance, and sufficient. Needs an account key (sk-sl_*), not an instance token.

sl.archive.quote(input: { paths: string[]; flow: ArchiveFlow }): Promise<ArchiveQuote>

Parameters

hover a row to find it in the code

Required

pathsrequiredstring[]
flowrequiredArchiveFlow
Returns Promise<ArchiveQuote>
partitions
number
bundles
number
usdMicros
number
usd
string
freeAllowanceAppliedMicros
number
allowanceRemainingBundles
number
balanceUsdMicros
number
sufficient
boolean

Get presigned download URLs for archive partitions.

Draws credits per partition bundle; your first six repair bundles each month are free. Lists longer than 64 paths go out in batches of 64. Each URL is short-lived (expiresAt); pass it to download. An empty balance throws InsufficientArchiveCreditsError with the shortfall. Needs an account key (sk-sl_*).

sl.archive.fetch(
input: { paths: string[]; flow: ArchiveFlow },
): Promise<ArchiveFetchResult>
fetch.tsts
import { SecondLayer } from "@secondlayer/sdk";
const sl = new SecondLayer({
apiKey: process.env.SECONDLAYER_API_KEY,
});
const manifest = await sl.archive.latest();
const wanted = sl.archive.partitions(manifest, {
dataset: "blocks",
fromBlock: 0,
toBlock: 99_999,
});
const paths = wanted.map((p) => p.path);
const quote = await sl.archive.quote({ paths, flow: "bootstrap" });
^Prices the fetch against your balance. Nothing is charged yet.
if (!quote.sufficient) {
console.error(`need $${quote.usd}, balance is short`);
process.exit(2);
}
const { urls } = await sl.archive.fetch({ paths, flow: "bootstrap" });
^This is the step that draws credits. Each URL is short-lived.
for (const partition of wanted) {
const url = urls.find((u) => u.path === partition.path)?.url;
const bytes = await sl.archive.download(partition, { url });
^Checks the sha256 against the manifest before returning the bytes.
await Bun.write(`archive/${partition.path}`, bytes);
}

Parameters

hover a row to find it in the code

Required

pathsrequiredstring[]
flowrequiredArchiveFlow
Returns Promise<ArchiveFetchResult>
urls
ArchiveFetchItem[]
chargedTotalUsdMicros
number
balanceAfterUsdMicros
number

Download a partition's bytes and verify them.

The sha256 is checked against the manifest, and a mismatch throws ArchiveSignatureError. On the official archive host you must pass the presigned url from fetch, or it throws a ValidationError; any other host downloads straight from its archive tree.

sl.archive.download(
partition: ArchivePartition,
opts?: { url?: string },
): Promise<Uint8Array>

Parameters

hover a row to find it in the code

Required

partition.datasetrequiredstring
partition.from_blockrequirednumber
partition.to_blockrequirednumber
partition.pathrequiredstring
partition.row_countrequirednumber
partition.byte_sizerequirednumber
partition.sha256requiredstring

Options

opts.urlstring

Get your archive credit balance.

Returns creditsUsdMicros (millionths of a dollar, as a string) and your auto-refill setting. Needs an account key (sk-sl_*).

sl.archive.credits.balance(): Promise<ArchiveCreditsBalance>
Returns Promise<ArchiveCreditsBalance>
creditsUsdMicros
string
refill
{ belowUsd: number | null; packUsd: number | null; lastAt: string | null }

Start a card checkout for a credit pack.

pack is the dollar amount: 10, 25, 50, or 100. Resolves to the checkout url. Needs no account key.

sl.archive.credits.checkout(
input: { email: string; pack: 10 | 25 | 50 | 100 },
): Promise<{ url: string }>

Parameters

hover a row to find it in the code

Required

emailrequiredstring
packrequired10 | 25 | 50 | 100

Set or turn off automatic credit refill.

Pass belowUsd and packUsd to buy a pack whenever the balance drops below the threshold, or { off: true } to stop. Needs an account key (sk-sl_*).

sl.archive.credits.refill(
input: { belowUsd: number; packUsd: 10 | 25 | 50 | 100 } | { off: true },
): Promise<{ belowUsd: number | null; packUsd: number | null }>

Parameters

hover a row to find it in the code

Required

inputrequired{ belowUsd: number; packUsd: 10 | 25 | 50 | 100 } | { o…

Check your instance's data against a signed archive.

Runs POST /v1/archive/verify on your instance: read-only, and it compares raw identity digests only (the deep semantic check is CLI-only). Resolves to clean, diverged, or unanchored; a failed signature is unanchored, never clean. Narrow the check with fromBlock and toBlock. Verification is free.

sl.archive.verify(input: ArchiveVerifyInput): Promise<ArchiveVerifyResult>
verify.tsts
import { SecondLayer } from "@secondlayer/sdk";
const sl = new SecondLayer({
apiKey: process.env.SECONDLAYER_API_KEY,
});
const result = await sl.archive.verify({
against: "https://archive.secondlayer.tools/latest.json",
fromBlock: 0,
toBlock: 99_999,
});
for (const range of result.ranges) {
if (range.status === "match") continue;
console.log(
`${range.dataset} ${range.from_block}-${range.to_block}: ${range.status}`,
);
}
if (result.status === "unanchored") process.exit(2);
^Could not check, so it is never success: the archive was unreachable or its signature failed.
if (result.status === "diverged") process.exit(1);
console.log("local data matches the archive");

Parameters

hover a row to find it in the code

Required

againstrequiredstring

Options

targetstring
fromBlocknumber
toBlocknumber
insecureboolean
publicKeyPemstring
Returns Promise<ArchiveVerifyResult>
status
"clean" | "diverged" | "unanchored"
target
string
against
string
signature
{ verified: boolean; reason?: string }
coverage
{ from_block: number; to_block: number }
ranges
{ dataset: string; from_block: number; to_block: number; status: ArchiveVerifyR…
reason
string
ArchiveCreditsBalance
Your archive credit balance and its refill settings.
ArchiveDataset
One archive dataset: blocks, transactions, events or state writes.
ArchiveFetchItem
path, url, expiresAt, chargedUsdMicros
ArchiveFetchResult
Download links for archive partitions and what they cost.
ArchiveFlow
Whether an archive purchase is a bootstrap or a repair.
ArchiveLoadOptions
Options for loading an archive manifest.
ArchiveManifest
network, coverage, partition_size_blocks, range_digests, partitions, signature, …
ArchivePartition
One archive file: dataset, block range, path, rows, bytes.
ArchiveQuote
The price of an archive request, after any free allowance.
ArchiveState
"fresh" | "lagging" | "stale" | "gap" | "failed-audit" | "source-unavailable"
ArchiveStatus
The archive's state, coverage, and a plain-language reason.
ArchiveVerifyInput
What to verify against, and the optional block range.
ArchiveVerifyRangeStatus
"match" | "digest-mismatch" | "count-mismatch" | "missing"
ArchiveVerifyResult
Whether the archive is clean, diverged, or unanchored, by range.
LoadedArchive
A loaded archive manifest with its origin and signature check.
RangeDigest
dataset, from_block, to_block, row_count, digest, digest_spec
RangeDigestDataset
"events" | "blocks" | "transactions" | "state_writes"
Edit on GitHub