is it bette rthan this file ? use base64;
use dashmap::DashMap;
use log::{debug, error, info};
use once_cell::sync::OnceCell;
use parking_lot::RwLock;
use pyo3::exceptions::{PyFileNotFoundError, PyRuntimeError, PyValueError};
use pyo3::prelude::*;
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_TYPE};
use solana_client::rpc_client::RpcClient;
use solana_client::rpc_config::RpcSendTransactionConfig;
use solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel};
use solana_sdk::compute_budget::ComputeBudgetInstruction;
use solana_sdk::hash::Hash;
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::program_pack::Pack;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{read_keypair_file, Keypair, Signature, Signer};
use solana_sdk::transaction::Transaction;
use solana_sdk::transaction::TransactionError;
use solana_transaction_status::UiTransactionEncoding;
use spl_associated_token_account::{
    get_associated_token_address, instruction::create_associated_token_account_idempotent,
};
use spl_token;
use std::env;
use std::path::Path;
use std::str::FromStr;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::runtime::Runtime;

// Add this new struct above your SolanaTrader implementation
struct SafeRpcClient {
    inner: RpcClient,
}

impl SafeRpcClient {
    fn new(url: &str, timeout: Duration, commitment_config: CommitmentConfig) -> Self {
        // Always strip trailing slash from URL
        let clean_url = url.trim_end_matches('/');
        // Create RPC client with cleaned URL and shortened timeout
        let inner =
            RpcClient::new_with_timeout_and_commitment(clean_url, timeout, commitment_config);
        SafeRpcClient { inner }
    }
}

// Implement required methods by delegating to inner client
impl SafeRpcClient {
    fn get_latest_blockhash(&self) -> Result<Hash, solana_client::client_error::ClientError> {
        self.inner.get_latest_blockhash()
    }
    fn get_balance(
        &self,
        pubkey: &Pubkey,
    ) -> Result<u64, solana_client::client_error::ClientError> {
        self.inner.get_balance(pubkey)
    }
    fn get_account_data(
        &self,
        pubkey: &Pubkey,
    ) -> Result<Vec<u8>, solana_client::client_error::ClientError> {
        self.inner.get_account_data(pubkey)
    }
    fn send_and_confirm_transaction(
        &self,
        transaction: &Transaction,
    ) -> Result<Signature, solana_client::client_error::ClientError> {
        self.inner.send_and_confirm_transaction(transaction)
    }
    fn send_transaction_with_config(
        &self,
        transaction: &Transaction,
        config: RpcSendTransactionConfig,
    ) -> Result<Signature, solana_client::client_error::ClientError> {
        self.inner.send_transaction_with_config(transaction, config)
    }
    fn get_signature_status(
        &self,
        signature: &Signature,
    ) -> Result<Option<Result<(), TransactionError>>, solana_client::client_error::ClientError>
    {
        self.inner.get_signature_status(signature)
    }
}

struct FastBlockhashCache {
    blockhash: RwLock<Hash>,
    last_update: RwLock<Instant>,
    update_interval: Duration,
    rpc_client: Arc<SafeRpcClient>,
}

impl FastBlockhashCache {
    fn new(rpc_client: Arc<SafeRpcClient>, update_interval_seconds: u64) -> Self {
        let mut attempts = 0;
        let max_attempts = 3; // Increased max attempts since we'll retry very quickly
        let mut blockhash: Option<Hash> = None;

        while attempts < max_attempts {
            match rpc_client.get_latest_blockhash() {
                Ok(hash) => {
                    blockhash = Some(hash);
                    info!("Successfully retrieved initial blockhash");
                    break;
                }
                Err(_) => {
                    // No error logging, just increment attempts
                    attempts += 1;
                    // No sleep delay - retry immediately
                }
            }
        }

        let blockhash = blockhash.unwrap_or_else(|| {
            // Use debug level instead of error to be less visible
            debug!("Using default blockhash, will update shortly");
            Hash::default()
        });

        Self {
            blockhash: RwLock::new(blockhash),
            last_update: RwLock::new(Instant::now()),
            update_interval: Duration::from_secs(update_interval_seconds),
            rpc_client,
        }
    }

    fn get_blockhash(&self) -> Hash {
        let should_update = {
            let last_update = self.last_update.read();
            last_update.elapsed() >= self.update_interval
        };

        if should_update {
            let mut attempts = 0;
            let max_attempts = 5;

            while attempts < max_attempts {
                match self.rpc_client.get_latest_blockhash() {
                    Ok(new_hash) => {
                        *self.blockhash.write() = new_hash;
                        *self.last_update.write() = Instant::now();
                        break;
                    }
                    Err(_) => {
                        // No error logging, just increment attempts
                        attempts += 1;
                        // No sleep delay for faster retries
                    }
                }
            }
        }

        *self.blockhash.read()
    }

    fn force_update(&self) -> Hash {
        match self.rpc_client.get_latest_blockhash() {
            Ok(new_hash) => {
                *self.blockhash.write() = new_hash;
                *self.last_update.write() = Instant::now();
                new_hash
            }
            Err(_) => {
                // No error logging
                *self.blockhash.read()
            }
        }
    }
}

struct JupiterCache {
    routes: DashMap<String, (serde_json::Value, Instant)>,
    ttl: Duration,
}

impl JupiterCache {
    fn new(ttl_seconds: u64) -> Self {
        Self {
            routes: DashMap::new(),
            ttl: Duration::from_secs(ttl_seconds),
        }
    }

    fn get(&self, key: &str) -> Option<serde_json::Value> {
        if let Some(entry) = self.routes.get(key) {
            if entry.1.elapsed() < self.ttl {
                return Some(entry.0.clone());
            }
        }
        None
    }

    fn set(&self, key: String, value: serde_json::Value) {
        self.routes.insert(key, (value, Instant::now()));
    }

    fn clear_expired(&self) {
        let now = Instant::now();
        let expired_keys: Vec<String> = self
            .routes
            .iter()
            .filter(|r| now.duration_since(r.value().1) >= self.ttl)
            .map(|r| r.key().clone())
            .collect();

        for key in expired_keys {
            self.routes.remove(&key);
        }
    }
}

static TOKEN_DECIMALS_CACHE: once_cell::sync::Lazy<DashMap<String, u8>> =
    once_cell::sync::Lazy::new(|| DashMap::new());

static BLOCKHASH_CACHE: once_cell::sync::Lazy<OnceCell<Arc<FastBlockhashCache>>> =
    once_cell::sync::Lazy::new(OnceCell::new);

static JUPITER_CACHE: once_cell::sync::Lazy<OnceCell<Arc<JupiterCache>>> =
    once_cell::sync::Lazy::new(OnceCell::new);

