remove provider/signers trait bound
This commit is contained in:
parent
27ca5dd55a
commit
b5a1b27e3a
|
@ -19,7 +19,7 @@ pub type HttpProvider = Provider<Http>;
|
||||||
/// JSON-RPC provider.
|
/// JSON-RPC provider.
|
||||||
pub trait JsonRpcClient: Debug {
|
pub trait JsonRpcClient: Debug {
|
||||||
/// A JSON-RPC Error
|
/// A JSON-RPC Error
|
||||||
type Error: Error;
|
type Error: Error + Into<ProviderError>;
|
||||||
|
|
||||||
/// Sends a request with the provided JSON-RPC and parameters serialized as JSON
|
/// Sends a request with the provided JSON-RPC and parameters serialized as JSON
|
||||||
async fn request<T: Serialize + Send + Sync, R: for<'a> Deserialize<'a>>(
|
async fn request<T: Serialize + Send + Sync, R: for<'a> Deserialize<'a>>(
|
||||||
|
|
|
@ -33,18 +33,18 @@ pub enum ProviderError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON RPC bindings
|
// JSON RPC bindings
|
||||||
impl<P> Provider<P>
|
impl<P: JsonRpcClient> Provider<P> {
|
||||||
where
|
|
||||||
P: JsonRpcClient,
|
|
||||||
ProviderError: From<<P as JsonRpcClient>::Error>,
|
|
||||||
{
|
|
||||||
////// Blockchain Status
|
////// Blockchain Status
|
||||||
//
|
//
|
||||||
// Functions for querying the state of the blockchain
|
// Functions for querying the state of the blockchain
|
||||||
|
|
||||||
/// Gets the latest block number via the `eth_BlockNumber` API
|
/// Gets the latest block number via the `eth_BlockNumber` API
|
||||||
pub async fn get_block_number(&self) -> Result<U256, ProviderError> {
|
pub async fn get_block_number(&self) -> Result<U256, ProviderError> {
|
||||||
Ok(self.0.request("eth_blockNumber", None::<()>).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_blockNumber", None::<()>)
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the block at `block_hash_or_number` (transaction hashes only)
|
/// Gets the block at `block_hash_or_number` (transaction hashes only)
|
||||||
|
@ -78,12 +78,18 @@ where
|
||||||
BlockId::Hash(hash) => {
|
BlockId::Hash(hash) => {
|
||||||
let hash = utils::serialize(&hash);
|
let hash = utils::serialize(&hash);
|
||||||
let args = vec![hash, include_txs];
|
let args = vec![hash, include_txs];
|
||||||
self.0.request("eth_getBlockByHash", Some(args)).await?
|
self.0
|
||||||
|
.request("eth_getBlockByHash", Some(args))
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?
|
||||||
}
|
}
|
||||||
BlockId::Number(num) => {
|
BlockId::Number(num) => {
|
||||||
let num = utils::serialize(&num);
|
let num = utils::serialize(&num);
|
||||||
let args = vec![num, include_txs];
|
let args = vec![num, include_txs];
|
||||||
self.0.request("eth_getBlockByNumber", Some(args)).await?
|
self.0
|
||||||
|
.request("eth_getBlockByNumber", Some(args))
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -97,7 +103,8 @@ where
|
||||||
Ok(self
|
Ok(self
|
||||||
.0
|
.0
|
||||||
.request("eth_getTransactionByHash", Some(hash))
|
.request("eth_getTransactionByHash", Some(hash))
|
||||||
.await?)
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the transaction receipt with `transaction_hash`
|
/// Gets the transaction receipt with `transaction_hash`
|
||||||
|
@ -109,17 +116,26 @@ where
|
||||||
Ok(self
|
Ok(self
|
||||||
.0
|
.0
|
||||||
.request("eth_getTransactionReceipt", Some(hash))
|
.request("eth_getTransactionReceipt", Some(hash))
|
||||||
.await?)
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the current gas price as estimated by the node
|
/// Gets the current gas price as estimated by the node
|
||||||
pub async fn get_gas_price(&self) -> Result<U256, ProviderError> {
|
pub async fn get_gas_price(&self) -> Result<U256, ProviderError> {
|
||||||
Ok(self.0.request("eth_gasPrice", None::<()>).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_gasPrice", None::<()>)
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the accounts on the node
|
/// Gets the accounts on the node
|
||||||
pub async fn get_accounts(&self) -> Result<Vec<Address>, ProviderError> {
|
pub async fn get_accounts(&self) -> Result<Vec<Address>, ProviderError> {
|
||||||
Ok(self.0.request("eth_accounts", None::<()>).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_accounts", None::<()>)
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the nonce of the address
|
/// Returns the nonce of the address
|
||||||
|
@ -133,7 +149,8 @@ where
|
||||||
Ok(self
|
Ok(self
|
||||||
.0
|
.0
|
||||||
.request("eth_getTransactionCount", Some(&[from, block]))
|
.request("eth_getTransactionCount", Some(&[from, block]))
|
||||||
.await?)
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the account's balance
|
/// Returns the account's balance
|
||||||
|
@ -147,13 +164,18 @@ where
|
||||||
Ok(self
|
Ok(self
|
||||||
.0
|
.0
|
||||||
.request("eth_getBalance", Some(&[from, block]))
|
.request("eth_getBalance", Some(&[from, block]))
|
||||||
.await?)
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the currently configured chain id, a value used in replay-protected
|
/// Returns the currently configured chain id, a value used in replay-protected
|
||||||
/// transaction signing as introduced by EIP-155.
|
/// transaction signing as introduced by EIP-155.
|
||||||
pub async fn get_chainid(&self) -> Result<U256, ProviderError> {
|
pub async fn get_chainid(&self) -> Result<U256, ProviderError> {
|
||||||
Ok(self.0.request("eth_chainId", None::<()>).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_chainId", None::<()>)
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
////// Contract Execution
|
////// Contract Execution
|
||||||
|
@ -169,7 +191,11 @@ where
|
||||||
) -> Result<Bytes, ProviderError> {
|
) -> Result<Bytes, ProviderError> {
|
||||||
let tx = utils::serialize(&tx);
|
let tx = utils::serialize(&tx);
|
||||||
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
||||||
Ok(self.0.request("eth_call", Some(vec![tx, block])).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_call", Some(vec![tx, block]))
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a transaction to a single Ethereum node and return the estimated amount of gas required (as a U256) to send it
|
/// Send a transaction to a single Ethereum node and return the estimated amount of gas required (as a U256) to send it
|
||||||
|
@ -187,7 +213,11 @@ where
|
||||||
None => vec![tx],
|
None => vec![tx],
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(self.0.request("eth_estimateGas", Some(args)).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_estimateGas", Some(args))
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the transaction to the entire Ethereum network and returns the transaction's hash
|
/// Send the transaction to the entire Ethereum network and returns the transaction's hash
|
||||||
|
@ -209,21 +239,33 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self.0.request("eth_sendTransaction", Some(tx)).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_sendTransaction", Some(tx))
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the raw RLP encoded transaction to the entire Ethereum network and returns the transaction's hash
|
/// Send the raw RLP encoded transaction to the entire Ethereum network and returns the transaction's hash
|
||||||
/// This will consume gas from the account that signed the transaction.
|
/// This will consume gas from the account that signed the transaction.
|
||||||
pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result<TxHash, ProviderError> {
|
pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result<TxHash, ProviderError> {
|
||||||
let rlp = utils::serialize(&tx.rlp());
|
let rlp = utils::serialize(&tx.rlp());
|
||||||
Ok(self.0.request("eth_sendRawTransaction", Some(rlp)).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_sendRawTransaction", Some(rlp))
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
////// Contract state
|
////// Contract state
|
||||||
|
|
||||||
/// Returns an array (possibly empty) of logs that match the filter
|
/// Returns an array (possibly empty) of logs that match the filter
|
||||||
pub async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, ProviderError> {
|
pub async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, ProviderError> {
|
||||||
Ok(self.0.request("eth_getLogs", Some(filter)).await?)
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_getLogs", Some(filter))
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get_code, get_storage_at
|
// TODO: get_code, get_storage_at
|
||||||
|
|
|
@ -40,8 +40,6 @@ impl<P, S> Client<P, S>
|
||||||
where
|
where
|
||||||
S: Signer,
|
S: Signer,
|
||||||
P: JsonRpcClient,
|
P: JsonRpcClient,
|
||||||
ProviderError: From<<P as JsonRpcClient>::Error>,
|
|
||||||
ClientError: From<<S as Signer>::Error>,
|
|
||||||
{
|
{
|
||||||
/// Signs and broadcasts the transaction
|
/// Signs and broadcasts the transaction
|
||||||
pub async fn send_transaction(
|
pub async fn send_transaction(
|
||||||
|
@ -71,7 +69,7 @@ where
|
||||||
self.fill_transaction(&mut tx, block).await?;
|
self.fill_transaction(&mut tx, block).await?;
|
||||||
|
|
||||||
// sign the transaction with the network
|
// sign the transaction with the network
|
||||||
let signed_tx = signer.sign_transaction(tx)?;
|
let signed_tx = signer.sign_transaction(tx).map_err(Into::into)?;
|
||||||
|
|
||||||
// broadcast it
|
// broadcast it
|
||||||
self.provider.send_raw_transaction(&signed_tx).await?;
|
self.provider.send_raw_transaction(&signed_tx).await?;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::error::Error;
|
||||||
/// Implement this trait to support different signing modes, e.g. Ledger, hosted etc.
|
/// Implement this trait to support different signing modes, e.g. Ledger, hosted etc.
|
||||||
// TODO: We might need a `SignerAsync` trait for HSM use cases?
|
// TODO: We might need a `SignerAsync` trait for HSM use cases?
|
||||||
pub trait Signer {
|
pub trait Signer {
|
||||||
type Error: Error;
|
type Error: Error + Into<ClientError>;
|
||||||
/// Signs the hash of the provided message after prefixing it
|
/// Signs the hash of the provided message after prefixing it
|
||||||
fn sign_message<S: AsRef<[u8]>>(&self, message: S) -> Signature;
|
fn sign_message<S: AsRef<[u8]>>(&self, message: S) -> Signature;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,7 @@ use ethers_providers::{JsonRpcClient, Provider};
|
||||||
use ethers_core::{
|
use ethers_core::{
|
||||||
rand::Rng,
|
rand::Rng,
|
||||||
secp256k1,
|
secp256k1,
|
||||||
types::{
|
types::{Address, PrivateKey, PublicKey, Signature, Transaction, TransactionRequest, TxError},
|
||||||
Address, PrivateKey, PublicKey, Signature, Transaction, TransactionRequest, TxError,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
|
@ -14,7 +14,8 @@ async fn send_eth() {
|
||||||
|
|
||||||
// this private key belongs to the above mnemonic
|
// this private key belongs to the above mnemonic
|
||||||
let wallet: Wallet = "380eb0f3d505f087e438eca80bc4df9a7faa24f868e69fc0440261a0fc0567dc"
|
let wallet: Wallet = "380eb0f3d505f087e438eca80bc4df9a7faa24f868e69fc0440261a0fc0567dc"
|
||||||
.parse().unwrap();
|
.parse()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// connect to the network
|
// connect to the network
|
||||||
let provider = Provider::<Http>::try_from(url.as_str()).unwrap();
|
let provider = Provider::<Http>::try_from(url.as_str()).unwrap();
|
||||||
|
|
Loading…
Reference in New Issue