ln_gateway/
config.rs

1use std::fmt::Display;
2use std::net::SocketAddr;
3use std::path::PathBuf;
4use std::str::FromStr;
5
6use bitcoin::Network;
7use clap::Parser;
8use fedimint_core::util::SafeUrl;
9use fedimint_ln_common::config::GatewayFee;
10
11use super::envs;
12use super::lightning::LightningMode;
13use super::rpc::V1_API_ENDPOINT;
14
15/// Command line parameters for starting the gateway. `mode`, `data_dir`,
16/// `listen`, and `api_addr` are all required.
17#[derive(Parser)]
18#[command(version)]
19pub struct GatewayOpts {
20    #[clap(subcommand)]
21    pub mode: LightningMode,
22
23    /// Path to folder containing gateway config and data files
24    #[arg(long = "data-dir", env = envs::FM_GATEWAY_DATA_DIR_ENV)]
25    pub data_dir: PathBuf,
26
27    /// Gateway webserver listen address
28    #[arg(long = "listen", env = envs::FM_GATEWAY_LISTEN_ADDR_ENV)]
29    listen: SocketAddr,
30
31    /// Public URL from which the webserver API is reachable
32    #[arg(long = "api-addr", env = envs::FM_GATEWAY_API_ADDR_ENV)]
33    api_addr: SafeUrl,
34
35    /// Gateway webserver authentication password
36    #[arg(long = "password", env = envs::FM_GATEWAY_PASSWORD_ENV)]
37    password: Option<String>,
38
39    /// Bitcoin network this gateway will be running on
40    #[arg(long = "network", env = envs::FM_GATEWAY_NETWORK_ENV)]
41    network: Option<Network>,
42
43    /// Configured gateway routing fees
44    /// Format: <base_msat>,<proportional_millionths>
45    #[arg(long = "default-fees", env = envs::FM_DEFAULT_GATEWAY_FEES_ENV)]
46    default_fees: Option<GatewayFee>,
47
48    /// Number of route hints to return in invoices
49    #[arg(
50        long = "num-route-hints",
51        env = envs::FM_NUMBER_OF_ROUTE_HINTS_ENV,
52        default_value_t = super::DEFAULT_NUM_ROUTE_HINTS
53    )]
54    num_route_hints: u32,
55
56    /// The Lightning module to use: LNv1, LNv2, or both
57    #[arg(long = "lightning-module-mode", env = envs::FM_GATEWAY_LIGHTNING_MODULE_MODE_ENV, default_value_t = LightningModuleMode::LNv1)]
58    lightning_module_mode: LightningModuleMode,
59}
60
61impl GatewayOpts {
62    /// Converts the command line parameters into a helper struct the Gateway
63    /// uses to store runtime parameters.
64    pub fn to_gateway_parameters(&self) -> anyhow::Result<GatewayParameters> {
65        let versioned_api = self.api_addr.join(V1_API_ENDPOINT).map_err(|e| {
66            anyhow::anyhow!(
67                "Failed to version gateway API address: {api_addr:?}, error: {e:?}",
68                api_addr = self.api_addr,
69            )
70        })?;
71        Ok(GatewayParameters {
72            listen: self.listen,
73            versioned_api,
74            password: self.password.clone(),
75            network: self.network,
76            num_route_hints: self.num_route_hints,
77            fees: self.default_fees.clone(),
78            lightning_module_mode: self.lightning_module_mode,
79        })
80    }
81}
82
83/// `GatewayParameters` is a helper struct that can be derived from
84/// `GatewayOpts` that holds the CLI or environment variables that are specified
85/// by the user.
86///
87/// If `GatewayConfiguration is set in the database, that takes precedence and
88/// the optional parameters will have no affect.
89#[derive(Clone, Debug)]
90pub struct GatewayParameters {
91    pub listen: SocketAddr,
92    pub versioned_api: SafeUrl,
93    pub password: Option<String>,
94    pub network: Option<Network>,
95    pub num_route_hints: u32,
96    pub fees: Option<GatewayFee>,
97    pub lightning_module_mode: LightningModuleMode,
98}
99
100#[derive(Debug, Clone, Copy, Eq, PartialEq)]
101pub enum LightningModuleMode {
102    LNv1,
103    LNv2,
104    All,
105}
106
107impl Display for LightningModuleMode {
108    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109        match self {
110            LightningModuleMode::LNv1 => write!(f, "LNv1"),
111            LightningModuleMode::LNv2 => write!(f, "LNv2"),
112            LightningModuleMode::All => write!(f, "All"),
113        }
114    }
115}
116
117impl FromStr for LightningModuleMode {
118    type Err = anyhow::Error;
119
120    fn from_str(s: &str) -> Result<Self, Self::Err> {
121        let mode = match s {
122            "LNv1" => LightningModuleMode::LNv1,
123            "LNv2" => LightningModuleMode::LNv2,
124            _ => LightningModuleMode::All,
125        };
126
127        Ok(mode)
128    }
129}