Repository: gakonst/ethers-rs
Pull request #410 (2021-08-27 18:36:34)

chore: remove cyclical dependencies
* Removes any cyclical dependencies from the code


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index f6ad107e..14644fab 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -856,11 +856,9 @@ dependencies = [
 name = "ethers-contract"
 version = "0.4.7"
 dependencies = [
- "ethers",
  "ethers-contract-abigen",
  "ethers-contract-derive",
  "ethers-core",
- "ethers-middleware",
  "ethers-providers",
  "ethers-signers",
  "futures-util",
@@ -917,7 +915,6 @@ dependencies = [
  "ecdsa",
  "elliptic-curve",
  "ethabi",
- "ethers",
  "futures-util",
  "generic-array 0.14.4",
  "glob",
@@ -940,7 +937,6 @@ name = "ethers-middleware"
 version = "0.4.8"
 dependencies = [
  "async-trait",
- "ethers",
  "ethers-contract",
  "ethers-core",
  "ethers-providers",
@@ -967,7 +963,6 @@ dependencies = [
  "async-trait",
  "auto_impl",
  "bytes",
- "ethers",
  "ethers-core",
  "futures-channel",
  "futures-core",
@@ -1004,7 +999,6 @@ dependencies = [
  "coins-ledger",
  "elliptic-curve",
  "eth-keystore",
- "ethers",
  "ethers-core",
  "futures-executor",
  "futures-util",
diff --git a/ethers-contract/Cargo.toml b/ethers-contract/Cargo.toml
index 9bd1f4a0..2c38cb64 100644
--- a/ethers-contract/Cargo.toml
+++ b/ethers-contract/Cargo.toml
@@ -24,10 +24,10 @@ futures-util = { version = "0.3.16" }
 hex = { version = "0.4.3", default-features = false, features = ["std"] }
 
 [dev-dependencies]
-ethers = { version = "0.4.0", path = ".." }
 ethers-providers = { version = "0.4.6", path = "../ethers-providers", default-features = false, features = ["ws"] }
 ethers-signers = { version = "0.4.6", path = "../ethers-signers" }
-ethers-middleware = { version = "0.4.8", path = "../ethers-middleware" }
+ethers-contract-abigen = { version = "0.4.7", path = "ethers-contract-abigen" }
+ethers-contract-derive = { version = "0.4.7", path = "ethers-contract-derive" }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
 tokio = { version = "1.5", default-features = false, features = ["macros"] }
diff --git a/ethers-contract/src/contract.rs b/ethers-contract/src/contract.rs
index a1b56d9c..d239ae45 100644
--- a/ethers-contract/src/contract.rs
+++ b/ethers-contract/src/contract.rs
@@ -65,14 +65,14 @@ use std::{fmt::Debug, marker::PhantomData, sync::Arc};
 /// interact with its methods and retrieve raw logs it has emitted.
 ///
 /// ```no_run
-/// use ethers::{
+/// use ethers_core::{
 ///     abi::Abi,
 ///     utils::Solc,
 ///     types::{Address, H256},
-///     contract::Contract,
-///     providers::{Provider, Http},
-///     signers::Wallet,
 /// };
+/// use ethers_contract::Contract;
+/// use ethers_providers::{Provider, Http};
+/// use ethers_signers::Wallet;
 /// use std::convert::TryFrom;
 ///
 /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@@ -112,7 +112,7 @@ use std::{fmt::Debug, marker::PhantomData, sync::Arc};
 /// datatypes and to have implemented `Detokenize` for it. This boilerplate code
 /// is generated for you via the [`abigen`] and [`Abigen` builder] utilities.
 ///
-/// ```no_run
+/// ```ignore
 /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
 /// use ethers_core::{abi::Abi, types::Address};
 /// use ethers_contract::{Contract, EthEvent};
diff --git a/ethers-contract/src/factory.rs b/ethers-contract/src/factory.rs
index ae818f06..8f846805 100644
--- a/ethers-contract/src/factory.rs
+++ b/ethers-contract/src/factory.rs
@@ -92,12 +92,10 @@ impl<M: Middleware> Deployer<M> {
 /// # Example
 ///
 /// ```no_run
-/// use ethers::{
-///     utils::Solc,
-///     contract::ContractFactory,
-///     providers::{Provider, Http},
-///     signers::Wallet
-/// };
+/// use ethers_core::utils::Solc;
+/// use ethers_contract::ContractFactory;
+/// use ethers_providers::{Provider, Http};
+/// use ethers_signers::Wallet;
 /// use std::convert::TryFrom;
 ///
 /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
diff --git a/ethers-contract/src/lib.rs b/ethers-contract/src/lib.rs
index 6d2c544d..ff93c8b5 100644
--- a/ethers-contract/src/lib.rs
+++ b/ethers-contract/src/lib.rs
@@ -44,11 +44,11 @@ pub mod builders {
     pub use super::factory::Deployer;
 }
 
-#[cfg(feature = "abigen")]
+#[cfg(any(test, feature = "abigen"))]
 #[cfg_attr(docsrs, doc(cfg(feature = "abigen")))]
 pub use ethers_contract_abigen::Abigen;
 
-#[cfg(feature = "abigen")]
+#[cfg(any(test, feature = "abigen"))]
 #[cfg_attr(docsrs, doc(cfg(feature = "abigen")))]
 pub use ethers_contract_derive::{abigen, EthAbiType, EthEvent};
 
diff --git a/ethers-contract/src/multicall/mod.rs b/ethers-contract/src/multicall/mod.rs
index 11d4a108..1b31252f 100644
--- a/ethers-contract/src/multicall/mod.rs
+++ b/ethers-contract/src/multicall/mod.rs
@@ -63,12 +63,12 @@ pub static ADDRESS_BOOK: Lazy<HashMap<U256, Address>> = Lazy::new(|| {
 /// # Example
 ///
 /// ```no_run
-/// use ethers::{
+/// use ethers_core::{
 ///     abi::Abi,
-///     contract::{Contract, Multicall},
-///     providers::{Middleware, Http, Provider, PendingTransaction},
 ///     types::{Address, H256, U256},
 /// };
+/// use ethers_contract::{Contract, Multicall};
+/// use ethers_providers::{Middleware, Http, Provider, PendingTransaction};
 /// use std::{convert::TryFrom, sync::Arc};
 ///
 /// # async fn bar() -> Result<(), Box<dyn std::error::Error>> {
@@ -247,7 +247,9 @@ impl<M: Middleware> Multicall<M> {
     ///
     /// ```no_run
     /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-    /// # use ethers::{abi::Abi, prelude::*};
+    /// # use ethers_core::{abi::Abi, types::{Address, H256}};
+    /// # use ethers_providers::{Provider, Http};
+    /// # use ethers_contract::{Multicall, Contract};
     /// # use std::{sync::Arc, convert::TryFrom};
     /// #
     /// # let client = Provider::<Http>::try_from("http://localhost:8545")?;
@@ -290,7 +292,9 @@ impl<M: Middleware> Multicall<M> {
     ///
     /// ```no_run
     /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-    /// # use ethers::prelude::*;
+    /// # use ethers_core::types::{U256, Address};
+    /// # use ethers_providers::{Provider, Http};
+    /// # use ethers_contract::Multicall;
     /// # use std::convert::TryFrom;
     /// #
     /// # let client = Provider::<Http>::try_from("http://localhost:8545")?;
@@ -343,7 +347,8 @@ impl<M: Middleware> Multicall<M> {
     ///
     /// ```no_run
     /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-    /// # use ethers::prelude::*;
+    /// # use ethers_providers::{Provider, Http};
+    /// # use ethers_contract::Multicall;
     /// # use std::convert::TryFrom;
     /// # let client = Provider::<Http>::try_from("http://localhost:8545")?;
     /// # let multicall = Multicall::new(client, None).await?;
diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml
index ab1350ea..19011f18 100644
--- a/ethers-core/Cargo.toml
+++ b/ethers-core/Cargo.toml
@@ -37,8 +37,6 @@ tokio = { version = "1.5", default-features = false, optional = true}
 futures-util = { version = "0.3.16", optional = true }
 
 [dev-dependencies]
-ethers = { version = "0.4.0", path = ".." }
-
 serde_json = { version = "1.0.64", default-features = false }
 bincode = { version = "1.3.3", default-features = false }
 once_cell = { version = "1.8.0" }
diff --git a/ethers-core/src/abi/human_readable.rs b/ethers-core/src/abi/human_readable.rs
index 8b0de3ee..2a08fc5b 100644
--- a/ethers-core/src/abi/human_readable.rs
+++ b/ethers-core/src/abi/human_readable.rs
@@ -21,7 +21,7 @@ impl AbiParser {
     /// # Example
     ///
     /// ```
-    ///  # use ethers::abi::AbiParser;
+    ///  # use ethers_core::abi::AbiParser;
     /// let abi = AbiParser::default().parse_str(r#"[
     ///         function setValue(string)
     ///         function getValue() external view returns (string)
@@ -42,7 +42,7 @@ impl AbiParser {
     ///
     /// # Example
     /// ```
-    /// use ethers::abi::AbiParser;
+    /// use ethers_core::abi::AbiParser;
     ///
     /// let abi = AbiParser::default().parse(&[
     ///     "function x() external view returns (uint256)",
@@ -377,7 +377,7 @@ impl Default for AbiParser {
 /// Parses a "human readable abi" string vector
 ///
 /// ```
-/// use ethers::abi::parse_abi;
+/// use ethers_core::abi::parse_abi;
 ///
 /// let abi = parse_abi(&[
 ///     "function x() external view returns (uint256)",
diff --git a/ethers-core/src/abi/struct_def.rs b/ethers-core/src/abi/struct_def.rs
index 7c2ec6b4..92d96f3f 100644
--- a/ethers-core/src/abi/struct_def.rs
+++ b/ethers-core/src/abi/struct_def.rs
@@ -225,7 +225,7 @@ impl SolStruct {
     /// # Example
     ///
     /// ```
-    /// # use ethers::abi::SolStruct;
+    /// # use ethers_core::abi::SolStruct;
     /// let s = SolStruct::parse("struct MyStruct { uint x; uint y;}").unwrap();
     /// ```
     pub fn parse(s: &str) -> Result<Self> {
diff --git a/ethers-core/src/lib.rs b/ethers-core/src/lib.rs
index 3a4d3ff7..7a947887 100644
--- a/ethers-core/src/lib.rs
+++ b/ethers-core/src/lib.rs
@@ -12,7 +12,7 @@
 //! `"\x19Ethereum Signed Message:\n" + message.length`, and then
 //! signing the hash of the result.
 //!
-//! ```rust
+//! ```rust,ignore
 //! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
 //! use ethers::signers::{Signer, LocalWallet};
 //!
diff --git a/ethers-core/src/types/log.rs b/ethers-core/src/types/log.rs
index 06705d16..2f5e3748 100644
--- a/ethers-core/src/types/log.rs
+++ b/ethers-core/src/types/log.rs
@@ -254,7 +254,7 @@ impl Filter {
     /// Match only a specific block
     ///
     /// ```rust
-    /// # use ethers::types::Filter;
+    /// # use ethers_core::types::Filter;
     /// # fn main() {
     /// let filter = Filter::new().select(69u64);
     /// # }
@@ -264,7 +264,7 @@ impl Filter {
     /// Match the latest block only
     ///
     /// ```rust
-    /// # use ethers::types::{Filter, BlockNumber};
+    /// # use ethers_core::types::{Filter, BlockNumber};
     /// # fn main() {
     /// let filter = Filter::new().select(BlockNumber::Latest);
     /// # }
@@ -273,7 +273,7 @@ impl Filter {
     /// Match a block by its hash
     ///
     /// ```rust
-    /// # use ethers::types::{Filter, H256};
+    /// # use ethers_core::types::{Filter, H256};
     /// # fn main() {
     /// let filter = Filter::new().select(H256::zero());
     /// # }
@@ -283,7 +283,7 @@ impl Filter {
     /// Match a range of blocks
     ///
     /// ```rust
-    /// # use ethers::types::{Filter, H256};
+    /// # use ethers_core::types::{Filter, H256};
     /// # fn main() {
     /// let filter = Filter::new().select(0u64..100u64);
     /// # }
@@ -292,7 +292,7 @@ impl Filter {
     /// Match all blocks in range `(1337..BlockNumber::Latest)`
     ///
     /// ```rust
-    /// # use ethers::types::{Filter, H256};
+    /// # use ethers_core::types::{Filter, H256};
     /// # fn main() {
     /// let filter = Filter::new().select(1337u64..);
     /// # }
@@ -301,7 +301,7 @@ impl Filter {
     /// Match all blocks in range `(BlockNumber::Earliest..1337)`
     ///
     /// ```rust
-    /// # use ethers::types::{Filter, H256};
+    /// # use ethers_core::types::{Filter, H256};
     /// # fn main() {
     /// let filter = Filter::new().select(..1337u64);
     /// # }
diff --git a/ethers-core/src/utils/ganache.rs b/ethers-core/src/utils/ganache.rs
index e1df6e80..09d48e07 100644
--- a/ethers-core/src/utils/ganache.rs
+++ b/ethers-core/src/utils/ganache.rs
@@ -64,7 +64,7 @@ impl Drop for GanacheInstance {
 /// # Example
 ///
 /// ```no_run
-/// use ethers::utils::Ganache;
+/// use ethers_core::utils::Ganache;
 ///
 /// let port = 8545u16;
 /// let url = format!("http://localhost:{}", port).to_string();
diff --git a/ethers-core/src/utils/geth.rs b/ethers-core/src/utils/geth.rs
index 8787e38a..e938c120 100644
--- a/ethers-core/src/utils/geth.rs
+++ b/ethers-core/src/utils/geth.rs
@@ -60,7 +60,7 @@ impl Drop for GethInstance {
 /// # Example
 ///
 /// ```no_run
-/// use ethers::utils::Geth;
+/// use ethers_core::utils::Geth;
 ///
 /// let port = 8545u16;
 /// let url = format!("http://localhost:{}", port).to_string();
diff --git a/ethers-core/src/utils/mod.rs b/ethers-core/src/utils/mod.rs
index 5957d074..864e6e2f 100644
--- a/ethers-core/src/utils/mod.rs
+++ b/ethers-core/src/utils/mod.rs
@@ -79,7 +79,7 @@ pub fn format_units<T: Into<U256>, K: Into<Units>>(amount: T, units: K) -> U256
 /// Converts the input to a U256 and converts from Ether to Wei.
 ///
 /// ```
-/// use ethers::{types::U256, utils::{parse_ether, WEI_IN_ETHER}};
+/// use ethers_core::{types::U256, utils::{parse_ether, WEI_IN_ETHER}};
 ///
 /// let eth = U256::from(WEI_IN_ETHER);
 /// assert_eq!(eth, parse_ether(1u8).unwrap());
diff --git a/ethers-core/src/utils/solc.rs b/ethers-core/src/utils/solc.rs
index 2ca44395..175c295d 100644
--- a/ethers-core/src/utils/solc.rs
+++ b/ethers-core/src/utils/solc.rs
@@ -40,7 +40,7 @@ pub struct CompiledContract {
 /// # Examples
 ///
 /// ```no_run
-/// use ethers::utils::Solc;
+/// use ethers_core::utils::Solc;
 ///
 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
 /// // Give it a glob
diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml
index f8ff8c32..7c0cf7ea 100644
--- a/ethers-middleware/Cargo.toml
+++ b/ethers-middleware/Cargo.toml
@@ -38,12 +38,12 @@ instant = {version = "0.1.10", features = ["now"] }
 tokio = { version = "1.5" }
 
 [dev-dependencies]
-ethers = { version = "0.4.0", path = ".." }
 hex = { version = "0.4.3", default-features = false, features = ["std"] }
 rand = { version = "0.8.4", default-features = false }
+ethers-providers = { version = "0.4.6", path = "../ethers-providers", default-features = false, features = ["ws", "rustls"] }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
 tokio = { version = "1.5", default-features = false, features = ["rt", "macros", "time"] }
 
 [features]
-celo = ["ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo"]
+celo = ["ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo", "ethers-contract/celo"]
diff --git a/ethers-middleware/src/gas_escalator/mod.rs b/ethers-middleware/src/gas_escalator/mod.rs
index 1dad83ad..77de8509 100644
--- a/ethers-middleware/src/gas_escalator/mod.rs
+++ b/ethers-middleware/src/gas_escalator/mod.rs
@@ -44,12 +44,10 @@ pub enum Frequency {
 /// stuck in the memory pool.
 ///
 /// ```no_run
-/// use ethers::{
-///     providers::{Provider, Http},
-///     middleware::{
-///         gas_escalator::{GeometricGasPrice, Frequency, GasEscalatorMiddleware},
-///         gas_oracle::{GasNow, GasCategory, GasOracleMiddleware},
-///     },
+/// use ethers_providers::{Provider, Http};
+/// use ethers_middleware::{
+///     gas_escalator::{GeometricGasPrice, Frequency, GasEscalatorMiddleware},
+///     gas_oracle::{GasNow, GasCategory, GasOracleMiddleware},
 /// };
 /// use std::{convert::TryFrom, time::Duration, sync::Arc};
 ///
diff --git a/ethers-middleware/src/gas_oracle/mod.rs b/ethers-middleware/src/gas_oracle/mod.rs
index 99d8a99b..82a68906 100644
--- a/ethers-middleware/src/gas_oracle/mod.rs
+++ b/ethers-middleware/src/gas_oracle/mod.rs
@@ -52,7 +52,7 @@ pub enum GasOracleError {
 /// # Example
 ///
 /// ```no_run
-/// use ethers::middleware::{
+/// use ethers_middleware::{
 ///     gas_oracle::{EthGasStation, Etherscan, GasCategory, GasOracle},
 /// };
 ///
@@ -73,7 +73,7 @@ pub trait GasOracle: Send + Sync + std::fmt::Debug {
     /// # Example
     ///
     /// ```
-    /// use ethers::middleware::{
+    /// use ethers_middleware::{
     ///     gas_oracle::{Etherchain, GasCategory, GasOracle},
     /// };
     ///
diff --git a/ethers-middleware/src/lib.rs b/ethers-middleware/src/lib.rs
index 7d4acc49..4e2bfbf6 100644
--- a/ethers-middleware/src/lib.rs
+++ b/ethers-middleware/src/lib.rs
@@ -19,17 +19,15 @@
 //! ## Example of a middleware stack
 //!
 //! ```no_run
-//! use ethers::{
-//!     providers::{Provider, Http},
-//!     signers::{LocalWallet, Signer},
-//!     middleware::{
-//!         gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
-//!         gas_oracle::{GasOracleMiddleware, GasNow, GasCategory},
-//!         signer::SignerMiddleware,
-//!         nonce_manager::NonceManagerMiddleware,
-//!     },
-//!     core::rand,
+//! use ethers_providers::{Provider, Http};
+//! use ethers_signers::{LocalWallet, Signer};
+//! use ethers_middleware::{
+//!     gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
+//!     gas_oracle::{GasOracleMiddleware, GasNow, GasCategory},
+//!     signer::SignerMiddleware,
+//!     nonce_manager::NonceManagerMiddleware,
 //! };
+//! use ethers_core::rand;
 //! use std::convert::TryFrom;
 //!
 //! // Start the stack
diff --git a/ethers-middleware/src/signer.rs b/ethers-middleware/src/signer.rs
index 437ddc89..b395afa5 100644
--- a/ethers-middleware/src/signer.rs
+++ b/ethers-middleware/src/signer.rs
@@ -14,12 +14,10 @@ use thiserror::Error;
 /// # Example
 ///
 /// ```no_run
-/// use ethers::{
-///     providers::{Middleware, Provider, Http},
-///     signers::LocalWallet,
-///     middleware::SignerMiddleware,
-///     types::{Address, TransactionRequest},
-/// };
+/// use ethers_providers::{Middleware, Provider, Http};
+/// use ethers_signers::LocalWallet;
+/// use ethers_middleware::SignerMiddleware;
+/// use ethers_core::types::{Address, TransactionRequest};
 /// use std::convert::TryFrom;
 ///
 /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@@ -250,11 +248,12 @@ where
 #[cfg(all(test, not(feature = "celo"), not(target_arch = "wasm32")))]
 mod tests {
     use super::*;
-    use ethers::{providers::Provider, signers::LocalWallet};
     use ethers_core::{
         types::TransactionRequest,
         utils::{self, keccak256, Ganache},
     };
+    use ethers_providers::Provider;
+    use ethers_signers::LocalWallet;
     use std::convert::TryFrom;
 
     #[tokio::test]
diff --git a/ethers-middleware/src/transformer/ds_proxy/mod.rs b/ethers-middleware/src/transformer/ds_proxy/mod.rs
index 3e1dfa10..76bd35e0 100644
--- a/ethers-middleware/src/transformer/ds_proxy/mod.rs
+++ b/ethers-middleware/src/transformer/ds_proxy/mod.rs
@@ -22,10 +22,10 @@ const DS_PROXY_EXECUTE_CODE: &str =
 /// # Example
 ///
 /// ```no_run
-/// use ethers::{
-///     middleware::transformer::DsProxy,
-///     prelude::*,
-/// };
+/// use ethers_middleware::{SignerMiddleware, transformer::DsProxy};
+/// use ethers_signers::LocalWallet;
+/// use ethers_providers::{Provider, Http};
+/// use ethers_core::types::{Address, Bytes};
 /// use std::{convert::TryFrom, sync::Arc};
 ///
 /// type HttpWallet = SignerMiddleware<Provider<Http>, LocalWallet>;
diff --git a/ethers-providers/Cargo.toml b/ethers-providers/Cargo.toml
index 9b644e1f..de60328f 100644
--- a/ethers-providers/Cargo.toml
+++ b/ethers-providers/Cargo.toml
@@ -53,9 +53,6 @@ wasm-timer = "0.2"
 # this is currently necessary for `wasm-timer::Delay` to work
 parking_lot = { version = "0.11", features = ["wasm-bindgen"] }
 
-[dev-dependencies]
-ethers = { version = "0.4.0", path = ".." }
-
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
 tokio = { version = "1.5", default-features = false, features = ["rt", "macros"] }
 tempfile = "3.2.0"
diff --git a/ethers-providers/src/lib.rs b/ethers-providers/src/lib.rs
index 2369b9bb..c08b8bd2 100644
--- a/ethers-providers/src/lib.rs
+++ b/ethers-providers/src/lib.rs
@@ -12,7 +12,7 @@
 //! # Examples
 //!
 //! ```no_run
-//! use ethers::providers::{Provider, Http, Middleware};
+//! use ethers_providers::{Provider, Http, Middleware};
 //! use std::convert::TryFrom;
 //!
 //! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@@ -35,7 +35,7 @@
 //!
 //! ```
 //! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-//! # use ethers::providers::Ws;
+//! # use ethers_providers::Ws;
 //! let ws = Ws::connect("ws://localhost:8545").await?;
 //! # Ok(())
 //! # }
@@ -47,7 +47,7 @@
 //! to addresses (and vice versa). The default ENS address is [mainnet](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) and can be overriden by calling the [`ens`](method@crate::Provider::ens) method on the provider.
 //!
 //! ```no_run
-//! # use ethers::providers::{Provider, Http, Middleware};
+//! # use ethers_providers::{Provider, Http, Middleware};
 //! # use std::convert::TryFrom;
 //! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
 //! # let provider = Provider::<Http>::try_from(
@@ -137,7 +137,8 @@ where
 /// 3. implementing any of the methods you want to override
 ///
 /// ```rust
-/// use ethers::{providers::{Middleware, FromErr}, types::{U64, TransactionRequest, U256, transaction::eip2718::TypedTransaction}};
+/// use ethers_providers::{Middleware, FromErr};
+/// use ethers_core::types::{U64, TransactionRequest, U256, transaction::eip2718::TypedTransaction};
 /// use thiserror::Error;
 /// use async_trait::async_trait;
 ///
diff --git a/ethers-providers/src/provider.rs b/ethers-providers/src/provider.rs
index 446c41a1..834ed0f5 100644
--- a/ethers-providers/src/provider.rs
+++ b/ethers-providers/src/provider.rs
@@ -38,7 +38,7 @@ use tracing_futures::Instrument;
 ///
 /// ```no_run
 /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-/// use ethers::providers::{Middleware, Provider, Http};
+/// use ethers_providers::{Middleware, Provider, Http};
 /// use std::convert::TryFrom;
 ///
 /// let provider = Provider::<Http>::try_from(
@@ -905,7 +905,8 @@ impl Provider<MockProvider> {
     ///
     /// ```
     /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-    /// use ethers::{types::U64, providers::{Middleware, Provider}};
+    /// use ethers_core::types::U64;
+    /// use ethers_providers::{Middleware, Provider};
     /// // Instantiate the provider
     /// let (provider, mock) = Provider::mocked();
     /// // Push the mock response
diff --git a/ethers-providers/src/transports/http.rs b/ethers-providers/src/transports/http.rs
index 6e915681..82b54a70 100644
--- a/ethers-providers/src/transports/http.rs
+++ b/ethers-providers/src/transports/http.rs
@@ -18,7 +18,8 @@ use super::common::{JsonRpcError, Request, Response};
 /// # Example
 ///
 /// ```no_run
-/// use ethers::{types::U64, providers::{JsonRpcClient, Http}};
+/// use ethers_core::types::U64;
+/// use ethers_providers::{JsonRpcClient, Http};
 /// use std::str::FromStr;
 ///
 /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@@ -95,7 +96,7 @@ impl Provider {
     /// # Example
     ///
     /// ```
-    /// use ethers::providers::Http;
+    /// use ethers_providers::Http;
     /// use url::Url;
     ///
     /// let url = Url::parse("http://localhost:8545").unwrap();
diff --git a/ethers-providers/src/transports/ipc.rs b/ethers-providers/src/transports/ipc.rs
index d2bb5df0..a61bb862 100644
--- a/ethers-providers/src/transports/ipc.rs
+++ b/ethers-providers/src/transports/ipc.rs
@@ -338,8 +338,7 @@ impl From<IpcError> for ProviderError {
 #[cfg(not(feature = "celo"))]
 mod test {
     use super::*;
-    use ethers::utils::Geth;
-    use ethers_core::types::{Block, TxHash, U256};
+    use ethers_core::{utils::Geth, types::{Block, TxHash, U256}};
     use tempfile::NamedTempFile;
 
     #[tokio::test]
diff --git a/ethers-providers/src/transports/mod.rs b/ethers-providers/src/transports/mod.rs
index 535dd413..c8171669 100644
--- a/ethers-providers/src/transports/mod.rs
+++ b/ethers-providers/src/transports/mod.rs
@@ -1,5 +1,7 @@
 mod common;
 
+// only used with WS
+#[cfg(feature = "ws")]
 macro_rules! if_wasm {
     ($($item:item)*) => {$(
         #[cfg(target_arch = "wasm32")]
diff --git a/ethers-providers/src/transports/ws.rs b/ethers-providers/src/transports/ws.rs
index d9c9cfa7..f282a0d4 100644
--- a/ethers-providers/src/transports/ws.rs
+++ b/ethers-providers/src/transports/ws.rs
@@ -91,7 +91,7 @@ enum Incoming {
 ///
 /// ```no_run
 /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-/// use ethers::providers::Ws;
+/// use ethers_providers::Ws;
 ///
 /// let ws = Ws::connect("wss://localhost:8545").await?;
 /// # Ok(())
diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml
index a9c9e022..2cc37d0a 100644
--- a/ethers-signers/Cargo.toml
+++ b/ethers-signers/Cargo.toml
@@ -39,13 +39,12 @@ spki = { version = "0.4.0", optional = true }
 eth-keystore = { version = "0.3.0" }
 
 [dev-dependencies]
-ethers = { version = "0.4.0", path = ".." }
 tracing-subscriber = "0.2.20"
 yubihsm = { version = "0.39.0", features = ["secp256k1", "usb", "mockhsm"] }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
 yubihsm = { version = "0.39.0", features = ["secp256k1", "usb", "mockhsm"] }
-tokio = { version = "1.5", default-features = false, features = ["macros"] }
+tokio = { version = "1.5", default-features = false, features = ["macros", "rt"] }
 tempfile = "3.2.0"
 
 [features]
diff --git a/ethers-signers/src/ledger/app.rs b/ethers-signers/src/ledger/app.rs
index 0a02294f..dff7951e 100644
--- a/ethers-signers/src/ledger/app.rs
+++ b/ethers-signers/src/ledger/app.rs
@@ -35,7 +35,7 @@ impl LedgerEthereum {
     ///
     /// ```
     /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
-    /// use ethers::signers::{Ledger, HDPath};
+    /// use ethers_signers::{Ledger, HDPath};
     ///
     /// let ledger = Ledger::new(HDPath::LedgerLive(0), 1).await?;
     /// # Ok(())
@@ -200,7 +200,7 @@ impl LedgerEthereum {
 mod tests {
     use super::*;
     use crate::Signer;
-    use ethers::prelude::*;
+    use ethers_core::types::{Address, TransactionRequest};
     use std::str::FromStr;
 
     #[tokio::test]
diff --git a/ethers-signers/src/lib.rs b/ethers-signers/src/lib.rs
index df67ee14..3af7a2e4 100644
--- a/ethers-signers/src/lib.rs
+++ b/ethers-signers/src/lib.rs
@@ -13,10 +13,9 @@
 //! - [AWS KMS](crate::AwsSigner)
 //!
 //! ```no_run
-//! # use ethers::{
-//! #     signers::{LocalWallet, Signer},
-//! #     core::{k256::ecdsa::SigningKey, types::TransactionRequest},
-//! # };
+//! # use ethers_signers::{LocalWallet, Signer};
+//! # use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest};
+//!
 //! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
 //! // instantiate the wallet
 //! let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"


Test patch:
diff --git a/ethers-contract/tests/abigen.rs b/ethers-contract/tests/abigen.rs
index fdf6cd8a..cb577ce4 100644
--- a/ethers-contract/tests/abigen.rs
+++ b/ethers-contract/tests/abigen.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "abigen")]
 //! Test cases to validate the `abigen!` macro
 use ethers_contract::{abigen, EthEvent};
 use ethers_core::abi::Tokenizable;
diff --git a/ethers-contract/tests/common/derive.rs b/ethers-contract/tests/common/derive.rs
index 98bead20..b9d04aa6 100644
--- a/ethers-contract/tests/common/derive.rs
+++ b/ethers-contract/tests/common/derive.rs
@@ -1,7 +1,8 @@
-use ethers::core::types::{H160, H256, I256, U128, U256};
-use ethers_contract::{abigen, EthAbiType, EthEvent, EthLogDecode};
+use ethers_contract::EthLogDecode;
+use ethers_contract::{abigen, EthAbiType, EthEvent};
 use ethers_core::abi::{RawLog, Tokenizable};
 use ethers_core::types::Address;
+use ethers_core::types::{H160, H256, I256, U128, U256};
 
 #[derive(Debug, Clone, PartialEq, EthAbiType)]
 struct ValueChanged {
diff --git a/ethers-contract/tests/common/mod.rs b/ethers-contract/tests/common/mod.rs
index 256802b1..91c4acec 100644
--- a/ethers-contract/tests/common/mod.rs
+++ b/ethers-contract/tests/common/mod.rs
@@ -1,19 +1,23 @@
 #![cfg(not(target_arch = "wasm32"))]
+
+#[cfg(feature = "abigen")]
+use ethers_core::types::Address;
+
+#[cfg(feature = "abigen")]
+use ethers_contract::EthEvent;
+
+#[cfg(feature = "abigen")]
 mod derive;
-use ethers_core::{
-    abi::Abi,
-    types::{Address, Bytes},
-};
 
-use ethers_contract::{Contract, ContractFactory, EthEvent};
+use ethers_contract::{Contract, ContractFactory};
 use ethers_core::utils::{GanacheInstance, Solc};
-use ethers_middleware::signer::SignerMiddleware;
+use ethers_core::{abi::Abi, types::Bytes};
 use ethers_providers::{Http, Middleware, Provider};
-use ethers_signers::{LocalWallet, Signer};
 use std::{convert::TryFrom, sync::Arc, time::Duration};
 
 // Note: The `EthEvent` derive macro implements the necessary conversion between `Tokens` and
 // the struct
+#[cfg(feature = "abigen")]
 #[derive(Clone, Debug, EthEvent)]
 pub struct ValueChanged {
     #[ethevent(indexed)]
@@ -33,16 +37,14 @@ pub fn compile_contract(name: &str, filename: &str) -> (Abi, Bytes) {
     (contract.abi.clone(), contract.bytecode.clone())
 }
 
-type HttpWallet = SignerMiddleware<Provider<Http>, LocalWallet>;
-
 /// connects the private key to http://localhost:8545
-pub fn connect(ganache: &GanacheInstance, idx: usize) -> Arc<HttpWallet> {
+pub fn connect(ganache: &GanacheInstance, idx: usize) -> Arc<Provider<Http>> {
+    let sender = ganache.addresses()[idx];
     let provider = Provider::<Http>::try_from(ganache.endpoint())
         .unwrap()
-        .interval(Duration::from_millis(10u64));
-    let wallet: LocalWallet = ganache.keys()[idx].clone().into();
-    let wallet = wallet.with_chain_id(1u64);
-    Arc::new(SignerMiddleware::new(provider, wallet))
+        .interval(Duration::from_millis(10u64))
+        .with_sender(sender);
+    Arc::new(provider)
 }
 
 /// Launches a ganache instance and deploys the SimpleStorage contract
diff --git a/ethers-contract/tests/contract.rs b/ethers-contract/tests/contract.rs
index 7475aad3..39a4f45c 100644
--- a/ethers-contract/tests/contract.rs
+++ b/ethers-contract/tests/contract.rs
@@ -1,8 +1,5 @@
-#![cfg(not(target_arch = "wasm32"))]
-use ethers::{
-    contract::ContractFactory,
-    types::{Filter, ValueOrArray, H256},
-};
+use ethers_contract::ContractFactory;
+use ethers_core::types::{Filter, ValueOrArray, H256};
 
 mod common;
 pub use common::*;
@@ -10,12 +7,12 @@ pub use common::*;
 #[cfg(not(feature = "celo"))]
 mod eth_tests {
     use super::*;
-    use ethers::{
-        contract::{LogMeta, Multicall},
-        providers::{Http, Middleware, PendingTransaction, Provider, StreamExt},
+    use ethers_contract::{LogMeta, Multicall};
+    use ethers_core::{
         types::{Address, BlockId, U256},
         utils::Ganache,
     };
+    use ethers_providers::{Http, Middleware, PendingTransaction, Provider, StreamExt};
     use std::{convert::TryFrom, sync::Arc};
 
     #[tokio::test]
@@ -27,6 +24,8 @@ mod eth_tests {
 
         // Instantiate the clients. We assume that clients consume the provider and the wallet
         // (which makes sense), so for multi-client tests, you must clone the provider.
+        let addrs = ganache.addresses().to_vec();
+        let addr2 = addrs[1];
         let client = connect(&ganache, 0);
         let client2 = connect(&ganache, 1);
 
@@ -62,7 +61,7 @@ mod eth_tests {
         let pending_tx = contract_call.send().await.unwrap();
         let tx = client.get_transaction(*pending_tx).await.unwrap().unwrap();
         let tx_receipt = pending_tx.await.unwrap().unwrap();
-        assert_eq!(last_sender.clone().call().await.unwrap(), client2.address());
+        assert_eq!(last_sender.clone().call().await.unwrap(), addr2);
         assert_eq!(get_value.clone().call().await.unwrap(), "hi");
         assert_eq!(tx.input, calldata);
         assert_eq!(tx_receipt.gas_used.unwrap(), gas_estimate);
@@ -99,10 +98,12 @@ mod eth_tests {
     }
 
     #[tokio::test]
+    #[cfg(feature = "abigen")]
     async fn get_past_events() {
         let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
         let ganache = Ganache::new().spawn();
         let client = connect(&ganache, 0);
+        let address = client.get_accounts().await.unwrap()[0];
         let contract = deploy(client.clone(), abi, bytecode).await;
 
         // make a call with `client`
@@ -117,7 +118,7 @@ mod eth_tests {
         let logs: Vec<ValueChanged> = contract
             .event()
             .from_block(0u64)
-            .topic1(client.address()) // Corresponds to the first indexed parameter
+            .topic1(address) // Corresponds to the first indexed parameter
             .query()
             .await
             .unwrap();
@@ -130,7 +131,7 @@ mod eth_tests {
         let logs: Vec<ValueChanged> = contract
             .event()
             .at_block_hash(hash)
-            .topic1(client.address()) // Corresponds to the first indexed parameter
+            .topic1(address) // Corresponds to the first indexed parameter
             .query()
             .await
             .unwrap();
@@ -139,17 +140,19 @@ mod eth_tests {
     }
 
     #[tokio::test]
+    #[cfg(feature = "abigen")]
     async fn get_events_with_meta() {
         let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
         let ganache = Ganache::new().spawn();
         let client = connect(&ganache, 0);
+        let address = ganache.addresses()[0];
         let contract = deploy(client.clone(), abi, bytecode).await;
 
         // and we can fetch the events
         let logs: Vec<(ValueChanged, LogMeta)> = contract
             .event()
             .from_block(0u64)
-            .topic1(client.address()) // Corresponds to the first indexed parameter
+            .topic1(address) // Corresponds to the first indexed parameter
             .query_with_meta()
             .await
             .unwrap();
@@ -288,6 +291,7 @@ mod eth_tests {
     }
 
     #[tokio::test]
+    #[cfg(feature = "abigen")]
     async fn watch_events() {
         let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
         let ganache = Ganache::new().spawn();
@@ -436,6 +440,9 @@ mod eth_tests {
         // `client2` is used to deploy the first SimpleStorage contract
         // `client3` is used to deploy the second SimpleStorage contract
         // `client4` is used to make the aggregate call
+        let addrs = ganache.addresses().to_vec();
+        let addr2 = addrs[1];
+        let addr3 = addrs[2];
         let client = connect(&ganache, 0);
         let client2 = connect(&ganache, 1);
         let client3 = connect(&ganache, 2);
@@ -516,9 +523,9 @@ mod eth_tests {
 
         assert_eq!(return_data.0, "reset first");
         assert_eq!((return_data.1).0, "reset second");
-        assert_eq!((return_data.1).1, client3.address());
-        assert_eq!(return_data.2, client2.address());
-        assert_eq!(return_data.3, client3.address());
+        assert_eq!((return_data.1).1, addr3);
+        assert_eq!(return_data.2, addr2);
+        assert_eq!(return_data.3, addr3);
 
         // construct broadcast transactions that will be batched and broadcast via Multicall
         let broadcast = simple_contract
@@ -574,68 +581,3 @@ mod eth_tests {
         assert_eq!(balances.2, U256::from(100000000000000000000u128));
     }
 }
-
-#[cfg(feature = "celo")]
-mod celo_tests {
-    use super::*;
-    use ethers::{
-        middleware::signer::SignerMiddleware,
-        providers::{Http, Middleware, Provider},
-        signers::{LocalWallet, Signer},
-        types::BlockNumber,
-    };
-    use std::{convert::TryFrom, sync::Arc, time::Duration};
-
-    #[tokio::test]
-    async fn deploy_and_call_contract() {
-        let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
-
-        // Celo testnet
-        let provider = Provider::<Http>::try_from("https://alfajores-forno.celo-testnet.org")
-            .unwrap()
-            .interval(Duration::from_millis(6000));
-        let chain_id = provider.get_chainid().await.unwrap().as_u64();
-
-        // Funded with https://celo.org/developers/faucet
-        let wallet = "d652abb81e8c686edba621a895531b1f291289b63b5ef09a94f686a5ecdd5db1"
-            .parse::<LocalWallet>()
-            .unwrap()
-            .with_chain_id(chain_id);
-
-        let client = SignerMiddleware::new(provider, wallet);
-        let client = Arc::new(client);
-
-        let factory = ContractFactory::new(abi, bytecode, client);
-        let deployer = factory
-            .deploy("initial value".to_string())
-            .unwrap()
-            .legacy();
-        let contract = deployer.block(BlockNumber::Pending).send().await.unwrap();
-
-        let value: String = contract
-            .method("getValue", ())
-            .unwrap()
-            .call()
-            .await
-            .unwrap();
-        assert_eq!(value, "initial value");
-
-        // make a state mutating transaction
-        // gas estimation costs are sometimes under-reported on celo,
-        // so we manually set it to avoid failures
-        let call = contract
-            .method::<_, H256>("setValue", "hi".to_owned())
-            .unwrap()
-            .gas(100000);
-        let pending_tx = call.send().await.unwrap();
-        let _receipt = pending_tx.await.unwrap();
-
-        let value: String = contract
-            .method("getValue", ())
-            .unwrap()
-            .call()
-            .await
-            .unwrap();
-        assert_eq!(value, "hi");
-    }
-}
diff --git a/ethers-middleware/tests/nonce_manager.rs b/ethers-middleware/tests/nonce_manager.rs
index 98be6f69..6472647e 100644
--- a/ethers-middleware/tests/nonce_manager.rs
+++ b/ethers-middleware/tests/nonce_manager.rs
@@ -15,7 +15,7 @@ async fn nonce_manager() {
             .interval(Duration::from_millis(2000u64));
     let chain_id = provider.get_chainid().await.unwrap().as_u64();
 
-    let wallet = "59c37cb6b16fa2de30675f034c8008f890f4b2696c729d6267946d29736d73e4"
+    let wallet = "fa4a1a79e869a96fcb42727f75e3232d6865a82ea675bb95de967a7fe6a773b2"
         .parse::<LocalWallet>()
         .unwrap()
         .with_chain_id(chain_id);
diff --git a/ethers-middleware/tests/signer.rs b/ethers-middleware/tests/signer.rs
index 48671ab9..3efea144 100644
--- a/ethers-middleware/tests/signer.rs
+++ b/ethers-middleware/tests/signer.rs
@@ -1,4 +1,3 @@
-#![cfg(not(target_arch = "wasm32"))]
 use ethers_providers::{Http, Middleware, Provider};
 
 use ethers_core::types::TransactionRequest;
@@ -44,6 +43,106 @@ async fn send_eth() {
     assert!(balance_before > balance_after);
 }
 
+#[tokio::test]
+#[cfg(not(feature = "celo"))]
+async fn pending_txs_with_confirmations_testnet() {
+    let provider =
+        Provider::<Http>::try_from("https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
+            .unwrap()
+            .interval(Duration::from_millis(3000));
+    let chain_id = provider.get_chainid().await.unwrap();
+    let wallet = "59c37cb6b16fa2de30675f034c8008f890f4b2696c729d6267946d29736d73e4"
+        .parse::<LocalWallet>()
+        .unwrap()
+        .with_chain_id(chain_id.as_u64());
+    let address = wallet.address();
+    let provider = SignerMiddleware::new(provider, wallet);
+    generic_pending_txs_test(provider, address).await;
+}
+
+#[cfg(not(feature = "celo"))]
+use ethers_core::types::{
+    transaction::eip2718::TypedTransaction, Address, Eip1559TransactionRequest,
+};
+
+// different keys to avoid nonce errors
+#[tokio::test]
+#[cfg(not(feature = "celo"))]
+async fn websocket_pending_txs_with_confirmations_testnet() {
+    let provider =
+        Provider::connect("wss://rinkeby.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27")
+            .await
+            .unwrap()
+            .interval(Duration::from_millis(3000));
+    let chain_id = provider.get_chainid().await.unwrap();
+    let wallet = "ff7f80c6e9941865266ed1f481263d780169f1d98269c51167d20c630a5fdc8a"
+        .parse::<LocalWallet>()
+        .unwrap()
+        .with_chain_id(chain_id.as_u64());
+    let address = wallet.address();
+    let provider = SignerMiddleware::new(provider, wallet);
+    generic_pending_txs_test(provider, address).await;
+}
+
+#[cfg(not(feature = "celo"))]
+async fn generic_pending_txs_test<M: Middleware>(provider: M, who: Address) {
+    let tx = TransactionRequest::new().to(who).from(who);
+    let pending_tx = provider.send_transaction(tx, None).await.unwrap();
+    let tx_hash = *pending_tx;
+    let receipt = pending_tx.confirmations(3).await.unwrap().unwrap();
+    // got the correct receipt
+    assert_eq!(receipt.transaction_hash, tx_hash);
+}
+
+#[tokio::test]
+#[cfg(not(feature = "celo"))]
+async fn typed_txs() {
+    let provider =
+        Provider::<Http>::try_from("https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
+            .unwrap();
+
+    let chain_id = provider.get_chainid().await.unwrap();
+    let wallet = "87203087aed9246e0b2417e248752a1a0df4fdaf65085c11a2b48087ba036b41"
+        .parse::<LocalWallet>()
+        .unwrap()
+        .with_chain_id(chain_id.as_u64());
+    let address = wallet.address();
+    let provider = SignerMiddleware::new(provider, wallet);
+
+    async fn check_tx<M: Middleware>(provider: &M, tx: TypedTransaction, expected: u64) {
+        let receipt = provider
+            .send_transaction(tx, None)
+            .await
+            .unwrap()
+            .await
+            .unwrap()
+            .unwrap();
+        let tx = provider
+            .get_transaction(receipt.transaction_hash)
+            .await
+            .unwrap()
+            .unwrap();
+        assert_eq!(receipt.transaction_type, Some(expected.into()));
+        assert_eq!(tx.transaction_type, Some(expected.into()));
+    }
+
+    let tx: TypedTransaction = TransactionRequest::new().from(address).to(address).into();
+    check_tx(&provider, tx, 0).await;
+
+    let tx: TypedTransaction = TransactionRequest::new()
+        .from(address)
+        .to(address)
+        .with_access_list(vec![])
+        .into();
+    check_tx(&provider, tx, 1).await;
+
+    let tx: TypedTransaction = Eip1559TransactionRequest::new()
+        .from(address)
+        .to(address)
+        .into();
+    check_tx(&provider, tx, 2).await;
+}
+
 #[tokio::test]
 #[cfg(feature = "celo")]
 async fn test_send_transaction() {
@@ -144,3 +243,60 @@ async fn send_transaction_handles_tx_from_field() {
 
     assert_eq!(sent_tx.from, other.address());
 }
+
+#[tokio::test]
+#[cfg(feature = "celo")]
+async fn deploy_and_call_contract() {
+    use ethers_contract::ContractFactory;
+    use ethers_core::{
+        abi::Abi,
+        types::{BlockNumber, Bytes, H256, U256},
+        utils::Solc,
+    };
+    use std::sync::Arc;
+
+    fn compile_contract(name: &str, filename: &str) -> (Abi, Bytes) {
+        let compiled = Solc::new(&format!("./tests/solidity-contracts/{}", filename))
+            .build()
+            .unwrap();
+        let contract = compiled.get(name).expect("could not find contract");
+        (contract.abi.clone(), contract.bytecode.clone())
+    }
+
+    let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
+
+    // Celo testnet
+    let provider = Provider::<Http>::try_from("https://alfajores-forno.celo-testnet.org")
+        .unwrap()
+        .interval(Duration::from_millis(6000));
+    let chain_id = provider.get_chainid().await.unwrap().as_u64();
+
+    // Funded with https://celo.org/developers/faucet
+    let wallet = "58ea5643a78c36926ad5128a6b0d8dfcc7fc705788a993b1c724be3469bc9697"
+        .parse::<LocalWallet>()
+        .unwrap()
+        .with_chain_id(chain_id);
+
+    let client = SignerMiddleware::new(provider, wallet);
+    let client = Arc::new(client);
+
+    let factory = ContractFactory::new(abi, bytecode, client);
+    let deployer = factory.deploy(()).unwrap().legacy();
+    let contract = deployer.block(BlockNumber::Pending).send().await.unwrap();
+
+    let value: U256 = contract.method("value", ()).unwrap().call().await.unwrap();
+    assert_eq!(value, 0.into());
+
+    // make a state mutating transaction
+    // gas estimation costs are sometimes under-reported on celo,
+    // so we manually set it to avoid failures
+    let call = contract
+        .method::<_, H256>("setValue", U256::from(1))
+        .unwrap()
+        .gas(100000);
+    let pending_tx = call.send().await.unwrap();
+    let _receipt = pending_tx.await.unwrap();
+
+    let value: U256 = contract.method("value", ()).unwrap().call().await.unwrap();
+    assert_eq!(value, 1.into());
+}
diff --git a/ethers-providers/tests/provider.rs b/ethers-providers/tests/provider.rs
index 962af4a8..47c7d826 100644
--- a/ethers-providers/tests/provider.rs
+++ b/ethers-providers/tests/provider.rs
@@ -1,15 +1,12 @@
 #![cfg(not(target_arch = "wasm32"))]
-use ethers::providers::{Http, Middleware, Provider};
+use ethers_providers::{Http, Middleware, Provider};
 use std::{convert::TryFrom, time::Duration};
 
 #[cfg(not(feature = "celo"))]
 mod eth_tests {
     use super::*;
-    use ethers::{
-        middleware::SignerMiddleware,
-        prelude::transaction::eip2718::TypedTransaction,
-        signers::{LocalWallet, Signer},
-        types::{BlockId, TransactionRequest, H256},
+    use ethers_core::{
+        types::{Address, BlockId, TransactionRequest, H256},
         utils::Ganache,
     };
 
@@ -60,7 +57,7 @@ mod eth_tests {
     // Without TLS this would error with "TLS Support not compiled in"
     #[tokio::test]
     async fn ssl_websocket() {
-        use ethers::providers::Ws;
+        use ethers_providers::Ws;
         let ws = Ws::connect("wss://rinkeby.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27")
             .await
             .unwrap();
@@ -70,10 +67,8 @@ mod eth_tests {
 
     #[tokio::test]
     async fn watch_blocks_websocket() {
-        use ethers::{
-            providers::{StreamExt, Ws},
-            types::H256,
-        };
+        use ethers_core::types::H256;
+        use ethers_providers::{StreamExt, Ws};
 
         let ganache = Ganache::new().block_time(2u64).spawn();
         let (ws, _) = tokio_tungstenite::connect_async(ganache.ws_endpoint())
@@ -98,43 +93,8 @@ mod eth_tests {
     }
 
     #[tokio::test]
-    async fn pending_txs_with_confirmations_testnet() {
-        let provider = Provider::<Http>::try_from(
-            "https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
-        )
-        .unwrap();
-        let chain_id = provider.get_chainid().await.unwrap();
-        let wallet = "59c37cb6b16fa2de30675f034c8008f890f4b2696c729d6267946d29736d73e4"
-            .parse::<LocalWallet>()
-            .unwrap()
-            .with_chain_id(chain_id.as_u64());
-        let address = wallet.address();
-        let provider = SignerMiddleware::new(provider, wallet);
-        generic_pending_txs_test(provider, address).await;
-    }
-
-    #[tokio::test]
-    #[cfg(any(feature = "tokio-runtime", feature = "tokio-tls"))]
-    // different keys to avoid nonce errors
-    async fn websocket_pending_txs_with_confirmations_testnet() {
-        let provider =
-            Provider::connect("wss://rinkeby.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27")
-                .await
-                .unwrap();
-        let chain_id = provider.get_chainid().await.unwrap();
-        let wallet = "ff7f80c6e9941865266ed1f481263d780169f1d98269c51167d20c630a5fdc8a"
-            .parse::<LocalWallet>()
-            .unwrap()
-            .with_chain_id(chain_id.as_64());
-        let address = wallet.address();
-        let provider = SignerMiddleware::new(provider, wallet);
-        generic_pending_txs_test(provider, address).await;
-    }
-
-    #[tokio::test]
-    #[cfg(any(feature = "tokio-runtime", feature = "tokio-tls"))]
     async fn websocket_pending_txs_with_confirmations_ganache() {
-        use ethers::providers::Ws;
+        use ethers_providers::Ws;
         let ganache = Ganache::new().block_time(2u64).spawn();
         let ws = Ws::connect(ganache.ws_endpoint()).await.unwrap();
         let provider = Provider::new(ws);
@@ -142,7 +102,7 @@ mod eth_tests {
         generic_pending_txs_test(provider, accounts[0]).await;
     }
 
-    async fn generic_pending_txs_test<M: Middleware>(provider: M, who: ethers::types::Address) {
+    async fn generic_pending_txs_test<M: Middleware>(provider: M, who: Address) {
         let tx = TransactionRequest::new().to(who).from(who);
         let pending_tx = provider.send_transaction(tx, None).await.unwrap();
         let tx_hash = *pending_tx;
@@ -151,56 +111,6 @@ mod eth_tests {
         assert_eq!(receipt.transaction_hash, tx_hash);
     }
 
-    #[tokio::test]
-    async fn typed_txs() {
-        use ethers_core::types::Eip1559TransactionRequest;
-        let provider = Provider::<Http>::try_from(
-            "https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
-        )
-        .unwrap();
-
-        let chain_id = provider.get_chainid().await.unwrap();
-        let wallet = "87203087aed9246e0b2417e248752a1a0df4fdaf65085c11a2b48087ba036b41"
-            .parse::<LocalWallet>()
-            .unwrap()
-            .with_chain_id(chain_id.as_u64());
-        let address = wallet.address();
-        let provider = SignerMiddleware::new(provider, wallet);
-
-        async fn check_tx<M: Middleware>(provider: &M, tx: TypedTransaction, expected: u64) {
-            let receipt = provider
-                .send_transaction(tx, None)
-                .await
-                .unwrap()
-                .await
-                .unwrap()
-                .unwrap();
-            let tx = provider
-                .get_transaction(receipt.transaction_hash)
-                .await
-                .unwrap()
-                .unwrap();
-            assert_eq!(receipt.transaction_type, Some(expected.into()));
-            assert_eq!(tx.transaction_type, Some(expected.into()));
-        }
-
-        let tx: TypedTransaction = TransactionRequest::new().from(address).to(address).into();
-        check_tx(&provider, tx, 0).await;
-
-        let tx: TypedTransaction = TransactionRequest::new()
-            .from(address)
-            .to(address)
-            .with_access_list(vec![])
-            .into();
-        check_tx(&provider, tx, 1).await;
-
-        let tx: TypedTransaction = Eip1559TransactionRequest::new()
-            .from(address)
-            .to(address)
-            .into();
-        check_tx(&provider, tx, 2).await;
-    }
-
     #[tokio::test]
     async fn eip1559_fee_estimation() {
         let provider = Provider::<Http>::try_from(
@@ -216,7 +126,7 @@ mod eth_tests {
 #[cfg(feature = "celo")]
 mod celo_tests {
     use super::*;
-    use ethers::types::{Randomness, H256};
+    use ethers_core::types::{Randomness, H256};
     use futures_util::stream::StreamExt;
 
     #[tokio::test]
diff --git a/ethers-providers/tests/txpool.rs b/ethers-providers/tests/txpool.rs
index 9079c85f..07be64fe 100644
--- a/ethers-providers/tests/txpool.rs
+++ b/ethers-providers/tests/txpool.rs
@@ -1,9 +1,9 @@
 #![cfg(not(target_arch = "wasm32"))]
-use ethers::{
-    providers::{Http, Middleware, Provider},
-    types::TransactionRequest,
+use ethers_core::{
+    types::{TransactionRequest, U256},
     utils::Geth,
 };
+use ethers_providers::{Http, Middleware, Provider};
 use std::convert::TryFrom;
 
 #[tokio::test]
@@ -13,7 +13,7 @@ async fn txpool() {
 
     let account = provider.get_accounts().await.unwrap()[0];
     let value: u64 = 42;
-    let gas_price = ethers::types::U256::from_dec_str("221435145689").unwrap();
+    let gas_price = U256::from_dec_str("221435145689").unwrap();
     let mut tx = TransactionRequest::new()
         .to(account)
         .from(account)