alloy_signer/
error.rs

1use alloy_primitives::{hex, ChainId};
2use k256::ecdsa;
3use std::{fmt, fmt::Display};
4use thiserror::Error;
5
6/// Result type alias for [`Error`](enum@Error).
7pub type Result<T, E = Error> = std::result::Result<T, E>;
8
9/// Generic error type for [`Signer`](crate::Signer) implementations.
10#[derive(Debug, Error)]
11pub enum Error {
12    /// This operation is not supported by the signer.
13    #[error("operation `{0}` is not supported by the signer")]
14    UnsupportedOperation(UnsupportedSignerOperation),
15    /// Mismatch between provided transaction chain ID and signer chain ID.
16    #[error(
17        "transaction-provided chain ID ({tx}) does not match the signer's chain ID ({signer})"
18    )]
19    TransactionChainIdMismatch {
20        /// The signer's chain ID.
21        signer: ChainId,
22        /// The chain ID provided by the transaction.
23        tx: ChainId,
24    },
25    /// [`alloy_dyn_abi`] error.
26    #[error(transparent)]
27    #[cfg(feature = "eip712")]
28    DynAbiError(#[from] alloy_dyn_abi::Error),
29    /// [`ecdsa`] error.
30    #[error(transparent)]
31    Ecdsa(#[from] ecdsa::Error),
32    /// [`hex`](mod@hex) error.
33    #[error(transparent)]
34    HexError(#[from] hex::FromHexError),
35    /// Signature error.
36    #[error(transparent)]
37    SignatureError(#[from] alloy_primitives::SignatureError),
38    /// Generic error.
39    #[error(transparent)]
40    Other(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
41}
42
43impl Error {
44    /// Constructs a new [`Other`](Self::Other) error.
45    #[cold]
46    pub fn other(error: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>) -> Self {
47        Self::Other(error.into())
48    }
49
50    /// Constructs a new [`Other`](Self::Other) with an error message.
51    #[cold]
52    pub fn message(err: impl Display) -> Self {
53        Self::Other(err.to_string().into())
54    }
55
56    /// Returns `true` if the error is [`UnsupportedOperation`](Self::UnsupportedOperation).
57    #[inline]
58    pub const fn is_unsupported(&self) -> bool {
59        matches!(self, Self::UnsupportedOperation(_))
60    }
61
62    /// Returns the [`UnsupportedSignerOperation`] if the error is
63    /// [`UnsupportedOperation`](Self::UnsupportedOperation).
64    #[inline]
65    pub const fn unsupported(&self) -> Option<UnsupportedSignerOperation> {
66        match self {
67            Self::UnsupportedOperation(op) => Some(*op),
68            _ => None,
69        }
70    }
71}
72
73/// An unsupported signer operation.
74#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
75pub enum UnsupportedSignerOperation {
76    /// `sign_hash` is not supported by the signer.
77    SignHash,
78    /// `sign_message` is not supported by the signer.
79    SignMessage,
80    /// `sign_transaction` is not supported by the signer.
81    SignTransaction,
82    /// `sign_typed_data` is not supported by the signer.
83    SignTypedData,
84}
85
86impl fmt::Display for UnsupportedSignerOperation {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        self.as_str().fmt(f)
89    }
90}
91
92impl UnsupportedSignerOperation {
93    /// Returns the string representation of the operation.
94    #[inline]
95    pub const fn as_str(&self) -> &'static str {
96        match self {
97            Self::SignHash => "sign_hash",
98            Self::SignMessage => "sign_message",
99            Self::SignTransaction => "sign_transaction",
100            Self::SignTypedData => "sign_typed_data",
101        }
102    }
103}