diff --git a/crates/cashu-sdk/src/client/minreq_client.rs b/crates/cashu-sdk/src/client/minreq_client.rs index d01c589d..4f2ec562 100644 --- a/crates/cashu-sdk/src/client/minreq_client.rs +++ b/crates/cashu-sdk/src/client/minreq_client.rs @@ -1,5 +1,7 @@ //! Minreq http Client +use std::println; + use async_trait::async_trait; use cashu::nuts::nut00::wallet::BlindedMessages; use cashu::nuts::nut00::{BlindedMessage, Proof}; @@ -16,6 +18,7 @@ use cashu::nuts::MintInfo; use cashu::nuts::*; use cashu::{Amount, Bolt11Invoice}; use serde_json::Value; +use tracing::debug; use url::Url; use super::join_url; @@ -161,17 +164,16 @@ impl Client for HttpClient { ) -> Result { let url = join_url(mint_url, "split")?; - let res = minreq::post(url) - .with_json(&split_request)? - .send()? - .json::()?; + let res = minreq::post(url).with_json(&split_request)?.send()?; + + println!("{:?}", res); let response: Result = - serde_json::from_value(res.clone()); + serde_json::from_value(res.json::()?.clone()); match response { Ok(res) if res.promises.is_some() => Ok(res), - _ => Err(Error::from_json(&res.to_string())?), + _ => Err(Error::from_json(&res.json::()?.to_string())?), } } diff --git a/crates/cashu-sdk/src/client/mod.rs b/crates/cashu-sdk/src/client/mod.rs index 4d8693b8..a2aaeef0 100644 --- a/crates/cashu-sdk/src/client/mod.rs +++ b/crates/cashu-sdk/src/client/mod.rs @@ -52,23 +52,27 @@ pub enum Error { impl Error { pub fn from_json(json: &str) -> Result { - let mint_res: MintErrorResponse = serde_json::from_str(json)?; + if let Ok(mint_res) = serde_json::from_str::(json) { + let err = mint_res + .error + .as_deref() + .or(mint_res.detail.as_deref()) + .unwrap_or_default(); - let err = mint_res - .error - .as_deref() - .or(mint_res.detail.as_deref()) - .unwrap_or_default(); - - let mint_error = match err { - error if error.starts_with("Lightning invoice not paid yet.") => Error::InvoiceNotPaid, - error if error.starts_with("Lightning wallet not responding") => { - let mint = utils::extract_url_from_error(error); - Error::LightingWalletNotResponding(mint) - } - error => Error::Custom(error.to_owned()), - }; - Ok(mint_error) + let mint_error = match err { + error if error.starts_with("Lightning invoice not paid yet.") => { + Error::InvoiceNotPaid + } + error if error.starts_with("Lightning wallet not responding") => { + let mint = utils::extract_url_from_error(error); + Error::LightingWalletNotResponding(mint) + } + error => Error::Custom(error.to_owned()), + }; + Ok(mint_error) + } else { + Ok(Error::Custom(json.to_string())) + } } } diff --git a/crates/cashu-sdk/src/wallet.rs b/crates/cashu-sdk/src/wallet.rs index af8493b1..6dc4884c 100644 --- a/crates/cashu-sdk/src/wallet.rs +++ b/crates/cashu-sdk/src/wallet.rs @@ -147,7 +147,7 @@ impl Wallet { // Sum amount of all proofs let _amount: Amount = token.proofs.iter().map(|p| p.amount).sum(); - let split_payload = self.create_split(token.proofs)?; + let split_payload = self.create_split(None, token.proofs)?; let split_response = self .client @@ -175,15 +175,26 @@ impl Wallet { } /// Create Split Payload - fn create_split(&self, proofs: Proofs) -> Result { - let mut proofs = proofs; + /// TODO: This needs to sort to avoid finer printing + fn create_split(&self, amount: Option, proofs: Proofs) -> Result { + let proofs = proofs; - // Sort proofs in ascending order to avoid fingerprinting - proofs.sort(); + // Since split is used to get the needed combination of tokens for a specific + // amount first blinded messages are created for the amount - let value = proofs.iter().map(|p| p.amount).sum(); + let blinded_messages = if let Some(amount) = amount { + let mut desired_messages = BlindedMessages::random(amount)?; - let blinded_messages = BlindedMessages::random(value)?; + let change_amount = proofs.iter().map(|p| p.amount).sum::() - amount; + + let change_messages = BlindedMessages::random(change_amount)?; + desired_messages.combine(change_messages); + desired_messages + } else { + let value = proofs.iter().map(|p| p.amount).sum(); + + BlindedMessages::random(value)? + }; let split_payload = SplitRequest::new(proofs, blinded_messages.blinded_messages.clone()); @@ -240,7 +251,7 @@ impl Wallet { return Err(Error::InsufficientFunds); } - let split_payload = self.create_split(proofs)?; + let split_payload = self.create_split(Some(amount), proofs)?; let split_response = self .client diff --git a/crates/cashu/src/nuts/nut00.rs b/crates/cashu/src/nuts/nut00.rs index cd939d6b..f290ff47 100644 --- a/crates/cashu/src/nuts/nut00.rs +++ b/crates/cashu/src/nuts/nut00.rs @@ -97,6 +97,13 @@ pub mod wallet { Ok(blinded_messages) } + + pub fn combine(&mut self, mut other: Self) { + self.blinded_messages.append(&mut other.blinded_messages); + self.secrets.append(&mut other.secrets); + self.rs.append(&mut other.rs); + self.amounts.append(&mut other.amounts); + } } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]