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