zescrow_core/
error.rs

1//! Error types for `zescrow_core`.
2//!
3//! Provides the following error types:
4//! - [`EscrowError`]: Top-level error for escrow operations
5//! - [`ConditionError`]: Cryptographic condition verification failures
6//! - [`IdentityError`]: Identity parsing and validation errors
7//! - [`AssetError`]: Asset validation and serialization errors
8
9use thiserror::Error;
10
11use crate::BigNumber;
12
13/// Errors arising from on-chain `Escrow` operations and parameter validation.
14#[derive(Debug, Error)]
15#[non_exhaustive]
16pub enum EscrowError {
17    /// A cryptographic condition failed to verify.
18    #[error("condition error: {0}")]
19    Condition(#[from] ConditionError),
20
21    /// Attempted to transition an `Escrow` in an invalid state.
22    #[error("invalid state transition")]
23    InvalidState,
24
25    /// An identity could not be parsed or validated.
26    #[error("identity error: {0}")]
27    Identity(#[from] IdentityError),
28
29    /// An asset failed parsing, validation, or formatting.
30    #[error("asset error: {0}")]
31    Asset(#[from] AssetError),
32
33    /// Attempted a chain-specific operation on the wrong network
34    /// (e.g., getting Solana PDA on Ethereum).
35    #[error("invalid chain operation: {0}")]
36    InvalidChainOp(String),
37
38    /// An I/O error occurred (e.g., reading or writing JSON files).
39    #[error("I/O error: {0}")]
40    Io(#[from] std::io::Error),
41
42    /// JSON parsing or serialization error.
43    #[cfg(feature = "json")]
44    #[error("JSON error: {0}")]
45    Json(#[from] serde_json::Error),
46
47    /// The specified blockchain network is not supported.
48    #[error("unsupported chain specified")]
49    UnsupportedChain,
50}
51
52/// Errors related to cryptographic condition verification.
53#[derive(Debug, Error)]
54#[non_exhaustive]
55pub enum ConditionError {
56    /// Hashlock error
57    #[error("preimage (hashlock) failed: {0}")]
58    Hashlock(#[from] crate::condition::hashlock::Error),
59
60    /// Ed25519 error
61    #[error("ed25519 signature failed: {0}")]
62    Ed25519(#[from] crate::condition::ed25519::Error),
63
64    /// Secp256k1 error
65    #[error("secp256k1 signature failed: {0}")]
66    Secp256k1(#[from] crate::condition::secp256k1::Error),
67
68    /// Threshold error
69    #[error("threshold check failed: {0}")]
70    Threshold(#[from] crate::condition::threshold::Error),
71}
72
73/// Errors related to identity parsing and validation.
74#[derive(Debug, Error)]
75#[non_exhaustive]
76pub enum IdentityError {
77    /// The provided identity string was empty.
78    #[error("empty identity string")]
79    EmptyIdentity,
80
81    /// The provided identity string exceeds the maximum allowed.
82    #[error("input length {len} exceeds maximum of {max} characters")]
83    InputTooLong {
84        /// Input length
85        len: usize,
86        /// Max allowed
87        max: usize,
88    },
89
90    /// Error decoding a hex-encoded identity.
91    #[error("hex decoding error: {0}")]
92    Hex(#[from] hex::FromHexError),
93
94    /// Error decoding a Base58-encoded identity.
95    #[error("Base58 decoding error: {0}")]
96    Base58(#[from] bs58::decode::Error),
97
98    /// Error decoding a Base64-encoded identity.
99    #[error("Base64 decoding error: {0}")]
100    Base64(#[from] base64::DecodeError),
101
102    /// The input string did not match any supported identity format (hex, Base58, Base64).
103    #[error("unsupported identity format")]
104    UnsupportedFormat,
105}
106
107/// Errors related to asset parsing, validation, or formatting.
108#[derive(Debug, Error)]
109#[non_exhaustive]
110pub enum AssetError {
111    /// Failed to parse an asset from a string or JSON.
112    #[error("could not serialize asset: {0}")]
113    Serialization(String),
114
115    /// Failed to parse an asset from bytes or JSON.
116    #[error("could not parse asset: {0}")]
117    Parsing(String),
118
119    /// A fungible or multi-token amount and/or total supply was zero, which is not allowed.
120    #[error("amount must be non-zero")]
121    ZeroAmount,
122
123    /// ID for asset, program, or contract not provided.
124    #[error("missing ID for asset, program, or contract")]
125    MissingId,
126
127    /// Total supply of token not provided.
128    #[error("missing `total_supply` for specified token")]
129    MissingTotalSupply,
130
131    /// Invalid ID for asset, program, or contract.
132    #[error("invalid ID for asset, program, or contract")]
133    InvalidId,
134
135    /// A liquidity pool share was invalid;
136    /// `share` must be > 0 and <= total supply.
137    #[error("share must be non-zero and <= total supply (share={0}, total={1})")]
138    InvalidShare(BigNumber, BigNumber),
139
140    /// The specified number of decimals was invalid.
141    #[error("invalid decimals: {0}")]
142    InvalidDecimals(u8),
143
144    /// Fixed-point formatting overflow (e.g., amount or decimals too large).
145    #[error("human formatting overflow: amount={0}, decimals={1}")]
146    FormatOverflow(BigNumber, u8),
147
148    /// The provided asset string did not match a supported format.
149    #[error("unsupported asset string format")]
150    UnsupportedFormat,
151
152    /// Error parsing an integer (e.g., token ID or amount) from a string.
153    #[error("integer parsing error: {0}")]
154    ParseInt(#[from] std::num::ParseIntError),
155}
156
157impl EscrowError {
158    /// A helper to bypass the unavailability of the `ToString` trait
159    /// in the RISC Zero guest.
160    pub fn to_str(&self) -> String {
161        self.to_string()
162    }
163}