feat: allow querying logs with their respective tx hashes
This commit is contained in:
parent
c71c46ff56
commit
095be63b3b
|
@ -7,7 +7,7 @@ use ethers_core::{
|
||||||
types::{BlockNumber, Filter, ValueOrArray, H256},
|
types::{BlockNumber, Filter, ValueOrArray, H256},
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::{collections::HashMap, marker::PhantomData};
|
||||||
|
|
||||||
pub struct Event<'a, 'b, P, N, D> {
|
pub struct Event<'a, 'b, P, N, D> {
|
||||||
pub filter: Filter,
|
pub filter: Filter,
|
||||||
|
@ -34,16 +34,27 @@ impl<'a, 'b, P, N, D: Detokenize> Event<'a, 'b, P, N, D> {
|
||||||
self.filter.topics[0] = Some(topic.into());
|
self.filter.topics[0] = Some(topic.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn topic1<T: Into<ValueOrArray<H256>>>(mut self, topic: T) -> Self {
|
||||||
|
self.filter.topics[1] = Some(topic.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Can we get rid of the static?
|
// TODO: Can we get rid of the static?
|
||||||
impl<'a, 'b, P: JsonRpcClient, N: Network, D: Detokenize> Event<'a, 'b, P, N, D>
|
impl<'a, 'b, P: JsonRpcClient, N: Network, D: Detokenize + Clone> Event<'a, 'b, P, N, D>
|
||||||
where
|
where
|
||||||
P::Error: 'static,
|
P::Error: 'static,
|
||||||
{
|
{
|
||||||
/// Queries the blockchain for the selected filter and returns a vector of matching
|
/// Queries the blockchain for the selected filter and returns a vector of matching
|
||||||
/// event logs
|
/// event logs
|
||||||
pub async fn query(self) -> Result<Vec<D>, ContractError<P>> {
|
pub async fn query(self) -> Result<Vec<D>, ContractError<P>> {
|
||||||
|
Ok(self.query_with_hashes().await?.values().cloned().collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Queries the blockchain for the selected filter and returns a vector of matching
|
||||||
|
/// event logs
|
||||||
|
pub async fn query_with_hashes(self) -> Result<HashMap<H256, D>, ContractError<P>> {
|
||||||
// get the logs
|
// get the logs
|
||||||
let logs = self
|
let logs = self
|
||||||
.provider
|
.provider
|
||||||
|
@ -68,9 +79,12 @@ where
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// convert the tokens to the requested datatype
|
// convert the tokens to the requested datatype
|
||||||
Ok::<_, ContractError<P>>(D::from_tokens(tokens)?)
|
Ok::<_, ContractError<P>>((
|
||||||
|
log.transaction_hash.expect("should have tx hash"),
|
||||||
|
D::from_tokens(tokens)?,
|
||||||
|
))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<HashMap<H256, D>, _>>()?;
|
||||||
|
|
||||||
Ok(events)
|
Ok(events)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
mod http;
|
pub mod http;
|
||||||
mod provider;
|
mod provider;
|
||||||
|
|
||||||
pub mod networks;
|
pub mod networks;
|
||||||
|
|
|
@ -123,6 +123,12 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
self.0.request("eth_getBalance", Some(&[from, block])).await
|
self.0.request("eth_getBalance", Some(&[from, block])).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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, P::Error> {
|
||||||
|
self.0.request("eth_chainId", None::<()>).await
|
||||||
|
}
|
||||||
|
|
||||||
////// Contract Execution
|
////// Contract Execution
|
||||||
//
|
//
|
||||||
// These are relatively low-level calls. The Contracts API should usually be used instead.
|
// These are relatively low-level calls. The Contracts API should usually be used instead.
|
||||||
|
|
|
@ -106,6 +106,11 @@ where
|
||||||
pub fn provider(&self) -> &Provider<P, N> {
|
pub fn provider(&self) -> &Provider<P, N> {
|
||||||
self.provider
|
self.provider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the client's signer, will panic if no signer is set
|
||||||
|
pub fn signer_unchecked(&self) -> &S {
|
||||||
|
self.signer.as_ref().expect("no signer is configured")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abuse Deref to use the Provider's methods without re-writing everything.
|
// Abuse Deref to use the Provider's methods without re-writing everything.
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// TODO: We might need a `SignerAsync` trait for HSM use cases?
|
|
||||||
mod wallet;
|
mod wallet;
|
||||||
pub use wallet::Wallet;
|
pub use wallet::Wallet;
|
||||||
|
|
||||||
|
@ -11,6 +10,7 @@ use std::error::Error;
|
||||||
/// Trait for signing transactions and messages
|
/// Trait for signing transactions and messages
|
||||||
///
|
///
|
||||||
/// 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?
|
||||||
pub trait Signer {
|
pub trait Signer {
|
||||||
type Error: Error;
|
type Error: Error;
|
||||||
/// Signs the hash of the provided message after prefixing it
|
/// Signs the hash of the provided message after prefixing it
|
||||||
|
@ -31,3 +31,6 @@ pub type MainnetWallet = Wallet<Mainnet>;
|
||||||
/// A wallet which does not use EIP-155 and does not take the chain id into account
|
/// A wallet which does not use EIP-155 and does not take the chain id into account
|
||||||
/// when creating transactions
|
/// when creating transactions
|
||||||
pub type AnyWallet = Wallet<Any>;
|
pub type AnyWallet = Wallet<Any>;
|
||||||
|
|
||||||
|
/// An HTTP client configured to work with ANY blockchain without replay protection
|
||||||
|
pub type HttpClient<'a> = Client<'a, ethers_providers::http::Provider, Any, Wallet<Any>>;
|
||||||
|
|
|
@ -53,7 +53,11 @@ async fn main() -> Result<()> {
|
||||||
let _tx_hash = contract.set_value("hi".to_owned()).send().await?;
|
let _tx_hash = contract.set_value("hi".to_owned()).send().await?;
|
||||||
|
|
||||||
// 11. get all events
|
// 11. get all events
|
||||||
let logs = contract.value_changed_filter().from_block(0u64).query().await?;
|
let logs = contract
|
||||||
|
.value_changed_filter()
|
||||||
|
.from_block(0u64)
|
||||||
|
.query()
|
||||||
|
.await?;
|
||||||
|
|
||||||
// 12. get the new value
|
// 12. get the new value
|
||||||
let value = contract.get_value().call().await?;
|
let value = contract.get_value().call().await?;
|
||||||
|
|
|
@ -151,7 +151,7 @@ pub mod signers {
|
||||||
///
|
///
|
||||||
/// let message = "Some data";
|
/// let message = "Some data";
|
||||||
/// let key = PrivateKey::new(&mut rand::thread_rng());
|
/// let key = PrivateKey::new(&mut rand::thread_rng());
|
||||||
/// let address = Address::from(key);
|
/// let address = Address::from(&key);
|
||||||
///
|
///
|
||||||
/// // Sign the message
|
/// // Sign the message
|
||||||
/// let signature = key.sign(message);
|
/// let signature = key.sign(message);
|
||||||
|
|
Loading…
Reference in New Issue