A ready-to-go Lightning node library built using LDK and BDK.
LDK Node is a self-custodial Lightning node in library form. Its central goal is to provide a small, simple, and straightforward interface that enables users to easily set up and run a Lightning node with an integrated on-chain wallet. While minimalism is at its core, LDK Node aims to be sufficiently modular and configurable to be useful for a variety of use cases.
The primary abstraction of the library is the Node, which can be retrieved by setting up and configuring a Builder to your liking and calling one of the build methods. Node can then be controlled via commands such as start, stop, open_channel, send, etc.
use ldk_node::bitcoin::secp256k1::PublicKey;
use ldk_node::bitcoin::Network;
use ldk_node::bip39::Mnemonic;
use ldk_node::entropy::NodeEntropy;
use ldk_node::lightning::ln::msgs::SocketAddress;
use ldk_node::lightning_invoice::Bolt11Invoice;
use ldk_node::Builder;
use std::str::FromStr;
fn main() {
let mut builder = Builder::new();
builder.set_network(Network::Testnet);
builder.set_chain_source_esplora("https://blockstream.info/testnet/api".to_string(), None);
builder.set_gossip_source_rgs(
"https://rapidsync.lightningdevkit.org/testnet/v2/snapshot".to_string(),
);
let mnemonic = Mnemonic::generate(24).unwrap();
let node_entropy = NodeEntropy::from_bip39_mnemonic(mnemonic, None);
let node = builder.build(node_entropy).unwrap();
node.start().unwrap();
let funding_address = node.onchain_payment().new_address();
// .. fund address ..
let node_id = PublicKey::from_str("NODE_ID").unwrap();
let node_addr = SocketAddress::from_str("IP_ADDR:PORT").unwrap();
node.open_channel(node_id, node_addr, 10000, None, None).unwrap();
let event = node.wait_next_event();
println!("EVENT: {:?}", event);
node.event_handled();
let invoice = Bolt11Invoice::from_str("INVOICE_STR").unwrap();
node.bolt11_payment().send(&invoice, None).unwrap();
node.stop().unwrap();
}LDK Node currently comes with a decidedly opinionated set of design choices:
- On-chain data is handled by the integrated BDK wallet.
- Chain data may currently be sourced from the Bitcoin Core RPC interface, or from an Electrum or Esplora server.
- Wallet and channel state may be persisted to an SQLite or PostgreSQL database, to the filesystem, to a VSS server, or to a custom back-end to be implemented by the user.
- Gossip data may be sourced via Lightning's peer-to-peer network or the Rapid Gossip Sync protocol.
- Entropy for the Lightning and on-chain wallets may be sourced from raw bytes or a BIP39 mnemonic. In addition, LDK Node offers the means to generate and persist the entropy bytes to disk.
LDK Node's optional dependencies are grouped by the functionality they provide:
| Feature | Functionality |
|---|---|
chain-esplora |
Esplora chain source |
chain-electrum |
Electrum chain source |
chain-bitcoind |
Bitcoin Core RPC and REST chain source |
storage-sqlite |
SQLite storage |
storage-filesystem |
Filesystem storage |
storage-vss |
Versioned Storage Service storage |
storage-postgres |
PostgreSQL storage |
storage-postgres-vendored-tls |
PostgreSQL storage with vendored OpenSSL |
unified-payments |
BIP 21 and human-readable-name payment support |
uniffi |
UniFFI language bindings |
uniffi-default |
The standard language-binding feature set |
The default feature set preserves the native Rust API's previous behavior. It enables all three
chain sources, SQLite, filesystem and VSS storage, and unified payments. PostgreSQL and UniFFI
remain opt-in. Every build must enable at least one chain source feature.
On Linux, storage-postgres uses the system OpenSSL installation and requires the OpenSSL
development headers and pkg-config. Enable storage-postgres-vendored-tls instead to build
OpenSSL from source. Vendored builds require a C compiler, make, and Perl.
Disable the default features to select only the functionality and dependencies an application needs. For example:
cargo build --no-default-features --features chain-esplora,storage-sqliteuniffi-default enables UniFFI, Esplora, Electrum, SQLite, VSS, and unified payments. It excludes
Bitcoin Core, filesystem storage, and PostgreSQL. Binding users can add any of those features:
cargo build --no-default-features --features uniffi-default,chain-bitcoindUse uniffi directly instead of uniffi-default to assemble a fully custom binding build. For
example, a Bitcoin Core and PostgreSQL-only binding build uses:
cargo build --no-default-features --features uniffi,chain-bitcoind,storage-postgresThe binding generation scripts use uniffi-default. Set LDK_NODE_EXTRA_FEATURES to add features
to their builds:
LDK_NODE_EXTRA_FEATURES=chain-bitcoind,storage-postgres \
./scripts/uniffi_bindgen_generate_python.shLDK Node does not provide a stable public API until v1.0. Persisted node state is backwards compatible: newer releases are guaranteed to load state written by older releases. Downgrades are not supported, so state written by a newer release may not load with an older release.
LDK Node itself is written in Rust and may therefore be natively added as a library dependency to any std Rust program. However, beyond its Rust API it also offers language bindings for Swift, Kotlin, and Python based on the UniFFI.
The Minimum Supported Rust Version (MSRV) is currently 1.85.0.