circle_user_controlled_wallets/models/
challenge.rs1use serde::{Deserialize, Serialize};
8
9use super::{
10 common::{AccountType, Blockchain},
11 wallet::WalletMetadata,
12};
13
14#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
18#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
19pub enum ChallengeType {
20 Initialize,
22 SetPin,
24 ChangePin,
26 SetSecurityQuestions,
28 CreateWallet,
30 RestorePin,
32 CreateTransaction,
34 AccelerateTransaction,
36 CancelTransaction,
38 ContractExecution,
40 WalletUpgrade,
42 SignMessage,
44 SignTypeddata,
46 SignTransaction,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
52#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
53pub enum ChallengeStatus {
54 Pending,
56 InProgress,
58 Complete,
60 Failed,
62 Expired,
64}
65
66#[derive(Debug, Clone, Deserialize, Serialize)]
70#[serde(rename_all = "camelCase")]
71pub struct Challenge {
72 pub id: String,
74 #[serde(rename = "type")]
76 pub challenge_type: ChallengeType,
77 pub status: ChallengeStatus,
79 pub correlation_ids: Option<Vec<String>>,
81 pub error_code: Option<i32>,
83 pub error_message: Option<String>,
85}
86
87#[derive(Debug, Clone, Deserialize, Serialize)]
89#[serde(rename_all = "camelCase")]
90pub struct ChallengesData {
91 pub challenges: Vec<Challenge>,
93}
94
95#[derive(Debug, Clone, Deserialize, Serialize)]
97#[serde(rename_all = "camelCase")]
98pub struct Challenges {
99 pub data: ChallengesData,
101}
102
103#[derive(Debug, Clone, Deserialize, Serialize)]
105#[serde(rename_all = "camelCase")]
106pub struct ChallengeData {
107 pub challenge: Challenge,
109}
110
111#[derive(Debug, Clone, Deserialize, Serialize)]
113#[serde(rename_all = "camelCase")]
114pub struct ChallengeResponse {
115 pub data: ChallengeData,
117}
118
119#[derive(Debug, Clone, Deserialize, Serialize)]
121#[serde(rename_all = "camelCase")]
122pub struct ChallengeIdData {
123 pub challenge_id: String,
125}
126
127#[derive(Debug, Clone, Deserialize, Serialize)]
129#[serde(rename_all = "camelCase")]
130pub struct ChallengeIdResponse {
131 pub data: ChallengeIdData,
133}
134
135#[derive(Debug, Clone, Deserialize, Serialize)]
139#[serde(rename_all = "camelCase")]
140pub struct SetPinAndInitWalletRequest {
141 pub idempotency_key: String,
143 pub account_type: Option<AccountType>,
145 pub blockchains: Option<Vec<Blockchain>>,
147 pub metadata: Option<Vec<WalletMetadata>>,
149}
150
151#[derive(Debug, Clone, Deserialize, Serialize)]
153#[serde(rename_all = "camelCase")]
154pub struct SetPinRequest {
155 pub idempotency_key: String,
157}
158
159#[cfg(test)]
162mod tests {
163 use super::*;
164
165 #[test]
166 fn challenge_type_screaming() -> Result<(), Box<dyn std::error::Error>> {
167 assert_eq!(serde_json::to_string(&ChallengeType::CreateWallet)?, "\"CREATE_WALLET\"");
168 assert_eq!(serde_json::to_string(&ChallengeType::SignTypeddata)?, "\"SIGN_TYPEDDATA\"");
169 Ok(())
170 }
171
172 #[test]
173 fn challenge_status_screaming() -> Result<(), Box<dyn std::error::Error>> {
174 assert_eq!(serde_json::to_string(&ChallengeStatus::Complete)?, "\"COMPLETE\"");
175 assert_eq!(serde_json::to_string(&ChallengeStatus::InProgress)?, "\"IN_PROGRESS\"");
176 Ok(())
177 }
178
179 #[test]
180 fn challenge_id_response_round_trip() -> Result<(), Box<dyn std::error::Error>> {
181 let json = r#"{"data":{"challengeId":"abc-123"}}"#;
182 let resp: ChallengeIdResponse = serde_json::from_str(json)?;
183 assert_eq!(resp.data.challenge_id, "abc-123");
184 Ok(())
185 }
186
187 #[test]
188 fn challenge_type_field_renamed_to_type() -> Result<(), Box<dyn std::error::Error>> {
189 let c = Challenge {
190 id: "c1".to_string(),
191 challenge_type: ChallengeType::SetPin,
192 status: ChallengeStatus::Pending,
193 correlation_ids: None,
194 error_code: None,
195 error_message: None,
196 };
197 let s = serde_json::to_string(&c)?;
198 assert!(s.contains("\"type\""), "expected type key in {s}");
199 Ok(())
200 }
201}