Cesar Rodas 2 months ago
parent
commit
1c8b39a577
1 changed files with 116 additions and 90 deletions
  1. 116 90
      crates/cdk-ffi/src/database.rs

+ 116 - 90
crates/cdk-ffi/src/database.rs

@@ -3,8 +3,10 @@
 use std::collections::HashMap;
 use std::sync::Arc;
 
-use cdk::cdk_database::WalletDatabase as CdkWalletDatabase;
-use cdk_common::database::{DbTransactionFinalizer, WalletDatabaseTransaction};
+use cdk_common::database::{
+    DbTransactionFinalizer, WalletDatabase as CdkWalletDatabase,
+    WalletDatabaseTransaction as CdkWalleTransaction,
+};
 
 use crate::error::FfiError;
 //use crate::postgres::WalletPostgresDatabase;
@@ -16,7 +18,74 @@ use crate::types::*;
 #[uniffi::export(with_foreign)]
 #[async_trait::async_trait]
 pub trait WalletDatabase: Send + Sync {
-    // Mint Management
+    /// Begins a DB transaction
+    async fn begin_db_transaction(&self) -> Result<Arc<dyn WalletDatabaseTransaction>, FfiError>;
+
+    /// Get mint from storage
+    async fn get_mint(&self, mint_url: MintUrl) -> Result<Option<MintInfo>, FfiError>;
+
+    /// Get all mints from storage
+    async fn get_mints(&self) -> Result<HashMap<MintUrl, Option<MintInfo>>, FfiError>;
+
+    /// Get mint keysets for mint url
+    async fn get_mint_keysets(
+        &self,
+        mint_url: MintUrl,
+    ) -> Result<Option<Vec<KeySetInfo>>, FfiError>;
+
+    /// Get mint keyset by id
+    async fn get_keyset_by_id(&self, keyset_id: Id) -> Result<Option<KeySetInfo>, FfiError>;
+
+    /// Get mint quote from storage
+    async fn get_mint_quote(&self, quote_id: String) -> Result<Option<MintQuote>, FfiError>;
+
+    /// Get mint quotes from storage
+    async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, FfiError>;
+
+    /// Get melt quote from storage
+    async fn get_melt_quote(&self, quote_id: String) -> Result<Option<MeltQuote>, FfiError>;
+
+    /// Get melt quotes from storage
+    async fn get_melt_quotes(&self) -> Result<Vec<MeltQuote>, FfiError>;
+
+    /// Get [`Keys`] from storage
+    async fn get_keys(&self, id: Id) -> Result<Option<Keys>, FfiError>;
+
+    /// Get proofs from storage
+    async fn get_proofs(
+        &self,
+        mint_url: Option<MintUrl>,
+        unit: Option<CurrencyUnit>,
+        state: Option<Vec<ProofState>>,
+        spending_conditions: Option<Vec<SpendingConditions>>,
+    ) -> Result<Vec<ProofInfo>, FfiError>;
+
+    /// Get balance
+    async fn get_balance(
+        &self,
+        mint_url: Option<MintUrl>,
+        unit: Option<CurrencyUnit>,
+        state: Option<Vec<ProofState>>,
+    ) -> Result<u64, FfiError>;
+
+    /// Get transaction from storage
+    async fn get_transaction(
+        &self,
+        transaction_id: TransactionId,
+    ) -> Result<Option<Transaction>, FfiError>;
+
+    /// List transactions from storage
+    async fn list_transactions(
+        &self,
+        mint_url: Option<MintUrl>,
+        direction: Option<TransactionDirection>,
+        unit: Option<CurrencyUnit>,
+    ) -> Result<Vec<Transaction>, FfiError>;
+}
+
+#[uniffi::export(with_foreign)]
+#[async_trait::async_trait]
+pub trait WalletDatabaseTransaction: Send + Sync + 'static {
     /// Add Mint to storage
     async fn add_mint(
         &self,
@@ -27,12 +96,6 @@ pub trait WalletDatabase: Send + Sync {
     /// Remove Mint from storage
     async fn remove_mint(&self, mint_url: MintUrl) -> Result<(), FfiError>;
 
-    /// Get mint from storage
-    async fn get_mint(&self, mint_url: MintUrl) -> Result<Option<MintInfo>, FfiError>;
-
-    /// Get all mints from storage
-    async fn get_mints(&self) -> Result<HashMap<MintUrl, Option<MintInfo>>, FfiError>;
-
     /// Update mint url
     async fn update_mint_url(
         &self,
@@ -40,7 +103,12 @@ pub trait WalletDatabase: Send + Sync {
         new_mint_url: MintUrl,
     ) -> Result<(), FfiError>;
 
-    // Keyset Management
+    /// Get mint keyset by id
+    async fn get_keyset_by_id(&self, keyset_id: Id) -> Result<Option<KeySetInfo>, FfiError>;
+
+    /// Get [`Keys`] from storage
+    async fn get_keys(&self, id: Id) -> Result<Option<Keys>, FfiError>;
+
     /// Add mint keyset to storage
     async fn add_mint_keysets(
         &self,
@@ -48,60 +116,31 @@ pub trait WalletDatabase: Send + Sync {
         keysets: Vec<KeySetInfo>,
     ) -> Result<(), FfiError>;
 
-    /// Get mint keysets for mint url
-    async fn get_mint_keysets(
-        &self,
-        mint_url: MintUrl,
-    ) -> Result<Option<Vec<KeySetInfo>>, FfiError>;
-
-    /// Get mint keyset by id
-    async fn get_keyset_by_id(&self, keyset_id: Id) -> Result<Option<KeySetInfo>, FfiError>;
+    /// Get mint quote from storage. This function locks the returned minted quote for update
+    async fn get_mint_quote(&self, quote_id: String) -> Result<Option<MintQuote>, FfiError>;
 
-    // Mint Quote Management
     /// Add mint quote to storage
     async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), FfiError>;
 
-    /// Get mint quote from storage
-    async fn get_mint_quote(&self, quote_id: String) -> Result<Option<MintQuote>, FfiError>;
-
-    /// Get mint quotes from storage
-    async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, FfiError>;
-
     /// Remove mint quote from storage
     async fn remove_mint_quote(&self, quote_id: String) -> Result<(), FfiError>;
 
-    // Melt Quote Management
-    /// Add melt quote to storage
-    async fn add_melt_quote(&self, quote: MeltQuote) -> Result<(), FfiError>;
-
     /// Get melt quote from storage
     async fn get_melt_quote(&self, quote_id: String) -> Result<Option<MeltQuote>, FfiError>;
 
-    /// Get melt quotes from storage
-    async fn get_melt_quotes(&self) -> Result<Vec<MeltQuote>, FfiError>;
+    /// Add melt quote to storage
+    async fn add_melt_quote(&self, quote: MeltQuote) -> Result<(), FfiError>;
 
     /// Remove melt quote from storage
     async fn remove_melt_quote(&self, quote_id: String) -> Result<(), FfiError>;
 
-    // Keys Management
-    /// Add Keys to storage
+    /// Add [`Keys`] to storage
     async fn add_keys(&self, keyset: KeySet) -> Result<(), FfiError>;
 
-    /// Get Keys from storage
-    async fn get_keys(&self, id: Id) -> Result<Option<Keys>, FfiError>;
-
-    /// Remove Keys from storage
-    async fn remove_keys(&self, id: Id) -> Result<(), FfiError>;
+    /// Remove [`Keys`] from storage
+    async fn remove_keys(&self, id: String) -> Result<(), FfiError>;
 
-    // Proof Management
-    /// Update the proofs in storage by adding new proofs or removing proofs by their Y value
-    async fn update_proofs(
-        &self,
-        added: Vec<ProofInfo>,
-        removed_ys: Vec<PublicKey>,
-    ) -> Result<(), FfiError>;
-
-    /// Get proofs from storage
+    /// Get proofs from storage and lock them for update
     async fn get_proofs(
         &self,
         mint_url: Option<MintUrl>,
@@ -110,13 +149,13 @@ pub trait WalletDatabase: Send + Sync {
         spending_conditions: Option<Vec<SpendingConditions>>,
     ) -> Result<Vec<ProofInfo>, FfiError>;
 
-    /// Get balance efficiently using SQL aggregation
-    async fn get_balance(
+    /// Update the proofs in storage by adding new proofs or removing proofs by
+    /// their Y value.
+    async fn update_proofs(
         &self,
-        mint_url: Option<MintUrl>,
-        unit: Option<CurrencyUnit>,
-        state: Option<Vec<ProofState>>,
-    ) -> Result<u64, FfiError>;
+        added: Vec<ProofInfo>,
+        removed_ys: Vec<PublicKey>,
+    ) -> Result<(), FfiError>;
 
     /// Update proofs state in storage
     async fn update_proofs_state(
@@ -125,28 +164,12 @@ pub trait WalletDatabase: Send + Sync {
         state: ProofState,
     ) -> Result<(), FfiError>;
 
-    // Keyset Counter Management
-    /// Increment Keyset counter
+    /// Atomically increment Keyset counter and return new value
     async fn increment_keyset_counter(&self, keyset_id: Id, count: u32) -> Result<u32, FfiError>;
 
-    // Transaction Management
     /// Add transaction to storage
     async fn add_transaction(&self, transaction: Transaction) -> Result<(), FfiError>;
 
-    /// Get transaction from storage
-    async fn get_transaction(
-        &self,
-        transaction_id: TransactionId,
-    ) -> Result<Option<Transaction>, FfiError>;
-
-    /// List transactions from storage
-    async fn list_transactions(
-        &self,
-        mint_url: Option<MintUrl>,
-        direction: Option<TransactionDirection>,
-        unit: Option<CurrencyUnit>,
-    ) -> Result<Vec<Transaction>, FfiError>;
-
     /// Remove transaction from storage
     async fn remove_transaction(&self, transaction_id: TransactionId) -> Result<(), FfiError>;
 }
@@ -169,6 +192,8 @@ impl std::fmt::Debug for WalletDatabaseBridge {
     }
 }
 
+/*
+
 #[async_trait::async_trait]
 impl CdkWalletDatabase for WalletDatabaseBridge {
     type Err = cdk::cdk_database::Error;
@@ -445,7 +470,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     for WalletDatabaseTransactionBridge
 {
     async fn add_mint(
-        &mut self,
+        &self,
         mint_url: cdk::mint_url::MintUrl,
         mint_info: Option<cdk::nuts::MintInfo>,
     ) -> Result<(), cdk::cdk_database::Error> {
@@ -458,7 +483,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn remove_mint(
-        &mut self,
+        &self,
         mint_url: cdk::mint_url::MintUrl,
     ) -> Result<(), cdk::cdk_database::Error> {
         let ffi_mint_url = mint_url.into();
@@ -469,7 +494,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn update_mint_url(
-        &mut self,
+        &self,
         old_mint_url: cdk::mint_url::MintUrl,
         new_mint_url: cdk::mint_url::MintUrl,
     ) -> Result<(), cdk::cdk_database::Error> {
@@ -482,7 +507,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn add_mint_keysets(
-        &mut self,
+        &self,
         mint_url: cdk::mint_url::MintUrl,
         keysets: Vec<cdk::nuts::KeySetInfo>,
     ) -> Result<(), cdk::cdk_database::Error> {
@@ -495,7 +520,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn add_mint_quote(
-        &mut self,
+        &self,
         quote: cdk::wallet::MintQuote,
     ) -> Result<(), cdk::cdk_database::Error> {
         let ffi_quote = quote.into();
@@ -505,7 +530,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
             .map_err(|e| cdk::cdk_database::Error::Database(e.to_string().into()))
     }
 
-    async fn remove_mint_quote(&mut self, quote_id: &str) -> Result<(), cdk::cdk_database::Error> {
+    async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), cdk::cdk_database::Error> {
         self.ffi_db
             .remove_mint_quote(quote_id.to_string())
             .await
@@ -513,7 +538,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn add_melt_quote(
-        &mut self,
+        &self,
         quote: cdk::wallet::MeltQuote,
     ) -> Result<(), cdk::cdk_database::Error> {
         let ffi_quote = quote.into();
@@ -523,7 +548,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
             .map_err(|e| cdk::cdk_database::Error::Database(e.to_string().into()))
     }
 
-    async fn remove_melt_quote(&mut self, quote_id: &str) -> Result<(), cdk::cdk_database::Error> {
+    async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), cdk::cdk_database::Error> {
         self.ffi_db
             .remove_melt_quote(quote_id.to_string())
             .await
@@ -531,7 +556,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn add_keys(
-        &mut self,
+        &self,
         keyset: cdk::nuts::KeySet,
     ) -> Result<(), cdk::cdk_database::Error> {
         let ffi_keyset: KeySet = keyset.into();
@@ -541,7 +566,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
             .map_err(|e| cdk::cdk_database::Error::Database(e.to_string().into()))
     }
 
-    async fn remove_keys(&mut self, id: &cdk::nuts::Id) -> Result<(), cdk::cdk_database::Error> {
+    async fn remove_keys(&self, id: &cdk::nuts::Id) -> Result<(), cdk::cdk_database::Error> {
         let ffi_id = (*id).into();
         self.ffi_db
             .remove_keys(ffi_id)
@@ -550,7 +575,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn update_proofs(
-        &mut self,
+        &self,
         added: Vec<cdk::types::ProofInfo>,
         removed_ys: Vec<cdk::nuts::PublicKey>,
     ) -> Result<(), cdk::cdk_database::Error> {
@@ -563,7 +588,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn update_proofs_state(
-        &mut self,
+        &self,
         ys: Vec<cdk::nuts::PublicKey>,
         state: cdk::nuts::State,
     ) -> Result<(), cdk::cdk_database::Error> {
@@ -576,7 +601,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn increment_keyset_counter(
-        &mut self,
+        &self,
         keyset_id: &cdk::nuts::Id,
         count: u32,
     ) -> Result<u32, cdk::cdk_database::Error> {
@@ -588,7 +613,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn add_transaction(
-        &mut self,
+        &self,
         transaction: cdk::wallet::types::Transaction,
     ) -> Result<(), cdk::cdk_database::Error> {
         let ffi_transaction = transaction.into();
@@ -599,7 +624,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn remove_transaction(
-        &mut self,
+        &self,
         transaction_id: cdk::wallet::types::TransactionId,
     ) -> Result<(), cdk::cdk_database::Error> {
         let ffi_id = transaction_id.into();
@@ -611,7 +636,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
 
     // Read methods needed during transactions
     async fn get_keyset_by_id(
-        &mut self,
+        &self,
         keyset_id: &cdk::nuts::Id,
     ) -> Result<Option<cdk::nuts::KeySetInfo>, cdk::cdk_database::Error> {
         let ffi_id = (*keyset_id).into();
@@ -624,7 +649,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn get_keys(
-        &mut self,
+        &self,
         id: &cdk::nuts::Id,
     ) -> Result<Option<cdk::nuts::Keys>, cdk::cdk_database::Error> {
         let ffi_id = (*id).into();
@@ -642,7 +667,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn get_mint_quote(
-        &mut self,
+        &self,
         quote_id: &str,
     ) -> Result<Option<cdk::wallet::MintQuote>, cdk::cdk_database::Error> {
         let result = self
@@ -659,7 +684,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn get_melt_quote(
-        &mut self,
+        &self,
         quote_id: &str,
     ) -> Result<Option<cdk::wallet::MeltQuote>, cdk::cdk_database::Error> {
         let result = self
@@ -676,7 +701,7 @@ impl<'a> WalletDatabaseTransaction<'a, cdk::cdk_database::Error>
     }
 
     async fn get_proofs(
-        &mut self,
+        &self,
         mint_url: Option<cdk::mint_url::MintUrl>,
         unit: Option<cdk::nuts::CurrencyUnit>,
         state: Option<Vec<cdk::nuts::State>>,
@@ -751,6 +776,7 @@ pub enum WalletDbBackend {
         url: String,
     },
 }
+*/
 
 /// Factory helpers returning a CDK wallet database behind the FFI trait
 #[uniffi::export]