docs: add more docs (#130)
This commit is contained in:
parent
5c1f8f532a
commit
5f292670fc
|
@ -88,3 +88,12 @@ This library would not have been possibly without the great work done in:
|
||||||
|
|
||||||
A lot of the code was inspired and adapted from them, to a unified and opinionated interface,
|
A lot of the code was inspired and adapted from them, to a unified and opinionated interface,
|
||||||
built with async/await and std futures from the ground up.
|
built with async/await and std futures from the ground up.
|
||||||
|
|
||||||
|
## Projects using ethers-rs
|
||||||
|
|
||||||
|
- [Yield Liquidator](https://github.com/yieldprotocol/yield-liquidator/): Liquidator for Yield Protocol
|
||||||
|
- [MEV Inspect](https://github.com/flashbots/mev-inspect-rs/): Miner Extractable Value inspector
|
||||||
|
- [Ethers Fireblocks](https://github.com/gakonst/ethers-fireblocks): Ethers middleware and signer for [Fireblocks](https://fireblocks.io)' API
|
||||||
|
- [Celo Threshold BLS DKG](https://github.com/celo-org/celo-threshold-bls-rs/): CLI for using Celo as a data availability network for the Joint-Feldman BLS DKG
|
||||||
|
- [Celo Plumo Prover](https://github.com/celo-org/plumo-prover): Creates Celo's ultralight client proof from on-chain data
|
||||||
|
- [Celo SNARK Setup Coordinator](https://github.com/celo-org/snark-setup-operator): Coordinator for executing a pipelined Groth16 SNARK setup
|
||||||
|
|
|
@ -53,7 +53,7 @@ impl BaseContract {
|
||||||
/// versions, consider using `encode_with_selector`
|
/// versions, consider using `encode_with_selector`
|
||||||
pub fn encode<T: Tokenize>(&self, name: &str, args: T) -> Result<Bytes, AbiError> {
|
pub fn encode<T: Tokenize>(&self, name: &str, args: T) -> Result<Bytes, AbiError> {
|
||||||
let function = self.abi.function(name)?;
|
let function = self.abi.function(name)?;
|
||||||
encode_fn(function, args)
|
encode_function_data(function, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the ABI encoded data for the provided function selector and arguments
|
/// Returns the ABI encoded data for the provided function selector and arguments
|
||||||
|
@ -63,7 +63,7 @@ impl BaseContract {
|
||||||
args: T,
|
args: T,
|
||||||
) -> Result<Bytes, AbiError> {
|
) -> Result<Bytes, AbiError> {
|
||||||
let function = self.get_from_signature(signature)?;
|
let function = self.get_from_signature(signature)?;
|
||||||
encode_fn(function, args)
|
encode_function_data(function, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes the provided ABI encoded function arguments with the selected function name.
|
/// Decodes the provided ABI encoded function arguments with the selected function name.
|
||||||
|
@ -76,7 +76,7 @@ impl BaseContract {
|
||||||
bytes: T,
|
bytes: T,
|
||||||
) -> Result<D, AbiError> {
|
) -> Result<D, AbiError> {
|
||||||
let function = self.abi.function(name)?;
|
let function = self.abi.function(name)?;
|
||||||
decode_fn(function, bytes, true)
|
decode_function_data(function, bytes, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes for a given event name, given the `log.topics` and
|
/// Decodes for a given event name, given the `log.topics` and
|
||||||
|
@ -98,7 +98,7 @@ impl BaseContract {
|
||||||
bytes: T,
|
bytes: T,
|
||||||
) -> Result<D, AbiError> {
|
) -> Result<D, AbiError> {
|
||||||
let function = self.get_from_signature(signature)?;
|
let function = self.get_from_signature(signature)?;
|
||||||
decode_fn(function, bytes, true)
|
decode_function_data(function, bytes, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_from_signature(&self, signature: Selector) -> Result<&Function, AbiError> {
|
fn get_from_signature(&self, signature: Selector) -> Result<&Function, AbiError> {
|
||||||
|
@ -147,14 +147,14 @@ pub(crate) fn decode_event<D: Detokenize>(
|
||||||
Ok(D::from_tokens(tokens)?)
|
Ok(D::from_tokens(tokens)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for encoding arguments for a specific function
|
/// Helper for ABI encoding arguments for a specific function
|
||||||
pub(crate) fn encode_fn<T: Tokenize>(function: &Function, args: T) -> Result<Bytes, AbiError> {
|
pub fn encode_function_data<T: Tokenize>(function: &Function, args: T) -> Result<Bytes, AbiError> {
|
||||||
let tokens = args.into_tokens();
|
let tokens = args.into_tokens();
|
||||||
Ok(function.encode_input(&tokens).map(Into::into)?)
|
Ok(function.encode_input(&tokens).map(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for decoding bytes from a specific function
|
/// Helper for ABI decoding raw data based on a function's input or output.
|
||||||
pub fn decode_fn<D: Detokenize, T: AsRef<[u8]>>(
|
pub fn decode_function_data<D: Detokenize, T: AsRef<[u8]>>(
|
||||||
function: &Function,
|
function: &Function,
|
||||||
bytes: T,
|
bytes: T,
|
||||||
is_input: bool,
|
is_input: bool,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::base::{decode_fn, AbiError};
|
use super::base::{decode_function_data, AbiError};
|
||||||
use ethers_core::{
|
use ethers_core::{
|
||||||
abi::{Detokenize, Function, InvalidOutputType},
|
abi::{Detokenize, Function, InvalidOutputType},
|
||||||
types::{Address, BlockNumber, Bytes, TransactionRequest, U256},
|
types::{Address, BlockNumber, Bytes, TransactionRequest, U256},
|
||||||
|
@ -120,7 +120,7 @@ where
|
||||||
.map_err(ContractError::MiddlewareError)?;
|
.map_err(ContractError::MiddlewareError)?;
|
||||||
|
|
||||||
// decode output
|
// decode output
|
||||||
let data = decode_fn(&self.function, &bytes, false)?;
|
let data = decode_function_data(&self.function, &bytes, false)?;
|
||||||
|
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::{
|
use super::{
|
||||||
base::{encode_fn, AbiError, BaseContract},
|
base::{encode_function_data, AbiError, BaseContract},
|
||||||
call::ContractCall,
|
call::ContractCall,
|
||||||
event::Event,
|
event::Event,
|
||||||
};
|
};
|
||||||
|
@ -227,7 +227,7 @@ impl<M: Middleware> Contract<M> {
|
||||||
function: &Function,
|
function: &Function,
|
||||||
args: T,
|
args: T,
|
||||||
) -> Result<ContractCall<M, D>, AbiError> {
|
) -> Result<ContractCall<M, D>, AbiError> {
|
||||||
let data = encode_fn(function, args)?;
|
let data = encode_function_data(function, args)?;
|
||||||
|
|
||||||
// create the tx object
|
// create the tx object
|
||||||
let tx = TransactionRequest {
|
let tx = TransactionRequest {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{base::decode_event, ContractError, EventStream};
|
use crate::{base::decode_event, stream::EventStream, ContractError};
|
||||||
|
|
||||||
use ethers_core::{
|
use ethers_core::{
|
||||||
abi::{Detokenize, Event as AbiEvent},
|
abi::{Detokenize, Event as AbiEvent},
|
||||||
|
|
|
@ -17,7 +17,7 @@ mod contract;
|
||||||
pub use contract::Contract;
|
pub use contract::Contract;
|
||||||
|
|
||||||
mod base;
|
mod base;
|
||||||
pub use base::{decode_fn, BaseContract};
|
pub use base::{decode_function_data, encode_function_data, BaseContract};
|
||||||
|
|
||||||
mod call;
|
mod call;
|
||||||
pub use call::ContractError;
|
pub use call::ContractError;
|
||||||
|
@ -28,7 +28,6 @@ pub use factory::ContractFactory;
|
||||||
mod event;
|
mod event;
|
||||||
|
|
||||||
mod stream;
|
mod stream;
|
||||||
pub use stream::EventStream;
|
|
||||||
|
|
||||||
mod multicall;
|
mod multicall;
|
||||||
pub use multicall::Multicall;
|
pub use multicall::Multicall;
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct EthGasStationResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EthGasStation {
|
impl EthGasStation {
|
||||||
|
/// Creates a new [EthGasStation](https://docs.ethgasstation.info/) gas oracle
|
||||||
pub fn new(api_key: Option<&'static str>) -> Self {
|
pub fn new(api_key: Option<&'static str>) -> Self {
|
||||||
let url = match api_key {
|
let url = match api_key {
|
||||||
Some(key) => format!("{}?api-key={}", ETH_GAS_STATION_URL_PREFIX, key),
|
Some(key) => format!("{}?api-key={}", ETH_GAS_STATION_URL_PREFIX, key),
|
||||||
|
@ -43,6 +44,7 @@ impl EthGasStation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the gas price category to be used when fetching the gas price.
|
||||||
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
||||||
self.gas_category = gas_category;
|
self.gas_category = gas_category;
|
||||||
self
|
self
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct EtherchainResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Etherchain {
|
impl Etherchain {
|
||||||
|
/// Creates a new [Etherchain](https://etherchain.org/tools/gasPriceOracle) gas price oracle.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let url = Url::parse(ETHERCHAIN_URL).expect("invalid url");
|
let url = Url::parse(ETHERCHAIN_URL).expect("invalid url");
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ impl Etherchain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the gas price category to be used when fetching the gas price.
|
||||||
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
||||||
self.gas_category = gas_category;
|
self.gas_category = gas_category;
|
||||||
self
|
self
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct EtherscanResponseInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Etherscan {
|
impl Etherscan {
|
||||||
|
/// Creates a new [Etherscan](https://etherscan.io/gastracker) gas price oracle.
|
||||||
pub fn new(api_key: Option<&str>) -> Self {
|
pub fn new(api_key: Option<&str>) -> Self {
|
||||||
let url = match api_key {
|
let url = match api_key {
|
||||||
Some(key) => format!("{}&apikey={}", ETHERSCAN_URL_PREFIX, key),
|
Some(key) => format!("{}&apikey={}", ETHERSCAN_URL_PREFIX, key),
|
||||||
|
@ -54,6 +55,7 @@ impl Etherscan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the gas price category to be used when fetching the gas price.
|
||||||
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
||||||
self.gas_category = gas_category;
|
self.gas_category = gas_category;
|
||||||
self
|
self
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct GasNowResponseInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GasNow {
|
impl GasNow {
|
||||||
|
/// Creates a new [GasNow](https://gasnow.org) gas price oracle.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let url = Url::parse(GAS_NOW_URL).expect("invalid url");
|
let url = Url::parse(GAS_NOW_URL).expect("invalid url");
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ impl GasNow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the gas price category to be used when fetching the gas price.
|
||||||
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
pub fn category(mut self, gas_category: GasCategory) -> Self {
|
||||||
self.gas_category = gas_category;
|
self.gas_category = gas_category;
|
||||||
self
|
self
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
//! # Ethers Middleware
|
//! # Ethers Middleware
|
||||||
//!
|
//!
|
||||||
//! Ethers uses a middleware architecture. You start the middleware stack with
|
//! Ethers uses a middleware-based architecture. You start the middleware stack with
|
||||||
//! a [`Provider`](ethers_providers::Provider), and wrap it with additional
|
//! a [`Provider`](ethers_providers::Provider), and wrap it with additional
|
||||||
//! middleware functionalities that you need.
|
//! middleware functionalities that you need.
|
||||||
//!
|
//!
|
||||||
//! ## Available Middleware
|
//! ## Available Middleware
|
||||||
//! - Signer
|
//! - [`Signer`](crate::SignerMiddleware): Signs transactions locally, with a private
|
||||||
//! - Nonce Manager
|
//! key or a hardware wallet
|
||||||
//! - Gas Escalator
|
//! - [`Nonce Manager`](crate::NonceManagerMiddleware): Manages nonces locally, allowing
|
||||||
//! - Gas Oracle
|
//! 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`.
|
||||||
//!
|
//!
|
||||||
//! ## Example of a middleware stack
|
//! ## Example of a middleware stack
|
||||||
//!
|
//!
|
||||||
|
@ -49,19 +53,22 @@
|
||||||
//! // ... do something with the provider
|
//! // ... do something with the provider
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
/// The gas escalator middleware is used to re-broadcast transactions with an
|
/// The [Gas Escalator middleware](crate::gas_escalator::GasEscalatorMiddleware)
|
||||||
/// increasing gas price to guarantee their timely inclusion
|
/// is used to re-broadcast transactions with an increasing gas price to guarantee
|
||||||
|
/// their timely inclusion.
|
||||||
pub mod gas_escalator;
|
pub mod gas_escalator;
|
||||||
|
|
||||||
/// The gas oracle middleware is used to get the gas price from a list of gas oracles
|
/// The gas oracle middleware is used to get the gas price from a list of gas oracles
|
||||||
/// instead of using eth_gasPrice
|
/// instead of using eth_gasPrice. For usage examples, refer to the
|
||||||
|
/// [`GasOracle`](crate::gas_oracle::GasOracle) trait.
|
||||||
pub mod gas_oracle;
|
pub mod gas_oracle;
|
||||||
|
|
||||||
/// The nonce manager middleware is used to locally calculate nonces instead of
|
/// The [Nonce Manager](crate::NonceManagerMiddleware) is used to locally calculate nonces instead of
|
||||||
/// using eth_getTransactionCount
|
/// using eth_getTransactionCount
|
||||||
pub mod nonce_manager;
|
pub mod nonce_manager;
|
||||||
|
pub use nonce_manager::NonceManagerMiddleware;
|
||||||
|
|
||||||
/// The signer middleware is used to locally sign transactions and messages
|
/// The [Signer](crate::SignerMiddleware) is used to locally sign transactions and messages
|
||||||
/// instead of using eth_sendTransaction and eth_sign
|
/// instead of using eth_sendTransaction and eth_sign
|
||||||
pub mod signer;
|
pub mod signer;
|
||||||
pub use signer::SignerMiddleware;
|
pub use signer::SignerMiddleware;
|
||||||
|
|
|
@ -8,17 +8,18 @@ use thiserror::Error;
|
||||||
/// Middleware used for calculating nonces locally, useful for signing multiple
|
/// Middleware used for calculating nonces locally, useful for signing multiple
|
||||||
/// consecutive transactions without waiting for them to hit the mempool
|
/// consecutive transactions without waiting for them to hit the mempool
|
||||||
pub struct NonceManagerMiddleware<M> {
|
pub struct NonceManagerMiddleware<M> {
|
||||||
pub inner: M,
|
inner: M,
|
||||||
pub initialized: AtomicBool,
|
initialized: AtomicBool,
|
||||||
pub nonce: AtomicU64,
|
nonce: AtomicU64,
|
||||||
pub address: Address,
|
address: Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> NonceManagerMiddleware<M>
|
impl<M> NonceManagerMiddleware<M>
|
||||||
where
|
where
|
||||||
M: Middleware,
|
M: Middleware,
|
||||||
{
|
{
|
||||||
/// Instantiates the nonce manager with a 0 nonce.
|
/// Instantiates the nonce manager with a 0 nonce. The `address` should be the
|
||||||
|
/// address which you'll be sending transactions from
|
||||||
pub fn new(inner: M, address: Address) -> Self {
|
pub fn new(inner: M, address: Address) -> Self {
|
||||||
Self {
|
Self {
|
||||||
initialized: false.into(),
|
initialized: false.into(),
|
||||||
|
|
|
@ -113,13 +113,70 @@ pub trait FromErr<T> {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
#[auto_impl(&, Box, Arc)]
|
#[auto_impl(&, Box, Arc)]
|
||||||
|
/// A middleware allows customizing requests send and received from an ethereum node.
|
||||||
|
///
|
||||||
|
/// Writing a middleware is as simple as:
|
||||||
|
/// 1. implementing the [`inner`](crate::Middleware::inner) method to point to the next layer in the "middleware onion",
|
||||||
|
/// 2. implementing the [`FromErr`](crate::FromErr) trait on your middleware's error type
|
||||||
|
/// 3. implementing any of the methods you want to override
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use ethers::{providers::{Middleware, FromErr}, types::{U64, TransactionRequest, U256}};
|
||||||
|
/// use thiserror::Error;
|
||||||
|
/// use async_trait::async_trait;
|
||||||
|
///
|
||||||
|
/// #[derive(Debug)]
|
||||||
|
/// struct MyMiddleware<M>(M);
|
||||||
|
///
|
||||||
|
/// #[derive(Error, Debug)]
|
||||||
|
/// pub enum MyError<M: Middleware> {
|
||||||
|
/// #[error("{0}")]
|
||||||
|
/// MiddlewareError(M::Error),
|
||||||
|
///
|
||||||
|
/// // Add your middleware's specific errors here
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl<M: Middleware> FromErr<M::Error> for MyError<M> {
|
||||||
|
/// fn from(src: M::Error) -> MyError<M> {
|
||||||
|
/// MyError::MiddlewareError(src)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[async_trait]
|
||||||
|
/// impl<M> Middleware for MyMiddleware<M>
|
||||||
|
/// where
|
||||||
|
/// M: Middleware,
|
||||||
|
/// {
|
||||||
|
/// type Error = MyError<M>;
|
||||||
|
/// type Provider = M::Provider;
|
||||||
|
/// type Inner = M;
|
||||||
|
///
|
||||||
|
/// fn inner(&self) -> &M {
|
||||||
|
/// &self.0
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// Overrides the default `get_block_number` method to always return 0
|
||||||
|
/// async fn get_block_number(&self) -> Result<U64, Self::Error> {
|
||||||
|
/// Ok(U64::zero())
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// Overrides the default `estimate_gas` method to log that it was called,
|
||||||
|
/// /// before forwarding the call to the next layer.
|
||||||
|
/// async fn estimate_gas(&self, tx: &TransactionRequest) -> Result<U256, Self::Error> {
|
||||||
|
/// println!("Estimating gas...");
|
||||||
|
/// self.inner().estimate_gas(tx).await.map_err(FromErr::from)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub trait Middleware: Sync + Send + Debug {
|
pub trait Middleware: Sync + Send + Debug {
|
||||||
type Error: Sync + Send + Error + FromErr<<Self::Inner as Middleware>::Error>;
|
type Error: Sync + Send + Error + FromErr<<Self::Inner as Middleware>::Error>;
|
||||||
type Provider: JsonRpcClient;
|
type Provider: JsonRpcClient;
|
||||||
type Inner: Middleware<Provider = Self::Provider>;
|
type Inner: Middleware<Provider = Self::Provider>;
|
||||||
|
|
||||||
|
/// The next middleware in the stack
|
||||||
fn inner(&self) -> &Self::Inner;
|
fn inner(&self) -> &Self::Inner;
|
||||||
|
|
||||||
|
/// The HTTP or Websocket provider.
|
||||||
fn provider(&self) -> &Provider<Self::Provider> {
|
fn provider(&self) -> &Provider<Self::Provider> {
|
||||||
self.inner().provider()
|
self.inner().provider()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub trait PubsubClient: JsonRpcClient {
|
||||||
|
|
||||||
#[must_use = "subscriptions do nothing unless you stream them"]
|
#[must_use = "subscriptions do nothing unless you stream them"]
|
||||||
#[pin_project(PinnedDrop)]
|
#[pin_project(PinnedDrop)]
|
||||||
|
/// Streams data from an installed filter via `eth_subscribe`
|
||||||
pub struct SubscriptionStream<'a, P: PubsubClient, R: DeserializeOwned> {
|
pub struct SubscriptionStream<'a, P: PubsubClient, R: DeserializeOwned> {
|
||||||
/// The subscription's installed id on the ethereum node
|
/// The subscription's installed id on the ethereum node
|
||||||
pub id: U256,
|
pub id: U256,
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum FilterWatcherState<'a, R> {
|
||||||
|
|
||||||
#[must_use = "filters do nothing unless you stream them"]
|
#[must_use = "filters do nothing unless you stream them"]
|
||||||
#[pin_project]
|
#[pin_project]
|
||||||
|
/// Streams data from an installed filter via `eth_getFilterCahnges`
|
||||||
pub struct FilterWatcher<'a, P, R> {
|
pub struct FilterWatcher<'a, P, R> {
|
||||||
/// The filter's installed id on the ethereum node
|
/// The filter's installed id on the ethereum node
|
||||||
pub id: U256,
|
pub id: U256,
|
||||||
|
|
|
@ -4,9 +4,13 @@ use std::fmt;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
/// Ledger wallet type
|
||||||
pub enum DerivationType {
|
pub enum DerivationType {
|
||||||
|
/// Ledger Live-generated HD path
|
||||||
LedgerLive(usize),
|
LedgerLive(usize),
|
||||||
|
/// Legacy generated HD Path
|
||||||
Legacy(usize),
|
Legacy(usize),
|
||||||
|
/// Any other path
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +29,7 @@ impl fmt::Display for DerivationType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
|
/// Error when using the Ledger transport
|
||||||
pub enum LedgerError {
|
pub enum LedgerError {
|
||||||
/// Underlying ledger transport error
|
/// Underlying ledger transport error
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -34,10 +39,8 @@ pub enum LedgerError {
|
||||||
UnexpectedNullResponse,
|
UnexpectedNullResponse,
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
/// Error when converting from a hex string
|
||||||
HexError(#[from] hex::FromHexError),
|
HexError(#[from] hex::FromHexError),
|
||||||
|
|
||||||
#[error("Error when decoding UTF8 Response: {0}")]
|
|
||||||
Utf8Error(#[from] std::str::Utf8Error),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const P1_FIRST: u8 = 0x00;
|
pub const P1_FIRST: u8 = 0x00;
|
||||||
|
|
|
@ -7,14 +7,15 @@
|
||||||
//! and the [`TransactionRequest`] to a [`Transaction`], look at the signing middleware.
|
//! and the [`TransactionRequest`] to a [`Transaction`], look at the signing middleware.
|
||||||
//!
|
//!
|
||||||
//! Supported signers:
|
//! Supported signers:
|
||||||
//! - Private key
|
//! - [Private key](crate::LocalWallet)
|
||||||
//! - Ledger
|
//! - [Ledger](crate::Ledger)
|
||||||
|
//! - [YubiHSM2](crate::YubiWallet)
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # use ethers::{
|
//! # use ethers::{
|
||||||
//! signers::{LocalWallet, Signer},
|
//! # signers::{LocalWallet, Signer},
|
||||||
//! core::{k256::ecdsa::SigningKey, types::TransactionRequest},
|
//! # core::{k256::ecdsa::SigningKey, types::TransactionRequest},
|
||||||
//! };
|
//! # };
|
||||||
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! // instantiate the wallet
|
//! // instantiate the wallet
|
||||||
//! let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
|
//! let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
|
||||||
|
@ -37,8 +38,6 @@
|
||||||
//!
|
//!
|
||||||
//! [`Transaction`]: ethers_core::types::Transaction
|
//! [`Transaction`]: ethers_core::types::Transaction
|
||||||
//! [`TransactionRequest`]: ethers_core::types::TransactionRequest
|
//! [`TransactionRequest`]: ethers_core::types::TransactionRequest
|
||||||
// mod wallet;
|
|
||||||
// pub use wallet::Wallet;
|
|
||||||
mod wallet;
|
mod wallet;
|
||||||
pub use wallet::Wallet;
|
pub use wallet::Wallet;
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
//!
|
//!
|
||||||
//! > ethers-rs is a port of [ethers-js](github.com/ethers-io/ethers.js) in Rust.
|
//! > ethers-rs is a port of [ethers-js](github.com/ethers-io/ethers.js) in Rust.
|
||||||
//!
|
//!
|
||||||
//! _Note: All examples using `await` are assuming that they are called from inside an `async`
|
|
||||||
//! function which is run in an async runtime. You are free to use any runtime and executor of
|
|
||||||
//! your preference._
|
|
||||||
//!
|
|
||||||
//! ## Quickstart: `prelude`
|
//! ## Quickstart: `prelude`
|
||||||
//!
|
//!
|
||||||
//! A prelude is provided which imports all the important data types and traits for you. Use this
|
//! A prelude is provided which imports all the important data types and traits for you. Use this
|
||||||
|
@ -55,8 +51,9 @@
|
||||||
//!
|
//!
|
||||||
//! ## `signers`
|
//! ## `signers`
|
||||||
//!
|
//!
|
||||||
//! For security reasons, you typically do not want your private keys to be stored on the nodes.
|
//! This module provides a [`Signer`] trait which can be used for signing messages
|
||||||
//! This module provides a [`Wallet`] type for connecting to a private key or a YubiHSM2
|
//! or transactions. A [`Wallet`] type is implemented which can be used with a
|
||||||
|
//! raw private key, or a YubiHSM2. We also provide Ledger support.
|
||||||
//!
|
//!
|
||||||
//! ## `contract`
|
//! ## `contract`
|
||||||
//!
|
//!
|
||||||
|
@ -71,14 +68,23 @@
|
||||||
//! [`Contract`] and [`ContractFactory`] abstractions so that you do not have to worry about that.
|
//! [`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].
|
//! It also provides typesafe bindings via the [`abigen`] macro and the [`Abigen` builder].
|
||||||
//!
|
//!
|
||||||
//! [`Provider`]: providers::Provider
|
//! ## `middleware`
|
||||||
//! [`Wallet`]: signers::Wallet
|
|
||||||
//!
|
//!
|
||||||
|
//! In order to keep the ethers architecture as modular as possible, providers define a [`Middleware`]
|
||||||
|
//! trait which defines all the methods to interact with an Ethereum node. By implementing the
|
||||||
|
//! middleware trait, you are able to override the default behavior of methods and do things such
|
||||||
|
//! as using other gas oracles, escalating your transactions' gas prices, or signing your transactions
|
||||||
|
//! with a [`Signer`]. The middleware architecture allows users to either use one of the existing
|
||||||
|
//! middleware, or they are free to write on of their own.
|
||||||
|
//!
|
||||||
|
//! [`Provider`]: providers::Provider
|
||||||
|
//! [`Middleware`]: providers::Middleware
|
||||||
|
//! [`Wallet`]: signers::Wallet
|
||||||
|
//! [`Signer`]: signers::Signer
|
||||||
//! [`ContractFactory`]: contract::ContractFactory
|
//! [`ContractFactory`]: contract::ContractFactory
|
||||||
//! [`Contract`]: contract::Contract
|
//! [`Contract`]: contract::Contract
|
||||||
//! [`abigen`]: ./contract/macro.abigen.html
|
//! [`abigen`]: ./contract/macro.abigen.html
|
||||||
//! [`Abigen` builder]: contract::Abigen
|
//! [`Abigen` builder]: contract::Abigen
|
||||||
//!
|
|
||||||
//! [`utils`]: core::utils
|
//! [`utils`]: core::utils
|
||||||
//! [`abi`]: core::abi
|
//! [`abi`]: core::abi
|
||||||
//! [`types`]: core::types
|
//! [`types`]: core::types
|
||||||
|
|
Loading…
Reference in New Issue