A Rust library for establishing connections to Lightning Network nodes. This library provides low-level primitives for establishing encrypted communication channels with Lightning Network nodes using the Noise_XK protocol as specified in BOLT #8.
lnsocket also comes batteries included with Commando support, allowing you to call RPCs on core-lightning nodes remotely!
- Establish encrypted connections to Lightning Network nodes with Noise_XK handshake protocol
- Send and receive Lightning Network messages
- Support for Commando CLN RPC messages
- TOR connections for .onion addresses with automatic detection
Add to your Cargo.toml:
[dependencies]
lnsocket = "0.1.0"lnsocket-rs automatically detects and connects to .onion addresses via TOR, providing support for hidden services.
- Default SOCKS proxy:
127.0.0.1:9050(standard TOR proxy address) - The library automatically detects
.onionaddresses and routes through TOR
use bitcoin::secp256k1::{SecretKey, PublicKey, rand};
use lnsocket::LNSocket;
async fn connect_onion() -> Result<(), lnsocket::Error> {
let key = SecretKey::new(&mut rand::thread_rng());
let pk = PublicKey::from_str("03...")?.unwrap();
// Onion addresses automatically use TOR (127.0.0.1:9050)
let mut sock = LNSocket::connect_and_init(key, pk, "node.onion:9735").await?;
// Use the socket normally - TOR is handled transparently
Ok(())
}use lnsocket::{LNSocket, TorConfig};
async fn connect_custom_proxy() -> Result<(), lnsocket::Error> {
let key = SecretKey::new(&mut rand::thread_rng());
let pk = PublicKey::from_str("03...")?.unwrap();
// Custom TOR proxy (e.g., different port or remote proxy)
let tor_config = TorConfig::new("127.0.0.1".to_string(), 9150);
let mut sock = LNSocket::connect_and_init_with_tor_config(
key, pk, "node.onion:9735", Some(tor_config)
).await?;
Ok(())
}This crate includes a small Commando client that runs over the same encrypted Lightning transport.
use bitcoin::secp256k1::{SecretKey, PublicKey, rand};
use lnsocket::{LNSocket, CommandoClient};
use serde_json::json;
use lnsocket::commando::CallOpts;
async fn commando_rpc_demo(pk: PublicKey, rune: &str) -> Result<(), lnsocket::Error> {
let key = SecretKey::new(&mut rand::thread_rng());
let sock = LNSocket::connect_and_init(key, pk, "ln.example.com:9735").await?;
let client = CommandoClient::spawn(sock, rune);
// Inherit client defaults (30s timeout, auto-reconnect with backoff,
// and retry up to 3 times). Override per call if needed:
let res = client.call("getinfo", json!({})).await?;
println!("{}", res);
let opts = CallOpts::new().timeout(std::time::Duration::from_secs(5)).retry(5);
let channels = client.call_with_opts("listchannels", json!({}), &opts).await?;
Ok(())
}This library is experimental and under active development. APIs may change significantly between versions.
This library contains code derived from LDK, which is licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.
Contributions are welcome! Please feel free to submit a Pull Request.