rain_sdk/api/
signatures.rs

1//! Signatures API
2//!
3//! This module provides functionality to get payment and withdrawal signatures.
4
5use crate::client::RainClient;
6use crate::error::Result;
7use crate::models::signatures::*;
8use uuid::Uuid;
9
10impl RainClient {
11    /// Get payment signature for a company
12    ///
13    /// # Arguments
14    ///
15    /// * `company_id` - The unique identifier of the company
16    /// * `params` - Query parameters for the signature request
17    ///
18    /// # Returns
19    ///
20    /// Returns a [`PaymentSignatureResponse`] which can be either pending or ready.
21    ///
22    /// # Errors
23    ///
24    /// This method can return the following errors:
25    /// - `400` - Invalid request
26    /// - `401` - Invalid authorization
27    /// - `404` - Company not found
28    /// - `409` - Another active signature already exists
29    /// - `500` - Internal server error
30    ///
31    /// # Examples
32    ///
33    /// ```no_run
34    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
35    /// use rain_sdk::models::signatures::PaymentSignatureParams;
36    /// use uuid::Uuid;
37    ///
38    /// # #[cfg(feature = "async")]
39    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
40    /// let config = Config::new(Environment::Dev);
41    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
42    /// let client = RainClient::new(config, auth)?;
43    ///
44    /// let company_id = Uuid::new_v4();
45    /// let params = PaymentSignatureParams {
46    ///     chain_id: Some(1),
47    ///     token: "0xabc123...".to_string(),
48    ///     amount: "1000000".to_string(),
49    ///     admin_address: "0xdef456...".to_string(),
50    ///     is_amount_native: Some(false),
51    ///     rain_collateral_contract_id: None,
52    /// };
53    /// let response = client.get_company_payment_signature(&company_id, &params).await?;
54    /// # Ok(())
55    /// # }
56    /// ```
57    #[cfg(feature = "async")]
58    pub async fn get_company_payment_signature(
59        &self,
60        company_id: &Uuid,
61        params: &PaymentSignatureParams,
62    ) -> Result<PaymentSignatureResponse> {
63        let path = format!("/companies/{company_id}/signatures/payments");
64        let query_string = serde_urlencoded::to_string(params)?;
65        let full_path = if query_string.is_empty() {
66            path
67        } else {
68            format!("{path}?{query_string}")
69        };
70        self.get(&full_path).await
71    }
72
73    /// Get withdrawal signature for a company
74    ///
75    /// # Arguments
76    ///
77    /// * `company_id` - The unique identifier of the company
78    /// * `params` - Query parameters for the signature request
79    ///
80    /// # Returns
81    ///
82    /// Returns a [`WithdrawalSignatureResponse`] which can be either pending or ready.
83    ///
84    /// # Errors
85    ///
86    /// This method can return the following errors:
87    /// - `400` - Invalid request
88    /// - `401` - Invalid authorization
89    /// - `404` - Company not found
90    /// - `409` - Another active signature already exists
91    /// - `500` - Internal server error
92    ///
93    /// # Examples
94    ///
95    /// ```no_run
96    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
97    /// use rain_sdk::models::signatures::WithdrawalSignatureParams;
98    /// use uuid::Uuid;
99    ///
100    /// # #[cfg(feature = "async")]
101    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
102    /// let config = Config::new(Environment::Dev);
103    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
104    /// let client = RainClient::new(config, auth)?;
105    ///
106    /// let company_id = Uuid::new_v4();
107    /// let params = WithdrawalSignatureParams {
108    ///     chain_id: Some(1),
109    ///     token: "0xabc123...".to_string(),
110    ///     amount: "500000".to_string(),
111    ///     admin_address: "0xdef456...".to_string(),
112    ///     recipient_address: "0x789ghi...".to_string(),
113    ///     is_amount_native: Some(false),
114    ///     rain_collateral_contract_id: None,
115    /// };
116    /// let response = client.get_company_withdrawal_signature(&company_id, &params).await?;
117    /// # Ok(())
118    /// # }
119    /// ```
120    #[cfg(feature = "async")]
121    pub async fn get_company_withdrawal_signature(
122        &self,
123        company_id: &Uuid,
124        params: &WithdrawalSignatureParams,
125    ) -> Result<WithdrawalSignatureResponse> {
126        let path = format!("/companies/{company_id}/signatures/withdrawals");
127        let query_string = serde_urlencoded::to_string(params)?;
128        let full_path = if query_string.is_empty() {
129            path
130        } else {
131            format!("{path}?{query_string}")
132        };
133        self.get(&full_path).await
134    }
135
136    /// Get payment signature for an authorized user tenant
137    ///
138    /// # Arguments
139    ///
140    /// * `params` - Query parameters for the signature request
141    ///
142    /// # Returns
143    ///
144    /// Returns a [`PaymentSignatureResponse`] which can be either pending or ready.
145    ///
146    /// # Errors
147    ///
148    /// This method can return the following errors:
149    /// - `400` - Invalid request
150    /// - `401` - Invalid authorization
151    /// - `409` - Another active signature already exists
152    /// - `500` - Internal server error
153    #[cfg(feature = "async")]
154    pub async fn get_payment_signature(
155        &self,
156        params: &PaymentSignatureParams,
157    ) -> Result<PaymentSignatureResponse> {
158        let path = "/signatures/payments";
159        let query_string = serde_urlencoded::to_string(params)?;
160        let full_path = if query_string.is_empty() {
161            path.to_string()
162        } else {
163            format!("{path}?{query_string}")
164        };
165        self.get(&full_path).await
166    }
167
168    /// Get withdrawal signature for an authorized user tenant
169    ///
170    /// # Arguments
171    ///
172    /// * `params` - Query parameters for the signature request
173    ///
174    /// # Returns
175    ///
176    /// Returns a [`WithdrawalSignatureResponse`] which can be either pending or ready.
177    ///
178    /// # Errors
179    ///
180    /// This method can return the following errors:
181    /// - `400` - Invalid request
182    /// - `401` - Invalid authorization
183    /// - `409` - Another active signature already exists
184    /// - `500` - Internal server error
185    #[cfg(feature = "async")]
186    pub async fn get_withdrawal_signature(
187        &self,
188        params: &WithdrawalSignatureParams,
189    ) -> Result<WithdrawalSignatureResponse> {
190        let path = "/signatures/withdrawals";
191        let query_string = serde_urlencoded::to_string(params)?;
192        let full_path = if query_string.is_empty() {
193            path.to_string()
194        } else {
195            format!("{path}?{query_string}")
196        };
197        self.get(&full_path).await
198    }
199
200    /// Get payment signature for a user
201    ///
202    /// # Arguments
203    ///
204    /// * `user_id` - The unique identifier of the user
205    /// * `params` - Query parameters for the signature request
206    ///
207    /// # Returns
208    ///
209    /// Returns a [`PaymentSignatureResponse`] which can be either pending or ready.
210    ///
211    /// # Errors
212    ///
213    /// This method can return the following errors:
214    /// - `400` - Invalid request
215    /// - `401` - Invalid authorization
216    /// - `404` - User not found
217    /// - `409` - Another active signature already exists
218    /// - `500` - Internal server error
219    #[cfg(feature = "async")]
220    pub async fn get_user_payment_signature(
221        &self,
222        user_id: &Uuid,
223        params: &PaymentSignatureParams,
224    ) -> Result<PaymentSignatureResponse> {
225        let path = format!("/users/{user_id}/signatures/payments");
226        let query_string = serde_urlencoded::to_string(params)?;
227        let full_path = if query_string.is_empty() {
228            path
229        } else {
230            format!("{path}?{query_string}")
231        };
232        self.get(&full_path).await
233    }
234
235    /// Get withdrawal signature for a user
236    ///
237    /// # Arguments
238    ///
239    /// * `user_id` - The unique identifier of the user
240    /// * `params` - Query parameters for the signature request
241    ///
242    /// # Returns
243    ///
244    /// Returns a [`WithdrawalSignatureResponse`] which can be either pending or ready.
245    ///
246    /// # Errors
247    ///
248    /// This method can return the following errors:
249    /// - `400` - Invalid request
250    /// - `401` - Invalid authorization
251    /// - `404` - User not found
252    /// - `409` - Another active signature already exists
253    /// - `500` - Internal server error
254    #[cfg(feature = "async")]
255    pub async fn get_user_withdrawal_signature(
256        &self,
257        user_id: &Uuid,
258        params: &WithdrawalSignatureParams,
259    ) -> Result<WithdrawalSignatureResponse> {
260        let path = format!("/users/{user_id}/signatures/withdrawals");
261        let query_string = serde_urlencoded::to_string(params)?;
262        let full_path = if query_string.is_empty() {
263            path
264        } else {
265            format!("{path}?{query_string}")
266        };
267        self.get(&full_path).await
268    }
269
270    // ============================================================================
271    // Blocking Methods
272    // ============================================================================
273
274    /// Get payment signature for a company (blocking)
275    #[cfg(feature = "sync")]
276    pub fn get_company_payment_signature_blocking(
277        &self,
278        company_id: &Uuid,
279        params: &PaymentSignatureParams,
280    ) -> Result<PaymentSignatureResponse> {
281        let path = format!("/companies/{company_id}/signatures/payments");
282        let query_string = serde_urlencoded::to_string(params)?;
283        let full_path = if query_string.is_empty() {
284            path
285        } else {
286            format!("{path}?{query_string}")
287        };
288        self.get_blocking(&full_path)
289    }
290
291    /// Get withdrawal signature for a company (blocking)
292    #[cfg(feature = "sync")]
293    pub fn get_company_withdrawal_signature_blocking(
294        &self,
295        company_id: &Uuid,
296        params: &WithdrawalSignatureParams,
297    ) -> Result<WithdrawalSignatureResponse> {
298        let path = format!("/companies/{company_id}/signatures/withdrawals");
299        let query_string = serde_urlencoded::to_string(params)?;
300        let full_path = if query_string.is_empty() {
301            path
302        } else {
303            format!("{path}?{query_string}")
304        };
305        self.get_blocking(&full_path)
306    }
307
308    /// Get payment signature for an authorized user tenant (blocking)
309    #[cfg(feature = "sync")]
310    pub fn get_payment_signature_blocking(
311        &self,
312        params: &PaymentSignatureParams,
313    ) -> Result<PaymentSignatureResponse> {
314        let path = "/signatures/payments";
315        let query_string = serde_urlencoded::to_string(params)?;
316        let full_path = if query_string.is_empty() {
317            path.to_string()
318        } else {
319            format!("{path}?{query_string}")
320        };
321        self.get_blocking(&full_path)
322    }
323
324    /// Get withdrawal signature for an authorized user tenant (blocking)
325    #[cfg(feature = "sync")]
326    pub fn get_withdrawal_signature_blocking(
327        &self,
328        params: &WithdrawalSignatureParams,
329    ) -> Result<WithdrawalSignatureResponse> {
330        let path = "/signatures/withdrawals";
331        let query_string = serde_urlencoded::to_string(params)?;
332        let full_path = if query_string.is_empty() {
333            path.to_string()
334        } else {
335            format!("{path}?{query_string}")
336        };
337        self.get_blocking(&full_path)
338    }
339
340    /// Get payment signature for a user (blocking)
341    #[cfg(feature = "sync")]
342    pub fn get_user_payment_signature_blocking(
343        &self,
344        user_id: &Uuid,
345        params: &PaymentSignatureParams,
346    ) -> Result<PaymentSignatureResponse> {
347        let path = format!("/users/{user_id}/signatures/payments");
348        let query_string = serde_urlencoded::to_string(params)?;
349        let full_path = if query_string.is_empty() {
350            path
351        } else {
352            format!("{path}?{query_string}")
353        };
354        self.get_blocking(&full_path)
355    }
356
357    /// Get withdrawal signature for a user (blocking)
358    #[cfg(feature = "sync")]
359    pub fn get_user_withdrawal_signature_blocking(
360        &self,
361        user_id: &Uuid,
362        params: &WithdrawalSignatureParams,
363    ) -> Result<WithdrawalSignatureResponse> {
364        let path = format!("/users/{user_id}/signatures/withdrawals");
365        let query_string = serde_urlencoded::to_string(params)?;
366        let full_path = if query_string.is_empty() {
367            path
368        } else {
369            format!("{path}?{query_string}")
370        };
371        self.get_blocking(&full_path)
372    }
373}