Skip to content

Commit

Permalink
Consolidate Wallet::get_proofs variants
Browse files Browse the repository at this point in the history
  • Loading branch information
ok300 committed Oct 27, 2024
1 parent 09b5a55 commit 6a567ec
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 97 deletions.
4 changes: 2 additions & 2 deletions crates/cdk-integration-tests/tests/fake_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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?;

Expand Down
4 changes: 2 additions & 2 deletions crates/cdk-integration-tests/tests/regtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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?;

Expand Down
2 changes: 1 addition & 1 deletion crates/cdk/examples/proof-selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
45 changes: 9 additions & 36 deletions crates/cdk/src/wallet/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Amount, Error> {
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<HashMap<CurrencyUnit, Amount>, 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
});

Expand All @@ -49,18 +29,11 @@ impl Wallet {
/// Total reserved balance
#[instrument(skip(self))]
pub async fn total_reserved_balance(&self) -> Result<HashMap<CurrencyUnit, Amount>, 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
});

Expand Down
2 changes: 1 addition & 1 deletion crates/cdk/src/wallet/melt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion crates/cdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec<Amount>, Error> {
let unspent_proofs = self.get_proofs().await?;
let unspent_proofs = self.get_unspent_proofs().await?;

let amounts_count: HashMap<usize, usize> =
unspent_proofs
Expand Down
2 changes: 1 addition & 1 deletion crates/cdk/src/wallet/multi_mint_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
44 changes: 16 additions & 28 deletions crates/cdk/src/wallet/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,44 @@ 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,
};

impl Wallet {
/// Get unspent proofs for mint
#[instrument(skip(self))]
pub async fn get_proofs(&self) -> Result<Proofs, Error> {
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<Proofs, Error> {
self.get_proofs_with(Some(vec![State::Unspent]), None).await
}

/// Get pending [`Proofs`]
#[instrument(skip(self))]
pub async fn get_pending_proofs(&self) -> Result<Proofs, Error> {
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<Proofs, Error> {
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<Vec<State>>,
spending_conditions: Option<Vec<SpendingConditions>>,
) -> Result<Proofs, Error> {
Ok(self
.localstore
.get_proofs(
Some(self.mint_url.clone()),
Some(self.unit),
Some(vec![State::Reserved]),
None,
state,
spending_conditions,
)
.await?
.into_iter()
Expand Down
32 changes: 7 additions & 25 deletions crates/cdk/src/wallet/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(
Expand All @@ -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
};
Expand Down

0 comments on commit 6a567ec

Please sign in to comment.