remove provider/signers trait bound

This commit is contained in:
Georgios Konstantopoulos 2020-06-02 02:00:58 +03:00
parent 27ca5dd55a
commit b5a1b27e3a
No known key found for this signature in database
GPG Key ID: FA607837CD26EDBC
6 changed files with 68 additions and 29 deletions

View File

@ -19,7 +19,7 @@ pub type HttpProvider = Provider<Http>;
/// JSON-RPC provider.
pub trait JsonRpcClient: Debug {
/// 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
async fn request<T: Serialize + Send + Sync, R: for<'a> Deserialize<'a>>(

View File

@ -33,18 +33,18 @@ pub enum ProviderError {
}
// JSON RPC bindings
impl<P> Provider<P>
where
P: JsonRpcClient,
ProviderError: From<<P as JsonRpcClient>::Error>,
{
impl<P: JsonRpcClient> Provider<P> {
////// Blockchain Status
//
// Functions for querying the state of the blockchain
/// Gets the latest block number via the `eth_BlockNumber` API
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)
@ -78,12 +78,18 @@ where
BlockId::Hash(hash) => {
let hash = utils::serialize(&hash);
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) => {
let num = utils::serialize(&num);
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
.0
.request("eth_getTransactionByHash", Some(hash))
.await?)
.await
.map_err(Into::into)?)
}
/// Gets the transaction receipt with `transaction_hash`
@ -109,17 +116,26 @@ where
Ok(self
.0
.request("eth_getTransactionReceipt", Some(hash))
.await?)
.await
.map_err(Into::into)?)
}
/// Gets the current gas price as estimated by the node
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
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
@ -133,7 +149,8 @@ where
Ok(self
.0
.request("eth_getTransactionCount", Some(&[from, block]))
.await?)
.await
.map_err(Into::into)?)
}
/// Returns the account's balance
@ -147,13 +164,18 @@ where
Ok(self
.0
.request("eth_getBalance", Some(&[from, block]))
.await?)
.await
.map_err(Into::into)?)
}
/// Returns the currently configured chain id, a value used in replay-protected
/// transaction signing as introduced by EIP-155.
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
@ -169,7 +191,11 @@ where
) -> Result<Bytes, ProviderError> {
let tx = utils::serialize(&tx);
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
@ -187,7 +213,11 @@ where
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
@ -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
/// This will consume gas from the account that signed the transaction.
pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result<TxHash, ProviderError> {
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
/// Returns an array (possibly empty) of logs that match the filter
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

View File

@ -40,8 +40,6 @@ impl<P, S> Client<P, S>
where
S: Signer,
P: JsonRpcClient,
ProviderError: From<<P as JsonRpcClient>::Error>,
ClientError: From<<S as Signer>::Error>,
{
/// Signs and broadcasts the transaction
pub async fn send_transaction(
@ -71,7 +69,7 @@ where
self.fill_transaction(&mut tx, block).await?;
// 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
self.provider.send_raw_transaction(&signed_tx).await?;

View File

@ -13,7 +13,7 @@ use std::error::Error;
/// Implement this trait to support different signing modes, e.g. Ledger, hosted etc.
// TODO: We might need a `SignerAsync` trait for HSM use cases?
pub trait Signer {
type Error: Error;
type Error: Error + Into<ClientError>;
/// Signs the hash of the provided message after prefixing it
fn sign_message<S: AsRef<[u8]>>(&self, message: S) -> Signature;

View File

@ -5,9 +5,7 @@ use ethers_providers::{JsonRpcClient, Provider};
use ethers_core::{
rand::Rng,
secp256k1,
types::{
Address, PrivateKey, PublicKey, Signature, Transaction, TransactionRequest, TxError,
},
types::{Address, PrivateKey, PublicKey, Signature, Transaction, TransactionRequest, TxError},
};
use std::str::FromStr;

View File

@ -14,7 +14,8 @@ async fn send_eth() {
// this private key belongs to the above mnemonic
let wallet: Wallet = "380eb0f3d505f087e438eca80bc4df9a7faa24f868e69fc0440261a0fc0567dc"
.parse().unwrap();
.parse()
.unwrap();
// connect to the network
let provider = Provider::<Http>::try_from(url.as_str()).unwrap();