const LAMPORTS_PER_SOL: u64 = 1_000_000_000;
const WSOL_ADDRESS: &str = "So11111111111111111111111111111111111111112";
const TOKEN_PROGRAM_ID: &str = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
const RAYDIUM_PROGRAM_ID: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
const SERUM_PROGRAM_ID: &str = "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin";

const JUPITER_QUOTE_API: &str = "https://quote-api.jup.ag/v6/quote";
const JUPITER_SWAP_API: &str = "https://quote-api.jup.ag/v6/swap-instructions";

const RAYDIUM_SWAP_INSTRUCTION: u8 = 9;
const DEFAULT_COMPUTE_LIMIT: u32 = 200_000;
const DEFAULT_PRIORITY_FEE: u64 = 60_000;
const DEFAULT_SLIPPAGE: f64 = 0.03;
const DEFAULT_MAX_RETRIES: usize = 5;

const DEFAULT_MIN_SOL_BALANCE: f64 = 0.05;
const DEFAULT_MIN_WSOL_BALANCE: f64 = 0.0;

struct PyError(String);

impl From<PyError> for PyErr {
    fn from(e: PyError) -> PyErr {
        PyRuntimeError::new_err(e.0)
    }
}

fn get_tokio_runtime() -> &'static Runtime {
    static RUNTIME: OnceCell<Runtime> = OnceCell::new();
    RUNTIME.get_or_init(|| Runtime::new().expect("Failed to create Tokio runtime"))
}

#[derive(Debug, Clone)]
struct RaydiumSwapAccounts {
    amm_id: String,
    amm_authority: String,
    amm_open_orders: String,
    amm_target_orders: String,
    pool_coin_token_account: String,
    pool_pc_token_account: String,
    serum_program_id: String,
    serum_market: String,
    serum_bids: String,
    serum_asks: String,
    serum_event_queue: String,
    serum_coin_vault: String,
    serum_pc_vault: String,
    serum_vault_signer: String,
    token_mint: String,
    token_program_id: String,
}

#[pyclass]
struct SolanaTrader {
    keypair: Arc<Keypair>,
    rpc_client: Arc<SafeRpcClient>,
    rpc_url: String,
    ws_url: String,
    compute_limit: u32,
    priority_fee: u64,
    skip_preflight: bool,
    max_retries: usize,
    min_sol_balance: f64,
    min_wsol_balance: f64,
    wsol_address: String,
    token_program_id: String,
    system_program_id: String,
    raydium_program_id: String,
    serum_program_id: String,
    keypair_path: String,
    http_client: reqwest::blocking::Client,
    api_key: Option<String>,
}

#[pymethods]
impl SolanaTrader {
    #[new]
    fn new(
        rpc_url: String,
        ws_url: String,
        keypair_path: String,
        compute_limit: Option<u32>,
        api_key: Option<String>,
    ) -> PyResult<Self> {
        // Tokio runtime initialization
        let _ = get_tokio_runtime();

        // Load env variables if .env exists
        let _ = dotenv::dotenv();

        // Get API key from param or environment
        let api_key = api_key.or_else(|| env::var("HELIUS_API_KEY").ok());
        if let Some(key) = &api_key {
            info!("Using API key for authentication");
        }

        // Keypair loading robust
        let keypair = if Path::new(&keypair_path).exists() {
            match read_keypair_file(&keypair_path) {
                Ok(kp) => kp,
                Err(_) => match std::fs::read(&keypair_path) {
                    Ok(bytes) => {
                        if bytes.len() == 64 {
                            match Keypair::from_bytes(&bytes) {
                                Ok(kp) => kp,
                                Err(e) => {
                                    return Err(PyValueError::new_err(format!(
                                        "Invalid binary keypair: {}",
                                        e
                                    )))
                                }
                            }
                        } else {
                            match bs58::decode(std::str::from_utf8(&bytes).unwrap_or(""))
                                .into_vec()
                                .map(|secret_key| Keypair::from_bytes(&secret_key))
                            {
                                Ok(Ok(kp)) => kp,
                                _ => {
                                    return Err(PyValueError::new_err(
                                        "Could not parse keypair file in any format",
                                    ))
                                }
                            }
                        }
                    }
                    Err(e) => {
                        return Err(PyRuntimeError::new_err(format!(
                            "Failed to read keypair file: {}",
                            e
                        )))
                    }
                },
            }
        } else {
            return Err(PyFileNotFoundError::new_err(format!(
                "Keypair file not found: {}",
                keypair_path
            )));
        };

        // === FIXED RPC and WS URL handling ===
        // RPC: always trim trailing slash
        let rpc_url = rpc_url.trim_end_matches('/').to_string();
        
        let ws_url = ws_url.trim_end_matches('/').to_string();

        // Create safe RPC client
        let safe_rpc_client = {
            let commitment_config = CommitmentConfig::processed();
            // Change this line from 1 second to 1200ms:
            let timeout = Duration::from_millis(1200); // Changed from seconds to 1200ms

            let client =
                SafeRpcClient::new(&rpc_url.trim_end_matches('/'), timeout, commitment_config);

            Arc::new(client)
        };

        // Read env vars with fallbacks
        let compute = compute_limit.unwrap_or_else(|| {
            env::var("COMPUTE_LIMIT")
                .map(|v| v.parse::<u32>().unwrap_or(DEFAULT_COMPUTE_LIMIT))
                .unwrap_or(DEFAULT_COMPUTE_LIMIT)
        });

        let priority_fee = env::var("PRIORITY_FEE")
            .map(|v| v.parse::<u64>().unwrap_or(DEFAULT_PRIORITY_FEE))
            .unwrap_or(DEFAULT_PRIORITY_FEE);

        let skip_preflight = env::var("SKIP_PREFLIGHT")
            .map(|v| v.parse::<bool>().unwrap_or(true))
            .unwrap_or(true);

        let max_retries = env::var("MAX_RETRIES")
            .map(|v| v.parse::<usize>().unwrap_or(DEFAULT_MAX_RETRIES))
            .unwrap_or(DEFAULT_MAX_RETRIES);

        let min_sol_balance = env::var("MIN_SOL_BALANCE")
            .map(|v| v.parse::<f64>().unwrap_or(DEFAULT_MIN_SOL_BALANCE))
            .unwrap_or(DEFAULT_MIN_SOL_BALANCE);

        let min_wsol_balance = env::var("MIN_WSOL_BALANCE")
            .map(|v| v.parse::<f64>().unwrap_or(DEFAULT_MIN_WSOL_BALANCE))
            .unwrap_or(DEFAULT_MIN_WSOL_BALANCE);

        let http_client = {
            let builder = reqwest::blocking::Client::builder()
                .timeout(Duration::from_millis(900))
                .connect_timeout(Duration::from_millis(600))
                .pool_max_idle_per_host(32);

            let mut headers = HeaderMap::new();

            if let Ok(value) = HeaderValue::from_str(
                "solana-cli 1.18.23 (src:aeb3a2e1; feat:4215500110, client:SolanaLabs)",
            ) {
                headers.insert(reqwest::header::USER_AGENT, value);
                headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
            }

            if let Some(key) = &api_key {
                let auth_value = format!("Bearer {}", key);
                if let Ok(value) = HeaderValue::from_str(&auth_value) {
                    headers.insert(AUTHORIZATION, value);
                }
            }

            builder.default_headers(headers).build()
        }
        .unwrap_or_else(|_| reqwest::blocking::Client::new());

        // Initialize fast blockhash cache with safe client
        BLOCKHASH_CACHE.get_or_init(|| {
            let cache = FastBlockhashCache::new(
                safe_rpc_client.clone(),
                10, // Cache for 10 seconds
            );
            Arc::new(cache)
        });

        JUPITER_CACHE.get_or_init(|| {
            let cache = JupiterCache::new(60);
            Arc::new(cache)
        });

        {
            let jupiter_cache = JUPITER_CACHE.get().unwrap().clone();
            std::thread::spawn(move || loop {
                std::thread::sleep(Duration::from_secs(60));
                jupiter_cache.clear_expired();
                debug!("Cleared expired Jupiter cache entries");
            });
        }

        info!(
            "Initialized trader with compute_limit: {}, priority_fee: {}",
            compute, priority_fee
        );

        Ok(Self {
            keypair: Arc::new(keypair),
            rpc_client: safe_rpc_client,
            rpc_url,
            ws_url,
            compute_limit: compute,
            priority_fee,
            skip_preflight,
            max_retries,
            min_sol_balance,
            min_wsol_balance,
            wsol_address: WSOL_ADDRESS.to_string(),
            token_program_id: TOKEN_PROGRAM_ID.to_string(),
            system_program_id: "11111111111111111111111111111111".to_string(),
            raydium_program_id: RAYDIUM_PROGRAM_ID.to_string(),
            serum_program_id: SERUM_PROGRAM_ID.to_string(),
            keypair_path,
            http_client,
            api_key,
        })
    }
    
