use thiserror::Error;
#[derive(Debug, Error)]
pub enum OnchainError {
#[error("Contract call failed: {0}")]
ContractError(String),
#[error("Transaction failed: {0}")]
TransactionFailed(String),
#[error("Insufficient balance: have {have}, need {need}")]
InsufficientBalance { have: String, need: String },
#[error("Token approval failed: {0}")]
ApprovalFailed(String),
#[error("Invalid condition ID: {0}")]
InvalidConditionId(String),
#[error("Invalid address: {0}")]
InvalidAddress(String),
#[error("Invalid amount: {0}")]
InvalidAmount(String),
#[error("Network configuration error: {0}")]
NetworkError(String),
#[error("Wallet error: {0}")]
WalletError(String),
#[error("Provider error: {0}")]
ProviderError(String),
#[error("Signer error: {0}")]
SignerError(String),
#[error("Invalid private key: {0}")]
InvalidPrivateKey(String),
#[error("Configuration error: {0}")]
ConfigurationError(String),
#[error("ABI error: {0}")]
AbiError(String),
#[error("Safe wallet error: {0}")]
SafeError(String),
#[error("Proxy wallet error: {0}")]
ProxyError(String),
#[error("Token not approved: {token} needs approval for {spender}")]
NotApproved { token: String, spender: String },
#[error("Position not found for condition {condition_id}")]
PositionNotFound { condition_id: String },
#[error("Market not yet resolved for condition {0}")]
MarketNotResolved(String),
#[error("Alloy contract error: {0}")]
AlloyContractError(String),
#[error("Alloy primitives error: {0}")]
AlloyPrimitivesError(String),
#[error("Hex decoding error: {0}")]
HexError(#[from] alloy::hex::FromHexError),
#[error("{0}")]
Other(String),
}
pub type Result<T> = std::result::Result<T, OnchainError>;
impl From<alloy::primitives::ruint::ParseError> for OnchainError {
fn from(err: alloy::primitives::ruint::ParseError) -> Self {
OnchainError::AlloyPrimitivesError(err.to_string())
}
}
impl From<std::num::ParseIntError> for OnchainError {
fn from(err: std::num::ParseIntError) -> Self {
OnchainError::InvalidAmount(err.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = OnchainError::InsufficientBalance {
have: "10.0".to_string(),
need: "20.0".to_string(),
};
assert_eq!(
err.to_string(),
"Insufficient balance: have 10.0, need 20.0"
);
}
#[test]
fn test_contract_error() {
let err = OnchainError::ContractError("Revert".to_string());
assert!(err.to_string().contains("Contract call failed"));
}
#[test]
fn test_invalid_condition_id() {
let err = OnchainError::InvalidConditionId("bad_hex".to_string());
assert!(err.to_string().contains("Invalid condition ID"));
}
}