diff --git a/crates/cdk-integration-tests/tests/fake_wallet.rs b/crates/cdk-integration-tests/tests/fake_wallet.rs index e120a4a2..9b6f3ddb 100644 --- a/crates/cdk-integration-tests/tests/fake_wallet.rs +++ b/crates/cdk-integration-tests/tests/fake_wallet.rs @@ -104,7 +104,7 @@ async fn test_fake_melt_payment_fail() -> Result<()> { assert!(melt.is_err()); // The mint should have unset proofs from pending since payment failed - let all_proof = wallet.get_proofs().await?; + let all_proof = wallet.get_unspent_proofs().await?; let states = wallet.check_proofs_spent(all_proof).await?; for state in states { assert!(state.state == State::Unspent); @@ -344,7 +344,7 @@ async fn test_fake_melt_change_in_quote() -> Result<()> { let invoice = create_fake_invoice(9000, serde_json::to_string(&fake_description).unwrap()); - let proofs = wallet.get_proofs().await?; + let proofs = wallet.get_unspent_proofs().await?; let melt_quote = wallet.melt_quote(invoice.to_string(), None).await?; diff --git a/crates/cdk-integration-tests/tests/regtest.rs b/crates/cdk-integration-tests/tests/regtest.rs index 5658fb57..c10d5ffe 100644 --- a/crates/cdk-integration-tests/tests/regtest.rs +++ b/crates/cdk-integration-tests/tests/regtest.rs @@ -111,7 +111,7 @@ async fn test_restore() -> Result<()> { assert!(wallet_2.total_balance().await? == 0.into()); let restored = wallet_2.restore().await?; - let proofs = wallet_2.get_proofs().await?; + let proofs = wallet_2.get_unspent_proofs().await?; wallet_2 .swap(None, SplitTarget::default(), proofs, None, false) @@ -121,7 +121,7 @@ async fn test_restore() -> Result<()> { assert!(wallet_2.total_balance().await? == 100.into()); - let proofs = wallet.get_proofs().await?; + let proofs = wallet.get_unspent_proofs().await?; let states = wallet.check_proofs_spent(proofs).await?; diff --git a/crates/cdk/examples/proof-selection.rs b/crates/cdk/examples/proof-selection.rs index 46d687a2..210b7731 100644 --- a/crates/cdk/examples/proof-selection.rs +++ b/crates/cdk/examples/proof-selection.rs @@ -48,7 +48,7 @@ async fn main() { println!("Minted {}", receive_amount); } - let proofs = wallet.get_proofs().await.unwrap(); + let proofs = wallet.get_unspent_proofs().await.unwrap(); let selected = wallet .select_proofs_to_send(Amount::from(64), proofs, false) diff --git a/crates/cdk/src/wallet/balance.rs b/crates/cdk/src/wallet/balance.rs index 8fe277b9..6d127646 100644 --- a/crates/cdk/src/wallet/balance.rs +++ b/crates/cdk/src/wallet/balance.rs @@ -2,44 +2,24 @@ use std::collections::HashMap; use tracing::instrument; -use crate::{ - nuts::{CurrencyUnit, State}, - Amount, Error, Wallet, -}; +use crate::nuts::nut00::ProofsMethods; +use crate::{nuts::CurrencyUnit, Amount, Error, Wallet}; impl Wallet { /// Total unspent balance of wallet #[instrument(skip(self))] pub async fn total_balance(&self) -> Result { - let proofs = self - .localstore - .get_proofs( - Some(self.mint_url.clone()), - Some(self.unit), - Some(vec![State::Unspent]), - None, - ) - .await?; - let balance = Amount::try_sum(proofs.iter().map(|p| p.proof.amount))?; - - Ok(balance) + Ok(self.get_unspent_proofs().await?.total_amount()?) } /// Total pending balance #[instrument(skip(self))] pub async fn total_pending_balance(&self) -> Result, Error> { - let proofs = self - .localstore - .get_proofs( - Some(self.mint_url.clone()), - Some(self.unit), - Some(vec![State::Pending]), - None, - ) - .await?; + let proofs = self.get_pending_proofs().await?; + // TODO If only the proofs for this wallet's unit are retrieved, why build a map with key = unit? let balances = proofs.iter().fold(HashMap::new(), |mut acc, proof| { - *acc.entry(proof.unit).or_insert(Amount::ZERO) += proof.proof.amount; + *acc.entry(self.unit).or_insert(Amount::ZERO) += proof.amount; acc }); @@ -49,18 +29,11 @@ impl Wallet { /// Total reserved balance #[instrument(skip(self))] pub async fn total_reserved_balance(&self) -> Result, Error> { - let proofs = self - .localstore - .get_proofs( - Some(self.mint_url.clone()), - Some(self.unit), - Some(vec![State::Reserved]), - None, - ) - .await?; + let proofs = self.get_reserved_proofs().await?; + // TODO If only the proofs for this wallet's unit are retrieved, why build a map with key = unit? let balances = proofs.iter().fold(HashMap::new(), |mut acc, proof| { - *acc.entry(proof.unit).or_insert(Amount::ZERO) += proof.proof.amount; + *acc.entry(self.unit).or_insert(Amount::ZERO) += proof.amount; acc }); diff --git a/crates/cdk/src/wallet/melt.rs b/crates/cdk/src/wallet/melt.rs index 6d0f709b..c31f2ff4 100644 --- a/crates/cdk/src/wallet/melt.rs +++ b/crates/cdk/src/wallet/melt.rs @@ -286,7 +286,7 @@ impl Wallet { let inputs_needed_amount = quote_info.amount + quote_info.fee_reserve; - let available_proofs = self.get_proofs().await?; + let available_proofs = self.get_unspent_proofs().await?; let input_proofs = self .select_proofs_to_swap(inputs_needed_amount, available_proofs) diff --git a/crates/cdk/src/wallet/mod.rs b/crates/cdk/src/wallet/mod.rs index c0488c2f..85045eaa 100644 --- a/crates/cdk/src/wallet/mod.rs +++ b/crates/cdk/src/wallet/mod.rs @@ -181,7 +181,7 @@ impl Wallet { /// Get amounts needed to refill proof state #[instrument(skip(self))] pub async fn amounts_needed_for_state_target(&self) -> Result, Error> { - let unspent_proofs = self.get_proofs().await?; + let unspent_proofs = self.get_unspent_proofs().await?; let amounts_count: HashMap = unspent_proofs diff --git a/crates/cdk/src/wallet/multi_mint_wallet.rs b/crates/cdk/src/wallet/multi_mint_wallet.rs index 6f3c3334..8d26e9e4 100644 --- a/crates/cdk/src/wallet/multi_mint_wallet.rs +++ b/crates/cdk/src/wallet/multi_mint_wallet.rs @@ -125,7 +125,7 @@ impl MultiMintWallet { let mut mint_proofs = BTreeMap::new(); for (WalletKey { mint_url, unit: u }, wallet) in self.wallets.lock().await.iter() { - let wallet_proofs = wallet.get_proofs().await?; + let wallet_proofs = wallet.get_unspent_proofs().await?; mint_proofs.insert(mint_url.clone(), (wallet_proofs, *u)); } Ok(mint_proofs) diff --git a/crates/cdk/src/wallet/proofs.rs b/crates/cdk/src/wallet/proofs.rs index 5ea4f53b..12fed0ef 100644 --- a/crates/cdk/src/wallet/proofs.rs +++ b/crates/cdk/src/wallet/proofs.rs @@ -5,7 +5,7 @@ use tracing::instrument; use crate::nuts::nut00::ProofsMethods; use crate::{ amount::SplitTarget, - nuts::{Proof, ProofState, Proofs, PublicKey, State}, + nuts::{Proof, ProofState, Proofs, PublicKey, SpendingConditions, State}, types::ProofInfo, Amount, Error, Wallet, }; @@ -13,48 +13,36 @@ use crate::{ impl Wallet { /// Get unspent proofs for mint #[instrument(skip(self))] - pub async fn get_proofs(&self) -> Result { - Ok(self - .localstore - .get_proofs( - Some(self.mint_url.clone()), - Some(self.unit), - Some(vec![State::Unspent]), - None, - ) - .await? - .into_iter() - .map(|p| p.proof) - .collect()) + pub async fn get_unspent_proofs(&self) -> Result { + self.get_proofs_with(Some(vec![State::Unspent]), None).await } /// Get pending [`Proofs`] #[instrument(skip(self))] pub async fn get_pending_proofs(&self) -> Result { - Ok(self - .localstore - .get_proofs( - Some(self.mint_url.clone()), - Some(self.unit), - Some(vec![State::Pending]), - None, - ) - .await? - .into_iter() - .map(|p| p.proof) - .collect()) + self.get_proofs_with(Some(vec![State::Pending]), None).await } /// Get reserved [`Proofs`] #[instrument(skip(self))] pub async fn get_reserved_proofs(&self) -> Result { + self.get_proofs_with(Some(vec![State::Reserved]), None) + .await + } + + /// Get this wallet's [Proofs] that match the args + pub async fn get_proofs_with( + &self, + state: Option>, + spending_conditions: Option>, + ) -> Result { Ok(self .localstore .get_proofs( Some(self.mint_url.clone()), Some(self.unit), - Some(vec![State::Reserved]), - None, + state, + spending_conditions, ) .await? .into_iter() diff --git a/crates/cdk/src/wallet/send.rs b/crates/cdk/src/wallet/send.rs index f9a62b9a..7885db5c 100644 --- a/crates/cdk/src/wallet/send.rs +++ b/crates/cdk/src/wallet/send.rs @@ -43,19 +43,14 @@ impl Wallet { } } - let mint_url = &self.mint_url; - let unit = &self.unit; let available_proofs = self - .localstore - .get_proofs( - Some(mint_url.clone()), - Some(*unit), + .get_proofs_with( Some(vec![State::Unspent]), conditions.clone().map(|c| vec![c]), ) .await?; - let (available_proofs, proofs_sum) = available_proofs.into_iter().map(|p| p.proof).fold( + let (available_proofs, proofs_sum) = available_proofs.into_iter().fold( (Vec::new(), Amount::ZERO), |(mut acc1, mut acc2), p| { acc2 += p.amount; @@ -66,20 +61,9 @@ impl Wallet { let available_proofs = if proofs_sum < amount { match &conditions { Some(conditions) => { - let available_proofs = self - .localstore - .get_proofs( - Some(mint_url.clone()), - Some(*unit), - Some(vec![State::Unspent]), - None, - ) - .await?; - - let available_proofs = available_proofs.into_iter().map(|p| p.proof).collect(); + let unspent_proofs = self.get_unspent_proofs().await?; - let proofs_to_swap = - self.select_proofs_to_swap(amount, available_proofs).await?; + let proofs_to_swap = self.select_proofs_to_swap(amount, unspent_proofs).await?; let proofs_with_conditions = self .swap( @@ -90,12 +74,10 @@ impl Wallet { include_fees, ) .await?; - proofs_with_conditions.ok_or(Error::InsufficientFunds)? + proofs_with_conditions.ok_or(Error::InsufficientFunds) } - None => { - return Err(Error::InsufficientFunds); - } - } + None => Err(Error::InsufficientFunds), + }? } else { available_proofs };