gateway_cli/
main.rs

1#![deny(clippy::pedantic, clippy::nursery)]
2
3mod config_commands;
4mod ecash_commands;
5mod general_commands;
6mod lightning_commands;
7mod onchain_commands;
8
9use clap::{CommandFactory, Parser, Subcommand};
10use config_commands::ConfigCommands;
11use ecash_commands::EcashCommands;
12use fedimint_connectors::ConnectorRegistry;
13use fedimint_core::util::SafeUrl;
14use fedimint_ln_common::client::GatewayApi;
15use fedimint_logging::TracingSetup;
16use general_commands::GeneralCommands;
17use lightning_commands::LightningCommands;
18use onchain_commands::OnchainCommands;
19use serde::Serialize;
20
21#[derive(Parser)]
22#[command(version)]
23struct Cli {
24    /// The address of the gateway webserver
25    #[clap(long, short, default_value = "http://127.0.0.1:80")]
26    address: SafeUrl,
27
28    /// The command to execute
29    #[command(subcommand)]
30    command: Commands,
31
32    /// Password for authenticated requests to the gateway
33    #[clap(long)]
34    rpcpassword: Option<String>,
35}
36
37#[derive(Subcommand)]
38enum Commands {
39    #[command(flatten)]
40    General(GeneralCommands),
41    #[command(subcommand)]
42    Lightning(LightningCommands),
43    #[command(subcommand)]
44    Ecash(EcashCommands),
45    #[command(subcommand)]
46    Onchain(OnchainCommands),
47    #[command(subcommand)]
48    Cfg(ConfigCommands),
49    Completion {
50        shell: clap_complete::Shell,
51    },
52}
53
54#[tokio::main]
55async fn main() {
56    if let Err(err) = TracingSetup::default().init() {
57        eprintln!("Failed to initialize logging: {err}");
58        std::process::exit(1);
59    }
60
61    if let Err(err) = run().await {
62        eprintln!("Error: {err}");
63        let mut source = err.source();
64        eprintln!("Caused by");
65        while let Some(err) = source {
66            eprintln!("    {err}");
67            source = err.source();
68        }
69        std::process::exit(1);
70    }
71}
72
73async fn run() -> anyhow::Result<()> {
74    let cli = Cli::parse();
75    let connector_registry = ConnectorRegistry::build_from_client_defaults()
76        .with_env_var_overrides()?
77        .bind()
78        .await?;
79    let client = GatewayApi::new(cli.rpcpassword, connector_registry);
80
81    match cli.command {
82        Commands::General(general_command) => general_command.handle(&client, &cli.address).await?,
83        Commands::Lightning(lightning_command) => {
84            lightning_command.handle(&client, &cli.address).await?;
85        }
86        Commands::Ecash(ecash_command) => ecash_command.handle(&client, &cli.address).await?,
87        Commands::Onchain(onchain_command) => onchain_command.handle(&client, &cli.address).await?,
88        Commands::Cfg(config_commands) => config_commands.handle(&client, &cli.address).await?,
89        Commands::Completion { shell } => {
90            clap_complete::generate(
91                shell,
92                &mut Cli::command(),
93                "gateway-cli",
94                &mut std::io::stdout(),
95            );
96        }
97    }
98
99    Ok(())
100}
101
102fn print_response<T: Serialize>(val: T) {
103    println!(
104        "{}",
105        serde_json::to_string_pretty(&val).expect("Cannot serialize")
106    );
107}