    /// Execute token swap using Jupiter (Solana's DEX aggregator) - Optimized implementation
    fn execute_jupiter_swap(
        &self,
        py: Python<'_>,
        input_mint: String,
        output_mint: String,
        amount_sol: f64,
        slippage_percent: Option<f64>,
        priority_multiplier: Option<u64>,
    ) -> PyResult<String> {
        let amount_lamports = (amount_sol * LAMPORTS_PER_SOL as f64).round() as u64;

        let slippage = match slippage_percent {
            Some(val) => val / 100.0,
            None => DEFAULT_SLIPPAGE,
        };
        let slippage_bps = (slippage * 10000.0) as u32;

        let priority_multiplier_value = priority_multiplier.unwrap_or(1);
        let priority_fee_value = self.priority_fee * priority_multiplier_value;

        py.allow_threads(|| {
            let cache_key = format!(
                "{}:{}:{}:{}",
                input_mint, output_mint, amount_lamports, slippage_bps
            );
            let jupiter_cache = JUPITER_CACHE.get().unwrap();

            let quote_response = match jupiter_cache.get(&cache_key) {
                Some(cached) => {
                    debug!("Jupiter quote cache hit: {}", cache_key);
                    cached
                }
                None => {
                    let quote_url = format!(
                        "{}?inputMint={}&outputMint={}&amount={}&slippageBps={}",
                        JUPITER_QUOTE_API, input_mint, output_mint, amount_lamports, slippage_bps
                    );

                    info!("Getting Jupiter quote: {}", quote_url);

                    let mut retries = 0;
                    let max_retries = 5;

                    loop {
                        let mut request = self.http_client.get(&quote_url);
                        if let Some(key) = &self.api_key {
                            request = request.header(AUTHORIZATION, format!("Bearer {}", key));
                        }

                        match request.send() {
                            Ok(response) => {
                                if response.status().is_success() {
                                    match response.json::<serde_json::Value>() {
                                        Ok(quote_data) => {
                                            if quote_data.get("error").is_some() {
                                                let error_msg = quote_data["error"]
                                                    .as_str()
                                                    .unwrap_or("Unknown error");
                                                error!("Jupiter quote error: {}", error_msg);
                                                return Err(PyError(format!(
                                                    "Jupiter quote error: {}",
                                                    error_msg
                                                ))
                                                .into());
                                            }
                                            jupiter_cache
                                                .set(cache_key.clone(), quote_data.clone());
                                            break quote_data;
                                        }
                                        Err(e) => {
                                            error!("Failed to parse Jupiter quote response: {}", e);
                                            return Err(PyError(format!(
                                                "Failed to parse Jupiter quote: {}",
                                                e
                                            ))
                                            .into());
                                        }
                                    }
                                } else {
                                    let status = response.status();
                                    error!("Jupiter API error: HTTP {}", status);

                                    if status.is_server_error() && retries < max_retries {
                                        retries += 1;
                                        let wait_time = 50 * retries;
                                        std::thread::sleep(Duration::from_millis(wait_time));
                                        continue;
                                    }

                                    return Err(PyError(format!(
                                        "Jupiter API error: HTTP {}",
                                        status
                                    ))
                                    .into());
                                }
                            }
                            Err(e) => {
                                error!("Jupiter API request failed: {}", e);

                                if retries < max_retries {
                                    retries += 1;
                                    let wait_time = 50 * retries;
                                    std::thread::sleep(Duration::from_millis(wait_time));
                                    continue;
                                }

                                return Err(
                                    PyError(format!("Jupiter API request failed: {}", e)).into()
                                );
                            }
                        }
                    }
                }
            };

            let max_accounts = env::var("MAX_ACCOUNTS")
                .map(|v| v.parse::<u32>().unwrap_or(8))
                .unwrap_or(8);

            let instr_payload = serde_json::json!({
                "quoteResponse": quote_response,
                "userPublicKey": self.keypair.pubkey().to_string(),
                "computeUnitPriceMicroLamports": priority_fee_value,
                "wrapUnwrapSOL": true,
                "onlyDirectRoutes": true,
                "maxHops": 1,
                "maxAccounts": max_accounts
            });

            info!("Getting Jupiter swap instructions");

            let mut retries = 0;
            let max_retries = 3;

            let instr_response = loop {
                let mut request = self.http_client.post(JUPITER_SWAP_API).json(&instr_payload);
                if let Some(key) = &self.api_key {
                    request = request.header(AUTHORIZATION, format!("Bearer {}", key));
                }

                match request.send() {
                    Ok(response) => {
                        if response.status().is_success() {
                            match response.json::<serde_json::Value>() {
                                Ok(instr_data) => {
                                    if instr_data.get("error").is_some() {
                                        let error_msg =
                                            instr_data["error"].as_str().unwrap_or("Unknown error");
                                        error!("Jupiter instructions error: {}", error_msg);
                                        return Err(PyError(format!(
                                            "Jupiter instructions error: {}",
                                            error_msg
                                        ))
                                        .into());
                                    }

                                    break instr_data;
                                }
                                Err(e) => {
                                    error!("Failed to parse Jupiter instructions response: {}", e);
                                    return Err(PyError(format!(
                                        "Failed to parse Jupiter instructions response: {}",
                                        e
                                    ))
                                    .into());
                                }
                            }
                        } else {
                            let status = response.status();
                            error!("Jupiter API error: HTTP {}", status);

                            if status.is_server_error() && retries < max_retries {
                                retries += 1;
                                let wait_time = 50 * retries;
                                std::thread::sleep(Duration::from_millis(wait_time));
                                continue;
                            }

                            return Err(
                                PyError(format!("Jupiter API error: HTTP {}", status)).into()
                            );
                        }
                    }
                    Err(e) => {
                        error!("Jupiter API request failed: {}", e);

                        if retries < max_retries {
                            retries += 1;
                            let wait_time = 50 * retries;
                            std::thread::sleep(Duration::from_millis(wait_time));
                            continue;
                        }

                        return Err(PyError(format!("Jupiter API request failed: {}", e)).into());
                    }
                }
            };

            let mut essential_instructions = Vec::new();

            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(
                self.compute_limit,
            ));
            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(
                priority_fee_value,
            ));

            if let Some(setup_instructions) = instr_response
                .get("setupInstructions")
                .and_then(|v| v.as_array())
            {
                for instr in setup_instructions {
                    let program_id_str = instr["programId"].as_str().ok_or_else(|| {
                        error!("Program ID not found in setup instruction");
                        PyError("Program ID not found in setup instruction".to_string())
                    })?;
                    let program_id = Pubkey::from_str(program_id_str).map_err(|e| {
                        error!("Invalid program ID: {}", e);
                        PyError(format!("Invalid program ID: {}", e))
                    })?;

                    let accounts_arr = instr["accounts"].as_array().ok_or_else(|| {
                        error!("Accounts not found in setup instruction");
                        PyError("Accounts not found in setup instruction".to_string())
                    })?;

                    let mut accounts = Vec::new();

                    for account in accounts_arr {
                        let pubkey_str = account["pubkey"].as_str().ok_or_else(|| {
                            error!("Pubkey not found in account");
                            PyError("Pubkey not found in account".to_string())
                        })?;
                        let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {
                            error!("Invalid pubkey: {}", e);
                            PyError(format!("Invalid pubkey: {}", e))
                        })?;

                        let is_signer = account["isSigner"].as_bool().unwrap_or(false);
                        let is_writable = account["isWritable"].as_bool().unwrap_or(false);

                        let account_meta = if is_writable {
                            if is_signer {
                                AccountMeta::new(pubkey, true)
                            } else {
                                AccountMeta::new(pubkey, false)
                            }
                        } else {
                            if is_signer {
                                AccountMeta::new_readonly(pubkey, true)
                            } else {
                                AccountMeta::new_readonly(pubkey, false)
                            }
                        };

                        accounts.push(account_meta);
                    }

                    let data_str = instr["data"].as_str().ok_or_else(|| {
                        error!("Data not found in setup instruction");
                        PyError("Data not found in setup instruction".to_string())
                    })?;

                    let data = base64::decode(data_str).map_err(|e| {
                        error!("Failed to decode setup instruction data: {}", e);
                        PyError(format!("Failed to decode setup instruction data: {}", e))
                    })?;

                    let instruction = Instruction {
                        program_id,
                        accounts,
                        data,
                    };

                    essential_instructions.push(instruction);
                }
            }

