cdk_common/database/
mod.rs1mod kvstore;
4
5#[cfg(feature = "mint")]
6pub mod mint;
7#[cfg(feature = "wallet")]
8pub mod wallet;
9
10pub use kvstore::{
12 validate_kvstore_params, validate_kvstore_string, KVStore, KVStoreCompareAndSwap,
13 KVStoreDatabase, KVStoreTransaction, KVSTORE_NAMESPACE_KEY_ALPHABET,
14 KVSTORE_NAMESPACE_KEY_MAX_LEN,
15};
16
17pub type DynKVStore = std::sync::Arc<dyn KVStore<Err = Error> + Send + Sync>;
19
20#[cfg(feature = "mint")]
21pub use mint::{
22 Database as MintDatabase, DynMintDatabase, DynMintTransaction,
23 KeysDatabase as MintKeysDatabase, KeysDatabaseTransaction as MintKeyDatabaseTransaction,
24 ProofsDatabase as MintProofsDatabase, ProofsTransaction as MintProofsTransaction,
25 QuotesDatabase as MintQuotesDatabase, QuotesTransaction as MintQuotesTransaction,
26 SignaturesDatabase as MintSignaturesDatabase,
27 SignaturesTransaction as MintSignatureTransaction, Transaction as MintTransaction,
28};
29#[cfg(feature = "mint")]
30pub use mint::{DynMintAuthDatabase, MintAuthDatabase, MintAuthTransaction};
31#[cfg(feature = "wallet")]
32pub use wallet::Database as WalletDatabase;
33
34#[derive(thiserror::Error, Debug)]
36pub enum ConversionError {
37 #[error("Not enough elements: expected {0}, got {1}")]
39 MissingColumn(usize, usize),
40
41 #[error("Missing parameter {0}")]
43 MissingParameter(String),
44
45 #[error("Invalid type from db, expected {0} got {1}")]
47 InvalidType(String, String),
48
49 #[error("Error converting {1}, expecting type {0}")]
51 InvalidConversion(String, String),
52
53 #[error(transparent)]
55 MintUrl(#[from] crate::mint_url::Error),
56
57 #[error(transparent)]
59 CDKNUT00(#[from] crate::nuts::nut00::Error),
60
61 #[error(transparent)]
63 CDKNUT01(#[from] crate::nuts::nut01::Error),
64
65 #[error(transparent)]
67 CDKNUT02(#[from] crate::nuts::nut02::Error),
68
69 #[error(transparent)]
71 CDKNUT04(#[from] crate::nuts::nut04::Error),
72
73 #[error(transparent)]
75 CDKNUT05(#[from] crate::nuts::nut05::Error),
76
77 #[error(transparent)]
79 CDKNUT07(#[from] crate::nuts::nut07::Error),
80
81 #[error(transparent)]
83 CDKNUT23(#[from] crate::nuts::nut23::Error),
84
85 #[error(transparent)]
87 CDKSECRET(#[from] crate::secret::Error),
88
89 #[error(transparent)]
91 Serde(#[from] serde_json::Error),
92
93 #[error(transparent)]
95 BIP32(#[from] bitcoin::bip32::Error),
96
97 #[error(transparent)]
99 Generic(#[from] Box<crate::Error>),
100}
101
102impl From<crate::Error> for ConversionError {
103 fn from(err: crate::Error) -> Self {
104 ConversionError::Generic(Box::new(err))
105 }
106}
107
108#[derive(Debug, thiserror::Error)]
110pub enum Error {
111 #[error(transparent)]
113 Database(Box<dyn std::error::Error + Send + Sync>),
114
115 #[error("Duplicate entry")]
117 Duplicate,
118
119 #[error("Locked resource")]
121 Locked,
122
123 #[error("Amount overflow")]
125 AmountOverflow,
126 #[error("Amount zero")]
128 AmountZero,
129
130 #[error(transparent)]
132 DHKE(#[from] crate::dhke::Error),
133 #[error(transparent)]
135 NUT00(#[from] crate::nuts::nut00::Error),
136 #[error(transparent)]
138 NUT01(#[from] crate::nuts::nut01::Error),
139 #[error(transparent)]
141 NUT02(#[from] crate::nuts::nut02::Error),
142 #[error(transparent)]
144 NUT22(#[from] crate::nuts::nut22::Error),
145 #[error(transparent)]
147 NUT04(#[from] crate::nuts::nut04::Error),
148 #[error(transparent)]
150 #[cfg(feature = "mint")]
151 QuoteId(#[from] crate::quote_id::QuoteIdError),
152 #[error(transparent)]
154 Serde(#[from] serde_json::Error),
155 #[error("Unknown Quote")]
157 UnknownQuote,
158 #[error("Attempt to remove spent proof")]
160 AttemptRemoveSpentProof,
161 #[error("Attempt to update state of spent proof")]
163 AttemptUpdateSpentProof,
164 #[error("Proof not found")]
166 ProofNotFound,
167 #[error("Proof not in unspent state")]
169 ProofNotUnspent,
170 #[error("Quote already in use by another operation")]
172 QuoteAlreadyInUse,
173 #[error("Unknown or invalid keyset")]
175 InvalidKeysetId,
176 #[cfg(feature = "mint")]
177 #[error("Invalid state transition")]
179 InvalidStateTransition(crate::state::Error),
180
181 #[error("Invalid credentials {0}")]
183 InvalidConnectionSettings(String),
184
185 #[error("Invalid database response")]
187 InvalidDbResponse,
188
189 #[error("Internal {0}")]
191 Internal(String),
192
193 #[error(transparent)]
195 Conversion(#[from] ConversionError),
196
197 #[error("Missing placeholder value {0}")]
199 MissingPlaceholder(String),
200
201 #[error("Empty IN clause for placeholder: {0}")]
203 EmptyInClause(String),
204
205 #[error("Unknown quote ttl")]
207 UnknownQuoteTTL,
208
209 #[error("Invalid UUID: {0}")]
211 InvalidUuid(String),
212
213 #[error("Quote not found")]
215 QuoteNotFound,
216
217 #[error("Invalid KV store key or namespace: {0}")]
219 KVStoreInvalidKey(String),
220
221 #[error("Concurrent update detected")]
223 ConcurrentUpdate,
224}
225
226#[cfg(feature = "mint")]
227impl From<crate::state::Error> for Error {
228 fn from(state: crate::state::Error) -> Self {
229 match state {
230 crate::state::Error::AlreadySpent => Error::AttemptUpdateSpentProof,
231 _ => Error::InvalidStateTransition(state),
232 }
233 }
234}
235
236#[async_trait::async_trait]
237pub trait DbTransactionFinalizer {
239 type Err: Into<Error> + From<Error>;
241
242 async fn commit(self: Box<Self>) -> Result<(), Self::Err>;
244
245 async fn rollback(self: Box<Self>) -> Result<(), Self::Err>;
247}