1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Deserialize)]
7pub struct Wallet {
8 pub id: String,
9 pub address: String,
10 pub chain_type: String,
11 #[serde(default)]
12 pub policy_ids: Vec<String>,
13 #[serde(default)]
14 pub additional_signers: Vec<WalletSigner>,
15}
16
17#[derive(Debug, Clone, Deserialize)]
19pub struct WalletSigner {
20 pub signer_id: String,
21 #[serde(default)]
22 pub override_policy_ids: Vec<String>,
23}
24
25#[derive(Debug, Deserialize)]
27pub struct WalletsResponse {
28 pub data: Vec<Wallet>,
29}
30
31#[derive(Debug, Deserialize)]
35pub struct SignTransactionResponse {
36 #[serde(default)]
37 pub method: String,
38 pub data: SignTransactionData,
39}
40
41#[derive(Debug, Deserialize)]
43pub struct SignTransactionData {
44 pub signed_transaction: String,
45 #[serde(default)]
46 pub encoding: String,
47}
48
49#[derive(Debug, Serialize)]
53pub struct CreatePolicyRequest {
54 pub version: String,
55 pub name: String,
56 pub chain_type: String,
57 pub rules: Vec<PolicyRule>,
58}
59
60#[derive(Debug, Clone, Serialize)]
62pub struct PolicyRule {
63 pub name: String,
64 pub method: String,
65 pub conditions: Vec<PolicyCondition>,
66 pub action: String,
67}
68
69#[derive(Debug, Clone, Serialize)]
71pub struct PolicyCondition {
72 pub field_source: String,
73 pub field: String,
74 pub operator: String,
75 pub value: serde_json::Value,
76}
77
78#[derive(Debug, Deserialize)]
80pub struct CreatePolicyResponse {
81 pub id: String,
82}
83
84#[derive(Debug, Deserialize, Default)]
86#[serde(default)]
87pub struct GetPolicyResponse {
88 pub id: String,
89 pub name: String,
90 pub rules: Vec<PolicyRuleResponse>,
91}
92
93#[derive(Debug, Deserialize, Default)]
95#[serde(default)]
96pub struct PolicyRuleResponse {
97 pub id: String,
98 pub name: String,
99 pub method: String,
100 pub conditions: Vec<PolicyConditionResponse>,
101 pub action: String,
102}
103
104#[derive(Debug, Deserialize, Default)]
106#[serde(default)]
107pub struct PolicyConditionResponse {
108 pub field_source: String,
109 pub field: String,
110 pub operator: String,
111 pub value: serde_json::Value,
112}
113
114#[derive(Debug, Serialize, Deserialize)]
118pub struct PrivyClaims {
119 pub aud: String,
120 pub exp: u64,
121 pub iss: String,
122 pub sub: String,
124 pub sid: String,
125 pub iat: u64,
126 #[serde(default)]
127 pub linked_accounts: Option<String>,
128 #[serde(default)]
129 pub custom_metadata: Option<String>,
130}
131
132#[derive(Debug, Clone, Deserialize)]
134#[serde(tag = "type", rename_all = "snake_case")]
135pub enum LinkedAccount {
136 Email {
137 address: String,
138 },
139 Wallet {
140 address: String,
141 #[serde(default)]
142 chain_type: Option<String>,
143 },
144 Phone {
145 #[serde(rename = "phoneNumber")]
146 phone_number: String,
147 },
148 Google {
149 email: String,
150 #[serde(default)]
151 name: Option<String>,
152 },
153 Apple {
154 email: String,
155 },
156 #[serde(other)]
157 Unknown,
158}
159
160impl PrivyClaims {
161 pub fn get_email(&self) -> Option<String> {
163 let accounts_json = self.linked_accounts.as_ref()?;
164 let accounts: Vec<LinkedAccount> = serde_json::from_str(accounts_json).ok()?;
165 accounts.into_iter().find_map(|acc| match acc {
166 LinkedAccount::Email { address } => Some(address),
167 LinkedAccount::Google { email, .. } => Some(email),
168 LinkedAccount::Apple { email } => Some(email),
169 _ => None,
170 })
171 }
172
173 pub fn get_all_emails(&self) -> Vec<String> {
175 let Some(accounts_json) = self.linked_accounts.as_ref() else {
176 return Vec::new();
177 };
178 let Ok(accounts) = serde_json::from_str::<Vec<LinkedAccount>>(accounts_json) else {
179 return Vec::new();
180 };
181 accounts
182 .into_iter()
183 .filter_map(|acc| match acc {
184 LinkedAccount::Email { address } => Some(address),
185 LinkedAccount::Google { email, .. } => Some(email),
186 LinkedAccount::Apple { email } => Some(email),
187 _ => None,
188 })
189 .collect()
190 }
191
192 pub fn get_wallet_addresses(&self) -> Vec<String> {
194 let Some(accounts_json) = self.linked_accounts.as_ref() else {
195 return Vec::new();
196 };
197 let Ok(accounts) = serde_json::from_str::<Vec<LinkedAccount>>(accounts_json) else {
198 return Vec::new();
199 };
200 accounts
201 .into_iter()
202 .filter_map(|acc| match acc {
203 LinkedAccount::Wallet { address, .. } => Some(address),
204 _ => None,
205 })
206 .collect()
207 }
208}