diff --git a/Cargo.lock b/Cargo.lock index 44af2ee7..28e9b475 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -946,12 +946,13 @@ dependencies = [ [[package]] name = "ethers" -version = "0.5.4" +version = "0.6.0" dependencies = [ "anyhow", "bytes", "ethers-contract", "ethers-core", + "ethers-etherscan", "ethers-middleware", "ethers-providers", "ethers-signers", @@ -965,7 +966,7 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "0.5.3" +version = "0.6.0" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", @@ -987,7 +988,7 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "0.5.3" +version = "0.6.0" dependencies = [ "Inflector", "anyhow", @@ -1007,7 +1008,7 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "0.5.3" +version = "0.6.0" dependencies = [ "ethers-contract-abigen", "ethers-core", @@ -1020,7 +1021,7 @@ dependencies = [ [[package]] name = "ethers-core" -version = "0.5.5" +version = "0.6.0" dependencies = [ "arrayvec 0.7.2", "bincode", @@ -1051,7 +1052,7 @@ dependencies = [ [[package]] name = "ethers-derive-eip712" -version = "0.1.0" +version = "0.2.0" dependencies = [ "ethers-contract", "ethers-contract-derive", @@ -1067,7 +1068,7 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "0.1.1" +version = "0.2.0" dependencies = [ "ethers-core", "reqwest", @@ -1079,7 +1080,7 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "0.5.3" +version = "0.6.0" dependencies = [ "async-trait", "ethers-contract", @@ -1105,7 +1106,7 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "0.5.4" +version = "0.6.0" dependencies = [ "async-trait", "auto_impl", @@ -1138,7 +1139,7 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "0.5.3" +version = "0.6.0" dependencies = [ "async-trait", "coins-bip32", @@ -2965,7 +2966,8 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "svm-rs" version = "0.1.2" -source = "git+https://github.com/roynalnaruto/svm-rs#5d353ec236a596dbfd2b37878ee5aee53ab6eadf" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ff0db3eea702209e1127ec16e007552f3ccbae84610db6d2f66c7bda0650f" dependencies = [ "anyhow", "cfg-if 1.0.0", diff --git a/Cargo.toml b/Cargo.toml index 3ea619d2..7877c4cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethers" -version = "0.5.4" +version = "0.6.0" authors = ["Georgios Konstantopoulos "] license = "MIT OR Apache-2.0" edition = "2021" @@ -82,16 +82,17 @@ solc-tests = ["ethers-solc/tests"] [dependencies] -ethers-contract = { version = "^0.5.0", default-features = false, path = "./ethers-contract" } -ethers-core = { version = "^0.5.0", default-features = false, path = "./ethers-core" } -ethers-providers = { version = "^0.5.0", default-features = false, path = "./ethers-providers" } -ethers-signers = { version = "^0.5.0", default-features = false, path = "./ethers-signers" } -ethers-middleware = { version = "^0.5.0", default-features = false, path = "./ethers-middleware" } +ethers-contract = { version = "^0.6.0", default-features = false, path = "./ethers-contract" } +ethers-core = { version = "^0.6.0", default-features = false, path = "./ethers-core" } +ethers-providers = { version = "^0.6.0", default-features = false, path = "./ethers-providers" } +ethers-signers = { version = "^0.6.0", default-features = false, path = "./ethers-signers" } +ethers-middleware = { version = "^0.6.0", default-features = false, path = "./ethers-middleware" } ethers-solc = { version = "^0.1.0", default-features = false, path = "./ethers-solc" } +ethers-etherscan = { version = "^0.2.0", default-features = false, path = "./ethers-etherscan" } [dev-dependencies] -ethers-contract = { version = "^0.5.0", default-features = false, path = "./ethers-contract", features = ["abigen", "eip712"] } -ethers-providers = { version = "^0.5.0", default-features = false, path = "./ethers-providers", features = ["ws", "ipc"] } +ethers-contract = { version = "^0.6.0", default-features = false, path = "./ethers-contract", features = ["abigen", "eip712"] } +ethers-providers = { version = "^0.6.0", default-features = false, path = "./ethers-providers", features = ["ws", "ipc"] } anyhow = "1.0.39" rand = "0.8.4" diff --git a/assets/CONTRACT_README.md b/assets/CONTRACT_README.md new file mode 120000 index 00000000..c28ebb7e --- /dev/null +++ b/assets/CONTRACT_README.md @@ -0,0 +1 @@ +../ethers-contract/README.md \ No newline at end of file diff --git a/assets/CORE_README.md b/assets/CORE_README.md new file mode 120000 index 00000000..b61206a8 --- /dev/null +++ b/assets/CORE_README.md @@ -0,0 +1 @@ +../ethers-core/README.md \ No newline at end of file diff --git a/assets/MIDDLEWARE_README.md b/assets/MIDDLEWARE_README.md new file mode 120000 index 00000000..31026c1a --- /dev/null +++ b/assets/MIDDLEWARE_README.md @@ -0,0 +1 @@ +../ethers-middleware/README.md \ No newline at end of file diff --git a/assets/PROVIDERS_README.md b/assets/PROVIDERS_README.md new file mode 120000 index 00000000..149647fb --- /dev/null +++ b/assets/PROVIDERS_README.md @@ -0,0 +1 @@ +../ethers-providers/README.md \ No newline at end of file diff --git a/assets/SIGNERS_README.md b/assets/SIGNERS_README.md new file mode 120000 index 00000000..ea8f7fac --- /dev/null +++ b/assets/SIGNERS_README.md @@ -0,0 +1 @@ +../ethers-signers/README.md \ No newline at end of file diff --git a/assets/SOLC_README.md b/assets/SOLC_README.md new file mode 120000 index 00000000..bb5c3c0f --- /dev/null +++ b/assets/SOLC_README.md @@ -0,0 +1 @@ +../ethers-solc/README.md \ No newline at end of file diff --git a/ethers-contract/Cargo.toml b/ethers-contract/Cargo.toml index e50be9f0..8c891970 100644 --- a/ethers-contract/Cargo.toml +++ b/ethers-contract/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-contract" license = "MIT OR Apache-2.0" -version = "0.5.3" +version = "0.6.0" authors = ["Georgios Konstantopoulos "] edition = "2018" description = "Smart contract bindings for the ethers-rs crate" @@ -10,11 +10,11 @@ repository = "https://github.com/gakonst/ethers-rs" keywords = ["ethereum", "web3", "celo", "ethers"] [dependencies] -ethers-providers = { version = "^0.5.0", path = "../ethers-providers", default-features = false } -ethers-core = { version = "^0.5.0", path = "../ethers-core", default-features = false } -ethers-contract-abigen = { version = "^0.5.0", path = "ethers-contract-abigen", default-features = false, optional = true } -ethers-contract-derive = { version = "^0.5.0", path = "ethers-contract-derive", optional = true } -ethers-derive-eip712 = { version = "0.1.0", path = "../ethers-core/ethers-derive-eip712", optional = true } +ethers-providers = { version = "^0.6.0", path = "../ethers-providers", default-features = false } +ethers-core = { version = "^0.6.0", path = "../ethers-core", default-features = false } +ethers-contract-abigen = { version = "^0.6.0", path = "ethers-contract-abigen", default-features = false, optional = true } +ethers-contract-derive = { version = "^0.6.0", path = "ethers-contract-derive", optional = true } +ethers-derive-eip712 = { version = "^0.2.0", path = "../ethers-core/ethers-derive-eip712", optional = true } serde = { version = "1.0.124", default-features = false } serde_json = { version = "1.0.64", default-features = false } @@ -25,13 +25,13 @@ futures-util = { version = "0.3.18" } hex = { version = "0.4.3", default-features = false, features = ["std"] } [dev-dependencies] -ethers-middleware = { version = "^0.5.0", path = "../ethers-middleware" } -ethers-providers = { version = "^0.5.0", path = "../ethers-providers", default-features = false, features = ["ws"] } -ethers-signers = { version = "^0.5.0", path = "../ethers-signers" } -ethers-contract-abigen = { version = "^0.5.0", path = "ethers-contract-abigen" } -ethers-contract-derive = { version = "^0.5.0", path = "ethers-contract-derive" } -ethers-core = { version = "^0.5.0", path = "../ethers-core", default-features = false, features = ["eip712"]} -ethers-derive-eip712 = { version = "0.1.0", path = "../ethers-core/ethers-derive-eip712"} +ethers-middleware = { version = "^0.6.0", path = "../ethers-middleware" } +ethers-providers = { version = "^0.6.0", path = "../ethers-providers", default-features = false, features = ["ws"] } +ethers-signers = { version = "^0.6.0", path = "../ethers-signers" } +ethers-contract-abigen = { version = "^0.6.0", path = "ethers-contract-abigen" } +ethers-contract-derive = { version = "^0.6.0", path = "ethers-contract-derive" } +ethers-core = { version = "^0.6.0", path = "../ethers-core", default-features = false, features = ["eip712"]} +ethers-derive-eip712 = { version = "^0.2.0", path = "../ethers-core/ethers-derive-eip712"} ethers-solc = { version = "^0.1.0", path = "../ethers-solc", default-features = false } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] diff --git a/ethers-contract/README.md b/ethers-contract/README.md new file mode 100644 index 00000000..d5658613 --- /dev/null +++ b/ethers-contract/README.md @@ -0,0 +1,16 @@ +Type-safe abstractions for interacting with Ethereum smart contracts + +Interacting with a smart contract requires broadcasting carefully crafted +[transactions](ethers_core::types::TransactionRequest) where the `data` field +contains the +[function's selector](https://ethereum.stackexchange.com/questions/72363/what-is-a-function-selector) +along with the arguments of the called function. + +This module provides the [`Contract`] and [`ContractFactory`] abstractions so +that you do not have to worry about that. It also provides typesafe bindings via +the [`abigen`] macro and the [`Abigen` builder]. + +[`contractfactory`]: ./struct.ContractFactory.html +[`contract`]: ./struct.Contract.html +[`abigen`]: ./macro.abigen.html +[`abigen` builder]: ./struct.Abigen.html diff --git a/ethers-contract/ethers-contract-abigen/Cargo.toml b/ethers-contract/ethers-contract-abigen/Cargo.toml index 46c06759..38366945 100644 --- a/ethers-contract/ethers-contract-abigen/Cargo.toml +++ b/ethers-contract/ethers-contract-abigen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethers-contract-abigen" -version = "0.5.3" +version = "0.6.0" authors = ["Nicholas Rodrigues Lordello ", "Georgios Konstantopoulos "] edition = "2018" license = "MIT OR Apache-2.0" @@ -10,7 +10,7 @@ repository = "https://github.com/gakonst/ethers-rs" keywords = ["ethereum", "web3", "celo", "ethers"] [dependencies] -ethers-core = { version = "^0.5.0", path = "../../ethers-core", features = ["macros"] } +ethers-core = { version = "^0.6.0", path = "../../ethers-core", features = ["macros"] } anyhow = "1.0.37" Inflector = "0.11" diff --git a/ethers-contract/ethers-contract-derive/Cargo.toml b/ethers-contract/ethers-contract-derive/Cargo.toml index 0c616f85..a4311090 100644 --- a/ethers-contract/ethers-contract-derive/Cargo.toml +++ b/ethers-contract/ethers-contract-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethers-contract-derive" -version = "0.5.3" +version = "0.6.0" authors = ["Nicholas Rodrigues Lordello ", "Georgios Konstantopoulos "] edition = "2018" license = "MIT OR Apache-2.0" @@ -13,8 +13,8 @@ keywords = ["ethereum", "web3", "celo", "ethers"] proc-macro = true [dependencies] -ethers-core = { version = "^0.5.0", path = "../../ethers-core" } -ethers-contract-abigen = { version = "^0.5.0", path = "../ethers-contract-abigen" } +ethers-core = { version = "^0.6.0", path = "../../ethers-core" } +ethers-contract-abigen = { version = "^0.6.0", path = "../ethers-contract-abigen" } serde_json = "1.0.53" hex = { version = "0.4.3", default-features = false, features = ["std"] } diff --git a/ethers-contract/src/lib.rs b/ethers-contract/src/lib.rs index cc0e5188..2af9a18c 100644 --- a/ethers-contract/src/lib.rs +++ b/ethers-contract/src/lib.rs @@ -1,18 +1,5 @@ #![cfg_attr(docsrs, feature(doc_cfg))] -//! Type-safe abstractions for interacting with Ethereum smart contracts -//! -//! Interacting with a smart contract requires broadcasting carefully crafted -//! [transactions](ethers_core::types::TransactionRequest) where the `data` field contains -//! the [function's -//! selector](https://ethereum.stackexchange.com/questions/72363/what-is-a-function-selector) -//! along with the arguments of the called function. This module provides the -//! [`Contract`] and [`ContractFactory`] abstractions so that you do not have to worry about that. -//! It also provides typesafe bindings via the [`abigen`] macro and the [`Abigen` builder]. -//! -//! [`ContractFactory`]: crate::ContractFactory -//! [`Contract`]: crate::Contract -//! [`abigen`]: ./macro.abigen.html -//! [`Abigen` builder]: crate::Abigen +#![doc = include_str!("../README.md")] mod contract; pub use contract::Contract; diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml index 9240dd9a..098bb42a 100644 --- a/ethers-core/Cargo.toml +++ b/ethers-core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-core" license = "MIT OR Apache-2.0" -version = "0.5.5" +version = "0.6.0" authors = ["Georgios Konstantopoulos "] edition = "2018" description = "Core structures for the ethers-rs crate" diff --git a/ethers-core/README.md b/ethers-core/README.md new file mode 100644 index 00000000..dcaf77d2 --- /dev/null +++ b/ethers-core/README.md @@ -0,0 +1,48 @@ +# Ethereum types, cryptography and utilities. + +It is recommended to use the `utils`, `types` and `abi` re-exports instead of +the `core` module to simplify your imports.\_ + +This library provides type definitions for Ethereum's main datatypes along with +other utilities for interacting with the Ethereum ecosystem + +## Signing an ethereum-prefixed message + +Signing in Ethereum is done by first prefixing the message with +`"\x19Ethereum Signed Message:\n" + message.length`, and then signing the hash +of the result. + +```rust,ignore +# async fn foo() -> Result<(), Box> { +use ethers::signers::{Signer, LocalWallet}; + +let message = "Some data"; +let wallet = LocalWallet::new(&mut rand::thread_rng()); + +// Sign the message +let signature = wallet.sign_message(message).await?; + +// Recover the signer from the message +let recovered = signature.recover(message)?; + +assert_eq!(recovered, wallet.address()); +# Ok(()) +# } +``` + +## Utilities + +The crate provides utilities for launching local Ethereum testnets by using +`ganache-cli` via the `GanacheBuilder` struct. + +# Features + +- - ["eip712"] | Provides Eip712 trait for EIP-712 encoding of typed data for + derived structs + +# ABI Encoding and Decoding + +This crate re-exports the [`ethabi`](https://docs.rs/ethabi) crate's functions +under the `abi` module, as well as the +[`secp256k1`](https://docs.rs/libsecp256k1) and [`rand`](https://docs.rs/rand) +crates for convenience. diff --git a/ethers-core/ethers-derive-eip712/Cargo.toml b/ethers-core/ethers-derive-eip712/Cargo.toml index d02de967..912b9b21 100644 --- a/ethers-core/ethers-derive-eip712/Cargo.toml +++ b/ethers-core/ethers-derive-eip712/Cargo.toml @@ -1,8 +1,9 @@ [package] name = "ethers-derive-eip712" -version = "0.1.0" +version = "0.2.0" edition = "2018" description = "Custom derive macro for EIP-712 typed data" +license = "MIT OR Apache-2.0" [lib] proc-macro = true @@ -10,13 +11,13 @@ proc-macro = true [dependencies] quote = "1.0.9" syn = "1.0.77" -ethers-core = { version = "^0.5.0", path = "../", default-features = false, features = ["eip712", "macros"] } +ethers-core = { version = "^0.6.0", path = "../", default-features = false, features = ["eip712", "macros"] } hex = "0.4.3" serde = "1.0.130" serde_json = "1.0.68" proc-macro2 = "1.0.29" [dev-dependencies] -ethers-contract = { version = "^0.5.0", path = "../../ethers-contract"} -ethers-contract-derive = { version = "^0.5.0", path = "../../ethers-contract/ethers-contract-derive" } -ethers-signers = { version = "^0.5.0", path = "../../ethers-signers" } +ethers-contract = { version = "^0.6.0", path = "../../ethers-contract"} +ethers-contract-derive = { version = "^0.6.0", path = "../../ethers-contract/ethers-contract-derive" } +ethers-signers = { version = "^0.6.0", path = "../../ethers-signers" } diff --git a/ethers-core/src/lib.rs b/ethers-core/src/lib.rs index a0d3de26..c381d19f 100644 --- a/ethers-core/src/lib.rs +++ b/ethers-core/src/lib.rs @@ -1,49 +1,5 @@ #![cfg_attr(docsrs, feature(doc_cfg))] -//! Ethereum types, cryptography and utilities. -//! _It is recommended to use the `utils`, `types` and `abi` re-exports instead of -//! the `core` module to simplify your imports._ -//! -//! This library provides type definitions for Ethereum's main datatypes along -//! with other utilities for interacting with the Ethereum ecosystem -//! -//! ## Signing an ethereum-prefixed message -//! -//! Signing in Ethereum is done by first prefixing the message with -//! `"\x19Ethereum Signed Message:\n" + message.length`, and then -//! signing the hash of the result. -//! -//! ```rust,ignore -//! # async fn foo() -> Result<(), Box> { -//! use ethers::signers::{Signer, LocalWallet}; -//! -//! let message = "Some data"; -//! let wallet = LocalWallet::new(&mut rand::thread_rng()); -//! -//! // Sign the message -//! let signature = wallet.sign_message(message).await?; -//! -//! // Recover the signer from the message -//! let recovered = signature.recover(message)?; -//! -//! assert_eq!(recovered, wallet.address()); -//! # Ok(()) -//! # } -//! ``` -//! -//! ## Utilities -//! -//! The crate provides utilities for launching local Ethereum testnets by using `ganache-cli` -//! via the `GanacheBuilder` struct. -//! -//! # Features -//! -//! * - ["eip712"] | Provides Eip712 trait for EIP-712 encoding of typed data for derived structs -//! -//! # ABI Encoding and Decoding -//! -//! This crate re-exports the [`ethabi`](ethabi) crate's functions -//! under the `abi` module, as well as the [`secp256k1`](https://docs.rs/libsecp256k1) -//! and [`rand`](https://docs.rs/rand) crates for convenience. +#![doc = include_str!("../README.md")] pub mod types; pub mod abi; diff --git a/ethers-etherscan/Cargo.toml b/ethers-etherscan/Cargo.toml index a85fa428..f7c327d9 100644 --- a/ethers-etherscan/Cargo.toml +++ b/ethers-etherscan/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethers-etherscan" -version = "0.1.1" +version = "0.2.0" authors = ["Matthias Seitz ", "Georgios Konstantopoulos "] license = "MIT OR Apache-2.0" edition = "2018" @@ -14,7 +14,7 @@ Rust API bindings for the etherscan.io web API keywords = ["ethereum", "web3", "etherscan", "ethers"] [dependencies] -ethers-core = { version = "^0.5.0", path = "../ethers-core", default-features = false } +ethers-core = { version = "^0.6.0", path = "../ethers-core", default-features = false } reqwest = { version = "0.11.6", features = ["json"] } serde = { version = "1.0.124", default-features = false, features = ["derive"] } serde_json = { version = "1.0.64", default-features = false } diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml index adf659e7..3facf35a 100644 --- a/ethers-middleware/Cargo.toml +++ b/ethers-middleware/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-middleware" license = "MIT OR Apache-2.0" -version = "0.5.3" +version = "0.6.0" authors = ["Georgios Konstantopoulos "] edition = "2018" description = "Middleware implementations for the ethers-rs crate" @@ -14,10 +14,10 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -ethers-contract = { version = "^0.5.0", path = "../ethers-contract", default-features = false, features = ["abigen"] } -ethers-core = { version = "^0.5.0", path = "../ethers-core", default-features = false } -ethers-providers = { version = "^0.5.0", path = "../ethers-providers", default-features = false } -ethers-signers = { version = "^0.5.0", path = "../ethers-signers", default-features = false } +ethers-contract = { version = "^0.6.0", path = "../ethers-contract", default-features = false, features = ["abigen"] } +ethers-core = { version = "^0.6.0", path = "../ethers-core", default-features = false } +ethers-providers = { version = "^0.6.0", path = "../ethers-providers", default-features = false } +ethers-signers = { version = "^0.6.0", path = "../ethers-signers", default-features = false } async-trait = { version = "0.1.50", default-features = false } serde = { version = "1.0.124", default-features = false, features = ["derive"] } @@ -40,7 +40,7 @@ tokio = { version = "1.5" } [dev-dependencies] hex = { version = "0.4.3", default-features = false, features = ["std"] } rand = { version = "0.8.4", default-features = false } -ethers-providers = { version = "^0.5.0", path = "../ethers-providers", default-features = false, features = ["ws", "rustls"] } +ethers-providers = { version = "^0.6.0", path = "../ethers-providers", default-features = false, features = ["ws", "rustls"] } once_cell = "1.8.0" ethers-solc = { version = "^0.1.0", path = "../ethers-solc", default-features = false } diff --git a/ethers-middleware/README.md b/ethers-middleware/README.md new file mode 100644 index 00000000..9366bbeb --- /dev/null +++ b/ethers-middleware/README.md @@ -0,0 +1,55 @@ +Ethers uses a middleware-based architecture. You start the middleware stack with +a [`Provider`](ethers_providers::Provider), and wrap it with additional +middleware functionalities that you need. + +## Available Middleware + +- [`Signer`](./signer/struct.SignerMiddleware.html): Signs transactions locally, + with a private key or a hardware wallet +- [`Nonce Manager`](./nonce_manager/struct.NonceManagerMiddleware.html): Manages + nonces locally, allowing the rapid broadcast of transactions without having to + wait for them to be submitted +- [`Gas Escalator`](./gas_escalator/struct.GasEscalatorMiddleware.html): Bumps + transaction gas prices in the background +- [`Gas Oracle`](./gas_oracle/struct.GasOracleMiddleware.html): Allows getting + your gas price estimates from places other than `eth_gasPrice`. +- [`Transformer`](./transformer/trait.Transformer.html): Allows intercepting and + transforming a transaction to be broadcasted via a proxy wallet, e.g. + [`DSProxy`](./transformer/struct.DsProxy.html). + +## Example of a middleware stack + +```no_run +use ethers_providers::{Provider, Http}; +use ethers_signers::{LocalWallet, Signer}; +use ethers_middleware::{ + gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency}, + gas_oracle::{GasOracleMiddleware, EthGasStation, GasCategory}, + signer::SignerMiddleware, + nonce_manager::NonceManagerMiddleware, +}; +use ethers_core::rand; +use std::convert::TryFrom; + +// Start the stack +let provider = Provider::::try_from("http://localhost:8545").unwrap(); + +// Escalate gas prices +let escalator = GeometricGasPrice::new(1.125, 60u64, None::); +let provider = + GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); + +// Sign transactions with a private key +let signer = LocalWallet::new(&mut rand::thread_rng()); +let address = signer.address(); +let provider = SignerMiddleware::new(provider, signer); + +// Use EthGasStation as the gas oracle +let gas_oracle = EthGasStation::new(None); +let provider = GasOracleMiddleware::new(provider, gas_oracle); + +// Manage nonces locally +let provider = NonceManagerMiddleware::new(provider, address); + +// ... do something with the provider +``` diff --git a/ethers-middleware/src/lib.rs b/ethers-middleware/src/lib.rs index 6c8a00ba..357447ab 100644 --- a/ethers-middleware/src/lib.rs +++ b/ethers-middleware/src/lib.rs @@ -1,57 +1,4 @@ -//! # Ethers Middleware -//! -//! Ethers uses a middleware-based architecture. You start the middleware stack with -//! a [`Provider`](ethers_providers::Provider), and wrap it with additional -//! middleware functionalities that you need. -//! -//! ## Available Middleware -//! - [`Signer`](crate::SignerMiddleware): Signs transactions locally, with a private -//! key or a hardware wallet -//! - [`Nonce Manager`](crate::NonceManagerMiddleware): Manages nonces locally, allowing -//! the rapid broadcast of transactions without having to wait for them to be submitted -//! - [`Gas Escalator`](crate::gas_escalator::GasEscalatorMiddleware): Bumps transaction -//! gas prices in the background -//! - [`Gas Oracle`](crate::gas_oracle): Allows getting your gas price estimates from -//! places other than `eth_gasPrice`. -//! - [`Transformer`](crate::transformer): Allows intercepting and transforming a transaction to -//! be broadcasted via a proxy wallet, e.g. [`DSProxy`](crate::transformer::DsProxy). -//! -//! ## Example of a middleware stack -//! -//! ```no_run -//! use ethers_providers::{Provider, Http}; -//! use ethers_signers::{LocalWallet, Signer}; -//! use ethers_middleware::{ -//! gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency}, -//! gas_oracle::{GasOracleMiddleware, EthGasStation, GasCategory}, -//! signer::SignerMiddleware, -//! nonce_manager::NonceManagerMiddleware, -//! }; -//! use ethers_core::rand; -//! use std::convert::TryFrom; -//! -//! // Start the stack -//! let provider = Provider::::try_from("http://localhost:8545").unwrap(); -//! -//! // Escalate gas prices -//! let escalator = GeometricGasPrice::new(1.125, 60u64, None::); -//! let provider = -//! GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); -//! -//! // Sign transactions with a private key -//! let signer = LocalWallet::new(&mut rand::thread_rng()); -//! let address = signer.address(); -//! let provider = SignerMiddleware::new(provider, signer); -//! -//! // Use EthGasStation as the gas oracle -//! let gas_oracle = EthGasStation::new(None); -//! let provider = GasOracleMiddleware::new(provider, gas_oracle); -//! -//! // Manage nonces locally -//! let provider = NonceManagerMiddleware::new(provider, address); -//! -//! // ... do something with the provider -//! ``` +#![doc = include_str!("../README.md")] /// The [Gas Escalator middleware](crate::gas_escalator::GasEscalatorMiddleware) /// is used to re-broadcast transactions with an increasing gas price to guarantee diff --git a/ethers-providers/Cargo.toml b/ethers-providers/Cargo.toml index 23e313ec..0218e7ce 100644 --- a/ethers-providers/Cargo.toml +++ b/ethers-providers/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-providers" license = "MIT OR Apache-2.0" -version = "0.5.4" +version = "0.6.0" authors = ["Georgios Konstantopoulos "] edition = "2018" description = "Provider implementations for the ethers-rs crate" @@ -14,7 +14,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -ethers-core = { version = "^0.5.0", path = "../ethers-core", default-features = false } +ethers-core = { version = "^0.6.0", path = "../ethers-core", default-features = false } async-trait = { version = "0.1.50", default-features = false } hex = { version = "0.4.3", default-features = false, features = ["std"] } diff --git a/ethers-providers/README.md b/ethers-providers/README.md new file mode 100644 index 00000000..ca1f7f77 --- /dev/null +++ b/ethers-providers/README.md @@ -0,0 +1,67 @@ +# Clients for interacting with Ethereum nodes + +This crate provides asynchronous +[Ethereum JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) compliant +clients. + +For more documentation on the available calls, refer to the +[`Provider`](./struct.Provider.html) struct. + +# Examples + +```no_run +use ethers_providers::{Provider, Http, Middleware}; +use std::convert::TryFrom; + +# async fn foo() -> Result<(), Box> { +let provider = Provider::::try_from( + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" +)?; + +let block = provider.get_block(100u64).await?; +println!("Got block: {}", serde_json::to_string(&block)?); + +let code = provider.get_code("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", None).await?; +println!("Got code: {}", serde_json::to_string(&code)?); +# Ok(()) +# } +``` + +# Websockets + +The crate has support for WebSockets via Tokio. + +``` +# async fn foo() -> Result<(), Box> { +# use ethers_providers::Ws; +let ws = Ws::connect("ws://localhost:8545").await?; +# Ok(()) +# } +``` + +# Ethereum Name Service + +The provider may also be used to resolve +[Ethereum Name Service](https://ens.domains) (ENS) names to addresses (and vice +versa). The default ENS address is +[mainnet](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) +and can be overriden by calling the [`ens`](./struct.Provider.html#method.ens) +method on the provider. + +```no_run +# use ethers_providers::{Provider, Http, Middleware}; +# use std::convert::TryFrom; +# async fn foo() -> Result<(), Box> { +# let provider = Provider::::try_from( +# "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" +# )?; +// Resolve ENS name to Address +let name = "vitalik.eth"; +let address = provider.resolve_name(name).await?; + +// Lookup ENS name given Address +let resolved_name = provider.lookup_address(address).await?; +assert_eq!(name, resolved_name); +# Ok(()) +# } +``` diff --git a/ethers-providers/src/lib.rs b/ethers-providers/src/lib.rs index 5955380a..99dd869d 100644 --- a/ethers-providers/src/lib.rs +++ b/ethers-providers/src/lib.rs @@ -1,68 +1,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![deny(broken_intra_doc_links)] #![allow(clippy::type_complexity)] -//! # Clients for interacting with Ethereum nodes -//! -//! This crate provides asynchronous [Ethereum JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) -//! compliant clients. -//! -//! For more documentation on the available calls, refer to the [`Provider`](crate::Provider) -//! struct. -//! -//! # Examples -//! -//! ```no_run -//! use ethers_providers::{Provider, Http, Middleware}; -//! use std::convert::TryFrom; -//! -//! # async fn foo() -> Result<(), Box> { -//! let provider = Provider::::try_from( -//! "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" -//! )?; -//! -//! let block = provider.get_block(100u64).await?; -//! println!("Got block: {}", serde_json::to_string(&block)?); -//! -//! let code = provider.get_code("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", None).await?; -//! println!("Got code: {}", serde_json::to_string(&code)?); -//! # Ok(()) -//! # } -//! ``` -//! -//! # Websockets -//! -//! The crate has support for WebSockets via Tokio. -//! -//! ``` -//! # async fn foo() -> Result<(), Box> { -//! # use ethers_providers::Ws; -//! let ws = Ws::connect("ws://localhost:8545").await?; -//! # Ok(()) -//! # } -//! ``` -//! -//! # Ethereum Name Service -//! -//! The provider may also be used to resolve [Ethereum Name Service](https://ens.domains) (ENS) names -//! 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 std::convert::TryFrom; -//! # async fn foo() -> Result<(), Box> { -//! # let provider = Provider::::try_from( -//! # "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" -//! # )?; -//! // Resolve ENS name to Address -//! let name = "vitalik.eth"; -//! let address = provider.resolve_name(name).await?; -//! -//! // Lookup ENS name given Address -//! let resolved_name = provider.lookup_address(address).await?; -//! assert_eq!(name, resolved_name); -//! # Ok(()) -//! # } -//! ``` +#![doc = include_str!("../README.md")] mod transports; use futures_util::future::join_all; pub use transports::*; diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml index 8e33415c..f52b7b66 100644 --- a/ethers-signers/Cargo.toml +++ b/ethers-signers/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-signers" license = "MIT OR Apache-2.0" -version = "0.5.3" +version = "0.6.0" authors = ["Georgios Konstantopoulos "] edition = "2018" description = "Signer implementations for the ethers-rs crate" @@ -14,7 +14,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -ethers-core = { version = "^0.5.0", path = "../ethers-core", features = ["eip712"]} +ethers-core = { version = "^0.6.0", path = "../ethers-core", features = ["eip712"]} thiserror = { version = "1.0.30", default-features = false } coins-bip32 = "0.3.0" coins-bip39 = "0.3.0" @@ -40,8 +40,8 @@ spki = { version = "0.4.1", optional = true } eth-keystore = { version = "0.3.0" } [dev-dependencies] -ethers-contract = { version = "^0.5.0", path = "../ethers-contract", features = ["eip712", "abigen"]} -ethers-derive-eip712 = { version = "0.1.0", path = "../ethers-core/ethers-derive-eip712" } +ethers-contract = { version = "^0.6.0", path = "../ethers-contract", features = ["eip712", "abigen"]} +ethers-derive-eip712 = { version = "0.2.0", path = "../ethers-core/ethers-derive-eip712" } serde_json = { version = "1.0.64" } tracing-subscriber = "0.3.2" yubihsm = { version = "0.39.0", features = ["secp256k1", "usb", "mockhsm"] } diff --git a/ethers-signers/README.md b/ethers-signers/README.md new file mode 100644 index 00000000..6b2dde5f --- /dev/null +++ b/ethers-signers/README.md @@ -0,0 +1,40 @@ +You can implement the `Signer` trait to extend functionality to other signers +such as Hardware Security Modules, KMS etc. + +The exposed interfaces return a recoverable signature. In order to convert the +signature and the [`TransactionRequest`] to a [`Transaction`], look at the +signing middleware. + +Supported signers: + +- [Private key](./type.LocalWallet.html) +- [Ledger](./struct.Ledger.html) +- [YubiHSM2](./struct.Yubi.html) +- [AWS KMS](./struct.AwsSigner.html) + +```no_run +# use ethers_signers::{LocalWallet, Signer}; +# use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest}; + +# async fn foo() -> Result<(), Box> { +// instantiate the wallet +let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7" + .parse::()?; + +// create a transaction +let tx = TransactionRequest::new() + .to("vitalik.eth") // this will use ENS + .value(10000).into(); + +// sign it +let signature = wallet.sign_transaction(&tx).await?; + +// can also sign a message +let signature = wallet.sign_message("hello world").await?; +signature.verify("hello world", wallet.address()).unwrap(); +# Ok(()) +# } +``` + +[`transaction`]: ethers_core::types::Transaction +[`transactionrequest`]: ethers_core::types::TransactionRequest diff --git a/ethers-signers/src/lib.rs b/ethers-signers/src/lib.rs index 8e643307..4b94355c 100644 --- a/ethers-signers/src/lib.rs +++ b/ethers-signers/src/lib.rs @@ -1,43 +1,4 @@ //! Provides a unified interface for locally signing transactions. -//! -//! You can implement the `Signer` trait to extend functionality to other signers -//! such as Hardware Security Modules, KMS etc. -//! -//! The exposed interfaces return a recoverable signature. In order to convert the signature -//! and the [`TransactionRequest`] to a [`Transaction`], look at the signing middleware. -//! -//! Supported signers: -//! - [Private key](crate::LocalWallet) -//! - [Ledger](crate::Ledger) -//! - [YubiHSM2](crate::YubiWallet) -//! - [AWS KMS](crate::AwsSigner) -//! -//! ```no_run -//! # use ethers_signers::{LocalWallet, Signer}; -//! # use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest}; -//! -//! # async fn foo() -> Result<(), Box> { -//! // instantiate the wallet -//! let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7" -//! .parse::()?; -//! -//! // create a transaction -//! let tx = TransactionRequest::new() -//! .to("vitalik.eth") // this will use ENS -//! .value(10000).into(); -//! -//! // sign it -//! let signature = wallet.sign_transaction(&tx).await?; -//! -//! // can also sign a message -//! let signature = wallet.sign_message("hello world").await?; -//! signature.verify("hello world", wallet.address()).unwrap(); -//! # Ok(()) -//! # } -//! ``` -//! -//! [`Transaction`]: ethers_core::types::Transaction -//! [`TransactionRequest`]: ethers_core::types::TransactionRequest mod wallet; pub use wallet::{MnemonicBuilder, Wallet, WalletError}; diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index c16d601c..478861fa 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -14,7 +14,7 @@ Utilites for working with solc keywords = ["ethereum", "web3", "solc", "solidity", "ethers"] [dependencies] -ethers-core = { version = "^0.5.0", path = "../ethers-core", default-features = false } +ethers-core = { version = "^0.6.0", path = "../ethers-core", default-features = false } serde_json = "1.0.68" serde = { version = "1.0.130", features = ["derive"] } semver = "1.0.4" @@ -27,7 +27,7 @@ md-5 = "0.9.1" thiserror = "1.0.30" hex = "0.4.3" colored = "2.0.0" -svm = { package = "svm-rs", git = "https://github.com/roynalnaruto/svm-rs", optional = true } +svm = { package = "svm-rs", version = "0.1.2", optional = true } glob = "0.3.0" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/src/lib.rs b/src/lib.rs index ab77ce62..d5dc218d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,30 +83,58 @@ //! [`utils`]: core::utils //! [`abi`]: core::abi //! [`types`]: core::types -pub use ethers_contract as contract; -pub use ethers_core as core; -pub use ethers_middleware as middleware; -pub use ethers_providers as providers; -pub use ethers_signers as signers; -pub use ethers_solc as solc; -// Re-export ethers_core::utils/types/abi -// We hide these docs so that the rustdoc links send the visitor -// to the corresponding crate, instead of the re-export -#[doc(hidden)] -pub use ethers_core::abi; -#[doc(hidden)] -pub use ethers_core::types; -#[doc(hidden)] -pub use ethers_core::utils; +#[doc = include_str!("../assets/CONTRACT_README.md")] +pub mod contract { + pub use ethers_contract::*; +} + +#[doc = include_str!("../assets/CORE_README.md")] +pub mod core { + pub use ethers_core::*; +} + +#[doc = include_str!("../assets/PROVIDERS_README.md")] +pub mod providers { + pub use ethers_providers::*; +} + +#[doc = include_str!("../assets/MIDDLEWARE_README.md")] +pub mod middleware { + pub use ethers_middleware::*; +} + +#[doc = include_str!("../assets/SIGNERS_README.md")] +pub mod signers { + pub use ethers_signers::*; +} + +#[doc = include_str!("../assets/SOLC_README.md")] +pub mod solc { + pub use ethers_solc::*; +} + +/// Etherscan bindings +pub mod etherscan { + pub use ethers_etherscan::*; +} + +pub use crate::core::{abi, types, utils}; /// Easy imports of frequently used type definitions and traits #[doc(hidden)] pub mod prelude { - pub use ethers_contract::*; - pub use ethers_core::types::*; - pub use ethers_middleware::*; - pub use ethers_providers::*; - pub use ethers_signers::*; - pub use ethers_solc::*; + pub use super::contract::*; + + pub use super::core::{types::*, *}; + + pub use super::middleware::*; + + pub use super::providers::*; + + pub use super::signers::*; + + pub use super::solc::*; + + pub use super::etherscan::*; }