feat: select proofs from localstore

This commit is contained in:
thesimplekid
2024-01-01 21:52:31 +00:00
parent 762870073f
commit 7df07731c9

View File

@@ -1,5 +1,5 @@
//! Cashu Wallet
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::str::FromStr;
use bip39::Mnemonic;
@@ -7,15 +7,14 @@ use cashu::dhke::{construct_proofs, unblind_message};
#[cfg(feature = "nut07")]
use cashu::nuts::nut00::mint;
use cashu::nuts::{
BlindedSignature, CurrencyUnit, Id, Keys, PreMintSecrets, PreSwap, Proof, Proofs, SwapRequest,
Token,
BlindedSignature, CurrencyUnit, Id, KeySetInfo, Keys, PreMintSecrets, PreSwap, Proof, Proofs,
SwapRequest, Token,
};
#[cfg(feature = "nut07")]
use cashu::types::ProofsStatus;
use cashu::types::{MeltQuote, Melted, MintQuote, SendProofs};
use cashu::url::UncheckedUrl;
use cashu::Amount;
pub use cashu::Bolt11Invoice;
use cashu::{Amount, Bolt11Invoice};
use thiserror::Error;
use tracing::warn;
@@ -495,13 +494,64 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {
Ok(quote)
}
// Select proofs
async fn select_proofs(
&self,
mint_url: UncheckedUrl,
unit: &CurrencyUnit,
amount: Amount,
) -> Result<Proofs, Error> {
let mint_proofs = self
.localstore
.get_proofs(mint_url.clone())
.await?
.ok_or(Error::InsufficientFunds)?;
let mint_keysets = self.localstore.get_mint_keysets(mint_url).await?.unwrap();
let (active, inactive): (HashSet<KeySetInfo>, HashSet<KeySetInfo>) = mint_keysets
.into_iter()
.filter(|p| p.unit.eq(unit))
.partition(|x| x.active);
let active: HashSet<Id> = active.iter().map(|k| k.id).collect();
let inactive: HashSet<Id> = inactive.iter().map(|k| k.id).collect();
let mut active_proofs: Proofs = Vec::new();
let mut inactive_proofs: Proofs = Vec::new();
for proof in mint_proofs {
if active.contains(&proof.keyset_id) {
active_proofs.push(proof);
} else if inactive.contains(&proof.keyset_id) {
inactive_proofs.push(proof);
}
}
active_proofs.reverse();
inactive_proofs.reverse();
inactive_proofs.append(&mut active_proofs);
let proofs = inactive_proofs;
let mut selected_proofs: Proofs = Vec::new();
for proof in proofs {
if selected_proofs.iter().map(|p| p.amount).sum::<Amount>() < amount {
selected_proofs.push(proof);
}
}
if selected_proofs.iter().map(|p| p.amount).sum::<Amount>() < amount {
return Err(Error::InsufficientFunds);
}
Ok(selected_proofs)
}
/// Melt
pub async fn melt(
&mut self,
mint_url: &UncheckedUrl,
quote_id: &str,
proofs: Proofs,
) -> Result<Melted, Error> {
pub async fn melt(&mut self, mint_url: &UncheckedUrl, quote_id: &str) -> Result<Melted, Error> {
let quote_info = self.localstore.get_melt_quote(quote_id).await?;
let quote_info = if let Some(quote) = quote_info {
@@ -521,6 +571,10 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {
quote_info.fee_reserve,
)?;
let proofs = self
.select_proofs(mint_url.clone(), &quote_info.unit, quote_info.amount)
.await?;
let melt_response = self
.client
.post_melt(