浏览代码

Add get_mint_keysets to the tx trait

Cesar Rodas 1 月之前
父节点
当前提交
e4a75f1789

+ 7 - 1
crates/cdk-common/src/database/wallet.rs

@@ -23,7 +23,13 @@ use crate::wallet::{
 #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
 #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
 pub trait DatabaseTransaction<'a, Error>: DbTransactionFinalizer<Err = Error> {
 pub trait DatabaseTransaction<'a, Error>: DbTransactionFinalizer<Err = Error> {
     /// Get [`Keys`] from storage
     /// Get [`Keys`] from storage
-    async fn get_keys(&mut self, id: &Id) -> Result<Option<Keys>, Self::Err>;
+    async fn get_keys(&mut self, id: &Id) -> Result<Option<Keys>, Error>;
+
+    /// Get mint keysets for mint url
+    async fn get_mint_keysets(
+        &mut self,
+        mint_url: MintUrl,
+    ) -> Result<Option<Vec<KeySetInfo>>, Error>;
 
 
     /// Add Mint to storage
     /// Add Mint to storage
     async fn add_mint(
     async fn add_mint(

+ 13 - 0
crates/cdk-ffi/src/database.rs

@@ -198,6 +198,19 @@ impl<'a> cdk::cdk_database::WalletDatabaseTransaction<'a, cdk::cdk_database::Err
             .transpose()
             .transpose()
     }
     }
 
 
+    async fn get_mint_keysets(
+        &mut self,
+        mint_url: cdk::mint_url::MintUrl,
+    ) -> Result<Option<Vec<cdk::nuts::KeySetInfo>>, cdk::cdk_database::Error> {
+        let ffi_mint_url = mint_url.into();
+        let result = self
+            .ffi_db
+            .get_mint_keysets(ffi_mint_url)
+            .await
+            .map_err(|e| cdk::cdk_database::Error::Database(e.to_string().into()))?;
+        Ok(result.map(|keysets| keysets.into_iter().map(Into::into).collect()))
+    }
+
     async fn add_mint(
     async fn add_mint(
         &mut self,
         &mut self,
         mint_url: cdk::mint_url::MintUrl,
         mint_url: cdk::mint_url::MintUrl,

+ 42 - 2
crates/cdk-redb/src/wallet/mod.rs

@@ -16,7 +16,9 @@ use cdk_common::{
     database, CurrencyUnit, Id, KeySet, KeySetInfo, Keys, MintInfo, PublicKey, SpendingConditions,
     database, CurrencyUnit, Id, KeySet, KeySetInfo, Keys, MintInfo, PublicKey, SpendingConditions,
     State,
     State,
 };
 };
-use redb::{Database, MultimapTableDefinition, ReadableTable, TableDefinition};
+use redb::{
+    Database, MultimapTableDefinition, ReadableMultimapTable, ReadableTable, TableDefinition,
+};
 use tracing::instrument;
 use tracing::instrument;
 
 
 use super::error::Error;
 use super::error::Error;
@@ -486,7 +488,7 @@ impl<'a> cdk_common::database::WalletDatabaseTransaction<'a, database::Error>
     for RedbWalletTransaction
     for RedbWalletTransaction
 {
 {
     #[instrument(skip(self), fields(keyset_id = %keyset_id))]
     #[instrument(skip(self), fields(keyset_id = %keyset_id))]
-    async fn get_keys(&mut self, keyset_id: &Id) -> Result<Option<Keys>, Self::Err> {
+    async fn get_keys(&mut self, keyset_id: &Id) -> Result<Option<Keys>, database::Error> {
         let txn = self.txn().map_err(Into::<database::Error>::into)?;
         let txn = self.txn().map_err(Into::<database::Error>::into)?;
         let table = txn.open_table(MINT_KEYS_TABLE).map_err(Error::from)?;
         let table = txn.open_table(MINT_KEYS_TABLE).map_err(Error::from)?;
 
 
@@ -500,6 +502,44 @@ impl<'a> cdk_common::database::WalletDatabaseTransaction<'a, database::Error>
         Ok(None)
         Ok(None)
     }
     }
 
 
+    #[instrument(skip(self))]
+    async fn get_mint_keysets(
+        &mut self,
+        mint_url: MintUrl,
+    ) -> Result<Option<Vec<KeySetInfo>>, database::Error> {
+        let txn = self.txn().map_err(Into::<database::Error>::into)?;
+        let table = txn
+            .open_multimap_table(MINT_KEYSETS_TABLE)
+            .map_err(Error::from)?;
+
+        let keyset_ids = table
+            .get(mint_url.to_string().as_str())
+            .map_err(Error::from)?
+            .flatten()
+            .map(|k| Id::from_bytes(k.value()))
+            .collect::<Result<Vec<_>, _>>()?;
+
+        let mut keysets = vec![];
+
+        let keysets_t = txn.open_table(KEYSETS_TABLE).map_err(Error::from)?;
+
+        for keyset_id in keyset_ids {
+            if let Some(keyset) = keysets_t
+                .get(keyset_id.to_bytes().as_slice())
+                .map_err(Error::from)?
+            {
+                let keyset = serde_json::from_str(keyset.value()).map_err(Error::from)?;
+
+                keysets.push(keyset);
+            }
+        }
+
+        match keysets.is_empty() {
+            true => Ok(None),
+            false => Ok(Some(keysets)),
+        }
+    }
+
     #[instrument(skip(self, mint_info))]
     #[instrument(skip(self, mint_info))]
     async fn add_mint(
     async fn add_mint(
         &mut self,
         &mut self,

+ 31 - 0
crates/cdk-sql-common/src/wallet/mod.rs

@@ -173,6 +173,37 @@ where
         .transpose()?)
         .transpose()?)
     }
     }
 
 
+    #[instrument(skip(self))]
+    async fn get_mint_keysets(
+        &mut self,
+        mint_url: MintUrl,
+    ) -> Result<Option<Vec<KeySetInfo>>, Error> {
+        let keysets = query(
+            r#"
+            SELECT
+                id,
+                unit,
+                active,
+                input_fee_ppk,
+                final_expiry
+            FROM
+                keyset
+            WHERE mint_url = :mint_url
+            "#,
+        )?
+        .bind("mint_url", mint_url.to_string())
+        .fetch_all(&self.inner)
+        .await?
+        .into_iter()
+        .map(sql_row_to_keyset)
+        .collect::<Result<Vec<_>, Error>>()?;
+
+        match keysets.is_empty() {
+            false => Ok(Some(keysets)),
+            true => Ok(None),
+        }
+    }
+
     #[instrument(skip(self, mint_info))]
     #[instrument(skip(self, mint_info))]
     async fn add_mint(
     async fn add_mint(
         &mut self,
         &mut self,

+ 8 - 5
crates/cdk/src/wallet/auth/auth_wallet.rs

@@ -203,11 +203,14 @@ impl AuthWallet {
         &self,
         &self,
         tx: Option<&mut Tx<'_, '_>>,
         tx: Option<&mut Tx<'_, '_>>,
     ) -> Result<Vec<KeySetInfo>, Error> {
     ) -> Result<Vec<KeySetInfo>, Error> {
-        match self
-            .localstore
-            .get_mint_keysets(self.mint_url.clone())
-            .await?
-        {
+        let mut tx = tx;
+        match if let Some(tx) = tx.as_mut() {
+            tx.get_mint_keysets(self.mint_url.clone()).await?
+        } else {
+            self.localstore
+                .get_mint_keysets(self.mint_url.clone())
+                .await?
+        } {
             Some(keysets_info) => {
             Some(keysets_info) => {
                 let auth_keysets: Vec<KeySetInfo> =
                 let auth_keysets: Vec<KeySetInfo> =
                     keysets_info.unit(CurrencyUnit::Sat).cloned().collect();
                     keysets_info.unit(CurrencyUnit::Sat).cloned().collect();