use solana_pubkey::Pubkey;
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum PlanError {
#[error("invalid liquidity parameter: {0}")]
InvalidLiquidityParam(String),
#[error("liquidity quote computation failed: {0}")]
QuoteComputation(String),
#[error("token account planning failed: {0}")]
TokenAccountPlanning(String),
#[error("Token-2022 mint extension parse failed: {0}")]
TokenExtensionParse(String),
}
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum FetchError {
#[error("RPC call failed: {0}")]
Rpc(#[from] anyhow::Error),
#[error("invalid fetch input: {0}")]
InvalidInput(String),
#[error("account not found: {0}")]
AccountNotFound(Pubkey),
#[error("account decode failed: {0}")]
AccountDecode(String),
}
impl From<solana_token_toolkit::TokenError> for FetchError {
fn from(err: solana_token_toolkit::TokenError) -> Self {
use solana_token_toolkit::TokenError as T;
match err {
#[cfg(feature = "rpc")]
T::Rpc(client_err) => FetchError::Rpc(anyhow::Error::new(client_err)),
T::MintNotFound(pk) => FetchError::AccountNotFound(pk),
T::MintDecodeFailed { mint, reason } => {
FetchError::AccountDecode(format!("mint {mint}: {reason}"))
}
T::TokenAccountDecodeFailed { token_account, reason } => {
FetchError::AccountDecode(format!("token account {token_account}: {reason}"))
}
T::LengthMismatch { mints, mint_accounts } => FetchError::InvalidInput(format!(
"mints/mint_accounts length mismatch: {mints} vs {mint_accounts}"
)),
T::TransferHookDetected { mint, program } => {
FetchError::InvalidInput(format!("transfer hook on mint {mint}: {program}"))
}
T::WithBalanceNotSupported(pk) => {
FetchError::InvalidInput(format!("WithBalance not supported for {pk}"))
}
err @ T::IncoherentWrapStrategy => FetchError::InvalidInput(err.to_string()),
T::InstructionBuild(msg) => {
FetchError::InvalidInput(format!("instruction build: {msg}"))
}
err @ T::InsufficientBalance { .. } => FetchError::InvalidInput(err.to_string()),
err @ T::RequireBalanceForSolNotSupported(_) => {
FetchError::InvalidInput(err.to_string())
}
_ => FetchError::InvalidInput(err.to_string()),
}
}
}
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum OrchestrateError {
#[error("plan layer failed: {0}")]
Plan(#[from] PlanError),
#[error("fetch layer failed: {0}")]
Fetch(#[from] FetchError),
#[error("transaction send failed: {0}")]
Send(#[source] anyhow::Error),
}