Jelajahi Sumber

Storage expriment

Cesar Rodas 4 minggu lalu
induk
melakukan
2acecdd64d
2 mengubah file dengan 178 tambahan dan 0 penghapusan
  1. 1 0
      crates/cdk/src/wallet/mod.rs
  2. 177 0
      crates/cdk/src/wallet/storage.rs

+ 1 - 0
crates/cdk/src/wallet/mod.rs

@@ -46,6 +46,7 @@ pub mod payment_request;
 mod proofs;
 mod receive;
 mod send;
+mod storage;
 #[cfg(not(target_arch = "wasm32"))]
 mod streams;
 pub mod subscription;

+ 177 - 0
crates/cdk/src/wallet/storage.rs

@@ -0,0 +1,177 @@
+use std::sync::Arc;
+
+use cdk_common::{
+    database::{Error, WalletDatabase},
+    mint_url::MintUrl,
+    nuts::{CurrencyUnit, Id, KeySet, KeySetInfo, Keys},
+    wallet::TransactionId,
+    MintInfo, PublicKey, State,
+};
+
+use crate::nuts::SpendingConditions;
+use crate::types::ProofInfo;
+
+use super::Tx;
+
+/// Abstraction for all operations that can be executed in a database transaction and in a database
+/// trait, to avoid duplicating code for accesing data
+pub enum Storage<'a, 'b> {
+    Db(Arc<dyn WalletDatabase<Err = Error> + Send + Sync>),
+    Tx(&'a mut Tx<'a, 'b>),
+}
+
+impl<'a, 'b> From<Arc<dyn WalletDatabase<Err = Error> + Send + Sync>> for Storage<'a, 'b> {
+    fn from(value: Arc<dyn WalletDatabase<Err = Error> + Send + Sync>) -> Self {
+        Self::Db(value)
+    }
+}
+
+impl<'a, 'b> From<&'a mut Tx<'a, 'b>> for Storage<'a, 'b> {
+    fn from(value: &'a mut Tx<'a, 'b>) -> Self {
+        Self::Tx(value)
+    }
+}
+
+impl<'a, 'b> Storage<'a, 'b> {
+    /// Get mint from storage
+    pub async fn get_mint(&mut self, mint_url: MintUrl) -> Result<Option<MintInfo>, Error> {
+        match self {
+            Self::Db(db) => db.get_mint(mint_url).await,
+            Self::Tx(tx) => tx.get_mint(mint_url).await,
+        }
+    }
+
+    /// Add mint - automatically uses transaction or connection
+    pub async fn add_mint(
+        &mut self,
+        mint_url: MintUrl,
+        mint_info: Option<MintInfo>,
+    ) -> Result<(), Error> {
+        match self {
+            Self::Db(db) => {
+                let mut new_tx = db.begin_db_transaction().await?;
+                new_tx.add_mint(mint_url, mint_info).await?;
+                new_tx.commit().await?;
+                Ok(())
+            }
+            Self::Tx(tx) => tx.add_mint(mint_url, mint_info).await,
+        }
+    }
+
+    /// Get keys - automatically uses transaction or connection
+    pub async fn get_keys(&mut self, keyset_id: &Id) -> Result<Option<Keys>, Error> {
+        match self {
+            Self::Db(db) => db.get_keys(keyset_id).await,
+            Self::Tx(tx) => tx.get_keys(keyset_id).await,
+        }
+    }
+
+    /// Add keys - automatically uses transaction or connection
+    pub async fn add_keys(&mut self, keys: KeySet) -> Result<(), Error> {
+        match self {
+            Self::Db(db) => {
+                // For non-transactional context, create and commit a transaction
+                let mut new_tx = db.begin_db_transaction().await?;
+                new_tx.add_keys(keys).await?;
+                new_tx.commit().await?;
+                Ok(())
+            }
+            Self::Tx(tx) => tx.add_keys(keys).await,
+        }
+    }
+
+    /// Get mint keysets - automatically uses transaction or connection
+    pub async fn get_mint_keysets(
+        &mut self,
+        mint_url: MintUrl,
+    ) -> Result<Option<Vec<KeySetInfo>>, Error> {
+        match self {
+            Self::Db(db) => db.get_mint_keysets(mint_url).await,
+            Self::Tx(tx) => tx.get_mint_keysets(mint_url).await,
+        }
+    }
+
+    /// Add mint keysets - automatically uses transaction or connection
+    pub async fn add_mint_keysets(
+        &mut self,
+        mint_url: MintUrl,
+        keysets: Vec<KeySetInfo>,
+    ) -> Result<(), Error> {
+        match self {
+            Self::Db(db) => {
+                let mut new_tx = db.begin_db_transaction().await?;
+                new_tx.add_mint_keysets(mint_url, keysets).await?;
+                new_tx.commit().await?;
+                Ok(())
+            }
+            Self::Tx(tx) => tx.add_mint_keysets(mint_url, keysets).await,
+        }
+    }
+
+    /// Get proofs - automatically uses transaction or connection
+    pub async fn get_proofs(
+        &mut self,
+        mint_url: Option<MintUrl>,
+        unit: Option<CurrencyUnit>,
+        state: Option<Vec<State>>,
+        spending_conditions: Option<Vec<SpendingConditions>>,
+    ) -> Result<Vec<ProofInfo>, Error> {
+        match self {
+            Self::Db(db) => {
+                db.get_proofs(mint_url, unit, state, spending_conditions)
+                    .await
+            }
+            Self::Tx(tx) => {
+                tx.get_proofs(mint_url, unit, state, spending_conditions)
+                    .await
+            }
+        }
+    }
+
+    /// Update proofs - automatically uses transaction or connection
+    pub async fn update_proofs(
+        &mut self,
+        proofs: Vec<ProofInfo>,
+        spent_proofs: Vec<PublicKey>,
+    ) -> Result<(), Error> {
+        match self {
+            Self::Db(db) => {
+                let mut new_tx = db.begin_db_transaction().await?;
+                new_tx.update_proofs(proofs, spent_proofs).await?;
+                new_tx.commit().await?;
+                Ok(())
+            }
+            Self::Tx(tx) => tx.update_proofs(proofs, spent_proofs).await,
+        }
+    }
+
+    /// Update proofs state - automatically uses transaction or connection
+    pub async fn update_proofs_state(
+        &mut self,
+        ys: Vec<PublicKey>,
+        state: State,
+    ) -> Result<(), Error> {
+        match self {
+            Self::Db(db) => {
+                let mut new_tx = db.begin_db_transaction().await?;
+                new_tx.update_proofs_state(ys, state).await?;
+                new_tx.commit().await?;
+                Ok(())
+            }
+            Self::Tx(tx) => tx.update_proofs_state(ys, state).await,
+        }
+    }
+
+    /// Remove transaction - automatically uses transaction or connection
+    pub async fn remove_transaction(&mut self, transaction_id: TransactionId) -> Result<(), Error> {
+        match self {
+            Self::Db(db) => {
+                let mut new_tx = db.begin_db_transaction().await?;
+                new_tx.remove_transaction(transaction_id).await?;
+                new_tx.commit().await?;
+                Ok(())
+            }
+            Self::Tx(tx) => tx.remove_transaction(transaction_id).await,
+        }
+    }
+}