Files
lez-programs/programs/amm/client/src/error.rs
T
Ricardo Guilherme Schmidt a7395aadb7 feat(amm): add reusable client APIs
Add validated shared quote orchestration, canonical planners for every guest instruction, and exact RISC Zero serialization. Expose integer-only slippage preparation and lossless JSON/C adapters without runtime deployment identity checks.
2026-08-10 11:22:44 -03:00

127 lines
4.6 KiB
Rust

use std::{error::Error, fmt};
use nssa_core::{account::AccountId, program::ProgramId};
/// Failure while validating AMM client input or constructing a request.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ClientError {
/// An account ID differs from its canonical or stored value.
AccountIdMismatch {
account: &'static str,
expected: AccountId,
actual: AccountId,
},
/// An account owner differs from the owner required by the program.
ProgramOwnerMismatch {
account: &'static str,
expected: ProgramId,
actual: ProgramId,
},
/// Account bytes cannot be decoded as the required program type.
InvalidAccountData {
account: &'static str,
expected: &'static str,
},
/// A token account is not a fungible holding.
ExpectedFungibleToken { account: &'static str },
/// A token holding points at the wrong definition.
TokenDefinitionMismatch {
account: &'static str,
expected: AccountId,
actual: AccountId,
},
/// A holding cannot cover the amount required by a quoted operation.
InsufficientBalance {
account: &'static str,
available: u128,
required: u128,
},
/// A pool was requested with the same token on both sides.
IdenticalTokenDefinitions,
/// Slippage basis points exceed one whole quoted amount.
SlippageToleranceOutOfRange { bps: u128, maximum_bps: u128 },
/// A slippage-adjusted upper guard exceeds the chain amount range.
SlippageBoundOverflow {
quoted_amount: u128,
slippage_bps: u128,
},
/// Program-owned quote logic rejected the requested transition.
Quote {
code: &'static str,
message: &'static str,
},
}
impl ClientError {
/// Stable machine-readable error code.
#[must_use]
pub const fn code(&self) -> &'static str {
match self {
Self::AccountIdMismatch { .. } => "account_id_mismatch",
Self::ProgramOwnerMismatch { .. } => "program_owner_mismatch",
Self::InvalidAccountData { .. } => "invalid_account_data",
Self::ExpectedFungibleToken { .. } => "expected_fungible_token",
Self::TokenDefinitionMismatch { .. } => "token_definition_mismatch",
Self::InsufficientBalance { .. } => "insufficient_balance",
Self::IdenticalTokenDefinitions => "identical_token_definitions",
Self::SlippageToleranceOutOfRange { .. } => "slippage_tolerance_out_of_range",
Self::SlippageBoundOverflow { .. } => "slippage_bound_overflow",
Self::Quote { code, .. } => code,
}
}
}
impl fmt::Display for ClientError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AccountIdMismatch { account, .. } => {
write!(formatter, "{account} account ID mismatch")
}
Self::ProgramOwnerMismatch { account, .. } => {
write!(formatter, "{account} program owner mismatch")
}
Self::InvalidAccountData { account, expected } => {
write!(
formatter,
"{account} does not contain valid {expected} data"
)
}
Self::ExpectedFungibleToken { account } => {
write!(formatter, "{account} must be a fungible token holding")
}
Self::TokenDefinitionMismatch { account, .. } => {
write!(formatter, "{account} token definition mismatch")
}
Self::InsufficientBalance {
account,
available,
required,
} => write!(
formatter,
"{account} balance {available} is less than required amount {required}"
),
Self::IdenticalTokenDefinitions => {
formatter.write_str("pool token definitions must be distinct")
}
Self::SlippageToleranceOutOfRange {
bps,
maximum_bps,
} => write!(
formatter,
"slippage tolerance {bps} bps exceeds maximum {maximum_bps} bps"
),
Self::SlippageBoundOverflow {
quoted_amount,
slippage_bps,
} => write!(
formatter,
"slippage-adjusted upper guard for {quoted_amount} at {slippage_bps} bps exceeds u128"
),
Self::Quote { message, .. } => formatter.write_str(message),
}
}
}
impl Error for ClientError {}