Welcome to your weekly summary of the latest news and developments in the Lightning Network world. We did not publish in a while, so this issue covers 3 weeks, from January 26th to February 15th. Let's dive in!
$1M Lightning Payment Settled$1M Lightning Payment Settled
On Wednesday 28th January, Secure Digital Markets sent a 1 million dollars transaction to Kraken, leveraging Voltage's infrastructure. The payment settled in 0.47 seconds, per Voltage's X post.
Now of course the transaction very likely went through a single big direct channel between SDM's Voltage node and Kraken. But still, the $1M mark is loud enough that it sends a clear signal that Lightning can indeed be used for large, enterprise-scale transactions, and not only for micropayments, as it is sometimes misconceived to be. Of course, a transaction of this size could have been conducted on-chain[1]. But even outside of the PR operation, conducting such transaction off-chain can make sense, for example:
- to preserve some degree of confidentiality around the exact flows of funds ;
- to be able to achieve instant settlement by committing funds beforehand, while still retaining self-custody as long as they're on SDM' side of the channel[2] ;
- to act as a blazingly fast "clearing house" that is setup once, and can be reused numerous times for free.
Bolt12 In LexeBolt12 In Lexe
Lexe added support for Bolt12 Offers, enabling users to receive funds to a static Lightning payment identifier. Since Lexe leverages Trusted Execution Environments (TEEs) to run users' nodes in the cloud, the user is not required to have the Lexe app open, nor their phone to be even connected to the internet or powered on, for a payment to successfully settle. This contrasts with other Bolt12-enabled wallets such as Phoenix, where the user's device is needs to be connected for the payment to settle (or even to begin, since the first step with Bolt12 Offers is for the sender's node to reach out to the recipient's to request a Bolt11 invoice)[3].
All the user needs to do is get their Bolt12 Offer in the Lexe app, and then share it to receive payments. If you want to try it out and support my writing at the same time, you can give it a try with the offer below (wink).
lno1zr5qx998w53arh9utk6kpq0de0py4wpqkd0rgwnvva53wm08qlqh34zhqvhuz7pmelcx8e7anetk7k807knc0728983e3g6djpdwhfzgaejfuqsrs8ugw9ke824eqd6grqn98jvn4frrzuj35250m47wncwt597fvazsqvey2jllxhsee5xfsh0zenf50tvlgut7epj29q8k74mg4e7qanvfaup0zvrms4un52ye83spafdreavc8kxxqvfduy4v0l3hssgn2ezj22262yqd29jp09yc2m8pvl0whhj4s4emxqpva0x489kks6muwf5kp6ejcnx53qh9d28nl9u8gyq5ltjqvmr07yt66c98rk6dx650mrnum7qkyypdmuskxsr6pkr62qhfuukrt4pjtrak6x7g5gkclxd7vvuwxkdc4cs
Amboss Reveals RailsXAmboss Reveals RailsX
Amboss revealed RailsX, an extension to their Rails product bringing stablecoins into the mix.
Rails is first and foremost a "self-custodial" yield product built on top of Bitcoin's Lightning Network[4]. Liquidity Providers (LPs) deposit bitcoins into a Lightning node, and give Amboss permissions to perform a limited set of actions, such as viewing the details of the node, opening and closing channels, adjusting the routing policies of channel, or creating an invoice. Crucially, this permissions don't include paying invoices or sending to an on-chain address. Such fine-grained permissions are enabled by LND's macaroons system. The LND node itself can either run in the cloud (powered by Voltage), or run on the LPs premises. Once everything is setup, Amboss leverages its "machine learning algorithms"[5] to deploy liquidity in the right places. In other words, from a LP point-of-view, things can be as simple as launching a node in the cloud, topping it up and letting Amboss take care of generating the yield.
RailsX extends this by adding stablecoins support. From what I grasp, the offering caters to both stablecoin issuers and stablecoin holders. RailsX helps the former distribute their token across the "Rails cluster", making it available for real payment usage ; and lets the latter earn yield by deploying the stablecoins they own in optimized spots to maximize routing revenue. As of today, it remains unsure which stablecoins will be available, but a requirement is that they are deployed on LND's Taproot Assets (TapAss) protocol[6].
The "consumer" use cases of RailsX are twofold:
- they enable stablecoin payments (e.g. a customer could send sats and the merchant receive their favorite stablecoin, by going through one the RailsX nodes) ;
- they enable a form of self-custodial decentralized trading, which is basically an extension of the above payment use case where the customer and the merchant are the same person: a trader can select an available order published by a RailsX (e.g. 100 USDT in exchange for 100,000 sats), and compute a route that goes through this node and back to themselves, enabling P2P, atomic and self-custodial trading by leveraging TapAss and HTLCs.
Trader --- 101,100 sats --> Alice --- 101,090 sats --> Counterparty --- 100.09 USDT ---> Bob --- 100.00 USDT ---> Trader
Crucially, routing nodes on one side of the route (using the counterparty as the pivot) need to be TapAss aware in order to be able to route tokens. It's hence very likely that trading will mostly take place inside the RailsX cluster, at least in the beginning.
Lightning Sandbox && Agent WalletLightning Sandbox && Agent Wallet
The Alby team blessed us with a new fantastic Lightning playground last week! The Alby Sandbox lets you easily play with different scenarios, ranging from a simple invoice payment to subscriptions, payments prisms or wrapped invoices. Everything happens in the browser, and leverages Nostr Wallet Connect to interact with the different Lightning wallets that are part of a given scenario.
using Alby's faucet means that you're given a sub-wallet (ie, an account) on one Alby Hub instance dedicated to serving the sandbox. There are no channels between these sub-wallets. Rather, they leverage Alby Hub's self-payment capabilities to "emulate" actual payments going through channels, meaning things like HODL invoices still work the same as in an actual channel (modulo the fact that the funds are, at all time, cryptographically controlled by the operator of the underlying Lightning node). You can also connect a real Lightning wallet through NWC, for example if you're running your own Alby Hub. But you can't of, course, send payments between a real wallet and a "virtual" one, since the sandbox's Alby Hub doesn't have any channel.
The Alby Sandbox also comes with an AI dimension, enabling users to create scenarios via plain-text prompts. As a matter of fact, the Sandbox itself was built using Claude Code leveraging the Alby Agent Skill, which tells the agent everything its need to know about NWC, LNURL or WebLN.
Speaking of Agents, MoneyDevKit also joined the party with the Agent Wallet, an AI agent skill that lets agents run their own self-custodial Lightning wallet - in similar way that MoneyDevKit lets you run a Lightning node inside your NextJS or Replit web app.
ClamsClams
Clams V1 beta is live, with a full Rust rewrite of the core logic, and a huge focus on accounting. Clams (cloud or self-hosted) lets you bring your own node (Electrum, Esplora or Bitcoin RPC) and connect multiple wallets (incl. Lightning wallets, notably through NWC) to generate capital gains records, balance sheets, portfolio summarizes and full audit records.
Nested MuSig2Nested MuSig2
Nadav Kohen from Chaincode Labs published a paper on Nested MuSig2. The goal of this paper is to establish that the security and efficiency benefits of Musig2 can be conserved by using aggregate Schnorr signatures obtained with Musig2 as inputs of another Musig2 aggregation. The security of such an operation was always assumed, but so far no paper had formalized an actual signature scheme for Nested Musig2.
For more context on Musig and Musig2, see this Optech Summary.
Nested Musig2 could play an important role in multi-party contracts protocols (such as Lightning, Ark, etc.). A very direct and pragmatic outcome for Lightning is that it would enable a simple mechanism for signing and verifying simple taproot channels announcements.
When verifying the announcement of a channel between Alice and Bob, a Lightning node wants to check that:
- Alice's node owns a Bitcoin key
alice_bitcoin_key - Bob's node owns a Bitcoin key
bob_bitcoin_key - the channel funding transaction pays to
alice_bitcoin_keyandbob_bitcoin_key
The latter is verified by finding the on-chain transaction thanks to the short channel id (which indicates block height, transaction index and output index) and verifying that the script hash matches an OP_CHECKMULTISIG with those keys.
Verifying the ownership of the keys is done by having the channel announcement message[7] be signed by 4 keys:
alice_bitcoin_keybob_bitcoin_keyalice_node_key, which corresponds to the public key identity of Alice's nodebob_node_key, which is the same for Bob
This ties the node identities to the on-chain funds underlying the channel, which allows other nodes to verify that:
- the announced capacity matches the amount committed to the channel
- both peers agreed on opening the channel and routing through it
With Taproot channels, things get a little bit trickier because the funding transaction pays to a P2TR output like OP_1 <taproot_output_key>. The taproot_output_key will most likely be a Musig2 aggregate of multiple keys belonging to the parties, with a least 1 key from each party, but it can be more subtle than a 2-of-2, paving the way for threshold-based channels. The channel announcement verification hence becomes verifying the Musig2 signature of a key resulting from the Musig2 aggregation of alice_node_key, bob_node_key and taproot_output_key. Since taproot_output_key is a Musig2 aggregate itself, Taproot channels announcement would require a Nested Musig2 scheme, such as the one this paper provides.
Of course, Lightning developers have not waited on Nested Musig2 to start working on Taproot channels announcements. The (still draft) specification explores the Nested Musig2 path for when schemes such as Kohen's will be widely available, but also devises a practical solution in the meantime that all implementations can work on, which aggregates (with Musig2) the four keys used in P2SWH channels, and specifies how the ``taproot_output_keyshould be derived from thealice_bitcoin_keyandbob_bitcoin_key` keys.
Connector SwapsConnector Swaps
Supertestnet made an interesting proposal earlier last January that I had missed. Luckily, Scoresby resurfaced this gem on StackerNews, so I figured I'd cover it in this issue. Connector Swaps are a new kind of Lightning-to-bitcoin protocol (sending funds from a Lightning channel to a Bitcoin address, without closing the channel), bridging the benefits of swaps and splices while removing some of their disadvantages.
- Swaps: don't change the channel capacity, but they require two on-chain transactions per submarine swap ;
- Splicing: requires only one transaction, but changes the channel capacity (note that sometimes this is the result sought).
We can also mention PeerSwap here, which is basically a swap (as you'd do on Boltz), but with your channel partner directly. This makes it easier to reliably perform the swap (no routing), and theoretically decentralizes swaps away from central coordinators. Since they're regular submarine swaps, PeerSwaps require two on-chain transactions per swap, with one transaction "opening" the "smart contract", and a second claiming the funds. This has two drawbacks:
- increased on-chain cost
- if the swap is interrupted between the two transactions, the counterparty that created the on-chain smart contract loses funds to on-chain fees without gaining anything in return.
Connector Swaps addresses both limitations, while still adhering to this idea of performing swaps with your direct peers.
As the name implies, Connector Swaps leverage connector outputs (which were popularized by the Ark protocol) to achieve capacity-preserving Lightning-to-bitcoin swaps in only one transaction. Before we go deeper, SuperTestnet also gives a clear and concise reminder on what a connector output is:
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
Now, let's consider a scenario where Alice wants to send 20,000 sats from her channel with Bob, to the Bitcoin address of her friend Carol. What Alice wants to achieve is:
- push 20k sats (plus fees) to Bob's side of the channel ; and at the same time
- use one of Bob's UTXOs to send 20k sats on-chain to Carol ;
- if Bob stops responding mid-swap, be able to recover her 20k sats sent in the channel.
Bob wants to:
- help Alice perform the swap in exchange for a small fee ;
- if Alice stops responding mid-swap, not lose his 20k sats.
Let's say Bob charges 1,000 sats for the swap. To achieve their stated goals, Alice and Bob co-sign an off-chain transaction (inside their channel) that creates a new output of 21k sats, that is still a 2-of-2 multisig (we'll call it the "shared output"). They then co-sign 2 competing off-chain transactions that both spend this output: one to allow Alice to recover her funds, and the other to enable Bob to do the same.
- Alice's recovery transactions spends the shared output and a dust output that she controls (the connector output) to create a 21k sats output that she controls.
- Bob's recovery transaction spends only the shared output, creating an output that Bob can spend alone but after a timelock (e.g. 10 blocks) expires.
Once this 3 off-chain (still unpublished) transactions are signed by both parties, they collaborate to create a fourth transaction, called the "payment transaction", which will effectively send funds to Carol. This transaction consumes one or many of Bob's UTXO(s), as well as Alice's connector output. It sends 20k sats to Carol's address, and creates a new connector output for Alice, which can be used later for a future swap. Once the payment transaction is confirmed, the initial connector output ceases to exist, rendering Alice's recovery transaction invalid, and hence the only available path is Bob's recovery path. This means that if the channel was to close at this point, Bob's would be able to recover his 21k sats that Alice still owed him inside the channel. Of course, if both parties behave honestly, the 21k sats off-chain UTXO is resolved inside the channel, moving the funds to Bob's side.
On the other hand, if for any reason Bob doesn't publish the payment transaction and stops responding, then Alice can close the channel and claim her 21k sats back using her recovery transaction.
┌──────────────┐
│ 79k │
├──────────────┤
│ Channel │
┌─────▶│ 2-of-2 │
┌──────────────┐ │ └──────────────┘
│ 100k │ │
├──────────────┤ │
│ Channel │ │
│ 2-of-2 │──────┤
└──────────────┘ │ ┌──────────────┐
│ │ 21k │
│ ├──────────────┤
│ │ Swap Output │
└─────▶│ 2-of-2 │
└──────────────┘
┌────────────────────────────────────────────────┐
│ 1. Creation of the swap output in the channel │
└────────────────────────────────────────────────┘ ┌──────────────┐
│ 21k │
├──────────────┤
│ Swap Output │
│ 2-of-2 │───────┐ ┌──────────────┐
└──────────────┘ │ │ 21k │
│ ├──────────────┤
│ │ Recover │
├──────▶│ Alice │
┌──────────────┐ │ └──────────────┘
│ Connector │ │
│ Output Alice │───────┘
└──────────────┘
┌──────────────┐ ┌──────────────┐
│ 21k │ │ 21k │
├──────────────┤ ├──────────────┤
│ Swap Output │ │ Recover │
│ 2-of-2 │───10 blocks────▶│ Bob │
└──────────────┘ timelock └──────────────┘
┌──────────────────────────────────────────────────┐
│ 2. Creation of the recovery transactions │
└──────────────────────────────────────────────────┘ ┌──────────────┐ ┌──────────────┐
│ 20k │ │ 20k │
├──────────────┤ ├──────────────┤
│ Bob │ │ Carol │
│ │─┐ ┌──▶│ │
└──────────────┘ │ │ └──────────────┘
│ │
├────┤
┌──────────────┐ │ │ ┌──────────────┐
│ Connector │ │ │ │New Connector │
│ Output Alice │─┘ └──▶│ Output Alice │
└──────────────┘ └──────────────┘
┌──────────────────────────────────────────────────┐
│ 3. Creation of the payment transaction │
└──────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ │
│ ┌──────────────┐ │
│ │ 79k │ │
│ ├──────────────┤ │
│ │ Channel │ │
│ ┌─────▶│ 2-of-2 │ │
│ ┌──────────────┐ │ └──────────────┘ │
│ │ 100k │ │ │
│ ├──────────────┤ │ │
│ │ Channel │ │ │
│ │ 2-of-2 │──────┤ │
│ └──────────────┘ │ ┌──────────────┐ ┌──────────────┐ │
│ │ │ 21k │ │ 21k │ │
│ │ ├──────────────┤ ├──────────────┤ │
│ │ │ Swap Output │ 10 blocks │ Recover │ │
│ └─────▶│ 2-of-2 ├────timelock───▶│ Bob │ │
│ └──────────────┘ └──────────────┘ │
│ │ │
│ │
│ │ │
│ │
│ └ ─ ─ ─ ─ ─ ─ ─ │
│ │ ┌──────────────┐ │
│ ┌──────────────┐ │ 21k │ │
│ │ Connector │ │ ├──────────────┤ │
│ │ Output Alice │─ ─ ─ ─ ─ ─ ─ ─▶│ Recover │ │
│ └──────────────┘ │ Alice │ │
│ │ └──────────────┘ │
│ │ │
│ │ │
│ │ ┌──────────────┐ │
│ │ │ 20k │ │
│ └────────────────┐ ├──────────────┤ │
│ ┌──────────────┐ │ │ Carol │ │
│ │ 20k │ │ ┌──▶│ │ │
│ ├──────────────┤ │ │ └──────────────┘ │
│ │ Bob │ │ │ │
│ │ │─────────┴──┤ │
│ └──────────────┘ │ ┌──────────────┐ │
│ │ │New Connector │ │
│ └──▶│ Output Alice │ │
│ └──────────────┘ │
│ │
│ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Example: payment confirms and Bob claims the funds on-chain. │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────────┘That's it for today's issue. Once again, thank you so much for reading this far, and feel free to drop any feedback or questions in the comments. See you next week!
Whereas, interestingly, a lot of micro-transactions (e.g. below ~300 sats) cannot. ↩
This comes very handy, for example, in derivatives or lending markets, to quickly send funds to a position when a liquidation is near. ↩
Phoenix relies on FCM notifications to wake the user's device when someone tries to send to the user's Bolt12 Offer. This works okay for most devices with good connection, but starts falling apart in poor network conditions, or when FCM isn't available (for example on devices running GrapheneOS). ↩
My understanding is that only LND is supported as of today. ↩
This requirement can be more easily worked with by using TapAss tokens that are a representation of tokens on different chains, a process known as wrapping. ↩
More precisely, the hash of the message excluding signatures. See Bolt7 for more details. ↩
https://twiiit.com/voltage_cloud/status/2019402303032209818
gud bot