Skip to content

Commit

Permalink
Merge branch 'main' into building-a-node-with-ldk-intro
Browse files Browse the repository at this point in the history
  • Loading branch information
ConorOkus authored Jan 3, 2024
2 parents b87f182 + a49b9c0 commit a7fa74b
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 30 deletions.
8 changes: 8 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ const docsSidebar = [
"https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/",
"lightning-rapid-gossip-sync",
],
[
"https://docs.rs/lightning-transaction-sync/*/lightning_transaction_sync/",
"lightning-transaction-sync",
],
[
"https://docs.rs/lightning-custom-message/*/lightning_custom_message/",
"lightning-custom-message",
],
],
},
[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: "The Challenges of Developing Non-Custodial Lightning on Mobile"
description: "Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos."
date: "2023-12-14"
authors:
- Matt Corallo
tags:
- Mobile
- Non-Custodial
---

Lightning development is tough. While going custodial simplifies the process, it means sacrificing user privacy, censorship resistance, and self-sovereignty, all of which contradict bitcoin’s ethos. Therefore, many companies and projects have started with or redirected their focus from building custodial to non-custodial Lightning applications.

## Obstacles

There are several basic requirements for wallets wanting to add Lightning capabilities, such as connecting to the Lightning Network via a Lightning Implementation, syncing with on-chain transactions, and opening and closing channels. When building a mobile application, developers face additional technical challenges:

## Liquidity

To receive funds via Lightning, someone must have on-chain bitcoin locked up in a channel. Transaction completion is delayed if the receiver has an empty or insufficient channel balance. For example, let’s say that someone has 50,000 sats of inbound liquidity and is trying to receive 100,000 sats. Before the Lightning transaction can be initiated, additional liquidity is required to cover the 100,000 sats total plus fees from channel reserves and anchor outputs, which are mechanisms to improve security. This is done via on-chain transactions, which come with fees.

Additionally, on-chain transactions must be mined into multiple blocks before being confirmed. It’s not a great user experience if someone has to do work upfront and wait roughly 30–60 minutes before they can send or receive money.

[0-conf](https://lightningdevkit.org/blog/zero-confirmation-channels/) channels offer a partial solution, allowing users to receive Lightning instantly. 0-conf enables the client to trust their channel counterparty (usually an application vendor or partner) for a limited time until an on-chain transaction is confirmed. While this helps with speed, the fact that 0conf channels require some level of trust is a trade-off.

Liquidity Service Providers (LSPs) provide liquidity upfront through automated channel and liquidity management. LSPs supply more liquidity than required for immediate payments rather than the exact amount to ensure that remaining funds are in the channel for future transactions. If a user conducts multiple payments, it’s best to avoid doing on-chain transactions for every Lightning transaction.

LSPs do not want to pay excessive on-chain fees, but it’s hard to predict how often people will send and receive transactions and for how much. Therefore, there’s no straightforward way to know how much liquidity should be locked into a given channel. LSPs have to determine how much money they can contribute and how much it'll cost. This can be anywhere from aggressive (locking up a generous amount) to conservative (locking up a small amount). Ultimately, this decision results in a “compression ratio," i.e., the number of on-chain transactions required per Lightning transaction. Some very conservative LSPs may get a compression ratio close to one, saving their users relatively little on fees, but there is nearly always some gain to be had in using Lightning over on-chain.

While predicting what the compression ratio should be remains a major challenge, most solutions today offer some compression information, allowing us to learn and improve. For this reason, it’s worth deploying Lightning for instant transactions at lower costs compared to on-chain, even if it's not as common as it could be. We expect this to get better over time.

# Receive Wakeup

Lightning requires nodes (or, specifically, their cryptographic keys) to be online to exchange signatures and complete payments, meaning the user must be on their phone and with service. Receiving wakeups is problematic because incomplete payments are not great for the Lightning Network—it’s detrimental to keep the money for a payment locked up until someone comes back online.

iOS and Android operating systems help address this problem by allowing a small amount of code to run when notifications are received, even if the relevant application isn’t open. However, suppose an application is infrequently used or the device has a low battery. In that case, the application will often not get any CPU time, resulting in the payment being stuck until the user opens the app.

A lot of work must be done to make it possible for senders and recipients to exchange payments asynchronously, [but a protocol sketch is in the works](https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003307). You can find a more detailed explainer [here](https://gist.github.com/remyers/e0d2bedb7bc87371d1bdbbb6fff2edd1).

# Live Backups

These are especially problematic when a user has to reinstall an application or loses their phone. In addition to needing their seed phrase, they’ll need the latest Lightning state data stored on their device to get their money back reliably.

The Lightning state changes every time a user sends or receives money, so backups must be frequently updated on a server. While some devices use Google Drive or iCloud, those protocols sync asynchronously, often leading to data being out of sync. Cloud methods sanitize data stored on the client well, but they may not ensure reliable full funds recovery if a device is lost.

Advanced versions of live online sync allow users to open the same wallet on multiple devices. Users often do this despite it being challenging to do with Lightning applications since two devices running simultaneously can result in losing funds.

# Privacy-preserving Payment Routing

Another commonly discussed issue is payment routing through the Lightning Network. This isn't easy because the route finder has to have some history of liquidity on the Lightning Network.

The most common method is to rely on a server for route-finding, which sees users' payment history and therefore compromises privacy. This may also pose long-term regulatory concerns for apps relying on such servers.

Without a server, the client needs to download the full Lightning graph. This can be slow and performance-compromising. Worse, the Lightning graph alone doesn’t provide enough information to achieve reliable payment success, leading to the possibility that transactions may take a long time to complete, or not go through at all.

To achieve better payment success, the client must send lots of payments, which can be done via probing (fake payments). Probing trains data on the network graph from a client's perspective and builds up a history of liquidity on the network. While this offers a solution, probing must be done consistently, requiring the client to be online 24/7. This could instead be done by an LSP, which can offer the resulting data to clients. Additionally, information is not super portable across LSPs, so each LSP needs to do its own probing.

# Privacy-preserving Block Fetching

For users to see their transaction history and balance, bitcoin and Lightning wallets need to connect to and download the blockchain. Each block contains a lot of data, making downloading the full blockchain on mobile devices impractical due to bandwidth constraints.

The most common way to obtain blockchain data is to connect to a server using Electrum or Esplora. To do this and get the relevant information, the client has to provide their user’s list of addresses, exposing transaction histories and balances.

It’s difficult to fetch blockchain data without giving up privacy. One way around this is to use compact block filters, which download data from a full node and only download a select amount of blocks. While compact block filters offer better privacy than a server and are more efficient than downloading the entire blockchain, the method isn’t perfect. Compact block filters are slow to sync and still require substantial bandwidth on the user’s device, making it a less enticing tradeoff for many wallets.

A third option, called private information retrieval, is more future-looking. This method is efficient for clients but expensive on the server side.

# Conclusion

There are many obstacles to making non-custodial Lightning work privately on mobile devices, but it is doable. It requires a mobile-focused LN implementation, SDK, and infrastructure operated by an LSP or the application vendor. None of that needs to compromise user privacy or self-sovereignty, even though, in many designs, it does.
Binary file added docs/assets/etta.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/assets/portico.png
Binary file not shown.
41 changes: 20 additions & 21 deletions docs/case-studies.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,20 @@ lastUpdated: false
<h3><a href="https://bluewallet.io/" target="_blank">Blue Wallet</a></h3>
<p>A radically simple and powerful bitcoin and Lightning wallet</p>
</div>
<div class="case-study-item">
<a href="https://github.com/EttaWallet/EttaWallet" target="_blank"><img src="./assets/etta.png" /></a>
<h3><a href="https://github.com/EttaWallet/EttaWallet" target="_blank">EttaWallet</a></h3>
<p>A simple open-source wallet with a strong bias toward usability, accessibility, and UX</p>
</div>
<div class="case-study-item">
<a href="https://twitter.com/kumulydev" target="_blank"><img src="./assets/kumuly.png" /></a>
<h3><a href="https://twitter.com/kumulydev" target="_blank">Kumuly</a></h3>
<p>Colombian-based mobile bitcoin and Lightning wallet</p>
</div>
<div class="case-study-item">
<a href="https://lipa.swiss/" target="_blank"><img src="./assets/lipa.png" /></a>
<h3><a href="https://lipa.swiss/" target="_blank">Lipa</a></h3>
<p>Swiss-based app that offers a bitcoin wallet for individuals and businesses</p>
</div>
<div class="case-study-item">
<a href="https://mercurywallet.com/" target="_blank"><img src="./assets/mercury.png" /></a>
<h3><a href="https://mercurywallet.com/" target="_blank">Mercury</a></h3>
<p>A layer 2 bitcoin wallet that enables users to send and swap bitcoin privately</p>
</div>
<div class="case-study-item">
<a href="https://porticoexchange.github.io/porticoexchangev2.github.io/" target="_blank"><img src="./assets/portico.png" /></a>
<h3><a href="https://porticoexchange.github.io/porticoexchangev2.github.io/" target="_blank">Portico</a></h3>
<p>A DEX that enables people to swap between bitcoin layers and sidechains</p>
</div>
<div class="case-study-item">
<a href="https://www.velascommerce.com/" target="_blank"><img src="./assets/velas.png" /></a>
Expand Down Expand Up @@ -107,7 +102,6 @@ lastUpdated: false
</div>
</template>


<template v-slot:custodial>

<div class="case-studies">
Expand Down Expand Up @@ -174,6 +168,11 @@ lastUpdated: false

<template v-slot:misc>
<div class="case-studies">
<div class="case-study-item">
<a href="https://github.com/fiksn/gossiper" target="_blank"><img src="./assets/github.png" /></a>
<h3><a href="https://github.com/fiksn/gossiper" target="_blank">Gossiper</a></h3>
<p>Lightning Gossip Ingestion</p>
</div>
<div class="case-study-item">
<a href="https://github.com/BitcoinDevShop/hidden-lightning-network" target="_blank"><img src="./assets/github.png" /></a>
<h3><a href="https://github.com/BitcoinDevShop/hidden-lightning-network" target="_blank">The Hidden LN</a></h3>
Expand Down Expand Up @@ -240,6 +239,16 @@ lastUpdated: false
<h3><a href="https://cash.app/" target="_blank">Cash App</a></h3>
<p>Send and spend, bank, and buy stocks or bitcoin</p>
</div>
<div class="case-study-item">
<a href="https://github.com/EttaWallet/EttaWallet" target="_blank"><img src="./assets/etta.png" /></a>
<h3><a href="https://github.com/EttaWallet/EttaWallet" target="_blank">EttaWallet</a></h3>
<p>A simple open-source wallet with a strong bias toward usability, accessibility, and UX</p>
</div>
<div class="case-study-item">
<a href="https://github.com/fiksn/gossiper" target="_blank"><img src="./assets/github.png" /></a>
<h3><a href="https://github.com/fiksn/gossiper" target="_blank">Gossiper</a></h3>
<p>Lightning Gossip Ingestion</p>
</div>
<div class="case-study-item">
<a href="https://hydranet.ai/" target="_blank"><img src="./assets/hydranet.png" /></a>
<h3><a href="https://hydranet.ai/" target="_blank">Hydranet</a></h3>
Expand All @@ -265,11 +274,6 @@ lastUpdated: false
<h3><a href="https://github.com/lexe-tech" target="_blank">Lexe</a></h3>
<p>Managed non-custodial Lightning nodes inside secure hardware</p>
</div>
<div class="case-study-item">
<a href="https://lipa.swiss/" target="_blank"><img src="./assets/lipa.png" /></a>
<h3><a href="https://lipa.swiss/" target="_blank">Lipa</a></h3>
<p>Swiss-based mobile app that offers a bitcoin wallet for individuals and businesses</p>
</div>
<div class="case-study-item">
<a href="https://github.com/lndk-org/lndk" target="_blank"><img src="./assets/lndk.png" /></a>
<h3><a href="https://github.com/lndk-org/lndk" target="_blank">LNDK</a></h3>
Expand All @@ -285,11 +289,6 @@ lastUpdated: false
<h3><a href="https://mutinywallet.com/" target="_blank">Mutiny</a></h3>
<p>A web-first unstoppable bitcoin wallet for everyone</p>
</div>
<div class="case-study-item">
<a href="https://porticoexchange.github.io/porticoexchangev2.github.io/" target="_blank"><img src="./assets/portico.png" /></a>
<h3><a href="https://porticoexchange.github.io/porticoexchangev2.github.io/" target="_blank">Portico</a></h3>
<p>A DEX that enables people to swap between bitcoin layers and sidechains</p>
</div>
<div class="case-study-item">
<a href="https://github.com/RGB-Tools/rgb-lightning-sample" target="_blank"><img src="./assets/github.png" /></a>
<h3><a href="https://github.com/RGB-Tools/rgb-lightning-sample" target="_blank">rgb-lightning-sample</a></h3>
Expand Down
44 changes: 36 additions & 8 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,49 @@ Click the links below and learn from community-built example projects

### [Rust Sample Node](https://github.com/lightningdevkit/ldk-sample)

The sample serves as a complete reference for constructing a Lightning node with
the LDK. This is a good starting point if you want a self-guided tour!
This sample serves as a complete reference for constructing a lightning node with
LDK. This is a good starting point if you want a self-guided tour.

### [Java Sample Node](https://github.com/getlipa/ldk-sample-java)
### [Kotlin/Android Sample App](https://github.com/conorokus/umlando-wallet)

This repository contains a sample implementation of LDK as the result of following the steps described in [Building a Node with LDK in Java](/tutorials/build_a_node_in_java/).
This sample uses the Kotlin bindings provided by [ldk-garbagecollected](https://github.com/lightningdevkit/ldk-garbagecollected) to create a self-custodial mobile lightning wallet on Android.

### [Kotlin Sample Node](https://github.com/BlueWallet/HelloLightning)
### [Swift/iOS Sample App](https://github.com/Roy0Anonymous/Vajra-Wallet)

Kotlin based CLI lightning network server based on LDK. Provides HTTP-RPC interface.
This sample uses the Swift bindings provided by [ldk-swift](https://github.com/lightningdevkit/ldk-swift) to create a self-custodial mobile lightning wallet on iOS.

### [Rust node with sample Lightning Signer integration](https://gitlab.com/lightning-signer/lnrod/)

A Rust Lightning node implementation based on the LDK and the Lightning Signer projects. Aims to be production ready at some point.
A Rust lightning node implementation based on LDK and the Lightning Signer projects. Aims to be production ready at some point.

### [Rust node with sample Tor integration](https://github.com/TonyGiorgio/ldk-sample-tor)

A Rust Lightning node sample implementation based on LDK with an embedded Tor daemon.
A Rust lightning node sample implementation based on LDK with an embedded Tor daemon.

### [LDK Node](https://github.com/lightningdevkit/ldk-node)

A ready-to-go Lightning node library built using LDK and [BDK](https://bitcoindevkit.org/).

### [LDK Node Rust Sample](https://github.com/optout21/ldk-node-sample)

A sample lightning node command-line app built on top of LDK Node (similar to ldk-sample).

### [LDK Node Swift Sample App](https://github.com/reez/Monday/tree/main/LDKNodeMonday)

This sample uses [ldk-node-swift](https://github.com/lightningdevkit/ldk-node/blob/main/Package.swift) bindings to quickly build a self custodial lightning mobile wallet on iOS. Watch the video tutorial [here](https://www.youtube.com/watch?v=rcU3LU6iZCs).

### [LDK Node Swift Sample app using Bitcoin Design Guide](https://github.com/bdgwallet/dailywallet)

This sample is a good starting point for building a sample iOS wallet with a strong focus on user experience.

### [LDK Node Flutter Sample App](https://github.com/LtbLightning/ldk-node-flutter-demo)

This sample is a starting point for an LDK Node Flutter app.

### [LDK Node React Native Sample App](https://github.com/LtbLightning/ldk-node-rn-demo)

This sample is a starting point for an LDK Node React Native app.

### [LDK Node Sample Desktop App](https://github.com/jbesraa/ldk-node-desktop)

This sample is a desktop node manager for LDK Node.
2 changes: 1 addition & 1 deletion docs/running-a-sample-ldk-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ cd ldk-sample
```
Now, run the following command:
```
cargo run polaruser:[email protected]:18443 ./ 9732 regtest hellolightning 0.0.0.0
cargo run polaruser:[email protected]:18443 ./ 9732 regtest hellolightning 0.0.0.0:9732
```

If you have a different setup that doesn't involve Polar you can modify this command so that it contains different credentials.
Expand Down

0 comments on commit a7fa74b

Please sign in to comment.