            if let Some(swap_instr) = instr_response.get("swapInstruction") {
                let program_id_str = swap_instr["programId"].as_str().ok_or_else(|| {
                    error!("Program ID not found in swap instruction");
                    PyError("Program ID not found in swap instruction".to_string())
                })?;
                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {
                    error!("Invalid program ID: {}", e);
                    PyError(format!("Invalid program ID: {}", e))
                })?;

                let accounts_arr = swap_instr["accounts"].as_array().ok_or_else(|| {
                    error!("Accounts not found in swap instruction");
                    PyError("Accounts not found in swap instruction".to_string())
                })?;

                let mut accounts = Vec::new();

                for account in accounts_arr {
                    let pubkey_str = account["pubkey"].as_str().ok_or_else(|| {
                        error!("Pubkey not found in account");
                        PyError("Pubkey not found in account".to_string())
                    })?;
                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {
                        error!("Invalid pubkey: {}", e);
                        PyError(format!("Invalid pubkey: {}", e))
                    })?;

                    let is_signer = account["isSigner"].as_bool().unwrap_or(false);
                    let is_writable = account["isWritable"].as_bool().unwrap_or(false);

                    let account_meta = if is_writable {
                        if is_signer {
                            AccountMeta::new(pubkey, true)
                        } else {
                            AccountMeta::new(pubkey, false)
                        }
                    } else {
                        if is_signer {
                            AccountMeta::new_readonly(pubkey, true)
                        } else {
                            AccountMeta::new_readonly(pubkey, false)
                        }
                    };

