diff --git a/libs/sdk-bindings/src/breez_sdk.udl b/libs/sdk-bindings/src/breez_sdk.udl index b9b9d22de..abf2a213c 100644 --- a/libs/sdk-bindings/src/breez_sdk.udl +++ b/libs/sdk-bindings/src/breez_sdk.udl @@ -98,6 +98,13 @@ enum SendPaymentError { "ServiceConnectivity", }; +[Error] +enum RedeemOnchainError { + "Generic", + "ServiceConnectivity", + "InsufficientFunds", +}; + enum EnvironmentType { "Production", "Staging", @@ -874,7 +881,7 @@ interface BlockingBreezServices { [Throws=SdkError] void set_payment_metadata(string hash, string metadata); - [Throws=SdkError] + [Throws=RedeemOnchainError] RedeemOnchainFundsResponse redeem_onchain_funds(RedeemOnchainFundsRequest req); [Throws=SdkError] @@ -973,7 +980,7 @@ interface BlockingBreezServices { [Throws=ReceiveOnchainError] BuyBitcoinResponse buy_bitcoin(BuyBitcoinRequest req); - [Throws=SdkError] + [Throws=RedeemOnchainError] PrepareRedeemOnchainFundsResponse prepare_redeem_onchain_funds(PrepareRedeemOnchainFundsRequest req); }; diff --git a/libs/sdk-bindings/src/uniffi_binding.rs b/libs/sdk-bindings/src/uniffi_binding.rs index 7aada9bd0..ec446fd29 100644 --- a/libs/sdk-bindings/src/uniffi_binding.rs +++ b/libs/sdk-bindings/src/uniffi_binding.rs @@ -212,7 +212,7 @@ impl BlockingBreezServices { pub fn redeem_onchain_funds( &self, req: RedeemOnchainFundsRequest, - ) -> SdkResult { + ) -> RedeemOnchainResult { rt().block_on(self.breez_services.redeem_onchain_funds(req)) } @@ -382,7 +382,7 @@ impl BlockingBreezServices { pub fn prepare_redeem_onchain_funds( &self, req: PrepareRedeemOnchainFundsRequest, - ) -> SdkResult { + ) -> RedeemOnchainResult { rt().block_on(self.breez_services.prepare_redeem_onchain_funds(req)) } } diff --git a/libs/sdk-core/src/binding.rs b/libs/sdk-core/src/binding.rs index 13420a054..f22cd88df 100644 --- a/libs/sdk-core/src/binding.rs +++ b/libs/sdk-core/src/binding.rs @@ -31,8 +31,8 @@ use tokio::sync::Mutex; use crate::breez_services::{self, BreezEvent, BreezServices, EventListener}; use crate::chain::RecommendedFees; use crate::error::{ - ConnectError, ReceiveOnchainError, ReceivePaymentError, SdkError, SendOnchainError, - SendPaymentError, + ConnectError, ReceiveOnchainError, ReceivePaymentError, RedeemOnchainError, SdkError, + SendOnchainError, SendPaymentError, }; use crate::lsp::LspInformation; use crate::models::{Config, LogEntry, NodeState, Payment, SwapInfo}; @@ -639,7 +639,7 @@ pub fn buy_bitcoin(req: BuyBitcoinRequest) -> Result { /// See [BreezServices::redeem_onchain_funds] pub fn redeem_onchain_funds(req: RedeemOnchainFundsRequest) -> Result { block_on(async { get_breez_services().await?.redeem_onchain_funds(req).await }) - .map_err(anyhow::Error::new::) + .map_err(anyhow::Error::new::) } /// See [BreezServices::prepare_redeem_onchain_funds] @@ -652,7 +652,7 @@ pub fn prepare_redeem_onchain_funds( .prepare_redeem_onchain_funds(req) .await }) - .map_err(anyhow::Error::new::) + .map_err(anyhow::Error::new::) } /* Refundables API's */ diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index e3233b0b6..a8ff5bfb5 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -29,8 +29,8 @@ use crate::chain::{ DEFAULT_MEMPOOL_SPACE_URL, }; use crate::error::{ - ConnectError, ReceiveOnchainError, ReceiveOnchainResult, ReceivePaymentError, SdkError, - SdkResult, SendOnchainError, SendPaymentError, + ConnectError, ReceiveOnchainError, ReceiveOnchainResult, ReceivePaymentError, + RedeemOnchainResult, SdkError, SdkResult, SendOnchainError, SendPaymentError, }; use crate::greenlight::{GLBackupTransport, Greenlight}; use crate::lnurl::pay::*; @@ -626,7 +626,7 @@ impl BreezServices { pub async fn redeem_onchain_funds( &self, req: RedeemOnchainFundsRequest, - ) -> SdkResult { + ) -> RedeemOnchainResult { self.start_node().await?; let txid = self .node_api @@ -639,7 +639,7 @@ impl BreezServices { pub async fn prepare_redeem_onchain_funds( &self, req: PrepareRedeemOnchainFundsRequest, - ) -> SdkResult { + ) -> RedeemOnchainResult { self.start_node().await?; let response = self.node_api.prepare_redeem_onchain_funds(req).await?; Ok(response) diff --git a/libs/sdk-core/src/error.rs b/libs/sdk-core/src/error.rs index 4c7c22eee..a398d5faa 100644 --- a/libs/sdk-core/src/error.rs +++ b/libs/sdk-core/src/error.rs @@ -201,6 +201,53 @@ impl From for ReceiveOnchainError { } } +pub type RedeemOnchainResult = Result; + +#[derive(Debug, Error)] +pub enum RedeemOnchainError { + /// This error is raised when a general error occurs not specific to other error variants + /// in this enum. + #[error("Generic: {err}")] + Generic { err: String }, + + /// This error is raised when a connection to an external service fails. + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, + + /// This error is raised when the node does not have enough funds to redeem the onchain balance. + #[error("{err}")] + InsufficientFunds { err: String }, +} + +impl From for RedeemOnchainError { + fn from(value: NodeError) -> Self { + match value { + NodeError::InsufficientFunds(err) => Self::InsufficientFunds { err }, + NodeError::ServiceConnectivity(err) => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for RedeemOnchainError { + fn from(err: anyhow::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for RedeemOnchainError { + fn from(value: SdkError) -> Self { + match value { + SdkError::Generic { err } => Self::Generic { err }, + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + } + } +} + /// Error returned by [crate::breez_services::BreezServices::receive_payment] #[derive(Debug, Error)] pub enum ReceivePaymentError { diff --git a/libs/sdk-core/src/greenlight/node_api.rs b/libs/sdk-core/src/greenlight/node_api.rs index 0ddf06a1c..b89fb91e8 100644 --- a/libs/sdk-core/src/greenlight/node_api.rs +++ b/libs/sdk-core/src/greenlight/node_api.rs @@ -1260,7 +1260,9 @@ impl NodeAPI for Greenlight { + witness_input_size * txins.len() as u64; let fee: u64 = tx_weight * req.sat_per_vbyte as u64 / WITNESS_SCALE_FACTOR as u64; if fee >= amount_sat { - return Err(NodeError::generic("Insufficient funds to pay fees")); + return Err(NodeError::InsufficientFunds( + "Insufficient funds to pay fees".to_string(), + )); } return Ok(PrepareRedeemOnchainFundsResponse { diff --git a/libs/sdk-core/src/node_api.rs b/libs/sdk-core/src/node_api.rs index d669c6d98..5de808263 100644 --- a/libs/sdk-core/src/node_api.rs +++ b/libs/sdk-core/src/node_api.rs @@ -12,9 +12,9 @@ use crate::{ bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey}, lightning_invoice::RawBolt11Invoice, persist::error::PersistError, - CustomMessage, LspInformation, MaxChannelAmount, NodeCredentials, Payment, PaymentResponse, - PrepareRedeemOnchainFundsRequest, PrepareRedeemOnchainFundsResponse, RouteHint, RouteHintHop, - SyncResponse, TlvEntry, LnUrlAuthError + CustomMessage, LnUrlAuthError, LspInformation, MaxChannelAmount, NodeCredentials, Payment, + PaymentResponse, PrepareRedeemOnchainFundsRequest, PrepareRedeemOnchainFundsResponse, + RouteHint, RouteHintHop, SyncResponse, TlvEntry, }; pub type NodeResult = Result; @@ -59,6 +59,9 @@ pub enum NodeError { #[error("{0}")] ServiceConnectivity(String), + + #[error("{0}")] + InsufficientFunds(String), } impl NodeError { @@ -86,7 +89,7 @@ impl From for LnUrlAuthError { match value { NodeError::ServiceConnectivity(err) => Self::ServiceConnectivity { err }, _ => Self::Generic { - err: value.to_string() + err: value.to_string(), }, } }