Skip to content

Commit 2619f29

Browse files
Add CLI args and env var support
Adds support for configuring the node via CLI arguments and environment variables, allowing runtime overrides of the configuration file. - Added `clap` dependency for argument parsing. - Implemented layered config loading: config file (full set of options) + environment variables + CLI arguments. Env vars and CLI args override values from the config file when present. - Implemented `ConfigBuilder` to handle partial state and merging. - Added comprehensive unit tests for precedence and validation logic. - Updated README with usage instructions and explanation of config precedence. Co-authored-by: moisesPomilio <93723302+moisesPompilio@users.noreply.github.com>
1 parent e57af08 commit 2619f29

File tree

5 files changed

+675
-182
lines changed

5 files changed

+675
-182
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,60 @@ We welcome your feedback and contributions to help shape the future of LDK Serve
3838
### Configuration
3939
Refer `./ldk-server/ldk-server-config.toml` to see available configuration options.
4040

41+
You can configure the node via a TOML file, environment variables, or CLI arguments. All options are optional — values provided via CLI override environment variables, which override the values in the TOML file.
42+
4143
### Building
4244
```
4345
git clone https://github.com/lightningdevkit/ldk-server.git
4446
cargo build
4547
```
4648

4749
### Running
50+
- Using a config file:
4851
```
4952
cargo run --bin ldk-server ./ldk-server/ldk-server-config.toml
5053
```
5154

52-
Interact with the node using CLI:
55+
- Using environment variables (all optional):
56+
```
57+
export LDK_SERVER_NODE_NETWORK=regtest
58+
export LDK_SERVER_NODE_LISTENING_ADDRESS=localhost:3001
59+
export LDK_SERVER_NODE_REST_SERVICE_ADDRESS=127.0.0.1:3002
60+
export LDK_SERVER_NODE_ALIAS=LDK-Server
61+
export LDK_SERVER_BITCOIND_RPC_ADDRESS=127.0.0.1:18443
62+
export LDK_SERVER_BITCOIND_RPC_USER=your-rpc-user
63+
export LDK_SERVER_BITCOIND_RPC_PASSWORD=your-rpc-password
64+
export LDK_SERVER_STORAGE_DIR_PATH=/path/to/storage
65+
cargo run --bin ldk-server
66+
```
67+
68+
- Using CLI arguments (all optional):
69+
```
70+
cargo run --bin ldk-server -- \
71+
--node-network regtest \
72+
--node-listening-address localhost:3001 \
73+
--node-rest-service-address 127.0.0.1:3002 \
74+
--node-alias LDK-Server \
75+
--bitcoind-rpc-address 127.0.0.1:18443 \
76+
--bitcoind-rpc-user your-rpc-user \
77+
--bitcoind-rpc-password your-rpc-password \
78+
--storage-dir-path /path/to/storage
79+
```
80+
81+
- Mixed configuration example (config file + overrides):
82+
```
83+
# config file sets listening_address = "localhost:3001"
84+
cargo run --bin ldk-server ./ldk-server/ldk-server-config.toml --node-listening-address localhost:3009
85+
# Result: `localhost:3009` will be used because CLI overrides the config file
86+
```
87+
88+
### Interacting with the Node
89+
90+
Once running, use the CLI client:
5391
```
54-
./target/debug/ldk-server-cli -b localhost:3002 onchain-receive # To generate onchain-receive address.
55-
./target/debug/ldk-server-cli -b localhost:3002 help # To print help/available commands.
92+
# Generate an on-chain receive address
93+
./target/debug/ldk-server-cli -b localhost:3002 onchain-receive
94+
95+
# View commands
96+
./target/debug/ldk-server-cli -b localhost:3002 help
5697
```

ldk-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ async-trait = { version = "0.1.85", default-features = false }
2020
toml = { version = "0.8.9", default-features = false, features = ["parse"] }
2121
chrono = { version = "0.4", default-features = false, features = ["clock"] }
2222
log = "0.4.28"
23+
clap = { version = "4.0.5", default-features = false, features = ["derive", "std", "error-context", "suggestions", "help", "env"] }
2324

2425
# Required for RabittMQ based EventPublisher. Only enabled for `events-rabbitmq` feature.
2526
lapin = { version = "2.4.0", features = ["rustls"], default-features = false, optional = true }

ldk-server/src/main.rs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use tokio::signal::unix::SignalKind;
2222
use hyper::server::conn::http1;
2323
use hyper_util::rt::TokioIo;
2424

25+
use clap::Parser;
26+
2527
use crate::io::events::event_publisher::EventPublisher;
2628
use crate::io::events::get_event_name;
2729
#[cfg(feature = "events-rabbitmq")]
@@ -33,7 +35,7 @@ use crate::io::persist::{
3335
FORWARDED_PAYMENTS_PERSISTENCE_SECONDARY_NAMESPACE, PAYMENTS_PERSISTENCE_PRIMARY_NAMESPACE,
3436
PAYMENTS_PERSISTENCE_SECONDARY_NAMESPACE,
3537
};
36-
use crate::util::config::{load_config, ChainSource};
38+
use crate::util::config::{load_config, ArgsConfig, ChainSource};
3739
use crate::util::logger::ServerLogger;
3840
use crate::util::proto_adapter::{forwarded_payment_to_proto, payment_to_proto};
3941
use hex::DisplayHex;
@@ -45,38 +47,19 @@ use ldk_server_protos::types::Payment;
4547
use log::{error, info};
4648
use prost::Message;
4749
use rand::Rng;
48-
use std::fs;
49-
use std::path::{Path, PathBuf};
50+
use std::path::PathBuf;
5051
use std::sync::Arc;
5152
use std::time::{SystemTime, UNIX_EPOCH};
5253
use tokio::select;
5354

54-
const USAGE_GUIDE: &str = "Usage: ldk-server <config_path>";
55-
5655
fn main() {
57-
let args: Vec<String> = std::env::args().collect();
58-
59-
if args.len() < 2 {
60-
eprintln!("{USAGE_GUIDE}");
61-
std::process::exit(-1);
62-
}
63-
64-
let arg = args[1].as_str();
65-
if arg == "-h" || arg == "--help" {
66-
println!("{}", USAGE_GUIDE);
67-
std::process::exit(0);
68-
}
69-
70-
if fs::File::open(arg).is_err() {
71-
eprintln!("Unable to access configuration file.");
72-
std::process::exit(-1);
73-
}
56+
let args_config = ArgsConfig::parse();
7457

7558
let mut ldk_node_config = Config::default();
76-
let config_file = match load_config(Path::new(arg)) {
59+
let config_file = match load_config(&args_config) {
7760
Ok(config) => config,
7861
Err(e) => {
79-
eprintln!("Invalid configuration file: {}", e);
62+
eprintln!("Invalid configuration: {}", e);
8063
std::process::exit(-1);
8164
},
8265
};

0 commit comments

Comments
 (0)