From 6e5bd38d5068e003cb1b93566932cf5d42c3813d Mon Sep 17 00:00:00 2001 From: DanGould Date: Fri, 5 Jan 2024 12:28:50 -0500 Subject: [PATCH] Handle payjoin errors according to BIP 78 "The receiver is allowed to return implementation specific errors which may assist the sender to diagnose any issue. However, it is important that error codes that are not well-known and that the message do not appear on the sender's software user interface. Such error codes or messages could be used maliciously to phish a non- technical user. Instead those errors or messages can only appear in debug logs. It is advised to hard code the description of the well known error codes into the sender's software." See: https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors This commit displays templates based on a particular \`ResponseError\` and debugs the rest, according to this specification. --- mutiny-core/src/error.rs | 2 +- mutiny-core/src/nodemanager.rs | 11 ++++++----- mutiny-wasm/src/error.rs | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mutiny-core/src/error.rs b/mutiny-core/src/error.rs index 47763cd63..5b1786cdb 100644 --- a/mutiny-core/src/error.rs +++ b/mutiny-core/src/error.rs @@ -148,7 +148,7 @@ pub enum MutinyError { #[error("Failed to create payjoin request.")] PayjoinCreateRequest, /// Payjoin request failed. - #[error("Payjoin response error.")] + #[error("Payjoin response error: {0}")] PayjoinResponse(payjoin::send::ResponseError), /// Payjoin configuration error #[error("Payjoin configuration failed.")] diff --git a/mutiny-core/src/nodemanager.rs b/mutiny-core/src/nodemanager.rs index a52f5f16b..9221e2859 100644 --- a/mutiny-core/src/nodemanager.rs +++ b/mutiny-core/src/nodemanager.rs @@ -783,7 +783,7 @@ impl NodeManager { fee_rate: Option, ) -> Result { let address = Address::from_str(&uri.address.to_string()) - .map_err(|_| MutinyError::PayjoinConfigError)?; + .map_err(|_| MutinyError::InvalidArgumentsError)?; let original_psbt = self.wallet.create_signed_psbt(address, amount, fee_rate)?; let fee_rate = if let Some(rate) = fee_rate { @@ -796,18 +796,18 @@ impl NodeManager { let original_psbt = payjoin::bitcoin::psbt::PartiallySignedTransaction::from_str( &original_psbt.to_string(), ) - .map_err(|_| MutinyError::PayjoinConfigError)?; + .map_err(|_| MutinyError::WalletOperationFailed)?; log_debug!(self.logger, "Creating payjoin request"); let (req, ctx) = payjoin::send::RequestBuilder::from_psbt_and_uri(original_psbt.clone(), uri) .unwrap() .build_recommended(fee_rate) - .map_err(|_| MutinyError::PayjoinConfigError)? + .map_err(|_| MutinyError::PayjoinCreateRequest)? .extract_v1()?; let client = Client::builder() .build() - .map_err(|_| MutinyError::PayjoinConfigError)?; + .map_err(|e| MutinyError::Other(e.into()))?; log_debug!(self.logger, "Sending payjoin request"); let res = client @@ -825,7 +825,8 @@ impl NodeManager { log_debug!(self.logger, "Processing payjoin response"); let proposal_psbt = ctx.process_response(&mut cursor).map_err(|e| { - log_error!(self.logger, "Error processing payjoin response: {e}"); + // unrecognized error contents may only appear in debug logs and will not Display + log_debug!(self.logger, "Payjoin response error: {:?}", e); e })?; diff --git a/mutiny-wasm/src/error.rs b/mutiny-wasm/src/error.rs index 9cd4d4142..1946ac26e 100644 --- a/mutiny-wasm/src/error.rs +++ b/mutiny-wasm/src/error.rs @@ -148,8 +148,8 @@ pub enum MutinyJsError { #[error("Failed to create payjoin request.")] PayjoinCreateRequest, // Payjoin request failed. - #[error("Payjoin response error.")] - PayjoinResponse, + #[error("Payjoin response error: {0}")] + PayjoinResponse(String), /// Payjoin configuration error #[error("Payjoin configuration failed.")] PayjoinConfigError, @@ -209,7 +209,7 @@ impl From for MutinyJsError { MutinyError::NetworkMismatch => MutinyJsError::NetworkMismatch, MutinyError::PayjoinConfigError => MutinyJsError::PayjoinConfigError, MutinyError::PayjoinCreateRequest => MutinyJsError::PayjoinCreateRequest, - MutinyError::PayjoinResponse(_) => MutinyJsError::PayjoinResponse, + MutinyError::PayjoinResponse(e) => MutinyJsError::PayjoinResponse(e.to_string()), } } }