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, KVStoreDatabase, KVStoreTransaction,
13 KVSTORE_NAMESPACE_KEY_ALPHABET, KVSTORE_NAMESPACE_KEY_MAX_LEN,
14};
15
16pub type DynKVStore = std::sync::Arc<dyn KVStore<Err = Error> + Send + Sync>;
18
19#[cfg(feature = "mint")]
20pub use mint::{
21 Database as MintDatabase, DynMintDatabase, DynMintTransaction,
22 KeysDatabase as MintKeysDatabase, KeysDatabaseTransaction as MintKeyDatabaseTransaction,
23 ProofsDatabase as MintProofsDatabase, ProofsTransaction as MintProofsTransaction,
24 QuotesDatabase as MintQuotesDatabase, QuotesTransaction as MintQuotesTransaction,
25 SignaturesDatabase as MintSignaturesDatabase,
26 SignaturesTransaction as MintSignatureTransaction, Transaction as MintTransaction,
27};
28#[cfg(feature = "mint")]
29pub use mint::{DynMintAuthDatabase, MintAuthDatabase, MintAuthTransaction};
30#[cfg(feature = "wallet")]
31pub use wallet::Database as WalletDatabase;
32
33#[derive(thiserror::Error, Debug)]
35pub enum ConversionError {
36 #[error("Not enough elements: expected {0}, got {1}")]
38 MissingColumn(usize, usize),
39
40 #[error("Missing parameter {0}")]
42 MissingParameter(String),
43
44 #[error("Invalid type from db, expected {0} got {1}")]
46 InvalidType(String, String),
47
48 #[error("Error converting {1}, expecting type {0}")]
50 InvalidConversion(String, String),
51
52 #[error(transparent)]
54 MintUrl(#[from] crate::mint_url::Error),
55
56 #[error(transparent)]
58 CDKNUT00(#[from] crate::nuts::nut00::Error),
59
60 #[error(transparent)]
62 CDKNUT01(#[from] crate::nuts::nut01::Error),
63
64 #[error(transparent)]
66 CDKNUT02(#[from] crate::nuts::nut02::Error),
67
68 #[error(transparent)]
70 CDKNUT04(#[from] crate::nuts::nut04::Error),
71
72 #[error(transparent)]
74 CDKNUT05(#[from] crate::nuts::nut05::Error),
75
76 #[error(transparent)]
78 CDKNUT07(#[from] crate::nuts::nut07::Error),
79
80 #[error(transparent)]
82 CDKNUT23(#[from] crate::nuts::nut23::Error),
83
84 #[error(transparent)]
86 CDKSECRET(#[from] crate::secret::Error),
87
88 #[error(transparent)]
90 Serde(#[from] serde_json::Error),
91
92 #[error(transparent)]
94 BIP32(#[from] bitcoin::bip32::Error),
95
96 #[error(transparent)]
98 Generic(#[from] Box<crate::Error>),
99}
100
101impl From<crate::Error> for ConversionError {
102 fn from(err: crate::Error) -> Self {
103 ConversionError::Generic(Box::new(err))
104 }
105}
106
107#[derive(Debug, thiserror::Error)]
109pub enum Error {
110 #[error(transparent)]
112 Database(Box<dyn std::error::Error + Send + Sync>),
113
114 #[error("Duplicate entry")]
116 Duplicate,
117
118 #[error("Locked resource")]
120 Locked,
121
122 #[error("Amount overflow")]
124 AmountOverflow,
125 #[error("Amount zero")]
127 AmountZero,
128
129 #[error(transparent)]
131 DHKE(#[from] crate::dhke::Error),
132 #[error(transparent)]
134 NUT00(#[from] crate::nuts::nut00::Error),
135 #[error(transparent)]
137 NUT01(#[from] crate::nuts::nut01::Error),
138 #[error(transparent)]
140 NUT02(#[from] crate::nuts::nut02::Error),
141 #[error(transparent)]
143 NUT22(#[from] crate::nuts::nut22::Error),
144 #[error(transparent)]
146 NUT04(#[from] crate::nuts::nut04::Error),
147 #[error(transparent)]
149 #[cfg(feature = "mint")]
150 QuoteId(#[from] crate::quote_id::QuoteIdError),
151 #[error(transparent)]
153 Serde(#[from] serde_json::Error),
154 #[error("Unknown Quote")]
156 UnknownQuote,
157 #[error("Attempt to remove spent proof")]
159 AttemptRemoveSpentProof,
160 #[error("Attempt to update state of spent proof")]
162 AttemptUpdateSpentProof,
163 #[error("Proof not found")]
165 ProofNotFound,
166 #[error("Proof not in unspent state")]
168 ProofNotUnspent,
169 #[error("Quote already in use by another operation")]
171 QuoteAlreadyInUse,
172 #[error("Unknown or invalid keyset")]
174 InvalidKeysetId,
175 #[cfg(feature = "mint")]
176 #[error("Invalid state transition")]
178 InvalidStateTransition(crate::state::Error),
179
180 #[error("Invalid credentials {0}")]
182 InvalidConnectionSettings(String),
183
184 #[error("Invalid database response")]
186 InvalidDbResponse,
187
188 #[error("Internal {0}")]
190 Internal(String),
191
192 #[error(transparent)]
194 Conversion(#[from] ConversionError),
195
196 #[error("Missing placeholder value {0}")]
198 MissingPlaceholder(String),
199
200 #[error("Empty IN clause for placeholder: {0}")]
202 EmptyInClause(String),
203
204 #[error("Unknown quote ttl")]
206 UnknownQuoteTTL,
207
208 #[error("Invalid UUID: {0}")]
210 InvalidUuid(String),
211
212 #[error("Quote not found")]
214 QuoteNotFound,
215
216 #[error("Invalid KV store key or namespace: {0}")]
218 KVStoreInvalidKey(String),
219
220 #[error("Concurrent update detected")]
222 ConcurrentUpdate,
223}
224
225#[cfg(feature = "mint")]
226impl From<crate::state::Error> for Error {
227 fn from(state: crate::state::Error) -> Self {
228 match state {
229 crate::state::Error::AlreadySpent => Error::AttemptUpdateSpentProof,
230 _ => Error::InvalidStateTransition(state),
231 }
232 }
233}
234
235#[async_trait::async_trait]
236pub trait DbTransactionFinalizer {
238 type Err: Into<Error> + From<Error>;
240
241 async fn commit(self: Box<Self>) -> Result<(), Self::Err>;
243
244 async fn rollback(self: Box<Self>) -> Result<(), Self::Err>;
246}