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 /// # Errors
22 ///
23 /// This method can return the following errors:
24 /// - `401` - Invalid authorization
25 /// - `404` - Company not found
26 /// - `500` - Internal server error
27 ///
28 /// # Examples
29 ///
30 /// ```no_run
31 /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
32 /// use uuid::Uuid;
33 ///
34 /// # #[cfg(feature = "async")]
35 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
36 /// let config = Config::new(Environment::Dev);
37 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
38 /// let client = RainClient::new(config, auth)?;
39 ///
40 /// let company_id = Uuid::new_v4();
41 /// let contracts = client.get_company_contracts(&company_id).await?;
42 /// # Ok(())
43 /// # }
44 /// ```
45 #[cfg(feature = "async")]
46 pub async fn get_company_contracts(&self, company_id: &Uuid) -> Result<Vec<Contract>> {
47 let path = format!("/companies/{company_id}/contracts");
48 self.get(&path).await
49 }
50
51 /// Create a smart contract for a company
52 ///
53 /// # Arguments
54 ///
55 /// * `company_id` - The unique identifier of the company
56 /// * `request` - The contract creation request
57 ///
58 /// # Returns
59 ///
60 /// Returns success (202 Accepted) with no response body.
61 ///
62 /// # Errors
63 ///
64 /// This method can return the following errors:
65 /// - `400` - Invalid request
66 /// - `401` - Invalid authorization
67 /// - `404` - Company not found
68 /// - `409` - Company already has a contract on this chain
69 /// - `500` - Internal server error
70 ///
71 /// # Examples
72 ///
73 /// ```no_run
74 /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
75 /// use rain_sdk::models::contracts::CreateCompanyContractRequest;
76 /// use uuid::Uuid;
77 ///
78 /// # #[cfg(feature = "async")]
79 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
80 /// let config = Config::new(Environment::Dev);
81 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
82 /// let client = RainClient::new(config, auth)?;
83 ///
84 /// let company_id = Uuid::new_v4();
85 /// let request = CreateCompanyContractRequest {
86 /// chain_id: 1, // Ethereum mainnet
87 /// owner_address: "0x1234...".to_string(),
88 /// };
89 /// client.create_company_contract(&company_id, &request).await?;
90 /// # Ok(())
91 /// # }
92 /// ```
93 #[cfg(feature = "async")]
94 pub async fn create_company_contract(
95 &self,
96 company_id: &Uuid,
97 request: &CreateCompanyContractRequest,
98 ) -> Result<()> {
99 let path = format!("/companies/{company_id}/contracts");
100 // Returns 202 Accepted with no body - handle gracefully
101 let _: serde_json::Value = self.post(&path, request).await?;
102 Ok(())
103 }
104
105 /// Get smart contract information for an authorized user tenant
106 ///
107 /// # Returns
108 ///
109 /// Returns a [`Vec<Contract>`] containing the list of contracts.
110 ///
111 /// # Errors
112 ///
113 /// This method can return the following errors:
114 /// - `401` - Invalid authorization
115 /// - `500` - Internal server error
116 ///
117 /// # Examples
118 ///
119 /// ```no_run
120 /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
121 ///
122 /// # #[cfg(feature = "async")]
123 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
124 /// let config = Config::new(Environment::Dev);
125 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
126 /// let client = RainClient::new(config, auth)?;
127 ///
128 /// let contracts = client.get_contracts().await?;
129 /// println!("Found {} contracts", contracts.len());
130 /// # Ok(())
131 /// # }
132 /// ```
133 #[cfg(feature = "async")]
134 pub async fn get_contracts(&self) -> Result<Vec<Contract>> {
135 let path = "/contracts";
136 self.get(path).await
137 }
138
139 /// Update a smart contract
140 ///
141 /// # Arguments
142 ///
143 /// * `contract_id` - The unique identifier of the contract
144 /// * `request` - The contract update request
145 ///
146 /// # Returns
147 ///
148 /// Returns success (200 OK) with response body.
149 ///
150 /// # Errors
151 ///
152 /// This method can return the following errors:
153 /// - `400` - Invalid request
154 /// - `401` - Invalid authorization
155 /// - `404` - Contract not found
156 /// - `500` - Internal server error
157 ///
158 /// # Examples
159 ///
160 /// ```no_run
161 /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
162 /// use rain_sdk::models::contracts::UpdateContractRequest;
163 /// use uuid::Uuid;
164 ///
165 /// # #[cfg(feature = "async")]
166 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
167 /// let config = Config::new(Environment::Dev);
168 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
169 /// let client = RainClient::new(config, auth)?;
170 ///
171 /// let contract_id = Uuid::new_v4();
172 /// let request = UpdateContractRequest {
173 /// onramp: true,
174 /// };
175 /// let response: serde_json::Value = client.update_contract(&contract_id, &request).await?;
176 /// # Ok(())
177 /// # }
178 /// ```
179 #[cfg(feature = "async")]
180 pub async fn update_contract(
181 &self,
182 contract_id: &Uuid,
183 request: &UpdateContractRequest,
184 ) -> Result<serde_json::Value> {
185 let path = format!("/contracts/{contract_id}");
186 self.put(&path, request).await
187 }
188
189 /// Get smart contract information for a user
190 ///
191 /// # Arguments
192 ///
193 /// * `user_id` - The unique identifier of the user
194 ///
195 /// # Returns
196 ///
197 /// Returns a [`Vec<Contract>`] containing the list of contracts.
198 ///
199 /// # Errors
200 ///
201 /// This method can return the following errors:
202 /// - `401` - Invalid authorization
203 /// - `404` - User not found
204 /// - `500` - Internal server error
205 ///
206 /// # Examples
207 ///
208 /// ```no_run
209 /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
210 /// use uuid::Uuid;
211 ///
212 /// # #[cfg(feature = "async")]
213 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
214 /// let config = Config::new(Environment::Dev);
215 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
216 /// let client = RainClient::new(config, auth)?;
217 ///
218 /// let user_id = Uuid::new_v4();
219 /// let contracts = client.get_user_contracts(&user_id).await?;
220 /// # Ok(())
221 /// # }
222 /// ```
223 #[cfg(feature = "async")]
224 pub async fn get_user_contracts(&self, user_id: &Uuid) -> Result<Vec<Contract>> {
225 let path = format!("/users/{user_id}/contracts");
226 self.get(&path).await
227 }
228
229 /// Create a smart contract for a user
230 ///
231 /// # Arguments
232 ///
233 /// * `user_id` - The unique identifier of the user (must have EVM or Solana address)
234 /// * `request` - The contract creation request
235 ///
236 /// # Returns
237 ///
238 /// Returns success (202 Accepted) with no response body.
239 ///
240 /// # Errors
241 ///
242 /// This method can return the following errors:
243 /// - `400` - Invalid request
244 /// - `401` - Invalid authorization
245 /// - `404` - User not found
246 /// - `409` - User already has a contract on this chain
247 /// - `500` - Internal server error
248 ///
249 /// # Examples
250 ///
251 /// ```no_run
252 /// use rain_sdk::{RainClient, Config, Environment, AuthConfig};
253 /// use rain_sdk::models::contracts::CreateUserContractRequest;
254 /// use uuid::Uuid;
255 ///
256 /// # #[cfg(feature = "async")]
257 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
258 /// let config = Config::new(Environment::Dev);
259 /// let auth = AuthConfig::with_api_key("your-api-key".to_string());
260 /// let client = RainClient::new(config, auth)?;
261 ///
262 /// let user_id = Uuid::new_v4();
263 /// let request = CreateUserContractRequest {
264 /// chain_id: 1, // Ethereum mainnet
265 /// };
266 /// client.create_user_contract(&user_id, &request).await?;
267 /// # Ok(())
268 /// # }
269 /// ```
270 #[cfg(feature = "async")]
271 pub async fn create_user_contract(
272 &self,
273 user_id: &Uuid,
274 request: &CreateUserContractRequest,
275 ) -> Result<()> {
276 let path = format!("/users/{user_id}/contracts");
277 // Returns 202 Accepted with no body - handle gracefully
278 let _: serde_json::Value = self.post(&path, request).await?;
279 Ok(())
280 }
281
282 // ============================================================================
283 // Blocking Methods
284 // ============================================================================
285
286 /// Get smart contract information for a company (blocking)
287 #[cfg(feature = "sync")]
288 pub fn get_company_contracts_blocking(&self, company_id: &Uuid) -> Result<Vec<Contract>> {
289 let path = format!("/companies/{company_id}/contracts");
290 self.get_blocking(&path)
291 }
292
293 /// Create a smart contract for a company (blocking)
294 #[cfg(feature = "sync")]
295 pub fn create_company_contract_blocking(
296 &self,
297 company_id: &Uuid,
298 request: &CreateCompanyContractRequest,
299 ) -> Result<()> {
300 let path = format!("/companies/{company_id}/contracts");
301 // Returns 202 Accepted with no body - handle gracefully
302 let _: serde_json::Value = self.post_blocking(&path, request)?;
303 Ok(())
304 }
305
306 /// Get smart contract information for an authorized user tenant (blocking)
307 #[cfg(feature = "sync")]
308 pub fn get_contracts_blocking(&self) -> Result<Vec<Contract>> {
309 let path = "/contracts";
310 self.get_blocking(path)
311 }
312
313 /// Update a smart contract (blocking)
314 #[cfg(feature = "sync")]
315 pub fn update_contract_blocking(
316 &self,
317 contract_id: &Uuid,
318 request: &UpdateContractRequest,
319 ) -> Result<serde_json::Value> {
320 let path = format!("/contracts/{contract_id}");
321 self.put_blocking(&path, request)
322 }
323
324 /// Get smart contract information for a user (blocking)
325 #[cfg(feature = "sync")]
326 pub fn get_user_contracts_blocking(&self, user_id: &Uuid) -> Result<Vec<Contract>> {
327 let path = format!("/users/{user_id}/contracts");
328 self.get_blocking(&path)
329 }
330
331 /// Create a smart contract for a user (blocking)
332 #[cfg(feature = "sync")]
333 pub fn create_user_contract_blocking(
334 &self,
335 user_id: &Uuid,
336 request: &CreateUserContractRequest,
337 ) -> Result<()> {
338 let path = format!("/users/{user_id}/contracts");
339 // Returns 202 Accepted with no body - handle gracefully
340 let _: serde_json::Value = self.post_blocking(&path, request)?;
341 Ok(())
342 }
343}