Skip to content

Commit

Permalink
Merge pull request #396 from breez/ok300-lnurl-log-payloads
Browse files Browse the repository at this point in the history
Add optional logging of reqwest raw payloads
  • Loading branch information
ok300 authored Sep 15, 2023
2 parents c965851 + 784fc81 commit cd37b10
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 32 deletions.
6 changes: 2 additions & 4 deletions libs/sdk-core/src/boltzswap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::ReverseSwapServiceAPI;
Expand Down Expand Up @@ -232,10 +233,7 @@ impl ReverseSwapServiceAPI for BoltzApi {
}

pub async fn reverse_swap_pair_info() -> Result<ReverseSwapPairInfo> {
let pairs = reqwest::get(GET_PAIRS_ENDPOINT)
.await?
.json::<Pairs>()
.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) => {
Expand Down
6 changes: 6 additions & 0 deletions libs/sdk-core/src/breez_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,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.
Expand All @@ -1157,6 +1162,7 @@ impl BreezServices {
.parse_filters(
r#"
info,
breez_sdk_core::input_parser=warn,
gl_client=warn,
h2=warn,
hyper=warn,
Expand Down
23 changes: 4 additions & 19 deletions libs/sdk-core/src/chain.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -198,31 +199,15 @@ impl MempoolSpace {
#[tonic::async_trait]
impl ChainService for MempoolSpace {
async fn recommended_fees(&self) -> Result<RecommendedFees> {
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<Vec<OnchainTx>> {
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<u32> {
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
}

/// If successful, it returns the transaction ID. Otherwise returns an `Err` describing the error.
Expand Down
24 changes: 23 additions & 1 deletion libs/sdk-core/src/input_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ pub async fn parse(input: &str) -> Result<InputType> {
}

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
Expand All @@ -227,6 +227,28 @@ pub async fn parse(input: &str) -> Result<InputType> {
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<String> {
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<T>(url: &str) -> Result<T>
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))
Expand Down
5 changes: 2 additions & 3 deletions libs/sdk-core/src/lnurl/auth.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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::<LnUrlCallbackStatus>(&callback_resp_text).map_err(|e| anyhow!(e))
get_parse_and_log_response(callback_url.as_ref()).await
}

pub(crate) fn validate_request(
Expand Down
4 changes: 2 additions & 2 deletions libs/sdk-core/src/lnurl/pay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<LnUrlErrorData>(&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()?,
Expand Down
5 changes: 2 additions & 3 deletions libs/sdk-core/src/lnurl/withdraw.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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::<LnUrlCallbackStatus>(&callback_resp_text).map_err(|e| anyhow!(e))
get_parse_and_log_response(&callback_url).await
}
}
}
Expand Down

0 comments on commit cd37b10

Please sign in to comment.