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