casper_rust_wasm_sdk/sdk/rpcs/
get_account.rs1#[cfg(all(feature = "js", target_arch = "wasm32"))]
2use crate::types::identifier::block_identifier::BlockIdentifier;
3use crate::{
4 types::{
5 account::Account,
6 identifier::{
7 account_identifier::AccountIdentifier, block_identifier::BlockIdentifierInput,
8 },
9 sdk_error::SdkError,
10 verbosity::Verbosity,
11 },
12 SDK,
13};
14use casper_client::cli::parse::account_identifier as parse_account_identifier;
15use casper_client::{
16 cli::get_account as get_account_cli, get_account as get_account_lib,
17 rpcs::results::GetAccountResult as _GetAccountResult, JsonRpcId, SuccessResponse,
18};
19#[cfg(all(feature = "js", target_arch = "wasm32"))]
20use gloo_utils::format::JsValueSerdeExt;
21use rand::RngExt;
22use serde::{Deserialize, Serialize};
23#[cfg(feature = "js")]
24use wasm_bindgen::prelude::*;
25
26#[derive(Debug, Deserialize, Clone, Serialize)]
28#[cfg_attr(feature = "js", wasm_bindgen)]
29pub struct GetAccountResult(_GetAccountResult);
30
31impl From<GetAccountResult> for _GetAccountResult {
32 fn from(result: GetAccountResult) -> Self {
33 result.0
34 }
35}
36
37impl From<_GetAccountResult> for GetAccountResult {
38 fn from(result: _GetAccountResult) -> Self {
39 GetAccountResult(result)
40 }
41}
42
43impl GetAccountResult {
44 pub fn account_typed(&self) -> Account {
46 self.0.account.clone().into()
47 }
48}
49
50#[cfg(all(feature = "js", target_arch = "wasm32"))]
51#[cfg_attr(feature = "js", wasm_bindgen)]
52impl GetAccountResult {
53 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
54 #[cfg(feature = "js")]
55 pub fn api_version(&self) -> JsValue {
56 JsValue::from_serde(&self.0.api_version).unwrap()
57 }
58
59 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
60 #[cfg(feature = "js")]
61 pub fn account(&self) -> JsValue {
62 JsValue::from_serde(&self.0.account).unwrap()
63 }
64
65 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "accountTyped"))]
67 pub fn account_typed_js(&self) -> Account {
68 self.account_typed()
69 }
70
71 #[cfg_attr(feature = "js", wasm_bindgen(getter))]
72 pub fn merkle_proof(&self) -> String {
73 self.0.merkle_proof.clone()
74 }
75
76 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toJson"))]
77 #[cfg(feature = "js")]
78 pub fn to_json(&self) -> JsValue {
79 JsValue::from_serde(&self.0).unwrap_or(JsValue::null())
80 }
81}
82
83#[derive(Debug, Deserialize, Clone, Default, Serialize)]
85#[cfg(all(feature = "js", target_arch = "wasm32"))]
86#[cfg_attr(
87 feature = "js",
88 wasm_bindgen(js_name = "getAccountOptions", getter_with_clone)
89)]
90pub struct GetAccountOptions {
91 pub account_identifier: Option<AccountIdentifier>,
92 pub account_identifier_as_string: Option<String>,
93 pub maybe_block_id_as_string: Option<String>,
94 pub maybe_block_identifier: Option<BlockIdentifier>,
95 pub rpc_address: Option<String>,
96 pub verbosity: Option<Verbosity>,
97}
98
99#[cfg(all(feature = "js", target_arch = "wasm32"))]
100#[cfg_attr(feature = "js", wasm_bindgen)]
101impl SDK {
102 #[deprecated(note = "prefer 'get_entity_options'")]
104 #[allow(deprecated)]
105 #[cfg(feature = "js")]
106 pub fn get_account_options(&self, options: JsValue) -> Result<GetAccountOptions, JsError> {
107 options
108 .into_serde::<GetAccountOptions>()
109 .map_err(|err| JsError::new(&format!("Error deserializing options: {err:?}")))
110 }
111
112 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "get_account"))]
135 #[deprecated(note = "prefer 'get_entity'")]
136 #[allow(deprecated)]
137 #[cfg(feature = "js")]
138 pub async fn get_account_js_alias(
139 &self,
140 options: Option<GetAccountOptions>,
141 ) -> Result<GetAccountResult, JsError> {
142 let GetAccountOptions {
143 account_identifier,
144 account_identifier_as_string,
145 maybe_block_id_as_string,
146 maybe_block_identifier,
147 verbosity,
148 rpc_address,
149 } = options.unwrap_or_default();
150
151 let maybe_block_identifier = if let Some(maybe_block_identifier) = maybe_block_identifier {
152 Some(BlockIdentifierInput::BlockIdentifier(
153 maybe_block_identifier,
154 ))
155 } else {
156 maybe_block_id_as_string.map(BlockIdentifierInput::String)
157 };
158
159 let result = self
160 .get_account(
161 account_identifier,
162 account_identifier_as_string,
163 maybe_block_identifier,
164 verbosity,
165 rpc_address,
166 )
167 .await;
168 match result {
169 Ok(data) => Ok(data.result.into()),
170 Err(err) => {
171 let err = &format!("Error occurred with {err:?}");
172 Err(JsError::new(err))
173 }
174 }
175 }
176
177 #[cfg_attr(feature = "js", wasm_bindgen(js_name = "state_get_account_info"))]
179 #[deprecated(note = "prefer 'get_entity'")]
180 #[allow(deprecated)]
181 #[cfg(feature = "js")]
182 pub async fn state_get_account_info(
183 &self,
184 options: Option<GetAccountOptions>,
185 ) -> Result<GetAccountResult, JsError> {
186 self.get_account_js_alias(options).await
187 }
188}
189
190impl SDK {
191 #[deprecated(note = "prefer 'get_entity'")]
209 #[allow(deprecated)]
210 pub async fn get_account(
211 &self,
212 account_identifier: Option<AccountIdentifier>,
213 account_identifier_as_string: Option<String>,
214 maybe_block_identifier: Option<BlockIdentifierInput>,
215 verbosity: Option<Verbosity>,
216 rpc_address: Option<String>,
217 ) -> Result<SuccessResponse<_GetAccountResult>, SdkError> {
218 let account_identifier = if let Some(account_identifier) = account_identifier {
219 account_identifier
220 } else if let Some(account_identifier_as_string) = account_identifier_as_string.clone() {
221 match parse_account_identifier(&account_identifier_as_string) {
222 Ok(parsed) => parsed.into(),
223 Err(err) => {
224 return Err(err.into());
225 }
226 }
227 } else {
228 let err = "Error: Missing account identifier".to_string();
229 return Err(SdkError::InvalidArgument {
230 context: "get_account",
231 error: err,
232 });
233 };
234 let random_id = rand::rng().random::<u64>().to_string();
235 if let Some(BlockIdentifierInput::String(maybe_block_id)) = maybe_block_identifier {
236 get_account_cli(
237 &random_id,
238 &self.get_rpc_address(rpc_address),
239 self.get_verbosity(verbosity).into(),
240 &maybe_block_id,
241 &account_identifier.to_string(),
242 )
243 .await
244 .map_err(SdkError::from)
245 } else {
246 let maybe_block_identifier =
247 if let Some(BlockIdentifierInput::BlockIdentifier(maybe_block_identifier)) =
248 maybe_block_identifier
249 {
250 Some(maybe_block_identifier)
251 } else {
252 None
253 };
254 get_account_lib(
255 JsonRpcId::from(random_id),
256 &self.get_rpc_address(rpc_address),
257 self.get_verbosity(verbosity).into(),
258 maybe_block_identifier.map(Into::into),
259 account_identifier.into(),
260 )
261 .await
262 .map_err(SdkError::from)
263 }
264 }
265}
266
267#[cfg(test)]
268mod tests {
269 use super::*;
270 use crate::{
271 helpers::public_key_from_secret_key,
272 types::{identifier::block_identifier::BlockIdentifier, public_key::PublicKey},
273 };
274 use sdk_tests::tests::helpers::{
275 get_enable_addressable_entity, get_network_constants, get_user_secret_key,
276 };
277
278 #[allow(deprecated)]
279 fn get_account_identifier() -> AccountIdentifier {
280 let secret_key = get_user_secret_key(None).unwrap();
281 let account = public_key_from_secret_key(&secret_key).unwrap();
282 let public_key = PublicKey::new(&account).unwrap();
283
284 AccountIdentifier::from_account_under_public_key(public_key)
285 }
286
287 #[tokio::test]
288 #[allow(deprecated)]
289 async fn test_get_account_with_none_values() {
290 let sdk = SDK::new(None, None, None);
292 let error_message = "failed to parse node address as valid URL";
293 let account_identifier = get_account_identifier();
294
295 let result = sdk
297 .get_account(Some(account_identifier), None, None, None, None)
298 .await;
299
300 assert!(result.is_err());
302 let err_string = result.err().unwrap().to_string();
303 assert!(err_string.contains(error_message));
304 }
305
306 #[tokio::test]
307 #[allow(deprecated)]
308 async fn test_get_account_with_missing_account() {
309 let sdk = SDK::new(None, None, None);
311 let error_message = "Error: Missing account identifier";
312
313 let result = sdk.get_account(None, None, None, None, None).await;
315
316 assert!(result.is_err());
318 let err_string = result.err().unwrap().to_string();
319 assert!(err_string.contains(error_message));
320 }
321
322 #[tokio::test]
323 #[allow(deprecated)]
324 async fn _test_get_account_with_account_identifier() {
325 if get_enable_addressable_entity() {
326 return;
327 }
328 let sdk = SDK::new(None, None, None);
330 let account_identifier = get_account_identifier();
331 let verbosity = Some(Verbosity::High);
332 let (rpc_address, _, _, _, _) = get_network_constants();
333
334 let result = sdk
336 .get_account(
337 Some(account_identifier),
338 None,
339 None,
340 verbosity,
341 Some(rpc_address),
342 )
343 .await;
344 assert!(result.is_ok());
346 }
347
348 #[tokio::test]
349 #[allow(deprecated)]
350 async fn _test_get_account_with_account_identifier_as_string() {
351 if get_enable_addressable_entity() {
352 return;
353 }
354 let sdk = SDK::new(None, None, None);
356 let account_identifier_as_string = get_account_identifier().to_string();
357 let verbosity = Some(Verbosity::High);
358 let (rpc_address, _, _, _, _) = get_network_constants();
359
360 let result = sdk
362 .get_account(
363 None,
364 Some(account_identifier_as_string),
365 None,
366 verbosity,
367 Some(rpc_address),
368 )
369 .await;
370
371 assert!(result.is_ok());
373 }
374
375 #[tokio::test]
376 #[allow(deprecated)]
377 async fn _test_get_account_with_block_identifier() {
378 if get_enable_addressable_entity() {
379 return;
380 }
381 let sdk = SDK::new(None, None, None);
383 let block_identifier =
384 BlockIdentifierInput::BlockIdentifier(BlockIdentifier::from_height(1));
385 let account_identifier = get_account_identifier();
386 let verbosity = Some(Verbosity::High);
387 let (rpc_address, _, _, _, _) = get_network_constants();
388
389 let result = sdk
391 .get_account(
392 Some(account_identifier),
393 None,
394 Some(block_identifier),
395 verbosity,
396 Some(rpc_address),
397 )
398 .await;
399
400 assert!(result.is_ok());
402 }
403
404 #[tokio::test]
405 #[allow(deprecated)]
406 async fn test_get_account_with_error() {
407 let sdk = SDK::new(Some("http://localhost".to_string()), None, None);
408 let account_identifier = get_account_identifier();
409 let error_message = "error sending request";
410
411 let result = sdk
412 .get_account(Some(account_identifier), None, None, None, None)
413 .await;
414
415 assert!(result.is_err());
416 let err_string = result.err().unwrap().to_string();
417 assert!(err_string.contains(error_message));
418 }
419
420 #[tokio::test]
421 #[allow(deprecated)]
422 async fn test_get_account_typed_legacy() {
423 if get_enable_addressable_entity() {
424 return;
425 }
426 let sdk = SDK::new(None, None, None);
427 let account_identifier = get_account_identifier();
428 let verbosity = Some(Verbosity::High);
429 let (rpc_address, _, _, _, _) = get_network_constants();
430
431 let result = sdk
432 .get_account(
433 Some(account_identifier),
434 None,
435 None,
436 verbosity,
437 Some(rpc_address),
438 )
439 .await
440 .expect("get_account");
441
442 let account = GetAccountResult::from(result.result).account_typed();
443 assert!(!account.account_hash().to_formatted_string().is_empty());
444 assert!(!account.main_purse().to_formatted_string().is_empty());
445 }
446}