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)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
mod #name_mod {
|
mod #name_mod {
|
||||||
#imports
|
#imports
|
||||||
|
|
||||||
#struct_decl
|
#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`
|
/// Creates a new contract instance with the specified `ethers`
|
||||||
/// client at the given `Address`. The contract derefs to a `ethers::Contract`
|
/// client at the given `Address`. The contract derefs to a `ethers::Contract`
|
||||||
/// object
|
/// object
|
||||||
pub fn new<T: Into<Address>>(address: T, client: Arc<M>) -> Self {
|
pub fn new<T: Into<ethers_core::types::Address>>(address: T, client: ::std::sync::Arc<M>) -> Self {
|
||||||
let contract = Contract::new(address.into(), #abi_name.clone(), client);
|
let contract = ethers_contract::Contract::new(address.into(), #abi_name.clone(), client);
|
||||||
Self(contract)
|
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 {
|
let abi_parse = if !cx.human_readable {
|
||||||
quote! {
|
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"));
|
.expect("invalid abi"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
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"));
|
.expect("invalid abi"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -47,17 +47,17 @@ pub(crate) fn struct_declaration(cx: &Context, abi_name: &proc_macro2::Ident) ->
|
||||||
|
|
||||||
// Struct declaration
|
// Struct declaration
|
||||||
#[derive(Clone)]
|
#[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
|
// Deref to the inner contract in order to access more specific functions functions
|
||||||
impl<M> std::ops::Deref for #name<M> {
|
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 }
|
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 {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_tuple(stringify!(#name))
|
f.debug_tuple(stringify!(#name))
|
||||||
.field(&self.address())
|
.field(&self.address())
|
||||||
|
|
|
@ -63,19 +63,19 @@ impl Context {
|
||||||
#(#variants(#variants)),*
|
#(#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 {
|
Self: Sized {
|
||||||
#(
|
#(
|
||||||
if let Ok(decoded) = #variants::from_token(token.clone()) {
|
if let Ok(decoded) = #variants::from_token(token.clone()) {
|
||||||
return Ok(#enum_name::#variants(decoded))
|
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 {
|
match self {
|
||||||
#(
|
#(
|
||||||
#enum_name::#variants(element) => element.into_token()
|
#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 {
|
impl ethers_contract::EthLogDecode for #enum_name {
|
||||||
fn decode_log(log: ðers::abi::RawLog) -> Result<Self, ethers::abi::Error>
|
fn decode_log(log: ðers_core::abi::RawLog) -> Result<Self, ethers_core::abi::Error>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ impl Context {
|
||||||
return Ok(#enum_name::#variants(decoded))
|
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>});
|
return Ok(quote! {::std::vec::Vec<#ty>});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
quote! { H256 }
|
quote! { ethers_core::types::H256 }
|
||||||
}
|
}
|
||||||
(ParamType::FixedArray(ty, size), true) => {
|
(ParamType::FixedArray(ty, size), true) => {
|
||||||
if let ParamType::Tuple(..) = **ty {
|
if let ParamType::Tuple(..) = **ty {
|
||||||
|
@ -162,7 +162,7 @@ impl Context {
|
||||||
return Ok(quote! {[#ty; #size]});
|
return Ok(quote! {[#ty; #size]});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
quote! { H256 }
|
quote! { ethers_core::types::H256 }
|
||||||
}
|
}
|
||||||
(ParamType::Tuple(..), true) => {
|
(ParamType::Tuple(..), true) => {
|
||||||
// represents an struct
|
// represents an struct
|
||||||
|
@ -175,11 +175,11 @@ impl Context {
|
||||||
{
|
{
|
||||||
quote! {#ty}
|
quote! {#ty}
|
||||||
} else {
|
} else {
|
||||||
quote! { H256 }
|
quote! { ethers_core::types::H256 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(ParamType::Bytes, true) | (ParamType::String, true) => {
|
(ParamType::Bytes, true) | (ParamType::String, true) => {
|
||||||
quote! { H256 }
|
quote! { ethers_core::types::H256 }
|
||||||
}
|
}
|
||||||
(kind, _) => types::expand(kind)?,
|
(kind, _) => types::expand(kind)?,
|
||||||
})
|
})
|
||||||
|
@ -213,7 +213,7 @@ impl Context {
|
||||||
let doc = util::expand_doc(&format!("Gets the contract's `{}` event", event.name));
|
let doc = util::expand_doc(&format!("Gets the contract's `{}` event", event.name));
|
||||||
quote! {
|
quote! {
|
||||||
#doc
|
#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)")
|
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;
|
let event_abi_name = &event.name;
|
||||||
|
|
||||||
Ok(quote! {
|
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 )]
|
#[ethevent( name = #event_abi_name, abi = #abi_signature )]
|
||||||
pub #data_type_definition
|
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);
|
let bytes = hash.as_bytes().iter().copied().map(Literal::u8_unsuffixed);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
H256([#( #bytes ),*])
|
ethers_core::types::H256([#( #bytes ),*])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ mod tests {
|
||||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f".parse().unwrap()
|
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f".parse().unwrap()
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
H256([
|
ethers_core::types::H256([
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
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
|
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 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 arg = expand_inputs_call_arg(&function.inputs);
|
||||||
let doc = util::expand_doc(&format!(
|
let doc = util::expand_doc(&format!(
|
||||||
|
|
|
@ -5,7 +5,7 @@ use quote::quote;
|
||||||
|
|
||||||
pub(crate) fn expand(kind: &ParamType) -> Result<TokenStream> {
|
pub(crate) fn expand(kind: &ParamType) -> Result<TokenStream> {
|
||||||
match kind {
|
match kind {
|
||||||
ParamType::Address => Ok(quote! { Address }),
|
ParamType::Address => Ok(quote! { ethers_core::types::Address }),
|
||||||
ParamType::Bytes => Ok(quote! { Vec<u8> }),
|
ParamType::Bytes => Ok(quote! { Vec<u8> }),
|
||||||
ParamType::Int(n) => match n / 8 {
|
ParamType::Int(n) => match n / 8 {
|
||||||
1 => Ok(quote! { i8 }),
|
1 => Ok(quote! { i8 }),
|
||||||
|
@ -22,7 +22,7 @@ pub(crate) fn expand(kind: &ParamType) -> Result<TokenStream> {
|
||||||
3..=4 => Ok(quote! { u32 }),
|
3..=4 => Ok(quote! { u32 }),
|
||||||
5..=8 => Ok(quote! { u64 }),
|
5..=8 => Ok(quote! { u64 }),
|
||||||
9..=16 => Ok(quote! { u128 }),
|
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)),
|
_ => Err(anyhow!("unsupported solidity type uint{}", n)),
|
||||||
},
|
},
|
||||||
ParamType::Bool => Ok(quote! { bool }),
|
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 anon = attributes.anonymous.map(|(b, _)| b).unwrap_or_default();
|
||||||
|
|
||||||
let ethevent_impl = quote! {
|
let ethevent_impl = quote! {
|
||||||
impl ethers::contract::EthEvent for #name {
|
impl ethers_contract::EthEvent for #name {
|
||||||
|
|
||||||
fn name() -> ::std::borrow::Cow<'static, str> {
|
fn name() -> ::std::borrow::Cow<'static, str> {
|
||||||
#event_name.into()
|
#event_name.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature() -> ethers::types::H256 {
|
fn signature() -> ethers_core::types::H256 {
|
||||||
#signature
|
#signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ pub fn derive_abi_event(input: TokenStream) -> TokenStream {
|
||||||
#abi.into()
|
#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
|
#decode_log_impl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ fn topic_param_type_quote(kind: &ParamType) -> proc_macro2::TokenStream {
|
||||||
| ParamType::Bytes
|
| ParamType::Bytes
|
||||||
| ParamType::Array(_)
|
| ParamType::Array(_)
|
||||||
| ParamType::FixedArray(_, _)
|
| ParamType::FixedArray(_, _)
|
||||||
| ParamType::Tuple(_) => quote! {ethers::abi::ParamType::FixedBytes(32)},
|
| ParamType::Tuple(_) => quote! {ethers_core::abi::ParamType::FixedBytes(32)},
|
||||||
ty => param_type_quote(ty),
|
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 {
|
fn param_type_quote(kind: &ParamType) -> proc_macro2::TokenStream {
|
||||||
match kind {
|
match kind {
|
||||||
ParamType::Address => {
|
ParamType::Address => {
|
||||||
quote! {ethers::abi::ParamType::Address}
|
quote! {ethers_core::abi::ParamType::Address}
|
||||||
}
|
}
|
||||||
ParamType::Bytes => {
|
ParamType::Bytes => {
|
||||||
quote! {ethers::abi::ParamType::Bytes}
|
quote! {ethers_core::abi::ParamType::Bytes}
|
||||||
}
|
}
|
||||||
ParamType::Int(size) => {
|
ParamType::Int(size) => {
|
||||||
let size = Literal::usize_suffixed(*size);
|
let size = Literal::usize_suffixed(*size);
|
||||||
quote! {ethers::abi::ParamType::Int(#size)}
|
quote! {ethers_core::abi::ParamType::Int(#size)}
|
||||||
}
|
}
|
||||||
ParamType::Uint(size) => {
|
ParamType::Uint(size) => {
|
||||||
let size = Literal::usize_suffixed(*size);
|
let size = Literal::usize_suffixed(*size);
|
||||||
quote! {ethers::abi::ParamType::Uint(#size)}
|
quote! {ethers_core::abi::ParamType::Uint(#size)}
|
||||||
}
|
}
|
||||||
ParamType::Bool => {
|
ParamType::Bool => {
|
||||||
quote! {ethers::abi::ParamType::Bool}
|
quote! {ethers_core::abi::ParamType::Bool}
|
||||||
}
|
}
|
||||||
ParamType::String => {
|
ParamType::String => {
|
||||||
quote! {ethers::abi::ParamType::String}
|
quote! {ethers_core::abi::ParamType::String}
|
||||||
}
|
}
|
||||||
ParamType::Array(ty) => {
|
ParamType::Array(ty) => {
|
||||||
let ty = param_type_quote(&*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) => {
|
ParamType::FixedBytes(size) => {
|
||||||
let size = Literal::usize_suffixed(*size);
|
let size = Literal::usize_suffixed(*size);
|
||||||
quote! {ethers::abi::ParamType::FixedBytes(#size)}
|
quote! {ethers_core::abi::ParamType::FixedBytes(#size)}
|
||||||
}
|
}
|
||||||
ParamType::FixedArray(ty, size) => {
|
ParamType::FixedArray(ty, size) => {
|
||||||
let ty = param_type_quote(&*ty);
|
let ty = param_type_quote(&*ty);
|
||||||
let size = Literal::usize_suffixed(*size);
|
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) => {
|
ParamType::Tuple(tuple) => {
|
||||||
let elements = tuple.iter().map(param_type_quote);
|
let elements = tuple.iter().map(param_type_quote);
|
||||||
quote! {
|
quote! {
|
||||||
ethers::abi::ParamType::Tuple(
|
ethers_core::abi::ParamType::Tuple(
|
||||||
vec![
|
vec![
|
||||||
#( #elements ),*
|
#( #elements ),*
|
||||||
]
|
]
|
||||||
|
@ -424,16 +424,16 @@ fn derive_decode_from_log_impl(
|
||||||
},
|
},
|
||||||
quote! {
|
quote! {
|
||||||
if topic_tokens.len() != topics.len() {
|
if topic_tokens.len() != topics.len() {
|
||||||
return Err(ethers::abi::Error::InvalidData);
|
return Err(ethers_core::abi::Error::InvalidData);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
quote! {
|
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() {
|
if event_signature != &Self::signature() {
|
||||||
return Err(ethers::abi::Error::InvalidData);
|
return Err(ethers_core::abi::Error::InvalidData);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -441,7 +441,7 @@ fn derive_decode_from_log_impl(
|
||||||
},
|
},
|
||||||
quote! {
|
quote! {
|
||||||
if topic_tokens.is_empty() || topic_tokens.len() != topics.len() - 1 {
|
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)
|
.all(|(idx, f)| f.index == idx)
|
||||||
{
|
{
|
||||||
quote! {
|
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
|
#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();
|
let tokens:Vec<_> = topic_tokens.into_iter().chain(data_tokens.into_iter()).collect();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -470,9 +470,9 @@ fn derive_decode_from_log_impl(
|
||||||
});
|
});
|
||||||
|
|
||||||
quote! {
|
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
|
#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());
|
let mut tokens = Vec::with_capacity(topics.len() + data_tokens.len());
|
||||||
#( tokens.push(#swap_tokens); )*
|
#( tokens.push(#swap_tokens); )*
|
||||||
}
|
}
|
||||||
|
@ -480,7 +480,7 @@ fn derive_decode_from_log_impl(
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
|
|
||||||
let ethers::abi::RawLog {data, topics} = log;
|
let ethers_core::abi::RawLog {data, topics} = log;
|
||||||
|
|
||||||
#signature_check
|
#signature_check
|
||||||
|
|
||||||
|
@ -491,7 +491,7 @@ fn derive_decode_from_log_impl(
|
||||||
|
|
||||||
#tokens_init
|
#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 {
|
fn signature(hash: &[u8]) -> proc_macro2::TokenStream {
|
||||||
let bytes = hash.iter().copied().map(Literal::u8_unsuffixed);
|
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> {
|
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) => {
|
Fields::Named(ref fields) => {
|
||||||
let tokenize_predicates = fields.named.iter().map(|f| {
|
let tokenize_predicates = fields.named.iter().map(|f| {
|
||||||
let ty = &f.ty;
|
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 tokenize_predicates = quote! { #(#tokenize_predicates,)* };
|
||||||
|
|
||||||
let assignments = fields.named.iter().map(|f| {
|
let assignments = fields.named.iter().map(|f| {
|
||||||
let name = f.ident.as_ref().expect("Named fields have names");
|
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,)* } };
|
let init_struct_impl = quote! { Self { #(#assignments,)* } };
|
||||||
|
|
||||||
|
@ -753,12 +753,12 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
||||||
Fields::Unnamed(ref fields) => {
|
Fields::Unnamed(ref fields) => {
|
||||||
let tokenize_predicates = fields.unnamed.iter().map(|f| {
|
let tokenize_predicates = fields.unnamed.iter().map(|f| {
|
||||||
let ty = &f.ty;
|
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 tokenize_predicates = quote! { #(#tokenize_predicates,)* };
|
||||||
|
|
||||||
let assignments = fields.unnamed.iter().map(|f| {
|
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,)* ) };
|
let init_struct_impl = quote! { Self(#(#assignments,)* ) };
|
||||||
|
|
||||||
|
@ -794,17 +794,17 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl<#generic_params> ethers::abi::Tokenizable for #name<#generic_args>
|
impl<#generic_params> ethers_core::abi::Tokenizable for #name<#generic_args>
|
||||||
where
|
where
|
||||||
#generic_predicates
|
#generic_predicates
|
||||||
#tokenize_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 {
|
Self: Sized {
|
||||||
if let ethers::abi::Token::Tuple(tokens) = token {
|
if let ethers_core::abi::Token::Tuple(tokens) = token {
|
||||||
if tokens.len() != #params_len {
|
if tokens.len() != #params_len {
|
||||||
return Err(ethers::abi::InvalidOutputType(format!(
|
return Err(ethers_core::abi::InvalidOutputType(format!(
|
||||||
"Expected {} tokens, got {}: {:?}",
|
"Expected {} tokens, got {}: {:?}",
|
||||||
#params_len,
|
#params_len,
|
||||||
tokens.len(),
|
tokens.len(),
|
||||||
|
@ -816,15 +816,15 @@ fn derive_tokenizeable_impl(input: &DeriveInput) -> proc_macro2::TokenStream {
|
||||||
|
|
||||||
Ok(#init_struct_impl)
|
Ok(#init_struct_impl)
|
||||||
} else {
|
} else {
|
||||||
Err(ethers::abi::InvalidOutputType(format!(
|
Err(ethers_core::abi::InvalidOutputType(format!(
|
||||||
"Expected Tuple, got {:?}",
|
"Expected Tuple, got {:?}",
|
||||||
token
|
token
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_token(self) -> ethers::abi::Token {
|
fn into_token(self) -> ethers_core::abi::Token {
|
||||||
ethers::abi::Token::Tuple(
|
ethers_core::abi::Token::Tuple(
|
||||||
vec![
|
vec![
|
||||||
#into_token_impl
|
#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
|
where
|
||||||
#generic_predicates
|
#generic_predicates
|
||||||
#tokenize_predicates
|
#tokenize_predicates
|
||||||
|
|
|
@ -180,6 +180,7 @@ impl<M: Middleware> Contract<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an [`Event`](crate::builders::Event) builder for the provided event name.
|
/// 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> {
|
pub fn event<D: Detokenize>(&self, name: &str) -> Result<Event<M, D>, Error> {
|
||||||
// get the event's full name
|
// get the event's full name
|
||||||
let event = self.base_contract.abi.event(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
|
/// Returns true if this is an anonymous event
|
||||||
fn is_anonymous() -> bool;
|
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
|
// 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
|
/// Helper for managing the event filter before querying or streaming its logs
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[must_use = "event filters do nothing unless you `query` or `stream` them"]
|
#[must_use = "event filters do nothing unless you `query` or `stream` them"]
|
||||||
|
|
Loading…
Reference in New Issue