antelope/api/system/
mod.rs

1pub mod structs;
2
3use crate::api::client::{APIClient, Provider};
4use crate::api::system::structs::{
5    CreateAccountParams, DelegateBandwidthAction, NewAccountAction, SetAbiAction, SetCodeAction,
6    TransferAction,
7};
8use crate::api::v1::structs::{ClientError, SendTransactionResponse, SendTransactionResponseError};
9use crate::chain::abi::ABI;
10use crate::chain::action::{Action, PermissionLevel};
11use crate::chain::binary_extension::BinaryExtension;
12use crate::chain::name::Name;
13use crate::chain::private_key::PrivateKey;
14use crate::name;
15use crate::serializer::Encoder;
16use sha2::{Digest, Sha256};
17
18#[derive(Debug, Default, Clone)]
19pub struct SystemAPI<T: Provider> {
20    api_client: APIClient<T>,
21}
22
23impl<T: Provider> SystemAPI<T> {
24    pub fn new(api_client: APIClient<T>) -> Self {
25        SystemAPI { api_client }
26    }
27
28    pub async fn create_account(
29        &self,
30        create_params: CreateAccountParams,
31        creator_private_key: PrivateKey,
32    ) -> Result<SendTransactionResponse, ClientError<SendTransactionResponseError>> {
33        let CreateAccountParams {
34            name,
35            creator,
36            owner,
37            active,
38            ram_bytes,
39            stake_net,
40            stake_cpu,
41            transfer,
42        } = create_params;
43        let new_account_action = Action::new(
44            name!("eosio"),
45            name!("newaccount"),
46            PermissionLevel::new(creator, name!("active")),
47            NewAccountAction {
48                creator,
49                name,
50                owner,
51                active,
52            },
53        );
54        let buy_ram_action = Action::new(
55            name!("eosio"),
56            name!("buyrambytes"),
57            PermissionLevel::new(creator, name!("active")),
58            structs::BuyRamBytesAction {
59                payer: creator,
60                receiver: name,
61                bytes: ram_bytes,
62            },
63        );
64        let delegate_bw_action = Action::new(
65            name!("eosio"),
66            name!("delegatebw"),
67            PermissionLevel::new(creator, name!("active")),
68            DelegateBandwidthAction {
69                from: creator,
70                receiver: name,
71                stake_net_quantity: stake_net,
72                stake_cpu_quantity: stake_cpu,
73                transfer,
74            },
75        );
76        let actions = vec![new_account_action, buy_ram_action, delegate_bw_action];
77        self.api_client.transact(actions, creator_private_key).await
78    }
79
80    pub async fn transfer(
81        &self,
82        transfer_action: TransferAction,
83        sender_private_key: PrivateKey,
84        token_contract: Option<Name>,
85    ) -> Result<SendTransactionResponse, ClientError<SendTransactionResponseError>> {
86        self.api_client
87            .transact(
88                vec![Action::new(
89                    token_contract.unwrap_or(name!("eosio.token")),
90                    name!("transfer"),
91                    PermissionLevel::new(transfer_action.from, name!("active")),
92                    transfer_action,
93                )],
94                sender_private_key,
95            )
96            .await
97    }
98
99    pub async fn set_contract_from_files(
100        &self,
101        account: Name,
102        wasm_path: &str,
103        abi_path: &str,
104        memo: Option<String>,
105        private_key: PrivateKey,
106    ) -> Result<SendTransactionResponse, ClientError<SendTransactionResponseError>> {
107        let wasm = std::fs::read(wasm_path).unwrap();
108        let abi_json_bytes = std::fs::read(abi_path).unwrap();
109        let abi: ABI = serde_json::from_slice(&abi_json_bytes).unwrap();
110        let abi_bytes = Encoder::pack(&abi);
111        self.set_contract(account, wasm, abi_bytes, memo, private_key)
112            .await
113    }
114
115    pub async fn set_contract(
116        &self,
117        account: Name,
118        wasm: Vec<u8>,
119        abi: Vec<u8>,
120        memo: Option<String>,
121        private_key: PrivateKey,
122    ) -> Result<SendTransactionResponse, ClientError<SendTransactionResponseError>> {
123        let mut hasher = Sha256::new();
124        hasher.update(&wasm);
125        let wasm_hash = hasher.finalize();
126        println!(
127            "Setting contract for account: {:?}, with hash: {:?}",
128            account.as_string(),
129            wasm_hash
130        );
131        self.api_client
132            .transact(
133                vec![
134                    Action::new(
135                        name!("eosio"),
136                        name!("setcode"),
137                        PermissionLevel::new(account, name!("active")),
138                        SetCodeAction {
139                            vmtype: 0,
140                            vmversion: 0,
141                            account,
142                            code: wasm,
143                            memo: BinaryExtension::new(memo.clone()),
144                        },
145                    ),
146                    Action::new(
147                        name!("eosio"),
148                        name!("setabi"),
149                        PermissionLevel::new(account, name!("active")),
150                        SetAbiAction {
151                            account,
152                            abi,
153                            memo: BinaryExtension::new(memo),
154                        },
155                    ),
156                ],
157                private_key,
158            )
159            .await
160    }
161}