88// licenses.
99
1010use clap:: { Parser , Subcommand } ;
11+ use config:: {
12+ get_default_api_key_path, get_default_cert_path, get_default_config_path, load_config,
13+ } ;
14+ use hex_conservative:: DisplayHex ;
1115use ldk_server_client:: client:: LdkServerClient ;
1216use ldk_server_client:: error:: LdkServerError ;
1317use ldk_server_client:: error:: LdkServerErrorCode :: {
@@ -28,8 +32,10 @@ use ldk_server_client::ldk_server_protos::types::{
2832 RouteParametersConfig ,
2933} ;
3034use serde:: Serialize ;
35+ use std:: path:: PathBuf ;
3136use types:: CliListPaymentsResponse ;
3237
38+ mod config;
3339mod types;
3440
3541// Having these default values as constants in the Proto file and
@@ -43,19 +49,25 @@ const DEFAULT_EXPIRY_SECS: u32 = 86_400;
4349#[ derive( Parser , Debug ) ]
4450#[ command( version, about, long_about = None ) ]
4551struct Cli {
46- #[ arg( short, long, default_value = "localhost:3000 " ) ]
47- base_url : String ,
52+ #[ arg( short, long, help = "Base URL of the server. If not provided, reads from config file " ) ]
53+ base_url : Option < String > ,
4854
49- #[ arg( short, long, required( true ) ) ]
50- api_key : String ,
55+ #[ arg(
56+ short,
57+ long,
58+ help = "API key for authentication. If not provided, reads from config file"
59+ ) ]
60+ api_key : Option < String > ,
5161
5262 #[ arg(
5363 short,
5464 long,
55- required( true ) ,
56- help = "Path to the server's TLS certificate file (PEM format). Found at <server_storage_dir>/tls_cert.pem"
65+ help = "Path to the server's TLS certificate file (PEM format). If not provided, uses ~/.ldk-server/[network]/tls.crt"
5766 ) ]
58- tls_cert : String ,
67+ tls_cert : Option < String > ,
68+
69+ #[ arg( short, long, help = "Path to config file. Defaults to ~/.ldk-server/config.toml" ) ]
70+ config : Option < String > ,
5971
6072 #[ command( subcommand) ]
6173 command : Commands ,
@@ -226,18 +238,58 @@ enum Commands {
226238async fn main ( ) {
227239 let cli = Cli :: parse ( ) ;
228240
229- // Load server certificate for TLS verification
230- let server_cert_pem = std:: fs:: read ( & cli. tls_cert ) . unwrap_or_else ( |e| {
231- eprintln ! ( "Failed to read server certificate file '{}': {}" , cli. tls_cert, e) ;
232- std:: process:: exit ( 1 ) ;
233- } ) ;
241+ let config_path = cli. config . map ( PathBuf :: from) . or_else ( get_default_config_path) ;
242+ let config = config_path. as_ref ( ) . and_then ( |p| load_config ( p) . ok ( ) ) ;
234243
235- let client =
236- LdkServerClient :: new ( cli. base_url , cli. api_key , & server_cert_pem) . unwrap_or_else ( |e| {
237- eprintln ! ( "Failed to create client: {e}" ) ;
244+ // Get API key from argument, then from api_key file
245+ let api_key = cli
246+ . api_key
247+ . or_else ( || {
248+ // Try to read from api_key file based on network (file contains raw bytes)
249+ let network = config. as_ref ( ) . and_then ( |c| c. network ( ) . ok ( ) ) . unwrap_or ( "bitcoin" . to_string ( ) ) ;
250+ get_default_api_key_path ( & network)
251+ . and_then ( |path| std:: fs:: read ( & path) . ok ( ) )
252+ . map ( |bytes| bytes. to_lower_hex_string ( ) )
253+ } )
254+ . unwrap_or_else ( || {
255+ eprintln ! ( "API key not provided. Use --api-key or ensure the api_key file exists at ~/.ldk-server/[network]/api_key" ) ;
238256 std:: process:: exit ( 1 ) ;
239257 } ) ;
240258
259+ // Get base URL from argument then from config file
260+ let base_url =
261+ cli. base_url . or_else ( || config. as_ref ( ) . map ( |c| c. node . rest_service_address . clone ( ) ) )
262+ . unwrap_or_else ( || {
263+ eprintln ! ( "Base URL not provided. Use --base-url or ensure config file exists at ~/.ldk-server/config.toml" ) ;
264+ std:: process:: exit ( 1 ) ;
265+ } ) ;
266+
267+ // Get TLS cert path from argument, then from config file, then try default location
268+ let tls_cert_path = cli. tls_cert . map ( PathBuf :: from) . or_else ( || {
269+ config
270+ . as_ref ( )
271+ . and_then ( |c| c. tls . as_ref ( ) . and_then ( |t| t. cert_path . as_ref ( ) . map ( PathBuf :: from) ) )
272+ . or_else ( || {
273+ config
274+ . as_ref ( )
275+ . and_then ( |c| c. network ( ) . ok ( ) . and_then ( |n| get_default_cert_path ( & n) ) )
276+ } )
277+ } )
278+ . unwrap_or_else ( || {
279+ eprintln ! ( "TLS cert path not provided. Use --tls-cert or ensure config file exists at ~/.ldk-server/config.toml" ) ;
280+ std:: process:: exit ( 1 ) ;
281+ } ) ;
282+
283+ let server_cert_pem = std:: fs:: read ( & tls_cert_path) . unwrap_or_else ( |e| {
284+ eprintln ! ( "Failed to read server certificate file '{}': {}" , tls_cert_path. display( ) , e) ;
285+ std:: process:: exit ( 1 ) ;
286+ } ) ;
287+
288+ let client = LdkServerClient :: new ( base_url, api_key, & server_cert_pem) . unwrap_or_else ( |e| {
289+ eprintln ! ( "Failed to create client: {e}" ) ;
290+ std:: process:: exit ( 1 ) ;
291+ } ) ;
292+
241293 match cli. command {
242294 Commands :: GetNodeInfo => {
243295 handle_response_result :: < _ , GetNodeInfoResponse > (
0 commit comments