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