Skip to content

Instantly share code, notes, and snippets.

@supertestnet
Last active January 10, 2026 03:19
Show Gist options
  • Select an option

  • Save supertestnet/1844b927ec6e9e17d476a5fc2d691668 to your computer and use it in GitHub Desktop.

Select an option

Save supertestnet/1844b927ec6e9e17d476a5fc2d691668 to your computer and use it in GitHub Desktop.
Connector Swaps

Overview

In this document, I compare two existing technologies for paying L1 bitcoin addresses from lightning channels, and then introduce a new protocol for this.

Background

In bitcoin’s lightning network (LN), capital is typically allocated into structures called channels where two channel users split up the total balance of a utxo via presigned transactions. Additional off-chain transactions allow the two users to modify the balance they can withdraw from their channel as well as use a procedure called “routing” to chain transactions and channels together and thus pay other people without doing an L1 transaction.

Sometimes, a channel user wants to make an L1 transaction and pay a standard bitcoin address, but all their money is in an LN channel. There are two main solutions that allow this: splice-outs and swap-outs, which I will henceforth call splices and swaps.

Splices and Swaps

Splices allow two channel users to cooperatively sign a transaction that consumes their channel as an input and has two outputs: the first sends the intended amount to the sender’s intended destination, and the second returns the change to the channel, where it is divided up again via presigned transactions. In a splice, neither channel user loses their balance, except in the sense that the sender loses the amount he or she sent, plus mining fees.

Swaps allow a channel user to route an LN payment to a third party “swap provider,” whose business is to pay L1 addresses in return for LN payments. Swap providers typically charge a service fee to cover the cost of L1 mining fees and to make a profit, and they also often leverage smart contracts to assure LN users that they won’t get short-changed during the swap. Some (including me) even say that a swap provider who doesn’t use such a smart contract as an assurance to their users isn’t “really” a swap provider.

Advantage of swaps: capacity

I think swaps are usually better than splices. An initial clue in support of this intuition comes in the form of channel capacity. Suppose a channel has two users, and each puts 50k sats in the channel. Its total capacity is 100k sats (the sum of each user’s balance) and thus that is the maximum balance either user can have in that channel, without doing an L1 transaction to change it (a “splice-in”). If a user opts to send 10k sats out of the channel via a splice, not only does the user’s balance fall by 10k sats, but the total capacity of the channel also falls by 10k sats. Consequently, for both users, their maximum potential balance in that channel is lower than it was before. This is particularly painful when you recall that many wallets have their users “pay” for the capacity that goes into their channel. Every time such users do a splice, the capacity that they paid for goes down, and many users “feel” this loss every time.

In a swap, that doesn’t happen. Routed payments change a user’s balance, but not their channel’s capacity. If a user has 50k sats in a 100k sat channel, and they send someone 10k sats, their “balance” falls to 40k, but the channel capacity stays at 100k sats, because their channel counterparty’s balance “rises” by 10k sats. (That counterparty also “loses” 10k sats in other channels, in a chain of inter-channel payments that terminates with the final recipient.)

One might expect that splices should overall be cheaper than swaps due to the absence of a third party business charging a service fee, but since splices impose a “cost” on both parties (in terms of reduced channel capacity), many wallets that support splicing are designed so that the counterparty to a splice receives something equivalent to a service fee, probably in part to compensate them for this loss. But probably mostly because such wallets treat splices as a service that enhances the utility of the wallet, and thus they charge for providing that service. Either way, there’s a cost similar to the fee charged by “regular” swap providers, and on top of that, the channel’s capacity (which the user probably paid for) falls whenever they do a splice.

Advantage of swaps: batching

Swaps are also (usually) better than splices because, at least for now, there is better tooling for swap providers to batch transactions together. Swap providers like Lightning Loop routinely batch swap requests together from across the lightning network, allowing for a single transaction to satisfy a large number of users of many different wallets, and lowering the per-user fee as a result.

Theoretically, splices can be batched too, and work is ongoing to create tools for splice-compatible wallets to communicate with one another and organize their splices into cost-saving batches. But for now, it’s easier to make swaps cheaper than splices by batching them together, and businesses are already doing so.

Advantage of splices: 1 tx instead of 2

One significant advantage that splices have over most swap services is that splices only require 1 base layer transaction, whereas most swap services use 2. The first transaction in a swap funds a smart contract and the second executes that smart contract. But in a splice, no smart contract is required, unless you count a lightning channel itself as a kind of smart contract. So only 1 transaction occurs, and this characteristic often offsets the cost of not being batched, and perhaps the cost of lost capacity as well. As a result, sometimes splices are the most efficient way to pay an L1 bitcoin address.

Sidebar: papa swaps

What if it is possible to do a swap in only 1 transaction, thus making swaps equal to splices in respect of their transaction count? I think it is. In one of the projects I released last year, I announced and demonstrated the feasibility of “papa swaps,” which are a type of swap that only uses 1 transaction to go from LN to L1, or from L1 to LN.

