Skip to content

Commit 9dcc7b4

Browse files
authored
Merge pull request #716 from tnull/2025-11-introduce-mandatory-node-entropy
Introduce new mandatory `NodeEntropy` object
2 parents d0b8541 + 2fb1df5 commit 9dcc7b4

File tree

17 files changed

+405
-364
lines changed

17 files changed

+405
-364
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,26 @@ LDK Node is a self-custodial Lightning node in library form. Its central goal is
1414
The primary abstraction of the library is the [`Node`][api_docs_node], which can be retrieved by setting up and configuring a [`Builder`][api_docs_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.
1515

1616
```rust
17-
use ldk_node::Builder;
18-
use ldk_node::lightning_invoice::Bolt11Invoice;
19-
use ldk_node::lightning::ln::msgs::SocketAddress;
2017
use ldk_node::bitcoin::secp256k1::PublicKey;
2118
use ldk_node::bitcoin::Network;
19+
use ldk_node::entropy::{generate_entropy_mnemonic, NodeEntropy};
20+
use ldk_node::lightning::ln::msgs::SocketAddress;
21+
use ldk_node::lightning_invoice::Bolt11Invoice;
22+
use ldk_node::Builder;
2223
use std::str::FromStr;
2324

2425
fn main() {
2526
let mut builder = Builder::new();
2627
builder.set_network(Network::Testnet);
2728
builder.set_chain_source_esplora("https://blockstream.info/testnet/api".to_string(), None);
28-
builder.set_gossip_source_rgs("https://rapidsync.lightningdevkit.org/testnet/snapshot".to_string());
29+
builder.set_gossip_source_rgs(
30+
"https://rapidsync.lightningdevkit.org/testnet/snapshot".to_string(),
31+
);
32+
2933

30-
let node = builder.build().unwrap();
34+
let mnemonic = generate_entropy_mnemonic(None);
35+
let node_entropy = NodeEntropy::from_bip39_mnemonic(mnemonic, None);
36+
let node = builder.build(node_entropy).unwrap();
3137

3238
node.start().unwrap();
3339

bindings/kotlin/ldk-node-android/lib/src/androidTest/kotlin/org/lightningdevkit/ldknode/AndroidLibTest.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ class AndroidLibTest {
3434
val builder1 = Builder.fromConfig(config1)
3535
val builder2 = Builder.fromConfig(config2)
3636

37-
val node1 = builder1.build()
38-
val node2 = builder2.build()
37+
val mnemonic1 = generateEntropyMnemonic(null)
38+
val nodeEntropy1 = NodeEntropy.fromBip39Mnemonic(mnemonic1, null)
39+
val node1 = builder1.build(nodeEntropy1)
40+
41+
val mnemonic2 = generateEntropyMnemonic(null)
42+
val nodeEntropy2 = NodeEntropy.fromBip39Mnemonic(mnemonic2, null)
43+
val node2 = builder2.build(nodeEntropy2)
3944

4045
node1.start()
4146
node2.start()

bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,13 @@ class LibraryTest {
193193
builder2.setChainSourceEsplora(esploraEndpoint, null)
194194
builder2.setCustomLogger(logWriter2)
195195

196-
val node1 = builder1.build()
197-
val node2 = builder2.build()
196+
val mnemonic1 = generateEntropyMnemonic(null)
197+
val nodeEntropy1 = NodeEntropy.fromBip39Mnemonic(mnemonic1, null)
198+
val node1 = builder1.build(nodeEntropy1)
199+
200+
val mnemonic2 = generateEntropyMnemonic(null)
201+
val nodeEntropy2 = NodeEntropy.fromBip39Mnemonic(mnemonic2, null)
202+
val node2 = builder2.build(nodeEntropy2)
198203

199204
node1.start()
200205
node2.start()

bindings/ldk_node.udl

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ dictionary LSPS2ServiceConfig {
4747
boolean client_trusts_lsp;
4848
};
4949

50+
interface NodeEntropy {
51+
[Name=from_bip39_mnemonic]
52+
constructor(Mnemonic mnemonic, string? passphrase);
53+
[Throws=EntropyError, Name=from_seed_bytes]
54+
constructor(bytes seed_bytes);
55+
[Throws=EntropyError, Name=from_seed_path]
56+
constructor(string seed_path);
57+
};
58+
59+
enum EntropyError {
60+
"InvalidSeedBytes",
61+
"InvalidSeedFile",
62+
};
63+
5064
enum WordCount {
5165
"Words12",
5266
"Words15",
@@ -80,10 +94,6 @@ interface Builder {
8094
constructor();
8195
[Name=from_config]
8296
constructor(Config config);
83-
void set_entropy_seed_path(string seed_path);
84-
[Throws=BuildError]
85-
void set_entropy_seed_bytes(sequence<u8> seed_bytes);
86-
void set_entropy_bip39_mnemonic(Mnemonic mnemonic, string? passphrase);
8797
void set_chain_source_esplora(string server_url, EsploraSyncConfig? config);
8898
void set_chain_source_electrum(string server_url, ElectrumSyncConfig? config);
8999
void set_chain_source_bitcoind_rpc(string rpc_host, u16 rpc_port, string rpc_user, string rpc_password);
@@ -107,15 +117,15 @@ interface Builder {
107117
[Throws=BuildError]
108118
void set_async_payments_role(AsyncPaymentsRole? role);
109119
[Throws=BuildError]
110-
Node build();
120+
Node build(NodeEntropy node_entropy);
111121
[Throws=BuildError]
112-
Node build_with_fs_store();
122+
Node build_with_fs_store(NodeEntropy node_entropy);
113123
[Throws=BuildError]
114-
Node build_with_vss_store(string vss_url, string store_id, string lnurl_auth_server_url, record<string, string> fixed_headers);
124+
Node build_with_vss_store(NodeEntropy node_entropy, string vss_url, string store_id, string lnurl_auth_server_url, record<string, string> fixed_headers);
115125
[Throws=BuildError]
116-
Node build_with_vss_store_and_fixed_headers(string vss_url, string store_id, record<string, string> fixed_headers);
126+
Node build_with_vss_store_and_fixed_headers(NodeEntropy node_entropy, string vss_url, string store_id, record<string, string> fixed_headers);
117127
[Throws=BuildError]
118-
Node build_with_vss_store_and_header_provider(string vss_url, string store_id, VssHeaderProvider header_provider);
128+
Node build_with_vss_store_and_header_provider(NodeEntropy node_entropy, string vss_url, string store_id, VssHeaderProvider header_provider);
119129
};
120130

121131
interface Node {
@@ -357,8 +367,6 @@ dictionary BestBlock {
357367

358368
[Error]
359369
enum BuildError {
360-
"InvalidSeedBytes",
361-
"InvalidSeedFile",
362370
"InvalidSystemTime",
363371
"InvalidChannelMonitor",
364372
"InvalidListeningAddresses",

bindings/python/src/ldk_node/test_ldk_node.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,15 @@ def send_to_address(address, amount_sats):
9797

9898

9999
def setup_node(tmp_dir, esplora_endpoint, listening_addresses):
100+
mnemonic = generate_entropy_mnemonic(None)
101+
node_entropy = NodeEntropy.from_bip39_mnemonic(mnemonic, None)
100102
config = default_config()
101103
builder = Builder.from_config(config)
102104
builder.set_storage_dir_path(tmp_dir)
103105
builder.set_chain_source_esplora(esplora_endpoint, None)
104106
builder.set_network(DEFAULT_TEST_NETWORK)
105107
builder.set_listening_addresses(listening_addresses)
106-
return builder.build()
108+
return builder.build(node_entropy)
107109

108110
def get_esplora_endpoint():
109111
if os.environ.get('ESPLORA_ENDPOINT'):

0 commit comments

Comments
 (0)