casper_rust_wasm_sdk/sdk/contract/
call_entrypoint.rs1#[cfg(all(feature = "js", target_arch = "wasm32"))]
2use crate::transaction::transaction::PutTransactionResult;
3use crate::{
4 types::{
5 sdk_error::SdkError,
6 transaction_params::{
7 transaction_builder_params::TransactionBuilderParams,
8 transaction_str_params::TransactionStrParams,
9 },
10 },
11 SDK,
12};
13use casper_client::{
14 rpcs::results::PutTransactionResult as _PutTransactionResult, SuccessResponse,
15};
16#[cfg(all(feature = "js", target_arch = "wasm32"))]
17use wasm_bindgen::prelude::*;
18
19#[cfg(all(feature = "js", target_arch = "wasm32"))]
21#[cfg_attr(feature = "js", wasm_bindgen)]
22impl SDK {
23 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "call_entrypoint"))]
39 #[cfg(feature = "js")]
40 pub async fn call_entrypoint_js_alias(
41 &self,
42 builder_params: TransactionBuilderParams,
43 transaction_params: TransactionStrParams,
44 rpc_address: Option<String>,
45 runtime_v2: Option<bool>,
46 ) -> Result<PutTransactionResult, JsError> {
47 let result = self
48 .call_entrypoint(builder_params, transaction_params, rpc_address, runtime_v2)
49 .await;
50 match result {
51 Ok(data) => Ok(data.result.into()),
52 Err(err) => {
53 let err = &format!("Error occurred with {err:?}");
54 Err(JsError::new(err))
55 }
56 }
57 }
58}
59
60impl SDK {
63 pub async fn call_entrypoint(
84 &self,
85 mut builder_params: TransactionBuilderParams,
86 transaction_params: TransactionStrParams,
87 rpc_address: Option<String>,
88 runtime_v2: Option<bool>,
89 ) -> Result<SuccessResponse<_PutTransactionResult>, SdkError> {
90 apply_call_runtime_v2(&mut builder_params, runtime_v2);
91 self.transaction(builder_params, transaction_params, None, rpc_address)
92 .await
93 }
94}
95
96fn apply_call_runtime_v2(builder_params: &mut TransactionBuilderParams, runtime_v2: Option<bool>) {
97 match runtime_v2 {
98 None => {}
99 Some(true) => builder_params.set_runtime_v2(0, None),
100 Some(false) => builder_params.set_runtime_v1(),
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use crate::{
108 helpers::public_key_from_secret_key, install_cep78, types::addr::entity_addr::EntityAddr,
109 };
110 use once_cell::sync::Lazy;
111 use sdk_tests::{
112 config::{ARGS_SIMPLE, ENTRYPOINT_MINT, PAYMENT_AMOUNT},
113 tests::helpers::{get_network_constants, get_user_secret_key},
114 };
115 use tokio;
116
117 static ARGS: Lazy<Vec<String>> =
118 Lazy::new(|| ARGS_SIMPLE.iter().map(|s| s.to_string()).collect());
119
120 async fn get_entity_key() -> String {
121 install_cep78().await
122 }
123
124 #[tokio::test]
125 async fn test_call_entrypoint_with_none_values() {
126 let sdk = SDK::new(None, None, None);
128 let builder_params = TransactionBuilderParams::default();
129 let transaction_params = TransactionStrParams::default();
130 transaction_params.set_payment_amount(PAYMENT_AMOUNT);
131
132 let error_message =
133 "transaction requires account - use `with_account` or `with_secret_key`";
134
135 let result = sdk
137 .call_entrypoint(builder_params, transaction_params, None, None)
138 .await;
139
140 assert!(result.is_err());
142 let err_string = result.err().unwrap().to_string();
143 assert!(err_string.contains(error_message));
144 }
145
146 #[tokio::test]
147 async fn test_call_entrypoint_with_valid_input() {
148 let sdk = SDK::new(None, None, None);
150 let (rpc_address, _, _, _, chain_name) = get_network_constants();
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 entity_addr = EntityAddr::from_formatted_str(&get_entity_key().await).unwrap();
160
161 let builder_params =
162 TransactionBuilderParams::new_invocable_entity(entity_addr.into(), ENTRYPOINT_MINT);
163
164 let result = sdk
166 .call_entrypoint(builder_params, transaction_params, Some(rpc_address), None)
167 .await;
168
169 assert!(result.is_ok());
171 let transaction_hash = result.unwrap().result.transaction_hash;
172 assert!(!transaction_hash.to_string().is_empty());
173 }
174
175 #[tokio::test]
176 async fn test_call_entrypoint_with_invalid_input() {
177 let sdk = SDK::new(None, None, None);
179 let (rpc_address, _, _, _, chain_name) = get_network_constants();
180 let secret_key = get_user_secret_key(None).unwrap();
181
182 let error_message = "the transaction was invalid: no such contract at hash";
183 let mut transaction_params = TransactionStrParams::default();
184 transaction_params.set_secret_key(&secret_key);
185 transaction_params.set_chain_name(&chain_name);
186 transaction_params.set_session_args_simple(ARGS.to_vec());
187 transaction_params.set_payment_amount(PAYMENT_AMOUNT);
188
189 let entity_addr = EntityAddr::from_formatted_str(
190 "entity-contract-cfa781f5eb69c3eee952c2944ce9670a049f88c5e46b83fb5881ebe13fb98e6d",
191 )
192 .unwrap();
193
194 let builder_params =
195 TransactionBuilderParams::new_invocable_entity(entity_addr.into(), ENTRYPOINT_MINT);
196
197 let result = sdk
199 .call_entrypoint(builder_params, transaction_params, Some(rpc_address), None)
200 .await;
201
202 assert!(result.is_err());
204 let err_string = result.err().unwrap().to_string();
205 assert!(err_string.contains(error_message));
206 }
207
208 #[tokio::test]
209 async fn test_call_entrypoint_without_secret_key() {
210 let sdk = SDK::new(None, None, None);
212 let (rpc_address, _, _, _, chain_name) = get_network_constants();
213 let secret_key = get_user_secret_key(None).unwrap();
214 let initiator_addr = public_key_from_secret_key(&secret_key).unwrap();
215
216 let error_message = "the transaction was invalid: invalid associated keys";
217
218 let mut transaction_params = TransactionStrParams::default();
219 transaction_params.set_chain_name(&chain_name);
220 transaction_params.set_initiator_addr(&initiator_addr);
221 transaction_params.set_payment_amount(PAYMENT_AMOUNT);
222 transaction_params.set_session_args_simple(ARGS.to_vec());
223
224 let entity_addr = EntityAddr::from_formatted_str(
225 "entity-contract-cfa781f5eb69c3eee952c2944ce9670a049f88c5e46b83fb5881ebe13fb98e6d",
226 )
227 .unwrap();
228
229 let builder_params =
230 TransactionBuilderParams::new_invocable_entity(entity_addr.into(), ENTRYPOINT_MINT);
231
232 let result = sdk
234 .call_entrypoint(builder_params, transaction_params, Some(rpc_address), None)
235 .await;
236
237 assert!(result.is_err());
239 let err_string = result.err().unwrap().to_string();
240 assert!(err_string.contains(error_message));
241 }
242
243 #[tokio::test]
244 async fn test_call_entrypoint_with_error() {
245 let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
247 let (_, _, _, _, chain_name) = get_network_constants();
248 let secret_key = get_user_secret_key(None).unwrap();
249
250 let error_message = "error sending request";
251
252 let mut transaction_params = TransactionStrParams::default();
253 transaction_params.set_secret_key(&secret_key);
254 transaction_params.set_chain_name(&chain_name);
255 transaction_params.set_payment_amount(PAYMENT_AMOUNT);
256 transaction_params.set_session_args_simple(ARGS.to_vec());
257
258 let entity_addr = EntityAddr::from_formatted_str(
259 "entity-contract-cfa781f5eb69c3eee952c2944ce9670a049f88c5e46b83fb5881ebe13fb98e6d",
260 )
261 .unwrap();
262
263 let builder_params =
264 TransactionBuilderParams::new_invocable_entity(entity_addr.into(), ENTRYPOINT_MINT);
265
266 let result = sdk
268 .call_entrypoint(builder_params, transaction_params, None, None)
269 .await;
270
271 assert!(result.is_err());
273 let err_string = result.err().unwrap().to_string();
274 assert!(err_string.contains(error_message));
275 }
276}