gateway_cli/
general_commands.rs

1use std::time::{Duration, UNIX_EPOCH};
2
3use clap::Subcommand;
4use fedimint_core::config::FederationId;
5use fedimint_core::fedimint_build_code_version_env;
6use fedimint_core::time::now;
7use fedimint_eventlog::{EventKind, EventLogId};
8use fedimint_gateway_client::{
9    connect_federation, get_balances, get_info, get_mnemonic, leave_federation, payment_log,
10    payment_summary, stop,
11};
12use fedimint_gateway_common::{
13    ConnectFedPayload, LeaveFedPayload, PaymentLogPayload, PaymentSummaryPayload,
14};
15use fedimint_ln_common::client::GatewayRpcClient;
16
17use crate::print_response;
18
19#[derive(Subcommand)]
20pub enum GeneralCommands {
21    /// Display the version hash of the CLI.
22    VersionHash,
23    /// Display high-level information about the gateway.
24    Info,
25    /// Get the total on-chain, lightning, and eCash balances of the gateway.
26    GetBalances,
27    /// Register the gateway with a federation.
28    ConnectFed {
29        /// Invite code to connect to the federation
30        invite_code: String,
31        /// Activate usage of Tor (or not) as the connector for the federation
32        /// client
33        #[cfg(feature = "tor")]
34        use_tor: Option<bool>,
35        /// Indicates if the client should be recovered from a mnemonic
36        #[clap(long)]
37        recover: Option<bool>,
38    },
39    /// Leave a federation.
40    LeaveFed {
41        #[clap(long)]
42        federation_id: FederationId,
43    },
44    /// Prints the seed phrase for the gateway
45    Seed,
46    /// Safely stop the gateway
47    Stop,
48    /// List the fedimint transactions that the gateway has processed
49    PaymentLog {
50        #[clap(long)]
51        end_position: Option<EventLogId>,
52
53        #[clap(long, default_value_t = 25)]
54        pagination_size: usize,
55
56        #[clap(long)]
57        federation_id: FederationId,
58
59        #[clap(long)]
60        event_kinds: Vec<EventKind>,
61    },
62    /// Create a bcrypt hash of a password, for use in gateway deployment
63    CreatePasswordHash {
64        password: String,
65
66        /// The bcrypt cost factor to use when hashing the password
67        #[clap(long)]
68        cost: Option<u32>,
69    },
70    /// List a payment summary for the last day
71    PaymentSummary {
72        #[clap(long)]
73        start: Option<u64>,
74
75        #[clap(long)]
76        end: Option<u64>,
77    },
78}
79
80impl GeneralCommands {
81    #[allow(clippy::too_many_lines)]
82    pub async fn handle(self, client: &GatewayRpcClient) -> anyhow::Result<()> {
83        match self {
84            Self::VersionHash => {
85                println!("{}", fedimint_build_code_version_env!());
86            }
87            Self::Info => {
88                let response = get_info(client).await?;
89                print_response(response);
90            }
91            Self::GetBalances => {
92                let response = get_balances(client).await?;
93                print_response(response);
94            }
95            Self::ConnectFed {
96                invite_code,
97                #[cfg(feature = "tor")]
98                use_tor,
99                recover,
100            } => {
101                let response = connect_federation(
102                    client,
103                    ConnectFedPayload {
104                        invite_code,
105                        #[cfg(feature = "tor")]
106                        use_tor,
107                        #[cfg(not(feature = "tor"))]
108                        use_tor: None,
109                        recover,
110                    },
111                )
112                .await?;
113
114                print_response(response);
115            }
116            Self::LeaveFed { federation_id } => {
117                let response = leave_federation(client, LeaveFedPayload { federation_id }).await?;
118                print_response(response);
119            }
120            Self::Seed => {
121                let response = get_mnemonic(client).await?;
122                print_response(response);
123            }
124            Self::Stop => {
125                stop(client).await?;
126            }
127            Self::PaymentLog {
128                end_position,
129                pagination_size,
130                federation_id,
131                event_kinds,
132            } => {
133                let payment_log = payment_log(
134                    client,
135                    PaymentLogPayload {
136                        end_position,
137                        pagination_size,
138                        federation_id,
139                        event_kinds,
140                    },
141                )
142                .await?;
143                print_response(payment_log);
144            }
145            Self::CreatePasswordHash { password, cost } => print_response(
146                bcrypt::hash(password, cost.unwrap_or(bcrypt::DEFAULT_COST))
147                    .expect("Unable to create bcrypt hash"),
148            ),
149            Self::PaymentSummary { start, end } => {
150                let now = now();
151                let now_millis = now
152                    .duration_since(UNIX_EPOCH)
153                    .expect("Before unix epoch")
154                    .as_millis()
155                    .try_into()?;
156                let one_day_ago = now
157                    .checked_sub(Duration::from_secs(60 * 60 * 24))
158                    .expect("Before unix epoch");
159                let one_day_ago_millis = one_day_ago
160                    .duration_since(UNIX_EPOCH)
161                    .expect("Before unix epoch")
162                    .as_millis()
163                    .try_into()?;
164                let end_millis = end.unwrap_or(now_millis);
165                let start_millis = start.unwrap_or(one_day_ago_millis);
166                let payment_summary = payment_summary(
167                    client,
168                    PaymentSummaryPayload {
169                        start_millis,
170                        end_millis,
171                    },
172                )
173                .await?;
174                print_response(payment_summary);
175            }
176        }
177
178        Ok(())
179    }
180}