1use thiserror::Error;
2#[cfg(feature = "v4")]
3use world_id_core::primitives::PrimitiveError;
4
5#[cfg(feature = "storage")]
6use crate::storage::StorageError;
7#[cfg(feature = "v4")]
8use world_id_core::AuthenticatorError;
9
10#[derive(Debug, Error, uniffi::Error)]
12pub enum WalletKitError {
13 #[error("invalid_input_{attribute}")]
15 InvalidInput {
16 attribute: String,
18 reason: String,
20 },
21
22 #[error("invalid_number")]
24 InvalidNumber,
25
26 #[error("serialization_error")]
28 SerializationError {
29 error: String,
31 },
32
33 #[error("network_error at {url}: {error}")]
35 NetworkError {
36 url: String,
38 error: String,
40 status: Option<u16>,
42 },
43
44 #[error("request_error")]
46 Reqwest {
47 error: String,
49 },
50
51 #[error("proof_generation_error")]
53 ProofGeneration {
54 error: String,
56 },
57
58 #[error("semaphore_not_enabled")]
60 SemaphoreNotEnabled,
61
62 #[error("credential_not_issued")]
64 CredentialNotIssued,
65
66 #[error("credential_not_mined")]
68 CredentialNotMined,
69
70 #[error("Account is not registered for this authenticator.")]
73 AccountDoesNotExist,
74
75 #[error("Account already exists for this authenticator.")]
77 AccountAlreadyExists,
78
79 #[error("unauthorized_authenticator")]
81 UnauthorizedAuthenticator,
82
83 #[error("unexpected_authenticator_error")]
85 AuthenticatorError {
86 error: String,
88 },
89
90 #[error("unexpected_error: {error}")]
92 Generic {
93 error: String,
95 },
96}
97
98impl From<reqwest::Error> for WalletKitError {
99 fn from(error: reqwest::Error) -> Self {
100 Self::Reqwest {
101 error: error.to_string(),
102 }
103 }
104}
105
106#[cfg(feature = "v4")]
107impl From<PrimitiveError> for WalletKitError {
108 fn from(error: PrimitiveError) -> Self {
109 match error {
110 PrimitiveError::InvalidInput { attribute, reason } => {
111 Self::InvalidInput { attribute, reason }
112 }
113 PrimitiveError::Serialization(error) => Self::SerializationError { error },
114 PrimitiveError::Deserialization(reason) => Self::InvalidInput {
115 attribute: "deserialization".to_string(),
116 reason,
117 },
118 PrimitiveError::NotInField => Self::InvalidInput {
119 attribute: "field_element".to_string(),
120 reason: "Provided value is not in the field".to_string(),
121 },
122 PrimitiveError::OutOfBounds => Self::InvalidInput {
123 attribute: "index".to_string(),
124 reason: "Provided index is out of bounds".to_string(),
125 },
126 }
127 }
128}
129
130impl From<semaphore_rs::protocol::ProofError> for WalletKitError {
131 fn from(error: semaphore_rs::protocol::ProofError) -> Self {
132 Self::ProofGeneration {
133 error: error.to_string(),
134 }
135 }
136}
137
138#[cfg(feature = "storage")]
139impl From<StorageError> for WalletKitError {
140 fn from(error: StorageError) -> Self {
141 Self::Generic {
142 error: error.to_string(),
143 }
144 }
145}
146
147#[cfg(feature = "v4")]
148impl From<AuthenticatorError> for WalletKitError {
149 fn from(error: AuthenticatorError) -> Self {
150 match error {
151 AuthenticatorError::AccountDoesNotExist => Self::AccountDoesNotExist,
152 AuthenticatorError::AccountAlreadyExists => Self::AccountAlreadyExists,
153
154 AuthenticatorError::NetworkError(error) => Self::NetworkError {
155 url: error
156 .url()
157 .map(std::string::ToString::to_string)
158 .unwrap_or_default(),
159 error: error.to_string(),
160 status: None,
161 },
162 AuthenticatorError::PublicKeyNotFound => Self::UnauthorizedAuthenticator,
163 AuthenticatorError::GatewayError { status, body } => Self::NetworkError {
164 url: "gateway".to_string(),
165 error: body,
166 status: Some(status.as_u16()),
167 },
168 AuthenticatorError::PrimitiveError(error) => Self::from(error),
169
170 _ => Self::AuthenticatorError {
171 error: error.to_string(),
172 },
173 }
174 }
175}