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