From 21a5ac94069d35b2ef416c7f18cd72e142f55fc8 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Sat, 7 Jun 2025 17:23:00 +0100 Subject: [PATCH] feat(cli): enhance check-pending to reclaim proofs (#795) * feat(cli): enhance check-pending to reclaim proofs The check-pending command now directly attempts to reclaim proofs that are no longer pending, replacing the previous check-only behavior. Changes: - Replace check_all_pending_proofs with reclaim_unspent functionality - Add more detailed feedback about pending proof status - Update command description to reflect new reclaim behavior - Improve error handling and status reporting This change makes the command more useful by actively reclaiming proofs rather than just checking their status. * refactor: remove CheckSpendable command and check_spent module The CheckSpendable command and its associated check_spent.rs module have been removed as their functionality is redundant with the CheckPending command. --- crates/cdk-cli/src/main.rs | 8 +-- .../cdk-cli/src/sub_commands/check_pending.rs | 33 ++++++++++++ .../cdk-cli/src/sub_commands/check_spent.rs | 12 ----- .../src/sub_commands/list_mint_proofs.rs | 54 ++++++++++++++----- crates/cdk-cli/src/sub_commands/mod.rs | 2 +- 5 files changed, 79 insertions(+), 30 deletions(-) create mode 100644 crates/cdk-cli/src/sub_commands/check_pending.rs delete mode 100644 crates/cdk-cli/src/sub_commands/check_spent.rs diff --git a/crates/cdk-cli/src/main.rs b/crates/cdk-cli/src/main.rs index 7ce12b22..cd59f07b 100644 --- a/crates/cdk-cli/src/main.rs +++ b/crates/cdk-cli/src/main.rs @@ -65,8 +65,8 @@ enum Commands { Receive(sub_commands::receive::ReceiveSubCommand), /// Send Send(sub_commands::send::SendSubCommand), - /// Check if wallet balance is spendable - CheckSpendable, + /// Reclaim pending proofs that are no longer pending + CheckPending, /// View mint info MintInfo(sub_commands::mint_info::MintInfoSubcommand), /// Mint proofs via bolt11 @@ -215,8 +215,8 @@ async fn main() -> Result<()> { Commands::Send(sub_command_args) => { sub_commands::send::send(&multi_mint_wallet, sub_command_args).await } - Commands::CheckSpendable => { - sub_commands::check_spent::check_spent(&multi_mint_wallet).await + Commands::CheckPending => { + sub_commands::check_pending::check_pending(&multi_mint_wallet).await } Commands::MintInfo(sub_command_args) => { sub_commands::mint_info::mint_info(args.proxy, sub_command_args).await diff --git a/crates/cdk-cli/src/sub_commands/check_pending.rs b/crates/cdk-cli/src/sub_commands/check_pending.rs new file mode 100644 index 00000000..437bee94 --- /dev/null +++ b/crates/cdk-cli/src/sub_commands/check_pending.rs @@ -0,0 +1,33 @@ +use anyhow::Result; +use cdk::nuts::nut00::ProofsMethods; +use cdk::wallet::multi_mint_wallet::MultiMintWallet; + +pub async fn check_pending(multi_mint_wallet: &MultiMintWallet) -> Result<()> { + let wallets = multi_mint_wallet.get_wallets().await; + + for (i, wallet) in wallets.iter().enumerate() { + let mint_url = wallet.mint_url.clone(); + println!("{i}: {mint_url}"); + + // Get all pending proofs + let pending_proofs = wallet.get_pending_proofs().await?; + if pending_proofs.is_empty() { + println!("No pending proofs found"); + continue; + } + + println!( + "Found {} pending proofs with {} {}", + pending_proofs.len(), + pending_proofs.total_amount()?, + wallet.unit + ); + + // Try to reclaim any proofs that are no longer pending + match wallet.reclaim_unspent(pending_proofs).await { + Ok(()) => println!("Successfully reclaimed pending proofs"), + Err(e) => println!("Error reclaimed pending proofs: {}", e), + } + } + Ok(()) +} diff --git a/crates/cdk-cli/src/sub_commands/check_spent.rs b/crates/cdk-cli/src/sub_commands/check_spent.rs deleted file mode 100644 index 96145e45..00000000 --- a/crates/cdk-cli/src/sub_commands/check_spent.rs +++ /dev/null @@ -1,12 +0,0 @@ -use anyhow::Result; -use cdk::wallet::MultiMintWallet; - -pub async fn check_spent(multi_mint_wallet: &MultiMintWallet) -> Result<()> { - for wallet in multi_mint_wallet.get_wallets().await { - let amount = wallet.check_all_pending_proofs().await?; - - println!("Amount marked as spent: {amount}"); - } - - Ok(()) -} diff --git a/crates/cdk-cli/src/sub_commands/list_mint_proofs.rs b/crates/cdk-cli/src/sub_commands/list_mint_proofs.rs index 754c301e..6cc04863 100644 --- a/crates/cdk-cli/src/sub_commands/list_mint_proofs.rs +++ b/crates/cdk-cli/src/sub_commands/list_mint_proofs.rs @@ -1,5 +1,3 @@ -use std::collections::BTreeMap; - use anyhow::Result; use cdk::mint_url::MintUrl; use cdk::nuts::{CurrencyUnit, Proof}; @@ -13,27 +11,57 @@ pub async fn proofs(multi_mint_wallet: &MultiMintWallet) -> Result<()> { async fn list_proofs( multi_mint_wallet: &MultiMintWallet, ) -> Result, CurrencyUnit))>> { - let wallets_proofs: BTreeMap, CurrencyUnit)> = - multi_mint_wallet.list_proofs().await?; + let mut proofs_vec = Vec::new(); - let mut proofs_vec = Vec::with_capacity(wallets_proofs.len()); + let wallets = multi_mint_wallet.get_wallets().await; - for (i, (mint_url, proofs)) in wallets_proofs.iter().enumerate() { - let mint_url = mint_url.clone(); + for (i, wallet) in wallets.iter().enumerate() { + let mint_url = wallet.mint_url.clone(); println!("{i}: {mint_url}"); - println!("| Amount | Unit | Secret | DLEQ proof included"); - println!("|----------|------|------------------------------------------------------------------|--------------------"); - for proof in &proofs.0 { + println!("| Amount | Unit | State | Secret | DLEQ proof included"); + println!("|----------|------|----------|------------------------------------------------------------------|--------------------"); + + // Unspent proofs + let unspent_proofs = wallet.get_unspent_proofs().await?; + for proof in unspent_proofs.iter() { println!( - "| {:8} | {:4} | {:64} | {}", + "| {:8} | {:4} | {:8} | {:64} | {}", proof.amount, - proofs.1, + wallet.unit, + "unspent", proof.secret, proof.dleq.is_some() ); } + + // Pending proofs + let pending_proofs = wallet.get_pending_proofs().await?; + for proof in pending_proofs { + println!( + "| {:8} | {:4} | {:8} | {:64} | {}", + proof.amount, + wallet.unit, + "pending", + proof.secret, + proof.dleq.is_some() + ); + } + + // Reserved proofs + let reserved_proofs = wallet.get_reserved_proofs().await?; + for proof in reserved_proofs { + println!( + "| {:8} | {:4} | {:8} | {:64} | {}", + proof.amount, + wallet.unit, + "reserved", + proof.secret, + proof.dleq.is_some() + ); + } + println!(); - proofs_vec.push((mint_url, proofs.clone())) + proofs_vec.push((mint_url, (unspent_proofs, wallet.unit.clone()))); } Ok(proofs_vec) } diff --git a/crates/cdk-cli/src/sub_commands/mod.rs b/crates/cdk-cli/src/sub_commands/mod.rs index 92cd9452..aaf1cb92 100644 --- a/crates/cdk-cli/src/sub_commands/mod.rs +++ b/crates/cdk-cli/src/sub_commands/mod.rs @@ -2,7 +2,7 @@ pub mod balance; pub mod burn; pub mod cat_device_login; pub mod cat_login; -pub mod check_spent; +pub mod check_pending; pub mod create_request; pub mod decode_request; pub mod decode_token;