diff --git a/libs/sdk-common/Cargo.toml b/libs/sdk-common/Cargo.toml index 585918449..d124fe9e8 100644 --- a/libs/sdk-common/Cargo.toml +++ b/libs/sdk-common/Cargo.toml @@ -22,6 +22,7 @@ serde = { workspace = true } serde_json = { workspace = true } strum_macros = { workspace = true } thiserror = { workspace = true } +tokio = { workspace = true } tonic = { workspace = true, features = [ "tls", "transport", @@ -35,7 +36,6 @@ urlencoding = { version = "2.1.3" } [dev-dependencies] bitcoin = { workspace = true, features = ["rand"] } mockito = { workspace = true } -tokio = { workspace = true } once_cell = { workspace = true } [build-dependencies] diff --git a/libs/sdk-common/src/breez_server.rs b/libs/sdk-common/src/breez_server.rs index cc7ca0b4f..f1e10b6a2 100644 --- a/libs/sdk-common/src/breez_server.rs +++ b/libs/sdk-common/src/breez_server.rs @@ -1,5 +1,6 @@ use anyhow::Result; use log::trace; +use tokio::sync::Mutex; use tonic::codegen::InterceptedService; use tonic::metadata::errors::InvalidMetadataValue; use tonic::metadata::{Ascii, MetadataValue}; @@ -20,18 +21,26 @@ pub static PRODUCTION_BREEZSERVER_URL: &str = "https://bs1.breez.technology:443" pub static STAGING_BREEZSERVER_URL: &str = "https://bs1-st.breez.technology:443"; pub struct BreezServer { - grpc_channel: Channel, + grpc_channel: Mutex, api_key: Option, + server_url: String, } impl BreezServer { pub fn new(server_url: String, api_key: Option) -> Result { Ok(Self { - grpc_channel: Endpoint::from_shared(server_url)?.connect_lazy(), + grpc_channel: Mutex::new(Endpoint::from_shared(server_url.clone())?.connect_lazy()), api_key, + server_url, }) } + pub async fn reconnect(&self) -> Result<()> { + *self.grpc_channel.lock().await = + Endpoint::from_shared(self.server_url.clone())?.connect_lazy(); + Ok(()) + } + fn api_key_metadata(&self) -> Result>, ServiceConnectivityError> { match &self.api_key { Some(key) => Ok(Some(format!("Bearer {key}").parse().map_err( @@ -54,22 +63,22 @@ impl BreezServer { > { let api_key_metadata = self.api_key_metadata()?; let with_interceptor = ChannelOpenerClient::with_interceptor( - self.grpc_channel.clone(), + self.grpc_channel.lock().await.clone(), ApiKeyInterceptor { api_key_metadata }, ); Ok(with_interceptor) } pub async fn get_payment_notifier_client(&self) -> PaymentNotifierClient { - PaymentNotifierClient::new(self.grpc_channel.clone()) + PaymentNotifierClient::new(self.grpc_channel.lock().await.clone()) } pub async fn get_information_client(&self) -> InformationClient { - InformationClient::new(self.grpc_channel.clone()) + InformationClient::new(self.grpc_channel.lock().await.clone()) } pub async fn get_signer_client(&self) -> SignerClient { - SignerClient::new(self.grpc_channel.clone()) + SignerClient::new(self.grpc_channel.lock().await.clone()) } pub async fn get_support_client( @@ -80,13 +89,13 @@ impl BreezServer { > { let api_key_metadata = self.api_key_metadata()?; Ok(SupportClient::with_interceptor( - self.grpc_channel.clone(), + self.grpc_channel.lock().await.clone(), ApiKeyInterceptor { api_key_metadata }, )) } pub async fn get_swapper_client(&self) -> SwapperClient { - SwapperClient::new(self.grpc_channel.clone()) + SwapperClient::new(self.grpc_channel.lock().await.clone()) } pub async fn ping(&self) -> Result { diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index c6c9022b5..e16e5d4d2 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -2465,6 +2465,20 @@ impl BreezServicesBuilder { } }); + // Reconnect breez server on hibernation. + let cloned_breez_server = breez_server.clone(); + let mut cloned_hibernation_receiver = hibernation_receiver.clone(); + tokio::spawn(async move { + loop { + if cloned_hibernation_receiver.changed().await.is_err() { + return; + } + + debug!("Reconnect hibernation: reconnecting breez server"); + let _ = cloned_breez_server.reconnect().await; + } + }); + let current_lsp_id = persister.get_lsp_id()?; if current_lsp_id.is_none() && self.config.default_lsp_id.is_some() { persister.set_lsp(self.config.default_lsp_id.clone().unwrap(), None)?; diff --git a/tools/sdk-cli/Cargo.lock b/tools/sdk-cli/Cargo.lock index 36d4140ca..9e5daeffa 100644 --- a/tools/sdk-cli/Cargo.lock +++ b/tools/sdk-cli/Cargo.lock @@ -2996,6 +2996,7 @@ dependencies = [ "serde_json", "strum_macros", "thiserror", + "tokio", "tonic", "tonic-build", "url",