mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-05 05:06:14 +01:00
feat: select proofs from localstore
This commit is contained in:
@@ -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(), "e_info.unit, quote_info.amount)
|
||||
.await?;
|
||||
|
||||
let melt_response = self
|
||||
.client
|
||||
.post_melt(
|
||||
|
||||
Reference in New Issue
Block a user