                    accounts.push(account_meta);
                }

                let data_str = swap_instr["data"].as_str().ok_or_else(|| {
                    error!("Data not found in swap instruction");
                    PyError("Data not found in swap instruction".to_string())
                })?;

                let data = base64::decode(data_str).map_err(|e| {
                    error!("Failed to decode swap instruction data: {}", e);
                    PyError(format!("Failed to decode swap instruction data: {}", e))
                })?;

                let instruction = Instruction {
                    program_id,
                    accounts,
                    data,
                };

                essential_instructions.push(instruction);
            } else {
                error!("No swap instruction found in response");
                return Err(
                    PyError("Jupiter swap instruction not found in response".to_string()).into(),
                );
            }

            if let Some(cleanup_instr) = instr_response.get("cleanupInstruction") {
                let program_id_str = cleanup_instr["programId"].as_str().ok_or_else(|| {
                    error!("Program ID not found in cleanup instruction");
                    PyError("Program ID not found in cleanup instruction".to_string())
                })?;
                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {
                    error!("Invalid program ID: {}", e);
                    PyError(format!("Invalid program ID: {}", e))
                })?;

                let accounts_arr = cleanup_instr["accounts"].as_array().ok_or_else(|| {
                    error!("Accounts not found in cleanup instruction");
                    PyError("Accounts not found in cleanup instruction".to_string())
                })?;

                let mut accounts = Vec::new();

                for account in accounts_arr {
                    let pubkey_str = account["pubkey"].as_str().ok_or_else(|| {
                        error!("Pubkey not found in account");
                        PyError("Pubkey not found in account".to_string())
                    })?;
                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {
                        error!("Invalid pubkey: {}", e);
                        PyError(format!("Invalid pubkey: {}", e))
                    })?;

                    let is_signer = account["isSigner"].as_bool().unwrap_or(false);
                    let is_writable = account["isWritable"].as_bool().unwrap_or(false);

                    let account_meta = if is_writable {
                        if is_signer {
                            AccountMeta::new(pubkey, true)
                        } else {
                            AccountMeta::new(pubkey, false)
                        }
                    } else {
                        if is_signer {
                            AccountMeta::new_readonly(pubkey, true)
                        } else {
                            AccountMeta::new_readonly(pubkey, false)
                        }
                    };

                    accounts.push(account_meta);
                }

                let data_str = cleanup_instr["data"].as_str().ok_or_else(|| {
                    error!("Data not found in cleanup instruction");
                    PyError("Data not found in cleanup instruction".to_string())
                })?;

                let data = base64::decode(data_str).map_err(|e| {
                    error!("Failed to decode cleanup instruction data: {}", e);
                    PyError(format!("Failed to decode cleanup instruction data: {}", e))
                })?;

                let instruction = Instruction {
                    program_id,
                    accounts,
                    data,
                };

                essential_instructions.push(instruction);
            }

            if essential_instructions.len() <= 2 {
                error!("No Jupiter instructions found in response");
                return Err(
                    PyError("Jupiter instructions not found in response".to_string()).into(),
                );
            }

            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();
            let blockhash = blockhash_cache.get_blockhash();
            debug!("Using cached blockhash: {}", blockhash);

            let mut transaction = Transaction::new_signed_with_payer(
                &essential_instructions,
                Some(&self.keypair.pubkey()),
                &[&self.keypair],
                blockhash,
            );

            let send_config = RpcSendTransactionConfig {
                skip_preflight: self.skip_preflight,
                preflight_commitment: Some(CommitmentLevel::Processed),
                encoding: Some(UiTransactionEncoding::Base64),
                max_retries: Some(self.max_retries),
                ..Default::default()
            };

            let mut retry_count = 0;
            let max_retries = 2;

            while retry_count <= max_retries {
                match self
                    .rpc_client
                    .send_transaction_with_config(&transaction, send_config.clone())
                {
                    Ok(signature) => {
                        info!(
                            "Jupiter swap executed: {} SOL from {} to {} with signature {}",
                            amount_sol, input_mint, output_mint, signature
                        );
                        return Ok(signature.to_string());
                    }
                    Err(e) => {
                        let error_str = e.to_string();

                        if error_str.contains("blockhash") && retry_count < max_retries {
                            error!(
                                "Blockhash error, retrying with fresh blockhash: {}",
                                error_str
                            );

                            let new_blockhash = blockhash_cache.force_update();

                            let new_transaction = Transaction::new_signed_with_payer(
                                &essential_instructions,
                                Some(&self.keypair.pubkey()),
                                &[&self.keypair],
                                new_blockhash,
                            );

                            transaction = new_transaction;

                            retry_count += 1;
                            continue;
                        }

                        error!("Failed to send transaction: {}", e);
                        return Err(PyError(format!("Failed to send transaction: {}", e)).into());
                    }
                }
            }

            Err(PyError("Max retries exceeded".to_string()).into())
        })
    }

    /// Sell tokens for SOL via Jupiter - Optimized version
    fn sell_token_for_sol_via_jupiter(
        &self,
        py: Python<'_>,
        token_mint: String,
        amount_tokens: f64,
        slippage_percent: Option<f64>,
        priority_multiplier: Option<u64>,
    ) -> PyResult<String> {
        let token_decimals = self.get_token_decimals(py, token_mint.clone())?;

        let amount_in = (amount_tokens * 10f64.powi(token_decimals as i32)) as u64;

        let slippage = match slippage_percent {
            Some(val) => val / 100.0,
            None => DEFAULT_SLIPPAGE,
        };
        let slippage_bps = (slippage * 10000.0) as u32;

        let priority_multiplier_value = priority_multiplier.unwrap_or(1);
        let priority_fee_value = self.priority_fee * priority_multiplier_value;

        let sol_mint = WSOL_ADDRESS.to_string();

        let max_accounts = env::var("MAX_ACCOUNTS")
            .map(|v| v.parse::<u32>().unwrap_or(8))
            .unwrap_or(8);

        py.allow_threads(|| {
            let cache_key = format!("{}:{}:{}:{}", token_mint, sol_mint, amount_in, slippage_bps);
            let jupiter_cache = JUPITER_CACHE.get().unwrap();

            let quote_response = match jupiter_cache.get(&cache_key) {
                Some(cached) => {
                    debug!("Jupiter quote cache hit: {}", cache_key);
                    cached
                }
                None => {
                    let quote_url = format!(
                        "{}?inputMint={}&outputMint={}&amount={}&slippageBps={}",
                        JUPITER_QUOTE_API, token_mint, sol_mint, amount_in, slippage_bps
                    );

                    info!("Getting Jupiter quote for token sell: {}", quote_url);

                    let mut retries = 0;
                    let max_retries = 3;

                    loop {
                        let mut request = self.http_client.get(&quote_url);
                        if let Some(key) = &self.api_key {
                            request = request.header(AUTHORIZATION, format!("Bearer {}", key));
                        }

                        match request.send() {
                            Ok(response) => {
                                if response.status().is_success() {
                                    match response.json::<serde_json::Value>() {
                                        Ok(quote_data) => {
                                            if quote_data.get("error").is_some() {
                                                let error_msg = quote_data["error"]
                                                    .as_str()
                                                    .unwrap_or("Unknown error");
                                                error!("Jupiter quote error: {}", error_msg);
                                                return Err(PyError(format!(
                                                    "Jupiter quote error: {}",
                                                    error_msg
                                                ))
                                                .into());
                                            }
                                            jupiter_cache
                                                .set(cache_key.clone(), quote_data.clone());
                                            break quote_data;
                                        }
                                        Err(e) => {
                                            error!("Failed to parse Jupiter quote response: {}", e);
                                            return Err(PyError(format!(
                                                "Failed to parse Jupiter quote: {}",
                                                e
                                            ))
                                            .into());
                                        }
                                    }
                                } else {
                                    let status = response.status();
                                    error!("Jupiter API error: HTTP {}", status);

                                    if status.is_server_error() && retries < max_retries {
                                        retries += 1;
                                        let wait_time = 50 * retries;
                                        std::thread::sleep(Duration::from_millis(wait_time));
                                        continue;
                                    }

                                    return Err(PyError(format!(
                                        "Jupiter API error: HTTP {}",
                                        status
                                    ))
                                    .into());
                                }
                            }
                            Err(e) => {
                                error!("Jupiter API request failed: {}", e);

                                if retries < max_retries {
                                    retries += 1;
                                    let wait_time = 50 * retries;
                                    std::thread::sleep(Duration::from_millis(wait_time));
                                    continue;
                                }

                                return Err(
                                    PyError(format!("Jupiter API request failed: {}", e)).into()
                                );
                            }
                        }
                    }
                }
            };

            let instr_payload = serde_json::json!({
                "quoteResponse": quote_response,
                "userPublicKey": self.keypair.pubkey().to_string(),
                "computeUnitPriceMicroLamports": priority_fee_value,
                "wrapUnwrapSOL": true,
                "onlyDirectRoutes": true,
                "maxHops": 1,
                "maxAccounts": max_accounts
            });

            info!("Getting Jupiter swap instructions for sell");

            let mut retries = 0;
            let max_retries = 3;

            let instr_response = loop {
                let mut request = self.http_client.post(JUPITER_SWAP_API).json(&instr_payload);
                if let Some(key) = &self.api_key {
                    request = request.header(AUTHORIZATION, format!("Bearer {}", key));
                }

                match request.send() {
                    Ok(response) => {
                        if response.status().is_success() {
                            match response.json::<serde_json::Value>() {
                                Ok(instr_data) => {
                                    if instr_data.get("error").is_some() {
                                        let error_msg =
                                            instr_data["error"].as_str().unwrap_or("Unknown error");
                                        error!("Jupiter instructions error: {}", error_msg);
                                        return Err(PyError(format!(
                                            "Jupiter instructions error: {}",
                                            error_msg
                                        ))
                                        .into());
                                    }

                                    break instr_data;
                                }
                                Err(e) => {
                                    error!("Failed to parse Jupiter instructions response: {}", e);
                                    return Err(PyError(format!(
                                        "Failed to parse Jupiter instructions response: {}",
                                        e
                                    ))
                                    .into());
                                }
                            }
                        } else {
                            let status = response.status();
                            error!("Jupiter API error: HTTP {}", status);

                            if status.is_server_error() && retries < max_retries {
                                retries += 1;
                                let wait_time = 50 * retries;
                                std::thread::sleep(Duration::from_millis(wait_time));
                                continue;
                            }

                            return Err(
                                PyError(format!("Jupiter API error: HTTP {}", status)).into()
                            );
                        }
                    }
                    Err(e) => {
                        error!("Jupiter API request failed: {}", e);

                        if retries < max_retries {
                            retries += 1;
                            let wait_time = 50 * retries;
                            std::thread::sleep(Duration::from_millis(wait_time));
                            continue;
                        }

                        return Err(PyError(format!("Jupiter API request failed: {}", e)).into());
                    }
                }
            };

            let mut essential_instructions = Vec::new();

            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(
                self.compute_limit,
            ));
            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(
                priority_fee_value,
            ));

            if let Some(setup_instructions) = instr_response
                .get("setupInstructions")
                .and_then(|v| v.as_array())
            {
                for instr in setup_instructions {
                    let program_id_str = instr["programId"].as_str().ok_or_else(|| {
                        error!("Program ID not found in setup instruction");
                        PyError("Program ID not found in setup instruction".to_string())
                    })?;
                    let program_id = Pubkey::from_str(program_id_str).map_err(|e| {
                        error!("Invalid program ID: {}", e);
                        PyError(format!("Invalid program ID: {}", e))
                    })?;

                    let accounts_arr = instr["accounts"].as_array().ok_or_else(|| {
                        error!("Accounts not found in setup instruction");
                        PyError("Accounts not found in setup instruction".to_string())
                    })?;

                    let mut accounts = Vec::new();

                    for account in accounts_arr {
                        let pubkey_str = account["pubkey"].as_str().ok_or_else(|| {
                            error!("Pubkey not found in account");
                            PyError("Pubkey not found in account".to_string())
                        })?;
                        let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {
                            error!("Invalid pubkey: {}", e);
                            PyError(format!("Invalid pubkey: {}", e))
                        })?;

                        let is_signer = account["isSigner"].as_bool().unwrap_or(false);
                        let is_writable = account["isWritable"].as_bool().unwrap_or(false);

                        let account_meta = if is_writable {
                            if is_signer {
                                AccountMeta::new(pubkey, true)
                            } else {
                                AccountMeta::new(pubkey, false)
                            }
                        } else {
                            if is_signer {
                                AccountMeta::new_readonly(pubkey, true)
                            } else {
                                AccountMeta::new_readonly(pubkey, false)
                            }
                        };

                        accounts.push(account_meta);
                    }

                    let data_str = instr["data"].as_str().ok_or_else(|| {
                        error!("Data not found in setup instruction");
                        PyError("Data not found in setup instruction".to_string())
                    })?;

                    let data = base64::decode(data_str).map_err(|e| {
                        error!("Failed to decode setup instruction data: {}", e);
                        PyError(format!("Failed to decode setup instruction data: {}", e))
                    })?;

                    let instruction = Instruction {
                        program_id,
                        accounts,
                        data,
                    };

                    essential_instructions.push(instruction);
                }
            }

            if let Some(swap_instr) = instr_response.get("swapInstruction") {
                let program_id_str = swap_instr["programId"].as_str().ok_or_else(|| {
                    error!("Program ID not found in swap instruction");
                    PyError("Program ID not found in swap instruction".to_string())
                })?;
                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {
                    error!("Invalid program ID: {}", e);
                    PyError(format!("Invalid program ID: {}", e))
                })?;

                let accounts_arr = swap_instr["accounts"].as_array().ok_or_else(|| {
                    error!("Accounts not found in swap instruction");
                    PyError("Accounts not found in swap instruction".to_string())
                })?;

                let mut accounts = Vec::new();

                for account in accounts_arr {
                    let pubkey_str = account["pubkey"].as_str().ok_or_else(|| {
                        error!("Pubkey not found in account");
                        PyError("Pubkey not found in account".to_string())
                    })?;
                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {
                        error!("Invalid pubkey: {}", e);
                        PyError(format!("Invalid pubkey: {}", e))
                    })?;

                    let is_signer = account["isSigner"].as_bool().unwrap_or(false);
                    let is_writable = account["isWritable"].as_bool().unwrap_or(false);

                    let account_meta = if is_writable {
                        if is_signer {
                            AccountMeta::new(pubkey, true)
                        } else {
                            AccountMeta::new(pubkey, false)
                        }
                    } else {
                        if is_signer {
                            AccountMeta::new_readonly(pubkey, true)
                        } else {
                            AccountMeta::new_readonly(pubkey, false)
                        }
                    };

                    accounts.push(account_meta);
                }

                let data_str = swap_instr["data"].as_str().ok_or_else(|| {
                    error!("Data not found in swap instruction");
                    PyError("Data not found in swap instruction".to_string())
                })?;

                let data = base64::decode(data_str).map_err(|e| {
                    error!("Failed to decode swap instruction data: {}", e);
                    PyError(format!("Failed to decode swap instruction data: {}", e))
                })?;

                let instruction = Instruction {
                    program_id,
                    accounts,
                    data,
                };

                essential_instructions.push(instruction);
            } else {
                error!("No swap instruction found in response");
                return Err(
                    PyError("Jupiter swap instruction not found in response".to_string()).into(),
                );
            }

            if let Some(cleanup_instr) = instr_response.get("cleanupInstruction") {
                let program_id_str = cleanup_instr["programId"].as_str().ok_or_else(|| {
                    error!("Program ID not found in cleanup instruction");
                    PyError("Program ID not found in cleanup instruction".to_string())
                })?;
                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {
                    error!("Invalid program ID: {}", e);
                    PyError(format!("Invalid program ID: {}", e))
                })?;

                let accounts_arr = cleanup_instr["accounts"].as_array().ok_or_else(|| {
                    error!("Accounts not found in cleanup instruction");
                    PyError("Accounts not found in cleanup instruction".to_string())
                })?;

                let mut accounts = Vec::new();

                for account in accounts_arr {
                    let pubkey_str = account["pubkey"].as_str().ok_or_else(|| {
                        error!("Pubkey not found in account");
                        PyError("Pubkey not found in account".to_string())
                    })?;
                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {
                        error!("Invalid pubkey: {}", e);
                        PyError(format!("Invalid pubkey: {}", e))
                    })?;

                    let is_signer = account["isSigner"].as_bool().unwrap_or(false);
                    let is_writable = account["isWritable"].as_bool().unwrap_or(false);

                    let account_meta = if is_writable {
                        if is_signer {
                            AccountMeta::new(pubkey, true)
                        } else {
                            AccountMeta::new(pubkey, false)
                        }
                    } else {
                        if is_signer {
                            AccountMeta::new_readonly(pubkey, true)
                        } else {
                            AccountMeta::new_readonly(pubkey, false)
                        }
                    };

                    accounts.push(account_meta);
                }

                let data_str = cleanup_instr["data"].as_str().ok_or_else(|| {
                    error!("Data not found in cleanup instruction");
                    PyError("Data not found in cleanup instruction".to_string())
                })?;

                let data = base64::decode(data_str).map_err(|e| {
                    error!("Failed to decode cleanup instruction data: {}", e);
                    PyError(format!("Failed to decode cleanup instruction data: {}", e))
                })?;

                let instruction = Instruction {
                    program_id,
                    accounts,
                    data,
                };

                essential_instructions.push(instruction);
            }

            if essential_instructions.len() <= 2 {
                error!("No Jupiter instructions found in response");
                return Err(
                    PyError("Jupiter instructions not found in response".to_string()).into(),
                );
            }

            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();
            let blockhash = blockhash_cache.get_blockhash();
            debug!("Using cached blockhash: {}", blockhash);

            let mut transaction = Transaction::new_signed_with_payer(
                &essential_instructions,
                Some(&self.keypair.pubkey()),
                &[&self.keypair],
                blockhash,
            );

            let send_config = RpcSendTransactionConfig {
                skip_preflight: self.skip_preflight,
                preflight_commitment: Some(CommitmentLevel::Processed),
                encoding: Some(UiTransactionEncoding::Base64),
                max_retries: Some(self.max_retries),
                ..Default::default()
            };

            let mut retry_count = 0;
            let max_retries = 2;

            while retry_count <= max_retries {
                match self
                    .rpc_client
                    .send_transaction_with_config(&transaction, send_config.clone())
                {
                    Ok(signature) => {
                        info!(
                            "Jupiter token sell executed: {} tokens to SOL with signature {}",
                            amount_tokens, signature
                        );
                        return Ok(signature.to_string());
                    }
                    Err(e) => {
                        let error_str = e.to_string();

                        if error_str.contains("blockhash") && retry_count < max_retries {
                            error!(
                                "Blockhash error, retrying with fresh blockhash: {}",
                                error_str
                            );

                            let new_blockhash = blockhash_cache.force_update();

                            let new_transaction = Transaction::new_signed_with_payer(
                                &essential_instructions,
                                Some(&self.keypair.pubkey()),
                                &[&self.keypair],
                                new_blockhash,
                            );

                            transaction = new_transaction;

                            retry_count += 1;
                            continue;
                        }

                        error!("Failed to send transaction: {}", e);
                        return Err(PyError(format!("Failed to send transaction: {}", e)).into());
                    }
                }
            }

            Err(PyError("Max retries exceeded".to_string()).into())
        })
    }

    /// Get token decimals with caching for speed
    fn get_token_decimals(&self, py: Python<'_>, token_mint: String) -> PyResult<u8> {
        if let Some(decimals) = TOKEN_DECIMALS_CACHE.get(&token_mint) {
            return Ok(*decimals);
        }

        py.allow_threads(|| {
            let token_mint_pubkey = Pubkey::from_str(&token_mint)
                .map_err(|e| PyErr::new::<PyValueError, _>(format!("Invalid pubkey: {}", e)))?;

            let mint_data = self
                .rpc_client
                .get_account_data(&token_mint_pubkey)
                .map_err(|e| {
                    PyErr::new::<PyRuntimeError, _>(format!("Failed to get account data: {}", e))
                })?;

            let mint_info = spl_token::state::Mint::unpack(&mint_data).map_err(|e| {
                PyErr::new::<PyRuntimeError, _>(format!("Failed to unpack mint data: {}", e))
            })?;

            TOKEN_DECIMALS_CACHE.insert(token_mint, mint_info.decimals);

            Ok(mint_info.decimals)
        })
    }

    /// Create token account if it doesn't exist - with improved error handling
    fn create_token_account_if_needed(&self, py: Python<'_>, token_mint: String) -> PyResult<bool> {
        let token_mint_pubkey = match Pubkey::from_str(&token_mint) {
            Ok(pubkey) => pubkey,
            Err(e) => return Err(PyValueError::new_err(format!("Invalid pubkey: {}", e))),
        };

        let token_account =
            get_associated_token_address(&self.keypair.pubkey(), &token_mint_pubkey);

        let account_exists = self.rpc_client.get_account_data(&token_account).is_ok();
        if account_exists {
            return Ok(false);
        }

        let create_ata_ix = create_associated_token_account_idempotent(
            &self.keypair.pubkey(),
            &self.keypair.pubkey(),
            &token_mint_pubkey,
            &Pubkey::from_str(&self.token_program_id)
                .map_err(|e| PyValueError::new_err(format!("Invalid token program ID: {}", e)))?,
        );

        py.allow_threads(|| {
            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();
            let blockhash = blockhash_cache.get_blockhash();

            let transaction = Transaction::new_signed_with_payer(
                &[create_ata_ix],
                Some(&self.keypair.pubkey()),
                &[&self.keypair],
                blockhash,
            );

            match self.rpc_client.send_and_confirm_transaction(&transaction) {
                Ok(signature) => {
                    info!("Created token account for {}: {}", token_mint, signature);
                    Ok(true)
                }
                Err(e) => {
                    if e.to_string().contains("already in use") {
                        debug!("Token account for {} already exists", token_mint);
                        return Ok(true);
                    }

                    error!("Failed to create token account for {}: {}", token_mint, e);
                    return Err(PyRuntimeError::new_err(format!(
                        "Failed to create token account: {}",
                        e
                    )));
                }
            }
        })
    }

    /// Get SOL balance with optimized caching
    fn get_sol_balance(&self, py: Python<'_>) -> PyResult<f64> {
        py.allow_threads(
            || match self.rpc_client.get_balance(&self.keypair.pubkey()) {
                Ok(balance) => Ok(balance as f64 / LAMPORTS_PER_SOL as f64),
                Err(e) => {
                    error!("Failed to get SOL balance: {}", e);
                    Err(PyRuntimeError::new_err(format!(
                        "Failed to get SOL balance: {}",
                        e
                    )))
                }
            },
        )
    }

    /// Get token balance with optimized error handling
    fn get_token_balance(&self, py: Python<'_>, token_mint: String) -> PyResult<f64> {
        py.allow_threads(|| {
            let token_mint_pubkey = Pubkey::from_str(&token_mint)
                .map_err(|e| PyValueError::new_err(format!("Invalid pubkey: {}", e)))?;

            let token_account =
                get_associated_token_address(&self.keypair.pubkey(), &token_mint_pubkey);

            match self.rpc_client.get_account_data(&token_account) {
                Ok(data) => {
                    let account_info = spl_token::state::Account::unpack(&data).map_err(|e| {
                        PyRuntimeError::new_err(format!("Failed to unpack token account: {}", e))
                    })?;

                    let decimals = if let Some(decimals) = TOKEN_DECIMALS_CACHE.get(&token_mint) {
                        *decimals
                    } else {
                        let mint_data = self
                            .rpc_client
                            .get_account_data(&token_mint_pubkey)
                            .map_err(|e| {
                                PyRuntimeError::new_err(format!("Failed to get mint data: {}", e))
                            })?;

                        let mint_info =
                            spl_token::state::Mint::unpack(&mint_data).map_err(|e| {
                                PyRuntimeError::new_err(format!(
                                    "Failed to unpack mint data: {}",
                                    e
                                ))
                            })?;

                        TOKEN_DECIMALS_CACHE.insert(token_mint.clone(), mint_info.decimals);

                        mint_info.decimals
                    };

                    let balance = account_info.amount as f64 / 10f64.powi(decimals as i32);

                    Ok(balance)
                }
                Err(_) => Ok(0.0),
            }
        })
    }

    /// Get wallet's public address
    fn get_address(&self) -> PyResult<String> {
        Ok(self.keypair.pubkey().to_string())
    }

    /// Get cached blockhash with optimized approach
    fn get_cached_blockhash(&self, py: Python<'_>) -> PyResult<String> {
        py.allow_threads(|| {
            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();
            let blockhash = blockhash_cache.get_blockhash();
            Ok(blockhash.to_string())
        })
    }

    /// Force update the blockhash cache
    fn force_update_blockhash(&self, py: Python<'_>) -> PyResult<String> {
        py.allow_threads(|| {
            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();
            let blockhash = blockhash_cache.force_update();
            Ok(blockhash.to_string())
        })
    }

    /// Confirm transaction with optimized retry logic
    fn confirm_transaction(
        &self,
        py: Python<'_>,
        signature_str: String,
        timeout: u64,
    ) -> PyResult<bool> {
        py.allow_threads(|| {
            let signature = Signature::from_str(&signature_str)
                .map_err(|e| PyValueError::new_err(format!("Invalid signature: {}", e)))?;

            let start_time = Instant::now();
            let timeout_duration = Duration::from_secs(timeout);

            while start_time.elapsed() < timeout_duration {
                match self.rpc_client.get_signature_status(&signature) {
                    Ok(Some(Ok(_))) => return Ok(true),
                    Ok(Some(Err(e))) => {
                        error!("Transaction failed: {:?}", e);
                        return Err(PyRuntimeError::new_err(format!(
                            "Transaction failed: {:?}",
                            e
                        )));
                    }
                    Ok(None) => {
                        std::thread::sleep(Duration::from_millis(300));
                    }
                    Err(e) => {
                        error!("Status check failed: {}", e);
                        std::thread::sleep(Duration::from_millis(400));
                    }
                }
            }

            error!("Transaction confirmation timed out");
            Err(PyRuntimeError::new_err(
                "Transaction confirmation timed out".to_string(),
            ))
        })
    }
}

/// Python module initialization
#[pymodule]
fn solana_rust_bot(_py: Python, m: &PyModule) -> PyResult<()> {
    pyo3_log::init();

    m.add_class::<SolanaTrader>()?;

    m.add("LAMPORTS_PER_SOL", LAMPORTS_PER_SOL)?;
    m.add("DEFAULT_COMPUTE_LIMIT", DEFAULT_COMPUTE_LIMIT)?;
    m.add("DEFAULT_PRIORITY_FEE", DEFAULT_PRIORITY_FEE)?;
    m.add("DEFAULT_MAX_RETRIES", DEFAULT_MAX_RETRIES)?;
    m.add("DEFAULT_MIN_SOL_BALANCE", DEFAULT_MIN_SOL_BALANCE)?;
    m.add("DEFAULT_MIN_WSOL_BALANCE", DEFAULT_MIN_WSOL_BALANCE)?;
    m.add("WSOL_ADDRESS", WSOL_ADDRESS)?;

    Ok(())
}