breez_sdk_core/
support.rs1use std::time::SystemTime;
2
3use crate::error::{SdkError, SdkResult};
4use crate::{HealthCheckStatus, NodeState, Payment, ServiceHealthCheckResponse, SupportAPI};
5
6use anyhow::anyhow;
7use chrono::{DateTime, Utc};
8use sdk_common::grpc::{BreezStatusRequest, ReportPaymentFailureRequest};
9use sdk_common::prelude::BreezServer;
10use sdk_common::with_connection_retry;
11use serde::{Deserialize, Serialize};
12
13#[derive(Serialize, Deserialize)]
14struct PaymentFailureReport {
15 pub node_state: NodeState,
16 pub payment: Payment,
17}
18
19impl TryFrom<i32> for HealthCheckStatus {
20 type Error = anyhow::Error;
21
22 fn try_from(value: i32) -> Result<Self, Self::Error> {
23 match value {
24 0 => Ok(HealthCheckStatus::Operational),
25 1 => Ok(HealthCheckStatus::Maintenance),
26 2 => Ok(HealthCheckStatus::ServiceDisruption),
27 _ => Err(anyhow!("illegal value")),
28 }
29 }
30}
31
32#[tonic::async_trait]
33impl SupportAPI for BreezServer {
34 async fn service_health_check(&self) -> SdkResult<ServiceHealthCheckResponse> {
35 let mut client = self.get_support_client().await?;
36
37 let request = BreezStatusRequest {};
38 let response = with_connection_retry!(client.breez_status(request.clone()))
39 .await
40 .map_err(|e| SdkError::ServiceConnectivity {
41 err: format!("(Breez) Fetch status failed: {e}"),
42 })?;
43 let status = response.into_inner().status.try_into()?;
44 Ok(ServiceHealthCheckResponse { status })
45 }
46
47 async fn report_payment_failure(
48 &self,
49 node_state: NodeState,
50 payment: Payment,
51 lsp_id: Option<String>,
52 comment: Option<String>,
53 ) -> SdkResult<()> {
54 let mut client = self.get_support_client().await?;
55
56 let timestamp: DateTime<Utc> = SystemTime::now().into();
57 let report = PaymentFailureReport {
58 node_state: node_state.clone(),
59 payment,
60 };
61
62 let request = ReportPaymentFailureRequest {
63 sdk_version: option_env!("CARGO_PKG_VERSION")
64 .unwrap_or_default()
65 .to_string(),
66 sdk_git_hash: option_env!("SDK_GIT_HASH").unwrap_or_default().to_string(),
67 node_id: node_state.id,
68 lsp_id: lsp_id.unwrap_or_default(),
69 timestamp: timestamp.to_rfc3339(),
70 comment: comment.unwrap_or_default(),
71 report: serde_json::to_string(&report)?,
72 };
73 _ = with_connection_retry!(client.report_payment_failure(request.clone()))
74 .await
75 .map_err(|e| SdkError::ServiceConnectivity {
76 err: format!("(Breez) Report payment failure failed: {e}"),
77 })?;
78 Ok(())
79 }
80}