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