Swaps
9 min
swaps let a node backed voltage wallet send bitcoin on one rail using funds from the other your application creates a normal payment and sets flow preference to swap ; voltage coordinates the lightning payment and hashlocked on chain transaction see the demo see swaps in action with the voltage swap demo https //voltage swaps netlify app/ the demo runs on mutinynet and shows both on chain to lightning and lightning to on chain swaps open the voltage swap demo https //voltage swaps netlify app/ you can use swaps to pay an on chain bitcoin address using your wallet's lightning liquidity pay a bolt11 invoice using your wallet's on chain balance both directions use the same payments api you use for other sends before you begin node backed wallets only swaps are designed for btc wallets backed by your lightning node credit backed wallets already support both lightning and on chain payments natively from the same wallet, so they do not need swaps and cannot set flow preference "swap" you need a btc node backed wallet with swaps enabled an api key with access to its organization and environment enough balance on the funding rail for the payment and network fees we recommend testing first on mutinynet with low value funds and a destination controlled by a separate wallet or node create a swap send a post request to /v1/organizations/{organization id}/environments/{environment id}/payments generate the payment id in your application and retain it before sending the request payment creation returns 202 accepted , and you will use that id to track the swap on chain to lightning the following example uses 50,000 sats from the node backed wallet's on chain balance to pay a bolt11 invoice curl request post \\ \ url "https //voltageapi com/v1/organizations/$organization id/environments/$environment id/payments" \\ \ header "content type application/json" \\ \ header "x api key $voltage api key" \\ \ data '{ "id" "your payment uuid", "wallet id" "your node backed wallet id", "currency" "btc", "type" "bolt11", "flow preference" "swap", "data" { "payment request" "lntbs ", "amount" { "currency" "btc", "amount" 50000000 }, "max fee" { "currency" "btc", "amount" 2000000 } } }' btc amounts in this request are expressed in millisatoshis 50,000 sats is 50000000 millisats max fee is a ceiling, not a fee quote voltage publishes the hashlocked on chain funding transaction and waits for the required confirmation count—at least one confirmation—before paying the lightning invoice it then claims the on chain contract and completes the payment lightning to on chain to pay an on chain address from lightning liquidity, change the payment type and destination data { "id" "your payment uuid", "wallet id" "your node backed wallet id", "currency" "btc", "type" "onchain", "flow preference" "swap", "data" { "address" "tb1p ", "amount" { "currency" "btc", "amount" 50000000 }, "max fee" { "currency" "btc", "amount" 2000000 } } } voltage pays a private hold invoice from the customer node, funds the hashlocked on chain output, and claims it to the requested address the shared payment hash binds the two payment rails together track the payment poll the payment using the id you generated curl \\ \ url "https //voltageapi com/v1/organizations/$organization id/environments/$environment id/payments/your payment uuid" \\ \ header "x api key $voltage api key" continue until the top level status is completed or failed immediately after creation, a read can briefly return 404 while the payment reaches the read model; retry it as a processing state swap progress appears in data outflows entries with type "swap" direction progress steps on chain → lightning source submitted → target paid → source claimed lightning → on chain source payment submitted → target submitted → target claimed receipts on these outflows provide transaction ids, payment hashes, amounts, and confirmation details that you can surface in your application the optional payment breakdown contains the final principal and network fee totals when available testing notes use an external destination when testing if voltage finds a matching internal receive, it can complete the payment as a shortcircuit without creating a swap a completed on chain to lightning payment means the final claim was broadcast or recovered its block confirmation can arrive later flow preference "swap" does not fall back to a direct payment the contracts include timelocked refund paths, but the current public api does not automatically construct or broadcast refunds a failure after funds are locked can require help from voltage support