// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.
// OpenEthereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// OpenEthereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with OpenEthereum. If not, see .
//! EIP-712 encoding utilities
//!
//! # Specification
//!
//! `encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)`
//! - data adheres to 𝕊, a structure defined in the rigorous eip-712
//! - `\x01` is needed to comply with EIP-191
//! - `domainSeparator` and `hashStruct` are defined below
//!
//! ## A) domainSeparator
//!
//! `domainSeparator = hashStruct(eip712Domain)`
//!
//!
//! Struct named `EIP712Domain` with the following fields
//!
//! - `name: String`
//! - `version: String`
//! - `chain_id: U256`,
//! - `verifying_contract: H160`
//! - `salt: Option`
//!
//! ## C) hashStruct
//!
//! `hashStruct(s : 𝕊) = keccak256(typeHash ‖ encodeData(s))`
//!
//! `typeHash = keccak256(encodeType(typeOf(s)))`
//!
//! ### i) encodeType
//!
//! - `name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")"`
//! - each member is written as `type ‖ " " ‖ name`
//! - encodings cascade down and are sorted by name
//!
//! ### ii) encodeData
//!
//! - `enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)`
//! - each encoded member is 32-byte long
//!
//! #### a) atomic
//!
//! - `boolean` => `U256`
//! - `address` => `H160`
//! - `uint` => sign-extended `U256` in big endian order
//! - `bytes1:31` => `H@256`
//!
//! #### b) dynamic
//!
//! - `bytes` => `keccak256(bytes)`
//! - `string` => `keccak256(string)`
//!
//! #### c) referenced
//!
//! - `array` => `keccak256(encodeData(array))`
//! - `struct` => `rec(keccak256(hashStruct(struct)))`
//!
//! ## D) Example
//! ### Query
//! ```json
//! {
//! "jsonrpc": "2.0",
//! "method": "eth_signTypedData",
//! "params": [
//! "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
//! {
//! "types": {
//! "EIP712Domain": [
//! {
//! "name": "name",
//! "type": "string"
//! },
//! {
//! "name": "version",
//! "type": "string"
//! },
//! {
//! "name": "chainId",
//! "type": "uint256"
//! },
//! {
//! "name": "verifyingContract",
//! "type": "address"
//! }
//! ],
//! "Person": [
//! {
//! "name": "name",
//! "type": "string"
//! },
//! {
//! "name": "wallet",
//! "type": "address"
//! }
//! ],
//! "Mail": [
//! {
//! "name": "from",
//! "type": "Person"
//! },
//! {
//! "name": "to",
//! "type": "Person"
//! },
//! {
//! "name": "contents",
//! "type": "string"
//! }
//! ]
//! },
//! "primaryType": "Mail",
//! "domain": {
//! "name": "Ether Mail",
//! "version": "1",
//! "chainId": 1,
//! "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
//! },
//! "message": {
//! "from": {
//! "name": "Cow",
//! "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
//! },
//! "to": {
//! "name": "Bob",
//! "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
//! },
//! "contents": "Hello, Bob!"
//! }
//! }
//! ],
//! "id": 1
//! }
//! ```
//
//! ### Response
//! ```json
//! {
//! "id":1,
//! "jsonrpc": "2.0",
//! "result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
//! }
//! ```
#![warn(missing_docs)]
#[macro_use]
extern crate validator_derive;
#[macro_use]
extern crate serde_derive;
mod eip712;
mod encode;
mod error;
mod parser;
/// EIP712 struct
pub use crate::eip712::EIP712;
/// the EIP-712 encoding function
pub use crate::encode::hash_structured_data;
/// encoding Error types
pub use crate::error::{Error, ErrorKind};