import { Network } from '@babylonlabs-io/babylon-tbv-rust-wasm'; import { Address, Hex } from 'viem'; import { SignPsbtOptions } from '../../../../shared/wallets/interfaces/BitcoinWallet'; export declare const REFUND_VSIZE = 160; export declare const REFUND_MAX_FEE_RATE_SATS_VB = 2000; export declare const REFUND_MAX_FEE_FRACTION_NUMERATOR = 10n; export declare const REFUND_MAX_FEE_FRACTION_DENOMINATOR = 100n; /** * Network fee (sats) the SDK will charge for a refund tx at the given * sat/vB rate. Mirrors the internal computation in * {@link buildAndBroadcastRefund} so callers (e.g. UI fee previews) don't * have to duplicate the constant. */ export declare function estimateRefundFeeSats(feeRateSatsVb: number): bigint; /** * One vault's per-HTLC binding in a Pre-PegIn batch. Carries the fields * needed to reconstruct the WASM `WasmPrePeginTx` template byte-for-byte * against the funded transaction. */ export interface VaultBatchEntry { /** SHA-256 hashlock commitment for this vault (bytes32, 0x-prefixed). */ hashlock: Hex; /** * Vault deposit (peg-in) amount in satoshis — the on-chain contract's * `amount` field. This is the peg-in amount WASM expects in `pegInAmounts`, * NOT the funded HTLC output value (which is `amount + depositorClaimValue + * minPeginFee`). WASM re-adds that reserve internally when it sizes the HTLC * output, so this value is passed straight through. */ amount: bigint; /** Index of this vault's HTLC output in the funded Pre-PegIn tx. */ htlcVout: number; } /** * Authoritative vault fields needed to build a refund. Versioning fields, * the hashlock, and htlcVout must come from the on-chain contract (never the * indexer). The amount + `unsignedPrePeginTxHex` + `depositorBtcPubkey` can * come from the indexer since they are not security-critical for signing * (the PSBT builder re-derives the HTLC script from on-chain params). * * `batch` is the full, vout-ordered HTLC vector for the Pre-PegIn (one * entry per sibling vault that shares this funded transaction). For a * single-vault deposit this is a length-1 array. For batched deposits * (e.g. the Aave split) the orchestrator passes every sibling through * so the WASM template matches the funded tx's shape. */ export interface VaultRefundData { /** * Vault core (tx-graph) version stamped on-chain at registration * (`BTCVaultProtocolInfo.vaultCoreVersion`). The refund template must be * reconstructed under the same graph version the Pre-PegIn was built with. */ vaultCoreVersion: number; hashlock: Hex; htlcVout: number; offchainParamsVersion: number; appVaultKeepersVersion: number; universalChallengersVersion: number; vaultProvider: Address; applicationEntryPoint: Address; /** Vault deposit (peg-in) amount in satoshis — the on-chain `amount` field. */ amount: bigint; /** * Funded, pre-witness Pre-PegIn transaction hex. 0x prefix optional. * The name mirrors the contract/indexer schema; the bytes are the * funded form (refund construction needs real outpoints). */ unsignedPrePeginTxHex: string; /** Depositor's BTC public key (x-only or compressed hex; 0x prefix optional). */ depositorBtcPubkey: string; /** * Full vout-ordered HTLC vector for the funded Pre-PegIn (one entry * per sibling vault, including the target vault). Must satisfy * `batch[i].htlcVout === i` for all i, and the target's `htlcVout` / * `hashlock` / `amount` must equal `batch[vault.htlcVout]`. */ batch: ReadonlyArray; } /** * Version-resolved protocol context that parameterises the HTLC's taproot * scripts. The *signer-set* fields (`vaultKeeperPubkeys`, * `universalChallengerPubkeys`) and the version-locked numeric protocol * params **must** be sourced from the on-chain contract at the version * pinned in {@link VaultRefundData} — this is the trust boundary. * `vaultProviderPubkey` today is sourced from the GraphQL indexer via * `fetchVaultProviderById`; the caller is responsible for any additional * cross-check it requires. Keeper and challenger pubkey arrays must be * pre-sorted the same way the Rust protocol sorts them (canonical for * script derivation). */ export interface RefundPrePeginContext { vaultProviderPubkey: string; vaultKeeperPubkeys: readonly string[]; universalChallengerPubkeys: readonly string[]; timelockRefund: number; feeRate: bigint; minPeginFeeRate: bigint; numLocalChallengers: number; councilQuorum: number; councilSize: number; network: Network; } /** Minimum shape required from a broadcast result. */ export interface BtcBroadcastResult { txId: string; } export type BtcBroadcaster = (signedTxHex: string) => Promise; export type RefundPsbtSigner = (psbtHex: string, opts: SignPsbtOptions) => Promise; export interface RefundInput { vaultId: Hex; /** * Fetch authoritative on-chain + indexer vault data. The SDK passes no * arguments — the caller closes over `vaultId` (or any other context it * needs). */ readVault: () => Promise; /** * Fetch the version-pinned refund context (sorted pubkeys, timelock, etc.) * derived from the vault's locked versions. */ readPrePeginContext: (vault: VaultRefundData) => Promise; /** * Mempool-derived sat/vB fee rate to use for the refund tx (positive * number). Caller fetches this before invoking — it does not depend on * any value the SDK computes, and folding it into the call keeps the * orchestration honest. */ feeRate: number; /** BTC wallet signer; receives a PSBT hex + taproot script-path options. */ signPsbt: RefundPsbtSigner; /** Broadcast callback — returns whatever shape the caller needs. */ broadcastTx: BtcBroadcaster; /** Checked at every async boundary. */ signal?: AbortSignal; } /** * Build, sign, and broadcast a refund transaction for an expired vault. * * Trust boundary: `readVault` must source the hashlock, htlcVout, and * versioning fields from the on-chain contract — an indexer-only path * leaves the refund flow open to signer-set substitution. The SDK does * not enforce this; it is the caller's responsibility. * * The broadcast transport is expected to surface Bitcoin's `non-BIP68-final` * policy rejection as an `Error` whose message contains that string; when * it does, the SDK wraps it in {@link BIP68NotMatureError}. All other * transport errors propagate unchanged. * * @returns whatever the injected `broadcastTx` returns (generic pass-through) * @throws `Error` if any validation fails * @throws {@link BIP68NotMatureError} if the broadcast is rejected because * the refund CSV timelock has not yet matured * @throws anything `readVault`, `readPrePeginContext`, * `signPsbt`, or `broadcastTx` throws */ export declare function buildAndBroadcastRefund(input: RefundInput): Promise; //# sourceMappingURL=buildAndBroadcastRefund.d.ts.map