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]; /** 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 (Subscriptions-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", "sbtc_deposit", "sbtc_withdrawal_create", "sbtc_withdrawal_accept", "sbtc_withdrawal_reject", "sbtc_withdrawal_swept_confirmed"]; type ChainEventFilterType = (typeof CHAIN_EVENT_FILTER_TYPES)[number]; /** C32-encoded address version bytes for single-sig and multi-sig on each network. */ declare const AddressVersion: { readonly MainnetSingleSig: 22 readonly MainnetMultiSig: 20 readonly TestnetSingleSig: 26 readonly TestnetMultiSig: 21 }; type AddressVersion = (typeof AddressVersion)[keyof typeof AddressVersion]; /** Mainnet burn address (all-zero hash160). */ declare const ZERO_ADDRESS = "SP000000000000000000002Q6VF78"; /** Testnet burn address (all-zero hash160). */ declare const TESTNET_ZERO_ADDRESS = "ST000000000000000000002AMW42H"; /** Number of microSTX per 1 STX (10^6). */ declare const MICROSTX_PER_STX = 1000000n; /** Alias for validateStacksAddress — matches future.md naming. */ declare const isValidAddress: (address: string) => boolean; /** * Compare two Stacks addresses for equality (case-insensitive, version-aware). * Throws if either address is invalid. */ declare function isAddressEqual(a: string, b: string): boolean; /** * Build a contract address from deployer + contract name. * Validates both parts; returns `deployer.contractName`. */ declare function getContractAddress(deployer: string, contractName: string): string; 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; } /** * `::` — 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 (Subscriptions/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}`; /** 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 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 | PrintEventSpec | SbtcDepositSpec | SbtcWithdrawalCreateSpec | SbtcWithdrawalAcceptSpec | SbtcWithdrawalRejectSpec | SbtcWithdrawalSweptConfirmedSpec; type SpecFor = 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) }; /** Params fragment for `index.events.*` (spread into list/walk/consume). */ type IndexEventsParamsShape = { eventType: DecodedEventType /** A spec's contract set passes through verbatim (the API takes up to 20). */ contractId?: string | readonly string[] assetIdentifier?: AssetIdentifier sender?: string recipient?: 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 }; /** Params fragment for `streams.events.*`. */ type StreamsParamsShape = { types: readonly DecodedEventType[] contractId?: string | readonly string[] sender?: string recipient?: string assetIdentifier?: AssetIdentifier }; 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 `subscriptions.create({ triggers: [...] })`. BigInt * amounts become strings here — the one sanctioned boundary. */ toChainTrigger(): ChainTriggerOf } & (T extends DecodedMember ? { /** 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>(extra?: 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; 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 Subscriptions 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 }>; 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.subscriptions.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; /** Account derived from a local private key (mnemonic or raw key). */ type LocalAccount = { type: "local" address: string /** Compressed public key (hex) */ publicKey: string /** Raw ECDSA sign over a hash */ sign(hash: Uint8Array): Uint8Array /** Sign a raw UTF-8 / byte message (`sha256(bytes)`). Not SIP-018. */ signMessage(message: string | Uint8Array): string }; /** Account with a user-provided signing function (sync or async). */ type CustomAccount = { type: "custom" address: string publicKey: string sign(hash: Uint8Array): Promise | Uint8Array }; /** Browser wallet provider interface (e.g. Leather, Xverse). */ type StacksProvider = { request(method: string, params?: any): Promise }; /** Account backed by a browser wallet {@link StacksProvider}. */ type ProviderAccount = { type: "provider" address: string publicKey: string provider: StacksProvider }; type IntCV = { readonly type: "int" readonly value: bigint }; type UIntCV = { readonly type: "uint" readonly value: bigint }; type BooleanCV = TrueCV | FalseCV; type TrueCV = { readonly type: "true" }; type FalseCV = { readonly type: "false" }; type BufferCV = { readonly type: "buffer" readonly value: string }; type NoneCV = { readonly type: "none" }; type SomeCV = { readonly type: "some" readonly value: ClarityValue }; type ResponseOkCV = { readonly type: "ok" readonly value: ClarityValue }; type ResponseErrorCV = { readonly type: "err" readonly value: ClarityValue }; type StandardPrincipalCV = { readonly type: "address" readonly value: string }; type ContractPrincipalCV = { readonly type: "contract" readonly value: string }; type ListCV = { type: "list" value: ClarityValue[] }; type TupleData = { [key: string]: ClarityValue }; type TupleCV = { type: "tuple" value: TupleData }; type StringAsciiCV = { readonly type: "ascii" readonly value: string }; type StringUtf8CV = { readonly type: "utf8" readonly value: string }; type ClarityValue = IntCV | UIntCV | BooleanCV | BufferCV | NoneCV | SomeCV | ResponseOkCV | ResponseErrorCV | StandardPrincipalCV | ContractPrincipalCV | ListCV | TupleCV | StringAsciiCV | StringUtf8CV; declare const AuthType: { readonly Standard: 0x04 readonly Sponsored: 0x05 }; type AuthType = (typeof AuthType)[keyof typeof AuthType]; declare const PayloadType: { readonly TokenTransfer: 0x00 readonly SmartContract: 0x01 readonly ContractCall: 0x02 readonly PoisonMicroblock: 0x03 readonly Coinbase: 0x04 readonly CoinbaseToAltRecipient: 0x05 readonly VersionedSmartContract: 0x06 readonly TenureChange: 0x07 readonly NakamotoCoinbase: 0x08 }; type PayloadType = (typeof PayloadType)[keyof typeof PayloadType]; declare const ClarityVersion: { readonly Clarity1: 1 readonly Clarity2: 2 readonly Clarity3: 3 readonly Clarity4: 4 readonly Clarity5: 5 readonly Clarity6: 6 }; type ClarityVersion = (typeof ClarityVersion)[keyof typeof ClarityVersion]; declare const AnchorMode: { readonly OnChainOnly: 0x01 readonly OffChainOnly: 0x02 readonly Any: 0x03 }; type AnchorMode = (typeof AnchorMode)[keyof typeof AnchorMode]; declare const PostConditionModeWire: { readonly Allow: 0x01 readonly Deny: 0x02 readonly Originator: 0x03 }; type PostConditionModeWire = (typeof PostConditionModeWire)[keyof typeof PostConditionModeWire]; declare const AddressHashMode: { readonly P2PKH: 0x00 readonly P2SH: 0x01 readonly P2WPKH: 0x02 readonly P2WSH: 0x03 readonly P2SH_NonSequential: 0x05 readonly P2WSH_P2SH_NonSequential: 0x07 }; type AddressHashMode = (typeof AddressHashMode)[keyof typeof AddressHashMode]; declare const PubKeyEncoding: { readonly Compressed: 0x00 readonly Uncompressed: 0x01 }; type PubKeyEncoding = (typeof PubKeyEncoding)[keyof typeof PubKeyEncoding]; declare const PoxConditionCode: { readonly WillNotPerform: 0x30 readonly MayPerform: 0x31 readonly WillPerform: 0x32 }; type PoxConditionCode = (typeof PoxConditionCode)[keyof typeof PoxConditionCode]; declare const TenureChangeCause: { readonly BlockFound: 0x00 readonly Extended: 0x01 readonly ExtendedRuntime: 0x02 readonly ExtendedReadCount: 0x03 readonly ExtendedReadLength: 0x04 readonly ExtendedWriteCount: 0x05 readonly ExtendedWriteLength: 0x06 }; type TenureChangeCause = (typeof TenureChangeCause)[keyof typeof TenureChangeCause]; type TokenTransferPayload = { payloadType: typeof PayloadType.TokenTransfer recipient: ClarityValue amount: bigint memo: string }; type ContractCallPayload = { payloadType: typeof PayloadType.ContractCall contractAddress: string contractName: string functionName: string functionArgs: ClarityValue[] }; type SmartContractPayload = { payloadType: typeof PayloadType.SmartContract | typeof PayloadType.VersionedSmartContract clarityVersion?: ClarityVersion contractName: string codeBody: string }; type CoinbasePayload = { payloadType: typeof PayloadType.Coinbase coinbaseBuffer: string }; type CoinbaseToAltRecipientPayload = { payloadType: typeof PayloadType.CoinbaseToAltRecipient coinbaseBuffer: string recipient: ClarityValue }; type PoisonMicroblockPayload = { payloadType: typeof PayloadType.PoisonMicroblock header1: string header2: string }; type TenureChangePayload = { payloadType: typeof PayloadType.TenureChange tenureConsensusHash: string prevTenureConsensusHash: string burnViewConsensusHash: string previousTenureEnd: string previousTenureBlocks: number cause: TenureChangeCause pubkeyHash: string }; type NakamotoCoinbasePayload = { payloadType: typeof PayloadType.NakamotoCoinbase coinbaseBuffer: string recipient: ClarityValue | null vrfProof: string }; type TransactionPayload = TokenTransferPayload | ContractCallPayload | SmartContractPayload | CoinbasePayload | CoinbaseToAltRecipientPayload | PoisonMicroblockPayload | TenureChangePayload | NakamotoCoinbasePayload; type SingleSigSpendingCondition = { hashMode: typeof AddressHashMode.P2PKH | typeof AddressHashMode.P2WPKH signer: string nonce: bigint fee: bigint keyEncoding: PubKeyEncoding signature: string }; type TransactionAuthField = { pubKeyEncoding: PubKeyEncoding type: "publicKey" | "signature" data: string }; type MultiSigHashMode = typeof AddressHashMode.P2SH | typeof AddressHashMode.P2WSH | typeof AddressHashMode.P2SH_NonSequential | typeof AddressHashMode.P2WSH_P2SH_NonSequential; type MultiSigSpendingCondition = { hashMode: MultiSigHashMode signer: string nonce: bigint fee: bigint fields: TransactionAuthField[] signaturesRequired: number }; type SpendingCondition = SingleSigSpendingCondition | MultiSigSpendingCondition; type StandardAuthorization = { authType: typeof AuthType.Standard spendingCondition: SpendingCondition }; type SponsoredAuthorization = { authType: typeof AuthType.Sponsored spendingCondition: SpendingCondition sponsorSpendingCondition: SpendingCondition }; type Authorization = StandardAuthorization | SponsoredAuthorization; type StacksTransaction = { version: number chainId: number auth: Authorization anchorMode: AnchorMode postConditionMode: PostConditionModeWire postConditions: PostConditionWire[] payload: TransactionPayload /** Multi-sig signer metadata — not part of the wire format, preserved * through serialize/deserialize round-trip for auto-detection. */ _multisig?: { publicKeys: string[] } }; type PostConditionWire = StxPostConditionWire | FtPostConditionWire | NftPostConditionWire | StakingPostConditionWire | PoxPostConditionWire; type StxPostConditionWire = { type: "stx" principal: PostConditionPrincipalWire conditionCode: number amount: bigint }; type FtPostConditionWire = { type: "ft" principal: PostConditionPrincipalWire asset: AssetInfoWire conditionCode: number amount: bigint }; type NftPostConditionWire = { type: "nft" principal: PostConditionPrincipalWire asset: AssetInfoWire conditionCode: number assetId: ClarityValue }; type StakingPostConditionWire = { type: "staking" principal: PostConditionPrincipalWire conditionCode: number amount: bigint }; type PoxPostConditionWire = { type: "pox" principal: PostConditionPrincipalWire conditionCode: PoxConditionCode }; type PostConditionPrincipalWire = { type: "origin" } | { type: "standard" address: string } | { type: "contract" address: string contractName: string }; type AssetInfoWire = { address: string contractName: string assetName: string }; /** * Provides the confirmed on-chain nonce floor for an address. * * The default {@link jsonRpcSource} reads the configured node's `/v2/accounts` * endpoint — node-agnostic, no Hiro dependency. Other sources (mempool-aware, * first-party Index) can be swapped in without touching the manager. */ type NonceManagerSource = { get(params: { client: Client address: string }): Promise }; /** * Holds per-address allocation state and hands out the next nonce. * * `reserve` MUST be atomic per `key`: two concurrent reservations for the same * key must never return the same value. The in-memory {@link memoryStore} * serializes with a per-key promise chain; a persisted store (Redis `INCR`, * Postgres `SELECT ... FOR UPDATE`) becomes the cross-process lock for the * multi-builder / smart-wallet-as-a-service case. */ type NonceStore = { /** * Reserve the next nonce for `key`. `getFloor` reads the confirmed on-chain * nonce; it is only invoked when the store has no tracked value (cold start * or after {@link NonceStore.reset}). */ reserve(key: string, getFloor: () => Promise): Promise /** Forget tracked state for `key` so the next reserve re-syncs from the floor. */ reset(key: string): void | Promise /** * Hand back a nonce that {@link NonceStore.reserve} issued but that never * reached the mempool. Rolls the counter back ONLY when `nonce` is the * most recently issued value (`next - 1`); a stale release, or one that * races a newer reservation, is a no-op. Optional: stores that omit it * leave the gap for {@link reconcileNonce} to heal. */ release?(key: string, nonce: bigint): void | Promise /** * Return the next nonce that {@link NonceStore.reserve} would hand out for * `key` WITHOUT consuming it, or `undefined` if `key` is untracked. Used by * {@link reconcileNonce} to detect drift. Optional — stores that omit it * simply opt out of reconciliation. */ peek?(key: string): Promise | bigint | undefined }; /** Allocates mempool-safe sequential nonces across rapid broadcasts from one account. */ type NonceManager = { consume(params: { client: Client address: string }): Promise reset(params: { client: Client address: string }): void | Promise /** * Give back a nonce from {@link NonceManager.consume} whose transaction * was never accepted by the node. No-op unless it is the latest issued. */ release(params: { client: Client address: string nonce: bigint }): void | Promise /** Next nonce that {@link NonceManager.consume} would return without consuming it, or `undefined` if untracked. */ peek(params: { client: Client address: string }): Promise }; type CreateNonceManagerParams = { source?: NonceManagerSource store?: NonceStore }; /** Confirmed-nonce source backed by the configured node's `/v2/accounts` RPC (no Hiro dependency). */ declare function jsonRpcSource(): NonceManagerSource; /** * In-memory, single-process store. Tracks the next nonce per key and serializes * concurrent reservations with a per-key promise chain. * * Correct only within one process — swap in a persisted store for multi-process * deployments that share a signing key. */ declare function memoryStore(): NonceStore; /** * Create a nonce manager that floors on a confirmed-nonce {@link NonceManagerSource} * and increments a {@link NonceStore} on every {@link NonceManager.consume}. * * Defaults to {@link jsonRpcSource} + {@link memoryStore} — node-agnostic, * single-process, zero external dependencies. */ declare function createNonceManager(params?: CreateNonceManagerParams): NonceManager; /** Resolve the next nonce via the client's nonce manager, falling back to a confirmed read. */ declare function resolveNonce(client: Client, address: string): Promise; type ReconcileNonceParams = { client: Client address: string /** Authoritative (ideally mempool-aware) source to reconcile against. */ source: NonceManagerSource /** * Allow resetting DOWNWARD when the source's next nonce is below what the * store tracks — i.e. a previously-allocated tx is no longer pending or * confirmed (dropped/GC'd), so its nonce should be reused. Default `true`. * * Downward resets rely on `source` being current: with a go-forward mempool * source that lags broadcast, run reconciliation on an interval comfortably * longer than mempool propagation so a still-missing tx is genuinely dropped. * Set `false` for upward-only reconciliation (always safe). */ downward?: boolean }; type ReconcileNonceResult = { /** Whether the manager was reset (drift detected). */ reset: boolean /** Authoritative next nonce from `source`. */ authoritative: bigint /** Next nonce the store tracked, or `undefined` if untracked. */ tracked: bigint | undefined }; /** * Reconcile a tracked nonce against an authoritative source, healing silent * drift that produces no broadcast error (a dropped/GC'd mempool tx leaving the * counter overshot, or the chain advancing past the local view). * * When the source's next nonce differs from the tracked value, the manager is * {@link NonceManager.reset}; the next `consume` re-seeds from `source`. A no-op * if the store is untracked or does not implement `peek`. */ declare function reconcileNonce(manager: NonceManager, params: ReconcileNonceParams): Promise; type StartNonceReconcilerParams = { client: Client addresses: string[] source: NonceManagerSource /** Reconcile interval in ms. Default 60_000. Keep well above mempool propagation. */ intervalMs?: number downward?: boolean /** Per-address callback after each reconcile (observability). */ onReconcile?: (address: string, result: ReconcileNonceResult) => void /** Per-address error callback; reconciliation continues on the next tick. */ onError?: (address: string, error: unknown) => void /** Optional test clock. If provided, the reconciler advances time via * `clock.advance(ms)` instead of real `setInterval`. */ clock?: { advance: (ms: number) => Promise now: () => number } }; /** * Run {@link reconcileNonce} on a timer for a set of addresses. * * SINGLE-WRITER: run this in exactly ONE process. With a shared persisted store, * a reconciler resetting the counter while other workers allocate is racy — keep * reconciliation on one designated process and let the others only allocate. * * Returns a handle; call `stop()` to clear the timer. */ declare function startNonceReconciler(manager: NonceManager, params: StartNonceReconcilerParams): { stop: () => void }; /** True when a broadcast was rejected for a nonce conflict (`ConflictingNonceInMempool`, `BadNonce`). */ declare function isNonceConflictError(error: unknown): boolean; /** * Broadcast a signed transaction; on a nonce-conflict rejection, reset the * manager so the next build re-syncs to the confirmed floor. */ declare function broadcastWithNonceReset(client: Client, params: { transaction: StacksTransaction address: string }): Promise; /** Full chain descriptor used by clients and transports for network-aware operations. */ type StacksChain = { /** Chain ID (e.g. 0x00000001 for mainnet) */ id: number /** Human-readable name */ name: string /** Network type */ network: "mainnet" | "testnet" /** Transaction version byte for serialization */ transactionVersion: number /** Peer network ID for P2P broadcasting */ peerNetworkId: number /** Address version bytes */ addressVersion: { singleSig: number multiSig: number } /** Magic bytes for network identification */ magicBytes: string /** Boot address (system contracts deployer) */ bootAddress: string /** Native currency info */ nativeCurrency: { name: string symbol: string decimals: number } /** Default RPC URLs */ rpcUrls: { default: { http: string[] ws?: string[] } } /** Block explorer URLs */ blockExplorers?: { default: { name: string url: string } } }; /** Function that sends an HTTP request to a Stacks node API path. */ type RequestFn = (path: string, options?: RequestOptions) => Promise; /** Options for a transport-level HTTP request. */ type RequestOptions = { method?: "GET" | "POST" | "PUT" | "DELETE" body?: unknown headers?: Record /** * Cancel the request from the caller's side. An aborted signal rejects * with the signal's reason immediately and never retries; it is combined * with the transport's own per-attempt timeout. */ signal?: AbortSignal /** * Override the transport's retry budget for this one request. Broadcasts * pass `0`: re-sending a transaction the node may already hold trades a * transient failure for a confusing nonce conflict. */ retryCount?: number }; /** Shared configuration for all transport types. */ type TransportConfig = { url?: string /** * Per-attempt deadline in ms covering headers AND body. A stalled body * rejects with `TimeoutError` instead of hanging. Default 30_000. */ timeout?: number retryCount?: number retryDelay?: number fetchOptions?: RequestInit /** Sent as `x-api-key`. Held in the request closure and stripped from * `Transport.config` so it never prints with the client. */ apiKey?: string }; /** A resolved transport instance with a bound request function. */ type Transport = { type: string request: RequestFn config: TransportConfig destroy?: () => void }; /** Factory that creates a {@link Transport} given an optional chain context. */ type TransportFactory = (params?: { chain?: StacksChain }) => Transport; /** Union of all supported account types (local key, custom signer, or browser provider). */ type Account = LocalAccount | CustomAccount | ProviderAccount; /** * Core client instance that holds chain context, transport, and extensible actions. * Created via {@link createClient}, {@link createPublicClient}, or {@link createWalletClient}. */ type Client = Record> = { chain?: StacksChain account?: Account transport: Transport request: RequestFn /** Optional nonce manager for mempool-safe sequential nonces across rapid broadcasts. */ nonceManager?: NonceManager extend: >(fn: (client: Client) => TNew) => Client & TNew } & TExtended; /** Configuration for creating a base {@link Client}. */ type ClientConfig = { chain?: StacksChain transport: TransportFactory account?: Account /** Optional nonce manager threaded onto the client (see {@link createNonceManager}). */ nonceManager?: NonceManager }; /** A client pre-extended with read-only {@link PublicActions}. */ type PublicClient = Record> = Client; /** A client pre-extended with {@link WalletActions} and a required account. */ type WalletClient = Record> = Client & { account: Account }; /** * Create a base client with transport and optional chain/account. * Use `.extend()` to compose action decorators (public, wallet, multisig). */ declare function createClient = Record>(config: ClientConfig): Client; type EstimateFeeParams = { transaction: StacksTransaction }; type FeeEstimation = { feeRate: number fee: number }; type GetAccountHistoryParams = { address: string /** Capped at 50. Default 20. */ limit?: number }; type AccountHistoryResponse = { results: unknown[] total: number }; type GetAccountInfoParams = { address: string }; type AccountInfo = { balance: bigint nonce: bigint balanceProof: string nonceProof: string }; type GetBalanceParams = { address: string }; type GetBlockParams = { height?: number hash?: string }; type GetContractAbiParams = { contract: string }; type GetContractSourceParams = { contract: string }; type ContractSourceResponse = { source: string publish_height: number marf_proof?: string }; type GetDataVarParams = { contract: string varName: string }; type GetMapEntryParams = { contract: string mapName: string key: ClarityValue }; type GetNftHoldingsParams = { address: string /** Capped at 50. Default 20. */ limit?: number }; type NftHoldingsResponse = { results: unknown[] total: number }; type GetNonceParams = { address: string }; type GetRawBlockParams = { height: number }; /** * Raw node RPC block shape (`/v2/blocks/{height}`) — distinct from * {@link getBlock}'s Hiro extended-API shape. Carries consensus/identity * fields (`index_block_hash`, `miner_txid`, ...) that the indexed API doesn't * expose, for trust-minimized use cases (e.g. block-header proofs) that can't * rely on a third-party indexer. */ type RawBlockResponse = { hash: string height: number parent_block_hash: string burn_block_height: number burn_block_hash: string burn_block_time: number index_block_hash: string parent_index_block_hash: string miner_txid: string txs: string[] }; declare class BaseError extends Error { private; name: string; shortMessage: string; details?: string; constructor(shortMessage: string, options?: { cause?: Error details?: string code?: string }); /** * Stable identifier for programmatic handling; survives message * rewording and minification. An explicit `code` option wins, else it * is derived from `name` (`TimeoutError` gives `TIMEOUT_ERROR`). */ get code(): string; set code(value: string); toJSON(): { name: string code: string message: string shortMessage: string details: string | undefined cause: string | undefined }; } /** Thrown by the HTTP transport when a response's status isn't 2xx. */ declare class HttpRequestError extends BaseError { name: string; status: number; /** Request URL, when the transport knows it. */ url?: string; /** Request method, when the transport knows it. */ method?: string; constructor(status: number, options?: { cause?: Error details?: string url?: string method?: string }); } /** * Pluggable transaction-status sources for {@link getTransaction} / * `waitForTransactionReceipt`. * * A bare stacks-node has no confirmed-transaction endpoint, so status reads * need a host that indexes transactions. Where that data comes from is * pluggable, mirroring the nonce sources: * * - {@link extendedApiSource} — default; `/extended/v1/tx/{txid}` on the * client's transport host (Hiro API or any extended-API-compatible host). * - {@link indexTxSource}: a Secondlayer instance's * `/v1/index/transactions/{txid}`; returns the chain tip in the same * response, so N-confirmation waits need no second request. */ type TransactionStatus = "pending" | "success" | "abort_by_response" | "abort_by_post_condition" | "dropped"; type TransactionReceipt = { txid: string status: TransactionStatus /** Anchor block height; absent while pending. */ blockHeight?: number blockHash?: string /** Decoded Clarity result; absent while pending or when the source omits it. */ result?: ClarityValue resultHex?: string events: unknown[] /** The source's unnormalized response, for fields the receipt doesn't model. */ raw: unknown }; type TransactionSnapshot = { /** `null` when the source has no record of the tx (mempool + chain). */ receipt: TransactionReceipt | null /** Chain tip height, when the source knows it (saves a round-trip). */ tip?: number }; type TransactionStatusSource = { get(args: { client: Client txid: string }): Promise /** * True when the source only knows mined transactions and reports * `receipt: null` for the whole mempool life of a tx. The wait action * then stretches its dropped-grace window to the full timeout, since * "unknown" cannot mean "dropped" until the deadline. */ canonicalOnly?: boolean }; /** * Thrown when an index-backed source cannot reach a Secondlayer instance * because of how it was configured (no URL, a Hiro host, a bare node). * Sources that degrade on transient failures let this one through: a * misconfiguration would otherwise degrade silently on every read. */ declare class IndexSourceConfigError extends Error { name: string; } /** * Default source: `GET /extended/v1/tx/{txid}` via the client's transport. * Requires a host that serves Hiro's extended API (a bare stacks-node does * not). Does not report the chain tip — the wait action fetches it separately * when `confirmations > 1`. */ declare function extendedApiSource(): TransactionStatusSource; type IndexTxSourceParams = { /** * URL of your Secondlayer instance. Without it the client's transport * URL is assumed to be the instance: a transport on a Hiro host throws * up front, and a host that answers `/v1/index` with a non-JSON 404 * (a bare stacks-node) throws on the first read. Pass it whenever the * transport is not the instance. */ baseUrl?: string /** Instance token, sent as `Authorization: Bearer`. */ apiKey?: string }; /** * Source backed by a Secondlayer instance's `/v1/index/transactions/{txid}`. * The response embeds the chain tip, so N-confirmation math needs no extra * request. Requests go through the transport layer: same retries, timeout * and typed errors as every other read. The index only returns canonical * (mined) transactions; while a tx is in the mempool this source reports * `receipt: null`, and the wait action's grace window carries it until * inclusion. */ declare function indexTxSource(params?: IndexTxSourceParams): TransactionStatusSource; type GetTransactionParams = { txid: string /** Where to read status from. Defaults to {@link extendedApiSource}. */ source?: TransactionStatusSource }; /** * Fetch a transaction's receipt (status, block info, decoded result). * Returns `null` when the source has no record of the transaction. */ declare function getTransaction2(client: Client, params: GetTransactionParams): Promise; type MulticallCall = { contract: string functionName: string args?: ClarityValue[] sender?: string }; type MulticallParams = { calls: readonly MulticallCall[] allowFailure?: TAllowFailure /** * Reads in flight at once. Default 8. Each call is its own * `/v2/contracts/call-read` request (Stacks nodes have no batch RPC), so * an uncapped fan-out turns one multicall into a burst that trips rate * limits and then retries in lockstep. */ concurrency?: number }; type MulticallSuccessResult = { status: "success" result: ClarityValue }; type MulticallFailureResult = { status: "failure" error: Error }; type MulticallResult = T extends true ? (MulticallSuccessResult | MulticallFailureResult)[] : ClarityValue[]; type ReadContractParams = { contract: string functionName: string args?: ClarityValue[] sender?: string /** * Nakamoto StacksBlockId to evaluate against. Without it the node answers * at its own moving tip, which makes a read non-deterministic — the same * reindex of the same block can return a different value. */ tip?: string }; declare class SimulationError extends BaseError { name: string; writesDetected: boolean; constructor(message: string, options: { writesDetected: boolean details?: string }); } type SimulateCallParams = { contract: string functionName: string args?: ClarityValue[] sender?: string tip?: string }; type SimulateCallSuccess = { success: true result: ClarityValue }; type SimulateCallFailure = { success: false error: SimulationError }; type SimulateCallResult = SimulateCallSuccess | SimulateCallFailure; type SimulateTransactionParams = { transaction: StacksTransaction sender?: string tip?: string }; type SimulateContractCallResult = { type: "contract-call" execution: SimulateCallResult fees: FeeEstimation[] }; type SimulateTransferResult = { type: "token-transfer" fees: FeeEstimation[] }; type SimulateDeployResult = { type: "contract-deploy" fees: FeeEstimation[] }; type SimulateTransactionResult = SimulateContractCallResult | SimulateTransferResult | SimulateDeployResult; type WaitForTransactionReceiptParams = { txid: string /** Anchor-block confirmations to wait for. Default 1 (mined). */ confirmations?: number /** Give up after this many ms. Default 180_000 (3 min). */ timeout?: number /** Delay between status polls, ms. Default 3_000. */ pollingInterval?: number /** * How long a tx may be unknown to the source before it counts as dropped, * ms. Covers broadcast propagation lag. Default 30_000, or the full * `timeout` for a canonical-only source (one that cannot see the * mempool, so "unknown" means "not mined yet" until the deadline). */ droppedGracePeriod?: number /** Where to read status from. Defaults to {@link extendedApiSource}. */ source?: TransactionStatusSource }; /** * Poll until a transaction is mined with N confirmations, then return its * receipt. * * Rejects with {@link TransactionAbortedError} when the tx mines but aborts * (`abort_by_response` / `abort_by_post_condition`) — the receipt is attached. * Rejects with {@link TransactionDroppedError} when the tx leaves the mempool * unmined or stays unknown past `droppedGracePeriod`, and * {@link WaitForTransactionTimeoutError} at `timeout`. * * Reorg-tolerant: every cycle re-reads the receipt (block height may change) * and recomputes confirmations from the current tip. */ declare function waitForTransactionReceipt2(client: Client, params: WaitForTransactionReceiptParams): Promise; /** Handle returned by WebSocket subscription methods; call `unsubscribe()` to stop. */ type Subscription = { unsubscribe: () => void }; type WsEvent = "block" | "mempool" | "tx_update" | "address_tx_update" | "address_balance_update" | "nft_event" | "nft_asset_event" | "nft_collection_event"; type WsSubscribeParams = { event: WsEvent tx_id?: string address?: string asset_identifier?: string value?: string }; type BlockNotification = { canonical: boolean height: number hash: string index_block_hash: string parent_block_hash: string burn_block_height: number burn_block_hash: string parent_burn_block_hash: string parent_burn_block_height: number parent_index_block_hash: string txs: string[] }; type MempoolNotification = { tx_id: string tx_type: string tx_status: string receipt_time: number receipt_time_iso: string fee_rate: string sender_address: string sponsor_address?: string nonce: number contract_call?: { contract_id: string function_name: string function_signature: string } token_transfer?: { recipient_address: string amount: string memo: string } }; type TxUpdateNotification = { tx_id: string tx_type: string tx_status: string block_hash?: string block_height?: number burn_block_height?: number burn_block_time?: number tx_result?: { hex: string repr: string } }; type AddressTxNotification = { address: string tx_id: string tx_type: string tx_status: string stx_sent: string stx_received: string stx_transfers: Array<{ amount: string sender: string recipient: string }> ft_transfers: Array<{ amount: string asset_identifier: string sender: string recipient: string }> nft_transfers: Array<{ asset_identifier: string sender: string recipient: string value: { hex: string repr: string } }> }; type AddressBalanceNotification = { address: string balance: string total_sent: string total_received: string total_fees_sent: string total_miner_rewards_received: string lock_tx_id: string locked: string lock_height: number burnchain_lock_height: number burnchain_unlock_height: number }; type NftEventNotification = { sender: string recipient: string asset_identifier: string asset_event_type: string value: { hex: string repr: string } tx_id: string block_height: number }; type WatchBlocksParams = { onBlock: (block: BlockNotification) => void }; type WatchMempoolParams = { onTransaction: (tx: MempoolNotification) => void }; type WatchTransactionParams = { txId: string onUpdate: (update: TxUpdateNotification) => void }; type WatchAddressParams = { address: string onTransaction: (tx: AddressTxNotification) => void }; type WatchAddressBalanceParams = { address: string onBalance: (balance: AddressBalanceNotification) => void }; type WatchNftEventParams = { onEvent: (event: NftEventNotification) => void assetIdentifier?: string value?: string }; /** Read-only actions: balance queries, contract reads, block data, and event subscriptions. */ type PublicActions = { getNonce: (params: GetNonceParams) => Promise getBalance: (params: GetBalanceParams) => Promise getAccountInfo: (params: GetAccountInfoParams) => Promise getBlock: (params: GetBlockParams) => Promise getRawBlock: (params: GetRawBlockParams) => Promise getBlockHeight: () => Promise readContract: (params: ReadContractParams) => Promise getContractAbi: (params: GetContractAbiParams) => Promise getContractSource: (params: GetContractSourceParams) => Promise getDataVar: (params: GetDataVarParams) => Promise getMapEntry: (params: GetMapEntryParams) => Promise estimateFee: (params: EstimateFeeParams) => Promise multicall: (params: MulticallParams) => Promise> simulateCall: (params: SimulateCallParams) => Promise simulateTransaction: (params: SimulateTransactionParams) => Promise getTransaction: (params: GetTransactionParams) => Promise getAccountHistory: (params: GetAccountHistoryParams) => Promise getMempoolStats: () => Promise getNftHoldings: (params: GetNftHoldingsParams) => Promise waitForTransactionReceipt: (params: WaitForTransactionReceiptParams) => Promise watchBlocks: (params: WatchBlocksParams) => Promise watchMempool: (params: WatchMempoolParams) => Promise watchTransaction: (params: WatchTransactionParams) => Promise watchAddress: (params: WatchAddressParams) => Promise watchAddressBalance: (params: WatchAddressBalanceParams) => Promise watchNftEvent: (params: WatchNftEventParams) => Promise }; /** Decorator that binds {@link PublicActions} to a client instance. */ declare function publicActions(client: Client): PublicActions; /** Configuration for {@link createPublicClient} (no account needed). */ type PublicClientConfig = Omit; /** * Create a read-only client pre-extended with {@link PublicActions}. * Use for queries, contract reads, and event subscriptions. */ declare function createPublicClient(config: PublicClientConfig): Client & PublicActions; type FungibleComparator = "eq" | "gt" | "gte" | "lt" | "lte"; type NonFungibleComparator = "sent" | "not-sent" | "maybe-sent"; type StxPostCondition = { type: "stx-postcondition" address: string condition: FungibleComparator amount: string | bigint | number }; type FtPostCondition = { type: "ft-postcondition" address: string condition: FungibleComparator asset: string amount: string | bigint | number }; type NftPostCondition = { type: "nft-postcondition" address: string condition: NonFungibleComparator asset: string assetId: ClarityValue }; type StakingPostCondition = { type: "staking-postcondition" address: string condition: FungibleComparator amount: string | bigint | number }; type PoxComparator = "will-not-perform" | "may-perform" | "will-perform"; type PoxPostCondition = { type: "pox-postcondition" address: string condition: PoxComparator }; type PostCondition = StxPostCondition | FtPostCondition | NftPostCondition | StakingPostCondition | PoxPostCondition; /** Serialized PC hex is accepted anywhere a `PostCondition` object is. */ type PostConditionInput = PostCondition | string; type PostConditionMode = "allow" | "deny" | "originator"; type IntegerType = number | string | bigint | Uint8Array; /** * Named fee tiers. `'low' | 'mid' | 'high'` map to the node's three fee * estimations; `'min'` is the node's minimum relay fee — 1 uSTX per byte of * the serialized transaction, computable offline. */ type FeeTier = "min" | "low" | "mid" | "high"; /** Fee input accepted by wallet actions: an explicit amount or a named tier. */ type FeeParam = IntegerType | FeeTier; type CallContractParams = { contract: string functionName: string functionArgs?: ClarityValue[] fee?: FeeParam nonce?: IntegerType postConditionMode?: PostConditionMode postConditions?: PostConditionInput[] }; type DeployContractParams = { contractName: string codeBody: string clarityVersion?: ClarityVersion fee?: FeeParam nonce?: IntegerType postConditionMode?: PostConditionMode postConditions?: PostConditionInput[] }; type SendTransactionParams = { transaction: StacksTransaction attachment?: Uint8Array | string /** * Wait for the transaction to be mined before returning. `true` waits for * 1 confirmation; a number waits for that many. The receipt lands on the * result. Rejects if the tx aborts, is dropped, or the wait times out. */ wait?: boolean | number }; type SendTransactionResult = { txid: string /** Present when `wait` was requested. */ receipt?: TransactionReceipt }; type SignMessageParams = { message: string | ClarityValue domain?: { name: string version: string chainId: number } }; type SignTransactionParams = { transaction: StacksTransaction /** Public keys for multi-sig signing (auto-detected from _multisig metadata if omitted) */ signers?: string[] }; type SponsorTransactionParams = { transaction: StacksTransaction fee?: FeeParam nonce?: IntegerType }; type TransferStxParams = { to: string amount: IntegerType memo?: string fee?: FeeParam nonce?: IntegerType postConditionMode?: PostConditionMode postConditions?: PostConditionInput[] }; /** Signing actions: send transactions, transfer STX, call/deploy contracts, sign messages. */ type WalletActions = { sendTransaction: (params: SendTransactionParams) => Promise signTransaction: (params: SignTransactionParams) => Promise transferStx: (params: TransferStxParams) => Promise callContract: (params: CallContractParams) => Promise deployContract: (params: DeployContractParams) => Promise signMessage: (params: SignMessageParams) => Promise sponsorTransaction: (params: SponsorTransactionParams) => Promise }; /** Decorator that binds {@link WalletActions} to a client instance. */ declare function walletActions(client: Client): WalletActions; /** Configuration for {@link createWalletClient} — requires an account for signing. */ type WalletClientConfig = ClientConfig & { account: Account }; /** * Create a client pre-extended with {@link WalletActions} for signing and broadcasting transactions. */ declare function createWalletClient(config: WalletClientConfig): Client & WalletActions & { account: Account }; type MultiSigTransferStxParams = { to: string amount: IntegerType memo?: string fee?: IntegerType nonce?: IntegerType postConditionMode?: PostConditionMode postConditions?: PostConditionInput[] }; type MultiSigCallContractParams = { contract: string functionName: string functionArgs?: ClarityValue[] fee?: IntegerType nonce?: IntegerType postConditionMode?: PostConditionMode postConditions?: PostConditionInput[] }; type MultiSigDeployContractParams = { contractName: string codeBody: string clarityVersion?: ClarityVersion fee?: IntegerType nonce?: IntegerType postConditionMode?: PostConditionMode postConditions?: PostConditionInput[] }; type MultiSigSendTransactionParams = { transaction: StacksTransaction attachment?: Uint8Array | string }; /** Multi-sig transaction actions: build unsigned transactions and broadcast with auto-finalization. */ type MultiSigActions = { transferStx: (params: MultiSigTransferStxParams) => Promise callContract: (params: MultiSigCallContractParams) => Promise deployContract: (params: MultiSigDeployContractParams) => Promise sendTransaction: (params: MultiSigSendTransactionParams) => Promise }; /** Decorator that binds {@link MultiSigActions} to a multi-sig client. */ declare function multisigActions(client: Client): MultiSigActions; /** Configuration for {@link createMultiSigClient} — requires signer public keys and threshold. */ type MultiSigClientConfig = Omit & { signers: string[] requiredSignatures: number hashMode?: MultiSigHashMode }; /** A client pre-extended with {@link MultiSigActions} for m-of-n signing flows. */ type MultiSigClient = Client & MultiSigActions; /** * Create a client for multi-sig transaction flows. * Builds unsigned transactions that can be signed by each party then broadcast. */ declare function createMultiSigClient(config: MultiSigClientConfig): MultiSigClient; /** * Persisted {@link NonceStore} adapters for multi-process / multi-builder * deployments (the smart-wallet-as-a-service case). * * The in-memory {@link memoryStore} is correct only within one process: two * workers sharing a signing key both read the same confirmed floor and collide. * These adapters move the atomic reserve into a shared datastore — Redis `INCR` * inside an `EVAL`, or a single Postgres upsert under a row lock — so the store * itself becomes the cross-process lock and the durable source of truth. * * Both are dependency-injected: pass your own `Bun.redis` / `Bun.sql` client. * No global `Bun` reference, so importing this module is runtime-agnostic. */ /** Minimal structural shape of a `Bun.redis` client (the `send` escape hatch). */ type RedisLike = { send(command: string, args: string[]): Promise }; type RedisStoreParams = { redis: RedisLike /** Key prefix for stored nonce counters. Default `"stacks:nonce:"`. */ prefix?: string }; /** * Redis-backed nonce store. The atomic reserve lives in a Lua `EVAL`, so it is * safe across processes sharing one Redis. The confirmed floor (`getFloor`) is * read only once per key, on cold start. */ declare function redisStore(params: RedisStoreParams): NonceStore; /** Minimal structural shape of a `Bun.sql` tagged-template client. */ type SqlLike = (strings: TemplateStringsArray, ...values: unknown[]) => Promise>>; type PostgresStoreParams = { sql: SqlLike /** * Run `CREATE TABLE IF NOT EXISTS stacks_nonce_state` lazily on first use. * Default `true`. Set `false` if you manage the schema via migrations. */ ensureTable?: boolean }; /** * Postgres-backed nonce store. Each reserve is a single atomic statement under * a row lock, so concurrent reservers on the same key serialize and never * collide across processes. State is durable — survives restarts. * * Uses a fixed table `stacks_nonce_state (key text primary key, next numeric)`. */ declare function postgresStore(params: PostgresStoreParams): NonceStore; /** * Mempool-aware {@link NonceManagerSource}s. * * The default {@link jsonRpcSource} reads only the confirmed nonce, so a tx * sitting in the mempool is invisible — broadcasting many quickly forces manual * tracking. These sources fold pending (mempool) txs into the next-nonce * computation. The gap-filling core is generic; where the pending set comes from * is pluggable, so you are never locked to any one provider: * * - {@link mempoolAwareSource} — bring your own `getPending`. * - {@link indexSource}: prebuilt over a Secondlayer instance's `/v1/index/mempool`. * - {@link hiroNonceSource} — prebuilt over Hiro's `/extended` nonces endpoint. */ type FetchImpl = typeof globalThis.fetch; /** * The next free nonce ≥ `confirmed` not already taken by a pending tx. * * Unlike Hiro's `possible_next_nonce` (which is `max(pending) + 1` and strands * higher txs when a lower nonce is missing), this FILLS gaps: it returns the * lowest unused slot, so a dropped-tx hole is reused instead of stranding the * chain. */ declare function nextFreeNonce(confirmed: bigint, pending: bigint[]): bigint; type MempoolAwareSourceParams = { /** Pending (mempool) nonces for an address. */ getPending: (args: { client: Client address: string }) => Promise /** * Confirmed-nonce floor. Defaults to the node's `/v2/accounts` read — the * user's own node via the client transport, no provider dependency. */ getConfirmed?: (args: { client: Client address: string }) => Promise }; /** * Build a gap-filling, mempool-aware source from any `getPending`. The confirmed * floor defaults to the node read; if `getPending` throws, the source degrades * to confirmed-only rather than blocking a broadcast. A misconfigured pending * feed ({@link IndexSourceConfigError}) is rethrown: it would fail on every * read, and degrading silently would hide that the mempool is never consulted. */ declare function mempoolAwareSource(params: MempoolAwareSourceParams): NonceManagerSource; type IndexSourceParams = { /** * URL of your Secondlayer instance. Without it the client's transport * URL is assumed to be the instance: a transport on a Hiro host throws * up front, and a host that answers `/v1/index` with a non-JSON 404 * (a bare stacks-node) throws on the first read. Neither is degraded * to the confirmed floor. Pass it whenever the transport is not the * instance. */ baseUrl?: string /** Instance token, sent as `Authorization: Bearer`. */ apiKey?: string /** Max mempool pages to read per address. Default 10 (×200 = 2000 txs). */ maxPages?: number /** Override the confirmed floor (defaults to the node read). */ getConfirmed?: (args: { client: Client address: string }) => Promise }; /** * Mempool-aware source backed by a Secondlayer instance's `/v1/index/mempool`. * Requests go through the transport layer (retries, timeout, typed errors). * The instance's mempool is a go-forward view observed by its own node, so * it can lag or miss transactions that node never saw; the manager's local * increment still prevents same-process collisions. Past `maxPages` the * pending set is truncated and the next free nonce may already be taken; * a nonce conflict at broadcast then resets the manager. Transient failures * (5xx, timeout) degrade to the confirmed floor; a missing or wrong instance * URL throws so the misconfiguration is visible on the first read. */ declare function indexSource(params?: IndexSourceParams): NonceManagerSource; type HiroNonceSourceParams = { /** Hiro API base URL, e.g. `https://api.hiro.so` or `https://api.testnet.hiro.so`. */ baseUrl: string apiKey?: string fetchImpl?: FetchImpl }; /** * Off-the-shelf, non-Secondlayer mempool-aware source over Hiro's * `/extended/v1/address/{address}/nonces`. Fills the lowest detected gap first, * then falls back to `possible_next_nonce`. Requires a host that serves Hiro's * extended API (a bare stacks-node does not). */ declare function hiroNonceSource(params: HiroNonceSourceParams): NonceManagerSource; /** * Create an HTTP transport for Stacks node RPC calls. * Falls back to the chain's default RPC URL, then `localhost:3999`. */ declare function http(url?: string, config?: TransportConfig): TransportFactory; /** Create a transport backed by a user-provided request function. */ declare function custom(params: { request: RequestFn }): TransportFactory; /** Create a transport that tries each transport in order until one succeeds. */ declare function fallback(transports: TransportFactory[]): TransportFactory; /** Configuration for the WebSocket transport, extending base {@link TransportConfig}. */ type WebSocketTransportConfig = TransportConfig & { /** WebSocket URL (resolved from chain if omitted) */ url?: string /** Enable auto-reconnect (default: true) */ reconnect?: boolean /** Max reconnect attempts (default: 10) */ reconnectMaxAttempts?: number /** Base delay in ms for exponential backoff (default: 1000) */ reconnectBaseDelay?: number }; /** Transport with WebSocket subscription capabilities and auto-reconnect. */ type WebSocketTransport = Transport & { type: "webSocket" subscribe: (params: WsSubscribeParams, callback: (data: any) => void) => Promise destroy: () => void }; /** * Create a WebSocket transport for real-time Stacks event subscriptions. * HTTP requests use the resolved RPC URL; subscriptions use the WS endpoint. */ declare function webSocket(url?: string, config?: WebSocketTransportConfig): TransportFactory; /** Create a ProviderAccount by querying the wallet for addresses */ declare function providerToAccount(provider: StacksProvider): Promise; /** Stacks mainnet chain definition (Hiro API). */ declare const mainnet: StacksChain; /** Stacks testnet chain definition (Hiro API). */ declare const testnet: StacksChain; /** Local development chain definition (localhost:3999). */ declare const devnet: StacksChain; /** Alias for devnet used in mock/test environments. */ declare const mocknet: StacksChain; /** Identity helper for defining a custom {@link StacksChain} with full type inference. */ declare function defineChain(chain: StacksChain): StacksChain; /** * Format microSTX to STX string (6 decimals). * @example formatStx(1000000n) → "1.0" */ declare function formatStx(microStx: bigint | number | string): string; /** * Parse STX string to microSTX bigint (6 decimals). * @example parseStx("1.5") → 1500000n */ declare function parseStx(stx: string | number): bigint; declare class TransactionError extends BaseError { name: string; } /** * Rejection reasons a stacks-node returns from `POST /v2/transactions`. * Wire strings from stacks-core `MemPoolRejection::into_json` * (`stackslib/src/chainstate/stacks/db/blocks.rs`). */ type TxRejectionReason = "Serialization" | "Deserialization" | "SignatureValidation" | "BadNonce" | "ConflictingNonceInMempool" | "TooMuchChaining" | "FeeTooLow" | "NotEnoughFunds" | "NoSuchContract" | "NoSuchPublicFunction" | "BadFunctionArgument" | "ContractAlreadyExists" | "BadTransactionVersion" | "TransferRecipientCannotEqualSender" | "TransferAmountMustBePositive" | "PoisonMicroblocksDoNotConflict" | "PoisonMicroblockHasUnknownPubKeyHash" | "PoisonMicroblockIsInvalid" | "BadAddressVersionByte" | "NoCoinbaseViaMempool" | "NoTenureChangeViaMempool" | "EstimatorError" | "TemporarilyBlacklisted" | "ServerFailureNoSuchChainTip" | "ServerFailureDatabase" | "ServerFailureOther"; declare class BroadcastError extends BaseError { name: string; txid?: string; reason?: TxRejectionReason | (string & {}); /** Node-provided detail; shape varies per reason (see stacks-core RPC docs). */ reasonData?: unknown; constructor(message: string, options?: { cause?: Error txid?: string reason?: string reasonData?: unknown }); } /** The transaction was mined but its execution aborted (runtime error or failed post-condition). */ declare class TransactionAbortedError extends BaseError { name: string; /** The abort receipt (status, block info, raw source response). */ receipt: unknown; constructor(message: string, options: { receipt: unknown cause?: Error }); } /** The transaction left the mempool without being mined (dropped/replaced). */ declare class TransactionDroppedError extends BaseError { name: string; txid: string; constructor(message: string, options: { txid: string cause?: Error }); } /** waitForTransactionReceipt gave up before the tx reached the requested state. */ declare class WaitForTransactionTimeoutError extends BaseError { name: string; txid: string; constructor(message: string, options: { txid: string cause?: Error }); } declare class SerializationError extends BaseError { name: string; } declare class SigningError extends BaseError { name: string; } /** * Thrown by the HTTP transport when a request, headers and body included, * does not finish inside `timeout`. Carries enough to tell which endpoint * stalled and on which retry attempt. A caller-supplied `signal` abort is * NOT a timeout: that rejects with the signal's own reason and never retries. */ declare class TimeoutError extends BaseError { name: string; method: string; url: string; timeout: number; /** Zero-based attempt index at which the timeout fired. */ attempt: number; constructor(params: { method: string url: string timeout: number attempt: number }); } /** Thrown when a node/API response is missing an expected field. */ declare class MalformedResponseError extends BaseError { name: string; } /** Thrown when `/v2/contracts/call-read` answers `okay: false`. */ declare class ReadContractError extends BaseError { name: string; } declare class WebSocketError extends BaseError { name: string; } export { webSocket, walletActions, waitForTransactionReceipt2 as waitForTransactionReceipt, testnet, startNonceReconciler, resolveNonce, redisStore, reconcileNonce, publicActions, providerToAccount, postgresStore, parseStx, on, nextFreeNonce, multisigActions, mocknet, mempoolAwareSource, memoryStore, mainnet, jsonRpcSource, isValidAddress, isNonceConflictError, isAddressEqual, indexTxSource, indexSource, http, hiroNonceSource, getTransaction2 as getTransaction, getContractAddress, formatStx, fallback, extendedApiSource, devnet, defineChain, custom, createWalletClient, createPublicClient, createNonceManager, createMultiSigClient, createClient, broadcastWithNonceReset, ZERO_ADDRESS, WebSocketTransportConfig, WebSocketTransport, WebSocketError, WalletClientConfig, WalletClient, WalletActions, WaitForTransactionTimeoutError, WaitForTransactionReceiptParams, TxRejectionReason, TransportFactory, TransportConfig, Transport, TransactionStatusSource, TransactionStatus, TransactionSnapshot, TransactionReceipt, TransactionError, TransactionDroppedError, TransactionAbortedError, TimeoutError, TESTNET_ZERO_ADDRESS, Subscription, StartNonceReconcilerParams, StacksProvider, StacksChain, SqlLike, SimulationError, SigningError, SerializationError, RequestOptions, RequestFn, RedisStoreParams, RedisLike, ReconcileNonceResult, ReconcileNonceParams, ReadContractError, PublicClientConfig, PublicClient, PublicActions, ProviderAccount, PostgresStoreParams, NonceStore, NonceManagerSource, NonceManager, MultiSigClientConfig, MultiSigClient, MultiSigActions, MempoolAwareSourceParams, MalformedResponseError, MICROSTX_PER_STX, LocalAccount, IndexTxSourceParams, IndexSourceParams, IndexSourceConfigError, HttpRequestError, HiroNonceSourceParams, GetTransactionParams, CustomAccount, CreateNonceManagerParams, ClientConfig, Client, ChainTriggerOf, ChainEventFilterType, ChainEventFilterSpec, ChainEventFilter, BroadcastError, BaseError, AddressVersion, Account };