ethers_providers/
lib.rs

1#![doc = include_str!("../README.md")]
2#![allow(clippy::type_complexity)]
3#![warn(missing_docs)]
4#![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
5#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
6
7mod ext;
8pub use ext::*;
9
10mod rpc;
11pub use rpc::*;
12
13mod toolbox;
14pub use toolbox::*;
15
16/// Crate utilities and type aliases
17mod utils;
18pub use utils::{interval, maybe, EscalationPolicy};
19
20/// Errors
21mod errors;
22pub use errors::{MiddlewareError, ProviderError, RpcError};
23
24mod stream;
25pub use futures_util::StreamExt;
26pub use stream::{
27    tx_stream::TransactionStream, FilterWatcher, DEFAULT_LOCAL_POLL_INTERVAL, DEFAULT_POLL_INTERVAL,
28};
29
30mod middleware;
31#[cfg(feature = "celo")]
32pub use middleware::CeloMiddleware;
33pub use middleware::Middleware;
34
35#[allow(deprecated)]
36pub use test_provider::{GOERLI, MAINNET, ROPSTEN, SEPOLIA};
37
38/// Pre-instantiated Infura HTTP clients which rotate through multiple API keys
39/// to prevent rate limits
40#[allow(missing_docs)]
41pub mod test_provider {
42    use super::*;
43    use once_cell::sync::Lazy;
44    use std::{iter::Cycle, slice::Iter, sync::Mutex};
45
46    // List of infura keys to rotate through so we don't get rate limited
47    const INFURA_KEYS: &[&str] = &["15e8aaed6f894d63a0f6a0206c006cdd"];
48
49    pub static MAINNET: Lazy<TestProvider> =
50        Lazy::new(|| TestProvider::new(INFURA_KEYS, "mainnet"));
51    pub static GOERLI: Lazy<TestProvider> = Lazy::new(|| TestProvider::new(INFURA_KEYS, "goerli"));
52    pub static SEPOLIA: Lazy<TestProvider> =
53        Lazy::new(|| TestProvider::new(INFURA_KEYS, "sepolia"));
54
55    #[deprecated = "Ropsten testnet has been deprecated in favor of Goerli or Sepolia."]
56    pub static ROPSTEN: Lazy<TestProvider> =
57        Lazy::new(|| TestProvider::new(INFURA_KEYS, "ropsten"));
58
59    #[derive(Debug)]
60    pub struct TestProvider {
61        network: String,
62        keys: Mutex<Cycle<Iter<'static, &'static str>>>,
63    }
64
65    impl TestProvider {
66        pub fn new(keys: &'static [&'static str], network: impl Into<String>) -> Self {
67            Self { keys: keys.iter().cycle().into(), network: network.into() }
68        }
69
70        pub fn url(&self) -> String {
71            let Self { network, keys } = self;
72            let key = keys.lock().unwrap().next().unwrap();
73            format!("https://{network}.infura.io/v3/{key}")
74        }
75
76        pub fn provider(&self) -> Provider<Http> {
77            Provider::try_from(self.url().as_str()).unwrap()
78        }
79
80        #[cfg(feature = "ws")]
81        pub async fn ws(&self) -> Provider<crate::Ws> {
82            let url = format!(
83                "wss://{}.infura.io/ws/v3/{}",
84                self.network,
85                self.keys.lock().unwrap().next().unwrap()
86            );
87            Provider::connect(url.as_str()).await.unwrap()
88        }
89    }
90}