From 784fc81e4d4df9ae35f95ec5940076de461b8c97 Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Sat, 19 Aug 2023 15:20:46 +0200 Subject: [PATCH] Add optional logging of reqwest raw payloads --- libs/sdk-core/src/boltzswap.rs | 6 ++---- libs/sdk-core/src/breez_services.rs | 6 ++++++ libs/sdk-core/src/chain.rs | 23 ++++------------------- libs/sdk-core/src/input_parser.rs | 24 +++++++++++++++++++++++- libs/sdk-core/src/lnurl/auth.rs | 5 ++--- libs/sdk-core/src/lnurl/pay.rs | 4 ++-- libs/sdk-core/src/lnurl/withdraw.rs | 5 ++--- 7 files changed, 41 insertions(+), 32 deletions(-) diff --git a/libs/sdk-core/src/boltzswap.rs b/libs/sdk-core/src/boltzswap.rs index a2f64d902..a555bd4a4 100644 --- a/libs/sdk-core/src/boltzswap.rs +++ b/libs/sdk-core/src/boltzswap.rs @@ -11,6 +11,7 @@ use const_format::concatcp; use reqwest::header::CONTENT_TYPE; use reqwest::{Body, Client}; +use crate::input_parser::get_parse_and_log_response; use crate::models::ReverseSwapPairInfo; use crate::reverseswap::CreateReverseSwapResponse; use crate::ReverseSwapperAPI; @@ -232,10 +233,7 @@ impl ReverseSwapperAPI for BoltzApi { } pub async fn reverse_swap_pair_info() -> Result { - let pairs = reqwest::get(GET_PAIRS_ENDPOINT) - .await? - .json::() - .await?; + let pairs: Pairs = get_parse_and_log_response(GET_PAIRS_ENDPOINT).await?; match pairs.pairs.get("BTC/BTC") { None => Err(anyhow!("BTC pair not found")), Some(btc_pair) => { diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index ef0a218ac..f95c074cb 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -1027,6 +1027,11 @@ impl BreezServices { /// log output to a file in the configured `log_dir`, then do not register the /// app-specific logger as a global logger and instead call this method with the app logger as an arg. /// + /// ### Logging Configuration + /// + /// Setting `breez_sdk_core::input_parser=debug` will include in the logs the raw payloads received + /// when interacting with JSON endpoints, for example those used during all LNURL workflows. + /// /// ### Errors /// /// An error is thrown if the log file cannot be created in the working directory. @@ -1047,6 +1052,7 @@ impl BreezServices { .parse_filters( r#" info, + breez_sdk_core::input_parser=warn, gl_client=warn, h2=warn, hyper=warn, diff --git a/libs/sdk-core/src/chain.rs b/libs/sdk-core/src/chain.rs index cae9cbaa4..0ed03496e 100644 --- a/libs/sdk-core/src/chain.rs +++ b/libs/sdk-core/src/chain.rs @@ -1,3 +1,4 @@ +use crate::input_parser::get_parse_and_log_response; use anyhow::Result; use bitcoin::hashes::hex::FromHex; use bitcoin::{OutPoint, Txid}; @@ -196,31 +197,15 @@ impl MempoolSpace { #[tonic::async_trait] impl ChainService for MempoolSpace { async fn recommended_fees(&self) -> Result { - Ok( - reqwest::get(format!("{}/api/v1/fees/recommended", self.base_url)) - .await? - .json() - .await?, - ) + get_parse_and_log_response(&format!("{}/api/v1/fees/recommended", self.base_url)).await } async fn address_transactions(&self, address: String) -> Result> { - Ok( - reqwest::get(format!("{}/api/address/{}/txs", self.base_url, address)) - .await? - .json() - .await?, - ) + get_parse_and_log_response(&format!("{}/api/address/{address}/txs", self.base_url)).await } async fn current_tip(&self) -> Result { - Ok( - reqwest::get(format!("{}/api/blocks/tip/height", self.base_url)) - .await? - .text() - .await? - .parse()?, - ) + get_parse_and_log_response(&format!("{}/api/blocks/tip/height", self.base_url)).await } async fn broadcast_transaction(&self, tx: Vec) -> Result { diff --git a/libs/sdk-core/src/input_parser.rs b/libs/sdk-core/src/input_parser.rs index c64e43af5..27f3137af 100644 --- a/libs/sdk-core/src/input_parser.rs +++ b/libs/sdk-core/src/input_parser.rs @@ -204,7 +204,7 @@ pub async fn parse(input: &str) -> Result { } lnurl_endpoint = maybe_replace_host_with_mockito_test_host(lnurl_endpoint)?; - let lnurl_data: LnUrlRequestData = reqwest::get(lnurl_endpoint).await?.json().await?; + let lnurl_data: LnUrlRequestData = get_parse_and_log_response(&lnurl_endpoint).await?; let temp = lnurl_data.into(); let temp = match temp { // Modify the LnUrlPay payload by adding the domain of the LNURL endpoint @@ -227,6 +227,28 @@ pub async fn parse(input: &str) -> Result { Err(anyhow!("Unrecognized input type")) } +/// Makes a GET request to the specified `url` and logs on DEBUG: +/// - the URL +/// - the raw response body +pub(crate) async fn get_and_log_response(url: &str) -> Result { + debug!("Making GET request to: {url}"); + + let raw_body = reqwest::get(url).await?.text().await?; + debug!("Received raw response body: {raw_body}"); + + Ok(raw_body) +} + +/// Wrapper around [get_and_log_response] that, in addition, parses the payload into an expected type +pub(crate) async fn get_parse_and_log_response(url: &str) -> Result +where + for<'a> T: serde::de::Deserialize<'a>, +{ + let raw_body = get_and_log_response(url).await?; + + serde_json::from_str(&raw_body).map_err(|e| anyhow!("Failed to parse json: {e}")) +} + /// Prepends the given prefix to the input, if the input doesn't already start with it fn prepend_if_missing(prefix: &str, input: &str) -> String { format!("{}{}", prefix, input.trim_start_matches(prefix)) diff --git a/libs/sdk-core/src/lnurl/auth.rs b/libs/sdk-core/src/lnurl/auth.rs index 9024ab1a5..24c7eec6d 100644 --- a/libs/sdk-core/src/lnurl/auth.rs +++ b/libs/sdk-core/src/lnurl/auth.rs @@ -1,3 +1,4 @@ +use crate::input_parser::get_parse_and_log_response; use crate::{LnUrlAuthRequestData, LnUrlCallbackStatus, NodeAPI}; use anyhow::{anyhow, Result}; use bitcoin::hashes::{hex::ToHex, sha256, Hash, HashEngine, Hmac, HmacEngine}; @@ -29,10 +30,8 @@ pub(crate) async fn perform_lnurl_auth( callback_url .query_pairs_mut() .append_pair("key", &linking_keys.public_key().to_hex()); - debug!("Trying to call {}", callback_url.to_string()); - let callback_resp_text = reqwest::get(callback_url).await?.text().await?; - serde_json::from_str::(&callback_resp_text).map_err(|e| anyhow!(e)) + get_parse_and_log_response(callback_url.as_ref()).await } pub(crate) fn validate_request( diff --git a/libs/sdk-core/src/lnurl/pay.rs b/libs/sdk-core/src/lnurl/pay.rs index 596b668f7..f02745919 100644 --- a/libs/sdk-core/src/lnurl/pay.rs +++ b/libs/sdk-core/src/lnurl/pay.rs @@ -28,12 +28,12 @@ pub(crate) async fn validate_lnurl_pay( )?; let callback_url = build_pay_callback_url(user_amount_sat, &comment, &req_data)?; - let callback_resp_text = reqwest::get(&callback_url).await?.text().await?; + let callback_resp_text = get_and_log_response(&callback_url).await?; if let Ok(err) = serde_json::from_str::(&callback_resp_text) { Ok(ValidatedCallbackResponse::EndpointError { data: err }) } else { - let callback_resp: CallbackResponse = reqwest::get(&callback_url).await?.json().await?; + let callback_resp: CallbackResponse = serde_json::from_str(&callback_resp_text)?; if let Some(ref sa) = callback_resp.success_action { match sa { SuccessAction::Aes(data) => data.validate()?, diff --git a/libs/sdk-core/src/lnurl/withdraw.rs b/libs/sdk-core/src/lnurl/withdraw.rs index 879c147be..ce7e7df98 100644 --- a/libs/sdk-core/src/lnurl/withdraw.rs +++ b/libs/sdk-core/src/lnurl/withdraw.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use crate::input_parser::get_parse_and_log_response; use crate::{lnurl::*, LnUrlCallbackStatus}; use crate::{LNInvoice, LnUrlWithdrawRequestData}; use anyhow::{anyhow, Result}; @@ -29,9 +30,7 @@ pub(crate) async fn validate_lnurl_withdraw( )), _ => { let callback_url = build_withdraw_callback_url(&req_data, &invoice)?; - let callback_resp_text = reqwest::get(&callback_url).await?.text().await?; - - serde_json::from_str::(&callback_resp_text).map_err(|e| anyhow!(e)) + get_parse_and_log_response(&callback_url).await } } }