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}