.md

sl.index

Decoded rows: transfers, events, contract calls, blocks, transactions, sBTC, PoX and Runes. The same data the Index API serves over HTTP.

@secondlayer/sdk@15.5.054 methodsfrom source with openpkgIndex guideIndex API
ftTransfers(params)FtTransfersEnvelope<FtTransferField…Callable: index.ftTransfers(params) ≡ index.ftTransfers.list(params).
ftTransfers.list(params)FtTransfersEnvelope<FtTransferField…Read one page of fungible-token transfers, plus the cursor for the next.
ftTransfers.walk(params)AsyncIterable<FtTransferFields<F>>Iterate every fungible-token transfer, paging for you.
nftTransfers(params)NftTransfersEnvelope<NftTransferFie…Callable: index.nftTransfers(params) ≡ index.nftTransfers.list(params).
nftTransfers.list(params)NftTransfersEnvelope<NftTransferFie…Read one page of NFT transfers, plus the cursor for the next.
nftTransfers.walk(params)AsyncIterable<NftTransferFields<F>>Iterate every NFT transfer, paging for you.
events(params)EventsEnvelope<T, IndexEventFields<…Generic decoded events by event_type (the full /v1/index/events surface).
events.list(params)EventsEnvelope<T, IndexEventFields<…Read one page of decoded events of one type.
events.walk(params)AsyncIterable<IndexEventFields<T, F…Iterate every decoded event of one type, paging for you.
events.consume(params){ cursor: string | null; pages: num…Run a checkpointed, reorg-aware indexer over decoded events.
contractCalls.list(params)ContractCallsEnvelopeRead one page of decoded contract calls.
contractCalls.walk(params)AsyncIterable<IndexContractCall>Iterate every decoded contract call, paging for you.
contractCalls.consume(params){ cursor: string | null; pages: num…Run a checkpointed, reorg-aware indexer over contract calls.
canonical.list(params)CanonicalEnvelopeRead one page of the canonical block-hash map.
canonical.walk(params)AsyncIterable<IndexCanonicalBlock>Iterate every canonical block hash, paging for you.
stateWrites.list(params)StateWritesEnvelopeRead one page of the contract-state writes each block committed.
stateWrites.walk(params)AsyncIterable<IndexStateWrite>Iterate every state write, paging for you.
blocks.list(params)BlocksEnvelopeRead one page of canonical blocks.
blocks.walk(params)AsyncIterable<IndexBlock>Iterate every canonical block, paging for you.
blocks.get(ref)BlockEnvelope | nullGet one block by height or hash, or null.
transactions.list(params)TransactionsEnvelope<TransactionFie…Read one page of full transaction documents.
transactions.walk(params)AsyncIterable<IndexTransaction>Iterate every transaction document, paging for you.
transactions.get(txId)TransactionEnvelope | nullGet one transaction by id, or null.
transactions.getProof(txId)TransactionProof | nullGet a transaction's inclusion proof, or null.
stacking.list(params)StackingEnvelopeRead one page of decoded PoX-4 stacking actions.
stacking.walk(params)AsyncIterable<IndexStackingAction>Iterate every PoX-4 stacking action, paging for you.
mempool.list(params)MempoolEnvelopeRead one page of pending, unconfirmed transactions.
mempool.walk(params)AsyncIterable<IndexMempoolTransacti…Iterate every pending transaction, paging for you.
mempool.get(txId)MempoolTransactionEnvelope | nullGet one pending transaction, or null.
sbtc.deposits.list(params)SbtcDepositsEnvelope<SbtcDepositFie…Read one page of completed sBTC deposits.
sbtc.deposits.walk(params)AsyncIterable<IndexSbtcDeposit>Iterate every completed sBTC deposit, paging for you.
sbtc.deposits.consume(params){ cursor: string | null; pages: num…Run a checkpointed, reorg-aware indexer over completed deposits.
sbtc.deposits.get(bitcoinTxid)SbtcDepositEnvelope | nullFetch a completed deposit by Bitcoin txid; 404 → null.
sbtc.withdrawals.list(params)SbtcWithdrawalsEnvelope<SbtcWithdra…Read one page of sBTC withdrawals, each with its current status.
sbtc.withdrawals.walk(params)AsyncIterable<IndexSbtcWithdrawal>Iterate every sBTC withdrawal, paging for you.
sbtc.withdrawals.get(requestId)SbtcWithdrawalEnvelope | nullFetch a withdrawal's full lifecycle by request id; 404 → null.
sbtc.events.list(params)SbtcEventsEnvelopeRead one page of the raw sBTC peg event log.
sbtc.events.walk(params)AsyncIterable<IndexSbtcEvent>Iterate every sBTC peg event, paging for you.
sbtc.events.consume(params){ cursor: string | null; pages: num…Run a checkpointed, reorg-aware indexer over the raw peg event log.
sbtc.summary()SbtcSummaryEnvelopeGet the all-time sBTC peg scoreboard.
pox.cycles.list(params)PoxCyclesEnvelopeRead one page of PoX reward cycles, newest first.
pox.cycles.walk(params)AsyncIterable<IndexPoxCycle>Iterate every reward cycle, paging for you.
pox.cycles.get(rewardCycle)PoxCycleEnvelope | nullGet one reward cycle by number, or null.
pox5.events.list(params)Pox5EventsEnvelope<Pox5EventFields<…Read one page of decoded PoX-5 staking events.
pox5.events.walk(params)AsyncIterable<IndexPox5Event>Iterate every PoX-5 event, paging for you.
pox5.events.consume(params){ cursor: string | null; pages: num…Run a checkpointed, reorg-aware indexer over PoX-5 events.
runes.activity.list(params)RuneActivityEnvelope<IndexRuneEvent>Read one page of Rune etch, mint, transfer, and burn events.
runes.activity.walk(params)AsyncIterable<IndexRuneEvent>Iterate every Rune event, paging for you.
runes.list(params)RunesEnvelope<IndexRuneEntry>The rune catalog.
runes.get(rune)RuneEnvelope | nullGet one rune by id or name, or null.
runes.balances(params)RuneBalancesEnvelope<IndexRuneBalan…Current per-outpoint rune balances by address or outpoint.
bitcoin.outspend(txid, vout)BitcoinOutputUnspent | BitcoinOutpu…Whether a Bitcoin output is spent, and by which transaction.
discover()IndexDiscoveryGet the live vocabulary of what Index can query.
printSchema(contractId)PrintSchemaResponse | nullGet the print payload schema a contract actually emits.

Callable: index.ftTransfers(params) ≡ index.ftTransfers.list(params).

sl.index.ftTransfers(
params: FtTransfersListParams & { fields: readonly F[] },
): Promise<FtTransfersEnvelope<FtTransferFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime. Omitting block_time also lets the server skip the blocks join.

Options

cursorstring | null
fromCursorstring | null
limitnumber
contractIdstring
assetIdentifierstring
senderstring
recipientstring
fromHeightnumber
toHeightnumber
orderIndexOrder"desc" reads newest first. See IndexOrder.
Returns Promise<FtTransfersEnvelope<FtTransferFields<F>>>
events
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Read one page of fungible-token transfers, plus the cursor for the next.

Filter by contractId, assetIdentifier, sender, recipient, and a height range. Filters are equality only: there is no amount filter. order: "desc" reads newest first. Pass next_cursor back as cursor to continue. fields returns only those columns and narrows the row type; cursor, block_height, and event_type always come back. reorgs on the envelope lists forks that overlap the page.

sl.index.ftTransfers.list<const F extends keyof FtTransfer & string>(
params: FtTransfersListParams & { fields: readonly F[] },
): Promise<FtTransfersEnvelope<FtTransferFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime. Omitting block_time also lets the server skip the blocks join.

Options

cursorstring | null
fromCursorstring | null
limitnumber
contractIdstring
assetIdentifierstring
senderstring
recipientstring
fromHeightnumber
toHeightnumber
orderIndexOrder"desc" reads newest first. See IndexOrder.
Returns Promise<FtTransfersEnvelope<FtTransferFields<F>>>
events
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Iterate every fungible-token transfer, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip, or with order: "desc" when it reaches fromHeight (genesis by default). batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.ftTransfers.walk<const F extends keyof FtTransfer & string>(
params: {
cursor?: string | null;
fromHeight?: number;
toHeight?: number;
contractId?: string;
sender?: string;
recipient?: string;
assetIdentifier?: string;
fromCursor?: string | null;
fields?: readonly ("cursor" | "sender" | "recipient" | "block_height" | "event_type" | "block_time" | "tx_id" | "tx_index" | "event_index" | "contract_id" | "asset_identifier" | "amount")[];
order?: IndexOrder;
}
& PageRetryOptions
& { batchSize?: number; signal?: AbortSignal }
& { fields: readonly F[] },
): AsyncIterable<FtTransferFields<F>, any, any>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime. Omitting block_time also lets the server skip the blocks join.

Options

cursorstring | null
fromHeightnumber
toHeightnumber
contractIdstring
senderstring
recipientstring
assetIdentifierstring
fromCursorstring | null
6 more options
orderIndexOrder"desc" reads newest first. See IndexOrder.
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Callable: index.nftTransfers(params) ≡ index.nftTransfers.list(params).

sl.index.nftTransfers(
params: NftTransfersListParams & { fields: readonly F[] },
): Promise<NftTransfersEnvelope<NftTransferFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return (see FtTransfersListParams.fields).

Options

cursorstring | null
fromCursorstring | null
limitnumber
contractIdstring
assetIdentifierstring
senderstring
recipientstring
fromHeightnumber
toHeightnumber
orderIndexOrder"desc" reads newest first. See IndexOrder.
Returns Promise<NftTransfersEnvelope<NftTransferFields<F>>>
events
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Read one page of NFT transfers, plus the cursor for the next.

Filter by contractId, assetIdentifier, sender, recipient, and a height range. order: "desc" reads newest first. Pass next_cursor back as cursor to continue. fields returns only those columns and narrows the row type; cursor, block_height, and event_type always come back.

sl.index.nftTransfers.list<const F extends keyof NftTransfer & string>(
params: NftTransfersListParams & { fields: readonly F[] },
): Promise<NftTransfersEnvelope<NftTransferFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return (see FtTransfersListParams.fields).

Options

cursorstring | null
fromCursorstring | null
limitnumber
contractIdstring
assetIdentifierstring
senderstring
recipientstring
fromHeightnumber
toHeightnumber
orderIndexOrder"desc" reads newest first. See IndexOrder.
Returns Promise<NftTransfersEnvelope<NftTransferFields<F>>>
events
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Iterate every NFT transfer, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip, or with order: "desc" when it reaches fromHeight (genesis by default). batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.nftTransfers.walk<const F extends keyof NftTransfer & string>(
params: {
cursor?: string | null;
fromHeight?: number;
toHeight?: number;
contractId?: string;
sender?: string;
recipient?: string;
assetIdentifier?: string;
fromCursor?: string | null;
fields?: readonly ("cursor" | "sender" | "recipient" | "block_height" | "event_type" | "block_time" | "tx_id" | "tx_index" | "event_index" | "contract_id" | "asset_identifier" | "value")[];
order?: IndexOrder;
}
& PageRetryOptions
& { batchSize?: number; signal?: AbortSignal }
& { fields: readonly F[] },
): AsyncIterable<NftTransferFields<F>, any, any>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return (see FtTransfersListParams.fields).

Options

cursorstring | null
fromHeightnumber
toHeightnumber
contractIdstring
senderstring
recipientstring
assetIdentifierstring
fromCursorstring | null
6 more options
orderIndexOrder"desc" reads newest first. See IndexOrder.
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Generic decoded events by event_type (the full /v1/index/events surface). Callable: index.events(params) ≡ index.events.list(params).

sl.index.events(
params: EventsListParams<T> & { fields: readonly F[] },
): Promise<EventsEnvelope<T, IndexEventFields<T, F>>>

Parameters

hover a row to find it in the code

Required

eventTyperequiredTDecoded types or VM types (nested_contract_call, map_set, …).
fieldsrequiredreadonly F[]Return only these columns. The server projects the SELECT, so an unrequested field is physically absent — and the returned row type narrows to match, making a read of one a compile error rather than undefined. cursor, block_height, and event_type come back regardless: the first two are the consume contract, the third carries the discriminant. Don't list them. Cost note: this does NOT change your bill — Index meters per row read, not per field. What it buys is wire bytes, plus skipping the blocks join when block_time is omitted.

Options

cursorstring | null
fromCursorstring | null
limitnumber
contractIdstring | readonly string[]One id, or several to scope the sweep to a set of contracts (max 20). Mutually exclusive with trait.
assetIdentifierstring
senderstring
recipientstring
functionNamestring
9 more options
callerstring
mapstring
varNamestring
txIdstringRestrict to one transaction.
fromHeightnumber
toHeightnumber
orderIndexOrder"desc" reads newest first. See IndexOrder.
traitstringRestrict to contracts conforming to a trait/standard (e.g. "sip-010"). Mutually exclusive with contractId; contract-keyed event types only.
txContextbooleanJoin the submitting transaction into each event — populates tx_sender, tx_type, tx_status, tx_contract_id, tx_function_name. Off by default. Avoids a /v1/index/transactions call per event; for print events it's the only source of the submitting sender.
Returns Promise<EventsEnvelope<T, IndexEventFields<T, F>>>
events
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Read one page of decoded events of one type.

eventType is required: a decoded type (ft_transfer, print, ...) or a VM type (nested_contract_call, map_set, ...), and a literal narrows the row type. Scope with contractId (one id or up to 20) or trait, never both, plus assetIdentifier, sender, recipient, functionName, caller, map, varName, txId, and a height range. order: "desc" reads newest first. txContext: true joins the submitting transaction onto each event. fields returns only those columns and narrows the row type; it saves wire bytes but does not change what you are billed, since rows are metered, not columns.

sl.index.events.list<T extends IndexEventType, const F extends keyof IndexEventOf<T> & string>(
params: EventsListParams<T> & { fields: readonly F[] },
): Promise<EventsEnvelope<T, IndexEventFields<T, F>>>

Parameters

hover a row to find it in the code

Required

eventTyperequiredTDecoded types or VM types (nested_contract_call, map_set, …).
fieldsrequiredreadonly F[]Return only these columns. The server projects the SELECT, so an unrequested field is physically absent — and the returned row type narrows to match, making a read of one a compile error rather than undefined. cursor, block_height, and event_type come back regardless: the first two are the consume contract, the third carries the discriminant. Don't list them. Cost note: this does NOT change your bill — Index meters per row read, not per field. What it buys is wire bytes, plus skipping the blocks join when block_time is omitted.

Options

cursorstring | null
fromCursorstring | null
limitnumber
contractIdstring | readonly string[]One id, or several to scope the sweep to a set of contracts (max 20). Mutually exclusive with trait.
assetIdentifierstring
senderstring
recipientstring
functionNamestring
9 more options
callerstring
mapstring
varNamestring
txIdstringRestrict to one transaction.
fromHeightnumber
toHeightnumber
orderIndexOrder"desc" reads newest first. See IndexOrder.
traitstringRestrict to contracts conforming to a trait/standard (e.g. "sip-010"). Mutually exclusive with contractId; contract-keyed event types only.
txContextbooleanJoin the submitting transaction into each event — populates tx_sender, tx_type, tx_status, tx_contract_id, tx_function_name. Off by default. Avoids a /v1/index/transactions call per event; for print events it's the only source of the submitting sender.
Returns Promise<EventsEnvelope<T, IndexEventFields<T, F>>>
events
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Iterate every decoded event of one type, paging for you.

Takes the same filters as list, including eventType. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip, or with order: "desc" when it reaches fromHeight (genesis by default). batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.events.walk<T extends IndexEventType, const F extends keyof IndexEventOf<T> & string>(
params: {
cursor?: string | null;
fromHeight?: number;
toHeight?: number;
contractId?: string | readonly string[];
sender?: string;
recipient?: string;
assetIdentifier?: string;
fromCursor?: string | null;
functionName?: string;
trait?: string;
txContext?: boolean;
fields?: readonly (keyof Extract<IndexFtTransfer, { event_type: T; }> & keyof Extract<IndexNftTransfer, { event_type: T; }> & keyof Extract<IndexStxTransfer, { event_type: T; }> & keyof Extract<IndexStxMint, { event_type: T; }> & keyof Extract<IndexStxBurn, { event_type: T; }> & keyof Extract<IndexStxLock, { event_type: T; }> & keyof Extract<IndexFtMint, { event_type: T; }> & keyof Extract<IndexFtBurn, { event_type: T; }> & keyof Extract<IndexNftMint, { event_type: T; }> & keyof Extract<IndexNftBurn, { event_type: T; }> & keyof Extract<IndexPrint, { event_type: T; }> & keyof Extract<IndexNestedContractCall, { event_type: T; }> & keyof Extract<IndexVarSet, { event_type: T; }> & keyof Extract<IndexMapSet, { event_type: T; }> & keyof Extract<IndexMapInsert, { event_type: T; }> & keyof Extract<IndexMapDelete, { event_type: T; }> & string)[];
caller?: string;
order?: IndexOrder;
eventType: T;
map?: string;
varName?: string;
txId?: string;
}
& PageRetryOptions
& { batchSize?: number; signal?: AbortSignal }
& { fields: readonly F[] },
): AsyncIterable<IndexEventFields<T, F>, any, any>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Return only these columns. The server projects the SELECT, so an unrequested field is physically absent — and the returned row type narrows to match, making a read of one a compile error rather than undefined. cursor, block_height, and event_type come back regardless: the first two are the consume contract, the third carries the discriminant. Don't list them. Cost note: this does NOT change your bill — Index meters per row read, not per field. What it buys is wire bytes, plus skipping the blocks join when block_time is omitted.
eventTyperequiredTDecoded types or VM types (nested_contract_call, map_set, …).

Options

cursorstring | null
fromHeightnumber
toHeightnumber
contractIdstring | readonly string[]One id, or several to scope the sweep to a set of contracts (max 20). Mutually exclusive with trait.
senderstring
recipientstring
assetIdentifierstring
fromCursorstring | null
13 more options
functionNamestring
traitstringRestrict to contracts conforming to a trait/standard (e.g. "sip-010"). Mutually exclusive with contractId; contract-keyed event types only.
txContextbooleanJoin the submitting transaction into each event — populates tx_sender, tx_type, tx_status, tx_contract_id, tx_function_name. Off by default. Avoids a /v1/index/transactions call per event; for print events it's the only source of the submitting sender.
callerstring
orderIndexOrder"desc" reads newest first. See IndexOrder.
mapstring
varNamestring
txIdstringRestrict to one transaction.
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Run a checkpointed, reorg-aware indexer over decoded events.

Write your rows in onBatch and commit ctx.cursor in the same transaction; resume with fromCursor. Without fromCursor or fromHeight the API serves only its recent default window, so pass fromHeight: 0 for a full backfill. A reorg at or below your checkpoint calls onReorg, then the loop re-reads from the fork point. Delivery is at-least-once, so keep writes idempotent. With a sink, the checkpoint and rollback are handled for you. finalizedOnly holds delivery to finalized rows, so no reorg handling is needed. mode: "tail" (default) keeps polling at the tip; mode: "bounded" returns on the first empty page. Resolves to { cursor, pages, emptyPolls }.

sl.index.events.consume<T extends IndexEventType, TTx = never>(
params: {
fromHeight?: number;
toHeight?: number;
contractId?: string | readonly string[];
sender?: string;
recipient?: string;
assetIdentifier?: string;
functionName?: string;
trait?: string;
txContext?: boolean;
caller?: string;
eventType: T;
map?: string;
varName?: string;
txId?: string;
}
& IndexConsumeOptions<IndexEventOf<T>, EventsEnvelope<T, IndexEventOf<T>>, TTx>
& { sink?: ConsumerSink<TTx> },
): Promise<{ cursor: string | null; pages: number; emptyPolls: number }>
events.consume.tsts
import { Database } from "bun:sqlite";
import { SecondLayer } from "@secondlayer/sdk";
import { bunSqliteSink } from "@secondlayer/sdk/sinks/bun-sqlite";
const SBTC = "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token";
const db = new Database("transfers.db");
db.exec(`create table if not exists transfers (
cursor text primary key,
block_height integer not null,
sender text not null,
recipient text not null,
amount text not null
)`);
const sl = new SecondLayer({
apiKey: process.env.SECONDLAYER_API_KEY,
});
await sl.index.events.consume({
eventType: "ft_transfer",
contractId: SBTC,
fromHeight: 0,
^First run only: backfill from genesis. Ignored once the sink holds a cursor.
sink: bunSqliteSink(db, {
^Rows and the checkpoint commit together, and a reorg rolls back rows above the fork.
id: "sbtc-transfers",
tables: ["transfers"],
height: "block_height",
}),
onBatch: (events, _envelope, ctx) => {
for (const event of events) {

Parameters

hover a row to find it in the code

Required

eventTyperequiredT
onBatchrequired(items: TItem[], envelope: TEnvelope, ctx: ConsumerBatc…

Options

fromHeightnumberStart a fresh sweep at this height (e.g. 0 for genesis backfill). Ignored once a cursor exists (including a sink's committed cursor).
toHeightnumber
contractIdstring | readonly string[]
senderstring
recipientstring
assetIdentifierstring
functionNamestring
traitstring
21 more options
txContextboolean
callerstring
mapstring
varNamestring
txIdstring
fromCursorstring | nullResume from a committed checkpoint. Without it (and without fromHeight) the API serves only the recent default window.
mode"tail" | "bounded"tail (default) keeps polling at the tip; bounded returns on the first empty page.
finalizedOnlybooleanEmit only rows at or below the tip's finalized_height; the unfinalized tail is re-read each poll until it settles. Finalized data never reorgs, so onReorg is skipped entirely.
batchSizenumber
sinkConsumerSink<TTx>
onProgress(ctx: ConsumerBatchContext) => voidFires once per page, before onBatch and before any early return — an empty page still proves the loop is alive. Feed it to consumerHealth().record.
onReorg(reorg: IndexReorg, ctx: { cursor: string | null }) => …Called once per new reorg at or below the checkpoint, before the loop rewinds to ctx.cursor (null = pre-genesis) and re-reads. A reorg whose fork sits ABOVE the checkpoint is not a rollback: nothing past it was written, so it is noted and the page is read as normal.
maxRollbackDepthnumberDeepest rewind one reorg may make below the checkpoint before the loop refuses with ValidationError. Default 1000 blocks. The fork point is server supplied and drives a delete on every declared table, so raise this only for a source you trust.
sleepSleep
emptyBackoffMsnumber
maxPagesnumber
maxEmptyPollsnumber
signalAbortSignal
retryCountnumberPage-fetch retries after the first failure (429/5xx/network only — 4xx and handler throws always propagate). Default 3; 0 disables.
retryDelaynumberBase retry delay in ms; the n-th retry waits retryDelay * n. A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep. Cannot change the retry decision — the policy owns it.
Callback context ctx: ConsumerBatchContext
cursor
Checkpoint to commit alongside your rows.
height
Highest canonical block a row was DELIVERED from. null before the first row of a fresh consume. With a sparse filter this parks at the last matching event — it measures event recency, not progress.
scannedHeight
Highest canonical block the sweep has VERIFIED through: an empty page is the server confirming nothing matches between the cursor and the tip, so a caught-up tail scans to the tip even when height is far below it. Rolls back with reorg rewinds.
tipHeight
Chain tip as of this page's read.
blocksBehind
tipHeight - scannedHeight, floored at 0 — the consumer's actual backlog. null until a position is known. A caught-up consumer on a quiet contract reads ~0 here while tipHeight - height grows — that difference is event age, not lag.
tip
The full tip for this page — StreamsTip or IndexTip depending on the surface. Exposed here so a handler never needs the envelope parameter, which is the only way to reach it today and is also how the worst finalizedOnly mistake becomes reachable (return envelope.next_cursor jumps the cursor past events that were filtered out and never delivered).
reorgs
Reorgs reported alongside this page; empty when none. Rollback still belongs in onReorg — this is for observability inside a batch.

Read one page of decoded contract calls.

Filter by contractId (one id or up to 20) or trait, never both, plus functionName, sender, and a height range. Each row has the function name, arguments, result, and status. Pass next_cursor back as cursor to continue.

sl.index.contractCalls.list(
params?: ContractCallsListParams,
): Promise<ContractCallsEnvelope>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
limitnumber
contractIdstring | readonly string[]One id, or several to scope the sweep to a set of contracts (max 20). Mutually exclusive with trait.
functionNamestring
senderstring
fromHeightnumber
toHeightnumber
traitstringRestrict to contracts conforming to a trait/standard (e.g. "sip-010"). Mutually exclusive with contractId.
Returns Promise<ContractCallsEnvelope>
contract_calls
IndexContractCall[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Iterate every decoded contract call, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.contractCalls.walk(
params?: ContractCallsWalkParams,
): AsyncIterable<IndexContractCall, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
contractIdstring | readonly string[]One id, or several to scope the sweep to a set of contracts (max 20). Mutually exclusive with trait.
senderstring
fromCursorstring | null
functionNamestring
traitstringRestrict to contracts conforming to a trait/standard (e.g. "sip-010"). Mutually exclusive with contractId.
5 more options
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Run a checkpointed, reorg-aware indexer over contract calls.

Write your rows in onBatch and commit ctx.cursor in the same transaction; resume with fromCursor. Without fromCursor or fromHeight the API serves only its recent default window, so pass fromHeight: 0 for a full backfill. A reorg at or below your checkpoint calls onReorg, then the loop re-reads from the fork point. Delivery is at-least-once, so keep writes idempotent. With a sink, the checkpoint and rollback are handled for you. finalizedOnly holds delivery to finalized rows, so no reorg handling is needed. mode: "tail" (default) keeps polling at the tip; mode: "bounded" returns on the first empty page. Resolves to { cursor, pages, emptyPolls }. Calls already carry sender and function_name, so there is no txContext.

sl.index.contractCalls.consume(
params: {
fromHeight?: number;
toHeight?: number;
contractId?: string | readonly string[];
sender?: string;
functionName?: string;
trait?: string;
}
& IndexConsumeOptions<IndexContractCall, ContractCallsEnvelope, TTx>
& { sink?: ConsumerSink<TTx> },
): Promise<{ cursor: string | null; pages: number; emptyPolls: number }>

Parameters

hover a row to find it in the code

Required

onBatchrequired(items: TItem[], envelope: TEnvelope, ctx: ConsumerBatc…

Options

fromHeightnumberStart a fresh sweep at this height (e.g. 0 for genesis backfill). Ignored once a cursor exists (including a sink's committed cursor).
toHeightnumber
contractIdstring | readonly string[]
senderstring
functionNamestring
traitstring
fromCursorstring | nullResume from a committed checkpoint. Without it (and without fromHeight) the API serves only the recent default window.
mode"tail" | "bounded"tail (default) keeps polling at the tip; bounded returns on the first empty page.
14 more options
finalizedOnlybooleanEmit only rows at or below the tip's finalized_height; the unfinalized tail is re-read each poll until it settles. Finalized data never reorgs, so onReorg is skipped entirely.
batchSizenumber
sinkConsumerSink<TTx>
onProgress(ctx: ConsumerBatchContext) => voidFires once per page, before onBatch and before any early return — an empty page still proves the loop is alive. Feed it to consumerHealth().record.
onReorg(reorg: IndexReorg, ctx: { cursor: string | null }) => …Called once per new reorg at or below the checkpoint, before the loop rewinds to ctx.cursor (null = pre-genesis) and re-reads. A reorg whose fork sits ABOVE the checkpoint is not a rollback: nothing past it was written, so it is noted and the page is read as normal.
maxRollbackDepthnumberDeepest rewind one reorg may make below the checkpoint before the loop refuses with ValidationError. Default 1000 blocks. The fork point is server supplied and drives a delete on every declared table, so raise this only for a source you trust.
sleepSleep
emptyBackoffMsnumber
maxPagesnumber
maxEmptyPollsnumber
signalAbortSignal
retryCountnumberPage-fetch retries after the first failure (429/5xx/network only — 4xx and handler throws always propagate). Default 3; 0 disables.
retryDelaynumberBase retry delay in ms; the n-th retry waits retryDelay * n. A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep. Cannot change the retry decision — the policy owns it.
Callback context ctx: ConsumerBatchContext
cursor
Checkpoint to commit alongside your rows.
height
Highest canonical block a row was DELIVERED from. null before the first row of a fresh consume. With a sparse filter this parks at the last matching event — it measures event recency, not progress.
scannedHeight
Highest canonical block the sweep has VERIFIED through: an empty page is the server confirming nothing matches between the cursor and the tip, so a caught-up tail scans to the tip even when height is far below it. Rolls back with reorg rewinds.
tipHeight
Chain tip as of this page's read.
blocksBehind
tipHeight - scannedHeight, floored at 0 — the consumer's actual backlog. null until a position is known. A caught-up consumer on a quiet contract reads ~0 here while tipHeight - height grows — that difference is event age, not lag.
tip
The full tip for this page — StreamsTip or IndexTip depending on the surface. Exposed here so a handler never needs the envelope parameter, which is the only way to reach it today and is also how the worst finalizedOnly mistake becomes reachable (return envelope.next_cursor jumps the cursor past events that were filtered out and never delivered).
reorgs
Reorgs reported alongside this page; empty when none. Rollback still belongs in onReorg — this is for observability inside a batch.

Read one page of the canonical block-hash map.

Each row is a block's hash, its parent hash, and its burn-chain anchor. Compare it with your own tables to confirm you follow the current chain.

sl.index.canonical.list(params?: CanonicalListParams): Promise<CanonicalEnvelope>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
limitnumber
fromHeightnumber
toHeightnumber
Returns Promise<CanonicalEnvelope>
canonical
IndexCanonicalBlock[]
next_cursor
string | null
tip
IndexTip

Iterate every canonical block hash, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.canonical.walk(
params?: CanonicalWalkParams,
): AsyncIterable<IndexCanonicalBlock, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
fromCursorstring | null
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Read one page of the contract-state writes each block committed.

Rows are the exact key and value writes, in the node's write order (ordinal), so you can see which key a transaction changed when events alone do not show it. Filter by blockHeight (excludes fromHeight and toHeight) or contractId. txContext: true joins the writing transaction. Rows exist only from the height your node first subscribed to state writes.

sl.index.stateWrites.list(params?: StateWritesListParams): Promise<StateWritesEnvelope>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
limitnumber
fromHeightnumber
toHeightnumber
blockHeightnumberOne block. Excludes fromHeight/toHeight; a cursor must sit at it.
contractIdstringOne contract (<address>.<name>): only keys under vm::<contractId>::.
txContextbooleanJoin the writing transaction's tx_* fields onto each row.
Returns Promise<StateWritesEnvelope>
state_writes
IndexStateWrite[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Iterate every state write, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.stateWrites.walk(
params?: StateWritesWalkParams,
): AsyncIterable<IndexStateWrite, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
contractIdstringOne contract (<address>.<name>): only keys under vm::<contractId>::.
fromCursorstring | null
blockHeightnumberOne block. Excludes fromHeight/toHeight; a cursor must sit at it.
txContextbooleanJoin the writing transaction's tx_* fields onto each row.
retryCountnumberRetries after the first failure. Default 3; 0 disables.
4 more options
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Read one page of canonical blocks.

Each block has its hash, parent hash, burn-chain anchor, and block_time. Filter by a height range.

sl.index.blocks.list(params?: BlocksListParams): Promise<BlocksEnvelope>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
limitnumber
fromHeightnumber
toHeightnumber
Returns Promise<BlocksEnvelope>
blocks
IndexBlock[]
next_cursor
string | null
tip
IndexTip

Iterate every canonical block, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.blocks.walk(params?: BlocksWalkParams): AsyncIterable<IndexBlock, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
fromCursorstring | null
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Get one block by height or hash, or null.

Resolves to null when no such block exists (404).

sl.index.blocks.get(ref: string | number): Promise<BlockEnvelope | null>

Parameters

hover a row to find it in the code

Required

refrequiredstring | number
Returns Promise<BlockEnvelope | null>
block
IndexBlock
tip
IndexTip

Read one page of full transaction documents.

Filter by type, sender, contractId, and a height range. Each document has the decoded post conditions and the payload for its tx_type; enrichment fields are null when the raw transaction cannot be decoded. fields returns only those columns and narrows the row type; cursor, block_height, and tx_id always come back.

sl.index.transactions.list(
params: TransactionsListParams & { fields: readonly F[] },
): Promise<TransactionsEnvelope<TransactionFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.

Options

cursorstring | null
fromCursorstring | null
limitnumber
typestring
senderstring
contractIdstring
fromHeightnumber
toHeightnumber
Returns Promise<TransactionsEnvelope<TransactionFields<F>>>
transactions
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]

Iterate every transaction document, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.transactions.walk(
params?: TransactionsWalkParams,
): AsyncIterable<IndexTransaction, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
contractIdstring
senderstring
fromCursorstring | null
fieldsreadonly ("cursor" | "sender" | "block_height" | "block…Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.
typestring
5 more options
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Get one transaction by id, or null.

Resolves to null when the transaction is not found (404).

sl.index.transactions.get(txId: string): Promise<TransactionEnvelope | null>

Parameters

hover a row to find it in the code

Required

txIdrequiredstring
Returns Promise<TransactionEnvelope | null>
transaction
IndexTransaction
tip
IndexTip

Get a transaction's inclusion proof, or null.

The proof is the raw transaction, the Nakamoto block header, and the merkle path. Check it yourself with verifyTransactionProof; nothing in it needs to be trusted. Resolves to null on 404. A 503 (PROOF_TX_SET_INCOMPLETE or PROOF_NODE_UNAVAILABLE) throws an ApiError: the proof cannot be assembled on this deployment right now.

sl.index.transactions.getProof(txId: string): Promise<TransactionProof | null>
transactions.getProof.tsts
import { SecondLayer, verifyTransactionProof } from "@secondlayer/sdk";
const txId = process.argv[2];
if (!txId) throw new Error("usage: bun transactions.getProof.ts <tx_id>");
const sl = new SecondLayer({
apiKey: process.env.SECONDLAYER_API_KEY,
});
const proof = await sl.index.transactions.getProof(txId);
if (!proof) throw new Error(`no proof for ${txId}`);
^Null when the transaction is not found.
const result = verifyTransactionProof(proof);
^Recomputes the txid, merkle path, and header hash locally. Nothing in the proof is trusted.
console.log(result.level, result.ok ? "verified" : result.errors.join("; "));

Parameters

hover a row to find it in the code

Required

txIdrequiredstring
Returns Promise<TransactionProof | null>
txid
string
index_block_hash
string
block_height
number
tx_index
number
raw_tx
Raw consensus-serialized transaction bytes (hex).
raw_header
Raw Nakamoto block-header bytes (hex) — parsed + re-hashed by the verifier.
tx_merkle_path
Authentication path from the tx leaf to tx_merkle_root.
consensus
Present when consensus-level verification is available: the reward cycle and its signer set, against which the header's signer signatures are checked.

Read one page of decoded PoX-4 stacking actions.

One row per stacking contract call. Filter by functionName, stacker, caller, and a height range. The feed is empty, with a notes hint, when the instance's PoX-4 decoder is disabled. For the current PoX, use pox5.events and pox.cycles.

sl.index.stacking.list(params?: StackingListParams): Promise<StackingEnvelope>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
limitnumber
functionNamestring
stackerstring
callerstring
fromHeightnumber
toHeightnumber
Returns Promise<StackingEnvelope>
stacking
IndexStackingAction[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]
notes
Present only when the PoX-4 decoder is disabled, explaining an empty feed.

Iterate every PoX-4 stacking action, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.stacking.walk(
params?: StackingWalkParams,
): AsyncIterable<IndexStackingAction, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
fromCursorstring | null
functionNamestring
stackerstring
callerstring
retryCountnumberRetries after the first failure. Default 3; 0 disables.
4 more options
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Read one page of pending, unconfirmed transactions.

Filter by sender, type, contractId, and functionName. There is no height filter: rows carry received_at and a sequence cursor instead of a block position.

sl.index.mempool.list(params?: MempoolListParams): Promise<MempoolEnvelope>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
limitnumber
senderstring
typestring
contractIdstringFilter to pending calls to a single contract (e.g. SP….contract).
functionNamestringFilter to pending calls to a single function (composes with contractId).
Returns Promise<MempoolEnvelope>
mempool
IndexMempoolTransaction[]
next_cursor
string | null
tip
IndexTip

Iterate every pending transaction, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.mempool.walk(
params?: MempoolWalkParams,
): AsyncIterable<IndexMempoolTransaction, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
contractIdstringFilter to pending calls to a single contract (e.g. SP….contract).
senderstring
fromCursorstring | null
functionNamestringFilter to pending calls to a single function (composes with contractId).
typestring
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
3 more options
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Get one pending transaction, or null.

Resolves to null once the transaction has confirmed or dropped.

sl.index.mempool.get(txId: string): Promise<MempoolTransactionEnvelope | null>

Parameters

hover a row to find it in the code

Required

txIdrequiredstring
Returns Promise<MempoolTransactionEnvelope | null>
transaction
IndexMempoolTransaction
tip
IndexTip

Read one page of completed sBTC deposits.

Filter by sender, bitcoinTxid, and a height range. confirmed: true keeps only deposits past the finality boundary. fields returns only those columns and narrows the row type; cursor and block_height always come back.

sl.index.sbtc.deposits.list(
params: SbtcDepositsListParams & { fields: readonly F[] },
): Promise<SbtcDepositsEnvelope<SbtcDepositFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.

Options

cursorstring | null
fromCursorstring | null
limitnumber
confirmedbooleanClamp to the finality boundary — only settled deposits past the reorg margin.
senderstring
bitcoinTxidstring
fromHeightnumber
toHeightnumber
Returns Promise<SbtcDepositsEnvelope<SbtcDepositFields<F>>>
deposits
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]
notes
Present only when the sBTC decoder is disabled, explaining an empty feed.

Iterate every completed sBTC deposit, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.sbtc.deposits.walk(
params?: SbtcDepositsWalkParams,
): AsyncIterable<IndexSbtcDeposit, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
senderstring
fromCursorstring | null
fieldsreadonly ("cursor" | "sender" | "block_height" | "block…Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.
confirmedbooleanClamp to the finality boundary — only settled deposits past the reorg margin.
bitcoinTxidstring
5 more options
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Run a checkpointed, reorg-aware indexer over completed deposits.

Deposits are append-only, so they are safe to mirror. See IndexConsumeOptions.

sl.index.sbtc.deposits.consume(
params: {
fromHeight?: number;
toHeight?: number;
sender?: string;
confirmed?: boolean;
bitcoinTxid?: string;
}
& IndexConsumeOptions<IndexSbtcDeposit, SbtcDepositsEnvelope<IndexSbtcDeposit>, TTx>
& { sink?: ConsumerSink<TTx> },
): Promise<{ cursor: string | null; pages: number; emptyPolls: number }>

Parameters

hover a row to find it in the code

Required

onBatchrequired(items: TItem[], envelope: TEnvelope, ctx: ConsumerBatc…

Options

fromHeightnumberStart a fresh sweep at this height (e.g. 0 for genesis backfill). Ignored once a cursor exists (including a sink's committed cursor).
toHeightnumber
senderstring
confirmedboolean
bitcoinTxidstring
fromCursorstring | nullResume from a committed checkpoint. Without it (and without fromHeight) the API serves only the recent default window.
mode"tail" | "bounded"tail (default) keeps polling at the tip; bounded returns on the first empty page.
finalizedOnlybooleanEmit only rows at or below the tip's finalized_height; the unfinalized tail is re-read each poll until it settles. Finalized data never reorgs, so onReorg is skipped entirely.
13 more options
batchSizenumber
sinkConsumerSink<TTx>
onProgress(ctx: ConsumerBatchContext) => voidFires once per page, before onBatch and before any early return — an empty page still proves the loop is alive. Feed it to consumerHealth().record.
onReorg(reorg: IndexReorg, ctx: { cursor: string | null }) => …Called once per new reorg at or below the checkpoint, before the loop rewinds to ctx.cursor (null = pre-genesis) and re-reads. A reorg whose fork sits ABOVE the checkpoint is not a rollback: nothing past it was written, so it is noted and the page is read as normal.
maxRollbackDepthnumberDeepest rewind one reorg may make below the checkpoint before the loop refuses with ValidationError. Default 1000 blocks. The fork point is server supplied and drives a delete on every declared table, so raise this only for a source you trust.
sleepSleep
emptyBackoffMsnumber
maxPagesnumber
maxEmptyPollsnumber
signalAbortSignal
retryCountnumberPage-fetch retries after the first failure (429/5xx/network only — 4xx and handler throws always propagate). Default 3; 0 disables.
retryDelaynumberBase retry delay in ms; the n-th retry waits retryDelay * n. A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep. Cannot change the retry decision — the policy owns it.
Callback context ctx: ConsumerBatchContext
cursor
Checkpoint to commit alongside your rows.
height
Highest canonical block a row was DELIVERED from. null before the first row of a fresh consume. With a sparse filter this parks at the last matching event — it measures event recency, not progress.
scannedHeight
Highest canonical block the sweep has VERIFIED through: an empty page is the server confirming nothing matches between the cursor and the tip, so a caught-up tail scans to the tip even when height is far below it. Rolls back with reorg rewinds.
tipHeight
Chain tip as of this page's read.
blocksBehind
tipHeight - scannedHeight, floored at 0 — the consumer's actual backlog. null until a position is known. A caught-up consumer on a quiet contract reads ~0 here while tipHeight - height grows — that difference is event age, not lag.
tip
The full tip for this page — StreamsTip or IndexTip depending on the surface. Exposed here so a handler never needs the envelope parameter, which is the only way to reach it today and is also how the worst finalizedOnly mistake becomes reachable (return envelope.next_cursor jumps the cursor past events that were filtered out and never delivered).
reorgs
Reorgs reported alongside this page; empty when none. Rollback still belongs in onReorg — this is for observability inside a batch.

Fetch a completed deposit by Bitcoin txid; 404 → null.

sl.index.sbtc.deposits.get(bitcoinTxid: string): Promise<SbtcDepositEnvelope | null>

Parameters

hover a row to find it in the code

Required

bitcoinTxidrequiredstring
Returns Promise<SbtcDepositEnvelope | null>
deposit
IndexSbtcDepositDetail
tip
IndexTip

Read one page of sBTC withdrawals, each with its current status.

Filter by status (REQUESTED, ACCEPTED, REJECTED), sender, requestId, settlementConfirmed, and a height range. A row changes as the peg-out moves along, which is why withdrawals have no consume. fields returns only those columns and narrows the row type; cursor and request_id always come back.

sl.index.sbtc.withdrawals.list(
params: SbtcWithdrawalsListParams & { fields: readonly F[] },
): Promise<SbtcWithdrawalsEnvelope<SbtcWithdrawalFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.

Options

cursorstring | null
fromCursorstring | null
limitnumber
confirmedboolean
statusSbtcWithdrawalStatus
senderstring
requestIdnumber
settlementConfirmedbooleanFilter by BTC L1 settlement: true → only confirmed sweeps; false → not yet confirmed (pending or no sweep).
fromHeightnumber
toHeightnumber
Returns Promise<SbtcWithdrawalsEnvelope<SbtcWithdrawalFields<F>…
withdrawals
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]
notes
string

Iterate every sBTC withdrawal, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.sbtc.withdrawals.walk(
params?: SbtcWithdrawalsWalkParams,
): AsyncIterable<IndexSbtcWithdrawal, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
senderstring
fromCursorstring | null
statusSbtcWithdrawalStatus
fieldsreadonly ("cursor" | "sender" | "amount" | "status" | "…Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.
confirmedboolean
7 more options
requestIdnumber
settlementConfirmedbooleanFilter by BTC L1 settlement: true → only confirmed sweeps; false → not yet confirmed (pending or no sweep).
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Fetch a withdrawal's full lifecycle by request id; 404 → null.

sl.index.sbtc.withdrawals.get(requestId: number): Promise<SbtcWithdrawalEnvelope | null>

Parameters

hover a row to find it in the code

Required

requestIdrequirednumber
Returns Promise<SbtcWithdrawalEnvelope | null>
withdrawal
IndexSbtcWithdrawalDetail
tip
IndexTip

Read one page of the raw sBTC peg event log.

Filter by topic, sender, requestId, bitcoinTxid, and a height range. confirmed: true keeps only events past the finality boundary.

sl.index.sbtc.events.list(params?: SbtcEventsListParams): Promise<SbtcEventsEnvelope>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
limitnumber
confirmedboolean
topicSbtcEventTopic
senderstring
requestIdnumber
bitcoinTxidstring
fromHeightnumber
toHeightnumber
Returns Promise<SbtcEventsEnvelope>
events
IndexSbtcEvent[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]
notes
string

Iterate every sBTC peg event, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.sbtc.events.walk(
params?: SbtcEventsWalkParams,
): AsyncIterable<IndexSbtcEvent, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
senderstring
fromCursorstring | null
confirmedboolean
bitcoinTxidstring
requestIdnumber
6 more options
topicSbtcEventTopic
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Run a checkpointed, reorg-aware indexer over the raw peg event log.

The log is append-only across all six topics. See IndexConsumeOptions.

sl.index.sbtc.events.consume(
params: {
fromHeight?: number;
toHeight?: number;
sender?: string;
confirmed?: boolean;
bitcoinTxid?: string;
requestId?: number;
topic?: SbtcEventTopic;
}
& IndexConsumeOptions<IndexSbtcEvent, SbtcEventsEnvelope, TTx>
& { sink?: ConsumerSink<TTx> },
): Promise<{ cursor: string | null; pages: number; emptyPolls: number }>

Parameters

hover a row to find it in the code

Required

onBatchrequired(items: TItem[], envelope: TEnvelope, ctx: ConsumerBatc…

Options

fromHeightnumberStart a fresh sweep at this height (e.g. 0 for genesis backfill). Ignored once a cursor exists (including a sink's committed cursor).
toHeightnumber
senderstring
confirmedboolean
bitcoinTxidstring
requestIdnumber
topicSbtcEventTopic
fromCursorstring | nullResume from a committed checkpoint. Without it (and without fromHeight) the API serves only the recent default window.
15 more options
mode"tail" | "bounded"tail (default) keeps polling at the tip; bounded returns on the first empty page.
finalizedOnlybooleanEmit only rows at or below the tip's finalized_height; the unfinalized tail is re-read each poll until it settles. Finalized data never reorgs, so onReorg is skipped entirely.
batchSizenumber
sinkConsumerSink<TTx>
onProgress(ctx: ConsumerBatchContext) => voidFires once per page, before onBatch and before any early return — an empty page still proves the loop is alive. Feed it to consumerHealth().record.
onReorg(reorg: IndexReorg, ctx: { cursor: string | null }) => …Called once per new reorg at or below the checkpoint, before the loop rewinds to ctx.cursor (null = pre-genesis) and re-reads. A reorg whose fork sits ABOVE the checkpoint is not a rollback: nothing past it was written, so it is noted and the page is read as normal.
maxRollbackDepthnumberDeepest rewind one reorg may make below the checkpoint before the loop refuses with ValidationError. Default 1000 blocks. The fork point is server supplied and drives a delete on every declared table, so raise this only for a source you trust.
sleepSleep
emptyBackoffMsnumber
maxPagesnumber
maxEmptyPollsnumber
signalAbortSignal
retryCountnumberPage-fetch retries after the first failure (429/5xx/network only — 4xx and handler throws always propagate). Default 3; 0 disables.
retryDelaynumberBase retry delay in ms; the n-th retry waits retryDelay * n. A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep. Cannot change the retry decision — the policy owns it.
Callback context ctx: ConsumerBatchContext
cursor
Checkpoint to commit alongside your rows.
height
Highest canonical block a row was DELIVERED from. null before the first row of a fresh consume. With a sparse filter this parks at the last matching event — it measures event recency, not progress.
scannedHeight
Highest canonical block the sweep has VERIFIED through: an empty page is the server confirming nothing matches between the cursor and the tip, so a caught-up tail scans to the tip even when height is far below it. Rolls back with reorg rewinds.
tipHeight
Chain tip as of this page's read.
blocksBehind
tipHeight - scannedHeight, floored at 0 — the consumer's actual backlog. null until a position is known. A caught-up consumer on a quiet contract reads ~0 here while tipHeight - height grows — that difference is event age, not lag.
tip
The full tip for this page — StreamsTip or IndexTip depending on the surface. Exposed here so a handler never needs the envelope parameter, which is the only way to reach it today and is also how the worst finalizedOnly mistake becomes reachable (return envelope.next_cursor jumps the cursor past events that were filtered out and never delivered).
reorgs
Reorgs reported alongside this page; empty when none. Rollback still belongs in onReorg — this is for observability inside a batch.

Get the all-time sBTC peg scoreboard.

A single aggregate, with no pagination.

sl.index.sbtc.summary(): Promise<SbtcSummaryEnvelope>
Returns Promise<SbtcSummaryEnvelope>
summary
IndexSbtcSummary
tip
IndexTip
notes
string

Read one page of PoX reward cycles, newest first.

cursor is a reward_cycle number, and the page returns the cycles below it. next_cursor is the next cycle number to page from, or null at the end. This reports the current PoX (PoX-5); PoX-4 history is not served here, so read stacking for it.

sl.index.pox.cycles.list(params?: PoxCyclesListParams): Promise<PoxCyclesEnvelope>

Parameters

hover a row to find it in the code

Options

cursornumber | nullA reward_cycle to page from; the page returns cycles below it (descending).
limitnumber
Returns Promise<PoxCyclesEnvelope>
pox_version
The PoX version this response reports. Currently 5.
cycles
IndexPoxCycle[]
next_cursor
The next reward_cycle to page from (cycles descend), or null at the end.
tip
IndexTip

Iterate every reward cycle, paging for you.

Takes the same filters as list (it pages by reward cycle number). Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.pox.cycles.walk(
params?: PoxCyclesWalkParams,
): AsyncIterable<IndexPoxCycle, any, any>

Parameters

hover a row to find it in the code

Options

cursornumber | nullA reward_cycle to page from; the page returns cycles below it (descending).
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Get one reward cycle by number, or null.

Resolves to null on 404: an unknown cycle, or one below pox-5's first reward cycle (141), whose PoX-4 history is final and not served here.

sl.index.pox.cycles.get(rewardCycle: number): Promise<PoxCycleEnvelope | null>

Parameters

hover a row to find it in the code

Required

rewardCyclerequirednumber
Returns Promise<PoxCycleEnvelope | null>
pox_version
5
cycle
IndexPoxCycle & { signers: IndexPoxCycleSigner[] }
tip
IndexTip

Read one page of decoded PoX-5 staking events.

Filter by topic, staker, signer, signerManager, bondIndex, rewardCycle, and a height range. confirmed: true keeps only rows past the finality boundary. fields returns only those columns and narrows the row type; cursor, block_height, and topic always come back.

sl.index.pox5.events.list(
params: Pox5EventsListParams & { fields: readonly F[] },
): Promise<Pox5EventsEnvelope<Pox5EventFields<F>>>

Parameters

hover a row to find it in the code

Required

fieldsrequiredreadonly F[]Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.

Options

cursorstring | null
fromCursorstring | null
limitnumber
confirmedbooleanClamp to the finality boundary — only rows past the reorg margin.
topicIndexPox5EventTopic
stakerstring
signerstring
signerManagerstring
4 more options
bondIndexnumber
rewardCyclenumber
fromHeightnumber
toHeightnumber
Returns Promise<Pox5EventsEnvelope<Pox5EventFields<F>>>
events
TRow[]
next_cursor
string | null
tip
IndexTip
reorgs
IndexReorg[]
notes
Present only when the PoX-5 decoder is disabled, explaining an empty feed.

Iterate every PoX-5 event, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.pox5.events.walk(
params?: Pox5EventsWalkParams,
): AsyncIterable<IndexPox5Event, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
fromCursorstring | null
fieldsreadonly ("cursor" | "block_height" | "block_time" | "t…Columns to return. The server projects the row, so an unrequested column is physically absent — and the narrowing overload on list makes reading one a compile error rather than undefined at runtime.
confirmedbooleanClamp to the finality boundary — only rows past the reorg margin.
topicIndexPox5EventTopic
stakerstring
9 more options
signerstring
signerManagerstring
bondIndexnumber
rewardCyclenumber
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

Run a checkpointed, reorg-aware indexer over PoX-5 events.

The pox-5 print log is append-only across all 19 topics. See IndexConsumeOptions.

sl.index.pox5.events.consume(
params: {
fromHeight?: number;
toHeight?: number;
fields?: readonly ("cursor" | "block_height" | "block_time" | "tx_id" | "tx_index" | "event_index" | "topic" | "staker" | "signer" | "signer_manager" | "bond_index" | "amount_ustx" | "amount_sats" | "reward_cycle" | "first_reward_cycle" | "unlock_cycle" | "unlock_burn_height" | "is_l1_lock" | "signer_key" | "data")[];
confirmed?: boolean;
topic?: IndexPox5EventTopic;
staker?: string;
signer?: string;
signerManager?: string;
bondIndex?: number;
rewardCycle?: number;
}
& IndexConsumeOptions<IndexPox5Event, Pox5EventsEnvelope<IndexPox5Event>, TTx>
& { sink?: ConsumerSink<TTx> },
): Promise<{ cursor: string | null; pages: number; emptyPolls: number }>

Parameters

hover a row to find it in the code

Required

onBatchrequired(items: TItem[], envelope: TEnvelope, ctx: ConsumerBatc…

Options

fromHeightnumberStart a fresh sweep at this height (e.g. 0 for genesis backfill). Ignored once a cursor exists (including a sink's committed cursor).
toHeightnumber
fieldsreadonly ("cursor" | "block_height" | "block_time" | "t…
confirmedboolean
topicIndexPox5EventTopic
stakerstring
signerstring
signerManagerstring
18 more options
bondIndexnumber
rewardCyclenumber
fromCursorstring | nullResume from a committed checkpoint. Without it (and without fromHeight) the API serves only the recent default window.
mode"tail" | "bounded"tail (default) keeps polling at the tip; bounded returns on the first empty page.
finalizedOnlybooleanEmit only rows at or below the tip's finalized_height; the unfinalized tail is re-read each poll until it settles. Finalized data never reorgs, so onReorg is skipped entirely.
batchSizenumber
sinkConsumerSink<TTx>
onProgress(ctx: ConsumerBatchContext) => voidFires once per page, before onBatch and before any early return — an empty page still proves the loop is alive. Feed it to consumerHealth().record.
onReorg(reorg: IndexReorg, ctx: { cursor: string | null }) => …Called once per new reorg at or below the checkpoint, before the loop rewinds to ctx.cursor (null = pre-genesis) and re-reads. A reorg whose fork sits ABOVE the checkpoint is not a rollback: nothing past it was written, so it is noted and the page is read as normal.
maxRollbackDepthnumberDeepest rewind one reorg may make below the checkpoint before the loop refuses with ValidationError. Default 1000 blocks. The fork point is server supplied and drives a delete on every declared table, so raise this only for a source you trust.
sleepSleep
emptyBackoffMsnumber
maxPagesnumber
maxEmptyPollsnumber
signalAbortSignal
retryCountnumberPage-fetch retries after the first failure (429/5xx/network only — 4xx and handler throws always propagate). Default 3; 0 disables.
retryDelaynumberBase retry delay in ms; the n-th retry waits retryDelay * n. A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep. Cannot change the retry decision — the policy owns it.
Callback context ctx: ConsumerBatchContext
cursor
Checkpoint to commit alongside your rows.
height
Highest canonical block a row was DELIVERED from. null before the first row of a fresh consume. With a sparse filter this parks at the last matching event — it measures event recency, not progress.
scannedHeight
Highest canonical block the sweep has VERIFIED through: an empty page is the server confirming nothing matches between the cursor and the tip, so a caught-up tail scans to the tip even when height is far below it. Rolls back with reorg rewinds.
tipHeight
Chain tip as of this page's read.
blocksBehind
tipHeight - scannedHeight, floored at 0 — the consumer's actual backlog. null until a position is known. A caught-up consumer on a quiet contract reads ~0 here while tipHeight - height grows — that difference is event age, not lag.
tip
The full tip for this page — StreamsTip or IndexTip depending on the surface. Exposed here so a handler never needs the envelope parameter, which is the only way to reach it today and is also how the worst finalizedOnly mistake becomes reachable (return envelope.next_cursor jumps the cursor past events that were filtered out and never delivered).
reorgs
Reorgs reported alongside this page; empty when none. Rollback still belongs in onReorg — this is for observability inside a batch.

Read one page of Rune etch, mint, transfer, and burn events.

Filter by rune (an id or a name), address, kind, txid, and a height range. The cursor is <block_height>:<event_index>, and the envelope's tip is a Bitcoin tip. notes says so when Runes is not configured on the instance.

sl.index.runes.activity.list(
params?: RuneActivityListParams,
): Promise<RuneActivityEnvelope<IndexRuneEvent>>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromCursorstring | null
fromHeightnumber
toHeightnumber
limitnumber
runeRuneRef
addressstring
kindreadonly IndexRuneEventKind[]
txidstring
Returns Promise<RuneActivityEnvelope<IndexRuneEvent>>
events
TRow[]
next_cursor
string | null
tip
IndexBitcoinTip
reorgs
IndexBtcReorg[]
notes
string

Iterate every Rune event, paging for you.

Takes the same filters as list. Not a live index: it does not checkpoint, ignores reorgs, and ends when it catches the tip. batchSize defaults to 200 (max 1000); page fetches retry on 429 and 5xx; aborting signal rejects the iterator.

sl.index.runes.activity.walk(
params?: RuneActivityWalkParams,
): AsyncIterable<IndexRuneEvent, any, any>

Parameters

hover a row to find it in the code

Options

cursorstring | null
fromHeightnumber
toHeightnumber
fromCursorstring | null
runeRuneRef
addressstring
kindreadonly IndexRuneEventKind[]
txidstring
5 more options
retryCountnumberRetries after the first failure. Default 3; 0 disables.
retryDelaynumberBase delay in ms; the n-th retry waits retryDelay * n (matches the stacks transport). A server Retry-After overrides it. Default 1000.
onError(err: unknown, ctx: { attempt: number; retriesLeft: num…Void observer, called before each retry sleep (metrics/logging). The retry policy owns the decision; this cannot change it.
batchSizenumberRows per page request. Default 200, max INDEX_MAX_PAGE_SIZE (1000).
signalAbortSignal

The rune catalog. search prefix-matches the name; sort is etch order (default) or busiest-first.

sl.index.runes.list(params?: RunesListParams): Promise<RunesEnvelope<IndexRuneEntry>>

Parameters

hover a row to find it in the code

Options

searchstringName prefix, spacers and case ignored (dog matches DOG•GO•TO•THE•MOON).
sort"number" | "mints"number (etch order, oldest first — default) or mints (busiest first).
cursorstring | null
limitnumber
Returns Promise<RunesEnvelope<IndexRuneEntry>>
runes
TRow[]
next_cursor
string | null
tip
IndexBitcoinTip
reorgs
Always empty: list reads a reorg-corrected snapshot table, not an append-only log — there is no stale page to reconcile.
notes
Present only when Runes data is not configured on this instance.

Get one rune by id or name, or null.

Resolves to null on 404: no such rune, or Runes isn't configured on this instance.

sl.index.runes.get(rune: RuneRef): Promise<RuneEnvelope | null>

Parameters

hover a row to find it in the code

Required

runerequiredRuneRef
Returns Promise<RuneEnvelope | null>
rune
IndexRuneEntry
tip
IndexBitcoinTip

Current per-outpoint rune balances by address or outpoint.

sl.index.runes.balances(
params: RuneBalancesListParams,
): Promise<RuneBalancesEnvelope<IndexRuneBalance>>

Parameters

hover a row to find it in the code

Required

paramsrequiredRuneBalancesListParams
Returns Promise<RuneBalancesEnvelope<IndexRuneBalance>>
balances
TRow[]
next_cursor
string | null
tip
IndexBitcoinTip
reorgs
Always empty — see RunesEnvelope.reorgs.
notes
string

Whether a Bitcoin output is spent, and by which transaction.

A mempool spend shows on the next read (mempool: true); a confirmed one names its block. Resolves to null on 404: no such transaction, no output at vout, or an OP_RETURN output.

sl.index.bitcoin.outspend(
txid: string,
vout: number,
): Promise<BitcoinOutputUnspent | BitcoinOutputSpent | null>

Parameters

hover a row to find it in the code

Required

txidrequiredstring
voutrequirednumber
Returns Promise<BitcoinOutputUnspent | BitcoinOutputSpent | nul…
txid
string
vout
number
spent
false

Get the live vocabulary of what Index can query.

The discovery doc lists every endpoint and each event type's columns, allowed and equality filters, and required-non-null fields. Read it to learn what's queryable (and which types accept trait) instead of hardcoding.

sl.index.discover(): Promise<IndexDiscovery>
Returns Promise<IndexDiscovery>
event_type_filters
Record<string, IndexEventTypeFilters>

sl.index.printSchema(contractId)

REST GET /v1/index/contracts/{contractId}/print-schemasource

Get the print payload schema a contract actually emits.

Lists the topics it emits and each field's observed Clarity, TS, and column types. Anonymous read; resolves to null on 404.

sl.index.printSchema(contractId: string): Promise<PrintSchemaResponse | null>

Parameters

hover a row to find it in the code

Required

contractIdrequiredstring
Returns Promise<PrintSchemaResponse | null>
contract_id
string
topics
InferredTopicSchema[]
sampled
boolean
total_events
number
total_events_capped
True when the count hit the server-side cap (total_events is the cap).
sample
{ size: number; newest_height: number | null; oldest_height: number | null }
tip
IndexTip
BitcoinOutputSpent
A Bitcoin output that some transaction spends.
BitcoinOutputUnspent
A Bitcoin output that no transaction spends yet.
BlockEnvelope
One block and the chain tip.
BlocksEnvelope
One page of blocks, with the next cursor and chain tip.
BlocksListParams
Paging and height filters for listing blocks.
BlocksWalkParams
BlocksListParams without limit, plus walk options.
CanonicalEnvelope
One page of canonical blocks, with the next cursor and chain tip.
CanonicalListParams
Paging and height filters for listing canonical blocks.
CanonicalWalkParams
CanonicalListParams without limit, plus walk options.
ColumnType
Supported column types for subgraph schemas
ConsumerBatchContext
What the loop knows at the end of a page, handed to onBatch.
ConsumerSink
A consumer sink: the destination adapter a consume loop writes through.
ContractCallsEnvelope
One page of contract calls, with the cursor, tip, and reorgs.
ContractCallsListParams
Paging and contract filters for listing contract calls.
ContractCallsWalkParams
ContractCallsListParams without limit, plus walk options.
EventsEnvelope
One page of decoded events, with the cursor, tip, and reorgs.
EventsListParams
Event type, paging, and filters for listing decoded events.
EventsWalkParams
EventsListParams without limit, plus walk options.
FtTransfer
A decoded fungible-token transfer: sender, recipient, asset, amount.
FtTransferFields
An ft-transfer row narrowed to the requested columns plus the always-present ones.
FtTransfersEnvelope
One page of fungible-token transfers, with the cursor, tip, and reorgs.
FtTransfersListParams
Column selection, paging, and filters for listing token transfers.
FtTransfersWalkParams
FtTransfersListParams without limit, plus walk options.
IndexBitcoinTip
The Bitcoin chain tip a Runes read was served against — a separate clock from the Stacks IndexTip: Runes ingest tracks Bitcoin blocks, not Stacks ones.
IndexBlock
A block resource.
IndexBtcReorg
A Bitcoin fork the Runes indexer rolled back.
IndexCanonicalBlock
One canonical block in the sync map.
IndexConsumeOptions
Consumer options shared by index.events.consume and index.contractCalls.consume.
IndexContractCall
A decoded contract call: contract, function, sender, arguments, result.
IndexDiscovery
The GET /v1/index discovery doc: live endpoints and filter vocabulary.
IndexEventFields
An event row narrowed to a fields selection (plus what always ships).
IndexEventOf
The single decoded-event member matching one event_type literal.
IndexEventTypeFilters
Per-event-type filter vocabulary in the IndexDiscovery doc.
IndexFtBurn
A fungible-token burn event.
IndexFtMint
A fungible-token mint event.
IndexFtTransfer
A fungible-token transfer event.
IndexMapDelete
A contract map entry deletion.
IndexMapInsert
A new contract map entry.
IndexMapSet
A contract map entry overwrite.
IndexMempoolTransaction
A pending (unconfirmed) transaction.
IndexNestedContractCall
A contract call made from inside another contract call.
IndexNftBurn
A non-fungible-token burn event.
IndexNftMint
A non-fungible-token mint event.
IndexNftTransfer
A non-fungible-token transfer event.
IndexOrder
Read direction for decoded-event lists.
IndexPostCondition
{ type: "stx"; principal: string; condition_code: number; condition_code_name: string | null; amount: string;…
IndexPox5Event
A raw decoded PoX-5 print event.
IndexPoxCycle
One pox-5 reward cycle, exact to the node.
IndexPoxCycleSigner
One signer's share of a pox-5 reward cycle.
IndexPrint
A contract print event with its topic and value.
IndexReorg
A chain reorg overlapping a returned page's height range.
IndexRuneBalance
A rune's balance on one unspent output, with the rune's identity embedded.
IndexRuneEntry
One etched rune: identity, counters, supply, and mint terms.
IndexRuneEvent
One rune etch, mint, transfer, or burn, with the rune's identity.
IndexRuneEventKind
"rune_etch" | "rune_mint" | "rune_transfer" | "rune_burn"
IndexRuneRefSummary
The rune identity bundle every Runes response embeds, so a client never needs a second lookup just to show a name next to an event or a balance.
IndexRuneTerms
Mint terms, or null for a premine-only rune that was never mintable.
IndexSbtcDeposit
A completed sBTC peg-in, keyed by bitcoin_txid (deposits carry no request_id).
IndexSbtcDepositDetail
A deposit fetched by Bitcoin txid — always terminal, hence status.
IndexSbtcEvent
A raw decoded sBTC protocol-state event, one per event.
IndexSbtcSummary
The peg "scoreboard" — a single all-time canonical aggregate.
IndexSbtcWithdrawal
A peg-out as one row per request, with its latest status.
IndexSbtcWithdrawalDetail
A single peg-out's full assembled lifecycle, fetched by request_id.
IndexSbtcWithdrawalPhase
One phase of a withdrawal's lifecycle (the on-Stacks event that drove it).
IndexStackingAction
A decoded PoX-4 stacking action (one per stacking contract call).
IndexStateWrite
One MARF write a block committed, in the node's write order.
IndexStxBurn
An STX burn event.
IndexStxLock
An STX lock event with its unlock height.
IndexStxMint
An STX mint event.
IndexStxTransfer
An STX transfer event.
IndexTip
block_height, finalized_height, lag_seconds
IndexTransaction
Full transaction document: columnar fields plus raw_tx-decoded enrichment.
IndexVarSet
A contract data variable write.
InferredPrintField
name, camel_name, clarity_type, ts_type, column_type, always_present, …
InferredTopicSchema
The fields seen in one print topic, with counts and heights.
MempoolEnvelope
One page of pending transactions, with the next cursor and chain tip.
MempoolListParams
Paging and sender filters for listing pending transactions.
MempoolTransactionEnvelope
One pending transaction and the chain tip.
MempoolWalkParams
MempoolListParams without limit, plus walk options.
MerkleProofStep
One authentication-path step: the sibling hash and which side it's on.
NftTransfer
A decoded non-fungible-token transfer: sender, recipient, asset, value.
NftTransferFields
An nft-transfer row narrowed to the requested columns plus the always-present ones.
NftTransfersEnvelope
One page of non-fungible-token transfers, with the cursor, tip, and reorgs.
NftTransfersListParams
Column selection, paging, and filters for listing NFT transfers.
NftTransfersWalkParams
NftTransfersListParams without limit, plus walk options.
PageRetryOptions
Options shared by both consume loops' page-fetch retry.
Pox5EventFields
A Pox5Event row narrowed to the requested columns plus the always-present ones.
Pox5EventsEnvelope
One page of PoX-5 events, with the cursor, tip, and reorgs.
Pox5EventsListParams
Column selection, paging, and filters for listing PoX-5 events.
Pox5EventsWalkParams
Pox5EventsListParams without limit, plus walk options.
PoxCycleEnvelope
One reward cycle with its signers and the chain tip.
PoxCyclesEnvelope
One page of reward cycles, newest first, with the next cursor.
PoxCyclesListParams
Paging for listing reward cycles.
PoxCyclesWalkParams
PoxCyclesListParams without limit, plus walk options.
PrintSchemaResponse
Per-topic print payload schema for a contract, inferred from sampled events.
RewardSet
signers, total_weight
RewardSetSigner
signing_key, weight
RuneActivityEnvelope
One page of rune events, with the cursor, Bitcoin tip, and reorgs.
RuneActivityListParams
Paging and height filters for listing rune events.
RuneActivityWalkParams
RuneActivityListParams without limit, plus walk options.
RuneBalancesEnvelope
One page of rune balances, with the cursor and Bitcoin tip.
RuneBalancesListParams
Rune balance filters; exactly one of address or outpoint.
RuneEnvelope
One rune and the Bitcoin tip.
RuneRef
A rune id or name, in any case, with or without spacers.
RunesEnvelope
One page of runes, with the cursor and Bitcoin tip.
RunesListParams
Name search, sort order, and paging for listing runes.
SbtcDepositEnvelope
One sBTC deposit and the chain tip.
SbtcDepositFields
A deposit row narrowed to the requested columns plus the always-present ones.
SbtcDepositsEnvelope
One page of sBTC deposits, with the cursor, tip, and reorgs.
SbtcDepositsListParams
Column selection, paging, and filters for listing sBTC deposits.
SbtcDepositsWalkParams
SbtcDepositsListParams without limit, plus walk options.
SbtcEventsEnvelope
One page of sBTC events, with the cursor, tip, and reorgs.
SbtcEventsListParams
Paging and filters for listing sBTC events.
SbtcEventsWalkParams
SbtcEventsListParams without limit, plus walk options.
SbtcSummaryEnvelope
The sBTC totals and the chain tip.
SbtcWithdrawalEnvelope
One sBTC withdrawal and the chain tip.
SbtcWithdrawalFields
A SbtcWithdrawal row narrowed to the requested columns plus the always-present ones.
SbtcWithdrawalsEnvelope
One page of sBTC withdrawals, with the cursor, tip, and reorgs.
SbtcWithdrawalsListParams
Column selection, paging, and filters for listing sBTC withdrawals.
SbtcWithdrawalStatus
"REQUESTED" | "ACCEPTED" | "REJECTED"
SbtcWithdrawalsWalkParams
SbtcWithdrawalsListParams without limit, plus walk options.
Sleep
(ms: number, signal?: AbortSignal) => Promise<void>
StackingEnvelope
One page of stacking actions, with the cursor, tip, and reorgs.
StackingListParams
Paging and filters for listing stacking actions.
StackingWalkParams
StackingListParams without limit, plus walk options.
StateWritesEnvelope
One page of contract state writes, with the cursor, tip, and reorgs.
StateWritesListParams
Paging and filters for listing contract state writes.
StateWritesWalkParams
StateWritesListParams without limit, plus walk options.
TransactionEnvelope
One transaction and the chain tip.
TransactionFields
A Transaction row narrowed to the requested columns plus the always-present ones.
TransactionProof
Trustless transaction-inclusion proof verification.
TransactionsEnvelope
One page of transactions, with the cursor, tip, and reorgs.
TransactionsListParams
Column selection, paging, and filters for listing transactions.
TransactionsWalkParams
TransactionsListParams without limit, plus walk options.
Edit on GitHub