ethers_providers_rs/
lib.rs

1use std::sync::{Arc, Mutex};
2
3pub mod error;
4pub mod providers;
5
6mod rpc;
7pub use rpc::*;
8
9mod event;
10pub use event::*;
11
12pub use error::ProviderError;
13
14/// Ether network api provider
15///
16#[derive(Clone)]
17#[allow(dead_code)]
18pub struct Provider {
19    id: String,
20    rpc_client: jsonrpc_rs::Client,
21    pub(crate) oneshot: OneshotCompleteQ,
22    pub(crate) channel: ChannelCompleteQ,
23    pub(crate) events: Arc<Mutex<Vec<EventType>>>,
24}
25
26impl Provider {
27    pub fn new(id: String, rpc_client: jsonrpc_rs::Client) -> Self {
28        let this = Self {
29            id,
30            oneshot: OneshotCompleteQ::new(),
31            channel: ChannelCompleteQ::new(),
32            events: Default::default(),
33            rpc_client,
34        };
35
36        this.start_event_poll();
37
38        this
39    }
40
41    pub fn id(&self) -> &str {
42        &self.id
43    }
44
45    /// Get provider inner jsonrpc [`Client`](jsonrpc_rs::Client) ref.
46    pub fn client(&mut self) -> &mut jsonrpc_rs::Client {
47        &mut self.rpc_client
48    }
49}
50
51#[cfg(test)]
52mod tests {
53
54    use ethers_types_rs::SyncingStatus;
55    use jsonrpc_rs::RPCResult;
56    use serde_json::json;
57
58    use crate::providers::http;
59
60    #[async_std::test]
61    async fn test_block_number() -> RPCResult<()> {
62        _ = pretty_env_logger::try_init();
63
64        let mut provider = http::connect_to("http://localhost:8545");
65
66        let block_number = provider.eth_block_number().await?;
67
68        log::debug!("block number {}", block_number);
69
70        Ok(())
71    }
72
73    #[async_std::test]
74    async fn test_chain_id() -> RPCResult<()> {
75        _ = pretty_env_logger::try_init();
76
77        let mut provider = http::connect_to("http://localhost:8545");
78
79        let block_number = provider.eth_chain_id().await?;
80
81        log::debug!("chain_id {}", block_number);
82
83        Ok(())
84    }
85
86    #[async_std::test]
87    async fn test_eth_getblockbynumber() -> RPCResult<()> {
88        _ = pretty_env_logger::try_init();
89
90        let mut provider = http::connect_to("http://localhost:8545");
91
92        let block = provider.eth_get_block_by_number("latest", true).await?;
93
94        log::debug!(
95            "block
96             {}",
97            serde_json::to_string(&block).expect("Serialize block to json")
98        );
99
100        let block = provider.eth_get_block_by_number("0x1", true).await?;
101
102        log::debug!(
103            "block
104             {}",
105            serde_json::to_string(&block).expect("Serialize block to json")
106        );
107
108        Ok(())
109    }
110
111    #[async_std::test]
112    async fn test_eth_getblocktransactioncountbyhash() -> RPCResult<()> {
113        _ = pretty_env_logger::try_init();
114
115        let mut provider = http::connect_to("http://localhost:8545");
116
117        let block = provider
118            .eth_get_block_by_number("pending", true)
119            .await?
120            .unwrap();
121
122        if let Some(hash) = block.hash {
123            let tx_count = provider
124                .eth_get_block_transaction_count_by_hash(hash.clone())
125                .await?;
126
127            assert_eq!(block.transactions.len(), tx_count.as_usize());
128
129            let uncles = provider
130                .eth_get_uncle_count_by_block_hash(hash.clone())
131                .await?;
132
133            assert_eq!(block.uncles.len(), uncles.as_usize());
134
135            if let Some(number) = block.number {
136                let uncles = provider.eth_get_uncle_count_by_block_number(number).await?;
137
138                assert_eq!(block.uncles.len(), uncles.as_usize());
139            }
140        }
141
142        Ok(())
143    }
144
145    #[async_std::test]
146    async fn test_eth_syncing() -> RPCResult<()> {
147        _ = pretty_env_logger::try_init();
148
149        let mut provider = http::connect_to("http://localhost:8545");
150
151        let status = provider.eth_syncing().await?;
152
153        assert_eq!(status, SyncingStatus::False);
154
155        Ok(())
156    }
157
158    #[async_std::test]
159    async fn test_eth_coinbase() {
160        _ = pretty_env_logger::try_init();
161
162        let mut provider = http::connect_to("http://localhost:8545");
163
164        let address = provider.eth_coinbase().await.expect("eth_coinbase");
165
166        log::debug!("{}", address);
167    }
168
169    #[async_std::test]
170    async fn test_eth_accounts() {
171        _ = pretty_env_logger::try_init();
172
173        let mut provider = http::connect_to("http://localhost:8545");
174
175        let accounts = provider.eth_accounts().await.expect("eth_coinbase");
176
177        log::debug!(
178            "{:?}",
179            accounts.iter().map(|a| a.to_string()).collect::<Vec<_>>()
180        );
181    }
182
183    #[async_std::test]
184    async fn test_eth_gas_price() {
185        _ = pretty_env_logger::try_init();
186
187        let mut provider = http::connect_to("http://localhost:8545");
188
189        let price = provider.eth_gas_price().await.expect("eth_gas_price");
190
191        log::debug!("{}", price);
192    }
193
194    #[async_std::test]
195    async fn test_eth_free_history() {
196        _ = pretty_env_logger::try_init();
197
198        let mut provider = http::connect_to("http://localhost:8545");
199
200        let history = provider
201            .eth_fee_history("0x10", "latest", &[100f64])
202            .await
203            .expect("eth_fee_history");
204
205        log::debug!(
206            "{}",
207            serde_json::to_string_pretty(&history).expect("Serialize history to json")
208        );
209    }
210
211    #[async_std::test]
212    async fn test_eth_new_filter() {
213        _ = pretty_env_logger::try_init();
214
215        let mut provider = http::connect_to("http://localhost:8545");
216
217        provider
218            .eth_new_filter(json!({
219                "fromBlock": "0x1",
220                "toBlock": "0x02",
221            }))
222            .await
223            .expect("eth_new_filter");
224    }
225
226    #[async_std::test]
227    async fn test_eth_new_any_filter() {
228        _ = pretty_env_logger::try_init();
229
230        let mut provider = http::connect_to("http://localhost:8545");
231
232        let filter = provider
233            .eth_new_block_filter()
234            .await
235            .expect("eth_newBlockFilter");
236
237        log::debug!("create new blockFilter {}", filter);
238
239        let filter = provider
240            .eth_new_pending_transaction_filter()
241            .await
242            .expect("eth_newPendingTransactionFilter");
243
244        log::debug!("create new pending transaction filter {}", filter);
245
246        let result = provider
247            .eth_get_filter_changes(filter.clone())
248            .await
249            .expect("eth_getFilterChanges");
250
251        log::debug!("eth_getFilterChanges {:?}", result);
252
253        assert_eq!(
254            provider
255                .eth_uninstall_filter(filter)
256                .await
257                .expect("eth_uninstallFilter"),
258            true
259        );
260    }
261
262    #[async_std::test]
263    async fn test_eth_get_logs() {
264        _ = pretty_env_logger::try_init();
265
266        let mut provider = http::connect_to("http://localhost:8545");
267
268        provider
269            .eth_new_filter(json!({
270                "fromBlock": "0x1",
271                "toBlock": "0x02",
272            }))
273            .await
274            .expect("eth_new_filter");
275
276        let result = provider
277            .eth_get_logs(json!({
278                "fromBlock": "0x1",
279                "toBlock": "0x02",
280            }))
281            .await
282            .expect("eth_getLogs");
283
284        log::debug!("eth_getFilterChanges {:?}", result);
285    }
286
287    #[async_std::test]
288    async fn test_eth_sign() {
289        _ = pretty_env_logger::try_init();
290
291        let mut provider = http::connect_to("http://localhost:8545");
292
293        let sig = provider
294            .eth_sign(
295                "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
296                "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
297            )
298            .await
299            .expect("eth_new_filter");
300
301        log::debug!("eth_getFilterChanges {:?}", sig);
302    }
303
304    #[async_std::test]
305    async fn test_eth_sign_transaction() {
306        _ = pretty_env_logger::try_init();
307
308        let mut provider = http::connect_to("http://localhost:8545");
309
310        let balance = provider
311            .eth_get_balance("0xa0Ee7A142d267C1f36714E4a8F75612F20a79720")
312            .await
313            .expect("eth_getBlance");
314
315        log::debug!("balance {}", balance);
316
317        let nonce = provider
318            .eth_get_transaction_count("0xa0Ee7A142d267C1f36714E4a8F75612F20a79720")
319            .await
320            .expect("eth_getTransactionCount");
321
322        log::debug!("nonce {}", nonce);
323
324        provider
325            .eth_sign_transaction(json!({
326                "nonce": nonce,
327                "from": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
328                "to": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
329                "value":"0x11",
330                "gas": "0x11",
331                "input":"0x0"
332            }))
333            .await
334            .expect_err("eth_signTransaction not support");
335    }
336
337    #[async_std::test]
338    async fn test_eth_send_raw_transaction() {
339        _ = pretty_env_logger::try_init();
340
341        let mut provider = http::connect_to("http://localhost:8545");
342
343        provider
344            .eth_send_raw_transaction("0x000")
345            .await
346            .expect_err("eth_sendRawTransaction error");
347    }
348
349    #[async_std::test]
350    async fn test_eth_get_transaction_by_hash() {
351        _ = pretty_env_logger::try_init();
352
353        let mut provider = http::connect_to("http://localhost:8545");
354
355        provider
356            .eth_get_transaction_by_hash(
357                "0x0bb3c2388383f714a8070dc6078a5edbe78f23c96646d4148d63cf964197ccc5",
358            )
359            .await
360            .expect("eth_getTransactionByHash");
361    }
362
363    #[async_std::test]
364    async fn test_eth_get_transaction_receipt() {
365        _ = pretty_env_logger::try_init();
366
367        let mut provider = http::connect_to("http://localhost:8545");
368
369        provider
370            .eth_get_transaction_receipt(
371                "0x0bb3c2388383f714a8070dc6078a5edbe78f23c96646d4148d63cf964197ccc5",
372            )
373            .await
374            .expect("eth_getTransactionByHash");
375    }
376}