casper_rust_wasm_sdk/sdk/transaction/
speculative_transaction.rs1#[cfg(target_arch = "wasm32")]
2use crate::rpcs::speculative_exec::SpeculativeExecTxnResult;
3use crate::{
4 types::{
5 sdk_error::SdkError,
6 transaction_params::{
7 transaction_builder_params::{
8 transaction_builder_params_to_casper_client, TransactionBuilderParams,
9 },
10 transaction_str_params::{
11 transaction_str_params_to_casper_client, TransactionStrParams,
12 },
13 },
14 verbosity::Verbosity,
15 },
16 SDK,
17};
18use casper_client::{
19 cli::make_transaction, rpcs::results::SpeculativeExecTxnResult as _SpeculativeExecTxnResult,
20 SuccessResponse,
21};
22#[cfg(target_arch = "wasm32")]
23use wasm_bindgen::prelude::*;
24
25#[cfg(target_arch = "wasm32")]
26#[wasm_bindgen]
27impl SDK {
28 #[wasm_bindgen(js_name = "speculative_transaction")]
41 #[allow(clippy::too_many_arguments)]
42 pub async fn speculative_transaction_js_alias(
43 &self,
44 builder_params: TransactionBuilderParams,
45 transaction_params: TransactionStrParams,
46 verbosity: Option<Verbosity>,
47 rpc_address: Option<String>,
48 ) -> Result<SpeculativeExecTxnResult, JsError> {
49 let result = self
50 .speculative_transaction(builder_params, transaction_params, verbosity, rpc_address)
51 .await;
52 match result {
53 Ok(data) => Ok(data.result.into()),
54 Err(err) => {
55 let err = &format!("Error occurred with {:?}", err);
56 Err(JsError::new(err))
57 }
58 }
59 }
60}
61
62impl SDK {
63 pub async fn speculative_transaction(
76 &self,
77 builder_params: TransactionBuilderParams,
78 transaction_params: TransactionStrParams,
79 verbosity: Option<Verbosity>,
80 rpc_address: Option<String>,
81 ) -> Result<SuccessResponse<_SpeculativeExecTxnResult>, SdkError> {
82 let transaction = make_transaction(
84 transaction_builder_params_to_casper_client(&builder_params),
85 transaction_str_params_to_casper_client(&transaction_params),
86 false,
87 );
88
89 if let Err(err) = transaction {
90 return Err(SdkError::from(err));
91 }
92
93 self.speculative_exec(transaction.unwrap().into(), verbosity, rpc_address)
94 .await
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use crate::helpers::public_key_from_secret_key;
102 use once_cell::sync::Lazy;
103 use sdk_tests::{
104 config::{ARGS_SIMPLE, HELLO_CONTRACT, PAYMENT_AMOUNT, WASM_PATH},
105 tests::helpers::{get_network_constants, get_user_secret_key, read_wasm_file},
106 };
107 use std::sync::Mutex;
108
109 static ARGS: Lazy<Vec<String>> =
110 Lazy::new(|| ARGS_SIMPLE.iter().map(|s| s.to_string()).collect());
111
112 static BUILDER_PARAMS: Lazy<Mutex<Option<TransactionBuilderParams>>> =
113 Lazy::new(|| Mutex::new(None));
114
115 fn get_builder_params() -> TransactionBuilderParams {
116 let mut builder_params = BUILDER_PARAMS.lock().unwrap();
117
118 if builder_params.is_none() {
119 let file_path = &format!("{WASM_PATH}{HELLO_CONTRACT}");
120 let transaction_bytes = match read_wasm_file(file_path) {
121 Ok(transaction_bytes) => transaction_bytes,
122 Err(err) => {
123 eprintln!("Error reading file: {:?}", err);
124 unimplemented!()
125 }
126 };
127
128 let is_install_upgrade = Some(true);
129
130 let new_builder_params = TransactionBuilderParams::new_session(
131 Some(transaction_bytes.into()),
132 is_install_upgrade,
133 );
134 *builder_params = Some(new_builder_params);
135 }
136
137 builder_params.clone().unwrap()
138 }
139
140 #[tokio::test]
141 #[ignore]
142 async fn _test_speculative_transaction_with_valid_params() {
143 let sdk = SDK::new(None, None, None);
145 let verbosity = Some(Verbosity::High);
146 let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
147
148 let secret_key = get_user_secret_key(None).unwrap();
149
150 let mut transaction_params = TransactionStrParams::default();
151 transaction_params.set_secret_key(&secret_key);
152 transaction_params.set_chain_name(&chain_name);
153 transaction_params.set_payment_amount(PAYMENT_AMOUNT);
154 transaction_params.set_session_args_simple(ARGS.to_vec());
155
156 let result = sdk
158 .speculative_transaction(
159 get_builder_params().clone(),
160 transaction_params,
161 verbosity,
162 Some(default_speculative_address),
163 )
164 .await;
165
166 assert!(result.is_ok());
168 }
169
170 #[tokio::test]
171 async fn test_speculative_transaction_with_valid_params_without_secret_key() {
172 let sdk = SDK::new(None, None, None);
174 let verbosity = Some(Verbosity::High);
175 let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
176 let secret_key = get_user_secret_key(None).unwrap();
177 let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
178
179 let mut transaction_params = TransactionStrParams::default();
180 transaction_params.set_chain_name(&chain_name);
181 transaction_params.set_initiator_addr(&initiator_addr);
182 transaction_params.set_payment_amount(PAYMENT_AMOUNT);
183 transaction_params.set_session_args_simple(ARGS.to_vec());
184
185 let result = sdk
187 .speculative_transaction(
188 get_builder_params().clone(),
189 transaction_params,
190 verbosity,
191 Some(default_speculative_address),
192 )
193 .await;
194
195 assert!(result.is_err());
197 }
198
199 #[tokio::test]
200 async fn test_speculative_transaction_with_invalid_params() {
201 let sdk = SDK::new(None, None, None);
203 let verbosity = Some(Verbosity::High);
204 let (_, _, default_speculative_address, _, chain_name) = get_network_constants();
205
206 let secret_key = get_user_secret_key(None).unwrap();
207
208 let error_message = "Node request failure";
209
210 let transaction_params = TransactionStrParams::default();
211 transaction_params.set_secret_key(&secret_key);
212 transaction_params.set_chain_name(&chain_name);
213 transaction_params.set_payment_amount(PAYMENT_AMOUNT);
214
215 let result = sdk
217 .speculative_transaction(
218 get_builder_params().clone(),
219 transaction_params,
220 verbosity,
221 Some(default_speculative_address),
222 )
223 .await;
224
225 assert!(result.is_err());
227 let err_string = result.err().unwrap().to_string();
228
229 assert!(err_string.contains(error_message));
230 }
231}