@arkade-os/boltz-swap
Version:
A production-ready TypeScript package that brings Boltz submarine-swaps to Arkade.
721 lines (717 loc) • 34 kB
TypeScript
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 };