tron_api_client/
client.rs1use crate::error::{Error, Result};
2use crate::params::*;
3use crate::response::{
4 Account, AccountNet, AssetIssueList, Block, BlockList, ChainParameters, Contract, NodeInfo,
5 NodeList, Transaction, TransactionInfo, WitnessList,
6};
7use reqwest::{Client as HttpClient, Method, RequestBuilder, Response};
8use serde::{de::DeserializeOwned, Serialize};
9use serde_json;
10use url::Url;
11
12#[derive(Debug)]
13pub struct Client {
14 base_url: Url,
15 http_client: HttpClient,
17}
18
19pub enum Address {
20 Base58(String),
21 Hex(String),
22}
23pub struct TxId(pub String);
24
25pub enum Network {
26 Main,
27 Shasta,
28}
29
30async fn decode_response<T>(res: Response) -> Result<T>
31where
32 T: DeserializeOwned,
33{
34 let data = res.text().await?;
35 let s: T =
38 serde_json::from_str(&data).map_err(|orig_err| match serde_json::from_str(&data) {
39 Err(_) => {
40 println!("{}", data);
41 orig_err.into()
43 }
44 Ok(r) => Error::ServerError(r),
45 })?;
46
47 Ok(s)
48}
49
50impl Client {
51 pub fn new(base_url: String) -> Self {
52 Client {
53 base_url: Url::parse(&base_url).expect("could not parse base_url"),
54 http_client: HttpClient::new(),
55 }
56 }
57
58 pub fn for_network(network: Network) -> Self {
59 let base_url = match network {
60 Network::Shasta => "https://api.shasta.trongrid.io".to_string(),
61 Network::Main => "https://api.trongrid.io".to_string(),
62 _ => unimplemented!(),
63 };
64 Self::new(base_url)
65 }
66
67 pub fn for_shasta() -> Self {
68 Self::for_network(Network::Shasta)
69 }
70
71 pub fn for_main() -> Self {
72 Self::for_network(Network::Main)
73 }
74
75 async fn prep_req(&self, method: Method, url: Url) -> Result<RequestBuilder> {
78 let req = self
79 .http_client
80 .request(method, url)
81 .header("Content-Type", "application/json");
82 Ok(req)
83 }
84
85 fn get_url(&self, path: &str) -> Url {
86 self.base_url.join(path).expect("could not parse url")
87 }
88
89 async fn req<T, U>(&self, path: &str, method: Method, body: U) -> Result<T>
90 where
91 T: DeserializeOwned,
92 U: Serialize,
93 {
94 let res = match method {
95 Method::GET => {
96 self.prep_req(method, self.get_url(path))
97 .await?
98 .send()
99 .await?
100 }
101 Method::POST => {
102 self.prep_req(method, self.get_url(path))
103 .await?
104 .json(&body)
105 .send()
106 .await?
107 }
108 _ => unimplemented!(),
109 };
110 decode_response::<T>(res).await
111 }
112
113 async fn post<T, U>(&self, path: &str, param: U) -> Result<T>
114 where
115 T: DeserializeOwned,
116 U: Serialize,
117 {
118 self.req(path, Method::POST, param).await
119 }
120
121 async fn get<T>(&self, path: &str) -> Result<T>
122 where
123 T: DeserializeOwned,
124 {
125 self.req(path, Method::GET, EmptyBody::default()).await
126 }
127
128 pub async fn get_node_info(&self) -> Result<NodeInfo> {
129 self.get("/wallet/getnodeinfo").await
130 }
131
132 pub async fn list_nodes(&self) -> Result<NodeList> {
133 self.get("/wallet/listnodes").await
134 }
135
136 pub async fn list_witnesses(&self) -> Result<WitnessList> {
137 self.get("/walletsolidity/listwitnesses").await
138 }
139
140 pub async fn get_chain_parameters(&self) -> Result<ChainParameters> {
141 self.get("/wallet/getchainparameters").await
142 }
143
144 pub async fn get_block_by_num(&self, num: u64) -> Result<Block> {
145 self.post("/wallet/getblockbynum", GetBlockByNumParams::new(num))
146 .await
147 }
148
149 pub async fn get_block_by_id(&self, id: &str) -> Result<Block> {
150 self.post("/wallet/getblockbyid", GetBlockByIdParams::new(id.into()))
151 .await
152 }
153
154 pub async fn get_now_block(&self) -> Result<Block> {
155 self.post("/wallet/getnowblock", EmptyBody::default()).await
156 }
157
158 pub async fn get_block_by_latest_num(&self, num: u64) -> Result<BlockList> {
160 self.post("/wallet/getblockbylatestnum", GetBlockByNumParams::new(num))
161 .await
162 }
163
164 pub async fn get_block_by_limit_next(&self, start_num: u64, end_num: u64) -> Result<BlockList> {
165 self.post(
166 "/wallet/getblockbylimitnext",
167 GetBlockByRangeParams::new(start_num, end_num),
168 )
169 .await
170 }
171
172 pub async fn get_account(&self, address: Address) -> Result<Account> {
186 self.post("/walletsolidity/getaccount", GetAccountParams::new(address))
187 .await
188 }
189
190 pub async fn get_account_net(&self, address: Address) -> Result<AccountNet> {
191 self.post("/wallet/getaccountnet", GetAccountParams::new(address))
192 .await
193 }
194
195 pub async fn get_transaction_by_id(&self, tx_id: TxId) -> Result<Transaction> {
198 self.post(
199 "/wallet/gettransactionbyid",
200 GetTransactionParams::new(tx_id),
201 )
202 .await
203 }
204
205 pub async fn get_transaction_info_by_id(&self, tx_id: TxId) -> Result<TransactionInfo> {
206 self.post(
207 "/wallet/gettransactioninfobyid",
208 GetTransactionParams::new(tx_id),
209 )
210 .await
211 }
212
213 pub async fn get_contract(&self, address: Address) -> Result<Contract> {
214 self.post("/wallet/getcontract", GetContractParams::new(address))
215 .await
216 }
217
218 pub async fn get_asset_issue_list(&self) -> Result<AssetIssueList> {
221 self.post("/walletsolidity/getassetissuelist", EmptyBody::default())
222 .await
223 }
224}