However, papa swaps have some limitations, including this: in an LN to L1 swap, the L1 address has to have a custom script. You can’t use papa swaps to send to any arbitrary L1 bitcoin address, like you can with a splice, because the address you want to send to is unlikely to encode the smart contract functionality that makes papa swaps work. Or rather, you can send to an arbitrary address with papa swaps, but it requires 2 transactions again, which defeats the purpose.

Connector swaps

Today I announce a new swap protocol that fixes this, and has the single-transaction characteristic of papa swaps. The new protocol – which I call “connector swaps” – is based on the connector output technology implemented in Ark, but in this protocol I apply the technology to lightning channels.

Here is a reminder of what connector outputs are: a connector output is a bitcoin utxo, typically small (e.g. a segwit output at the 294 sat dust limit qualifies), which allows users to conditionally “revoke” presigned bitcoin transactions. They require a setup procedure, which consists of adding the connector output to a bitcoin transaction as one of its inputs, and then signing it. This procedure creates a presigned transaction that can be revoked in the following manner: if anyone “spends” the connector output, one or more of the signatures in the presigned transaction become “revoked,” or invalidated, because a bitcoin signature is invalid if it signs a transaction with an input that has already been spent (with some exceptions when signers opt into using the atypical sighash_anyone_can_pay flag).

Setting up a channel to use connector swaps

For compatibility with the connector swap protocol, a lightning channel must be “connector aware,” i.e. both users of the channel need to use software that understands this protocol. This can be achieved through software patches, plugins, or wrappers. Also, a connector output must be created for one or both of the users to consume and recreate in connector swaps. Such a connector can be created in the same transaction that creates the lightning channel, if one or both of its users expect to do LN to L1 swaps later, or an existing channel can be “upgraded” to one that supports connector swaps by creating a connector output “for” that channel after-the-fact. But note that doing so costs more, unless you do it in an L1 transaction that was already going to happen anyway.

The connector swap protocol “proper”

Once a connector output exists, an LN user with connector aware software can use it in a swap in the following manner: suppose two users of a channel, Alice and Bob, have a balance of 50k sats apiece (so the total capacity of their channel is 100k sats), and Alice wants to send 20k sats to an arbitrary L1 btc address. I will henceforth call this address “the destination.” Alice should first create an off-chain utxo in the Alice <--> Bob channel worth 20k sats, plus a service fee for Bob, which covers the cost of an L1 transaction, and allows him to make a profit.

This off-chain utxo should be “recoverable” by Alice if and only if her connector output exists. This is achieved by making the off-chain utxo a 2 of 2 output between Alice and Bob, similar to the channel itself, and having both sign a transaction that consumes the ~20k sats and the connector as inputs, and creates one output: it restores the ~20k sats to Alice. Thus, if the connector output doesn’t exist, both signatures are invalid, and Alice can’t recover her ~20k sats. A second transaction, signed by Alice and Bob, allows Bob to take the ~20k sats after a timelock expires (e.g. 10 blocks), without consuming the connector – so, if it ceases to exist, Bob’s path is unaffected.

Once both transactions are signed, Alice gives Bob a final signature: one that is valid for an L1 transaction – “the payment transaction” – with the following properties. (1) It consumes one or more of Bob’s utxos (he gets to pick what ones to use) (2) it consumes the connector output (3) it pays 20k sats to the destination (4) it creates a “replacement” connector output with the same value and the same script as the current one (5) it sends any of Bob’s change anywhere Bob likes. Bob signs and broadcasts the payment transaction, and once it confirms, Bob knows he is guaranteed to get the off-chain ~20k sat output if he broadcasts the latest state of the Alice <--> Bob channel. But that’s the sad path.

The happy path is: the payment transaction confirms, whereupon Alice and Bob cooperatively resolve the utxo off-chain, pushing 20k sats from Alice’s side of the channel to Bob’s side in the process, plus his service fee. If the L1 tx does not confirm (e.g. maybe Bob decided not to broadcast it), Alice can unilaterally recover her ~20k sats by closing her channel and sweeping the ~20k sat utxo. If Bob’s L1 tx confirms but Alice refuses to pay him off-chain, Bob can close the channel in its latest state, wait for the timelock to expire, and then sweep the ~20k sat utxo.

Benefits of the connector swap protocol

The destination received the amount Alice wanted to send to it; it was allowed to be any bitcoin address; the capacity of the Alice <--> Bob channel did not change; Alice’s balance fell by the amount sent, plus a service fee; Bob’s balance rose by the same amount; a new connector replaced the old, ready for use in Alice’s next LN to L1 transaction (or perhaps Bob’s); and only 1 L1 transaction was required to accomplish this.

Connector swaps also significantly improve the main trust problem with submarine swaps, which is, what if the user abandons the swap just after the smart contract gets funded? If he didn't prepay the fee, the server loses money, but if he did, the server can steal the fee payment, and never do the swap. But with connector swaps, the smart contract is off-chain, so if the user innocently changes his mind, the server can cooperatively resolve it back to him. Thus, neither party loses any money, nor can either party steal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment