Skip to main content

erc8128/
error.rs

1/// Errors produced by ERC-8128 signing and verification.
2#[derive(Debug, thiserror::Error)]
3#[non_exhaustive]
4pub enum Erc8128Error {
5    // -- Signing errors --
6    /// The request URL is not absolute or cannot be parsed.
7    #[error("invalid url: {0}")]
8    InvalidUrl(String),
9
10    /// Sign/verify options are invalid (e.g. `expires <= created`).
11    #[error("invalid options: {0}")]
12    InvalidOptions(String),
13
14    /// A Structured Fields value contains forbidden characters.
15    #[error("invalid header value: {0}")]
16    InvalidHeaderValue(String),
17
18    /// A derived component (`@method`, `@authority`, …) produced non-visible-ASCII.
19    #[error("invalid derived value: {0}")]
20    InvalidDerivedValue(String),
21
22    /// A required field is empty or the overall format is wrong.
23    #[error("invalid format: {0}")]
24    InvalidFormat(String),
25
26    /// `content-digest` handling failed during signing.
27    #[error("digest error: {0}")]
28    DigestError(String),
29
30    /// The signer returned an empty or malformed signature.
31    #[error("signing failed: {0}")]
32    SigningFailed(String),
33
34    // -- Verification errors --
35    /// `Signature-Input` / `Signature` headers are missing.
36    #[error("missing signature headers")]
37    MissingHeaders,
38
39    /// The requested signature label was not found.
40    #[error("label not found")]
41    LabelNotFound,
42
43    /// `Signature-Input` / `Signature` could not be parsed.
44    #[error("bad signature input: {0}")]
45    BadSignatureInput(String),
46
47    /// The `keyid` does not match `erc8128:<chainId>:<address>`.
48    #[error("bad keyid")]
49    BadKeyId,
50
51    /// `created` / `expires` are missing, non-integer, or `expires <= created`.
52    #[error("bad time")]
53    BadTime,
54
55    /// Signature is not yet valid (`now + skew < created`).
56    #[error("not yet valid")]
57    NotYetValid,
58
59    /// Signature has expired (`now - skew > expires`).
60    #[error("expired")]
61    Expired,
62
63    /// `expires - created` exceeds the policy maximum.
64    #[error("validity too long")]
65    ValidityTooLong,
66
67    /// Replayable (nonce-less) signature rejected by policy.
68    #[error("replayable not allowed")]
69    ReplayableNotAllowed,
70
71    /// Replayable signature accepted but no invalidation mechanism is provided.
72    /// Required by ERC-8128 Section 3.2.2 + 5.2.
73    #[error("replayable invalidation required")]
74    ReplayableInvalidationRequired,
75
76    /// Replayable signature rejected: `created` before the per-key `not_before` cutoff.
77    #[error("replayable not before")]
78    ReplayableNotBefore,
79
80    /// Replayable signature explicitly invalidated by policy hook.
81    #[error("replayable invalidated")]
82    ReplayableInvalidated,
83
84    /// Signed components do not satisfy request-bound requirements.
85    #[error("not request bound")]
86    NotRequestBound,
87
88    /// Signed components do not match any class-bound policy.
89    #[error("class bound not allowed")]
90    ClassBoundNotAllowed,
91
92    /// `expires - created` exceeds the nonce retention window.
93    #[error("nonce window too long")]
94    NonceWindowTooLong,
95
96    /// `content-digest` header required by components but missing.
97    #[error("digest required")]
98    DigestRequired,
99
100    /// `content-digest` value does not match the body.
101    #[error("digest mismatch")]
102    DigestMismatch,
103
104    /// Signature bytes could not be decoded (bad base64 or empty).
105    #[error("bad signature bytes")]
106    BadSignatureBytes,
107
108    /// The signature is cryptographically invalid.
109    #[error("bad signature")]
110    BadSignature,
111
112    /// The nonce has already been consumed (replay detected).
113    #[error("replay detected")]
114    Replay,
115
116    /// Algorithm is not allowed by policy.
117    #[error("algorithm not allowed")]
118    AlgNotAllowed,
119
120    /// The cryptographic verification call itself failed (e.g. RPC error).
121    #[error("verification failed: {0}")]
122    VerificationFailed(String),
123}