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;