Skip to content

Commit c06b118

Browse files
committed
Introduce new mandatory NodeEntropy object
Previously, the `Builder` allowed setting different entropy sources via its `set_entropy...` methods, defaulting to sourcing from an auto-generated seed file in the storage path. While this allowed for really easy setup, it spared the user to actually think about where to store their node secret. Here, we therefore introduce a mandatory `NodeEntropy` object that, as before, allows the user to source entropy from BIP39 Mnemonic, seed bytes, or a seed file. However, it doesn't implement any default and hence intentionally requires manually setup by the user. Moreover, this API refactor also allows to reuse the same object outside of the `Node`'s `Builder` in a future commit.
1 parent 9040097 commit c06b118

File tree

16 files changed

+306
-269
lines changed

16 files changed

+306
-269
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)