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}