rain_sdk/api/
contracts.rs

1//! Contracts API
2//!
3//! This module provides functionality to manage smart contracts.
4
5use crate::client::RainClient;
6use crate::error::Result;
7use crate::models::contracts::*;
8use uuid::Uuid;
9
10impl RainClient {
11    /// Get smart contract information for a company
12    ///
13    /// # Arguments
14    ///
15    /// * `company_id` - The unique identifier of the company
16    ///
17    /// # Returns
18    ///
19    /// Returns a [`Vec<Contract>`] containing the list of contracts.
20    ///
21    /// # Examples
22    ///
23    /// ```no_run
24    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
25    /// use uuid::Uuid;
26    ///
27    /// # #[cfg(feature = "async")]
28    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
29    /// let config = Config::new(Environment::Dev);
30    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
31    /// let client = RainClient::new(config, auth)?;
32    ///
33    /// let company_id = Uuid::new_v4();
34    /// let contracts = client.get_company_contracts(&company_id).await?;
35    /// # Ok(())
36    /// # }
37    /// ```
38    #[cfg(feature = "async")]
39    pub async fn get_company_contracts(&self, company_id: &Uuid) -> Result<Vec<Contract>> {
40        let path = format!("/issuing/companies/{company_id}/contracts");
41        self.get(&path).await
42    }
43
44    /// Create a smart contract for a company
45    ///
46    /// # Arguments
47    ///
48    /// * `company_id` - The unique identifier of the company
49    /// * `request` - The contract creation request
50    ///
51    /// # Returns
52    ///
53    /// Returns success (202 Accepted) with no response body.
54    ///
55    /// # Examples
56    ///
57    /// ```no_run
58    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
59    /// use rain_sdk::models::contracts::CreateCompanyContractRequest;
60    /// use uuid::Uuid;
61    ///
62    /// # #[cfg(feature = "async")]
63    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
64    /// let config = Config::new(Environment::Dev);
65    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
66    /// let client = RainClient::new(config, auth)?;
67    ///
68    /// let company_id = Uuid::new_v4();
69    /// let request = CreateCompanyContractRequest {
70    ///     chain_id: 1, // Ethereum mainnet
71    ///     owner_address: "0x1234...".to_string(),
72    /// };
73    /// client.create_company_contract(&company_id, &request).await?;
74    /// # Ok(())
75    /// # }
76    /// ```
77    #[cfg(feature = "async")]
78    pub async fn create_company_contract(
79        &self,
80        company_id: &Uuid,
81        request: &CreateCompanyContractRequest,
82    ) -> Result<()> {
83        let path = format!("/issuing/companies/{company_id}/contracts");
84        // Returns 202 Accepted with no body - handle gracefully
85        let _: serde_json::Value = self.post(&path, request).await?;
86        Ok(())
87    }
88
89    /// Get smart contract information for an authorized user tenant
90    ///
91    /// # Returns
92    ///
93    /// Returns a [`Vec<Contract>`] containing the list of contracts.
94    ///
95    /// # Examples
96    ///
97    /// ```no_run
98    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
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 contracts = client.get_contracts().await?;
107    /// println!("Found {} contracts", contracts.len());
108    /// # Ok(())
109    /// # }
110    /// ```
111    #[cfg(feature = "async")]
112    pub async fn get_contracts(&self) -> Result<Vec<Contract>> {
113        let path = "/issuing/contracts";
114        self.get(path).await
115    }
116
117    /// Update a smart contract
118    ///
119    /// # Arguments
120    ///
121    /// * `contract_id` - The unique identifier of the contract
122    /// * `request` - The contract update request
123    ///
124    /// # Returns
125    ///
126    /// Returns success (200 OK) with response body.
127    ///
128    /// # Examples
129    ///
130    /// ```no_run
131    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
132    /// use rain_sdk::models::contracts::UpdateContractRequest;
133    /// use uuid::Uuid;
134    ///
135    /// # #[cfg(feature = "async")]
136    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
137    /// let config = Config::new(Environment::Dev);
138    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
139    /// let client = RainClient::new(config, auth)?;
140    ///
141    /// let contract_id = Uuid::new_v4();
142    /// let request = UpdateContractRequest {
143    ///     onramp: true,
144    /// };
145    /// let response: serde_json::Value = client.update_contract(&contract_id, &request).await?;
146    /// # Ok(())
147    /// # }
148    /// ```
149    #[cfg(feature = "async")]
150    pub async fn update_contract(
151        &self,
152        contract_id: &Uuid,
153        request: &UpdateContractRequest,
154    ) -> Result<serde_json::Value> {
155        let path = format!("/issuing/contracts/{contract_id}");
156        self.put(&path, request).await
157    }
158
159    /// Get smart contract information for a user
160    ///
161    /// # Arguments
162    ///
163    /// * `user_id` - The unique identifier of the user
164    ///
165    /// # Returns
166    ///
167    /// Returns a [`Vec<Contract>`] containing the list of contracts.
168    ///
169    /// # Examples
170    ///
171    /// ```no_run
172    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
173    /// use uuid::Uuid;
174    ///
175    /// # #[cfg(feature = "async")]
176    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
177    /// let config = Config::new(Environment::Dev);
178    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
179    /// let client = RainClient::new(config, auth)?;
180    ///
181    /// let user_id = Uuid::new_v4();
182    /// let contracts = client.get_user_contracts(&user_id).await?;
183    /// # Ok(())
184    /// # }
185    /// ```
186    #[cfg(feature = "async")]
187    pub async fn get_user_contracts(&self, user_id: &Uuid) -> Result<Vec<Contract>> {
188        let path = format!("/issuing/users/{user_id}/contracts");
189        self.get(&path).await
190    }
191
192    /// Create a smart contract for a user
193    ///
194    /// # Arguments
195    ///
196    /// * `user_id` - The unique identifier of the user (must have EVM or Solana address)
197    /// * `request` - The contract creation request
198    ///
199    /// # Returns
200    ///
201    /// Returns success (202 Accepted) with no response body.
202    ///
203    /// # Examples
204    ///
205    /// ```no_run
206    /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
207    /// use rain_sdk::models::contracts::CreateUserContractRequest;
208    /// use uuid::Uuid;
209    ///
210    /// # #[cfg(feature = "async")]
211    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
212    /// let config = Config::new(Environment::Dev);
213    /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
214    /// let client = RainClient::new(config, auth)?;
215    ///
216    /// let user_id = Uuid::new_v4();
217    /// let request = CreateUserContractRequest {
218    ///     chain_id: 1, // Ethereum mainnet
219    /// };
220    /// client.create_user_contract(&user_id, &request).await?;
221    /// # Ok(())
222    /// # }
223    /// ```
224    #[cfg(feature = "async")]
225    pub async fn create_user_contract(
226        &self,
227        user_id: &Uuid,
228        request: &CreateUserContractRequest,
229    ) -> Result<()> {
230        let path = format!("/issuing/users/{user_id}/contracts");
231        // Returns 202 Accepted with no body - handle gracefully
232        let _: serde_json::Value = self.post(&path, request).await?;
233        Ok(())
234    }
235
236    // ============================================================================
237    // Blocking Methods
238    // ============================================================================
239
240    /// Get smart contract information for a company (blocking)
241    #[cfg(feature = "sync")]
242    pub fn get_company_contracts_blocking(&self, company_id: &Uuid) -> Result<Vec<Contract>> {
243        let path = format!("/issuing/companies/{company_id}/contracts");
244        self.get_blocking(&path)
245    }
246
247    /// Create a smart contract for a company (blocking)
248    #[cfg(feature = "sync")]
249    pub fn create_company_contract_blocking(
250        &self,
251        company_id: &Uuid,
252        request: &CreateCompanyContractRequest,
253    ) -> Result<()> {
254        let path = format!("/issuing/companies/{company_id}/contracts");
255        // Returns 202 Accepted with no body - handle gracefully
256        let _: serde_json::Value = self.post_blocking(&path, request)?;
257        Ok(())
258    }
259
260    /// Get smart contract information for an authorized user tenant (blocking)
261    #[cfg(feature = "sync")]
262    pub fn get_contracts_blocking(&self) -> Result<Vec<Contract>> {
263        let path = "/issuing/contracts";
264        self.get_blocking(path)
265    }
266
267    /// Update a smart contract (blocking)
268    #[cfg(feature = "sync")]
269    pub fn update_contract_blocking(
270        &self,
271        contract_id: &Uuid,
272        request: &UpdateContractRequest,
273    ) -> Result<serde_json::Value> {
274        let path = format!("/issuing/contracts/{contract_id}");
275        self.put_blocking(&path, request)
276    }
277
278    /// Get smart contract information for a user (blocking)
279    #[cfg(feature = "sync")]
280    pub fn get_user_contracts_blocking(&self, user_id: &Uuid) -> Result<Vec<Contract>> {
281        let path = format!("/issuing/users/{user_id}/contracts");
282        self.get_blocking(&path)
283    }
284
285    /// Create a smart contract for a user (blocking)
286    #[cfg(feature = "sync")]
287    pub fn create_user_contract_blocking(
288        &self,
289        user_id: &Uuid,
290        request: &CreateUserContractRequest,
291    ) -> Result<()> {
292        let path = format!("/issuing/users/{user_id}/contracts");
293        // Returns 202 Accepted with no body - handle gracefully
294        let _: serde_json::Value = self.post_blocking(&path, request)?;
295        Ok(())
296    }
297}