gemblockchain/node.rs
1/// Module with a set of node answer struct
2pub mod response;
3
4use response::*;
5
6/// Mainnet node REST API
7pub const MAINNET_URL: &str = "https://nodes.wavesnodes.com";
8/// Testnet node REST API
9pub const TESTNET_URL: &str = "https://nodes-testnet.wavesnodes.com";
10/// Stagenet node REST API
11pub const STAGENET_URL: &str = "https://nodes-stagenet.wavesnodes.com";
12/// Local node REST API
13pub const LOCAL_URL: &str = "http://127.0.0.1:6869";
14
15/// [`Node`] client for executing asynchronous requests.
16///
17/// [`Node`] client has url as the configuration value, but the default is set to what is usually the most commonly desired value. Use [`Node::from_url()`] to create the node client.
18pub struct Node<'a> {
19 url: &'a str,
20}
21
22impl<'a> Default for Node<'a> {
23 fn default() -> Self {
24 Node { url: MAINNET_URL }
25 }
26}
27
28impl<'a> Node<'a> {
29 /// Create an [`Node`] from url string.
30 pub fn from_url(url: &'a str) -> Self {
31 Node { url }
32 }
33
34 /// Get the regular balance in WAVES at a given address
35 /// ```no_run
36 /// use gemblockchain::node::{Node, MAINNET_URL};
37 /// use gemblockchain::util::Amount;
38 ///
39 /// #[tokio::main]
40 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
41 /// let node = Node::from_url(MAINNET_URL);
42 ///
43 /// let result = node
44 /// .get_balance("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
45 /// .await?;
46 ///
47 /// let balance = Amount::from_wavelet(result.balance());
48 ///
49 /// println!("Balance: {} WAVES", balance);
50 ///
51 /// Ok(())
52 /// }
53 /// ```
54 pub async fn get_balance(
55 &self,
56 address: &str,
57 ) -> Result<ResponseBalance, Box<dyn std::error::Error>> {
58 let url = format!("{}/addresses/balance/{}", self.url, address);
59
60 let res = reqwest::get(url).await?.json::<ResponseBalance>().await?;
61
62 Ok(res)
63 }
64
65 /// Get the available, regular, generating, and effective balance
66 /// ```no_run
67 /// use gemblockchain::node::{Node, MAINNET_URL};
68 /// use gemblockchain::util::Amount;
69 ///
70 /// #[tokio::main]
71 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
72 /// let node = Node::from_url(MAINNET_URL);
73 ///
74 /// let result = node
75 /// .get_balance_details("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
76 /// .await?;
77 ///
78 /// let balance = Amount::from_wavelet(result.regular());
79 ///
80 /// println!("Regular balance: {} WAVES", balance);
81 ///
82 /// Ok(())
83 /// }
84 /// ```
85 pub async fn get_balance_details(
86 &self,
87 address: &str,
88 ) -> Result<ResponseBalanceDetails, Box<dyn std::error::Error>> {
89 let url = format!("{}/addresses/balance/details/{}", self.url, address);
90
91 let res = reqwest::get(url)
92 .await?
93 .json::<ResponseBalanceDetails>()
94 .await?;
95
96 Ok(res)
97 }
98
99 /// Get an address associated with a given alias.
100 /// ```no_run
101 /// use gemblockchain::node::{Node, MAINNET_URL};
102 ///
103 /// #[tokio::main]
104 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
105 /// let node = Node::from_url(MAINNET_URL);
106 ///
107 /// let result = node.get_address_by_alias("vlzhr").await?;
108 ///
109 /// println!("vlzhr -> {}", result.address());
110 ///
111 /// Ok(())
112 /// }
113 /// ```
114 pub async fn get_address_by_alias(
115 &self,
116 alias: &str,
117 ) -> Result<ResponseAddress, Box<dyn std::error::Error>> {
118 let url = format!("{}/alias/by-alias/{}", self.url, alias);
119
120 let res = reqwest::get(url).await?.json::<ResponseAddress>().await?;
121
122 Ok(res)
123 }
124
125 /// Get detailed information about given asset
126 /// ```no_run
127 /// use gemblockchain::node::{Node, MAINNET_URL};
128 ///
129 /// #[tokio::main]
130 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
131 /// let node = Node::from_url(MAINNET_URL);
132 ///
133 /// let result = node
134 /// .get_assets_details("34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ")
135 /// .await?;
136 ///
137 /// println!("{:?}", result);
138 ///
139 /// Ok(())
140 /// }
141 /// ```
142 pub async fn get_assets_details(
143 &self,
144 asset_id: &str,
145 ) -> Result<ResponseAsset, Box<dyn std::error::Error>> {
146 let url = format!("{}/assets/details/{}", self.url, asset_id);
147
148 let res = reqwest::get(url).await?.json::<ResponseAsset>().await?;
149
150 Ok(res)
151 }
152
153 /// Get headers of a given block
154 /// ```no_run
155 /// use gemblockchain::node::{Node, MAINNET_URL};
156 ///
157 /// #[tokio::main]
158 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
159 /// let node = Node::from_url(MAINNET_URL);
160 ///
161 /// let result = node
162 /// .get_blocks_headers("3cBRMpKHjPNKUXkgGJNGAaPviY4LmE8urTwd4B2J8v9M")
163 /// .await?;
164 ///
165 /// println!("{:?}", result);
166 ///
167 /// Ok(())
168 /// }
169 /// ```
170 pub async fn get_blocks_headers(
171 &self,
172 id: &str,
173 ) -> Result<ResponseBlock, Box<dyn std::error::Error>> {
174 let url = format!("{}/blocks/headers/{}", self.url, id);
175
176 let res = reqwest::get(url).await?.json::<ResponseBlock>().await?;
177
178 Ok(res)
179 }
180
181 /// Get headers of a given block
182 /// ```no_run
183 /// use gemblockchain::node::{Node, MAINNET_URL};
184 ///
185 /// #[tokio::main]
186 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
187 /// let node = Node::from_url(MAINNET_URL);
188 ///
189 /// let result = node.get_blocks_headers_at_height(3341874).await?;
190 ///
191 /// println!("{:?}", result);
192 ///
193 /// Ok(())
194 /// }
195 /// ```
196 pub async fn get_blocks_headers_at_height(
197 &self,
198 height: u64,
199 ) -> Result<ResponseBlock, Box<dyn std::error::Error>> {
200 let url = format!("{}/blocks/headers/at/{}", self.url, height);
201
202 let res = reqwest::get(url).await?.json::<ResponseBlock>().await?;
203
204 Ok(res)
205 }
206
207 /// Get the block at the current blockchain height
208 /// ```no_run
209 /// use gemblockchain::node::{Node, MAINNET_URL};
210 ///
211 /// #[tokio::main]
212 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
213 /// let node = Node::from_url(MAINNET_URL);
214 ///
215 /// let result = node.get_blocks_last().await?;
216 ///
217 /// println!("{:?}", result);
218 ///
219 /// Ok(())
220 /// }
221 /// ```
222 pub async fn get_blocks_last(&self) -> Result<ResponseBlock, Box<dyn std::error::Error>> {
223 let url = format!("{}/blocks/last", self.url);
224
225 let res = reqwest::get(url).await?.json::<ResponseBlock>().await?;
226
227 Ok(res)
228 }
229
230 /// Get lease parameters by lease ID
231 /// ```no_run
232 /// use gemblockchain::node::{Node, MAINNET_URL};
233 ///
234 /// #[tokio::main]
235 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
236 /// let node = Node::from_url(MAINNET_URL);
237 ///
238 /// let result = node
239 /// .get_leasing_info("YwVPf35VckF4Yu5XwF18P9VwWwfQVGAQmqDp4bpgtuV")
240 /// .await?;
241 ///
242 /// println!("{:?}", result);
243 ///
244 /// Ok(())
245 /// }
246 /// ```
247 pub async fn get_leasing_info(
248 &self,
249 id: &str,
250 ) -> Result<ResponseLease, Box<dyn std::error::Error>> {
251 let url = format!("{}/leasing/info/{}", self.url, id);
252
253 let res = reqwest::get(url).await?.json::<ResponseLease>().await?;
254
255 Ok(res)
256 }
257
258 /// Get node version
259 /// ```no_run
260 /// use gemblockchain::node::{Node, MAINNET_URL};
261 ///
262 /// #[tokio::main]
263 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
264 /// let node = Node::from_url(MAINNET_URL);
265 ///
266 /// let result = node.get_node_version().await?;
267 ///
268 /// println!("Version: {}", result.version());
269 ///
270 /// Ok(())
271 /// }
272 /// ```
273 pub async fn get_node_version(
274 &self,
275 ) -> Result<ResponseNodeVersion, Box<dyn std::error::Error>> {
276 let url = format!("{}/node/version", self.url);
277
278 let res = reqwest::get(url)
279 .await?
280 .json::<ResponseNodeVersion>()
281 .await?;
282
283 Ok(res)
284 }
285
286 /// Get a transaction by its ID
287 /// ```no_run
288 /// use gemblockchain::node::{Node, MAINNET_URL};
289 ///
290 /// #[tokio::main]
291 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
292 /// let node = Node::from_url(MAINNET_URL);
293 ///
294 /// let result = node
295 /// .get_transactions_info("YwVPf35VckF4Yu5XwF18P9VwWwfQVGAQmqDp4bpgtuV")
296 /// .await?;
297 ///
298 /// println!("{:?}", result);
299 ///
300 /// Ok(())
301 /// }
302 /// ```
303 pub async fn get_transactions_info(
304 &self,
305 id: &str,
306 ) -> Result<ResponseTransaction, Box<dyn std::error::Error>> {
307 let url = format!("{}/transactions/info/{}", self.url, id);
308
309 let res = reqwest::get(url)
310 .await?
311 .json::<ResponseTransaction>()
312 .await?;
313
314 Ok(res)
315 }
316
317 /// Get transaction status by its ID
318 /// ```no_run
319 /// use gemblockchain::node::{Node, MAINNET_URL};
320 ///
321 /// #[tokio::main]
322 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
323 /// let node = Node::from_url(MAINNET_URL);
324 ///
325 /// let result = node
326 /// .get_transactions_status("YwVPf35VckF4Yu5XwF18P9VwWwfQVGAQmqDp4bpgtuV")
327 /// .await?;
328 ///
329 /// println!("{:?}", result);
330 ///
331 /// Ok(())
332 /// }
333 /// ```
334 pub async fn get_transactions_status(
335 &self,
336 id: &str,
337 ) -> Result<ResponseTransactionStatus, Box<dyn std::error::Error>> {
338 let url = format!("{}/transactions/status/{}", self.url, id);
339
340 let res = reqwest::get(url)
341 .await?
342 .json::<ResponseTransactionStatus>()
343 .await?;
344
345 Ok(res)
346 }
347}