casper_rust_wasm_sdk/sdk/rpcs/
get_transaction.rs1use crate::types::hash::transaction_hash::TransactionHash;
2#[cfg(target_arch = "wasm32")]
3use crate::types::transaction::Transaction;
4use crate::{types::verbosity::Verbosity, SDK};
5use casper_client::{
6 get_transaction, rpcs::results::GetTransactionResult as _GetTransactionResult, Error,
7 JsonRpcId, SuccessResponse,
8};
9#[cfg(target_arch = "wasm32")]
10use gloo_utils::format::JsValueSerdeExt;
11use rand::Rng;
12#[cfg(target_arch = "wasm32")]
13use serde::{Deserialize, Serialize};
14use wasm_bindgen::prelude::*;
15
16#[cfg(target_arch = "wasm32")]
18#[derive(Debug, Deserialize, Clone, Serialize)]
19#[wasm_bindgen]
20pub struct GetTransactionResult(_GetTransactionResult);
21
22#[cfg(target_arch = "wasm32")]
23impl From<GetTransactionResult> for _GetTransactionResult {
24 fn from(result: GetTransactionResult) -> Self {
25 result.0
26 }
27}
28#[cfg(target_arch = "wasm32")]
29impl From<_GetTransactionResult> for GetTransactionResult {
30 fn from(result: _GetTransactionResult) -> Self {
31 GetTransactionResult(result)
32 }
33}
34
35#[cfg(target_arch = "wasm32")]
36#[wasm_bindgen]
37impl GetTransactionResult {
38 #[wasm_bindgen(getter)]
39 pub fn api_version(&self) -> JsValue {
41 JsValue::from_serde(&self.0.api_version).unwrap()
42 }
43
44 #[wasm_bindgen(getter)]
45 pub fn transaction(&self) -> Transaction {
47 self.0.transaction.clone().into()
48 }
49
50 #[wasm_bindgen(getter)]
51 pub fn execution_info(&self) -> JsValue {
53 JsValue::from_serde(&self.0.execution_info).unwrap()
54 }
55
56 #[wasm_bindgen(js_name = "toJson")]
57 pub fn to_json(&self) -> JsValue {
59 JsValue::from_serde(&self.0).unwrap_or(JsValue::null())
60 }
61}
62
63#[derive(Debug, Clone, Default, Deserialize, Serialize)]
65#[cfg(target_arch = "wasm32")]
66#[wasm_bindgen(js_name = "getTransactionOptions", getter_with_clone)]
67pub struct GetTransactionOptions {
68 pub transaction_hash_as_string: Option<String>,
69 pub transaction_hash: Option<TransactionHash>,
70 pub finalized_approvals: Option<bool>,
71 pub rpc_address: Option<String>,
72 pub verbosity: Option<Verbosity>,
73}
74
75#[wasm_bindgen]
76impl SDK {
77 #[cfg(target_arch = "wasm32")]
87 pub fn get_transaction_options(
88 &self,
89 options: JsValue,
90 ) -> Result<GetTransactionOptions, JsError> {
91 let options_result: Result<GetTransactionOptions, _> = options.into_serde();
92 match options_result {
93 Ok(mut options) => {
94 if let Some(finalized_approvals) = options.finalized_approvals {
95 options.finalized_approvals =
96 Some(JsValue::from_bool(finalized_approvals) == JsValue::TRUE);
97 }
98 Ok(options)
99 }
100 Err(err) => Err(JsError::new(&format!(
101 "Error deserializing options: {:?}",
102 err
103 ))),
104 }
105 }
106
107 #[cfg(target_arch = "wasm32")]
117 #[wasm_bindgen(js_name = "get_transaction")]
118 pub async fn get_transaction_js_alias(
119 &self,
120 options: Option<GetTransactionOptions>,
121 ) -> Result<GetTransactionResult, JsError> {
122 let GetTransactionOptions {
123 transaction_hash_as_string,
124 transaction_hash,
125 finalized_approvals,
126 verbosity,
127 rpc_address,
128 } = options.unwrap_or_default();
129
130 let transaction_hash = if let Some(transaction_hash_as_string) = transaction_hash_as_string
131 {
132 TransactionHash::new(&transaction_hash_as_string)?
133 } else {
134 if transaction_hash.is_none() {
135 let err_msg =
136 "Error: Missing transaction hash as string or transaction hash".to_string();
137 return Err(JsError::new(&err_msg));
138 }
139 transaction_hash.unwrap()
140 };
141
142 let result = self
143 .get_transaction(
144 transaction_hash,
145 finalized_approvals,
146 verbosity,
147 rpc_address,
148 )
149 .await;
150 match result {
151 Ok(data) => Ok(data.result.into()),
152 Err(err) => {
153 let err = &format!("Error occurred with {:?}", err);
154 Err(JsError::new(err))
155 }
156 }
157 }
158
159 #[cfg(target_arch = "wasm32")]
161 #[deprecated(note = "This function is an alias. Please use `get_transaction` instead.")]
162 #[allow(deprecated)]
163 pub async fn info_get_transaction(
164 &self,
165 options: Option<GetTransactionOptions>,
166 ) -> Result<GetTransactionResult, JsError> {
167 self.get_transaction_js_alias(options).await
168 }
169}
170
171impl SDK {
172 pub async fn get_transaction(
185 &self,
186 transaction_hash: TransactionHash,
187 finalized_approvals: Option<bool>,
188 verbosity: Option<Verbosity>,
189 rpc_address: Option<String>,
190 ) -> Result<SuccessResponse<_GetTransactionResult>, Error> {
191 get_transaction(
193 JsonRpcId::from(rand::thread_rng().gen::<u64>().to_string()),
194 &self.get_rpc_address(rpc_address),
195 self.get_verbosity(verbosity).into(),
196 transaction_hash.into(),
197 finalized_approvals.unwrap_or_default(),
198 )
199 .await
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206 use crate::{
207 helpers::public_key_from_secret_key,
208 types::transaction_params::transaction_str_params::TransactionStrParams,
209 };
210 use sdk_tests::{
211 config::TRANSFER_AMOUNT,
212 tests::helpers::{get_network_constants, get_user_secret_key},
213 };
214
215 #[tokio::test]
216 async fn test_get_transaction_with_none_values() {
217 let sdk = SDK::new(None, None, None);
219 let transaction_hash = TransactionHash::from_raw(&[1u8; 32]).unwrap();
220 let error_message = "failed to parse node address as valid URL";
221
222 let result = sdk
224 .get_transaction(transaction_hash, None, None, None)
225 .await;
226
227 assert!(result.is_err());
229 let err_string = result.err().unwrap().to_string();
230 assert!(err_string.contains(error_message));
231 }
232
233 #[tokio::test]
234 async fn test_get_transaction_with_invalid_transaction_hash() {
235 let sdk = SDK::new(None, None, None);
237 let transaction_hash = TransactionHash::from_raw(&[1u8; 32]).unwrap();
238 let verbosity = Some(Verbosity::High);
239 let (rpc_address, _, _, _, _) = get_network_constants();
240
241 let result = sdk
243 .get_transaction(transaction_hash, None, verbosity, Some(rpc_address))
244 .await;
245
246 assert!(result.is_err());
248 }
249
250 #[tokio::test]
251 async fn test_get_transaction_with_valid_transaction_hash() {
252 let sdk = SDK::new(None, None, None);
254 let verbosity = Some(Verbosity::High);
255 let (rpc_address, _, _, _, chain_name) = get_network_constants();
256
257 let secret_key = get_user_secret_key(None).unwrap();
258 let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
259
260 let transaction_params = TransactionStrParams::default();
261 transaction_params.set_secret_key(&secret_key);
262 transaction_params.set_chain_name(&chain_name);
263 transaction_params.set_payment_amount(TRANSFER_AMOUNT);
264
265 let transfer = sdk
266 .transfer_transaction(
267 None,
268 &initiator_addr, TRANSFER_AMOUNT,
270 transaction_params,
271 None,
272 verbosity,
273 Some(rpc_address.clone()),
274 )
275 .await
276 .unwrap();
277 let transaction_hash = transfer.result.transaction_hash;
278 assert!(!transaction_hash.to_string().is_empty());
279
280 let result = sdk
282 .get_transaction(transaction_hash.into(), None, verbosity, Some(rpc_address))
283 .await;
284
285 assert!(result.is_ok());
288 }
289
290 #[tokio::test]
291 async fn test_get_transaction_with_finalized_approvals() {
292 let sdk = SDK::new(None, None, None);
294 let verbosity = Some(Verbosity::High);
295 let (rpc_address, _, _, _, chain_name) = get_network_constants();
296
297 let secret_key = get_user_secret_key(None).unwrap();
298 let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
299
300 let transaction_params = TransactionStrParams::default();
301 transaction_params.set_secret_key(&secret_key);
302 transaction_params.set_chain_name(&chain_name);
303 transaction_params.set_payment_amount(TRANSFER_AMOUNT);
304
305 let transfer = sdk
306 .transfer_transaction(
307 None,
308 &initiator_addr, TRANSFER_AMOUNT,
310 transaction_params,
311 None,
312 verbosity,
313 Some(rpc_address.clone()),
314 )
315 .await
316 .unwrap();
317 let transaction_hash = transfer.result.transaction_hash;
318 assert!(!transaction_hash.to_string().is_empty());
319 let finalized_approvals = true;
320
321 let result = sdk
323 .get_transaction(
324 transaction_hash.into(),
325 Some(finalized_approvals),
326 verbosity,
327 Some(rpc_address),
328 )
329 .await;
330
331 assert!(result.is_ok());
333 }
334
335 #[tokio::test]
336 async fn test_get_transaction_with_error() {
337 let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
339 let transaction_hash = TransactionHash::from_raw(&[1u8; 32]).unwrap();
340 let error_message = "error sending request for url (http://localhost/rpc)";
341
342 let result = sdk
344 .get_transaction(transaction_hash, None, None, None)
345 .await;
346
347 assert!(result.is_err());
349 let err_string = result.err().unwrap().to_string();
350 assert!(err_string.contains(error_message));
351 }
352}