From 1dd08ae53706747cd9f8197fe04d0f50a3c999a8 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Sun, 14 Apr 2024 23:17:33 +0100 Subject: [PATCH] refactor(cdk-redb): feature gate mint and wallet --- crates/cdk-redb/src/mint_redb.rs | 504 ----------------------------- crates/cdk-redb/src/wallet.rs | 30 +- crates/cdk-redb/src/wallet_redb.rs | 493 ---------------------------- 3 files changed, 29 insertions(+), 998 deletions(-) delete mode 100644 crates/cdk-redb/src/mint_redb.rs delete mode 100644 crates/cdk-redb/src/wallet_redb.rs diff --git a/crates/cdk-redb/src/mint_redb.rs b/crates/cdk-redb/src/mint_redb.rs deleted file mode 100644 index a0639756..00000000 --- a/crates/cdk-redb/src/mint_redb.rs +++ /dev/null @@ -1,504 +0,0 @@ -use std::collections::HashMap; -use std::num::ParseIntError; -use std::str::FromStr; -use std::sync::Arc; - -use async_trait::async_trait; -<<<<<<<< HEAD:crates/cdk-redb/src/mint.rs -use cdk::cdk_database::MintDatabase; -======== -use cdk::cdk_database::{self, MintDatabase}; ->>>>>>>> f69aa2d (refactor: mint redb database):crates/cdk-redb/src/mint_redb.rs -use cdk::dhke::hash_to_curve; -use cdk::nuts::{ - BlindSignature, CurrencyUnit, Id, MintInfo, MintKeySet as KeySet, Proof, PublicKey, -}; -use cdk::secret::Secret; -use cdk::types::{MeltQuote, MintQuote}; -use redb::{Database, ReadableTable, TableDefinition}; -<<<<<<<< HEAD:crates/cdk-redb/src/mint.rs -use tokio::sync::Mutex; -use tracing::debug; - -use super::error::Error; -======== -use thiserror::Error; -use tokio::sync::Mutex; -use tracing::debug; ->>>>>>>> f69aa2d (refactor: mint redb database):crates/cdk-redb/src/mint_redb.rs - -const ACTIVE_KEYSETS_TABLE: TableDefinition<&str, &str> = TableDefinition::new("active_keysets"); -const KEYSETS_TABLE: TableDefinition<&str, &str> = TableDefinition::new("keysets"); -const MINT_QUOTES_TABLE: TableDefinition<&str, &str> = TableDefinition::new("mint_quotes"); -const MELT_QUOTES_TABLE: TableDefinition<&str, &str> = TableDefinition::new("melt_quotes"); -const PENDING_PROOFS_TABLE: TableDefinition<[u8; 33], &str> = - TableDefinition::new("pending_proofs"); -const SPENT_PROOFS_TABLE: TableDefinition<[u8; 33], &str> = TableDefinition::new("spent_proofs"); -const CONFIG_TABLE: TableDefinition<&str, &str> = TableDefinition::new("config"); -// Key is hex blinded_message B_ value is blinded_signature -const BLINDED_SIGNATURES: TableDefinition<[u8; 33], &str> = - TableDefinition::new("blinded_signatures"); - -const DATABASE_VERSION: u64 = 0; - -#[derive(Debug, Error)] -pub enum Error { - #[error(transparent)] - Redb(#[from] redb::Error), - #[error(transparent)] - Database(#[from] redb::DatabaseError), - #[error(transparent)] - Transaction(#[from] redb::TransactionError), - #[error(transparent)] - Commit(#[from] redb::CommitError), - #[error(transparent)] - Table(#[from] redb::TableError), - #[error(transparent)] - Storage(#[from] redb::StorageError), - #[error(transparent)] - Serde(#[from] serde_json::Error), - #[error(transparent)] - ParseInt(#[from] ParseIntError), - #[error(transparent)] - CDKDatabase(#[from] cdk_database::Error), - #[error(transparent)] - CDK(#[from] cdk::error::Error), - #[error(transparent)] - CDKNUT02(#[from] cdk::nuts::nut02::Error), - #[error(transparent)] - CDKNUT00(#[from] cdk::nuts::nut00::Error), - #[error("Unknown Mint Info")] - UnknownMintInfo, -} - -impl From for cdk_database::Error { - fn from(e: Error) -> Self { - Self::Database(Box::new(e)) - } -} - -#[derive(Debug, Clone)] -pub struct MintRedbDatabase { - db: Arc>, -} - -impl MintRedbDatabase { - pub fn new(path: &str) -> Result { - let db = Database::create(path)?; - - let write_txn = db.begin_write()?; - // Check database version - { - let _ = write_txn.open_table(CONFIG_TABLE)?; - let mut table = write_txn.open_table(CONFIG_TABLE)?; - - let db_version = table.get("db_version")?; - let db_version = db_version.map(|v| v.value().to_owned()); - - match db_version { - Some(db_version) => { - let current_file_version = u64::from_str(&db_version)?; - if current_file_version.ne(&DATABASE_VERSION) { - // Database needs to be upgraded - todo!() - } - } - None => { - // Open all tables to init a new db - let _ = write_txn.open_table(ACTIVE_KEYSETS_TABLE)?; - let _ = write_txn.open_table(KEYSETS_TABLE)?; - let _ = write_txn.open_table(MINT_QUOTES_TABLE)?; - let _ = write_txn.open_table(MELT_QUOTES_TABLE)?; - let _ = write_txn.open_table(PENDING_PROOFS_TABLE)?; - let _ = write_txn.open_table(SPENT_PROOFS_TABLE)?; - let _ = write_txn.open_table(BLINDED_SIGNATURES)?; - - table.insert("db_version", "0")?; - } - } - } - - write_txn.commit()?; - Ok(Self { - db: Arc::new(Mutex::new(db)), - }) - } -} - -#[async_trait] -impl MintDatabase for MintRedbDatabase { - type Err = Error; - - async fn set_mint_info(&self, mint_info: &MintInfo) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(CONFIG_TABLE)?; - table.insert("mint_info", serde_json::to_string(mint_info)?.as_str())?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_mint_info(&self) -> Result { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(CONFIG_TABLE)?; - - let mint_info = table.get("mint_info")?.ok_or(Error::UnknownMintInfo)?; - - Ok(serde_json::from_str(mint_info.value())?) - } - - async fn add_active_keyset(&self, unit: CurrencyUnit, id: Id) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(ACTIVE_KEYSETS_TABLE)?; - table.insert(unit.to_string().as_str(), id.to_string().as_str())?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_active_keyset_id(&self, unit: &CurrencyUnit) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(ACTIVE_KEYSETS_TABLE)?; - - if let Some(id) = table.get(unit.to_string().as_str())? { - return Ok(Some(Id::from_str(id.value())?)); - } - - Ok(None) - } - - async fn get_active_keysets(&self) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(ACTIVE_KEYSETS_TABLE)?; - - let mut active_keysets = HashMap::new(); - - for (unit, id) in (table.iter()?).flatten() { - let unit = CurrencyUnit::from(unit.value()); - let id = Id::from_str(id.value())?; - - active_keysets.insert(unit, id); - } - - Ok(active_keysets) - } - - async fn add_keyset(&self, keyset: KeySet) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(KEYSETS_TABLE)?; - table.insert( - Id::from(keyset.clone()).to_string().as_str(), - serde_json::to_string(&keyset)?.as_str(), - )?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_keyset(&self, keyset_id: &Id) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(KEYSETS_TABLE)?; - - match table.get(keyset_id.to_string().as_str())? { - Some(keyset) => Ok(serde_json::from_str(keyset.value())?), - None => Ok(None), - } - } - - async fn get_keysets(&self) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(KEYSETS_TABLE)?; - - let mut keysets = Vec::new(); - - for (_id, keyset) in (table.iter()?).flatten() { - let keyset = serde_json::from_str(keyset.value())?; - - keysets.push(keyset) - } - - Ok(keysets) - } - - async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MINT_QUOTES_TABLE)?; - table.insert(quote.id.as_str(), serde_json::to_string("e)?.as_str())?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_mint_quote(&self, quote_id: &str) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(MINT_QUOTES_TABLE)?; - - match table.get(quote_id)? { - Some(quote) => Ok(serde_json::from_str(quote.value())?), - None => Ok(None), - } - } - - async fn get_mint_quotes(&self) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(MINT_QUOTES_TABLE)?; - - let mut quotes = Vec::new(); - - for (_id, quote) in (table.iter()?).flatten() { - let quote = serde_json::from_str(quote.value())?; - - quotes.push(quote) - } - - Ok(quotes) - } - - async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MINT_QUOTES_TABLE)?; - table.remove(quote_id)?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn add_melt_quote(&self, quote: MeltQuote) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MELT_QUOTES_TABLE)?; - table.insert(quote.id.as_str(), serde_json::to_string("e)?.as_str())?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_melt_quote(&self, quote_id: &str) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(MELT_QUOTES_TABLE)?; - - let quote = table.get(quote_id)?; - - Ok(quote.map(|q| serde_json::from_str(q.value()).unwrap())) - } - - async fn get_melt_quotes(&self) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(MELT_QUOTES_TABLE)?; - - let mut quotes = Vec::new(); - - for (_id, quote) in (table.iter()?).flatten() { - let quote = serde_json::from_str(quote.value())?; - - quotes.push(quote) - } - - Ok(quotes) - } - - async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MELT_QUOTES_TABLE)?; - table.remove(quote_id)?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn add_spent_proof(&self, proof: Proof) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(SPENT_PROOFS_TABLE)?; - let y: PublicKey = hash_to_curve(&proof.secret.to_bytes())?; - table.insert(y.to_bytes(), serde_json::to_string(&proof)?.as_str())?; - } - write_txn.commit()?; - debug!("Added spend secret: {}", proof.secret.to_string()); - - Ok(()) - } - - async fn get_spent_proof_by_y(&self, y: &PublicKey) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(SPENT_PROOFS_TABLE)?; - - match table.get(y.to_bytes())? { - Some(proof) => Ok(serde_json::from_str(proof.value())?), - None => Ok(None), - } - } - - async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(SPENT_PROOFS_TABLE)?; - - let y: PublicKey = hash_to_curve(&secret.to_bytes())?; - - match table.get(y.to_bytes())? { - Some(proof) => Ok(serde_json::from_str(proof.value())?), - None => Ok(None), - } - } - - async fn add_pending_proof(&self, proof: Proof) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(PENDING_PROOFS_TABLE)?; - table.insert( - hash_to_curve(&proof.secret.to_bytes())?.to_bytes(), - serde_json::to_string(&proof)?.as_str(), - )?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_pending_proof_by_y(&self, y: &PublicKey) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(PENDING_PROOFS_TABLE)?; - - match table.get(y.to_bytes())? { - Some(proof) => Ok(serde_json::from_str(proof.value())?), - None => Ok(None), - } - } - - async fn get_pending_proof_by_secret(&self, secret: &Secret) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(PENDING_PROOFS_TABLE)?; - - let secret_hash = hash_to_curve(&secret.to_bytes())?; - - match table.get(secret_hash.to_bytes())? { - Some(proof) => Ok(serde_json::from_str(proof.value())?), - None => Ok(None), - } - } - - async fn remove_pending_proof(&self, secret: &Secret) -> Result<(), Error> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(PENDING_PROOFS_TABLE)?; - let secret_hash = hash_to_curve(&secret.to_bytes())?; - table.remove(secret_hash.to_bytes())?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn add_blinded_signature( - &self, - blinded_message: PublicKey, - blinded_signature: BlindSignature, - ) -> Result<(), Error> { - let db = self.db.lock().await; - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(BLINDED_SIGNATURES)?; - table.insert( - blinded_message.to_bytes(), - serde_json::to_string(&blinded_signature)?.as_str(), - )?; - } - - write_txn.commit()?; - - Ok(()) - } - - async fn get_blinded_signature( - &self, - blinded_message: &PublicKey, - ) -> Result, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(BLINDED_SIGNATURES)?; - - match table.get(blinded_message.to_bytes())? { - Some(blind_signature) => Ok(serde_json::from_str(blind_signature.value())?), - None => Ok(None), - } - } - - async fn get_blinded_signatures( - &self, - blinded_messages: Vec, - ) -> Result>, Error> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(BLINDED_SIGNATURES)?; - - let mut signatures = Vec::with_capacity(blinded_messages.len()); - - for blinded_message in blinded_messages { - match table.get(blinded_message.to_bytes())? { - Some(blind_signature) => { - signatures.push(Some(serde_json::from_str(blind_signature.value())?)) - } - None => signatures.push(None), - } - } - - Ok(signatures) - } -} diff --git a/crates/cdk-redb/src/wallet.rs b/crates/cdk-redb/src/wallet.rs index 7d30d4b3..e9326903 100644 --- a/crates/cdk-redb/src/wallet.rs +++ b/crates/cdk-redb/src/wallet.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::num::ParseIntError; use std::str::FromStr; use std::sync::Arc; @@ -8,9 +9,36 @@ use cdk::nuts::{Id, KeySetInfo, Keys, MintInfo, Proofs}; use cdk::types::{MeltQuote, MintQuote}; use cdk::url::UncheckedUrl; use redb::{Database, MultimapTableDefinition, ReadableTable, TableDefinition}; +use thiserror::Error; use tokio::sync::Mutex; -use super::error::Error; +#[derive(Debug, Error)] +pub enum Error { + #[error(transparent)] + Redb(#[from] redb::Error), + #[error(transparent)] + Database(#[from] redb::DatabaseError), + #[error(transparent)] + Transaction(#[from] redb::TransactionError), + #[error(transparent)] + Commit(#[from] redb::CommitError), + #[error(transparent)] + Table(#[from] redb::TableError), + #[error(transparent)] + Storage(#[from] redb::StorageError), + #[error(transparent)] + Serde(#[from] serde_json::Error), + #[error(transparent)] + ParseInt(#[from] ParseIntError), + #[error(transparent)] + CDKDatabase(#[from] cdk_database::Error), +} + +impl From for cdk_database::Error { + fn from(e: Error) -> Self { + Self::Database(Box::new(e)) + } +} const MINTS_TABLE: TableDefinition<&str, &str> = TableDefinition::new("mints_table"); const MINT_KEYSETS_TABLE: MultimapTableDefinition<&str, &str> = diff --git a/crates/cdk-redb/src/wallet_redb.rs b/crates/cdk-redb/src/wallet_redb.rs deleted file mode 100644 index be8c87c9..00000000 --- a/crates/cdk-redb/src/wallet_redb.rs +++ /dev/null @@ -1,493 +0,0 @@ -use std::collections::HashMap; -use std::num::ParseIntError; -use std::str::FromStr; -use std::sync::Arc; - -use async_trait::async_trait; -use cdk::cdk_database::{self, WalletDatabase}; -use cdk::nuts::{Id, KeySetInfo, Keys, MintInfo, Proofs}; -use cdk::types::{MeltQuote, MintQuote}; -use cdk::url::UncheckedUrl; -use redb::{Database, MultimapTableDefinition, ReadableTable, TableDefinition}; -use thiserror::Error; -use tokio::sync::Mutex; - -#[derive(Debug, Error)] -pub enum Error { - #[error(transparent)] - Redb(#[from] redb::Error), - #[error(transparent)] - Database(#[from] redb::DatabaseError), - #[error(transparent)] - Transaction(#[from] redb::TransactionError), - #[error(transparent)] - Commit(#[from] redb::CommitError), - #[error(transparent)] - Table(#[from] redb::TableError), - #[error(transparent)] - Storage(#[from] redb::StorageError), - #[error(transparent)] - Serde(#[from] serde_json::Error), - #[error(transparent)] - ParseInt(#[from] ParseIntError), - #[error(transparent)] - CDKDatabase(#[from] cdk_database::Error), -} - -impl From for cdk_database::Error { - fn from(e: Error) -> Self { - Self::Database(Box::new(e)) - } -} - -const MINTS_TABLE: TableDefinition<&str, &str> = TableDefinition::new("mints_table"); -const MINT_KEYSETS_TABLE: MultimapTableDefinition<&str, &str> = - MultimapTableDefinition::new("mint_keysets"); -const MINT_QUOTES_TABLE: TableDefinition<&str, &str> = TableDefinition::new("mint_quotes"); -const MELT_QUOTES_TABLE: TableDefinition<&str, &str> = TableDefinition::new("melt_quotes"); -const MINT_KEYS_TABLE: TableDefinition<&str, &str> = TableDefinition::new("mint_keys"); -const PROOFS_TABLE: MultimapTableDefinition<&str, &str> = MultimapTableDefinition::new("proofs"); -const PENDING_PROOFS_TABLE: MultimapTableDefinition<&str, &str> = - MultimapTableDefinition::new("pending_proofs"); -const CONFIG_TABLE: TableDefinition<&str, &str> = TableDefinition::new("config"); -const KEYSET_COUNTER: TableDefinition<&str, u64> = TableDefinition::new("keyset_counter"); - -const DATABASE_VERSION: u64 = 0; - -#[derive(Debug, Clone)] -pub struct RedbWalletDatabase { - db: Arc>, -} - -impl RedbWalletDatabase { - pub fn new(path: &str) -> Result { - let db = Database::create(path)?; - - let write_txn = db.begin_write()?; - - // Check database version - { - let _ = write_txn.open_table(CONFIG_TABLE)?; - let mut table = write_txn.open_table(CONFIG_TABLE)?; - - let db_version = table.get("db_version")?.map(|v| v.value().to_owned()); - - match db_version { - Some(db_version) => { - let current_file_version = u64::from_str(&db_version)?; - if current_file_version.ne(&DATABASE_VERSION) { - // Database needs to be upgraded - todo!() - } - let _ = write_txn.open_table(KEYSET_COUNTER)?; - } - None => { - // Open all tables to init a new db - let _ = write_txn.open_table(MINTS_TABLE)?; - let _ = write_txn.open_multimap_table(MINT_KEYSETS_TABLE)?; - let _ = write_txn.open_table(MINT_QUOTES_TABLE)?; - let _ = write_txn.open_table(MELT_QUOTES_TABLE)?; - let _ = write_txn.open_table(MINT_KEYS_TABLE)?; - let _ = write_txn.open_multimap_table(PROOFS_TABLE)?; - let _ = write_txn.open_table(KEYSET_COUNTER)?; - table.insert("db_version", "0")?; - } - } - } - write_txn.commit()?; - - Ok(Self { - db: Arc::new(Mutex::new(db)), - }) - } -} - -#[async_trait] -impl WalletDatabase for RedbWalletDatabase { - type Err = Error; - - async fn add_mint( - &self, - mint_url: UncheckedUrl, - mint_info: Option, - ) -> Result<(), Self::Err> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn - .open_table(MINTS_TABLE) - .map_err(Into::::into)?; - table.insert( - mint_url.to_string().as_str(), - serde_json::to_string(&mint_info) - .map_err(Into::::into)? - .as_str(), - )?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_mint(&self, mint_url: UncheckedUrl) -> Result, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read().map_err(Into::::into)?; - let table = read_txn.open_table(MINTS_TABLE)?; - - if let Some(mint_info) = table.get(mint_url.to_string().as_str())? { - return Ok(serde_json::from_str(mint_info.value())?); - } - - Ok(None) - } - - async fn get_mints(&self) -> Result>, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read().map_err(Into::::into)?; - let table = read_txn - .open_table(MINTS_TABLE) - .map_err(Into::::into)?; - - let mints = table - .iter()? - .flatten() - .map(|(mint, mint_info)| { - ( - UncheckedUrl::from_str(mint.value()).unwrap(), - serde_json::from_str(mint_info.value()).ok(), - ) - }) - .collect(); - - Ok(mints) - } - - async fn add_mint_keysets( - &self, - mint_url: UncheckedUrl, - keysets: Vec, - ) -> Result<(), Self::Err> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_multimap_table(MINT_KEYSETS_TABLE)?; - - for keyset in keysets { - table.insert( - mint_url.to_string().as_str(), - serde_json::to_string(&keyset)?.as_str(), - )?; - } - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_mint_keysets( - &self, - mint_url: UncheckedUrl, - ) -> Result>, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read().map_err(Into::::into)?; - let table = read_txn.open_multimap_table(MINT_KEYSETS_TABLE)?; - - let keysets = table - .get(mint_url.to_string().as_str())? - .flatten() - .flat_map(|k| serde_json::from_str(k.value())) - .collect(); - - Ok(keysets) - } - - async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), Self::Err> { - let db = self.db.lock().await; - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MINT_QUOTES_TABLE)?; - table - .insert(quote.id.as_str(), serde_json::to_string("e)?.as_str()) - .map_err(Into::::into)?; - } - - write_txn.commit().map_err(Into::::into)?; - - Ok(()) - } - - async fn get_mint_quote(&self, quote_id: &str) -> Result, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read().map_err(Into::::into)?; - let table = read_txn.open_table(MINT_QUOTES_TABLE)?; - - if let Some(mint_info) = table.get(quote_id)? { - return Ok(serde_json::from_str(mint_info.value())?); - } - - Ok(None) - } - - async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Self::Err> { - let db = self.db.lock().await; - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MINT_QUOTES_TABLE)?; - table.remove(quote_id)?; - } - - write_txn.commit()?; - - Ok(()) - } - - async fn add_melt_quote(&self, quote: MeltQuote) -> Result<(), Self::Err> { - let db = self.db.lock().await; - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MELT_QUOTES_TABLE)?; - table.insert(quote.id.as_str(), serde_json::to_string("e)?.as_str())?; - } - - write_txn.commit()?; - - Ok(()) - } - - async fn get_melt_quote(&self, quote_id: &str) -> Result, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(MELT_QUOTES_TABLE)?; - - if let Some(mint_info) = table.get(quote_id)? { - return Ok(serde_json::from_str(mint_info.value())?); - } - - Ok(None) - } - - async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> { - let db = self.db.lock().await; - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MELT_QUOTES_TABLE)?; - table.remove(quote_id)?; - } - - write_txn.commit()?; - - Ok(()) - } - - async fn add_keys(&self, keys: Keys) -> Result<(), Self::Err> { - let db = self.db.lock().await; - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MINT_KEYS_TABLE)?; - table.insert( - Id::from(&keys).to_string().as_str(), - serde_json::to_string(&keys)?.as_str(), - )?; - } - - write_txn.commit()?; - - Ok(()) - } - - async fn get_keys(&self, id: &Id) -> Result, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(MINT_KEYS_TABLE)?; - - if let Some(mint_info) = table.get(id.to_string().as_str())? { - return Ok(serde_json::from_str(mint_info.value())?); - } - - Ok(None) - } - - async fn remove_keys(&self, id: &Id) -> Result<(), Self::Err> { - let db = self.db.lock().await; - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_table(MINT_KEYS_TABLE)?; - - table.remove(id.to_string().as_str())?; - } - - write_txn.commit()?; - - Ok(()) - } - - async fn add_proofs(&self, mint_url: UncheckedUrl, proofs: Proofs) -> Result<(), Self::Err> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_multimap_table(PROOFS_TABLE)?; - - for proof in proofs { - table.insert( - mint_url.to_string().as_str(), - serde_json::to_string(&proof)?.as_str(), - )?; - } - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_proofs(&self, mint_url: UncheckedUrl) -> Result, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_multimap_table(PROOFS_TABLE)?; - - let proofs = table - .get(mint_url.to_string().as_str())? - .flatten() - .flat_map(|k| serde_json::from_str(k.value())) - .collect(); - - Ok(proofs) - } - - async fn remove_proofs( - &self, - mint_url: UncheckedUrl, - proofs: &Proofs, - ) -> Result<(), Self::Err> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_multimap_table(PROOFS_TABLE)?; - - for proof in proofs { - table.remove( - mint_url.to_string().as_str(), - serde_json::to_string(&proof)?.as_str(), - )?; - } - } - write_txn.commit()?; - - Ok(()) - } - - async fn add_pending_proofs( - &self, - mint_url: UncheckedUrl, - proofs: Proofs, - ) -> Result<(), Self::Err> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_multimap_table(PENDING_PROOFS_TABLE)?; - - for proof in proofs { - table.insert( - mint_url.to_string().as_str(), - serde_json::to_string(&proof)?.as_str(), - )?; - } - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_pending_proofs( - &self, - mint_url: UncheckedUrl, - ) -> Result, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_multimap_table(PENDING_PROOFS_TABLE)?; - - let proofs = table - .get(mint_url.to_string().as_str())? - .flatten() - .flat_map(|k| serde_json::from_str(k.value())) - .collect(); - - Ok(proofs) - } - - async fn remove_pending_proofs( - &self, - mint_url: UncheckedUrl, - proofs: &Proofs, - ) -> Result<(), Self::Err> { - let db = self.db.lock().await; - - let write_txn = db.begin_write()?; - - { - let mut table = write_txn.open_multimap_table(PENDING_PROOFS_TABLE)?; - - for proof in proofs { - table.remove( - mint_url.to_string().as_str(), - serde_json::to_string(&proof)?.as_str(), - )?; - } - } - write_txn.commit()?; - - Ok(()) - } - - async fn increment_keyset_counter(&self, keyset_id: &Id, count: u64) -> Result<(), Self::Err> { - let db = self.db.lock().await; - - let current_counter; - { - let read_txn = db.begin_read()?; - let table = read_txn.open_table(KEYSET_COUNTER)?; - let counter = table.get(keyset_id.to_string().as_str())?; - - current_counter = match counter { - Some(c) => c.value(), - None => 0, - }; - } - - let write_txn = db.begin_write()?; - { - let mut table = write_txn.open_table(KEYSET_COUNTER)?; - let new_counter = current_counter + count; - - table.insert(keyset_id.to_string().as_str(), new_counter)?; - } - write_txn.commit()?; - - Ok(()) - } - - async fn get_keyset_counter(&self, keyset_id: &Id) -> Result, Self::Err> { - let db = self.db.lock().await; - let read_txn = db.begin_read()?; - let table = read_txn.open_table(KEYSET_COUNTER)?; - - let counter = table.get(keyset_id.to_string().as_str())?; - - Ok(counter.map(|c| c.value())) - } -}