1#![forbid(unsafe_code)]
7
8pub use aelf_client::config::{BasicAuth, ClientConfig, RetryPolicy};
9pub use aelf_client::dto;
10#[cfg(feature = "native-http")]
11pub use aelf_client::provider::HttpProvider;
12pub use aelf_client::provider::Provider;
13pub use aelf_client::{AElfError, KeyPairInfo, TransactionBuilder};
14pub use aelf_contract::{
15 AedposContract, ContractError, CrossChainContract, DynamicContract, ElectionContract,
16 TokenContract, VoteContract, ZeroContract,
17};
18pub use aelf_crypto::{
19 address_from_public_key, address_to_pb, base58_to_chain_id, chain_id_to_base58, decode_address,
20 hash_to_pb, parse_aelf_address, pb_to_address, sign_transaction,
21 sign_transaction_with_private_key, transaction_hash, CryptoError, Wallet, DEFAULT_BIP44_PATH,
22};
23pub use aelf_keystore::{Keystore, KeystoreEncryptOptions, KeystoreError, UnlockedKeystore};
24pub use aelf_proto as proto;
25
26#[derive(Clone)]
28pub struct AElfClient {
29 inner: aelf_client::AElfClient,
30}
31
32impl AElfClient {
33 #[cfg(feature = "native-http")]
35 pub fn new(config: ClientConfig) -> Result<Self, AElfError> {
36 Ok(Self {
37 inner: aelf_client::AElfClient::new(config)?,
38 })
39 }
40
41 pub fn with_provider<P>(provider: P) -> Result<Self, AElfError>
43 where
44 P: Provider + 'static,
45 {
46 Ok(Self {
47 inner: aelf_client::AElfClient::with_provider(provider)?,
48 })
49 }
50
51 pub fn block(&self) -> aelf_client::BlockService {
53 self.inner.block()
54 }
55
56 pub fn chain(&self) -> aelf_client::ChainService {
58 self.inner.chain()
59 }
60
61 pub fn net(&self) -> aelf_client::NetService {
63 self.inner.net()
64 }
65
66 pub fn tx(&self) -> aelf_client::TransactionService {
68 self.inner.tx()
69 }
70
71 pub fn utils(&self) -> aelf_client::ClientUtilsService {
73 self.inner.utils()
74 }
75
76 pub fn transaction_builder(&self) -> TransactionBuilder {
78 self.inner.transaction_builder()
79 }
80
81 pub async fn contract_at(
83 &self,
84 address: impl Into<String>,
85 wallet: Wallet,
86 ) -> Result<DynamicContract, ContractError> {
87 DynamicContract::at(self.inner.clone(), address.into(), wallet).await
88 }
89
90 pub fn zero_contract(&self, address: impl Into<String>, wallet: Wallet) -> ZeroContract {
92 ZeroContract::new(self.inner.clone(), wallet, address)
93 }
94
95 pub fn token_contract(&self, address: impl Into<String>, wallet: Wallet) -> TokenContract {
97 TokenContract::new(self.inner.clone(), wallet, address)
98 }
99
100 pub fn election_contract(
102 &self,
103 address: impl Into<String>,
104 wallet: Wallet,
105 ) -> ElectionContract {
106 ElectionContract::new(self.inner.clone(), wallet, address)
107 }
108
109 pub fn vote_contract(&self, address: impl Into<String>, wallet: Wallet) -> VoteContract {
111 VoteContract::new(self.inner.clone(), wallet, address)
112 }
113
114 pub fn cross_chain_contract(
116 &self,
117 address: impl Into<String>,
118 wallet: Wallet,
119 ) -> CrossChainContract {
120 CrossChainContract::new(self.inner.clone(), wallet, address)
121 }
122
123 pub fn aedpos_contract(&self, address: impl Into<String>, wallet: Wallet) -> AedposContract {
125 AedposContract::new(self.inner.clone(), wallet, address)
126 }
127
128 pub fn inner(&self) -> &aelf_client::AElfClient {
130 &self.inner
131 }
132}
133
134pub fn format_token_amount(amount: i64, decimals: i32) -> String {
136 if decimals <= 0 {
137 return amount.to_string();
138 }
139
140 let negative = amount.is_negative();
141 let digits = amount.unsigned_abs().to_string();
142 let scale = decimals as usize;
143 let formatted = if digits.len() <= scale {
144 let mut value = String::from("0.");
145 value.push_str(&"0".repeat(scale - digits.len()));
146 value.push_str(&digits);
147 value
148 } else {
149 let split = digits.len() - scale;
150 format!("{}.{}", &digits[..split], &digits[split..])
151 };
152
153 if negative {
154 format!("-{formatted}")
155 } else {
156 formatted
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 use super::format_token_amount;
163
164 #[test]
165 fn formats_token_amount_with_decimals() {
166 assert_eq!(format_token_amount(123_456_789, 8), "1.23456789");
167 assert_eq!(format_token_amount(1, 8), "0.00000001");
168 assert_eq!(format_token_amount(-5, 2), "-0.05");
169 }
170}