Skip to main content

cdk_common/database/wallet/
mod.rs

1//! CDK Database
2
3use std::collections::HashMap;
4use std::fmt::Debug;
5
6use async_trait::async_trait;
7use cashu::KeySet;
8
9use super::Error;
10use crate::mint_url::MintUrl;
11use crate::nuts::{
12    CurrencyUnit, Id, KeySetInfo, Keys, MintInfo, PublicKey, SpendingConditions, State,
13};
14use crate::wallet::{
15    self, MintQuote as WalletMintQuote, ProofInfo, Transaction, TransactionDirection, TransactionId,
16};
17
18#[cfg(feature = "test")]
19pub mod test;
20
21/// Wallet Database trait
22#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
23#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
24pub trait Database<Err>: Debug
25where
26    Err: Into<Error> + From<Error>,
27{
28    /// Get mint from storage
29    async fn get_mint(&self, mint_url: MintUrl) -> Result<Option<MintInfo>, Err>;
30
31    /// Get all mints from storage
32    async fn get_mints(&self) -> Result<HashMap<MintUrl, Option<MintInfo>>, Err>;
33
34    /// Get mint keysets for mint url
35    async fn get_mint_keysets(&self, mint_url: MintUrl) -> Result<Option<Vec<KeySetInfo>>, Err>;
36
37    /// Get mint keyset by id
38    async fn get_keyset_by_id(&self, keyset_id: &Id) -> Result<Option<KeySetInfo>, Err>;
39
40    /// Get mint quote from storage
41    async fn get_mint_quote(&self, quote_id: &str) -> Result<Option<WalletMintQuote>, Err>;
42
43    /// Get mint quotes from storage
44    async fn get_mint_quotes(&self) -> Result<Vec<WalletMintQuote>, Err>;
45    /// Get unissued mint quotes from storage
46    /// Returns bolt11 quotes where nothing has been issued yet (amount_issued = 0) and all bolt12 quotes.
47    /// Includes unpaid bolt11 quotes to allow checking with the mint if they've been paid (wallet state may be outdated).
48    async fn get_unissued_mint_quotes(&self) -> Result<Vec<WalletMintQuote>, Err>;
49
50    /// Get melt quote from storage
51    async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<wallet::MeltQuote>, Err>;
52
53    /// Get melt quotes from storage
54    async fn get_melt_quotes(&self) -> Result<Vec<wallet::MeltQuote>, Err>;
55
56    /// Get [`Keys`] from storage
57    async fn get_keys(&self, id: &Id) -> Result<Option<Keys>, Err>;
58
59    /// Get proofs from storage
60    async fn get_proofs(
61        &self,
62        mint_url: Option<MintUrl>,
63        unit: Option<CurrencyUnit>,
64        state: Option<Vec<State>>,
65        spending_conditions: Option<Vec<SpendingConditions>>,
66    ) -> Result<Vec<ProofInfo>, Err>;
67
68    /// Get proofs by Y values
69    async fn get_proofs_by_ys(&self, ys: Vec<PublicKey>) -> Result<Vec<ProofInfo>, Err>;
70
71    /// Get balance
72    async fn get_balance(
73        &self,
74        mint_url: Option<MintUrl>,
75        unit: Option<CurrencyUnit>,
76        state: Option<Vec<State>>,
77    ) -> Result<u64, Err>;
78
79    /// Get transaction from storage
80    async fn get_transaction(
81        &self,
82        transaction_id: TransactionId,
83    ) -> Result<Option<Transaction>, Err>;
84
85    /// List transactions from storage
86    async fn list_transactions(
87        &self,
88        mint_url: Option<MintUrl>,
89        direction: Option<TransactionDirection>,
90        unit: Option<CurrencyUnit>,
91    ) -> Result<Vec<Transaction>, Err>;
92
93    /// Update the proofs in storage by adding new proofs or removing proofs by
94    /// their Y value
95    async fn update_proofs(
96        &self,
97        added: Vec<ProofInfo>,
98        removed_ys: Vec<PublicKey>,
99    ) -> Result<(), Err>;
100
101    /// Update proofs state in storage
102    async fn update_proofs_state(&self, ys: Vec<PublicKey>, state: State) -> Result<(), Err>;
103
104    /// Add transaction to storage
105    async fn add_transaction(&self, transaction: Transaction) -> Result<(), Err>;
106
107    /// Update mint url
108    async fn update_mint_url(
109        &self,
110        old_mint_url: MintUrl,
111        new_mint_url: MintUrl,
112    ) -> Result<(), Err>;
113
114    /// Atomically increment Keyset counter and return new value
115    async fn increment_keyset_counter(&self, keyset_id: &Id, count: u32) -> Result<u32, Err>;
116
117    /// Add Mint to storage
118    async fn add_mint(&self, mint_url: MintUrl, mint_info: Option<MintInfo>) -> Result<(), Err>;
119
120    /// Remove Mint from storage
121    async fn remove_mint(&self, mint_url: MintUrl) -> Result<(), Err>;
122
123    /// Add mint keyset to storage
124    async fn add_mint_keysets(
125        &self,
126        mint_url: MintUrl,
127        keysets: Vec<KeySetInfo>,
128    ) -> Result<(), Err>;
129
130    /// Add mint quote to storage
131    async fn add_mint_quote(&self, quote: WalletMintQuote) -> Result<(), Err>;
132
133    /// Remove mint quote from storage
134    async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Err>;
135
136    /// Add melt quote to storage
137    async fn add_melt_quote(&self, quote: wallet::MeltQuote) -> Result<(), Err>;
138
139    /// Remove melt quote from storage
140    async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Err>;
141
142    /// Add [`Keys`] to storage
143    async fn add_keys(&self, keyset: KeySet) -> Result<(), Err>;
144
145    /// Remove [`Keys`] from storage
146    async fn remove_keys(&self, id: &Id) -> Result<(), Err>;
147
148    /// Remove transaction from storage
149    async fn remove_transaction(&self, transaction_id: TransactionId) -> Result<(), Err>;
150
151    /// Add a wallet saga to storage.
152    ///
153    /// The saga should be created with `WalletSaga::new()` which initializes
154    /// `version = 0`. This is the starting point for optimistic locking.
155    async fn add_saga(&self, saga: wallet::WalletSaga) -> Result<(), Err>;
156
157    /// Get a wallet saga by ID.
158    async fn get_saga(&self, id: &uuid::Uuid) -> Result<Option<wallet::WalletSaga>, Err>;
159
160    /// Update a wallet saga with optimistic locking.
161    ///
162    /// Returns `Ok(true)` if the update succeeded (version match), or `Ok(false)`
163    /// if another instance modified the saga first (version mismatch).
164    async fn update_saga(&self, saga: wallet::WalletSaga) -> Result<bool, Err>;
165
166    /// Delete a wallet saga.
167    async fn delete_saga(&self, id: &uuid::Uuid) -> Result<(), Err>;
168
169    /// Get all incomplete sagas.
170    async fn get_incomplete_sagas(&self) -> Result<Vec<wallet::WalletSaga>, Err>;
171
172    /// Reserve proofs for an operation
173    async fn reserve_proofs(
174        &self,
175        ys: Vec<PublicKey>,
176        operation_id: &uuid::Uuid,
177    ) -> Result<(), Err>;
178
179    /// Release proofs reserved by an operation
180    async fn release_proofs(&self, operation_id: &uuid::Uuid) -> Result<(), Err>;
181
182    /// Get proofs reserved by an operation
183    async fn get_reserved_proofs(&self, operation_id: &uuid::Uuid) -> Result<Vec<ProofInfo>, Err>;
184
185    /// Reserve a melt quote for an operation.
186    async fn reserve_melt_quote(
187        &self,
188        quote_id: &str,
189        operation_id: &uuid::Uuid,
190    ) -> Result<(), Err>;
191
192    /// Release a melt quote reserved by an operation.
193    async fn release_melt_quote(&self, operation_id: &uuid::Uuid) -> Result<(), Err>;
194
195    /// Reserve a mint quote for an operation.
196    async fn reserve_mint_quote(
197        &self,
198        quote_id: &str,
199        operation_id: &uuid::Uuid,
200    ) -> Result<(), Err>;
201
202    /// Release a mint quote reserved by an operation.
203    async fn release_mint_quote(&self, operation_id: &uuid::Uuid) -> Result<(), Err>;
204
205    /// Read a value from the key-value store
206    async fn kv_read(
207        &self,
208        primary_namespace: &str,
209        secondary_namespace: &str,
210        key: &str,
211    ) -> Result<Option<Vec<u8>>, Err>;
212
213    /// List keys in a namespace
214    async fn kv_list(
215        &self,
216        primary_namespace: &str,
217        secondary_namespace: &str,
218    ) -> Result<Vec<String>, Err>;
219
220    /// Write a value to the key-value store
221    async fn kv_write(
222        &self,
223        primary_namespace: &str,
224        secondary_namespace: &str,
225        key: &str,
226        value: &[u8],
227    ) -> Result<(), Err>;
228
229    /// Remove a value from the key-value store
230    async fn kv_remove(
231        &self,
232        primary_namespace: &str,
233        secondary_namespace: &str,
234        key: &str,
235    ) -> Result<(), Err>;
236}