declare const DECODED_EVENT_TYPES: readonly ["stx_transfer", "stx_mint", "stx_burn", "stx_lock", "ft_transfer", "ft_mint", "ft_burn", "nft_transfer", "nft_mint", "nft_burn", "print"]; type DecodedEventType = (typeof DECODED_EVENT_TYPES)[number]; /** Opt-in node vm_events, stored names. Parallel to DECODED_EVENT_TYPES — not * the decoded_events / Streams 1.0 vocab. Cursor second component is * ordinal. Inner calls are never `contract_call`. */ declare const VM_EVENT_TYPES: readonly ["nested_contract_call", "var_set", "map_set", "map_insert", "map_delete"]; type VmEventType = (typeof VM_EVENT_TYPES)[number]; /** Node `/new_block.vm_events[].type` → stored/Index/Streams name. One map, * shared by the indexer parser and any consumer that reads raw observer * bodies, so the two dialects cannot drift. Inner calls are never * `contract_call` (that is the signed outer tx). */ declare const VM_NODE_TO_STORED_TYPE: { readonly contract_call_event: "nested_contract_call" readonly var_set_event: "var_set" readonly map_set_event: "map_set" readonly map_insert_event: "map_insert" readonly map_delete_event: "map_delete" }; type VmNodeEventType = keyof typeof VM_NODE_TO_STORED_TYPE; /** Every chain-event filter member across all four surfaces: the 10 decoded * token/STX types, the three contract-shaped types (spelled as subgraphs and * triggers spell them — Index/Streams project `print_event` → `print`), and * the five sBTC lifecycle types (Webhooks-only). */ declare const CHAIN_EVENT_FILTER_TYPES: readonly ["stx_transfer", "stx_mint", "stx_burn", "stx_lock", "ft_transfer", "ft_mint", "ft_burn", "nft_transfer", "nft_mint", "nft_burn", "contract_call", "contract_deploy", "print_event", "nested_contract_call", "var_set", "map_set", "map_insert", "map_delete", "sbtc_deposit", "sbtc_withdrawal_create", "sbtc_withdrawal_accept", "sbtc_withdrawal_reject", "sbtc_withdrawal_swept_confirmed"]; type ChainEventFilterType = (typeof CHAIN_EVENT_FILTER_TYPES)[number]; type AbiUInt128 = "uint128"; type AbiInt128 = "int128"; type AbiBool = "bool"; type AbiPrincipal = "principal"; type AbiTraitReference = "trait_reference"; type AbiNone = "none"; type AbiStringAscii = { "string-ascii": { length: L } }; type AbiStringUtf8 = { "string-utf8": { length: L } }; type AbiBuffer = { buff: { length: L } }; type AbiPrimitiveType = AbiUInt128 | AbiInt128 | AbiBool | AbiPrincipal | AbiTraitReference | AbiNone | AbiStringAscii | AbiStringUtf8 | AbiBuffer; interface AbiListType { list: { type: AbiType length: number }; } interface AbiTupleType { tuple: ReadonlyArray<{ name: string type: AbiType }>; } interface AbiOptionalType { optional: AbiType; } interface AbiResponseType { response: { ok: AbiType error: AbiType }; } /** Discriminated union of all Clarity value types (primitives, buffers, lists, tuples, optionals, responses). */ type AbiType = AbiPrimitiveType | AbiListType | AbiTupleType | AbiOptionalType | AbiResponseType; type FunctionAccess = "public" | "read-only" | "private"; interface FunctionArg { name: string; type: AbiType; } /** A single Clarity function definition with name, access level, arguments, and return type. */ interface AbiFunction { name: string; access: FunctionAccess; args: ReadonlyArray; outputs: AbiType; } type VariableAccess = "constant" | "variable"; interface AbiVariable { name: string; type: AbiType; access: VariableAccess; } interface AbiMap { name: string; key: AbiType; value: AbiType; } interface AbiFungibleToken { name: string; } interface AbiNonFungibleToken { name: string; type: AbiType; } type TraitFunctionAccess = Exclude; interface AbiTraitFunction { name: string; access: TraitFunctionAccess; args: ReadonlyArray; outputs: AbiType; } interface AbiTraitDefinition { name: string; functions: ReadonlyArray; } /** Full Clarity contract ABI including functions, maps, variables, and token definitions. */ interface AbiContract { functions: ReadonlyArray; maps?: ReadonlyArray; variables?: ReadonlyArray; fungible_tokens?: ReadonlyArray; non_fungible_tokens?: ReadonlyArray; implemented_traits?: ReadonlyArray; defined_traits?: ReadonlyArray; } /** A validated Stacks principal (standard or contract). Branded so downstream * code can require "already validated" without re-checking. */ type Principal = string & { readonly __principal: unique symbol }; /** * `::` — the shape a fungible/non-fungible asset filter * takes, expressed so the compiler can check it. * * The most common mistake in this API is passing a CONTRACT ID * (`SP….sbtc-token`) where an asset identifier (`SP….sbtc-token::sbtc-token`) * belongs, and the failure mode is a query that quietly returns zero rows. The * two differ structurally by `::`, so a template-literal type catches it at the * call site — no brand, no cast, literals just work. * * A value that is only known at runtime (config, env) is not narrow enough on * purpose; run it through {@link assetId} once, which validates and narrows. * * Wildcard patterns (Webhooks/Subgraphs-only) are admitted by the second arm — they * are legitimately not full identifiers (`SPB.*`), and the runtime validator * short-circuits on them for the same reason. */ type AssetIdentifier = `${string}::${string}` | `${string}*${string}`; /** * Narrow a runtime string to an {@link AssetIdentifier}, validating it. * * The escape hatch for config-driven values: `assetId(process.env.ASSET!)` * throws on a contract id instead of letting it through to a zero-row query. */ declare function assetId(value: string): AssetIdentifier; /** `true` for a standard (`SP…`/`ST…`) or contract (`SP….name`) principal. * Shares {@link parsePrincipal} with the ABI guards so the two surfaces can't * disagree about what a principal is. */ declare function isPrincipal(value: string): value is Principal; /** Webhooks and Subgraph sources match `*` wildcards in * principal/identifier patterns; every * other surface treats the value literally. */ declare function hasWildcard(value: string): boolean; /** Throw unless `value` is a principal or a wildcard pattern. The factories * call this so a swapped argument (asset id where a sender belongs, typo'd * address) fails at construction — not as a silent zero-row query. */ declare function assertPrincipalish(field: string, value: string): void; /** Throw unless `value` looks like `SP….contract::asset` (or a wildcard). */ declare function assertAssetIdentifier(field: string, value: string): void; /** Throw unless `value` is a contract id `SP….name` (or a wildcard). */ declare function assertContractId(field: string, value: string): void; /** Scalar print field types (structural mirror of the subgraphs `ColumnType`). */ type PrintScalarType = "uint" | "int" | "text" | "principal" | "boolean" | "timestamp" | "jsonb"; /** * One declared print field — structural mirror of `PrintField` in * `@secondlayer/subgraphs`. Composite forms exist because real print payloads * nest: a vocabulary that could only say `"jsonb"` is what let a flat-field * declaration type-check while every event decoded to null. * * Kept literal through `toSubgraphSource()` so handler narrowing survives. */ type PrintFieldType = PrintScalarType | { type: PrintFieldType optional: true } | { tuple: Record } | { list: PrintFieldType }; interface StxTransferSpec { type: "stx_transfer"; sender?: string; recipient?: string; minAmount?: bigint; maxAmount?: bigint; } interface StxMintSpec { type: "stx_mint"; recipient?: string; minAmount?: bigint; } interface StxBurnSpec { type: "stx_burn"; sender?: string; minAmount?: bigint; } interface StxLockSpec { type: "stx_lock"; lockedAddress?: string; minAmount?: bigint; } /** Scope to contracts conforming to a trait/standard (e.g. "sip-010") instead * of a fixed contract. Index + Subgraphs + Webhooks; Streams has no * trait resolution — `toStreamsParams()` throws if set. */ type TraitScope = { trait?: string }; /** Scope to a DYNAMIC address set discovered from another source's events — * a Subgraphs-only concept (`toSubgraphSource()` keeps it; every other * projection throws). Structural mirror of the subgraphs `FactoryScope`: * `stacks` is the dependency-graph leaf and cannot import it. */ type FactoryScope = { factory?: { /** Source name whose events reveal the addresses. */ from: string /** Dotted path to the address on that source's payload (e.g. "data.pool"). */ field: string } }; interface FtTransferSpec extends TraitScope { type: "ft_transfer"; assetIdentifier?: AssetIdentifier; sender?: string; recipient?: string; minAmount?: bigint; } interface FtMintSpec extends TraitScope { type: "ft_mint"; assetIdentifier?: AssetIdentifier; recipient?: string; minAmount?: bigint; } interface FtBurnSpec extends TraitScope { type: "ft_burn"; assetIdentifier?: AssetIdentifier; sender?: string; minAmount?: bigint; } interface NftTransferSpec extends TraitScope { type: "nft_transfer"; assetIdentifier?: AssetIdentifier; sender?: string; recipient?: string; } interface NftMintSpec extends TraitScope { type: "nft_mint"; assetIdentifier?: AssetIdentifier; recipient?: string; } interface NftBurnSpec extends TraitScope { type: "nft_burn"; assetIdentifier?: AssetIdentifier; sender?: string; } interface ContractCallSpec extends TraitScope, FactoryScope { type: "contract_call"; /** One contract id, or a set of them (max 20). Mirrors the subgraphs * filter — a router plus its pools is one source, not N. */ contractId?: string | readonly string[]; functionName?: string; caller?: string; /** Contract ABI (`as const`) — preserved literally so `toSubgraphSource()` * keeps typing `event.input` in `defineSubgraph`. */ abi?: AbiContract; } interface ContractDeploySpec { type: "contract_deploy"; deployer?: string; contractName?: string; } interface NestedContractCallSpec extends TraitScope, FactoryScope { type: "nested_contract_call"; contractId?: string | readonly string[]; functionName?: string; caller?: string; sender?: string; } interface VarSetSpec extends TraitScope, FactoryScope { type: "var_set"; contractId?: string | readonly string[]; varName?: string; } interface MapSetSpec extends TraitScope, FactoryScope { type: "map_set"; contractId?: string | readonly string[]; map?: string; } interface MapInsertSpec extends TraitScope, FactoryScope { type: "map_insert"; contractId?: string | readonly string[]; map?: string; } interface MapDeleteSpec extends TraitScope, FactoryScope { type: "map_delete"; contractId?: string | readonly string[]; map?: string; } interface PrintEventSpec extends TraitScope, FactoryScope { type: "print_event"; /** One contract id, or a set of them (max 20). */ contractId?: string | readonly string[]; topic?: string; /** Per-topic field schema — preserved literally so `toSubgraphSource()` * keeps the discriminated-union narrowing of `event.data`. */ prints?: Record>; } interface SbtcDepositSpec { type: "sbtc_deposit"; sender?: string; minAmount?: bigint; maxAmount?: bigint; bitcoinTxid?: string; requestId?: number; } interface SbtcWithdrawalCreateSpec { type: "sbtc_withdrawal_create"; sender?: string; minAmount?: bigint; maxAmount?: bigint; requestId?: number; } interface SbtcWithdrawalAcceptSpec { type: "sbtc_withdrawal_accept"; requestId?: number; sweepTxid?: string; } interface SbtcWithdrawalRejectSpec { type: "sbtc_withdrawal_reject"; requestId?: number; } interface SbtcWithdrawalSweptConfirmedSpec { type: "sbtc_withdrawal_swept_confirmed"; requestId?: number; sweepTxid?: string; } type ChainEventFilterSpec = StxTransferSpec | StxMintSpec | StxBurnSpec | StxLockSpec | FtTransferSpec | FtMintSpec | FtBurnSpec | NftTransferSpec | NftMintSpec | NftBurnSpec | ContractCallSpec | ContractDeploySpec | NestedContractCallSpec | VarSetSpec | MapSetSpec | MapInsertSpec | MapDeleteSpec | PrintEventSpec | SbtcDepositSpec | SbtcWithdrawalCreateSpec | SbtcWithdrawalAcceptSpec | SbtcWithdrawalRejectSpec | SbtcWithdrawalSweptConfirmedSpec; type SpecFor = Extract; /** The members expressible as subgraph sources (everything but the * Webhooks-only sBTC lifecycle types). Instantiating * `ChainEventFilter` keeps `toSubgraphSource` present: * the conditional in `ProjectionsFor` evaluates over this whole union * (non-distributive at an instantiated site), and every member qualifies. */ type SubgraphMemberType = Exclude; /** A subgraph-source-shaped filter object (the `toSubgraphSource()` output / * `fromSubgraphSource()` input). */ type SubgraphSourceSpec = Extract; /** Wire shape of a chain trigger (Webhooks), derived per member from * the spec: same fields, with `bigint` amounts stringified (uint128 exceeds * JS safe integers) and the type-only `abi`/`prints` decorations dropped. * Structurally assignable to the SDK's `ChainTrigger` union. */ type ChainTriggerOf = { [K in keyof Omit] : Exclude | (bigint extends S[K] ? string : never) }; /** Loose trigger shape (any member). */ type ChainTriggerShape = ChainTriggerOf; /** Params fragment for `index.events.*` (spread into list/walk/consume). */ type IndexEventsParamsShape = { eventType: DecodedEventType | VmEventType /** A spec's contract set passes through verbatim (the API takes up to 20). */ contractId?: string | readonly string[] assetIdentifier?: AssetIdentifier sender?: string recipient?: string functionName?: string caller?: string map?: string varName?: string trait?: string }; /** Params fragment for `index.contractCalls.*`. */ type ContractCallsParamsShape = { /** A spec's contract set passes through verbatim (the API takes up to 20). */ contractId?: string | readonly string[] functionName?: string /** Populated from the spec's `caller` — the endpoint filters by tx sender, * which is the caller. */ sender?: string trait?: string }; type VmMember = "nested_contract_call" | "var_set" | "map_set" | "map_insert" | "map_delete"; /** Params fragment for classic `streams.events.*` (Streams 1.0). VM members * project to {@link StreamsVmParamsShape} instead — mixing the vocabularies * here makes `events.consume({ ...on.ftTransfer().toStreamsParams(), onBatch })` * fail type-check. */ type StreamsParamsShape = { types: readonly DecodedEventType[] contractId?: string | readonly string[] sender?: string recipient?: string assetIdentifier?: AssetIdentifier }; /** VM member projection: `clock` is the `"vm"` literal so SDK overload 1 matches. */ type StreamsVmParamsShape = { types: readonly [T] clock: "vm" contractId?: string | readonly string[] }; type DecodedMember = "stx_transfer" | "stx_mint" | "stx_burn" | "stx_lock" | "ft_transfer" | "ft_mint" | "ft_burn" | "nft_transfer" | "nft_mint" | "nft_burn" | "print_event"; type ProjectionsFor< T extends ChainEventFilterType, S > = { /** Wire trigger for `webhooks.create({ triggers: [...] })`. BigInt * amounts become strings here — the one sanctioned boundary. */ toChainTrigger(): ChainTriggerOf } & (T extends DecodedMember | VmMember ? { /** Params for `index.events.list/walk/consume` (merge your own * `limit`/`fromHeight`/`txContext` etc. on top). */ toIndexParams>(extra?: Extra): IndexEventsParamsShape & Extra /** Params for `streams.events.list/consume/stream`. Throws if the * filter uses `trait` (Streams has no trait resolution) or a * min/max amount (Streams filters have no amount predicates). */ toStreamsParams = Record>(extra?: Extra): T extends VmMember ? StreamsVmParamsShape & Extra : StreamsParamsShape & Extra } : {}) & (T extends "contract_call" ? { /** Params for `index.contractCalls.list/walk/consume`. */ toContractCallsParams>(extra?: Extra): ContractCallsParamsShape & Extra } : {}) & (T extends Exclude ? { /** The `sources` entry for `defineSubgraph` — literal `prints`/`abi` * types are preserved, so handler narrowing survives. */ toSubgraphSource(): S } : {}); /** * A canonical chain-event filter: the spec fields plus the projections its * member supports. Write the filter once; project it to a query * (`toIndexParams`), a stream (`toStreamsParams`), a webhook trigger * (`toChainTrigger`), or a subgraph source (`toSubgraphSource`). */ type ChainEventFilter< T extends ChainEventFilterType = ChainEventFilterType, S extends { type: T } = SpecFor > = S & ProjectionsFor; /** Build a canonical filter: validated spec + the projections its member * supports (methods are attached per member at runtime, matching the * type-level gating exactly). `const F` preserves field literals — a * `prints`/`abi` declaration keeps its exact type through * `toSubgraphSource()`, which is what feeds `defineSubgraph` narrowing. */ declare function makeChainEventFilter< T extends ChainEventFilterType, const F extends Omit, "type"> >(type: T, fields: F): ChainEventFilter; /** * Rehydrate a canonical filter from a subgraph-source-shaped object (the * inverse of `toSubgraphSource`). Powers migration and the round-trip * property gate: `toSubgraphSource(fromSubgraphSource(f))` must deep-equal * `f` for every production subgraph source. */ declare function fromSubgraphSource(source: SubgraphSourceSpec): ChainEventFilter; type Fields = Omit, "type">; /** The `on.*` namespace, annotated explicitly — bunup's dts emitter needs an * annotation on exported values (an inferred object of generic factories * collapses to `{}` in the emitted declarations). */ interface OnNamespace { stxTransfer(fields?: Fields<"stx_transfer">): ChainEventFilter<"stx_transfer">; stxMint(fields?: Fields<"stx_mint">): ChainEventFilter<"stx_mint">; stxBurn(fields?: Fields<"stx_burn">): ChainEventFilter<"stx_burn">; stxLock(fields?: Fields<"stx_lock">): ChainEventFilter<"stx_lock">; ftTransfer(fields?: Fields<"ft_transfer">): ChainEventFilter<"ft_transfer">; ftMint(fields?: Fields<"ft_mint">): ChainEventFilter<"ft_mint">; ftBurn(fields?: Fields<"ft_burn">): ChainEventFilter<"ft_burn">; nftTransfer(fields?: Fields<"nft_transfer">): ChainEventFilter<"nft_transfer">; nftMint(fields?: Fields<"nft_mint">): ChainEventFilter<"nft_mint">; nftBurn(fields?: Fields<"nft_burn">): ChainEventFilter<"nft_burn">; /** `abi` literals are preserved (`const A`) so `toSubgraphSource()` keeps * typing `event.input` inside `defineSubgraph`. */ contractCall(fields?: Omit, "type" | "abi"> & { abi?: A }): ChainEventFilter<"contract_call", { type: "contract_call" } & Omit, "type" | "abi"> & { abi?: A }>; contractDeploy(fields?: Fields<"contract_deploy">): ChainEventFilter<"contract_deploy">; /** Canonical member is `print_event` (as Subgraphs and Webhooks spell * it); `toIndexParams`/`toStreamsParams` project to `print`. `prints` * literals are preserved (`const P`) for per-topic `event.data` narrowing. */ print> | undefined = undefined>(fields?: Omit, "type" | "prints"> & { prints?: P }): ChainEventFilter<"print_event", { type: "print_event" } & Omit, "type" | "prints"> & { prints?: P }>; nestedCall(fields?: Fields<"nested_contract_call">): ChainEventFilter<"nested_contract_call">; varSet(fields?: Fields<"var_set">): ChainEventFilter<"var_set">; mapSet(fields?: Fields<"map_set">): ChainEventFilter<"map_set">; mapInsert(fields?: Fields<"map_insert">): ChainEventFilter<"map_insert">; mapDelete(fields?: Fields<"map_delete">): ChainEventFilter<"map_delete">; sbtcDeposit(fields?: Fields<"sbtc_deposit">): ChainEventFilter<"sbtc_deposit">; sbtcWithdrawalCreate(fields?: Fields<"sbtc_withdrawal_create">): ChainEventFilter<"sbtc_withdrawal_create">; sbtcWithdrawalAccept(fields?: Fields<"sbtc_withdrawal_accept">): ChainEventFilter<"sbtc_withdrawal_accept">; sbtcWithdrawalReject(fields?: Fields<"sbtc_withdrawal_reject">): ChainEventFilter<"sbtc_withdrawal_reject">; sbtcWithdrawalSweptConfirmed(fields?: Fields<"sbtc_withdrawal_swept_confirmed">): ChainEventFilter<"sbtc_withdrawal_swept_confirmed">; } /** * `on.*` — one filter vocabulary for every surface. * * ```ts * import { on } from "@secondlayer/stacks/filters"; * * const usdc = on.ftTransfer({ assetIdentifier: USDC, minAmount: 1_000_000n }); * * sl.index.events.list(usdc.toIndexParams({ limit: 100 })); // pull * sl.streams.events.consume({ ...usdc.toStreamsParams(), onBatch }); * sl.webhooks.create({ name, url, triggers: [usdc.toChainTrigger()] }); * defineSubgraph({ sources: { usdc: usdc.toSubgraphSource() }, schema, handlers }); * ``` * * A surface a member can't reach is a missing method (compile error), and a * field a surface can't express throws at projection time — never a silent * zero-row or over-wide match. */ declare const on: OnNamespace; export { AssetIdentifier, CHAIN_EVENT_FILTER_TYPES, ChainEventFilter, ChainEventFilterSpec, ChainEventFilterType, ChainTriggerOf, ChainTriggerShape, ContractCallSpec, ContractCallsParamsShape, ContractDeploySpec, DECODED_EVENT_TYPES, DecodedEventType, FtBurnSpec, FtMintSpec, FtTransferSpec, IndexEventsParamsShape, MapDeleteSpec, MapInsertSpec, MapSetSpec, NestedContractCallSpec, NftBurnSpec, NftMintSpec, NftTransferSpec, Principal, PrintEventSpec, PrintFieldType, PrintScalarType, SbtcDepositSpec, SbtcWithdrawalAcceptSpec, SbtcWithdrawalCreateSpec, SbtcWithdrawalRejectSpec, SbtcWithdrawalSweptConfirmedSpec, SpecFor, StreamsParamsShape, StreamsVmParamsShape, StxBurnSpec, StxLockSpec, StxMintSpec, StxTransferSpec, SubgraphMemberType, SubgraphSourceSpec, VM_EVENT_TYPES, VM_NODE_TO_STORED_TYPE, VarSetSpec, VmEventType, VmNodeEventType, assertAssetIdentifier, assertContractId, assertPrincipalish, assetId, fromSubgraphSource, hasWildcard, isPrincipal, makeChainEventFilter, on };