fedimint_wallet_client/
error.rs1use bitcoin::Network;
7use fedimint_api_client::api::FederationError;
8use fedimint_bitcoind::BitcoinRpcError;
9use fedimint_client_module::error::{
10 OperationAlreadyExistsError, OperationLookupError, TransactionSubmitError,
11};
12use fedimint_core::core::OperationId;
13use fedimint_core::db::{AutocommitError, DatabaseError};
14use thiserror::Error;
15
16use crate::client_db::TweakIdx;
17
18#[derive(Debug, Error)]
25#[non_exhaustive]
26pub enum PegInError {
27 #[error("The address is not one of this client's deposit addresses")]
29 AddressNotDerived,
30
31 #[error("No deposit address belongs to operation {}", .operation_id.fmt_short())]
33 NoAddressForOperation {
34 operation_id: OperationId,
36 },
37
38 #[error("No deposit address is recorded for {tweak_idx}")]
40 TweakIdxNotFound {
41 tweak_idx: TweakIdx,
43 },
44
45 #[error("Database error")]
47 Database(#[from] DatabaseError),
48
49 #[error("The transaction claiming the deposit was rejected: {reason}")]
55 TransactionRejected {
56 reason: String,
58 },
59
60 #[error("The peg-in monitor is no longer running")]
62 MonitorStopped,
63}
64
65impl From<AutocommitError<PegInError>> for PegInError {
66 fn from(e: AutocommitError<Self>) -> Self {
67 match e {
68 AutocommitError::ClosureError { error, .. } => error,
69 AutocommitError::CommitFailed { last_error, .. } => Self::Database(last_error),
70 }
71 }
72}
73
74#[derive(Debug, Error)]
79#[non_exhaustive]
80pub enum DepositAddressError {
81 #[error("The federation was not verified to support safe deposits")]
84 SafeDepositUnverified,
85
86 #[error("The deposit address's operation already exists")]
88 OperationAlreadyExists(#[from] OperationAlreadyExistsError),
89
90 #[error("The bitcoin backend could not watch the deposit address")]
93 BitcoinRpc(#[from] BitcoinRpcError),
94
95 #[error("Database error")]
97 Database(#[from] DatabaseError),
98
99 #[error("The pooled deposit address {tweak_idx} disappeared while it was being reused")]
102 PooledAddressDisappeared {
103 tweak_idx: TweakIdx,
105 },
106
107 #[error("The pooled deposit address {tweak_idx} was used while it was being reused")]
110 PooledAddressUsed {
111 tweak_idx: TweakIdx,
113 },
114}
115
116impl From<AutocommitError<DepositAddressError>> for DepositAddressError {
117 fn from(e: AutocommitError<Self>) -> Self {
118 match e {
119 AutocommitError::ClosureError { error, .. } => error,
120 AutocommitError::CommitFailed { last_error, .. } => Self::Database(last_error),
121 }
122 }
123}
124
125#[derive(Debug, Error)]
127#[non_exhaustive]
128pub enum SubscribeDepositError {
129 #[error("The deposit operation could not be looked up")]
131 Operation(#[from] OperationLookupError),
132
133 #[error("The operation is not a deposit")]
136 NotADeposit,
137
138 #[error("The deposit address is not valid on {expected}")]
141 WrongNetwork {
142 expected: Network,
144 },
145
146 #[error("An old pending deposit cannot be subscribed to")]
149 OldPendingDeposit,
150
151 #[error("The recorded outcome of an old deposit is not final")]
154 NonFinalOutcome,
155}
156
157#[derive(Debug, Error)]
159#[non_exhaustive]
160pub enum WithdrawFeesError {
161 #[error("The peg-out fees could not be fetched")]
163 Federation(#[source] Box<FederationError>),
164
165 #[error("The federation did not quote peg-out fees")]
168 NoQuote,
169}
170
171impl From<FederationError> for WithdrawFeesError {
172 fn from(source: FederationError) -> Self {
173 Self::Federation(Box::new(source))
174 }
175}
176
177#[derive(Debug, Error)]
180#[non_exhaustive]
181pub enum MaxWithdrawableAmountError {
182 #[error("The peg-out fees could not be quoted")]
184 Fees(#[from] WithdrawFeesError),
185
186 #[error("The balance {balance} is too low to cover the dust limit {dust_limit} and fees")]
189 BalanceTooLow {
190 balance: fedimint_core::Amount,
192 dust_limit: bitcoin::Amount,
194 },
195
196 #[error("The fee quote for the withdrawal failed")]
198 Quote(#[source] TransactionSubmitError),
199}
200
201#[derive(Debug, Error)]
203#[non_exhaustive]
204pub enum PegOutError {
205 #[error("The destination address is not valid on {expected}")]
208 WrongNetwork {
209 expected: Network,
211 },
212
213 #[error("The peg-out fees could not be quoted")]
215 Fees(#[from] WithdrawFeesError),
216
217 #[error("The withdrawal transaction could not be submitted")]
219 Transaction(#[from] TransactionSubmitError),
220}
221
222#[derive(Debug, Error)]
224#[non_exhaustive]
225pub enum SubscribeWithdrawError {
226 #[error("The withdrawal operation could not be looked up")]
228 Operation(#[from] OperationLookupError),
229
230 #[error("The operation is not a withdrawal")]
233 NotAWithdrawal,
234}
235
236#[derive(Debug, Error)]
238#[non_exhaustive]
239pub enum ConsensusVersionVotingError {
240 #[error("Admin auth is not set")]
243 AdminAuthMissing,
244
245 #[error("The vote could not be submitted to the federation")]
247 Federation(#[source] Box<FederationError>),
248}
249
250impl From<FederationError> for ConsensusVersionVotingError {
251 fn from(source: FederationError) -> Self {
252 Self::Federation(Box::new(source))
253 }
254}