1use super::{Error, ResponseValue, types};
2use crate::{
3 AuthorizationContext, PrivyApiError, PrivyExportError, PrivyHpke, PrivySignedApiError,
4 ethereum::EthereumService,
5 generate_authorization_signatures,
6 generated::types::{
7 HpkeEncryption, PrivateKeyInitInput, Wallet, WalletExportRequestBody,
8 WalletImportSubmissionRequestAdditionalSignersItem, WalletImportSubmissionRequestOwner,
9 WalletImportSupportedChains,
10 },
11 import::WalletImport,
12 solana::SolanaService,
13 subclients::WalletsClient,
14};
15
16impl WalletsClient {
17 pub async fn rpc<'a>(
25 &'a self,
26 wallet_id: &'a str,
27 ctx: &'a AuthorizationContext,
28 privy_idempotency_key: Option<&'a str>,
29 body: &'a crate::generated::types::WalletRpcBody,
30 ) -> Result<ResponseValue<crate::generated::types::WalletRpcResponse>, PrivySignedApiError>
31 {
32 let sig = generate_authorization_signatures(
33 ctx,
34 &self.app_id,
35 crate::Method::POST,
36 format!("{}/v1/wallets/{}/rpc", self.base_url, wallet_id),
37 body,
38 privy_idempotency_key.map(|k| k.to_owned()),
39 )
40 .await?;
41
42 Ok(self
43 ._rpc(wallet_id, Some(&sig), privy_idempotency_key, body)
44 .await?)
45 }
46
47 pub async fn raw_sign<'a>(
55 &'a self,
56 wallet_id: &'a str,
57 ctx: &'a AuthorizationContext,
58 privy_idempotency_key: Option<&'a str>,
59 body: &'a crate::generated::types::RawSign,
60 ) -> Result<ResponseValue<crate::generated::types::RawSignResponse>, PrivySignedApiError> {
61 let sig = generate_authorization_signatures(
62 ctx,
63 &self.app_id,
64 crate::Method::POST,
65 format!("{}/v1/wallets/{}/raw_sign", self.base_url, wallet_id),
66 body,
67 privy_idempotency_key.map(|k| k.to_owned()),
68 )
69 .await?;
70
71 Ok(self
72 ._raw_sign(wallet_id, Some(&sig), privy_idempotency_key, body)
73 .await?)
74 }
75
76 pub async fn update<'a>(
83 &'a self,
84 wallet_id: &'a str,
85 ctx: &'a AuthorizationContext,
86 body: &'a crate::generated::types::UpdateWalletBody,
87 ) -> Result<ResponseValue<crate::generated::types::Wallet>, PrivySignedApiError> {
88 let sig = generate_authorization_signatures(
89 ctx,
90 &self.app_id,
91 crate::Method::PATCH,
92 format!("{}/v1/wallets/{}", self.base_url, wallet_id),
93 body,
94 None,
95 )
96 .await?;
97
98 Ok(self._update(wallet_id, Some(&sig), body).await?)
99 }
100
101 pub async fn export<'a>(
111 &'a self,
112 wallet_id: &'a str,
113 ctx: &'a AuthorizationContext,
114 ) -> Result<Vec<u8>, PrivyExportError> {
115 let privy_hpke = PrivyHpke::new();
116 let body = WalletExportRequestBody {
117 encryption_type: HpkeEncryption::Hpke,
118 recipient_public_key: privy_hpke.public_key()?,
119 };
120
121 let sig = generate_authorization_signatures(
122 ctx,
123 &self.app_id,
124 crate::Method::POST,
125 format!("{}/v1/wallets/{}/export", self.base_url, wallet_id),
126 &body,
127 None,
128 )
129 .await?;
130
131 let resp = self._export(wallet_id, Some(&sig), &body).await?;
132
133 tracing::debug!("Encapsulated key: {:?}", resp);
134
135 Ok(privy_hpke.decrypt_raw(&resp.encapsulated_key, &resp.ciphertext)?)
136 }
137
138 pub async fn import(
142 &self,
143 address: String,
144 private_key_hex: &str,
145 chain_type: WalletImportSupportedChains,
146 owner: Option<WalletImportSubmissionRequestOwner>,
147 policy_ids: Vec<String>,
148 additional_signers: Vec<WalletImportSubmissionRequestAdditionalSignersItem>,
149 ) -> Result<ResponseValue<Wallet>, PrivyApiError> {
150 WalletImport::new(
151 self.clone(),
152 crate::generated::types::WalletImportInitializationRequest::PrivateKeyInitInput(
153 PrivateKeyInitInput {
154 address: address.clone(),
155 chain_type,
156 encryption_type: HpkeEncryption::Hpke,
157 entropy_type:
158 crate::generated::types::PrivateKeyInitInputEntropyType::PrivateKey,
159 },
160 ),
161 )
162 .await?
163 .submit(private_key_hex, owner, policy_ids, additional_signers)
164 .await
165 }
166
167 pub(crate) async fn submit_import<'a>(
168 &'a self,
169 body: &'a types::WalletImportSubmissionRequest,
170 ) -> Result<ResponseValue<types::Wallet>, Error<()>> {
171 self._submit_import(body).await
172 }
173
174 pub fn ethereum(&self) -> EthereumService {
176 EthereumService::new(self.clone())
177 }
178
179 pub fn solana(&self) -> SolanaService {
181 SolanaService::new(self.clone())
182 }
183}