ethers_providers_rs/
lib.rs1use 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#[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 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}