fedimint_ln_common/
client.rs1use 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}