fedimint_mint_client/
error.rs1use fedimint_api_client::api::{FederationError, OutputOutcomeError, ServerError};
8use fedimint_client_module::error::{
9 AddStateMachinesError, OperationLookupError, TransactionSubmitError,
10};
11use fedimint_core::config::FederationIdPrefix;
12use fedimint_core::db::DatabaseError;
13use fedimint_core::encoding::DecodeError;
14#[cfg(feature = "uniffi")]
15use fedimint_core::util::FmtCompact as _;
16use fedimint_core::{Amount, PeerId};
17use thiserror::Error;
18
19pub use crate::{InsufficientBalanceError, ReissueExternalNotesError};
20
21#[derive(Debug, Error)]
23#[non_exhaustive]
24pub enum SelectNotesError {
25 #[error("The wallet does not hold enough notes")]
27 InsufficientBalance(#[from] InsufficientBalanceError),
28
29 #[error("The amount {requested} cannot be made exactly; the closest selection is {selected}")]
32 NoExactAmount {
33 requested: Amount,
35 selected: Amount,
37 },
38
39 #[error("A stored note could not be decoded")]
41 Decode(#[from] DecodeError),
42
43 #[error("The note selector failed")]
46 Custom(#[source] Box<dyn std::error::Error + Send + Sync>),
47}
48
49#[derive(Debug, Error)]
51#[non_exhaustive]
52pub enum SpendOOBError {
53 #[error("Zero-amount out-of-band spends are not supported")]
55 ZeroAmount,
56
57 #[error("The notes to spend could not be selected")]
59 NoteSelection(#[from] SelectNotesError),
60
61 #[error("Failed to add the spend's state machines")]
63 StateMachines(#[from] AddStateMachinesError),
64
65 #[error("Database error")]
67 Database(#[from] DatabaseError),
68}
69
70#[derive(Debug, Error)]
72#[non_exhaustive]
73pub enum AwaitOutputFinalizedError {
74 #[error("The transaction was rejected")]
76 TransactionRejected,
77
78 #[error("The notes could not be issued: {reason}")]
83 Failed {
84 reason: String,
86 },
87}
88
89#[derive(Debug, Error)]
91#[non_exhaustive]
92pub enum SendOOBNotesError {
93 #[error("The federation could not be reached")]
96 Federation(#[source] Box<FederationError>),
97
98 #[error("The reissue that would make the right denominations failed")]
100 Transaction(#[from] TransactionSubmitError),
101
102 #[error("Database error")]
104 Database(#[from] DatabaseError),
105}
106
107impl From<FederationError> for SendOOBNotesError {
108 fn from(source: FederationError) -> Self {
109 Self::Federation(Box::new(source))
110 }
111}
112
113#[derive(Debug, Error)]
115#[non_exhaustive]
116pub enum SubscribeReissueExternalNotesError {
117 #[error("The operation could not be looked up")]
119 Operation(#[from] OperationLookupError),
120
121 #[error("The operation is an out-of-band spend, not a reissuance")]
123 NotAReissuance,
124
125 #[error("The reissue operation records no transaction")]
127 NoTransaction,
128}
129
130#[derive(Debug, Error)]
132#[non_exhaustive]
133pub enum SubscribeSpendNotesError {
134 #[error("The operation could not be looked up")]
136 Operation(#[from] OperationLookupError),
137
138 #[error("The operation is a reissuance, not an out-of-band spend")]
140 NotAnOutOfBandSpend,
141}
142
143#[derive(Debug, Error)]
148#[non_exhaustive]
149pub enum ValidateNotesError {
150 #[error("The notes were issued by federation {found}, not {expected}")]
152 WrongFederationId {
153 expected: FederationIdPrefix,
155 found: FederationIdPrefix,
157 },
158
159 #[error("Note {index} claims the amount tier {amount}, which the federation does not issue")]
161 InvalidAmountTier {
162 index: usize,
164 amount: Amount,
166 },
167
168 #[error("Note {index} does not carry a valid federation signature")]
170 InvalidSignature {
171 index: usize,
173 },
174
175 #[error("Note {index} cannot be spent with the supplied spend key")]
177 WrongSpendKey {
178 index: usize,
180 },
181
182 #[error("A stored note could not be decoded")]
184 Decode(#[from] DecodeError),
185}
186
187#[cfg(feature = "uniffi")]
188impl From<ValidateNotesError> for fedimint_core::util::ffi::UniffiError {
189 fn from(e: ValidateNotesError) -> Self {
190 Self::General(e.fmt_compact().to_string())
191 }
192}
193
194#[cfg(feature = "uniffi")]
195impl From<SpendOOBError> for fedimint_core::util::ffi::UniffiError {
196 fn from(e: SpendOOBError) -> Self {
197 Self::General(e.fmt_compact().to_string())
198 }
199}
200
201#[cfg(feature = "uniffi")]
202impl From<ReissueExternalNotesError> for fedimint_core::util::ffi::UniffiError {
203 fn from(e: ReissueExternalNotesError) -> Self {
204 Self::General(e.fmt_compact().to_string())
205 }
206}
207
208#[cfg(feature = "uniffi")]
209impl From<SubscribeReissueExternalNotesError> for fedimint_core::util::ffi::UniffiError {
210 fn from(e: SubscribeReissueExternalNotesError) -> Self {
211 Self::General(e.fmt_compact().to_string())
212 }
213}
214
215#[cfg(feature = "uniffi")]
216impl From<SubscribeSpendNotesError> for fedimint_core::util::ffi::UniffiError {
217 fn from(e: SubscribeSpendNotesError) -> Self {
218 Self::General(e.fmt_compact().to_string())
219 }
220}
221
222#[derive(Debug, Error)]
229#[non_exhaustive]
230pub enum OOBNotesParseError {
231 #[error("The e-cash notes are not a well-formed base32 or base64 string")]
233 Encoding,
234
235 #[error("The e-cash notes could not be decoded: {0}")]
237 Decode(#[from] DecodeError),
238
239 #[error("The e-cash notes are empty")]
241 Empty,
242}
243
244#[derive(Debug, Error)]
246#[non_exhaustive]
247pub enum FetchRecoverySliceError {
248 #[error("The peer did not serve the recovery slice")]
250 Peer(#[from] ServerError),
251
252 #[error("The recovery slice could not be decoded")]
254 Decode(#[from] DecodeError),
255}
256
257#[derive(Debug, Error)]
259#[non_exhaustive]
260pub enum PrepareEcashBackupError {
261 #[error("The federation could not be reached")]
264 Federation(#[source] Box<FederationError>),
265
266 #[error("A stored note could not be decoded")]
268 Decode(#[from] DecodeError),
269}
270
271impl From<FederationError> for PrepareEcashBackupError {
272 fn from(source: FederationError) -> Self {
273 Self::Federation(Box::new(source))
274 }
275}
276
277#[derive(Debug, Error)]
279#[non_exhaustive]
280pub enum RepairWalletError {
281 #[error("The federation could not be reached")]
283 Federation(#[source] Box<FederationError>),
284
285 #[error("Database error")]
287 Database(#[from] DatabaseError),
288}
289
290impl From<FederationError> for RepairWalletError {
291 fn from(source: FederationError) -> Self {
292 Self::Federation(Box::new(source))
293 }
294}
295
296#[derive(Debug, Error)]
298#[non_exhaustive]
299pub enum VerifyBlindShareError {
300 #[error("The output outcome could not be read")]
302 Outcome(#[source] Box<OutputOutcomeError>),
303
304 #[error("No public key share is known for peer {peer}")]
306 UnknownPeer {
307 peer: PeerId,
309 },
310
311 #[error("The federation issues no notes of the amount tier {amount}")]
313 InvalidAmountTier {
314 amount: Amount,
316 },
317
318 #[error("The blind signature share does not verify")]
320 InvalidSignature,
321}
322
323impl From<OutputOutcomeError> for VerifyBlindShareError {
324 fn from(source: OutputOutcomeError) -> Self {
325 Self::Outcome(Box::new(source))
326 }
327}