polymarket 0.1.0

Rust SDK for Polymarket prediction market - CLOB trading, on-chain operations, and WebSocket streaming
Documentation
use thiserror::Error;

/// Onchain operation errors
#[derive(Debug, Error)]
pub enum OnchainError {
    /// Contract call failed
    #[error("Contract call failed: {0}")]
    ContractError(String),

    /// Transaction failed
    #[error("Transaction failed: {0}")]
    TransactionFailed(String),

    /// Insufficient balance for operation
    #[error("Insufficient balance: have {have}, need {need}")]
    InsufficientBalance { have: String, need: String },

    /// Token approval failed
    #[error("Token approval failed: {0}")]
    ApprovalFailed(String),

    /// Invalid condition ID format
    #[error("Invalid condition ID: {0}")]
    InvalidConditionId(String),

    /// Invalid address format
    #[error("Invalid address: {0}")]
    InvalidAddress(String),

    /// Invalid amount
    #[error("Invalid amount: {0}")]
    InvalidAmount(String),

    /// Network configuration error
    #[error("Network configuration error: {0}")]
    NetworkError(String),

    /// Wallet error
    #[error("Wallet error: {0}")]
    WalletError(String),

    /// Provider error
    #[error("Provider error: {0}")]
    ProviderError(String),

    /// Signer error
    #[error("Signer error: {0}")]
    SignerError(String),

    /// Invalid private key
    #[error("Invalid private key: {0}")]
    InvalidPrivateKey(String),

    /// Configuration error
    #[error("Configuration error: {0}")]
    ConfigurationError(String),

    /// ABI encoding/decoding error
    #[error("ABI error: {0}")]
    AbiError(String),

    /// Safe wallet error
    #[error("Safe wallet error: {0}")]
    SafeError(String),

    /// Proxy wallet error
    #[error("Proxy wallet error: {0}")]
    ProxyError(String),

    /// Token not approved for spending
    #[error("Token not approved: {token} needs approval for {spender}")]
    NotApproved { token: String, spender: String },

    /// Position not found
    #[error("Position not found for condition {condition_id}")]
    PositionNotFound { condition_id: String },

    /// Market not resolved
    #[error("Market not yet resolved for condition {0}")]
    MarketNotResolved(String),

    /// Alloy contract error
    #[error("Alloy contract error: {0}")]
    AlloyContractError(String),

    /// Alloy primitives error
    #[error("Alloy primitives error: {0}")]
    AlloyPrimitivesError(String),

    /// Hex decoding error
    #[error("Hex decoding error: {0}")]
    HexError(#[from] alloy::hex::FromHexError),

    /// Generic error for catch-all cases
    #[error("{0}")]
    Other(String),
}

/// Result type for onchain operations
pub type Result<T> = std::result::Result<T, OnchainError>;

// Implement conversions from common alloy errors
// Note: alloy::contract::Error will be added when contract feature is enabled in Phase 2
// impl From<alloy::contract::Error> for OnchainError {
//     fn from(err: alloy::contract::Error) -> Self {
//         OnchainError::AlloyContractError(err.to_string())
//     }
// }

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"));
    }
}