From df0de05571ef3ee9aa397118729400122f8277c7 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Sat, 17 May 2025 20:00:49 +0100 Subject: [PATCH] fix: get spendable to return witness (#756) --- crates/cashu/src/nuts/nut07.rs | 3 +- crates/cdk/src/mint/check_spendable.rs | 42 ++++++++++++++++---------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/crates/cashu/src/nuts/nut07.rs b/crates/cashu/src/nuts/nut07.rs index 00f10753..88cc2287 100644 --- a/crates/cashu/src/nuts/nut07.rs +++ b/crates/cashu/src/nuts/nut07.rs @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use super::nut01::PublicKey; +use super::Witness; /// NUT07 Error #[derive(Debug, Error, PartialEq, Eq)] @@ -89,7 +90,7 @@ pub struct ProofState { /// State of proof pub state: State, /// Witness data if it is supplied - pub witness: Option, + pub witness: Option, } impl From<(PublicKey, State)> for ProofState { diff --git a/crates/cdk/src/mint/check_spendable.rs b/crates/cdk/src/mint/check_spendable.rs index 10693b56..f44f3129 100644 --- a/crates/cdk/src/mint/check_spendable.rs +++ b/crates/cdk/src/mint/check_spendable.rs @@ -1,5 +1,6 @@ use std::collections::{HashMap, HashSet}; +use futures::future::try_join_all; use tracing::instrument; use super::{CheckStateRequest, CheckStateResponse, Mint, ProofState, PublicKey, State}; @@ -33,6 +34,7 @@ impl Mint { Ok(()) } + /// Check state #[instrument(skip_all)] pub async fn check_state( @@ -40,25 +42,33 @@ impl Mint { check_state: &CheckStateRequest, ) -> Result { let states = self.localstore.get_proofs_states(&check_state.ys).await?; + assert_eq!(check_state.ys.len(), states.len()); - let states = states - .iter() - .zip(&check_state.ys) - .map(|(state, y)| { - let state = match state { - Some(state) => *state, - None => State::Unspent, - }; + let proof_states_futures = + check_state + .ys + .iter() + .zip(states.iter()) + .map(|(y, state)| async move { + let witness: Result, Error> = if state.is_some() { + let proofs = self.localstore.get_proofs_by_ys(&[*y]).await?; + Ok(proofs.first().cloned().flatten().and_then(|p| p.witness)) + } else { + Ok(None) + }; - ProofState { - y: *y, - state, - witness: None, - } - }) - .collect(); + witness.map(|w| ProofState { + y: *y, + state: state.unwrap_or(State::Unspent), + witness: w, + }) + }); - Ok(CheckStateResponse { states }) + let proof_states = try_join_all(proof_states_futures).await?; + + Ok(CheckStateResponse { + states: proof_states, + }) } /// Check Tokens are not spent or pending