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