From ba285e52db0f7db23473d0cdf6020edf06816f14 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 6 Feb 2023 15:30:28 -0500 Subject: [PATCH 1/3] feature: allow signature to recover typed_data payloads --- ethers-core/src/types/signature.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ethers-core/src/types/signature.rs b/ethers-core/src/types/signature.rs index 68e60ecb4..b185b8f2a 100644 --- a/ethers-core/src/types/signature.rs +++ b/ethers-core/src/types/signature.rs @@ -17,6 +17,8 @@ use serde::{Deserialize, Serialize}; use std::{convert::TryFrom, fmt, str::FromStr}; use thiserror::Error; +use super::transaction::eip712::Eip712; + /// An error involving a signature. #[derive(Debug, Error)] pub enum SignatureError { @@ -111,6 +113,19 @@ impl Signature { Ok(Address::from_slice(&hash[12..])) } + /// Recovers the ethereum address which was used to sign a given EIP712 + /// typed data payload. + /// + /// Recovery signature data uses 'Electrum' notation, this means the `v` + /// value is expected to be either `27` or `28`. + pub fn recover_typed_data(&self, payload: T) -> Result + where + T: Eip712, + { + let encoded = payload.encode_eip712().map_err(|_| SignatureError::RecoveryError)?; + self.recover(encoded) + } + /// Retrieves the recovery signature. fn as_signature(&self) -> Result<(RecoverableSignature, RecoveryId), SignatureError> { let recovery_id = self.recovery_id()?; From 11c3f57a87e1504db6f75137641a7769acc5dd06 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 6 Feb 2023 15:35:48 -0500 Subject: [PATCH 2/3] fix: under feature flag and Changelog --- CHANGELOG.md | 1 + ethers-core/src/types/signature.rs | 35 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d434c479b..f28bc789a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Unreleased +- Add `Signature::recover_typed_data` [#2120](https://github.com/gakonst/ethers-rs/pull/2120) - Add `abi::encode_packed` [#2104](https://github.com/gakonst/ethers-rs/pull/2104) - Add support for custom JavaScript tracer to `debug_traceCall` and `debug_traceTransaction` [#2064](https://github.com/gakonst/ethers-rs/pull/2064) - Add a `Send` bound to the `IntoFuture` implementation of `ContractCall` [#2083](https://github.com/gakonst/ethers-rs/pull/2083) diff --git a/ethers-core/src/types/signature.rs b/ethers-core/src/types/signature.rs index b185b8f2a..0c377c62f 100644 --- a/ethers-core/src/types/signature.rs +++ b/ethers-core/src/types/signature.rs @@ -17,8 +17,6 @@ use serde::{Deserialize, Serialize}; use std::{convert::TryFrom, fmt, str::FromStr}; use thiserror::Error; -use super::transaction::eip712::Eip712; - /// An error involving a signature. #[derive(Debug, Error)] pub enum SignatureError { @@ -42,8 +40,8 @@ pub enum SignatureError { /// Recovery message data. /// -/// The message data can either be a binary message that is first hashed -/// according to EIP-191 and then recovered based on the signature or a +/// The message data can either be a binary message rst hashed +/// according to EIP-191 and then recovered based on the signathat is fiture or a /// precomputed hash. #[derive(Clone, Debug, PartialEq, Eq)] pub enum RecoveryMessage { @@ -71,6 +69,22 @@ impl fmt::Display for Signature { } } +#[cfg(feature = "eip712")] +impl Signature { + /// Recovers the ethereum address which was used to sign a given EIP712 + /// typed data payload. + /// + /// Recovery signature data uses 'Electrum' notation, this means the `v` + /// value is expected to be either `27` or `28`. + pub fn recover_typed_data(&self, payload: T) -> Result + where + T: super::transaction::eip712::Eip712, + { + let encoded = payload.encode_eip712().map_err(|_| SignatureError::RecoveryError)?; + self.recover(encoded) + } +} + impl Signature { /// Verifies that signature on `message` was produced by `address` pub fn verify(&self, message: M, address: A) -> Result<(), SignatureError> @@ -113,19 +127,6 @@ impl Signature { Ok(Address::from_slice(&hash[12..])) } - /// Recovers the ethereum address which was used to sign a given EIP712 - /// typed data payload. - /// - /// Recovery signature data uses 'Electrum' notation, this means the `v` - /// value is expected to be either `27` or `28`. - pub fn recover_typed_data(&self, payload: T) -> Result - where - T: Eip712, - { - let encoded = payload.encode_eip712().map_err(|_| SignatureError::RecoveryError)?; - self.recover(encoded) - } - /// Retrieves the recovery signature. fn as_signature(&self) -> Result<(RecoverableSignature, RecoveryId), SignatureError> { let recovery_id = self.recovery_id()?; From 4d69ff47d5a95ed5675a4830ab5c128d1dbafc62 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 6 Feb 2023 15:36:33 -0500 Subject: [PATCH 3/3] fix: undo accidental doc mangling --- ethers-core/src/types/signature.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethers-core/src/types/signature.rs b/ethers-core/src/types/signature.rs index 0c377c62f..886f2b771 100644 --- a/ethers-core/src/types/signature.rs +++ b/ethers-core/src/types/signature.rs @@ -40,8 +40,8 @@ pub enum SignatureError { /// Recovery message data. /// -/// The message data can either be a binary message rst hashed -/// according to EIP-191 and then recovered based on the signathat is fiture or a +/// The message data can either be a binary message that is first hashed +/// according to EIP-191 and then recovered based on the signature or a /// precomputed hash. #[derive(Clone, Debug, PartialEq, Eq)] pub enum RecoveryMessage {