fedimint_ln_common/
client.rs

1use std::fmt::Debug;
2
3use anyhow::Context;
4use fedimint_connectors::error::ServerError;
5use fedimint_connectors::{
6    ConnectionPool, ConnectorRegistry, DynGatewayConnection, IGatewayConnection, ServerResult,
7};
8use fedimint_core::util::SafeUrl;
9use reqwest::Method;
10use serde::Serialize;
11use serde::de::DeserializeOwned;
12
13#[derive(Clone, Debug)]
14pub struct GatewayApi {
15    password: Option<String>,
16    connection_pool: ConnectionPool<dyn IGatewayConnection>,
17}
18
19impl GatewayApi {
20    pub fn new(password: Option<String>, connectors: ConnectorRegistry) -> Self {
21        Self {
22            password,
23            connection_pool: ConnectionPool::new(connectors),
24        }
25    }
26
27    async fn get_or_create_connection(&self, url: &SafeUrl) -> ServerResult<DynGatewayConnection> {
28        self.connection_pool
29            .get_or_create_connection(url, None, |url, _api_secret, connectors| async move {
30                let conn = connectors
31                    .connect_gateway(&url)
32                    .await
33                    .map_err(ServerError::Connection)?;
34                Ok(conn)
35            })
36            .await
37    }
38
39    pub async fn request<P: Serialize, T: DeserializeOwned>(
40        &self,
41        base_url: &SafeUrl,
42        method: Method,
43        route: &str,
44        payload: Option<P>,
45    ) -> ServerResult<T> {
46        let conn = self
47            .get_or_create_connection(base_url)
48            .await
49            .context("Failed to connect to gateway")
50            .map_err(ServerError::Connection)?;
51        let payload = payload.map(|p| serde_json::to_value(p).expect("Could not serialize"));
52        let res = conn
53            .request(self.password.clone(), method, route, payload)
54            .await?;
55        let response = serde_json::from_value::<T>(res).map_err(|e| {
56            ServerError::InvalidResponse(anyhow::anyhow!("Received invalid response: {e}"))
57        })?;
58        Ok(response)
59    }
60}