Browse Source

feat: return change in check quote

thesimplekid 5 months ago
parent
commit
ca6fdb5bff

+ 30 - 0
crates/cdk-redb/src/mint/mod.rs

@@ -779,4 +779,34 @@ impl MintDatabase for MintRedbDatabase {
             None => Ok(None),
         }
     }
+
+    /// Get [`BlindSignature`]s for quote
+    async fn get_blind_signatures_for_quote(
+        &self,
+        quote_id: &str,
+    ) -> Result<Vec<BlindSignature>, Self::Err> {
+        let read_txn = self.db.begin_read().map_err(Error::from)?;
+        let quote_proofs_table = read_txn
+            .open_multimap_table(QUOTE_PROOFS_TABLE)
+            .map_err(Error::from)?;
+
+        let ys = quote_proofs_table.get(quote_id).unwrap();
+
+        let ys: Vec<[u8; 33]> = ys.into_iter().flatten().map(|v| v.value()).collect();
+
+        let mut signatures = Vec::new();
+
+        let signatures_table = read_txn
+            .open_table(BLINDED_SIGNATURES)
+            .map_err(Error::from)?;
+
+        for y in ys {
+            if let Some(sig) = signatures_table.get(y).map_err(Error::from)? {
+                let sig = serde_json::from_str(sig.value())?;
+                signatures.push(sig);
+            }
+        }
+
+        Ok(signatures)
+    }
 }

+ 31 - 0
crates/cdk-sqlite/src/mint/mod.rs

@@ -1202,6 +1202,37 @@ WHERE id=?;
             },
         }
     }
+
+    /// Get [`BlindSignature`]s for quote
+    async fn get_blind_signatures_for_quote(
+        &self,
+        quote_id: &str,
+    ) -> Result<Vec<BlindSignature>, Self::Err> {
+        let mut transaction = self.pool.begin().await.map_err(Error::from)?;
+
+        let mut signatures = Vec::new();
+
+        let rec = sqlx::query(
+            r#"
+SELECT *
+FROM blind_signature
+WHERE quote_id=?;
+        "#,
+        )
+        .bind(quote_id)
+        .fetch_one(&mut transaction)
+        .await;
+
+        if let Ok(row) = rec {
+            let blinded = sqlite_row_to_blind_signature(row)?;
+
+            signatures.push(blinded);
+        }
+
+        transaction.commit().await.map_err(Error::from)?;
+
+        Ok(signatures)
+    }
 }
 
 fn sqlite_row_to_keyset_info(row: SqliteRow) -> Result<MintKeySetInfo, Error> {

+ 10 - 0
crates/cdk/src/cdk_database/mint_memory.rs

@@ -407,4 +407,14 @@ impl MintDatabase for MintMemoryDatabase {
             .cloned()
             .collect())
     }
+
+    /// Get [`BlindSignature`]s for quote
+    async fn get_blind_signatures_for_quote(
+        &self,
+        quote_id: &str,
+    ) -> Result<Vec<BlindSignature>, Self::Err> {
+        let ys = self.quote_signatures.read().await;
+
+        Ok(ys.get(quote_id).cloned().unwrap_or_default())
+    }
 }

+ 5 - 0
crates/cdk/src/cdk_database/mod.rs

@@ -280,4 +280,9 @@ pub trait MintDatabase {
         &self,
         keyset_id: &Id,
     ) -> Result<Vec<BlindSignature>, Self::Err>;
+    /// Get [`BlindSignature`]s for quote
+    async fn get_blind_signatures_for_quote(
+        &self,
+        quote_id: &str,
+    ) -> Result<Vec<BlindSignature>, Self::Err>;
 }

+ 8 - 1
crates/cdk/src/mint/mod.rs

@@ -608,6 +608,13 @@ impl Mint {
             .await?
             .ok_or(Error::UnknownQuote)?;
 
+        let blind_signatures = self
+            .localstore
+            .get_blind_signatures_for_quote(quote_id)
+            .await?;
+
+        let change = blind_signatures.is_empty().then_some(blind_signatures);
+
         Ok(MeltQuoteBolt11Response {
             quote: quote.id,
             paid: Some(quote.state == QuoteState::Paid),
@@ -616,7 +623,7 @@ impl Mint {
             amount: quote.amount,
             fee_reserve: quote.fee_reserve,
             payment_preimage: quote.payment_preimage,
-            change: None,
+            change,
         })
     }