UNPKG

@arkade-os/boltz-swap

Version:

A production-ready TypeScript package that brings Boltz submarine-swaps to Arkade.

721 lines (717 loc) 34 kB
import { IWallet, ArkProvider, IndexerProvider, ArkInfo, Identity, ArkTxInput, VHTLC } from '@arkade-os/sdk'; import { r as BoltzSwapProvider, y as SwapManager, m as SwapRepository, q as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, n as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as BoltzReverseSwap, S as SendLightningPaymentRequest, o as SendLightningPaymentResponse, O as OptimisticSendLightningPaymentResponse, c as BoltzSubmarineSwap, f as SubmarineRefundOutcome, g as SubmarineRecoveryInfo, h as SubmarineRecoveryResult, j as ArkToBtcResponse, a as BoltzChainSwap, l as ChainArkRefundOutcome, k as BtcToArkResponse, d as Chain, F as FeesResponse, i as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from './types-BKEkNZxK.js'; import { TransactionOutput } from '@scure/btc-signer/psbt.js'; /** * Boltz-Ark VHTLC timeouts. The shape matches Boltz's `timeoutBlockHeights` * API field, but the legacy name is misleading — these are not all block * heights: * - `refund` is an absolute Unix timestamp in seconds (CLTV with timestamp * semantics, BIP65 threshold ≥ 500_000_000). * - `unilateralClaim`, `unilateralRefund`, `unilateralRefundWithoutReceiver` * are BIP68 *relative* delays measured from the lockup confirmation. Values * ≥ 512 are interpreted as seconds (BIP68 type-flag). For Boltz Ark mainnet * they're always seconds. */ type VhtlcTimeouts = { refund: number; unilateralClaim: number; unilateralRefund: number; unilateralRefundWithoutReceiver: number; }; /** * Unified entry point for Lightning and chain swaps between Arkade, Lightning Network, and Bitcoin. * * Orchestrates submarine swaps (Arkade → Lightning), reverse swaps (Lightning → Arkade), * and chain swaps (ARK ↔ BTC) through the Boltz swap protocol. * * Optionally integrates SwapManager for autonomous background monitoring, auto-claiming, * and auto-refunding of swaps. */ declare class ArkadeSwaps { /** The Arkade wallet instance used for signing and address generation. */ readonly wallet: IWallet; /** Provider for Ark protocol operations (VTXO management, batch joining). */ readonly arkProvider: ArkProvider; /** Boltz API client for creating and monitoring swaps. */ readonly swapProvider: BoltzSwapProvider; /** Provider for querying VTXO state on the Ark indexer. */ readonly indexerProvider: IndexerProvider; /** Background swap monitor, or null if not enabled. */ readonly swapManager: SwapManager | null; /** Storage backend for persisting swap data. */ readonly swapRepository: SwapRepository; /** * Creates an ArkadeSwaps instance, auto-detecting the network from the wallet's Ark server. * If no `swapProvider` is given, one is created automatically using the detected network. * * This is the recommended way to initialize ArkadeSwaps. * * @param config - Configuration options. swapProvider is auto-created from the wallet's network if omitted. * @returns A fully initialized ArkadeSwaps instance. * * @example * ```ts * const swaps = await ArkadeSwaps.create({ * wallet, * swapManager: true, * }); * ``` */ static create(config: ArkadeSwapsCreateConfig): Promise<ArkadeSwaps>; constructor(config: ArkadeSwapsConfig); private savePendingReverseSwap; private savePendingSubmarineSwap; private savePendingChainSwap; private getPendingReverseSwapsFromStorage; private getPendingSubmarineSwapsFromStorage; private getPendingChainSwapsFromStorage; /** * Start the background swap manager. * This will load all pending swaps and begin monitoring them. * Automatically called when SwapManager is enabled. */ startSwapManager(): Promise<void>; /** * Stop the background swap manager. */ stopSwapManager(): Promise<void>; /** * Get the SwapManager instance. * Useful for accessing manager stats or manually controlling swaps. */ getSwapManager(): SwapManagerClient | null; /** * Dispose of resources (stops SwapManager and cleans up). * Can be called manually or automatically with `await using` syntax (TypeScript 5.2+). */ /** * Reset all swap state: stops the SwapManager and clears the swap repository. * * **Destructive** — any swap in a non-terminal state will lose its * refund/claim path. Intended for wallet-reset / dev / test scenarios only. */ reset(): Promise<void>; dispose(): Promise<void>; /** * Symbol.asyncDispose for automatic cleanup with `await using` syntax. */ [Symbol.asyncDispose](): Promise<void>; /** * Creates a Lightning invoice via a reverse swap (Lightning → Arkade). * @param args.amount - Invoice amount in satoshis. * @param args.description - Optional description for the BOLT11 invoice. * @returns Object containing the BOLT11 invoice, payment hash, preimage, and pending swap for monitoring. * @throws {SwapError} If amount is <= 0 or wallet key retrieval fails. */ createLightningInvoice(args: CreateLightningInvoiceRequest): Promise<CreateLightningInvoiceResponse>; /** * Creates a reverse swap (Lightning → Arkade) and saves it to storage. * @param args.amount - Amount in satoshis for the reverse swap. * @param args.description - Optional invoice description. * @returns The pending reverse swap, added to SwapManager if enabled. * @throws {SwapError} If amount is <= 0 or key retrieval fails. */ createReverseSwap(args: CreateLightningInvoiceRequest): Promise<BoltzReverseSwap>; /** * Claims the VHTLC for a pending reverse swap, transferring locked funds to the wallet. * @param pendingSwap - The reverse swap whose VHTLC should be claimed. * @throws {Error} If preimage is missing, VHTLC script creation fails, or no spendable VTXOs found. */ claimVHTLC(pendingSwap: BoltzReverseSwap): Promise<void>; /** * Waits for a reverse swap to be confirmed and claims the VHTLC. * Delegates to SwapManager if enabled, otherwise monitors via WebSocket. * @param pendingSwap - The reverse swap to monitor and claim. * @returns The transaction ID of the claimed VHTLC. * @throws {InvoiceExpiredError} If the Lightning invoice expires. * @throws {SwapExpiredError} If the swap exceeds its time limit. * @throws {TransactionFailedError} If the on-chain transaction fails. */ waitAndClaim(pendingSwap: BoltzReverseSwap): Promise<{ txid: string; }>; /** * Sends a Lightning payment via a submarine swap (Arkade → Lightning). * Creates the swap, sends funds, and waits for settlement (or, with * `waitFor: "funded"`, only until the lockup transaction is observed — * see {@link SendLightningPaymentRequest.waitFor}). Auto-refunds on * failures observed before the promise resolves. * @param args.invoice - BOLT11 Lightning invoice to pay. * @param args.waitFor - "settled" (default) resolves with the preimage at * "transaction.claimed"; "funded" resolves without a preimage as soon as * the payment is in flight. * @returns The amount paid, preimage (proof of payment, unless resolved * at "funded"), and transaction ID. * @throws {TransactionFailedError} If the payment fails (auto-refunds if possible). * @remarks With `waitFor: "funded"`, failures observed *after* the promise * resolves are only persisted to the repository (refundable flag) — the * active auto-refund in this method is no longer reachable. Keep the * SwapManager enabled so late failures are refunded automatically; * without it the caller must recover via {@link restoreSwaps} / * {@link recoverSubmarineFunds}. * * Note on types: the overloads narrow on the `waitFor` literal, so a * request stored in a variable typed as `SendLightningPaymentRequest` * widens the result to {@link OptimisticSendLightningPaymentResponse} * (optional preimage) even on the default settled path. */ sendLightningPayment(args: SendLightningPaymentRequest & { waitFor?: "settled"; }): Promise<SendLightningPaymentResponse>; sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>; /** * Creates a submarine swap (Arkade → Lightning) and saves it to storage. * @param args.invoice - BOLT11 Lightning invoice to pay. * @returns The pending submarine swap, added to SwapManager if enabled. * @throws {SwapError} If invoice is missing or key retrieval fails. */ createSubmarineSwap(args: SendLightningPaymentRequest): Promise<BoltzSubmarineSwap>; /** * Reconstruct a submarine swap's VHTLC script from stored data. This does * not query the indexer, so bulk scans can build every script first and * then use batched VTXO lookups. * * @throws {Error} If preimage hash is unavailable, the swap response is * incomplete, the script can't be built, or the reconstructed address * doesn't match the one Boltz returned. */ private buildSubmarineVHTLCContext; /** * Reconstruct a submarine swap's VHTLC script from stored data and look * up its VTXOs at the indexer. Side-effect free; shared by `refundVHTLC` * (spending path) and `inspectSubmarineRecovery` (diagnostic path). * * `refundableVtxos` merges spendable + recoverable indexer queries * (deduped by outpoint). When that set is empty, a third query * populates `diagnostic` so callers can distinguish "never funded", * "already spent", and "preconfirmed-only". */ private lookupSubmarineVHTLC; private submarineRecoveryInfoFromLookup; /** * Refunds the VHTLC for a failed submarine swap, returning locked funds to the wallet. * Uses multi-party signatures (user + Boltz + server) for non-recoverable VTXOs. * @param pendingSwap - The submarine swap to refund. * @returns Counts of VTXOs swept vs. deferred. A return value of `{ swept: 0, skipped: N }` * means the call was a no-op — callers should not treat it as a successful refund. * @throws {Error} If preimage hash is unavailable, VHTLC not found, or already spent. */ refundVHTLC(pendingSwap: BoltzSubmarineSwap, cachedArkInfo?: ArkInfo): Promise<SubmarineRefundOutcome>; /** * Inspect a submarine swap's lockup address for recoverable funds. * * Side-effect free. Returns a structured snapshot the UI can use to * decide whether to offer the user a recovery action — it will not * trigger any signing or persistence. * * Only `transaction.claimed` (success with possible stranded extras) * and refundable failure statuses are recovery candidates. Pending * statuses (`invoice.set`, `transaction.mempool`, …) are returned as * `invalid_swap`; this API is for recovery, not a generic VTXO probe. * * @param swap - The submarine swap to inspect. */ inspectSubmarineRecovery(swap: BoltzSubmarineSwap): Promise<SubmarineRecoveryInfo>; /** * Scan all locally-known submarine swaps for recoverable VHTLC funds. * * Loads submarine swaps from the repository, filters to recovery * candidates (`transaction.claimed` plus refundable failure * statuses), reconstructs their scripts, and performs one batched * spendable query plus one batched recoverable query. Pending swaps are * skipped entirely — they appear in the local repository but cannot * be in a recovery state yet. * * Side-effect free: does not mutate the repository, does not sign, * and does not query Boltz swap status. */ scanRecoverableSubmarineSwaps(): Promise<SubmarineRecoveryInfo[]>; /** * Recover funds locked at a single submarine swap's VHTLC address. * * Thin wrapper around `refundVHTLC` for callers that have already * confirmed (e.g. via `inspectSubmarineRecovery`) that funds are * present. Centralises the spending logic in one place — flag-write * behavior matches `refundVHTLC` (no-op for `transaction.claimed`, * normal flag updates for failure statuses). */ recoverSubmarineFunds(swap: BoltzSubmarineSwap, arkInfo?: ArkInfo): Promise<SubmarineRefundOutcome>; /** * Recover funds for a batch of submarine swaps. * * Each swap's recovery is independent — a failure on one swap does * not abort the rest, and the caller receives a per-swap result so * they can present partial outcomes in the UI. Recovery runs * sequentially to avoid hammering Boltz / the indexer with parallel * batch joins. */ recoverAllSubmarineFunds(swaps: BoltzSubmarineSwap[]): Promise<SubmarineRecoveryResult[]>; /** * Waits for a submarine swap's Lightning payment to settle. * Resolves only at the terminal "transaction.claimed" status, once Boltz * has swept the HTLC. To resolve as soon as the payment is in flight, use * {@link waitForSwapFunded} instead. * @param pendingSwap - The submarine swap to monitor. * @returns The preimage from the settled Lightning payment (proof of payment). * @throws {SwapExpiredError} If the swap expires. * @throws {InvoiceFailedToPayError} If Boltz fails to route the payment. * @throws {TransactionLockupFailedError} If the lockup transaction fails. */ waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{ preimage: string; }>; /** * Waits until a submarine swap is funded: resolves as soon as the lockup * transaction is observed ("transaction.mempool" or any later status in * the lifecycle — statuses can be skipped since subscriptions report only * the current one). The sender's funds are committed and the swap is * refundable from this point, which is when most Lightning wallets show * a payment as "sent". * * Monitoring continues in the background until the swap reaches a * terminal status, persisting updates to the repository (the preimage on * claim, the refundable flag on failure), but this promise no longer * rejects once resolved — acting on a late failure is the caller's * responsibility (the SwapManager handles it automatically when enabled). * @param pendingSwap - The submarine swap to monitor. * @throws {SwapExpiredError} If the swap expires before funding. * @throws {InvoiceFailedToPayError} If Boltz fails to route the payment. * @throws {TransactionLockupFailedError} If the lockup transaction fails. */ waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>; /** * Shared wait machinery: monitors the swap and resolves at the terminal * "transaction.claimed" status (with the preimage) or, when `resolveAt` * is given, as soon as that status — or any later one in the successful * progression — is observed (without a preimage). */ private waitForSubmarineSwap; /** * Creates a chain swap from ARK to BTC. * @param args.btcAddress - Destination Bitcoin address. * @param args.senderLockAmount - Exact amount sender locks (receiver gets less after fees). Specify this OR receiverLockAmount. * @param args.receiverLockAmount - Exact amount receiver gets (sender pays more). Specify this OR senderLockAmount. * @param args.feeSatsPerByte - Fee rate for the BTC claim transaction (default: 1). * @returns The ARK lockup address, amount to pay, and pending swap. * @throws {SwapError} If chain swap verification fails. */ arkToBtc(args: { btcAddress: string; senderLockAmount?: number; receiverLockAmount?: number; feeSatsPerByte?: number; }): Promise<ArkToBtcResponse>; /** * Waits for the swap to be confirmed and claims BTC. * @param pendingSwap - The pending chain swap to monitor. * @returns The transaction ID of the claimed HTLC. */ waitAndClaimBtc(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; /** * Claim sats on BTC chain by claiming the HTLC. * * The claim output is `swapOutput.amount − max(feeToDeliverExactAmount, targetFee)`. * * @param pendingSwap - The pending chain swap with BTC transaction hex. * @returns The BTC transaction ID of the claim. */ claimBtc(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; /** * When an ARK to BTC swap fails, refund every unspent VTXO at the chain * swap's ARK lockup address. * * Path selection per VTXO: * - CLTV elapsed, live VTXO → `refundWithoutReceiver` offchain (sender + * server, no Boltz, no batch round). * - CLTV elapsed, swept VTXO → `refundWithoutReceiver` via `joinBatch` * (a swept VTXO is no longer a live leaf). * - Pre-CLTV recoverable → skipped (Boltz can't co-sign swept-batch refund). * - Pre-CLTV non-recoverable → cooperative 3-of-3 refund via Boltz. * * @param pendingSwap - The pending chain swap to refund. * @returns Counts of VTXOs swept vs. deferred. A `swept: 0` outcome means * the call was a no-op — callers should retry after CLTV. */ refundArk(pendingSwap: BoltzChainSwap): Promise<ChainArkRefundOutcome>; /** * Creates a chain swap from BTC to ARK. * @param args.feeSatsPerByte - Fee rate for BTC transactions (default: 1). * @param args.senderLockAmount - Exact BTC amount to lock. Specify this OR receiverLockAmount. * @param args.receiverLockAmount - Exact ARK amount to receive. Specify this OR senderLockAmount. * @returns The BTC lockup address, amount to pay, and pending swap. * @throws {SwapError} If chain swap verification fails. */ btcToArk(args: { feeSatsPerByte?: number; senderLockAmount?: number; receiverLockAmount?: number; }): Promise<BtcToArkResponse>; /** * Waits for the swap to be confirmed and claims ARK. * @param pendingSwap - The pending chain swap to monitor. * @returns The transaction ID of the claimed VHTLC. */ waitAndClaimArk(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; /** * Claim sats on ARK chain by claiming the VHTLC. * Refactored to use claimVHTLCIdentity + claimVHTLCwithOffchainTx utilities. * @param pendingSwap - The pending chain swap. * @returns The Ark transaction ID of the claim. */ claimArk(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; /** * Resolve the on-chain txid for a chain swap at completion. * * The claim transaction we broadcast (claimBtc/claimArk) carries the real * on-chain txid; getSwapStatus does not surface it at transaction.claimed. * Prefer the claim's txid and fall back to the provider status only for * resumed swaps where we never ran the claim ourselves (claimPromise is * undefined). Returns undefined when no usable txid is available, so * callers never resolve with the Boltz swap id in place of a real txid. */ private resolveChainClaimTxid; /** * Sign a cooperative claim for the server in BTC => ARK swaps. * @param pendingSwap - The pending chain swap. */ signCooperativeClaimForServer(pendingSwap: BoltzChainSwap): Promise<void>; /** * Waits for a chain swap to be claimable and then claims it. * Dispatches to waitAndClaimArk or waitAndClaimBtc based on swap direction. * @param pendingSwap - The pending swap to wait for and claim. * @returns The transaction ID of the claim. */ waitAndClaimChain(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; /** * Creates a chain swap. * @param args - The arguments for creating a chain swap. * @returns The created pending chain swap. */ createChainSwap(args: { to: Chain; from: Chain; toAddress: string; feeSatsPerByte?: number; senderLockAmount?: number; receiverLockAmount?: number; }): Promise<BoltzChainSwap>; /** * Validates the lockup and claim addresses match the expected scripts. * @param args - The arguments for verifying a chain swap. * @returns True if the addresses match. */ verifyChainSwap(args: { to: Chain; from: Chain; swap: BoltzChainSwap; arkInfo: ArkInfo; }): Promise<boolean>; /** * Verifies the BTC-side Taproot HTLC of a chain swap before funds are * committed: the lockup address must bind to MuSig2(boltz, user) over * Boltz's leaves, and those leaves must enforce the agreed preimage hash, * direction-specific keys, leaf version, and absolute refund CLTV. */ private verifyBtcChainHtlc; /** * Renegotiates the quote for an existing chain swap. Convenience wrapper * over `getSwapQuote` + `acceptSwapQuote` with a safety floor. * * The floor is resolved in order: * 1. `options.minAcceptableAmount` if provided. * 2. The original `response.claimDetails.amount` of the stored * pending swap (Boltz-confirmed server-lock amount at creation). * 3. Otherwise throws `QuoteRejectedError({ reason: "no_baseline" })`. * * `options.maxSlippageBps` (default 0) relaxes the floor by basis points. * Quotes ≤ 0 are always rejected. On rejection the acceptance is NOT * posted to Boltz. * * Prefer `getSwapQuote` / `acceptSwapQuote` for callers that want to * inspect the quote before committing. * * @param swapId - The ID of the swap. * @param options - Optional floor and slippage configuration. * @returns The accepted quote amount. * @throws QuoteRejectedError if the quote is non-positive, below the * effective floor, or no baseline is available. */ quoteSwap(swapId: string, options?: QuoteSwapOptions): Promise<number>; /** * Fetches a renegotiated quote from Boltz without accepting it. * Pair with `acceptSwapQuote` to commit a specific value. */ getSwapQuote(swapId: string): Promise<number>; /** * Accepts a quote amount for an existing chain swap, after validating it * against the configured floor. See `quoteSwap` for floor-resolution rules. * * @throws QuoteRejectedError if `amount` ≤ 0, below the effective floor, * or no baseline is available. */ acceptSwapQuote(swapId: string, amount: number, options?: QuoteSwapOptions): Promise<number>; private resolveEffectiveFloor; private resolveQuoteFloor; private validateQuoteOptions; private validateQuote; /** * Joins a batch to spend the vtxo via commitment transaction. * @param identity - The identity to use for signing. * @param input - The input vtxo. * @param output - The output script. * @param arkInfo - Chain information used for building transactions. * @param isRecoverable - Whether the input is recoverable. * @returns The commitment transaction ID. */ joinBatch(identity: Identity, input: ArkTxInput, output: TransactionOutput, arkInfo: ArkInfo, isRecoverable?: boolean): Promise<string>; /** * Settle a `refundWithoutReceiver` (sender + server, no Boltz) refund for a * single VTXO whose CLTV refund locktime has elapsed. * * A live VTXO settles the leaf with an offchain Ark tx — no batch round. A * swept (recoverable) VTXO is no longer a live leaf, so it can only be * reclaimed by re-registering it into a batch. */ private settleRefundWithoutReceiver; /** * Refund every VTXO at a swap's VHTLC address back to the wallet, shared by * {@link ArkadeSwaps.refundVHTLC} (submarine) and {@link ArkadeSwaps.refundArk} * (chain). Path selection per VTXO: * - CLTV elapsed → `refundWithoutReceiver` (offchain for a live VTXO, via a * batch round for a swept one — see {@link settleRefundWithoutReceiver}). * - Pre-CLTV recoverable → skipped (Boltz can't co-sign a swept-batch refund). * - Pre-CLTV non-recoverable → cooperative 3-of-3 refund via Boltz, falling * back to `refundWithoutReceiver` offchain if Boltz rejects after the * locktime has since elapsed. * * @returns Counts of VTXOs swept vs. deferred. */ private refundVtxos; /** * Creates a VHTLC script for the swap. * Works for submarine, reverse, and chain swaps. */ createVHTLCScript(args: { network: string; preimageHash: Uint8Array; receiverPubkey: string; senderPubkey: string; serverPubkey: string; timeoutBlockHeights: VhtlcTimeouts; }): { vhtlcScript: VHTLC.Script; vhtlcAddress: string; }; /** * Reconstruct a swap's VHTLC by matching the persisted `lockupAddress` * against the current and deprecated server signers, returning the matched * script together with the server key it was minted under. * * Recovery paths (claim/refund/lookup) must use this instead of building the * VHTLC from the current signer alone: a swap created before a planned arkd * signer rotation is locked to a now-deprecated signer, so the current key * would yield the wrong address and strand the funds. The returned * `serverXOnlyPublicKey` is the original (possibly deprecated) key and MUST * be threaded into downstream signing/verification. * * Throws a descriptive mismatch error when no candidate reproduces the * lockup address (e.g. the swap predates an already-pruned deprecated * signer) — replacing the previous current-signer-only equality check. */ private resolveVHTLCForLockup; /** * Retrieves fees for swaps. * - No arguments: returns lightning (submarine/reverse) fees * - With (from, to) arguments: returns chain swap fees */ getFees(): Promise<FeesResponse>; getFees(from: Chain, to: Chain): Promise<ChainFeesResponse>; /** * Retrieves max and min limits for swaps. * - No arguments: returns lightning swap limits * - With (from, to) arguments: returns chain swap limits */ getLimits(): Promise<LimitsResponse>; getLimits(from: Chain, to: Chain): Promise<LimitsResponse>; /** * Retrieves swap status by ID. * @param swapId - The ID of the swap. * @returns The status of the swap. */ getSwapStatus(swapId: string): Promise<GetSwapStatusResponse>; /** * Returns pending submarine swaps (those with status `invoice.set`). */ getPendingSubmarineSwaps(): Promise<BoltzSubmarineSwap[]>; /** * Returns pending reverse swaps (those with status `swap.created`). */ getPendingReverseSwaps(): Promise<BoltzReverseSwap[]>; /** * Returns pending chain swaps (those with status `swap.created`). */ getPendingChainSwaps(): Promise<BoltzChainSwap[]>; /** * Retrieves swap history from storage. * @returns Array of all swaps (reverse + submarine + chain) sorted by creation date (newest first). */ getSwapHistory(): Promise<BoltzSwap[]>; /** * Refreshes the status of all pending swaps in the storage provider. */ refreshSwapsStatus(): Promise<void>; /** * Restore swaps from Boltz API. * * Note: restored swaps may lack local-only data such as the original * Lightning invoice or preimage. They are intended primarily for * display/monitoring and are not automatically wired into the SwapManager. */ restoreSwaps(boltzFees?: FeesResponse): Promise<{ chainSwaps: BoltzChainSwap[]; reverseSwaps: BoltzReverseSwap[]; submarineSwaps: BoltzSubmarineSwap[]; }>; /** * Enrich a restored reverse swap with its preimage. */ enrichReverseSwapPreimage(swap: BoltzReverseSwap, preimage: string): BoltzReverseSwap; /** * Enrich a restored submarine swap with its invoice. */ enrichSubmarineSwapInvoice(swap: BoltzSubmarineSwap, invoice: string): BoltzSubmarineSwap; } /** Options controlling acceptance of a renegotiated chain-swap quote. */ type QuoteSwapOptions = { /** * Hard floor on the accepted quote (in sats). When provided, skips the * repository lookup. Pass the original `response.claimDetails.amount` * to require the renegotiated amount to be no worse than what Boltz * confirmed at swap creation. */ minAcceptableAmount?: number; /** * Slippage tolerance in basis points, applied to the floor. Default 0 * (strict). E.g. 100 allows accepting quotes within 1% below the floor. */ maxSlippageBps?: number; }; /** Public interface for ArkadeSwaps, defining all swap operations available to consumers. */ interface IArkadeSwaps extends AsyncDisposable { startSwapManager(): Promise<void>; stopSwapManager(): Promise<void>; getSwapManager(): SwapManagerClient | null; createLightningInvoice(args: CreateLightningInvoiceRequest): Promise<CreateLightningInvoiceResponse>; sendLightningPayment(args: SendLightningPaymentRequest & { waitFor?: "settled"; }): Promise<SendLightningPaymentResponse>; sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>; createSubmarineSwap(args: SendLightningPaymentRequest): Promise<BoltzSubmarineSwap>; createReverseSwap(args: CreateLightningInvoiceRequest): Promise<BoltzReverseSwap>; claimVHTLC(pendingSwap: BoltzReverseSwap): Promise<void>; refundVHTLC(pendingSwap: BoltzSubmarineSwap): Promise<SubmarineRefundOutcome>; inspectSubmarineRecovery(swap: BoltzSubmarineSwap): Promise<SubmarineRecoveryInfo>; scanRecoverableSubmarineSwaps(): Promise<SubmarineRecoveryInfo[]>; recoverSubmarineFunds(swap: BoltzSubmarineSwap): Promise<SubmarineRefundOutcome>; recoverAllSubmarineFunds(swaps: BoltzSubmarineSwap[]): Promise<SubmarineRecoveryResult[]>; waitAndClaim(pendingSwap: BoltzReverseSwap): Promise<{ txid: string; }>; waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{ preimage: string; }>; waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>; restoreSwaps(boltzFees?: FeesResponse): Promise<{ chainSwaps: BoltzChainSwap[]; reverseSwaps: BoltzReverseSwap[]; submarineSwaps: BoltzSubmarineSwap[]; }>; arkToBtc(args: { btcAddress: string; senderLockAmount?: number; receiverLockAmount?: number; feeSatsPerByte?: number; }): Promise<ArkToBtcResponse>; waitAndClaimBtc(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; claimBtc(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; refundArk(pendingSwap: BoltzChainSwap): Promise<ChainArkRefundOutcome>; btcToArk(args: { feeSatsPerByte?: number; senderLockAmount?: number; receiverLockAmount?: number; }): Promise<BtcToArkResponse>; waitAndClaimArk(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; claimArk(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; signCooperativeClaimForServer(pendingSwap: BoltzChainSwap): Promise<void>; waitAndClaimChain(pendingSwap: BoltzChainSwap): Promise<{ txid: string; }>; createChainSwap(args: { to: Chain; from: Chain; toAddress: string; feeSatsPerByte?: number; senderLockAmount?: number; receiverLockAmount?: number; }): Promise<BoltzChainSwap>; verifyChainSwap(args: { to: Chain; from: Chain; swap: BoltzChainSwap; arkInfo: ArkInfo; }): Promise<boolean>; quoteSwap(swapId: string, options?: QuoteSwapOptions): Promise<number>; getSwapQuote(swapId: string): Promise<number>; acceptSwapQuote(swapId: string, amount: number, options?: QuoteSwapOptions): Promise<number>; joinBatch(identity: Identity, input: ArkTxInput, output: TransactionOutput, arkInfo: ArkInfo, isRecoverable?: boolean): Promise<string>; createVHTLCScript(args: { network: string; preimageHash: Uint8Array; receiverPubkey: string; senderPubkey: string; serverPubkey: string; timeoutBlockHeights: VhtlcTimeouts; }): { vhtlcScript: VHTLC.Script; vhtlcAddress: string; }; getFees(): Promise<FeesResponse>; getFees(from: Chain, to: Chain): Promise<ChainFeesResponse>; getLimits(): Promise<LimitsResponse>; getLimits(from: Chain, to: Chain): Promise<LimitsResponse>; getPendingSubmarineSwaps(): Promise<BoltzSubmarineSwap[]>; getPendingReverseSwaps(): Promise<BoltzReverseSwap[]>; getPendingChainSwaps(): Promise<BoltzChainSwap[]>; getSwapHistory(): Promise<BoltzSwap[]>; refreshSwapsStatus(): Promise<void>; getSwapStatus(swapId: string): Promise<GetSwapStatusResponse>; enrichReverseSwapPreimage(swap: BoltzReverseSwap, preimage: string): BoltzReverseSwap; enrichSubmarineSwapInvoice(swap: BoltzSubmarineSwap, invoice: string): BoltzSubmarineSwap; /** * Reset all swap state: stops the SwapManager and clears the swap repository. * * **Destructive** — any swap in a non-terminal state will lose its * refund/claim path. Intended for wallet-reset / dev / test scenarios only. */ reset(): Promise<void>; dispose(): Promise<void>; } export { ArkadeSwaps as A, type IArkadeSwaps as I, type QuoteSwapOptions as Q, type VhtlcTimeouts as V };