1use reqwest::Client;
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Debug)]
5pub struct PrivySigner {
6 pub app_id: String,
7 pub app_secret: String,
8 pub wallet_id: String,
9 pub api_base_url: String,
10 pub client: Client,
11 pub public_key: solana_sdk::pubkey::Pubkey,
12}
13
14#[derive(Default)]
15pub struct PrivyConfig {
16 pub app_id: Option<String>,
17 pub app_secret: Option<String>,
18 pub wallet_id: Option<String>,
19}
20
21#[derive(Serialize)]
23pub struct SignTransactionRequest {
24 pub method: &'static str,
25 pub params: SignTransactionParams,
26}
27
28#[derive(Serialize)]
29pub struct SignTransactionParams {
30 pub transaction: String,
31 pub encoding: &'static str,
32}
33
34#[derive(Deserialize, Debug)]
35pub struct SignTransactionResponse {
36 pub method: String,
37 pub data: SignTransactionData,
38}
39
40#[derive(Deserialize, Debug)]
41pub struct SignTransactionData {
42 #[serde(rename = "signed_transaction")]
43 pub signed_transaction: String,
44 pub encoding: String,
45}
46
47#[derive(Deserialize, Debug)]
49pub struct WalletResponse {
50 pub id: String,
51 pub address: String,
52 pub chain_type: String,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub wallet_client_type: Option<String>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub connector_type: Option<String>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub imported: Option<bool>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub delegated: Option<bool>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub hd_path: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub public_key: Option<String>,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub owner_id: Option<String>,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub policy_ids: Option<Vec<String>>,
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub additional_signers: Option<Vec<String>>,
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub exported_at: Option<i64>,
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub created_at: Option<i64>,
75}
76
77#[derive(Debug)]
79pub enum PrivyError {
80 MissingConfig(&'static str),
81 ApiError(u16),
82 InvalidResponse,
83 InvalidPublicKey,
84 InvalidSignature,
85 RequestError(reqwest::Error),
86 JsonError(serde_json::Error),
87 Base64Error(base64::DecodeError),
88 InitializationError,
89 RuntimeError,
90 Other(anyhow::Error),
91}
92
93impl std::fmt::Display for PrivyError {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 match self {
96 PrivyError::MissingConfig(field) => write!(f, "Missing config: {}", field),
97 PrivyError::ApiError(status) => write!(f, "API error: {}", status),
98 PrivyError::InvalidResponse => write!(f, "Invalid response"),
99 PrivyError::InvalidPublicKey => write!(f, "Invalid public key"),
100 PrivyError::InvalidSignature => write!(f, "Invalid signature"),
101 PrivyError::RequestError(e) => write!(f, "Request error: {}", e),
102 PrivyError::JsonError(e) => write!(f, "JSON error: {}", e),
103 PrivyError::Base64Error(e) => write!(f, "Base64 error: {}", e),
104 PrivyError::InitializationError => write!(f, "Initialization error"),
105 PrivyError::RuntimeError => write!(f, "Runtime error"),
106 PrivyError::Other(e) => write!(f, "{}", e),
107 }
108 }
109}
110
111impl std::error::Error for PrivyError {
112 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
113 match self {
114 PrivyError::RequestError(e) => Some(e),
115 PrivyError::JsonError(e) => Some(e),
116 PrivyError::Base64Error(e) => Some(e),
117 PrivyError::Other(e) => Some(e.as_ref()),
118 _ => None,
119 }
120 }
121}
122
123impl From<reqwest::Error> for PrivyError {
124 fn from(err: reqwest::Error) -> Self {
125 PrivyError::RequestError(err)
126 }
127}
128
129impl From<serde_json::Error> for PrivyError {
130 fn from(err: serde_json::Error) -> Self {
131 PrivyError::JsonError(err)
132 }
133}
134
135impl From<base64::DecodeError> for PrivyError {
136 fn from(err: base64::DecodeError) -> Self {
137 PrivyError::Base64Error(err)
138 }
139}
140
141impl From<anyhow::Error> for PrivyError {
142 fn from(err: anyhow::Error) -> Self {
143 PrivyError::Other(err)
144 }
145}