/** 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 }; /** 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 }; /** 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 }; /** 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; /** * sBTC mainnet contract identifiers. * * The protocol uses three contracts: * - `sbtc-token` — SIP-010 fungible token with mint/burn/transfer SIP-005 events. * - `sbtc-deposit` — entry point for deposit completion calls (no print events). * - `sbtc-registry` — emits all protocol-state print events (deposits, withdrawals, * signer-set rotations, governance). * * Verified against the deployed contracts via Hiro's * `/v2/contracts/interface/...` endpoint (both networks, 2026-08-12). */ declare const SBTC_CONTRACTS: { readonly mainnet: { readonly address: "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4" readonly token: "sbtc-token" readonly deposit: "sbtc-deposit" readonly registry: "sbtc-registry" } readonly testnet: { readonly address: "SN3VMHXEN64ZZF71JQ5VESXDWTR301XTTXGF4J8F1" readonly token: "sbtc-token" readonly deposit: "sbtc-deposit" readonly registry: "sbtc-registry" } }; type SbtcNetwork = keyof typeof SBTC_CONTRACTS; /** Asset identifier for `sbtc-token` (mainnet). */ declare const SBTC_ASSET_IDENTIFIER_MAINNET: string; /** Asset identifier for `sbtc-token` (testnet). */ declare const SBTC_ASSET_IDENTIFIER_TESTNET: string; /** All print-event topic strings emitted by `sbtc-registry`. */ declare const SBTC_EVENT_TOPICS: readonly ["completed-deposit", "withdrawal-create", "withdrawal-accept", "withdrawal-reject", "key-rotation", "update-protocol-contract"]; type SbtcEventTopic = (typeof SBTC_EVENT_TOPICS)[number]; /** Bitcoin address version bytes used in BTC recipient tuples. Same byte map as PoX. */ declare const SBTC_BTC_ADDRESS_VERSION: { readonly p2pkh: 0x00 readonly p2sh: 0x01 readonly p2sh_p2wpkh: 0x02 readonly p2sh_p2wsh: 0x03 readonly p2wpkh: 0x04 readonly p2wsh: 0x05 readonly p2tr: 0x06 }; /** Number of decimal places in the sBTC fungible token (matches BTC). */ declare const SBTC_DECIMALS = 8; /** Smallest unit of sBTC, denominated in satoshis. */ declare const SBTC_UNIT_NAME: "satoshis"; /** * Resolve the qualified contract identifier for a given protocol contract. * * @example * sbtcContractId("mainnet", "registry") * // => "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-registry" */ declare function sbtcContractId(network: SbtcNetwork, contract: "token" | "deposit" | "registry"): string; /** * Bitcoin recipient address as encoded in `withdrawal-create` events. * `version` is a single byte mapping to {@link SBTC_BTC_ADDRESS_VERSION}; * `hashbytes` is the 20- or 32-byte hash payload. */ type SbtcBtcRecipient = { version: number hashbytes: Uint8Array }; /** `(print { topic: "completed-deposit", ... })` from `sbtc-registry`. */ type CompletedDepositEvent = { topic: "completed-deposit" bitcoinTxid: Uint8Array outputIndex: bigint amount: bigint burnHash: Uint8Array burnHeight: bigint sweepTxid: Uint8Array }; /** `(print { topic: "withdrawal-create", ... })`. */ type WithdrawalCreateEvent = { topic: "withdrawal-create" requestId: bigint amount: bigint sender: string recipient: SbtcBtcRecipient blockHeight: bigint maxFee: bigint }; /** `(print { topic: "withdrawal-accept", ... })`. */ type WithdrawalAcceptEvent = { topic: "withdrawal-accept" requestId: bigint bitcoinTxid: Uint8Array signerBitmap: bigint outputIndex: bigint fee: bigint burnHash: Uint8Array burnHeight: bigint sweepTxid: Uint8Array }; /** `(print { topic: "withdrawal-reject", ... })`. */ type WithdrawalRejectEvent = { topic: "withdrawal-reject" requestId: bigint signerBitmap: bigint }; /** `(print { topic: "key-rotation", ... })` — signer-set rotation. */ type KeyRotationEvent = { topic: "key-rotation" newKeys: Uint8Array[] newAddress: string newAggregatePubkey: Uint8Array newSignatureThreshold: bigint }; /** `(print { topic: "update-protocol-contract", ... })` — governance hook. */ type UpdateProtocolContractEvent = { topic: "update-protocol-contract" contractType: Uint8Array newContract: string }; /** Discriminated union of every protocol-state event from `sbtc-registry`. */ type SbtcRegistryEvent = CompletedDepositEvent | WithdrawalCreateEvent | WithdrawalAcceptEvent | WithdrawalRejectEvent | KeyRotationEvent | UpdateProtocolContractEvent; type SbtcTokenTransferEvent = { type: "transfer" sender: string recipient: string amount: bigint memo: Uint8Array | null }; type SbtcTokenMintEvent = { type: "mint" recipient: string amount: bigint }; type SbtcTokenBurnEvent = { type: "burn" sender: string amount: bigint }; type SbtcTokenEvent = SbtcTokenTransferEvent | SbtcTokenMintEvent | SbtcTokenBurnEvent; /** Helper for narrowing on `topic`. */ type SbtcEventByTopic = Extract; type BitcoinNetwork = "mainnet" | "testnet" | "regtest"; /** * Format a `(buff 1) + (buff 32)` BTC recipient tuple into a canonical * Bitcoin address string. Defaults to mainnet encoding; pass `network` * for testnet/regtest version bytes and hrp. * * Used to decode the `recipient` field of `withdrawal-create` events * into a human-readable address. The sBTC version bytes are the SIP-005 * PoX bytes, so this is `stringifyBtcAddress` from `pox5` under an * sBTC-shaped name; unknown versions and hash lengths throw there. */ declare function formatBtcAddress(recipient: SbtcBtcRecipient, network?: BitcoinNetwork): string; /** * Validate that a buffer is a 32-byte Bitcoin transaction id. * Throws if the buffer is the wrong length. */ declare function validateBitcoinTxid(buf: Uint8Array): void; /** * Hex-encode a Bitcoin txid for storage / display. Throws if the input is * not 32 bytes. */ declare function bitcoinTxidToHex(buf: Uint8Array): string; /** * Parse a hex string back into a 32-byte txid. Mirrors `bitcoinTxidToHex`. */ declare function bitcoinTxidFromHex(hex: string): Uint8Array; /** * Convert satoshis (BigInt) to a decimal-string sBTC amount. * * sBTC has 8 decimals (matching BTC). 100_000_000 sats = 1 sBTC. */ declare function satsToSbtc(sats: bigint): string; /** * Parse a decimal-string sBTC amount into satoshis. Inverse of * {@link satsToSbtc}. */ declare function sbtcToSats(amount: string): bigint; /** * Minimal read-only ABI for `sbtc-token`. * * Only covers the SIP-010 fungible-token getters needed for supply / balance * queries. Public mutating functions are intentionally omitted; the data plane * doesn't sign sBTC token transfers itself, and the dataset captures * mutation effects through SIP-005 token events on the indexer side. */ declare const SBTC_TOKEN_ABI: { readonly functions: readonly [{ readonly name: "get-name" readonly access: "read-only" readonly args: readonly [] readonly outputs: { readonly response: { readonly ok: { readonly "string-ascii": { readonly length: 32 } } readonly error: "none" } } }, { readonly name: "get-symbol" readonly access: "read-only" readonly args: readonly [] readonly outputs: { readonly response: { readonly ok: { readonly "string-ascii": { readonly length: 10 } } readonly error: "none" } } }, { readonly name: "get-decimals" readonly access: "read-only" readonly args: readonly [] readonly outputs: { readonly response: { readonly ok: "uint128" readonly error: "none" } } }, { readonly name: "get-total-supply" readonly access: "read-only" readonly args: readonly [] readonly outputs: { readonly response: { readonly ok: "uint128" readonly error: "none" } } }, { readonly name: "get-balance" readonly access: "read-only" readonly args: readonly [{ readonly name: "owner" readonly type: "principal" }] readonly outputs: { readonly response: { readonly ok: "uint128" readonly error: "none" } } }, { readonly name: "get-token-uri" readonly access: "read-only" readonly args: readonly [] readonly outputs: { readonly response: { readonly ok: { readonly optional: { readonly "string-utf8": { readonly length: 256 } } } readonly error: "none" } } }] }; /** Actions provided by the sBTC extension. */ type SbtcActions = { sbtc: { getTotalSupply: () => Promise getBalance: (owner: string) => Promise getName: () => Promise getSymbol: () => Promise getDecimals: () => Promise getTokenUri: () => Promise /** Current signer-set aggregate pubkey (33B compressed) from `sbtc-registry`. */ getSignersPublicKey: () => Promise /** Signers' taproot deposit address, network-aware from `client.chain`. */ getSignersAddress: () => Promise } }; /** * sBTC extension for the Stacks client. * * @example * import { createWalletClient, http, mainnet } from "stacks"; * import { sbtc } from "stacks/sbtc"; * * const client = createWalletClient({ * chain: mainnet, * transport: http(), * }).extend(sbtc()); * * const supply = await client.sbtc.getTotalSupply(); * const balance = await client.sbtc.getBalance("SP1..."); */ declare function sbtc(): (client: Client) => SbtcActions; export { validateBitcoinTxid, sbtcToSats, sbtcContractId, sbtc, satsToSbtc, formatBtcAddress, bitcoinTxidToHex, bitcoinTxidFromHex, WithdrawalRejectEvent, WithdrawalCreateEvent, WithdrawalAcceptEvent, UpdateProtocolContractEvent, SbtcTokenTransferEvent, SbtcTokenMintEvent, SbtcTokenEvent, SbtcTokenBurnEvent, SbtcRegistryEvent, SbtcNetwork, SbtcEventTopic, SbtcEventByTopic, SbtcBtcRecipient, SbtcActions, SBTC_UNIT_NAME, SBTC_TOKEN_ABI, SBTC_EVENT_TOPICS, SBTC_DECIMALS, SBTC_CONTRACTS, SBTC_BTC_ADDRESS_VERSION, SBTC_ASSET_IDENTIFIER_TESTNET, SBTC_ASSET_IDENTIFIER_MAINNET, KeyRotationEvent, CompletedDepositEvent };