refactor: use fully qualified syntax during abigen
This commit is contained in:
parent
855fd2deb2
commit
cf29488aae
|
@ -79,15 +79,14 @@ impl Context {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
mod #name_mod {
|
||||
#imports
|
||||
|
||||
#struct_decl
|
||||
|
||||
impl<'a, M: Middleware> #name<M> {
|
||||
impl<'a, M: ethers_providers::Middleware> #name<M> {
|
||||
/// Creates a new contract instance with the specified `ethers`
|
||||
/// client at the given `Address`. The contract derefs to a `ethers::Contract`
|
||||
/// object
|
||||
pub fn new<T: Into<Address>>(address: T, client: Arc<M>) -> Self {
|
||||
let contract = Contract::new(address.into(), #abi_name.clone(), client);
|
||||
pub fn new<T: Into<ethers_core::types::Address>>(address: T, client: ::std::sync::Arc<M>) -> Self {
|
||||
let contract = ethers_contract::Contract::new(address.into(), #abi_name.clone(), client);
|
||||
Self(contract)
|
||||
}
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@ pub(crate) fn struct_declaration(cx: &Context, abi_name: &proc_macro2::Ident) ->
|
|||
|
||||
let abi_parse = if !cx.human_readable {
|
||||
quote! {
|
||||
pub static #abi_name: Lazy<Abi> = Lazy::new(|| serde_json::from_str(#abi)
|
||||
pub static #abi_name: ethers_contract::Lazy<ethers_core::abi::Abi> = ethers_contract::Lazy::new(|| serde_json::from_str(#abi)
|
||||
.expect("invalid abi"));
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
pub static #abi_name: Lazy<Abi> = Lazy::new(|| ethers::core::abi::parse_abi_str(#abi)
|
||||
pub static #abi_name: ethers_contract::Lazy<ethers_core::abi::Abi> = ethers_contract::Lazy::new(|| ethers::core::abi::parse_abi_str(#abi)
|
||||
.expect("invalid abi"));
|
||||
}
|
||||
};
|
||||
|
@ -47,17 +47,17 @@ pub(crate) fn struct_declaration(cx: &Context, abi_name: &proc_macro2::Ident) ->
|
|||
|
||||
// Struct declaration
|
||||
#[derive(Clone)]
|
||||
pub struct #name<M>(Contract<M>);
|
||||
pub struct #name<M>(ethers_contract::Contract<M>);
|
||||
|
||||
|
||||
// Deref to the inner contract in order to access more specific functions functions
|
||||
impl<M> std::ops::Deref for #name<M> {
|
||||
type Target = Contract<M>;
|
||||
type Target = ethers_contract::Contract<M>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl<M: Middleware> std::fmt::Debug for #name<M> {
|
||||
impl<M: ethers_providers::Middleware> std::fmt::Debug for #name<M> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.debug_tuple(stringify!(#name))
|
||||
.field(&self.address())
|
||||
|
|
|
@ -63,19 +63,19 @@ impl Context {
|
|||
#(#variants(#variants)),*
|
||||
}
|
||||
|
||||
impl ethers::abi::Tokenizable for #enum_name {
|
||||
impl ethers_core::abi::Tokenizable for #enum_name {
|
||||
|
||||
fn from_token(token: ethers::abi::Token) -> Result<Self, ethers::abi::InvalidOutputType> where
|
||||
fn from_token(token: ethers_core::abi::Token) -> Result<Self, ethers_core::abi::InvalidOutputType> where
|
||||
Self: Sized {
|
||||
#(
|
||||
if let Ok(decoded) = #variants::from_token(token.clone()) {
|
||||
return Ok(#enum_name::#variants(decoded))
|
||||
}
|
||||
)*
|
||||
Err(ethers::abi::InvalidOutputType("Failed to decode all event variants".to_string()))
|
||||
Err(ethers_core::abi::InvalidOutputType("Failed to decode all event variants".to_string()))
|
||||
}
|
||||
|
||||
fn into_token(self) -> ethers::abi::Token {
|
||||
fn into_token(self) -> ethers_core::abi::Token {
|
||||
match self {
|
||||
#(
|
||||
#enum_name::#variants(element) => element.into_token()
|
||||
|
@ -83,10 +83,10 @@ impl Context {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl ethers::abi::TokenizableItem for #enum_name { }
|
||||
impl ethers_core::abi::TokenizableItem for #enum_name { }
|
||||
|
||||
impl ethers::contract::EthLogDecode for #enum_name {
|
||||
fn decode_log(log: ðers::abi::RawLog) -> Result<Self, ethers::abi::Error>
|
||||
impl ethers_contract::EthLogDecode for #enum_name {
|
||||
fn decode_log(log: ðers_core::abi::RawLog) -> Result<Self, ethers_core::abi::Error>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ impl Context {
|
|||
return Ok(#enum_name::#variants(decoded))
|
||||
}
|
||||
)*
|
||||
Err(ethers::abi::Error::InvalidData)
|
||||
Err(ethers_core::abi::Error::InvalidData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ impl Context {
|
|||
return Ok(quote! {::std::vec::Vec<#ty>});
|
||||
}
|
||||
}
|
||||
quote! { H256 }
|
||||
quote! { ethers_core::types::H256 }
|
||||
}
|
||||
(ParamType::FixedArray(ty, size), true) => {
|
||||
if let ParamType::Tuple(..) = **ty {
|
||||
|
@ -162,7 +162,7 @@ impl Context {
|
|||
return Ok(quote! {[#ty; #size]});
|
||||
}
|
||||
}
|
||||
quote! { H256 }
|
||||
quote! { ethers_core::types::H256 }
|
||||
}
|
||||
(ParamType::Tuple(..), true) => {
|
||||
// represents an struct
|
||||
|
@ -175,11 +175,11 @@ impl Context {
|
|||
{
|
||||
quote! {#ty}
|
||||
} else {
|
||||
quote! { H256 }
|
||||
quote! { ethers_core::types::H256 }
|
||||
}
|
||||
}
|
||||
(ParamType::Bytes, true) | (ParamType::String, true) => {
|
||||
quote! { H256 }
|
||||
quote! { ethers_core::types::H256 }
|
||||
}
|
||||
(kind, _) => types::expand(kind)?,
|
||||
})
|
||||
|
@ -213,7 +213,7 @@ impl Context {
|
|||
let doc = util::expand_doc(&format!("Gets the contract's `{}` event", event.name));
|
||||
quote! {
|
||||
#doc
|
||||
pub fn #name(&self) -> Event<M, #result> {
|
||||
pub fn #name(&self) -> ethers_contract::builders::Event<M, #result> {
|
||||
self.0.event(#ev_name).expect("event not found (this should never happen)")
|
||||
}
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ impl Context {
|
|||
let event_abi_name = &event.name;
|
||||
|
||||
Ok(quote! {
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, ethers::contract::EthEvent, #derives)]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, ethers_contract::EthEvent, #derives)]
|
||||
#[ethevent( name = #event_abi_name, abi = #abi_signature )]
|
||||
pub #data_type_definition
|
||||
})
|
||||
|
@ -335,7 +335,7 @@ fn expand_hash(hash: Hash) -> TokenStream {
|
|||
let bytes = hash.as_bytes().iter().copied().map(Literal::u8_unsuffixed);
|
||||
|
||||
quote! {
|
||||
H256([#( #bytes ),*])
|
||||
ethers_core::types::H256([#( #bytes ),*])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,7 +452,7 @@ mod tests {
|
|||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f".parse().unwrap()
|
||||
),
|
||||
{
|
||||
H256([
|
||||
ethers_core::types::H256([
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
|
||||
])
|
||||
|
|
|
@ -39,7 +39,7 @@ fn expand_function(function: &Function, alias: Option<Ident>) -> Result<TokenStr
|
|||
|
||||
let outputs = expand_fn_outputs(&function.outputs)?;
|
||||
|
||||
let result = quote! { ContractCall<M, #outputs> };
|
||||
let result = quote! { ethers_contract::builders::ContractCall<M, #outputs> };
|
||||
|
||||
let arg = expand_inputs_call_arg(&function.inputs);
|
||||
let doc = util::expand_doc(&format!(
|
||||
|
|
|
@ -5,7 +5,7 @@ use quote::quote;
|
|||
|
||||
pub(crate) fn expand(kind: &ParamType) -> Result<TokenStream> {
|
||||
match kind {
|
||||
ParamType::Address => Ok(quote! { Address }),
|
||||
ParamType::Address => Ok(quote! { ethers_core::types::Address }),
|
||||
ParamType::Bytes => Ok(quote! { Vec<u8> }),
|
||||
ParamType::Int(n) => match n / 8 {
|
||||
1 => Ok(quote! { i8 }),
|
||||
|
@ -22,7 +22,7 @@ pub(crate) fn expand(kind: &ParamType) -> Result<TokenStream> {
|
|||
3..=4 => Ok(quote! { u32 }),
|
||||
5..=8 => Ok(quote! { u64 }),
|
||||
9..=16 => Ok(quote! { u128 }),
|
||||
17..=32 => Ok(quote! { U256 }),
|
||||
17..=32 => Ok(quote! { ethers_core::types::U256 }),
|
||||
_ => Err(anyhow!("unsupported solidity type uint{}", n)),
|
||||
},
|
||||
ParamType::Bool => Ok(quote! { bool }),
|
||||
|
|
|
@ -206,13 +206,13 @@ pub fn derive_abi_event(input: TokenStream) -> TokenStream {
|
|||
let anon = attributes.anonymous.map(|(b, _)| b).unwrap_or_default();
|
||||
|
||||
let ethevent_impl = quote! {
|
||||
impl ethers::contract::EthEvent for #name {
|
||||
impl ethers_contract::EthEvent for #name {
|
||||
|
||||
fn name() -> ::std::borrow::Cow<'static, str> {
|
||||
#event_name.into()
|
||||
}
|
||||
|
||||
fn signature() -> ethers::types::H256 {
|
||||
fn signature() -> ethers_core::types::H256 {
|
||||
#signature
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,7 @@ pub fn derive_abi_event(input: TokenStream) -> TokenStream {
|
|||
#abi.into()
|
||||
}
|
||||
|
||||
fn decode_log(log: ðers::abi::RawLog) -> Result<Self, ethers::abi::Error> where Self: Sized {
|
||||
fn decode_log(log: ðers_core::abi::RawLog) -> Result<Self, ethers_core::abi::Error> where Self: Sized {
|
||||
#decode_log_impl
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ fn topic_param_type_quote(kind: &ParamType) -> proc_macro2::TokenStream {
|
|||
| ParamType::Bytes
|
||||
| ParamType::Array(_)
|
||||
| ParamType::FixedArray(_, _)
|
||||
| ParamType::Tuple(_) => quote! {ethers::abi::ParamType::FixedBytes(32)},
|
||||
| ParamType::Tuple(_) => quote! {ethers_core::abi::ParamType::FixedBytes(32)},
|
||||
ty => param_type_quote(ty),
|
||||
}
|
||||
}
|
||||
|
@ -269,42 +269,42 @@ fn topic_param_type_quote(kind: &ParamType) -> proc_macro2::TokenStream {
|
|||
fn param_type_quote(kind: &ParamType) -> proc_macro2::TokenStream {
|
||||
match kind {
|
||||
ParamType::Address => {
|
||||
quote! {ethers::abi::ParamType::Address}
|
||||
quote! {ethers_core::abi::ParamType::Address}
|
||||
}
|
||||
ParamType::Bytes => {
|
||||
quote! {ethers::abi::ParamType::Bytes}
|
||||
quote! {ethers_core::abi::ParamType::Bytes}
|
||||
}
|
||||
ParamType::Int(size) => {
|
||||
let size = Literal::usize_suffixed(*size);
|
||||
quote! {ethers::abi::ParamType::Int(#size)}
|
||||
quote! {ethers_core::abi::ParamType::Int(#size)}
|
||||
}
|
||||
ParamType::Uint(size) => {
|
||||
let size = Literal::usize_suffixed(*size);
|
||||
quote! {ethers::abi::ParamType::Uint(#size)}
|
||||
quote! {ethers_core::abi::ParamType::Uint(#size)}
|
||||
}
|
||||
ParamType::Bool => {
|
||||
quote! {ethers::abi::ParamType::Bool}
|
||||
quote! {ethers_core::abi::ParamType::Bool}
|
||||
}
|
||||
ParamType::String => {
|
||||
quote! {ethers::abi::ParamType::String}
|
||||
quote! {ethers_core::abi::ParamType::String}
|
||||
}
|
||||
ParamType::Array(ty) => {
|
||||
let ty = param_type_quote(&*ty);
|
||||
quote! {ethers::abi::ParamType::Array(Box::new(#ty))}
|
||||
quote! {ethers_core::abi::ParamType::Array(Box::new(#ty))}
|
||||
}
|
||||
ParamType::FixedBytes(size) => {
|
||||
let size = Literal::usize_suffixed(*size);
|
||||
quote! {ethers::abi::ParamType::FixedBytes(#size)}
|
||||
quote! {ethers_core::abi::ParamType::FixedBytes(#size)}
|
||||
}
|
||||
ParamType::FixedArray(ty, size) => {
|
||||
let ty = param_type_quote(&*ty);
|
||||
let size = Literal::usize_suffixed(*size);
|
||||
quote! {ethers::abi::ParamType::FixedArray(Box::new(#ty),#size)}
|
||||
quote! {ethers_core::abi::ParamType::FixedArray(Box::new(#ty),#size)}
|
||||
}
|
||||
ParamType::Tuple(tuple) => {
|
||||
let elements = tuple.iter().map(param_type_quote);
|
||||
quote! {
|
||||
ethers::abi::ParamType::Tuple(
|
||||
ethers_core::abi::ParamType::Tuple(
|
||||
vec![
|
||||
#( #elements ),*
|
||||
]
|
||||
|
@ -424,16 +424,16 @@ fn derive_decode_from_log_impl(
|
|||
},
|
||||
quote! {
|
||||
if topic_tokens.len() != topics.len() {
|
||||
return Err(ethers::abi::Error::InvalidData);
|
||||
return Err(ethers_core::abi::Error::InvalidData);
|
||||
}
|
||||
},
|
||||
)
|
||||
} else {
|
||||
(
|
||||
quote! {
|
||||
let event_signature = topics.get(0).ok_or(ethers::abi::Error::InvalidData)?;
|
||||
let event_signature = topics.get(0).ok_or(ethers_core::abi::Error::InvalidData)?;
|
||||
if event_signature != &Self::signature() {
|
||||
return Err(ethers::abi::Error::InvalidData);
|
||||
return Err(ethers_core::abi::Error::InvalidData);
|
||||
}
|
||||
},
|
||||
quote! {
|
||||
|
@ -441,7 +441,7 @@ fn derive_decode_from_log_impl(
|
|||
},
|
||||
quote! {
|
||||
if topic_tokens.is_empty() || topic_tokens.len() != topics.len() - 1 {
|
||||
return Err(ethers::abi::Error::InvalidData);
|
||||
return Err(ethers_core::abi::Error::InvalidData);
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -455,9 +455,9 @@ fn derive_decode_from_log_impl(
|
|||
.all(|(idx, f)| f.index == idx)
|
||||
{
|
||||
quote! {
|
||||
let topic_tokens = ethers::abi::decode(&topic_types, &flat_topics)?;
|
||||
let topic_tokens = ethers_core::abi::decode(&topic_types, &flat_topics)?;
|
||||
#topic_tokens_len_check
|
||||
let data_tokens = ethers::abi::decode(&data_types, &data)?;
|
||||
let data_tokens = ethers_core::abi::decode(&data_types, &data)?;
|
||||
let tokens:Vec<_> = topic_tokens.into_iter().chain(data_tokens.into_iter()).collect();
|
||||
}
|
||||
} else {
|
||||
|
@ -470,9 +470,9 @@ fn derive_decode_from_log_impl(
|
|||
});
|
||||
|
||||
quote! {
|
||||
let mut topic_tokens = ethers::abi::decode(&topic_types, &flat_topics)?;
|
||||
let mut topic_tokens = ethers_core::abi::decode(&topic_types, &flat_topics)?;
|
||||
#topic_tokens_len_check
|
||||
let mut data_tokens = ethers::abi::decode(&data_types, &data)?;
|
||||
let mut data_tokens = ethers_core::abi::decode(&data_types, &data)?;
|
||||
let mut tokens = Vec::with_capacity(topics.len() + data_tokens.len());
|
||||
#( tokens.push(#swap_tokens); )*
|
||||
}
|
||||
|
@ -480,7 +480,7 @@ fn derive_decode_from_log_impl(
|
|||
|
||||
Ok(quote! {
|
||||
|
||||
let ethers::abi::RawLog {data, topics} = log;
|
||||
let ethers_core::abi::RawLog {data, topics} = log;
|
||||
|
||||
#signature_check
|
||||
|
||||
|
@ -491,7 +491,7 @@ fn derive_decode_from_log_impl(
|
|||
|
||||
#tokens_init
|
||||
|
||||
ethers::abi::Detokenize::from_tokens(tokens).map_err(|_|ethers::abi::Error::InvalidData)
|
||||
ethers_core::abi::Detokenize::from_tokens(tokens).map_err(|_|ethers_core::abi::Error::InvalidData)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -678,7 +678,7 @@ fn parse_int_param_type(s: &str) -> Option<ParamType> {
|
|||
|
||||
fn signature(hash: &[u8]) -> proc_macro2::TokenStream {
|
||||
let bytes = hash.iter().copied().map(Literal::u8_unsuffixed);
|
||||
quote! {ethers::types::H256([#( #bytes ),*])}
|
||||
quote! {ethers_core::types::H256([#( #bytes ),*])}
|
||||
}
|
||||
|
||||
fn parse_event(abi: &str) -> Result<Event, String> {
|
||||
|
@ -727,13 +727,13 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
|||
Fields::Named(ref fields) => {
|
||||
let tokenize_predicates = fields.named.iter().map(|f| {
|
||||
let ty = &f.ty;
|
||||
quote_spanned! { f.span() => #ty: ethers::abi::Tokenize }
|
||||
quote_spanned! { f.span() => #ty: ethers_core::abi::Tokenize }
|
||||
});
|
||||
let tokenize_predicates = quote! { #(#tokenize_predicates,)* };
|
||||
|
||||
let assignments = fields.named.iter().map(|f| {
|
||||
let name = f.ident.as_ref().expect("Named fields have names");
|
||||
quote_spanned! { f.span() => #name: ethers::abi::Tokenizable::from_token(iter.next().expect("tokens size is sufficient qed").into_token())? }
|
||||
quote_spanned! { f.span() => #name: ethers_core::abi::Tokenizable::from_token(iter.next().expect("tokens size is sufficient qed").into_token())? }
|
||||
});
|
||||
let init_struct_impl = quote! { Self { #(#assignments,)* } };
|
||||
|
||||
|
@ -753,12 +753,12 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
|||
Fields::Unnamed(ref fields) => {
|
||||
let tokenize_predicates = fields.unnamed.iter().map(|f| {
|
||||
let ty = &f.ty;
|
||||
quote_spanned! { f.span() => #ty: ethers::abi::Tokenize }
|
||||
quote_spanned! { f.span() => #ty: ethers_core::abi::Tokenize }
|
||||
});
|
||||
let tokenize_predicates = quote! { #(#tokenize_predicates,)* };
|
||||
|
||||
let assignments = fields.unnamed.iter().map(|f| {
|
||||
quote_spanned! { f.span() => ethers::abi::Tokenizable::from_token(iter.next().expect("tokens size is sufficient qed").into_token())? }
|
||||
quote_spanned! { f.span() => ethers_core::abi::Tokenizable::from_token(iter.next().expect("tokens size is sufficient qed").into_token())? }
|
||||
});
|
||||
let init_struct_impl = quote! { Self(#(#assignments,)* ) };
|
||||
|
||||
|
@ -794,17 +794,17 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
|||
};
|
||||
|
||||
quote! {
|
||||
impl<#generic_params> ethers::abi::Tokenizable for #name<#generic_args>
|
||||
impl<#generic_params> ethers_core::abi::Tokenizable for #name<#generic_args>
|
||||
where
|
||||
#generic_predicates
|
||||
#tokenize_predicates
|
||||
{
|
||||
|
||||
fn from_token(token: ethers::abi::Token) -> Result<Self, ethers::abi::InvalidOutputType> where
|
||||
fn from_token(token: ethers_core::abi::Token) -> Result<Self, ethers_core::abi::InvalidOutputType> where
|
||||
Self: Sized {
|
||||
if let ethers::abi::Token::Tuple(tokens) = token {
|
||||
if let ethers_core::abi::Token::Tuple(tokens) = token {
|
||||
if tokens.len() != #params_len {
|
||||
return Err(ethers::abi::InvalidOutputType(format!(
|
||||
return Err(ethers_core::abi::InvalidOutputType(format!(
|
||||
"Expected {} tokens, got {}: {:?}",
|
||||
#params_len,
|
||||
tokens.len(),
|
||||
|
@ -816,15 +816,15 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
|||
|
||||
Ok(#init_struct_impl)
|
||||
} else {
|
||||
Err(ethers::abi::InvalidOutputType(format!(
|
||||
Err(ethers_core::abi::InvalidOutputType(format!(
|
||||
"Expected Tuple, got {:?}",
|
||||
token
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
fn into_token(self) -> ethers::abi::Token {
|
||||
ethers::abi::Token::Tuple(
|
||||
fn into_token(self) -> ethers_core::abi::Token {
|
||||
ethers_core::abi::Token::Tuple(
|
||||
vec![
|
||||
#into_token_impl
|
||||
]
|
||||
|
@ -832,7 +832,7 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
impl<#generic_params> ethers::abi::TokenizableItem for #name<#generic_args>
|
||||
impl<#generic_params> ethers_core::abi::TokenizableItem for #name<#generic_args>
|
||||
where
|
||||
#generic_predicates
|
||||
#tokenize_predicates
|
||||
|
|
|
@ -180,6 +180,7 @@ impl<M: Middleware> Contract<M> {
|
|||
}
|
||||
|
||||
/// Returns an [`Event`](crate::builders::Event) builder for the provided event name.
|
||||
/// TODO(mattsse) keep this but remove event
|
||||
pub fn event<D: Detokenize>(&self, name: &str) -> Result<Event<M, D>, Error> {
|
||||
// get the event's full name
|
||||
let event = self.base_contract.abi.event(name)?;
|
||||
|
|
|
@ -29,6 +29,19 @@ pub trait EthEvent: Detokenize {
|
|||
|
||||
/// Returns true if this is an anonymous event
|
||||
fn is_anonymous() -> bool;
|
||||
|
||||
/// Returns an Event builder for the ethereum event represented by this types ABI signature.
|
||||
fn new<M: Middleware>(filter: Filter, provider: &M) -> Event2<M, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let filter = filter.event(&Self::abi_signature());
|
||||
Event2 {
|
||||
filter,
|
||||
provider,
|
||||
datatype: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience implementation
|
||||
|
@ -41,6 +54,167 @@ impl<T: EthEvent> EthLogDecode for T {
|
|||
}
|
||||
}
|
||||
|
||||
/// Helper for managing the event filter before querying or streaming its logs
|
||||
#[derive(Debug)]
|
||||
#[must_use = "event filters do nothing unless you `query` or `stream` them"]
|
||||
pub struct Event2<'a, M, D> {
|
||||
/// The event filter's state
|
||||
pub filter: Filter,
|
||||
pub(crate) provider: &'a M,
|
||||
/// Stores the event datatype
|
||||
pub(crate) datatype: PhantomData<D>,
|
||||
}
|
||||
|
||||
// TODO: Improve these functions
|
||||
impl<M, D: EthLogDecode> Event2<'_, M, D> {
|
||||
/// Sets the filter's `from` block
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn from_block<T: Into<BlockNumber>>(mut self, block: T) -> Self {
|
||||
self.filter = self.filter.from_block(block);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the filter's `to` block
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn to_block<T: Into<BlockNumber>>(mut self, block: T) -> Self {
|
||||
self.filter = self.filter.to_block(block);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the filter's `blockHash`. Setting this will override previously
|
||||
/// set `from_block` and `to_block` fields.
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn at_block_hash<T: Into<H256>>(mut self, hash: T) -> Self {
|
||||
self.filter = self.filter.at_block_hash(hash);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the filter's 0th topic (typically the event name for non-anonymous events)
|
||||
pub fn topic0<T: Into<ValueOrArray<H256>>>(mut self, topic: T) -> Self {
|
||||
self.filter.topics[0] = Some(topic.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the filter's 1st topic
|
||||
pub fn topic1<T: Into<ValueOrArray<H256>>>(mut self, topic: T) -> Self {
|
||||
self.filter.topics[1] = Some(topic.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the filter's 2nd topic
|
||||
pub fn topic2<T: Into<ValueOrArray<H256>>>(mut self, topic: T) -> Self {
|
||||
self.filter.topics[2] = Some(topic.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the filter's 3rd topic
|
||||
pub fn topic3<T: Into<ValueOrArray<H256>>>(mut self, topic: T) -> Self {
|
||||
self.filter.topics[3] = Some(topic.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, M, D> Event2<'a, M, D>
|
||||
where
|
||||
M: Middleware,
|
||||
D: EthLogDecode,
|
||||
{
|
||||
/// Returns a stream for the event
|
||||
pub async fn stream(
|
||||
&'a self,
|
||||
) -> Result<
|
||||
// Wraps the FilterWatcher with a mapping to the event
|
||||
EventStream<'a, FilterWatcher<'a, M::Provider, Log>, D, ContractError<M>>,
|
||||
ContractError<M>,
|
||||
> {
|
||||
let filter = self
|
||||
.provider
|
||||
.watch(&self.filter)
|
||||
.await
|
||||
.map_err(ContractError::MiddlewareError)?;
|
||||
Ok(EventStream::new(
|
||||
filter.id,
|
||||
filter,
|
||||
Box::new(move |log| self.parse_log(log)),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, M, D> Event2<'a, M, D>
|
||||
where
|
||||
M: Middleware,
|
||||
<M as Middleware>::Provider: PubsubClient,
|
||||
D: EthLogDecode,
|
||||
{
|
||||
/// Returns a subscription for the event
|
||||
pub async fn subscribe(
|
||||
&'a self,
|
||||
) -> Result<
|
||||
// Wraps the SubscriptionStream with a mapping to the event
|
||||
EventStream<'a, SubscriptionStream<'a, M::Provider, Log>, D, ContractError<M>>,
|
||||
ContractError<M>,
|
||||
> {
|
||||
let filter = self
|
||||
.provider
|
||||
.subscribe_logs(&self.filter)
|
||||
.await
|
||||
.map_err(ContractError::MiddlewareError)?;
|
||||
Ok(EventStream::new(
|
||||
filter.id,
|
||||
filter,
|
||||
Box::new(move |log| self.parse_log(log)),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<M, D> Event2<'_, M, D>
|
||||
where
|
||||
M: Middleware,
|
||||
D: EthLogDecode,
|
||||
{
|
||||
/// Queries the blockchain for the selected filter and returns a vector of matching
|
||||
/// event logs
|
||||
pub async fn query(&self) -> Result<Vec<D>, ContractError<M>> {
|
||||
let logs = self
|
||||
.provider
|
||||
.get_logs(&self.filter)
|
||||
.await
|
||||
.map_err(ContractError::MiddlewareError)?;
|
||||
let events = logs
|
||||
.into_iter()
|
||||
.map(|log| self.parse_log(log))
|
||||
.collect::<Result<Vec<_>, ContractError<M>>>()?;
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
/// Queries the blockchain for the selected filter and returns a vector of logs
|
||||
/// along with their metadata
|
||||
pub async fn query_with_meta(&self) -> Result<Vec<(D, LogMeta)>, ContractError<M>> {
|
||||
let logs = self
|
||||
.provider
|
||||
.get_logs(&self.filter)
|
||||
.await
|
||||
.map_err(ContractError::MiddlewareError)?;
|
||||
let events = logs
|
||||
.into_iter()
|
||||
.map(|log| {
|
||||
let meta = LogMeta::from(&log);
|
||||
let event = self.parse_log(log)?;
|
||||
Ok((event, meta))
|
||||
})
|
||||
.collect::<Result<_, ContractError<M>>>()?;
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
fn parse_log(&self, log: Log) -> Result<D, ContractError<M>> {
|
||||
D::decode_log(&RawLog {
|
||||
topics: log.topics,
|
||||
data: log.data.to_vec(),
|
||||
})
|
||||
.map_err(From::from)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper for managing the event filter before querying or streaming its logs
|
||||
#[derive(Debug)]
|
||||
#[must_use = "event filters do nothing unless you `query` or `stream` them"]
|
||||
|
|
Loading…
Reference in New Issue