multiversx_sc_snippets/
account_tool.rs1use crate::sdk_core::data::esdt::EsdtBalance;
2use multiversx_chain_scenario_format::interpret_trait::IntoRaw;
3use multiversx_sc_scenario::{
4 imports::Bech32Address,
5 scenario_model::{Account, BytesKey, BytesValue, Scenario, SetStateStep, Step},
6};
7use multiversx_sdk::gateway::{GatewayAsyncService, SetStateAccount};
8use multiversx_sdk::gateway::{
9 GetAccountEsdtRolesRequest, GetAccountEsdtTokensRequest, GetAccountRequest,
10 GetAccountStorageRequest,
11};
12use std::collections::{BTreeMap, HashMap};
13
14pub async fn print_account_as_scenario_set_state<GatewayProxy: GatewayAsyncService>(
19 gateway_proxy: GatewayProxy,
20 address_bech32_string: String,
21) {
22 let address = Bech32Address::from_bech32_string(address_bech32_string);
23 let (_, set_state) = retrieve_account_as_scenario_set_state(&gateway_proxy, &address).await;
24 let scenario = build_scenario(set_state);
25 println!("{}", scenario.into_raw().to_json_string());
26}
27
28fn build_scenario(set_state: SetStateStep) -> Scenario {
29 Scenario {
30 name: None,
31 comment: None,
32 check_gas: None,
33 steps: vec![Step::SetState(set_state)],
34 }
35}
36
37pub async fn retrieve_account_as_scenario_set_state<GatewayProxy: GatewayAsyncService>(
38 api: &GatewayProxy,
39 bech32_address: &Bech32Address,
40) -> (SetStateAccount, SetStateStep) {
41 let sdk_account = api
42 .request(GetAccountRequest::new(bech32_address))
43 .await
44 .unwrap();
45
46 let account_esdt = api
47 .request(GetAccountEsdtTokensRequest::new(bech32_address))
48 .await
49 .unwrap_or_else(|err| {
50 eprintln!("failed to retrieve ESDT tokens for address {bech32_address}: {err}");
51 HashMap::new()
52 });
53 let account_esdt_roles = api
54 .request(GetAccountEsdtRolesRequest::new(bech32_address))
55 .await
56 .unwrap_or_else(|err| {
57 eprintln!("failed to retrieve ESDT roles for address {bech32_address}: {err}");
58 HashMap::new()
59 });
60 let account_storage = api
61 .request(GetAccountStorageRequest::new(bech32_address))
62 .await
63 .unwrap_or_else(|err| {
64 panic!("failed to retrieve storage for address {bech32_address}: {err}")
65 });
66
67 let account_state = set_account(
68 sdk_account.clone(),
69 account_storage.clone(),
70 account_esdt,
71 account_esdt_roles,
72 );
73
74 let set_state_account = SetStateAccount::from(sdk_account).with_storage(account_storage);
75 let set_state_step = SetStateStep::new();
76 (
77 set_state_account,
78 set_state_step.put_account(bech32_address, account_state),
79 )
80}
81
82fn set_account(
83 account: crate::sdk::data::account::Account,
84 account_storage: HashMap<String, String>,
85 account_esdt: HashMap<String, EsdtBalance>,
86 account_esdt_roles: HashMap<String, Vec<String>>,
87) -> Account {
88 let mut account_state = Account::new()
89 .nonce(account.nonce)
90 .balance(account.balance.as_str())
91 .code(BytesValue::from_hex(&account.code));
92 account_state.username = Some(format!("str:{}", account.username.as_str()).into());
93 account_state.storage = convert_storage(account_storage);
94
95 for (_, esdt_balance) in account_esdt.iter() {
96 let token_id_expr = format!("str:{}", esdt_balance.token_identifier);
97 account_state =
98 account_state.esdt_balance(token_id_expr.as_str(), esdt_balance.balance.as_str());
99 }
100
101 for (token_id, esdt_roles) in account_esdt_roles {
102 let token_id_expr = format!("str:{token_id}");
103 account_state = account_state.esdt_roles(token_id_expr.as_str(), esdt_roles);
104 }
105
106 account_state
107}
108
109fn convert_storage(account_storage: HashMap<String, String>) -> BTreeMap<BytesKey, BytesValue> {
110 account_storage
111 .into_iter()
112 .filter(|(k, _)| !k.starts_with("454c524f4e44"))
113 .map(|(k, v)| (BytesKey::from_hex(&k), BytesValue::from_hex(&v)))
114 .collect()
115}