chore: bump syn to 2.0, fix breaking changes
This commit is contained in:
parent
d5831b2679
commit
ef5a37b2e5
|
@ -104,7 +104,7 @@ checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -138,7 +138,7 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -485,7 +485,7 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -821,7 +821,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -872,7 +872,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -889,7 +889,7 @@ checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -932,7 +932,7 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1272,7 +1272,7 @@ dependencies = [
|
|||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"syn 2.0.0",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"toml",
|
||||
|
@ -1289,7 +1289,7 @@ dependencies = [
|
|||
"hex",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1312,13 +1312,12 @@ dependencies = [
|
|||
"num_enum",
|
||||
"once_cell",
|
||||
"open-fastrlp",
|
||||
"proc-macro2",
|
||||
"rand",
|
||||
"rlp",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
"syn",
|
||||
"syn 2.0.0",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tiny-keccak",
|
||||
|
@ -1332,9 +1331,10 @@ dependencies = [
|
|||
"ethers-contract-derive",
|
||||
"ethers-core",
|
||||
"hex",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"syn 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1816,7 +1816,7 @@ checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2204,7 +2204,7 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2615,7 +2615,7 @@ dependencies = [
|
|||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2664,7 +2664,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2690,7 +2690,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2790,7 +2790,7 @@ dependencies = [
|
|||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2911,7 +2911,7 @@ dependencies = [
|
|||
"phf_shared 0.11.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2955,7 +2955,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3051,7 +3051,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3096,7 +3096,7 @@ dependencies = [
|
|||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
@ -3340,7 +3340,7 @@ checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3549,7 +3549,7 @@ dependencies = [
|
|||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3687,7 +3687,7 @@ checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3753,7 +3753,7 @@ checksum = "079a83df15f85d89a68d64ae1238f142f172b1fa915d0d76b26a7cba1b659a69"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3844,7 +3844,7 @@ checksum = "ede930749cca4e3a3df7e37b5f0934a55693e01d028d7a4e506b44cbc059d95a"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3951,7 +3951,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4015,6 +4015,17 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cff13bb1732bccfe3b246f3fdb09edfd51c01d6f5299b7ccd9457c2e4e37774"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.6"
|
||||
|
@ -4023,7 +4034,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
|
@ -4099,7 +4110,7 @@ checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4200,7 +4211,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4316,7 +4327,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4388,7 +4399,7 @@ checksum = "258bc1c4f8e2e73a977812ab339d503e6feeb92700f6d07a6de4d321522d5c08"
|
|||
dependencies = [
|
||||
"lazy_static",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4600,7 +4611,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -4634,7 +4645,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -4919,7 +4930,7 @@ checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ serde_json = "1.0"
|
|||
# macros
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["extra-traits"] }
|
||||
syn = { version = "2.0", features = ["extra-traits"] }
|
||||
async-trait = "0.1.66"
|
||||
auto_impl = "1.0"
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ ethers-core = { workspace = true, features = ["macros"] }
|
|||
|
||||
proc-macro2.workspace = true
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
syn = { workspace = true, features = ["full"] }
|
||||
prettyplease = "0.1.25"
|
||||
|
||||
Inflector = "0.11"
|
||||
|
|
|
@ -55,7 +55,6 @@ cargo_metadata = { version = "0.15.3", optional = true }
|
|||
# eip712 feature enabled dependencies
|
||||
convert_case = { version = "0.6.0", optional = true }
|
||||
syn = { workspace = true, optional = true }
|
||||
proc-macro2 = { workspace = true, optional = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
tempfile.workspace = true
|
||||
|
@ -73,5 +72,5 @@ rand.workspace = true
|
|||
[features]
|
||||
celo = ["legacy"] # celo support extends the transaction format with extra fields
|
||||
legacy = []
|
||||
eip712 = ["convert_case", "syn", "proc-macro2"]
|
||||
eip712 = ["convert_case", "syn"]
|
||||
macros = ["syn", "cargo_metadata", "once_cell"]
|
||||
|
|
|
@ -19,6 +19,7 @@ proc-macro = true
|
|||
[dependencies]
|
||||
ethers-core = { workspace = true, features = ["eip712", "macros"] }
|
||||
|
||||
proc-macro2.workspace = true
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
|
||||
|
|
|
@ -62,49 +62,40 @@
|
|||
//! determine if there is a nested eip712 struct. However, this work is not yet complete.
|
||||
|
||||
#![deny(missing_docs, unsafe_code, rustdoc::broken_intra_doc_links)]
|
||||
|
||||
use ethers_core::{macros::ethers_core_crate, types::transaction::eip712};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use std::convert::TryFrom;
|
||||
use syn::parse_macro_input;
|
||||
use syn::{parse_macro_input, Result};
|
||||
|
||||
/// Derive macro for `Eip712`
|
||||
#[proc_macro_derive(Eip712, attributes(eip712))]
|
||||
pub fn eip_712_derive(input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input);
|
||||
|
||||
impl_eip_712_macro(&ast)
|
||||
let input = parse_macro_input!(input);
|
||||
match impl_eip_712_macro(&input) {
|
||||
Ok(tokens) => tokens,
|
||||
Err(e) => e.to_compile_error(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
// Main implementation macro, used to compute static values and define
|
||||
// method for encoding the final eip712 payload;
|
||||
fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||
fn impl_eip_712_macro(input: &syn::DeriveInput) -> Result<TokenStream2> {
|
||||
// Primary type should match the type in the ethereum verifying contract;
|
||||
let primary_type = &ast.ident;
|
||||
let primary_type = &input.ident;
|
||||
|
||||
// Instantiate domain from parsed attributes
|
||||
let domain = match eip712::EIP712Domain::try_from(ast) {
|
||||
Ok(attributes) => attributes,
|
||||
Err(e) => return TokenStream::from(e),
|
||||
};
|
||||
let domain = eip712::EIP712Domain::try_from(input)?;
|
||||
|
||||
let domain_separator = hex::encode(domain.separator());
|
||||
|
||||
//
|
||||
let domain_str = match serde_json::to_string(&domain) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return TokenStream::from(
|
||||
syn::Error::new(ast.ident.span(), e.to_string()).to_compile_error(),
|
||||
)
|
||||
}
|
||||
};
|
||||
let domain_str = serde_json::to_string(&domain).unwrap();
|
||||
|
||||
// Must parse the AST at compile time.
|
||||
let parsed_fields = match eip712::parse_fields(ast) {
|
||||
Ok(fields) => fields,
|
||||
Err(e) => return TokenStream::from(e),
|
||||
};
|
||||
let parsed_fields = eip712::parse_fields(input)?;
|
||||
|
||||
// Compute the type hash for the derived struct using the parsed fields from above.
|
||||
let type_hash =
|
||||
|
@ -113,7 +104,7 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|||
// Use reference to ethers_core instead of directly using the crate itself.
|
||||
let ethers_core = ethers_core_crate();
|
||||
|
||||
let implementation = quote! {
|
||||
let tokens = quote! {
|
||||
impl Eip712 for #primary_type {
|
||||
type Error = #ethers_core::types::transaction::eip712::Eip712Error;
|
||||
|
||||
|
@ -168,5 +159,5 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|||
}
|
||||
};
|
||||
|
||||
implementation.into()
|
||||
Ok(tokens)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ use crate::{
|
|||
use convert_case::{Case, Casing};
|
||||
use core::convert::TryFrom;
|
||||
use ethabi::encode;
|
||||
use proc_macro2::TokenStream;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashSet},
|
||||
|
@ -15,25 +14,25 @@ use std::{
|
|||
iter::FromIterator,
|
||||
};
|
||||
use syn::{
|
||||
parse::Error, spanned::Spanned as _, AttrStyle, Data, DeriveInput, Expr, Fields,
|
||||
GenericArgument, Lit, NestedMeta, PathArguments, Type,
|
||||
parse::Error, spanned::Spanned, Data, DeriveInput, Expr, Fields, GenericArgument, Lit, LitInt,
|
||||
LitStr, PathArguments, Type,
|
||||
};
|
||||
|
||||
/// Custom types for `TypedData`
|
||||
pub type Types = BTreeMap<String, Vec<Eip712DomainType>>;
|
||||
|
||||
/// Pre-computed value of the following statement:
|
||||
/// Pre-computed value of the following expression:
|
||||
///
|
||||
/// `ethers_core::utils::keccak256("EIP712Domain(string name,string version,uint256 chainId,address
|
||||
/// `keccak256("EIP712Domain(string name,string version,uint256 chainId,address
|
||||
/// verifyingContract)")`
|
||||
pub const EIP712_DOMAIN_TYPE_HASH: [u8; 32] = [
|
||||
139, 115, 195, 198, 155, 184, 254, 61, 81, 46, 204, 76, 247, 89, 204, 121, 35, 159, 123, 23,
|
||||
155, 15, 250, 202, 169, 167, 93, 82, 43, 57, 64, 15,
|
||||
];
|
||||
|
||||
/// Pre-computed value of the following statement:
|
||||
/// Pre-computed value of the following expression:
|
||||
///
|
||||
/// `ethers_core::utils::keccak256("EIP712Domain(string name,string version,uint256 chainId,address
|
||||
/// `keccak256("EIP712Domain(string name,string version,uint256 chainId,address
|
||||
/// verifyingContract,bytes32 salt)")`
|
||||
pub const EIP712_DOMAIN_TYPE_HASH_WITH_SALT: [u8; 32] = [
|
||||
216, 124, 214, 239, 121, 212, 226, 185, 94, 21, 206, 138, 191, 115, 45, 181, 30, 199, 113, 241,
|
||||
|
@ -247,190 +246,61 @@ impl<T: Eip712 + Clone> Eip712 for EIP712WithDomain<T> {
|
|||
|
||||
// Parse the AST of the struct to determine the domain attributes
|
||||
impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||
type Error = TokenStream;
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(input: &syn::DeriveInput) -> Result<EIP712Domain, Self::Error> {
|
||||
const ERROR: &str = "unrecognized eip712 attribute";
|
||||
const ALREADY_SPECIFIED: &str = "eip712 attribute already specified";
|
||||
|
||||
let mut domain = EIP712Domain::default();
|
||||
|
||||
let mut found_eip712_attribute = false;
|
||||
|
||||
'attribute_search: for attribute in input.attrs.iter() {
|
||||
if let AttrStyle::Outer = attribute.style {
|
||||
if let Ok(syn::Meta::List(meta)) = attribute.parse_meta() {
|
||||
if meta.path.is_ident("eip712") {
|
||||
found_eip712_attribute = true;
|
||||
|
||||
for n in meta.nested.iter() {
|
||||
if let NestedMeta::Meta(meta) = n {
|
||||
match meta {
|
||||
syn::Meta::NameValue(meta) => {
|
||||
let ident = meta.path.get_ident().ok_or_else(|| {
|
||||
Error::new(
|
||||
meta.path.span(),
|
||||
"unrecognized eip712 parameter",
|
||||
)
|
||||
.to_compile_error()
|
||||
})?;
|
||||
|
||||
match ident.to_string().as_ref() {
|
||||
"name" => match meta.lit {
|
||||
syn::Lit::Str(ref lit_str) => {
|
||||
if domain.name.is_some() {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain name already specified",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
|
||||
domain.name = Some(lit_str.value());
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain name must be a string",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
},
|
||||
"version" => match meta.lit {
|
||||
syn::Lit::Str(ref lit_str) => {
|
||||
if domain.version.is_some() {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain version already specified",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
|
||||
domain.version = Some(lit_str.value());
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain version must be a string",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
},
|
||||
"chain_id" => match meta.lit {
|
||||
syn::Lit::Int(ref lit_int) => {
|
||||
if domain.chain_id.is_some() {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain chain_id already specified",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
|
||||
domain.chain_id = Some(U256::from(
|
||||
lit_int.base10_parse::<u64>().map_err(
|
||||
|_| {
|
||||
Error::new(
|
||||
meta.path.span(),
|
||||
"failed to parse chain id",
|
||||
)
|
||||
.to_compile_error()
|
||||
},
|
||||
)?,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain chain_id must be a positive integer",
|
||||
)
|
||||
.to_compile_error());
|
||||
}
|
||||
},
|
||||
"verifying_contract" => match meta.lit {
|
||||
syn::Lit::Str(ref lit_str) => {
|
||||
if domain.verifying_contract.is_some() {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain verifying_contract already specified",
|
||||
)
|
||||
.to_compile_error());
|
||||
}
|
||||
|
||||
domain.verifying_contract = Some(lit_str.value().parse().map_err(|_| {
|
||||
Error::new(
|
||||
meta.path.span(),
|
||||
"failed to parse verifying contract into Address",
|
||||
)
|
||||
.to_compile_error()
|
||||
})?);
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain verifying_contract must be a string",
|
||||
)
|
||||
.to_compile_error());
|
||||
}
|
||||
},
|
||||
"salt" => match meta.lit {
|
||||
syn::Lit::Str(ref lit_str) => {
|
||||
if domain.salt.is_some() {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain salt already specified",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
|
||||
// keccak256(<string>) to compute bytes32
|
||||
// encoded domain salt
|
||||
let salt = keccak256(lit_str.value());
|
||||
|
||||
domain.salt = Some(salt);
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"domain salt must be a string",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"unrecognized eip712 parameter; must be one of 'name', 'version', 'chain_id', or 'verifying_contract'",
|
||||
)
|
||||
.to_compile_error());
|
||||
}
|
||||
}
|
||||
}
|
||||
syn::Meta::Path(path) => {
|
||||
return Err(Error::new(
|
||||
path.span(),
|
||||
"unrecognized eip712 parameter",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
syn::Meta::List(meta) => {
|
||||
return Err(Error::new(
|
||||
meta.path.span(),
|
||||
"unrecognized eip712 parameter",
|
||||
)
|
||||
.to_compile_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break 'attribute_search
|
||||
}
|
||||
for attr in input.attrs.iter() {
|
||||
if !attr.path().is_ident("eip712") {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if !found_eip712_attribute {
|
||||
return Err(Error::new_spanned(
|
||||
input,
|
||||
"missing required derive attribute: '#[eip712( ... )]'".to_string(),
|
||||
)
|
||||
.to_compile_error())
|
||||
attr.parse_nested_meta(|meta| {
|
||||
let ident = meta.path.get_ident().ok_or_else(|| meta.error(ERROR))?.to_string();
|
||||
match ident.as_str() {
|
||||
"name" if domain.name.is_none() => {
|
||||
let litstr: LitStr = meta.input.parse()?;
|
||||
domain.name = Some(litstr.value());
|
||||
}
|
||||
"name" => return Err(meta.error(ALREADY_SPECIFIED)),
|
||||
|
||||
"version" if domain.version.is_none() => {
|
||||
let litstr: LitStr = meta.input.parse()?;
|
||||
domain.version = Some(litstr.value());
|
||||
}
|
||||
"version" => return Err(meta.error(ALREADY_SPECIFIED)),
|
||||
|
||||
"chain_id" if domain.chain_id.is_none() => {
|
||||
let litint: LitInt = meta.input.parse()?;
|
||||
let n: u64 = litint.base10_parse()?;
|
||||
domain.chain_id = Some(n.into());
|
||||
}
|
||||
"chain_id" => return Err(meta.error(ALREADY_SPECIFIED)),
|
||||
|
||||
"verifying_contract" if domain.verifying_contract.is_none() => {
|
||||
let litstr: LitStr = meta.input.parse()?;
|
||||
let addr: Address =
|
||||
litstr.value().parse().map_err(|e| Error::new(litstr.span(), e))?;
|
||||
domain.verifying_contract = Some(addr);
|
||||
}
|
||||
"verifying_contract" => return Err(meta.error(ALREADY_SPECIFIED)),
|
||||
|
||||
"salt" if domain.salt.is_none() => {
|
||||
let litstr: LitStr = meta.input.parse()?;
|
||||
let hash = keccak256(litstr.value());
|
||||
domain.salt = Some(hash);
|
||||
}
|
||||
"salt" => return Err(meta.error(ALREADY_SPECIFIED)),
|
||||
|
||||
_ => return Err(meta.error(ERROR)),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(domain)
|
||||
|
@ -442,36 +312,35 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
|||
/// Typed data is a JSON object containing type information, domain separator parameters and the
|
||||
/// message object which has the following schema
|
||||
///
|
||||
/// ```js
|
||||
/// ```json
|
||||
/// {
|
||||
// type: 'object',
|
||||
// properties: {
|
||||
// types: {
|
||||
// type: 'object',
|
||||
// properties: {
|
||||
// EIP712Domain: {type: 'array'},
|
||||
// },
|
||||
// additionalProperties: {
|
||||
// type: 'array',
|
||||
// items: {
|
||||
// type: 'object',
|
||||
// properties: {
|
||||
// name: {type: 'string'},
|
||||
// type: {type: 'string'}
|
||||
// },
|
||||
// required: ['name', 'type']
|
||||
// }
|
||||
// },
|
||||
// required: ['EIP712Domain']
|
||||
// },
|
||||
// primaryType: {type: 'string'},
|
||||
// domain: {type: 'object'},
|
||||
// message: {type: 'object'}
|
||||
// },
|
||||
// required: ['types', 'primaryType', 'domain', 'message']
|
||||
// }
|
||||
/// "type": "object",
|
||||
/// "properties": {
|
||||
/// "types": {
|
||||
/// "type": "object",
|
||||
/// "properties": {
|
||||
/// "EIP712Domain": { "type": "array" }
|
||||
/// },
|
||||
/// "additionalProperties": {
|
||||
/// "type": "array",
|
||||
/// "items": {
|
||||
/// "type": "object",
|
||||
/// "properties": {
|
||||
/// "name": { "type": "string" },
|
||||
/// "type": { "type": "string" }
|
||||
/// },
|
||||
/// "required": ["name", "type"]
|
||||
/// }
|
||||
/// },
|
||||
/// "required": ["EIP712Domain"]
|
||||
/// },
|
||||
/// "primaryType": { "type": "string" },
|
||||
/// "domain": { "type": "object" },
|
||||
/// "message": { "type": "object" }
|
||||
/// },
|
||||
/// "required": ["types", "primaryType", "domain", "message"]
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct TypedData {
|
||||
|
@ -775,7 +644,7 @@ pub fn encode_field(
|
|||
/// Parse the eth abi parameter type based on the syntax type;
|
||||
/// this method is copied from <https://github.com/gakonst/ethers-rs/blob/master/ethers-contract/ethers-contract-derive/src/lib.rs#L600>
|
||||
/// with additional modifications for finding byte arrays
|
||||
pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
|
||||
pub fn find_parameter_type(ty: &Type) -> Result<ParamType, Error> {
|
||||
match ty {
|
||||
Type::Array(ty) => {
|
||||
let param = find_parameter_type(ty.elem.as_ref())?;
|
||||
|
@ -790,8 +659,7 @@ pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Err(Error::new(ty.span(), "Failed to derive proper ABI from array field")
|
||||
.to_compile_error())
|
||||
Err(Error::new(ty.span(), "Failed to derive proper ABI from array field"))
|
||||
}
|
||||
Type::Path(ty) => {
|
||||
if let Some(ident) = ty.path.get_ident() {
|
||||
|
@ -810,7 +678,6 @@ pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
|
|||
ty.span(),
|
||||
format!("Failed to derive proper ABI from field: {s})"),
|
||||
)
|
||||
.to_compile_error()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -834,15 +701,13 @@ pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
|
|||
}
|
||||
}
|
||||
|
||||
Err(Error::new(ty.span(), "Failed to derive proper ABI from fields").to_compile_error())
|
||||
Err(Error::new(ty.span(), "Failed to derive proper ABI from fields"))
|
||||
}
|
||||
Type::Tuple(ty) => {
|
||||
let params = ty.elems.iter().map(find_parameter_type).collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(ParamType::Tuple(params))
|
||||
}
|
||||
_ => {
|
||||
Err(Error::new(ty.span(), "Failed to derive proper ABI from fields").to_compile_error())
|
||||
}
|
||||
_ => Err(Error::new(ty.span(), "Failed to derive proper ABI from fields")),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,41 +722,33 @@ fn parse_int_param_type(s: &str) -> Option<ParamType> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return HashMap of the field name and the field type;
|
||||
pub fn parse_fields(ast: &DeriveInput) -> Result<Vec<(String, ParamType)>, TokenStream> {
|
||||
/// Return HashMap of the field name and the field type
|
||||
pub fn parse_fields(input: &DeriveInput) -> Result<Vec<(String, ParamType)>, Error> {
|
||||
let mut fields = Vec::new();
|
||||
|
||||
let data = match &ast.data {
|
||||
let data = match &input.data {
|
||||
Data::Struct(s) => s,
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
ast.span(),
|
||||
"invalid data type. can only derive Eip712 for a struct",
|
||||
)
|
||||
.to_compile_error())
|
||||
Data::Enum(e) => {
|
||||
return Err(Error::new(e.enum_token.span, "Eip712 is not derivable for enums"))
|
||||
}
|
||||
Data::Union(u) => {
|
||||
return Err(Error::new(u.union_token.span, "Eip712 is not derivable for unions"))
|
||||
}
|
||||
};
|
||||
|
||||
let named_fields = match &data.fields {
|
||||
Fields::Named(name) => name,
|
||||
_ => {
|
||||
return Err(Error::new(ast.span(), "unnamed fields are not supported").to_compile_error())
|
||||
}
|
||||
_ => return Err(Error::new(input.span(), "unnamed fields are not supported")),
|
||||
};
|
||||
|
||||
for f in named_fields.named.iter() {
|
||||
let field_name =
|
||||
f.ident.clone().map(|i| i.to_string().to_case(Case::Camel)).ok_or_else(|| {
|
||||
Error::new(named_fields.span(), "fields must be named").to_compile_error()
|
||||
})?;
|
||||
|
||||
let field_name = f.ident.as_ref().unwrap().to_string().to_case(Case::Camel);
|
||||
let field_type =
|
||||
match f.attrs.iter().find(|a| a.path.segments.iter().any(|s| s.ident == "eip712")) {
|
||||
match f.attrs.iter().find(|a| a.path().segments.iter().any(|s| s.ident == "eip712")) {
|
||||
// Found nested Eip712 Struct
|
||||
// TODO: Implement custom
|
||||
Some(a) => {
|
||||
return Err(Error::new(a.span(), "nested Eip712 struct are not yet supported")
|
||||
.to_compile_error())
|
||||
return Err(Error::new(a.span(), "nested Eip712 struct are not yet supported"))
|
||||
}
|
||||
// Not a nested eip712 struct, return the field param type;
|
||||
None => find_parameter_type(&f.ty)?,
|
||||
|
|
Loading…
Reference in New Issue