diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index d7ef4142639..a9c170ac157 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -9,6 +9,37 @@ use alloy_rlp::{ }; use core::hash::{Hash, Hasher}; +/// Represents the outcome of an attempt to recover the authority from an authorization. +/// It can either be valid (containing an [`Address`]) or invalid (indicating recovery failure). +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum RecoveredAuthority { + /// Indicates a successfully recovered authority address. + Valid(Address), + /// Indicates a failed recovery attempt where no valid address could be recovered. + Invalid, +} + +impl RecoveredAuthority { + /// Returns an optional address if valid. + pub const fn address(&self) -> Option
{ + match *self { + Self::Valid(address) => Some(address), + Self::Invalid => None, + } + } + + /// Returns true if the authority is valid. + pub const fn is_valid(&self) -> bool { + matches!(self, Self::Valid(_)) + } + + /// Returns true if the authority is invalid. + pub const fn is_invalid(&self) -> bool { + matches!(self, Self::Invalid) + } +} + /// An unsigned EIP-7702 authorization. #[derive(Debug, Clone, Hash, RlpEncodable, RlpDecodable, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -158,11 +189,12 @@ impl SignedAuthorization { /// Recover the authority and transform the signed authorization into a /// [`RecoveredAuthorization`]. - pub fn try_into_recovered( - self, - ) -> Result { - let authority = self.recover_authority()?; - Ok(RecoveredAuthorization { inner: self.inner, authority }) + pub fn into_recovered(self) -> RecoveredAuthorization { + let authority_result = self.recover_authority(); + let authority = + authority_result.map_or(RecoveredAuthority::Invalid, RecoveredAuthority::Valid); + + RecoveredAuthorization { inner: self.inner, authority } } } @@ -200,35 +232,41 @@ impl<'a> arbitrary::Arbitrary<'a> for SignedAuthorization { pub struct RecoveredAuthorization { #[cfg_attr(feature = "serde", serde(flatten))] inner: Authorization, - authority: Address, + /// The result of the authority recovery process, which can either be a valid address or + /// indicate a failure. + authority: RecoveredAuthority, } impl RecoveredAuthorization { /// Instantiate without performing recovery. This should be used carefully. - pub const fn new_unchecked(inner: Authorization, authority: Address) -> Self { + pub const fn new_unchecked(inner: Authorization, authority: RecoveredAuthority) -> Self { Self { inner, authority } } - /// Get the `authority` for the authorization. - pub const fn authority(&self) -> Address { - self.authority + /// Returns an optional address based on the current state of the authority. + pub const fn authority(&self) -> Option
{ + self.authority.address() } /// Splits the authorization into parts. - pub const fn into_parts(self) -> (Authorization, Address) { + pub const fn into_parts(self) -> (Authorization, RecoveredAuthority) { (self.inner, self.authority) } } #[cfg(feature = "k256")] -impl TryFrom for RecoveredAuthorization { - type Error = alloy_primitives::SignatureError; - - fn try_from(value: SignedAuthorization) -> Result { - value.try_into_recovered() +impl From for RecoveredAuthority { + fn from(value: SignedAuthorization) -> Self { + value.into_recovered().authority } } +#[cfg(feature = "k256")] +impl From for RecoveredAuthorization { + fn from(value: SignedAuthorization) -> Self { + value.into_recovered() + } +} impl Deref for RecoveredAuthorization { type Target = Authorization;