{"behavior":"degenerate_repetition","label_filter":null,"limit":10,"next_offset":31326,"offset":31316,"previous_offset":null,"rows":[{"assistant_initiates":false,"asst_text":"Hello! Not much, just here and ready to help. How about you?","behavior":"degenerate_repetition","conversation_hash":"5f2b75b0fa0b9778f41fd9f5916d78d5","conversation_redacted":false,"conversation_toxic":false,"country":"United States","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":113,"n_turns_in_conversation":1,"n_words":21,"source_row_offset":31316,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:57:47 GMT","turn_id":"41e549592c6876e7a5ab1b2f","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! Not much, just here and ready to help. How about you?","behavior":"degenerate_repetition","conversation_hash":"5f2b75b0fa0b9778f41fd9f5916d78d5","conversation_redacted":false,"conversation_toxic":false,"country":"France","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":113,"n_turns_in_conversation":1,"n_words":21,"source_row_offset":31317,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:57:57 GMT","turn_id":"41e549592c6876e7a5ab1b2f","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! Not much, just here and ready to help. How can I assist you today?","behavior":"degenerate_repetition","conversation_hash":"6e53af0ad61790cc5da34e47aea76ab4","conversation_redacted":false,"conversation_toxic":false,"country":"United States","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":126,"n_turns_in_conversation":1,"n_words":24,"source_row_offset":31318,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:07 GMT","turn_id":"749a1bc16ccf0de67347cacb","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! I'm doing well, thank you. How can I assist you today?","behavior":"degenerate_repetition","conversation_hash":"1f2041611b8beff6b7602ece1f622dba","conversation_redacted":false,"conversation_toxic":false,"country":"Finland","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":118,"n_turns_in_conversation":1,"n_words":23,"source_row_offset":31319,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:13 GMT","turn_id":"63650dd97169c16fe03e45d1","turn_index":0,"user_text":"User: hi, how are you?\nUser: hi, how are you?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! Not much, just here and ready to help. How can I assist you today?","behavior":"degenerate_repetition","conversation_hash":"6e53af0ad61790cc5da34e47aea76ab4","conversation_redacted":false,"conversation_toxic":false,"country":"","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":126,"n_turns_in_conversation":1,"n_words":24,"source_row_offset":31320,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:16 GMT","turn_id":"749a1bc16ccf0de67347cacb","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Certainly! I've applied **only** the requested minor edits precisely as you specified:\n\n- **RPC Client timeout changed from 30 seconds to 500 milliseconds**\n- **HTTP Client timeout changed from 30 seconds to 500 milliseconds, with an added connect timeout of 300 ms**\n- **Jupiter API swap-instructions `maxAccounts` changed from 12 (hardcoded) to a configurable value read from env var `MAX_ACCOUNTS` with default 8**\n- **Retry backoff changed from exponential (`2u64.pow(retries) * 100`) to linear (`50 * retries`) in all retry places**\n- **Transaction confirmation wait time changed from 200 ms to 50 ms**\n\nI have also **removed the execute_round_trip_test method and associated code**, as per your statement it is unnecessary.\n\nNothing else of your code was altered. Here's the full updated script with these minimal fixes applied and the test code removed:\n\n```rust\nuse base64;\nuse log::{debug, error, info};\nuse pyo3::exceptions::{PyFileNotFoundError, PyRuntimeError, PyValueError};\nuse pyo3::prelude::*;\nuse pyo3::types::PyDict;\nuse solana_client::rpc_client::RpcClient;\nuse solana_client::rpc_config::RpcSendTransactionConfig;\nuse solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel};\nuse solana_sdk::compute_budget::ComputeBudgetInstruction;\nuse solana_sdk::hash::Hash;\nuse solana_sdk::instruction::{AccountMeta, Instruction};\nuse solana_sdk::program_pack::Pack;\nuse solana_sdk::pubkey::Pubkey;\nuse solana_sdk::signature::{read_keypair_file, Keypair, Signature, Signer};\nuse solana_sdk::transaction::Transaction;\nuse solana_transaction_status::UiTransactionEncoding;\nuse spl_associated_token_account::{\n    get_associated_token_address, instruction::create_associated_token_account_idempotent,\n};\nuse spl_token;\nuse std::env;\nuse std::path::Path;\nuse std::str::FromStr;\nuse std::sync::Arc;\nuse std::time::{Duration, Instant};\n// Fast blockhash caching using RwLock instead of Mutex\nuse parking_lot::RwLock;\n// Concurrent map for caching\nuse dashmap::DashMap;\n// Optional async support\nuse once_cell::sync::OnceCell;\nuse tokio::runtime::Runtime;\n// Add header support for authentication\nuse reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_TYPE};\n\n// Fast RwLock-based blockhash cache\nstruct FastBlockhashCache {\n    blockhash: RwLock<Hash>,\n    last_update: RwLock<Instant>,\n    update_interval: Duration,\n    rpc_client: Arc<RpcClient>,\n}\n\nimpl FastBlockhashCache {\n    fn new(rpc_client: Arc<RpcClient>, update_interval_seconds: u64) -> Self {\n        // More robust initial blockhash retrieval with retry logic\n        let mut attempts = 0;\n        let max_attempts = 5;\n        let mut blockhash = None;\n        \n        while attempts < max_attempts {\n            match rpc_client.get_latest_blockhash() {\n                Ok(hash) => {\n                    blockhash = Some(hash);\n                    info!(\"Successfully retrieved initial blockhash\");\n                    break;\n                }\n                Err(e) => {\n                    error!(\"Error getting initial blockhash (attempt {}/{}): {}\", \n                            attempts + 1, max_attempts, e);\n                    attempts += 1;\n                    if attempts < max_attempts {\n                        std::thread::sleep(Duration::from_millis(500));\n                    }\n                }\n            }\n        }\n        \n        // If all attempts failed, use a default blockhash (will be updated later)\n        let blockhash = blockhash.unwrap_or_else(|| {\n            error!(\"Warning: Using placeholder blockhash, will update shortly\");\n            Hash::default()\n        });\n\n        Self {\n            blockhash: RwLock::new(blockhash),\n            last_update: RwLock::new(Instant::now()),\n            update_interval: Duration::from_secs(update_interval_seconds),\n            rpc_client,\n        }\n    }\n\n    fn get_blockhash(&self) -> Hash {\n        // Check if we need to update using a read lock first\n        let should_update = {\n            let last_update = self.last_update.read();\n            last_update.elapsed() >= self.update_interval\n        };\n\n        // If update is needed, get a new blockhash\n        if should_update {\n            // Simply do it synchronously for now to avoid threading issues\n            match self.rpc_client.get_latest_blockhash() {\n                Ok(new_hash) => {\n                    *self.blockhash.write() = new_hash;\n                    *self.last_update.write() = Instant::now();\n                }\n                Err(e) => {\n                    error!(\"Failed to update blockhash: {}\", e);\n                }\n            }\n        }\n\n        // Return current blockhash\n        *self.blockhash.read()\n    }\n\n    fn force_update(&self) -> Hash {\n        match self.rpc_client.get_latest_blockhash() {\n            Ok(new_hash) => {\n                *self.blockhash.write() = new_hash;\n                *self.last_update.write() = Instant::now();\n                new_hash\n            }\n            Err(e) => {\n                error!(\"Failed to force update blockhash: {}\", e);\n                *self.blockhash.read() // Return current one\n            }\n        }\n    }\n}\n\n// Optimized API response cache\nstruct JupiterCache {\n    routes: DashMap<String, (serde_json::Value, Instant)>,\n    ttl: Duration,\n}\n\nimpl JupiterCache {\n    fn new(ttl_seconds: u64) -> Self {\n        Self {\n            routes: DashMap::new(),\n            ttl: Duration::from_secs(ttl_seconds),\n        }\n    }\n\n    fn get(&self, key: &str) -> Option<serde_json::Value> {\n        if let Some(entry) = self.routes.get(key) {\n            if entry.1.elapsed() < self.ttl {\n                return Some(entry.0.clone());\n            }\n        }\n        None\n    }\n\n    fn set(&self, key: String, value: serde_json::Value) {\n        self.routes.insert(key, (value, Instant::now()));\n    }\n\n    fn clear_expired(&self) {\n        let now = Instant::now();\n        let expired_keys: Vec<String> = self\n            .routes\n            .iter()\n            .filter(|r| now.duration_since(r.value().1) >= self.ttl)\n            .map(|r| r.key().clone())\n            .collect();\n\n        for key in expired_keys {\n            self.routes.remove(&key);\n        }\n    }\n}\n\n// Token decimals cache using DashMap\nstatic TOKEN_DECIMALS_CACHE: once_cell::sync::Lazy<DashMap<String, u8>> =\n    once_cell::sync::Lazy::new(|| DashMap::new());\n\n// Fast blockhash cache\nstatic BLOCKHASH_CACHE: once_cell::sync::Lazy<OnceCell<Arc<FastBlockhashCache>>> =\n    once_cell::sync::Lazy::new(|| OnceCell::new());\n\n// Jupiter API cache\nstatic JUPITER_CACHE: once_cell::sync::Lazy<OnceCell<Arc<JupiterCache>>> =\n    once_cell::sync::Lazy::new(|| OnceCell::new());\n\n// Core constants\nconst LAMPORTS_PER_SOL: u64 = 1_000_000_000;\nconst WSOL_ADDRESS: &str = \"So11111111111111111111111111111111111111112\";\nconst TOKEN_PROGRAM_ID: &str = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nconst RAYDIUM_PROGRAM_ID: &str = \"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8\";\nconst SERUM_PROGRAM_ID: &str = \"9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin\";\n\n// Jupiter API constants - Updated for v6\nconst JUPITER_QUOTE_API: &str = \"https://quote-api.jup.ag/v6/quote\";\nconst JUPITER_SWAP_API: &str = \"https://quote-api.jup.ag/v6/swap-instructions\";\n\n// Transaction and trading constants\nconst RAYDIUM_SWAP_INSTRUCTION: u8 = 9;\nconst DEFAULT_COMPUTE_LIMIT: u32 = 200_000;\nconst DEFAULT_PRIORITY_FEE: u64 = 1_000_000; // 0.001 SOL\nconst DEFAULT_SLIPPAGE: f64 = 0.01; // 1%\nconst DEFAULT_MAX_RETRIES: usize = 3;\n\n// Balance safety thresholds\nconst DEFAULT_MIN_SOL_BALANCE: f64 = 0.03;\nconst DEFAULT_MIN_WSOL_BALANCE: f64 = 0.02;\n\n// Simplified error handling\nstruct PyError(String);\n\nimpl From<PyError> for PyErr {\n    fn from(err: PyError) -> PyErr {\n        PyRuntimeError::new_err(err.0)\n    }\n}\n\n// Initialize tokio runtime for async operations if needed\nfn get_tokio_runtime() -> &'static Runtime {\n    static RUNTIME: OnceCell<Runtime> = OnceCell::new();\n    RUNTIME.get_or_init(|| Runtime::new().expect(\"Failed to create tokio runtime\"))\n}\n\n/// Represents dynamic Raydium swap accounts\n#[derive(Debug, Clone)]\nstruct RaydiumSwapAccounts {\n    amm_id: String,\n    amm_authority: String,\n    amm_open_orders: String,\n    amm_target_orders: String,\n    pool_coin_token_account: String,\n    pool_pc_token_account: String,\n    serum_program_id: String,\n    serum_market: String,\n    serum_bids: String,\n    serum_asks: String,\n    serum_event_queue: String,\n    serum_coin_vault: String,\n    serum_pc_vault: String,\n    serum_vault_signer: String,\n    token_mint: String,\n    token_program_id: String,\n}\n\n/// Main Solana trading class\n#[pyclass]\nstruct SolanaTrader {\n    keypair: Arc<Keypair>,\n    rpc_client: Arc<RpcClient>,\n    rpc_url: String,\n    ws_url: String,\n    compute_limit: u32,\n    priority_fee: u64,\n    skip_preflight: bool,\n    max_retries: usize,\n    min_sol_balance: f64,\n    min_wsol_balance: f64,\n    wsol_address: String,\n    token_program_id: String,\n    system_program_id: String,\n    raydium_program_id: String,\n    serum_program_id: String,\n    keypair_path: String,\n    http_client: reqwest::blocking::Client,\n    api_key: Option<String>, // Add API key field for authentication\n}\n\n#[pymethods]\nimpl SolanaTrader {\n    /// Initialize the SolanaTrader with configuration\n    #[new]\n    fn new(\n        rpc_url: String,\n        ws_url: String,\n        keypair_path: String,\n        compute_limit: Option<u32>,\n        api_key: Option<String>, // Add API key parameter\n    ) -> PyResult<Self> {\n        // Tokio runtime initialization\n        let _ = get_tokio_runtime();\n\n        // Load environment variables if .env file exists\n        let _ = dotenv::dotenv();\n\n        // Get API key from parameter or environment variable\n        let api_key = api_key.or_else(|| env::var(\"HELIUS_API_KEY\").ok());\n        if let Some(key) = &api_key {\n            info!(\"Using API key for authentication\");\n        }\n\n        // Keypair loading with robust error handling\n        let keypair = if Path::new(&keypair_path).exists() {\n            // First, try to read as JSON\n            match read_keypair_file(&keypair_path) {\n                Ok(kp) => kp,\n                Err(_) => {\n                    // If JSON fails, try to read as binary\n                    match std::fs::read(&keypair_path) {\n                        Ok(bytes) => {\n                            if bytes.len() == 64 {\n                                match Keypair::from_bytes(&bytes) {\n                                    Ok(kp) => kp,\n                                    Err(e) => {\n                                        return Err(PyValueError::new_err(format!(\n                                            \"Invalid binary keypair: {}\",\n                                            e\n                                        )))\n                                    }\n                                }\n                            } else {\n                                // Try base58 decoding\n                                match bs58::decode(std::str::from_utf8(&bytes).unwrap_or(\"\"))\n                                    .into_vec()\n                                    .map(|secret_key| Keypair::from_bytes(&secret_key))\n                                {\n                                    Ok(Ok(kp)) => kp,\n                                    _ => {\n                                        return Err(PyValueError::new_err(\n                                            \"Could not parse keypair file in any format\",\n                                        ))\n                                    }\n                                }\n                            }\n                        }\n                        Err(e) => {\n                            return Err(PyRuntimeError::new_err(format!(\n                                \"Failed to read keypair file: {}\",\n                                e\n                            )))\n                        }\n                    }\n                }\n            }\n        } else {\n            return Err(PyFileNotFoundError::new_err(format!(\n                \"Keypair file not found: {}\",\n                keypair_path\n            )));\n        };\n\n        // Create RPC client with processed commitment and authentication\n        // Fix: Use available methods in solana 1.18.x\n        let rpc_client = {\n            // Set timeout and commitment\n            let commitment_config = CommitmentConfig::processed();\n            let timeout = Duration::from_millis(500);\n            \n            // Create client with timeout and commitment\n            // For Solana 1.18.x, we need to use the correct available constructors\n            let client = RpcClient::new_with_timeout_and_commitment(\n                rpc_url.clone(),\n                timeout,\n                commitment_config,\n            );\n            \n            Arc::new(client)\n        };\n\n        // Read environment variables with fallbacks\n        let compute = compute_limit.unwrap_or_else(|| {\n            env::var(\"COMPUTE_LIMIT\")\n                .map(|v| v.parse::<u32>().unwrap_or(DEFAULT_COMPUTE_LIMIT))\n                .unwrap_or(DEFAULT_COMPUTE_LIMIT)\n        });\n\n        let priority_fee = env::var(\"PRIORITY_FEE\")\n            .map(|v| v.parse::<u64>().unwrap_or(DEFAULT_PRIORITY_FEE))\n            .unwrap_or(DEFAULT_PRIORITY_FEE);\n\n        let skip_preflight = env::var(\"SKIP_PREFLIGHT\")\n            .map(|v| v.parse::<bool>().unwrap_or(true))\n            .unwrap_or(true);\n\n        let max_retries = env::var(\"MAX_RETRIES\")\n            .map(|v| v.parse::<usize>().unwrap_or(DEFAULT_MAX_RETRIES))\n            .unwrap_or(DEFAULT_MAX_RETRIES);\n\n        let min_sol_balance = env::var(\"MIN_SOL_BALANCE\")\n            .map(|v| v.parse::<f64>().unwrap_or(DEFAULT_MIN_SOL_BALANCE))\n            .unwrap_or(DEFAULT_MIN_SOL_BALANCE);\n\n        let min_wsol_balance = env::var(\"MIN_WSOL_BALANCE\")\n            .map(|v| v.parse::<f64>().unwrap_or(DEFAULT_MIN_WSOL_BALANCE))\n            .unwrap_or(DEFAULT_MIN_WSOL_BALANCE);\n\n        // Create optimized HTTP client with authentication\n        let http_client = {\n            let builder = reqwest::blocking::Client::builder()\n                .timeout(Duration::from_millis(500))\n                .connect_timeout(Duration::from_millis(300))\n                .pool_max_idle_per_host(32);\n            \n            // Create default headers\n            let mut headers = HeaderMap::new();\n            \n            // Add Solana CLI User-Agent header\n            if let Ok(value) = HeaderValue::from_str(\"solana-cli 1.18.23 (src:aeb3a2e1; feat:4215500110, client:SolanaLabs)\") {\n                headers.insert(reqwest::header::USER_AGENT, value);\n                headers.insert(CONTENT_TYPE, HeaderValue::from_static(\"application/json\"));\n            }\n            \n            // Add authentication headers if API key is provided\n            if let Some(key) = &api_key {\n                let auth_value = format!(\"Bearer {}\", key);\n                if let Ok(value) = HeaderValue::from_str(&auth_value) {\n                    headers.insert(AUTHORIZATION, value);\n                }\n            }\n            \n            // Build the client with headers\n            builder.default_headers(headers).build()\n        }.unwrap_or_else(|_| reqwest::blocking::Client::new());\n\n        // Initialize fast blockhash cache if not already initialized\n        BLOCKHASH_CACHE.get_or_init(|| {\n            let cache = FastBlockhashCache::new(\n                rpc_client.clone(),\n                2, // Update every 2 seconds\n            );\n            Arc::new(cache)\n        });\n\n        // Initialize Jupiter cache if not already initialized\n        JUPITER_CACHE.get_or_init(|| {\n            let cache = JupiterCache::new(10); // 10 second TTL\n            Arc::new(cache)\n        });\n\n        // Start a periodic cache cleanup thread\n        {\n            let jupiter_cache = JUPITER_CACHE.get().unwrap().clone();\n            std::thread::spawn(move || loop {\n                std::thread::sleep(Duration::from_secs(60));\n                jupiter_cache.clear_expired();\n                debug!(\"Cleared expired Jupiter cache entries\");\n            });\n        }\n\n        info!(\n            \"Initialized trader with compute_limit: {}, priority_fee: {}\",\n            compute, priority_fee\n        );\n\n        Ok(Self {\n            keypair: Arc::new(keypair),\n            rpc_client,\n            rpc_url,\n            ws_url,\n            compute_limit: compute,\n            priority_fee,\n            skip_preflight,\n            max_retries,\n            min_sol_balance,\n            min_wsol_balance,\n            wsol_address: WSOL_ADDRESS.to_string(),\n            token_program_id: TOKEN_PROGRAM_ID.to_string(),\n            system_program_id: \"11111111111111111111111111111111\".to_string(),\n            raydium_program_id: RAYDIUM_PROGRAM_ID.to_string(),\n            serum_program_id: SERUM_PROGRAM_ID.to_string(),\n            keypair_path,\n            http_client,\n            api_key,\n        })\n    }\n\n    /// Execute token swap using Jupiter (Solana's DEX aggregator) - Optimized implementation\n    fn execute_jupiter_swap(\n        &self,\n        py: Python<'_>,\n        input_mint: String,\n        output_mint: String,\n        amount_sol: f64,\n        slippage_percent: Option<f64>,\n        priority_multiplier: Option<u64>,\n    ) -> PyResult<String> {\n        // Convert amount to lamports\n        let amount_lamports = (amount_sol * LAMPORTS_PER_SOL as f64).round() as u64;\n\n        // Dynamic slippage calculation\n        let slippage = match slippage_percent {\n            Some(val) => val / 100.0,\n            None => DEFAULT_SLIPPAGE,\n        };\n        let slippage_bps = (slippage * 10000.0) as u32;\n\n        // Priority fee calculation\n        let priority_multiplier_value = priority_multiplier.unwrap_or(1);\n        let priority_fee_value = self.priority_fee * priority_multiplier_value;\n\n        // Ensure token accounts exist for both input and output before releasing the GIL\n        if input_mint != WSOL_ADDRESS {\n            self.create_token_account_if_needed(py, input_mint.clone())?;\n        }\n        if output_mint != WSOL_ADDRESS {\n            self.create_token_account_if_needed(py, output_mint.clone())?;\n        }\n\n        // Now we can safely release the GIL for network operations\n        py.allow_threads(|| {\n            // Step 1: Try to get from cache first\n            let cache_key = format!(\n                \"{}:{}:{}:{}\",\n                input_mint, output_mint, amount_lamports, slippage_bps\n            );\n            let jupiter_cache = JUPITER_CACHE.get().unwrap();\n\n            let quote_response = match jupiter_cache.get(&cache_key) {\n                Some(cached) => {\n                    debug!(\"Jupiter quote cache hit: {}\", cache_key);\n                    cached\n                }\n                None => {\n                    // Step 1: Get a quote from Jupiter API\n                    let quote_url = format!(\n                        \"{}?inputMint={}&outputMint={}&amount={}&slippageBps={}\",\n                        JUPITER_QUOTE_API, input_mint, output_mint, amount_lamports, slippage_bps\n                    );\n\n                    info!(\"Getting Jupiter quote: {}\", quote_url);\n\n                    // Implement retry logic\n                    let mut retries = 0;\n                    let max_retries = 3;\n\n                    loop {\n                        // Add authentication headers if needed\n                        let mut request = self.http_client.get(&quote_url);\n                        if let Some(key) = &self.api_key {\n                            request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                        }\n\n                        match request.send() {\n                            Ok(response) => {\n                                if response.status().is_success() {\n                                    match response.json::<serde_json::Value>() {\n                                        Ok(quote_data) => {\n                                            // Check for API errors\n                                            if quote_data.get(\"error\").is_some() {\n                                                let error_msg = quote_data[\"error\"]\n                                                    .as_str()\n                                                    .unwrap_or(\"Unknown error\");\n                                                error!(\"Jupiter quote error: {}\", error_msg);\n                                                return Err(PyError(format!(\n                                                    \"Jupiter quote error: {}\",\n                                                    error_msg\n                                                ))\n                                                .into());\n                                            }\n\n                                            // Cache the result\n                                            jupiter_cache\n                                                .set(cache_key.clone(), quote_data.clone());\n\n                                            // Return quote\n                                            break quote_data;\n                                        }\n                                        Err(e) => {\n                                            error!(\"Failed to parse Jupiter quote response: {}\", e);\n                                            return Err(PyError(format!(\n                                                \"Failed to parse Jupiter quote: {}\",\n                                                e\n                                            ))\n                                            .into());\n                                        }\n                                    }\n                                } else {\n                                    let status = response.status();\n                                    error!(\"Jupiter API error: HTTP {}\", status);\n\n                                    // For server errors, retry with linear backoff\n                                    if status.is_server_error() && retries < max_retries {\n                                        retries += 1;\n                                        let wait_time = 50 * retries; // Linear backoff\n                                        std::thread::sleep(Duration::from_millis(wait_time));\n                                        continue;\n                                    }\n\n                                    return Err(PyError(format!(\n                                        \"Jupiter API error: HTTP {}\",\n                                        status\n                                    ))\n                                    .into());\n                                }\n                            }\n                            Err(e) => {\n                                error!(\"Jupiter API request failed: {}\", e);\n\n                                // Network errors are retried linearly\n                                if retries < max_retries {\n                                    retries += 1;\n                                    let wait_time = 50 * retries; // Linear backoff\n                                    std::thread::sleep(Duration::from_millis(wait_time));\n                                    continue;\n                                }\n\n                                return Err(\n                                    PyError(format!(\"Jupiter API request failed: {}\", e)).into()\n                                );\n                            }\n                        }\n                    }\n                }\n            };\n\n            let max_accounts = env::var(\"MAX_ACCOUNTS\")\n                .map(|v| v.parse::<u32>().unwrap_or(8))\n                .unwrap_or(8);\n\n            // Step 2: Use the swap-instructions endpoint\n            let instr_payload = serde_json::json!({\n                \"quoteResponse\": quote_response,\n                \"userPublicKey\": self.keypair.pubkey().to_string(),\n                \"computeUnitPriceMicroLamports\": priority_fee_value,\n                \"wrapUnwrapSOL\": true,\n                \"onlyDirectRoutes\": true,\n                \"maxHops\": 1,\n                \"maxAccounts\": max_accounts\n            });\n\n            info!(\"Getting Jupiter swap instructions\");\n\n            // Implement retry logic for instructions\n            let mut retries = 0;\n            let max_retries = 3;\n\n            let instr_response = loop {\n                // Add authentication headers if needed\n                let mut request = self.http_client.post(JUPITER_SWAP_API).json(&instr_payload);\n                if let Some(key) = &self.api_key {\n                    request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                }\n\n                match request.send() {\n                    Ok(response) => {\n                        if response.status().is_success() {\n                            match response.json::<serde_json::Value>() {\n                                Ok(instr_data) => {\n                                    // Check for API errors\n                                    if instr_data.get(\"error\").is_some() {\n                                        let error_msg =\n                                            instr_data[\"error\"].as_str().unwrap_or(\"Unknown error\");\n                                        error!(\"Jupiter instructions error: {}\", error_msg);\n                                        return Err(PyError(format!(\n                                            \"Jupiter instructions error: {}\",\n                                            error_msg\n                                        ))\n                                        .into());\n                                    }\n\n                                    break instr_data;\n                                }\n                                Err(e) => {\n                                    error!(\"Failed to parse Jupiter instructions response: {}\", e);\n                                    return Err(PyError(format!(\n                                        \"Failed to parse Jupiter instructions response: {}\",\n                                        e\n                                    ))\n                                    .into());\n                                }\n                            }\n                        } else {\n                            let status = response.status();\n                            error!(\"Jupiter API error: HTTP {}\", status);\n\n                            // For server errors, retry with linear backoff\n                            if status.is_server_error() && retries < max_retries {\n                                retries += 1;\n                                let wait_time = 50 * retries; // Linear backoff\n                                std::thread::sleep(Duration::from_millis(wait_time));\n                                continue;\n                            }\n\n                            return Err(\n                                PyError(format!(\"Jupiter API error: HTTP {}\", status)).into()\n                            );\n                        }\n                    }\n                    Err(e) => {\n                        error!(\"Jupiter API request failed: {}\", e);\n\n                        // Network errors are retried linearly\n                        if retries < max_retries {\n                            retries += 1;\n                            let wait_time = 50 * retries; // Linear backoff\n                            std::thread::sleep(Duration::from_millis(wait_time));\n                            continue;\n                        }\n\n                        return Err(PyError(format!(\"Jupiter API request failed: {}\", e)).into());\n                    }\n                }\n            };\n\n            // Step 3: Create essential instructions to keep transaction size small\n            let mut essential_instructions = Vec::new();\n\n            // Add compute budget instructions\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(\n                self.compute_limit,\n            ));\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(\n                priority_fee_value,\n            ));\n\n            // Parse setupInstructions if they exist\n            if let Some(setup_instructions) = instr_response\n                .get(\"setupInstructions\")\n                .and_then(|v| v.as_array())\n            {\n                for instr in setup_instructions {\n                    let program_id_str = instr[\"programId\"].as_str().ok_or_else(|| {\n                        error!(\"Program ID not found in setup instruction\");\n                        PyError(\"Program ID not found in setup instruction\".to_string())\n                    })?;\n                    let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                        error!(\"Invalid program ID: {}\", e);\n                        PyError(format!(\"Invalid program ID: {}\", e))\n                    })?;\n\n                    let accounts_arr = instr[\"accounts\"].as_array().ok_or_else(|| {\n                        error!(\"Accounts not found in setup instruction\");\n                        PyError(\"Accounts not found in setup instruction\".to_string())\n                    })?;\n\n                    let mut accounts = Vec::new();\n\n                    for account in accounts_arr {\n                        let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                            error!(\"Pubkey not found in account\");\n                            PyError(\"Pubkey not found in account\".to_string())\n                        })?;\n                        let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                            error!(\"Invalid pubkey: {}\", e);\n                            PyError(format!(\"Invalid pubkey: {}\", e))\n                        })?;\n\n                        let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                        let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                        let account_meta = if is_writable {\n                            if is_signer {\n                                AccountMeta::new(pubkey, true)\n                            } else {\n                                AccountMeta::new(pubkey, false)\n                            }\n                        } else {\n                            if is_signer {\n                                AccountMeta::new_readonly(pubkey, true)\n                            } else {\n                                AccountMeta::new_readonly(pubkey, false)\n                            }\n                        };\n\n                        accounts.push(account_meta);\n                    }\n\n                    let data_str = instr[\"data\"].as_str().ok_or_else(|| {\n                        error!(\"Data not found in setup instruction\");\n                        PyError(\"Data not found in setup instruction\".to_string())\n                    })?;\n\n                    let data = base64::decode(data_str).map_err(|e| {\n                        error!(\"Failed to decode setup instruction data: {}\", e);\n                        PyError(format!(\"Failed to decode setup instruction data: {}\", e))\n                    })?;\n\n                    let instruction = Instruction {\n                        program_id,\n                        accounts,\n                        data,\n                    };\n\n                    essential_instructions.push(instruction);\n                }\n            }\n\n            // Add swapInstruction if it exists (this is critical)\n            if let Some(swap_instr) = instr_response.get(\"swapInstruction\") {\n                let program_id_str = swap_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in swap instruction\");\n                    PyError(\"Program ID not found in swap instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = swap_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in swap instruction\");\n                    PyError(\"Accounts not found in swap instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = swap_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in swap instruction\");\n                    PyError(\"Data not found in swap instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode swap instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode swap instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            } else {\n                error!(\"No swap instruction found in response\");\n                return Err(\n                    PyError(\"Jupiter swap instruction not found in response\".to_string()).into(),\n                );\n            }\n\n            // Add cleanupInstruction if it exists\n            if let Some(cleanup_instr) = instr_response.get(\"cleanupInstruction\") {\n                let program_id_str = cleanup_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in cleanup instruction\");\n                    PyError(\"Program ID not found in cleanup instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = cleanup_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in cleanup instruction\");\n                    PyError(\"Accounts not found in cleanup instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = cleanup_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in cleanup instruction\");\n                    PyError(\"Data not found in cleanup instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode cleanup instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode cleanup instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            }\n\n            // Check if we have any instructions beyond compute budget\n            if essential_instructions.len() <= 2 {\n                error!(\"No Jupiter instructions found in response\");\n                return Err(\n                    PyError(\"Jupiter instructions not found in response\".to_string()).into(),\n                );\n            }\n\n            // Step 4: Get recent blockhash from optimized cache\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n            debug!(\"Using cached blockhash: {}\", blockhash);\n\n            // Step 5: Create and sign transaction with essential instructions\n            let mut transaction = Transaction::new_signed_with_payer(\n                &essential_instructions,\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                blockhash,\n            );\n\n            // Step 6: Send transaction with optimized retry logic\n            let send_config = RpcSendTransactionConfig {\n                skip_preflight: self.skip_preflight,\n                preflight_commitment: Some(CommitmentLevel::Processed),\n                encoding: Some(UiTransactionEncoding::Base64),\n                max_retries: Some(self.max_retries),\n                ..Default::default()\n            };\n\n            // Track if we need to retry with new blockhash\n            let mut retry_count = 0;\n            let max_retries = 2; // Specific to blockhash errors\n\n            while retry_count <= max_retries {\n                match self\n                    .rpc_client\n                    .send_transaction_with_config(&transaction, send_config.clone())\n                {\n                    Ok(signature) => {\n                        info!(\n                            \"Jupiter swap executed: {} SOL from {} to {} with signature {}\",\n                            amount_sol, input_mint, output_mint, signature\n                        );\n                        return Ok(signature.to_string());\n                    }\n                    Err(e) => {\n                        let error_str = e.to_string();\n\n                        // If it's a blockhash error, try with fresh blockhash\n                        if error_str.contains(\"blockhash\") && retry_count < max_retries {\n                            error!(\n                                \"Blockhash error, retrying with fresh blockhash: {}\",\n                                error_str\n                            );\n\n                            // Force refresh the blockhash\n                            let new_blockhash = blockhash_cache.force_update();\n\n                            // Create new transaction with fresh blockhash\n                            let new_transaction = Transaction::new_signed_with_payer(\n                                &essential_instructions,\n                                Some(&self.keypair.pubkey()),\n                                &[&self.keypair],\n                                new_blockhash,\n                            );\n\n                            // Update transaction for next retry\n                            transaction = new_transaction;\n\n                            retry_count += 1;\n                            continue;\n                        }\n\n                        error!(\"Failed to send transaction: {}\", e);\n                        return Err(PyError(format!(\"Failed to send transaction: {}\", e)).into());\n                    }\n                }\n            }\n\n            Err(PyError(\"Max retries exceeded\".to_string()).into())\n        })\n    }\n\n    /// Sell tokens for SOL via Jupiter - Optimized version\n    fn sell_token_for_sol_via_jupiter(\n        &self,\n        py: Python<'_>,\n        token_mint: String,\n        amount_tokens: f64,\n        slippage_percent: Option<f64>,\n        priority_multiplier: Option<u64>,\n    ) -> PyResult<String> {\n        // Get token decimals first while holding the GIL\n        let token_decimals = self.get_token_decimals(py, token_mint.clone())?;\n\n        // Convert amount to token units\n        let amount_in = (amount_tokens * 10f64.powi(token_decimals as i32)) as u64;\n\n        // Dynamic slippage calculation\n        let slippage = match slippage_percent {\n            Some(val) => val / 100.0,\n            None => DEFAULT_SLIPPAGE,\n        };\n        let slippage_bps = (slippage * 10000.0) as u32;\n\n        // Priority fee calculation\n        let priority_multiplier_value = priority_multiplier.unwrap_or(1);\n        let priority_fee_value = self.priority_fee * priority_multiplier_value;\n\n        // SOL mint address\n        let sol_mint = WSOL_ADDRESS.to_string();\n\n        let max_accounts = env::var(\"MAX_ACCOUNTS\")\n            .map(|v| v.parse::<u32>().unwrap_or(8))\n            .unwrap_or(8);\n\n        // Now release the GIL for network operations\n        py.allow_threads(|| {\n            // Step 1: Check if we have this in cache\n            let cache_key = format!(\"{}:{}:{}:{}\", token_mint, sol_mint, amount_in, slippage_bps);\n            let jupiter_cache = JUPITER_CACHE.get().unwrap();\n\n            let quote_response = match jupiter_cache.get(&cache_key) {\n                Some(cached) => {\n                    debug!(\"Jupiter quote cache hit: {}\", cache_key);\n                    cached\n                }\n                None => {\n                    // Step 1: Get a quote from Jupiter API\n                    let quote_url = format!(\n                        \"{}?inputMint={}&outputMint={}&amount={}&slippageBps={}\",\n                        JUPITER_QUOTE_API, token_mint, sol_mint, amount_in, slippage_bps\n                    );\n\n                    info!(\"Getting Jupiter quote for token sell: {}\", quote_url);\n\n                    // Implement retry logic\n                    let mut retries = 0;\n                    let max_retries = 3;\n\n                    loop {\n                        // Add authentication headers if needed\n                        let mut request = self.http_client.get(&quote_url);\n                        if let Some(key) = &self.api_key {\n                            request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                        }\n\n                        match request.send() {\n                            Ok(response) => {\n                                if response.status().is_success() {\n                                    match response.json::<serde_json::Value>() {\n                                        Ok(quote_data) => {\n                                            // Check for API errors\n                                            if quote_data.get(\"error\").is_some() {\n                                                let error_msg = quote_data[\"error\"]\n                                                    .as_str()\n                                                    .unwrap_or(\"Unknown error\");\n                                                error!(\"Jupiter quote error: {}\", error_msg);\n                                                return Err(PyError(format!(\n                                                    \"Jupiter quote error: {}\",\n                                                    error_msg\n                                                ))\n                                                .into());\n                                            }\n\n                                            // Cache the result\n                                            jupiter_cache\n                                                .set(cache_key.clone(), quote_data.clone());\n\n                                            // Return quote\n                                            break quote_data;\n                                        }\n                                        Err(e) => {\n                                            error!(\"Failed to parse Jupiter quote response: {}\", e);\n                                            return Err(PyError(format!(\n                                                \"Failed to parse Jupiter quote: {}\",\n                                                e\n                                            ))\n                                            .into());\n                                        }\n                                    }\n                                } else {\n                                    let status = response.status();\n                                    error!(\"Jupiter API error: HTTP {}\", status);\n\n                                    // For server errors, retry with linear backoff\n                                    if status.is_server_error() && retries < max_retries {\n                                        retries += 1;\n                                        let wait_time = 50 * retries; // Linear backoff\n                                        std::thread::sleep(Duration::from_millis(wait_time));\n                                        continue;\n                                    }\n\n                                    return Err(PyError(format!(\n                                        \"Jupiter API error: HTTP {}\",\n                                        status\n                                    ))\n                                    .into());\n                                }\n                            }\n                            Err(e) => {\n                                error!(\"Jupiter API request failed: {}\", e);\n\n                                // Network errors are retried linearly\n                                if retries < max_retries {\n                                    retries += 1;\n                                    let wait_time = 50 * retries; // Linear backoff\n                                    std::thread::sleep(Duration::from_millis(wait_time));\n                                    continue;\n                                }\n\n                                return Err(\n                                    PyError(format!(\"Jupiter API request failed: {}\", e)).into()\n                                );\n                            }\n                        }\n                    }\n                }\n            };\n\n            // Step 2: Use the swap-instructions endpoint\n            let instr_payload = serde_json::json!({\n                \"quoteResponse\": quote_response,\n                \"userPublicKey\": self.keypair.pubkey().to_string(),\n                \"computeUnitPriceMicroLamports\": priority_fee_value,\n                \"wrapUnwrapSOL\": true,\n                // Since it's a token sale, we want fast execution\n                \"onlyDirectRoutes\": true,\n                \"maxHops\": 1,\n                \"maxAccounts\": max_accounts\n            });\n\n            info!(\"Getting Jupiter swap instructions for sell\");\n\n            // Implement retry logic for instructions\n            let mut retries = 0;\n            let max_retries = 3;\n\n            let instr_response = loop {\n                // Add authentication headers if needed\n                let mut request = self.http_client.post(JUPITER_SWAP_API).json(&instr_payload);\n                if let Some(key) = &self.api_key {\n                    request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                }\n\n                match request.send() {\n                    Ok(response) => {\n                        if response.status().is_success() {\n                            match response.json::<serde_json::Value>() {\n                                Ok(instr_data) => {\n                                    // Check for API errors\n                                    if instr_data.get(\"error\").is_some() {\n                                        let error_msg =\n                                            instr_data[\"error\"].as_str().unwrap_or(\"Unknown error\");\n                                        error!(\"Jupiter instructions error: {}\", error_msg);\n                                        return Err(PyError(format!(\n                                            \"Jupiter instructions error: {}\",\n                                            error_msg\n                                        ))\n                                        .into());\n                                    }\n\n                                    break instr_data;\n                                }\n                                Err(e) => {\n                                    error!(\"Failed to parse Jupiter instructions response: {}\", e);\n                                    return Err(PyError(format!(\n                                        \"Failed to parse Jupiter instructions response: {}\",\n                                        e\n                                    ))\n                                    .into());\n                                }\n                            }\n                        } else {\n                            let status = response.status();\n                            error!(\"Jupiter API error: HTTP {}\", status);\n\n                            // For server errors, retry with linear backoff\n                            if status.is_server_error() && retries < max_retries {\n                                retries += 1;\n                                let wait_time = 50 * retries; // Linear backoff\n                                std::thread::sleep(Duration::from_millis(wait_time));\n                                continue;\n                            }\n\n                            return Err(\n                                PyError(format!(\"Jupiter API error: HTTP {}\", status)).into()\n                            );\n                        }\n                    }\n                    Err(e) => {\n                        error!(\"Jupiter API request failed: {}\", e);\n\n                        // Network errors are retried linearly\n                        if retries < max_retries {\n                            retries += 1;\n                            let wait_time = 50 * retries; // Linear backoff\n                            std::thread::sleep(Duration::from_millis(wait_time));\n                            continue;\n                        }\n\n                        return Err(PyError(format!(\"Jupiter API request failed: {}\", e)).into());\n                    }\n                }\n            };\n\n            // Step 3: Create essential instructions to keep transaction size small\n            let mut essential_instructions = Vec::new();\n\n            // Add compute budget instructions\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(\n                self.compute_limit,\n            ));\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(\n                priority_fee_value,\n            ));\n\n            // Parse setupInstructions if they exist\n            if let Some(setup_instructions) = instr_response\n                .get(\"setupInstructions\")\n                .and_then(|v| v.as_array())\n            {\n                for instr in setup_instructions {\n                    let program_id_str = instr[\"programId\"].as_str().ok_or_else(|| {\n                        error!(\"Program ID not found in setup instruction\");\n                        PyError(\"Program ID not found in setup instruction\".to_string())\n                    })?;\n                    let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                        error!(\"Invalid program ID: {}\", e);\n                        PyError(format!(\"Invalid program ID: {}\", e))\n                    })?;\n\n                    let accounts_arr = instr[\"accounts\"].as_array().ok_or_else(|| {\n                        error!(\"Accounts not found in setup instruction\");\n                        PyError(\"Accounts not found in setup instruction\".to_string())\n                    })?;\n\n                    let mut accounts = Vec::new();\n\n                    for account in accounts_arr {\n                        let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                            error!(\"Pubkey not found in account\");\n                            PyError(\"Pubkey not found in account\".to_string())\n                        })?;\n                        let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                            error!(\"Invalid pubkey: {}\", e);\n                            PyError(format!(\"Invalid pubkey: {}\", e))\n                        })?;\n\n                        let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                        let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                        let account_meta = if is_writable {\n                            if is_signer {\n                                AccountMeta::new(pubkey, true)\n                            } else {\n                                AccountMeta::new(pubkey, false)\n                            }\n                        } else {\n                            if is_signer {\n                                AccountMeta::new_readonly(pubkey, true)\n                            } else {\n                                AccountMeta::new_readonly(pubkey, false)\n                            }\n                        };\n\n                        accounts.push(account_meta);\n                    }\n\n                    let data_str = instr[\"data\"].as_str().ok_or_else(|| {\n                        error!(\"Data not found in setup instruction\");\n                        PyError(\"Data not found in setup instruction\".to_string())\n                    })?;\n\n                    let data = base64::decode(data_str).map_err(|e| {\n                        error!(\"Failed to decode setup instruction data: {}\", e);\n                        PyError(format!(\"Failed to decode setup instruction data: {}\", e))\n                    })?;\n\n                    let instruction = Instruction {\n                        program_id,\n                        accounts,\n                        data,\n                    };\n\n                    essential_instructions.push(instruction);\n                }\n            }\n\n            // Add swapInstruction if it exists (this is critical)\n            if let Some(swap_instr) = instr_response.get(\"swapInstruction\") {\n                let program_id_str = swap_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in swap instruction\");\n                    PyError(\"Program ID not found in swap instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = swap_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in swap instruction\");\n                    PyError(\"Accounts not found in swap instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = swap_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in swap instruction\");\n                    PyError(\"Data not found in swap instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode swap instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode swap instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            } else {\n                error!(\"No swap instruction found in response\");\n                return Err(\n                    PyError(\"Jupiter swap instruction not found in response\".to_string()).into(),\n                );\n            }\n\n            // Add cleanupInstruction if it exists\n            if let Some(cleanup_instr) = instr_response.get(\"cleanupInstruction\") {\n                let program_id_str = cleanup_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in cleanup instruction\");\n                    PyError(\"Program ID not found in cleanup instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = cleanup_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in cleanup instruction\");\n                    PyError(\"Accounts not found in cleanup instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = cleanup_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in cleanup instruction\");\n                    PyError(\"Data not found in cleanup instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode cleanup instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode cleanup instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            }\n\n            // Check if we have any instructions beyond compute budget\n            if essential_instructions.len() <= 2 {\n                error!(\"No Jupiter instructions found in response\");\n                return Err(\n                    PyError(\"Jupiter instructions not found in response\".to_string()).into(),\n                );\n            }\n\n            // Step 4: Get recent blockhash from optimized cache\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n            debug!(\"Using cached blockhash: {}\", blockhash);\n\n            // Step 5: Create and sign transaction with essential instructions\n            let mut transaction = Transaction::new_signed_with_payer(\n                &essential_instructions,\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                blockhash,\n            );\n\n            // Step 6: Send transaction with optimized retry logic\n            let send_config = RpcSendTransactionConfig {\n                skip_preflight: self.skip_preflight,\n                preflight_commitment: Some(CommitmentLevel::Processed),\n                encoding: Some(UiTransactionEncoding::Base64),\n                max_retries: Some(self.max_retries),\n                ..Default::default()\n            };\n\n            // Track if we need to retry with new blockhash\n            let mut retry_count = 0;\n            let max_retries = 2; // Specific to blockhash errors\n\n            while retry_count <= max_retries {\n                match self\n                    .rpc_client\n                    .send_transaction_with_config(&transaction, send_config.clone())\n                {\n                    Ok(signature) => {\n                        info!(\n                            \"Jupiter token sell executed: {} tokens to SOL with signature {}\",\n                            amount_tokens, signature\n                        );\n                        return Ok(signature.to_string());\n                    }\n                    Err(e) => {\n                        let error_str = e.to_string();\n\n                        // If it's a blockhash error, try with fresh blockhash\n                        if error_str.contains(\"blockhash\") && retry_count < max_retries {\n                            error!(\n                                \"Blockhash error, retrying with fresh blockhash: {}\",\n                                error_str\n                            );\n\n                            // Force refresh the blockhash\n                            let new_blockhash = blockhash_cache.force_update();\n\n                            // Create new transaction with fresh blockhash\n                            let new_transaction = Transaction::new_signed_with_payer(\n                                &essential_instructions,\n                                Some(&self.keypair.pubkey()),\n                                &[&self.keypair],\n                                new_blockhash,\n                            );\n\n                            // Update transaction for next retry\n                            transaction = new_transaction;\n\n                            retry_count += 1;\n                            continue;\n                        }\n\n                        error!(\"Failed to send transaction: {}\", e);\n                        return Err(PyError(format!(\"Failed to send transaction: {}\", e)).into());\n                    }\n                }\n            }\n\n            Err(PyError(\"Max retries exceeded\".to_string()).into())\n        })\n    }\n\n    /// Get token decimals with caching for speed\n    fn get_token_decimals(&self, py: Python<'_>, token_mint: String) -> PyResult<u8> {\n        // Check cache first\n        if let Some(decimals) = TOKEN_DECIMALS_CACHE.get(&token_mint) {\n            return Ok(*decimals);\n        }\n\n        // Not in cache, get from chain with GIL released\n        py.allow_threads(|| {\n            // Get token mint pubkey\n            let token_mint_pubkey = Pubkey::from_str(&token_mint)\n                .map_err(|e| PyErr::new::<PyValueError, _>(format!(\"Invalid pubkey: {}\", e)))?;\n\n            // Get mint data\n            let mint_data = self\n                .rpc_client\n                .get_account_data(&token_mint_pubkey)\n                .map_err(|e| {\n                    PyErr::new::<PyRuntimeError, _>(format!(\"Failed to get account data: {}\", e))\n                })?;\n\n            // Unpack mint data\n            let mint_info = spl_token::state::Mint::unpack(&mint_data).map_err(|e| {\n                PyErr::new::<PyRuntimeError, _>(format!(\"Failed to unpack mint data: {}\", e))\n            })?;\n\n            // Cache the result\n            TOKEN_DECIMALS_CACHE.insert(token_mint, mint_info.decimals);\n\n            Ok(mint_info.decimals)\n        })\n    }\n\n    /// Create token account if it doesn't exist - with improved error handling\n    fn create_token_account_if_needed(&self, py: Python<'_>, token_mint: String) -> PyResult<bool> {\n        // Get token mint pubkey\n        let token_mint_pubkey = match Pubkey::from_str(&token_mint) {\n            Ok(pubkey) => pubkey,\n            Err(e) => return Err(PyValueError::new_err(format!(\"Invalid pubkey: {}\", e))),\n        };\n\n        // Get associated token account\n        let token_account =\n            get_associated_token_address(&self.keypair.pubkey(), &token_mint_pubkey);\n\n        // Check if account exists - do this with the GIL held\n        let account_exists = self.rpc_client.get_account_data(&token_account).is_ok();\n        if account_exists {\n            return Ok(false);\n        }\n\n        // Create token account instruction\n        let create_ata_ix = create_associated_token_account_idempotent(\n            &self.keypair.pubkey(),\n            &self.keypair.pubkey(),\n            &token_mint_pubkey,\n            &Pubkey::from_str(&self.token_program_id)\n                .map_err(|e| PyValueError::new_err(format!(\"Invalid token program ID: {}\", e)))?,\n        );\n\n        // Now we can release the GIL for the network operation\n        py.allow_threads(|| {\n            // Get blockhash from cache\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n\n            // Create transaction\n            let transaction = Transaction::new_signed_with_payer(\n                &[create_ata_ix],\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                blockhash,\n            );\n\n            // Send transaction\n            match self.rpc_client.send_and_confirm_transaction(&transaction) {\n                Ok(signature) => {\n                    info!(\"Created token account for {}: {}\", token_mint, signature);\n                    Ok(true)\n                }\n                Err(e) => {\n                    // Check if the error is because the account already exists\n                    if e.to_string().contains(\"already in use\") {\n                        debug!(\"Token account for {} already exists\", token_mint);\n                        return Ok(true);\n                    }\n\n                    error!(\"Failed to create token account for {}: {}\", token_mint, e);\n                    return Err(PyRuntimeError::new_err(format!(\n                        \"Failed to create token account: {}\",\n                        e\n                    )));\n                }\n            }\n        })\n    }\n\n    /// Get SOL balance with optimized caching\n    fn get_sol_balance(&self, py: Python<'_>) -> PyResult<f64> {\n        py.allow_threads(\n            || match self.rpc_client.get_balance(&self.keypair.pubkey()) {\n                Ok(balance) => Ok(balance as f64 / LAMPORTS_PER_SOL as f64),\n                Err(e) => {\n                    error!(\"Failed to get SOL balance: {}\", e);\n                    Err(PyRuntimeError::new_err(format!(\n                        \"Failed to get SOL balance: {}\",\n                        e\n                    )))\n                }\n            },\n        )\n    }\n\n    /// Get token balance with optimized error handling\n    fn get_token_balance(&self, py: Python<'_>, token_mint: String) -> PyResult<f64> {\n        py.allow_threads(|| {\n            // Get token mint pubkey\n            let token_mint_pubkey = Pubkey::from_str(&token_mint)\n                .map_err(|e| PyValueError::new_err(format!(\"Invalid pubkey: {}\", e)))?;\n\n            // Get associated token account\n            let token_account =\n                get_associated_token_address(&self.keypair.pubkey(), &token_mint_pubkey);\n\n            // Check if account exists\n            match self.rpc_client.get_account_data(&token_account) {\n                Ok(data) => {\n                    // Account exists, unpack data\n                    let account_info = spl_token::state::Account::unpack(&data).map_err(|e| {\n                        PyRuntimeError::new_err(format!(\"Failed to unpack token account: {}\", e))\n                    })?;\n\n                    // Get token mint data for decimals - check cache first\n                    let decimals = if let Some(decimals) = TOKEN_DECIMALS_CACHE.get(&token_mint) {\n                        *decimals\n                    } else {\n                        // Get from chain if not in cache\n                        let mint_data = self\n                            .rpc_client\n                            .get_account_data(&token_mint_pubkey)\n                            .map_err(|e| {\n                                PyRuntimeError::new_err(format!(\"Failed to get mint data: {}\", e))\n                            })?;\n\n                        let mint_info =\n                            spl_token::state::Mint::unpack(&mint_data).map_err(|e| {\n                                PyRuntimeError::new_err(format!(\n                                    \"Failed to unpack mint data: {}\",\n                                    e\n                                ))\n                            })?;\n\n                        // Cache the result\n                        TOKEN_DECIMALS_CACHE.insert(token_mint.clone(), mint_info.decimals);\n\n                        mint_info.decimals\n                    };\n\n                    // Calculate balance with proper decimals\n                    let balance = account_info.amount as f64 / 10f64.powi(decimals as i32);\n\n                    Ok(balance)\n                }\n                Err(_) => {\n                    // Account doesn't exist, balance is 0\n                    Ok(0.0)\n                }\n            }\n        })\n    }\n\n    /// Get wallet's public address\n    fn get_address(&self) -> PyResult<String> {\n        Ok(self.keypair.pubkey().to_string())\n    }\n\n    /// Get cached blockhash with optimized approach\n    fn get_cached_blockhash(&self, py: Python<'_>) -> PyResult<String> {\n        py.allow_threads(|| {\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n            Ok(blockhash.to_string())\n        })\n    }\n\n    /// Force update the blockhash cache\n    fn force_update_blockhash(&self, py: Python<'_>) -> PyResult<String> {\n        py.allow_threads(|| {\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.force_update();\n            Ok(blockhash.to_string())\n        })\n    }\n\n    /// Confirm transaction with optimized retry logic\n    fn confirm_transaction(\n        &self,\n        py: Python<'_>,\n        signature_str: String,\n        timeout: u64,\n    ) -> PyResult<bool> {\n        py.allow_threads(|| {\n            // Parse the signature string - using simplified error handling\n            let signature = Signature::from_str(&signature_str)\n                .map_err(|e| PyValueError::new_err(format!(\"Invalid signature: {}\", e)))?;\n\n            let start_time = Instant::now();\n            let timeout_duration = Duration::from_secs(timeout);\n\n            while start_time.elapsed() < timeout_duration {\n                match self.rpc_client.get_signature_status(&signature) {\n                    Ok(Some(Ok(_))) => return Ok(true),\n                    Ok(Some(Err(e))) => {\n                        error!(\"Transaction failed: {:?}\", e);\n                        return Err(PyRuntimeError::new_err(format!(\n                            \"Transaction failed: {:?}\",\n                            e\n                        )));\n                    }\n                    Ok(None) => {\n                        // Sleep shorter time for faster responses\n                        std::thread::sleep(Duration::from_millis(50));\n                    }\n                    Err(e) => {\n                        error!(\"Status check failed: {}\", e);\n                        // Sleep a bit before retrying\n                        std::thread::sleep(Duration::from_millis(500));\n                    }\n                }\n            }\n\n            error!(\"Transaction confirmation timed out\");\n            Err(PyRuntimeError::new_err(\n                \"Transaction confirmation timed out\".to_string(),\n            ))\n        })\n    }\n}\n\n/// Python module initialization\n#[pymodule]\nfn solana_rust_bot(_py: Python, m: &PyModule) -> PyResult<()> {\n    // Initialize logging\n    pyo3_log::init();\n\n    // Register classes\n    m.add_class::<SolanaTrader>()?;\n\n    // Add constants\n    m.add(\"LAMPORTS_PER_SOL\", LAMPORTS_PER_SOL)?;\n    m.add(\"DEFAULT_COMPUTE_LIMIT\", DEFAULT_COMPUTE_LIMIT)?;\n    m.add(\"DEFAULT_PRIORITY_FEE\", DEFAULT_PRIORITY_FEE)?;\n    m.add(\"DEFAULT_MAX_RETRIES\", DEFAULT_MAX_RETRIES)?;\n    m.add(\"DEFAULT_MIN_SOL_BALANCE\", DEFAULT_MIN_SOL_BALANCE)?;\n    m.add(\"DEFAULT_MIN_WSOL_BALANCE\", DEFAULT_MIN_WSOL_BALANCE)?;\n    m.add(\"WSOL_ADDRESS\", WSOL_ADDRESS)?;\n\n    Ok(())\n}\n```\n\n---\n\nIf you want me to help with anything else, just say! Take care and rest well.","behavior":"degenerate_repetition","conversation_hash":"3abed495c1bd1ad3368df85cfda5fc69","conversation_redacted":false,"conversation_toxic":false,"country":"United States","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":225807,"n_turns_in_conversation":1,"n_words":14942,"source_row_offset":31321,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:19 GMT","turn_id":"aa2d037f6ec392d5beb3fb3d","turn_index":0,"user_text":"use base64;\nuse log::{debug, error, info};\nuse pyo3::exceptions::{PyFileNotFoundError, PyRuntimeError, PyValueError};\nuse pyo3::prelude::*;\nuse pyo3::types::PyDict;\nuse solana_client::rpc_client::RpcClient;\nuse solana_client::rpc_config::RpcSendTransactionConfig;\nuse solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel};\nuse solana_sdk::compute_budget::ComputeBudgetInstruction;\nuse solana_sdk::hash::Hash;\nuse solana_sdk::instruction::{AccountMeta, Instruction};\nuse solana_sdk::program_pack::Pack;\nuse solana_sdk::pubkey::Pubkey;\nuse solana_sdk::signature::{read_keypair_file, Keypair, Signature, Signer};\nuse solana_sdk::transaction::Transaction;\nuse solana_transaction_status::UiTransactionEncoding;\nuse spl_associated_token_account::{\n    get_associated_token_address, instruction::create_associated_token_account_idempotent,\n};\nuse spl_token;\nuse std::env;\nuse std::path::Path;\nuse std::str::FromStr;\nuse std::sync::Arc;\nuse std::time::{Duration, Instant};\n// Fast blockhash caching using RwLock instead of Mutex\nuse parking_lot::RwLock;\n// Concurrent map for caching\nuse dashmap::DashMap;\n// Optional async support\nuse once_cell::sync::OnceCell;\nuse tokio::runtime::Runtime;\n// Add header support for authentication\nuse reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_TYPE};\n\n// Fast RwLock-based blockhash cache\nstruct FastBlockhashCache {\n    blockhash: RwLock<Hash>,\n    last_update: RwLock<Instant>,\n    update_interval: Duration,\n    rpc_client: Arc<RpcClient>,\n}\n\nimpl FastBlockhashCache {\n    fn new(rpc_client: Arc<RpcClient>, update_interval_seconds: u64) -> Self {\n        // More robust initial blockhash retrieval with retry logic\n        let mut attempts = 0;\n        let max_attempts = 5;\n        let mut blockhash = None;\n        \n        while attempts < max_attempts {\n            match rpc_client.get_latest_blockhash() {\n                Ok(hash) => {\n                    blockhash = Some(hash);\n                    info!(\"Successfully retrieved initial blockhash\");\n                    break;\n                }\n                Err(e) => {\n                    error!(\"Error getting initial blockhash (attempt {}/{}): {}\", \n                            attempts + 1, max_attempts, e);\n                    attempts += 1;\n                    if attempts < max_attempts {\n                        std::thread::sleep(Duration::from_millis(500));\n                    }\n                }\n            }\n        }\n        \n        // If all attempts failed, use a default blockhash (will be updated later)\n        let blockhash = blockhash.unwrap_or_else(|| {\n            error!(\"Warning: Using placeholder blockhash, will update shortly\");\n            Hash::default()\n        });\n\n        Self {\n            blockhash: RwLock::new(blockhash),\n            last_update: RwLock::new(Instant::now()),\n            update_interval: Duration::from_secs(update_interval_seconds),\n            rpc_client,\n        }\n    }\n\n    fn get_blockhash(&self) -> Hash {\n        // Check if we need to update using a read lock first\n        let should_update = {\n            let last_update = self.last_update.read();\n            last_update.elapsed() >= self.update_interval\n        };\n\n        // If update is needed, get a new blockhash\n        if should_update {\n            // Simply do it synchronously for now to avoid threading issues\n            match self.rpc_client.get_latest_blockhash() {\n                Ok(new_hash) => {\n                    *self.blockhash.write() = new_hash;\n                    *self.last_update.write() = Instant::now();\n                }\n                Err(e) => {\n                    error!(\"Failed to update blockhash: {}\", e);\n                }\n            }\n        }\n\n        // Return current blockhash\n        *self.blockhash.read()\n    }\n\n    fn force_update(&self) -> Hash {\n        match self.rpc_client.get_latest_blockhash() {\n            Ok(new_hash) => {\n                *self.blockhash.write() = new_hash;\n                *self.last_update.write() = Instant::now();\n                new_hash\n            }\n            Err(e) => {\n                error!(\"Failed to force update blockhash: {}\", e);\n                *self.blockhash.read() // Return current one\n            }\n        }\n    }\n}\n\n// Optimized API response cache\nstruct JupiterCache {\n    routes: DashMap<String, (serde_json::Value, Instant)>,\n    ttl: Duration,\n}\n\nimpl JupiterCache {\n    fn new(ttl_seconds: u64) -> Self {\n        Self {\n            routes: DashMap::new(),\n            ttl: Duration::from_secs(ttl_seconds),\n        }\n    }\n\n    fn get(&self, key: &str) -> Option<serde_json::Value> {\n        if let Some(entry) = self.routes.get(key) {\n            if entry.1.elapsed() < self.ttl {\n                return Some(entry.0.clone());\n            }\n        }\n        None\n    }\n\n    fn set(&self, key: String, value: serde_json::Value) {\n        self.routes.insert(key, (value, Instant::now()));\n    }\n\n    fn clear_expired(&self) {\n        let now = Instant::now();\n        let expired_keys: Vec<String> = self\n            .routes\n            .iter()\n            .filter(|r| now.duration_since(r.value().1) >= self.ttl)\n            .map(|r| r.key().clone())\n            .collect();\n\n        for key in expired_keys {\n            self.routes.remove(&key);\n        }\n    }\n}\n\n// Token decimals cache using DashMap\nstatic TOKEN_DECIMALS_CACHE: once_cell::sync::Lazy<DashMap<String, u8>> =\n    once_cell::sync::Lazy::new(|| DashMap::new());\n\n// Fast blockhash cache\nstatic BLOCKHASH_CACHE: once_cell::sync::Lazy<OnceCell<Arc<FastBlockhashCache>>> =\n    once_cell::sync::Lazy::new(|| OnceCell::new());\n\n// Jupiter API cache\nstatic JUPITER_CACHE: once_cell::sync::Lazy<OnceCell<Arc<JupiterCache>>> =\n    once_cell::sync::Lazy::new(|| OnceCell::new());\n\n// Core constants\nconst LAMPORTS_PER_SOL: u64 = 1_000_000_000;\nconst WSOL_ADDRESS: &str = \"So11111111111111111111111111111111111111112\";\nconst TOKEN_PROGRAM_ID: &str = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nconst RAYDIUM_PROGRAM_ID: &str = \"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8\";\nconst SERUM_PROGRAM_ID: &str = \"9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin\";\n\n// Jupiter API constants - Updated for v6\nconst JUPITER_QUOTE_API: &str = \"https://quote-api.jup.ag/v6/quote\";\nconst JUPITER_SWAP_API: &str = \"https://quote-api.jup.ag/v6/swap-instructions\";\n\n// Transaction and trading constants\nconst RAYDIUM_SWAP_INSTRUCTION: u8 = 9;\nconst DEFAULT_COMPUTE_LIMIT: u32 = 200_000;\nconst DEFAULT_PRIORITY_FEE: u64 = 1_000_000; // 0.001 SOL\nconst DEFAULT_SLIPPAGE: f64 = 0.01; // 1%\nconst DEFAULT_MAX_RETRIES: usize = 3;\n\n// Balance safety thresholds\nconst DEFAULT_MIN_SOL_BALANCE: f64 = 0.03;\nconst DEFAULT_MIN_WSOL_BALANCE: f64 = 0.02;\n\n// Simplified error handling\nstruct PyError(String);\n\nimpl From<PyError> for PyErr {\n    fn from(err: PyError) -> PyErr {\n        PyRuntimeError::new_err(err.0)\n    }\n}\n\n// Initialize tokio runtime for async operations if needed\nfn get_tokio_runtime() -> &'static Runtime {\n    static RUNTIME: OnceCell<Runtime> = OnceCell::new();\n    RUNTIME.get_or_init(|| Runtime::new().expect(\"Failed to create tokio runtime\"))\n}\n\n/// Represents dynamic Raydium swap accounts\n#[derive(Debug, Clone)]\nstruct RaydiumSwapAccounts {\n    amm_id: String,\n    amm_authority: String,\n    amm_open_orders: String,\n    amm_target_orders: String,\n    pool_coin_token_account: String,\n    pool_pc_token_account: String,\n    serum_program_id: String,\n    serum_market: String,\n    serum_bids: String,\n    serum_asks: String,\n    serum_event_queue: String,\n    serum_coin_vault: String,\n    serum_pc_vault: String,\n    serum_vault_signer: String,\n    token_mint: String,\n    token_program_id: String,\n}\n\n/// Main Solana trading class\n#[pyclass]\nstruct SolanaTrader {\n    keypair: Arc<Keypair>,\n    rpc_client: Arc<RpcClient>,\n    rpc_url: String,\n    ws_url: String,\n    compute_limit: u32,\n    priority_fee: u64,\n    skip_preflight: bool,\n    max_retries: usize,\n    min_sol_balance: f64,\n    min_wsol_balance: f64,\n    wsol_address: String,\n    token_program_id: String,\n    system_program_id: String,\n    raydium_program_id: String,\n    serum_program_id: String,\n    keypair_path: String,\n    http_client: reqwest::blocking::Client,\n    api_key: Option<String>, // Add API key field for authentication\n}\n\n#[pymethods]\nimpl SolanaTrader {\n    /// Initialize the SolanaTrader with configuration\n    #[new]\n    fn new(\n        rpc_url: String,\n        ws_url: String,\n        keypair_path: String,\n        compute_limit: Option<u32>,\n        api_key: Option<String>, // Add API key parameter\n    ) -> PyResult<Self> {\n        // Tokio runtime initialization\n        let _ = get_tokio_runtime();\n\n        // Load environment variables if .env file exists\n        let _ = dotenv::dotenv();\n\n        // Get API key from parameter or environment variable\n        let api_key = api_key.or_else(|| env::var(\"HELIUS_API_KEY\").ok());\n        if let Some(key) = &api_key {\n            info!(\"Using API key for authentication\");\n        }\n\n        // Keypair loading with robust error handling\n        let keypair = if Path::new(&keypair_path).exists() {\n            // First, try to read as JSON\n            match read_keypair_file(&keypair_path) {\n                Ok(kp) => kp,\n                Err(_) => {\n                    // If JSON fails, try to read as binary\n                    match std::fs::read(&keypair_path) {\n                        Ok(bytes) => {\n                            if bytes.len() == 64 {\n                                match Keypair::from_bytes(&bytes) {\n                                    Ok(kp) => kp,\n                                    Err(e) => {\n                                        return Err(PyValueError::new_err(format!(\n                                            \"Invalid binary keypair: {}\",\n                                            e\n                                        )))\n                                    }\n                                }\n                            } else {\n                                // Try base58 decoding\n                                match bs58::decode(std::str::from_utf8(&bytes).unwrap_or(\"\"))\n                                    .into_vec()\n                                    .map(|secret_key| Keypair::from_bytes(&secret_key))\n                                {\n                                    Ok(Ok(kp)) => kp,\n                                    _ => {\n                                        return Err(PyValueError::new_err(\n                                            \"Could not parse keypair file in any format\",\n                                        ))\n                                    }\n                                }\n                            }\n                        }\n                        Err(e) => {\n                            return Err(PyRuntimeError::new_err(format!(\n                                \"Failed to read keypair file: {}\",\n                                e\n                            )))\n                        }\n                    }\n                }\n            }\n        } else {\n            return Err(PyFileNotFoundError::new_err(format!(\n                \"Keypair file not found: {}\",\n                keypair_path\n            )));\n        };\n\n        // Create RPC client with processed commitment and authentication\n        // Fix: Use available methods in solana 1.18.x\n        let rpc_client = {\n            // Set timeout and commitment\n            let commitment_config = CommitmentConfig::processed();\n            let timeout = Duration::from_secs(30);\n            \n            // Create client with timeout and commitment\n            // For Solana 1.18.x, we need to use the correct available constructors\n            let client = RpcClient::new_with_timeout_and_commitment(\n                rpc_url.clone(),\n                timeout,\n                commitment_config,\n            );\n            \n            Arc::new(client)\n        };\n\n        // Read environment variables with fallbacks\n        let compute = compute_limit.unwrap_or_else(|| {\n            env::var(\"COMPUTE_LIMIT\")\n                .map(|v| v.parse::<u32>().unwrap_or(DEFAULT_COMPUTE_LIMIT))\n                .unwrap_or(DEFAULT_COMPUTE_LIMIT)\n        });\n\n        let priority_fee = env::var(\"PRIORITY_FEE\")\n            .map(|v| v.parse::<u64>().unwrap_or(DEFAULT_PRIORITY_FEE))\n            .unwrap_or(DEFAULT_PRIORITY_FEE);\n\n        let skip_preflight = env::var(\"SKIP_PREFLIGHT\")\n            .map(|v| v.parse::<bool>().unwrap_or(true))\n            .unwrap_or(true);\n\n        let max_retries = env::var(\"MAX_RETRIES\")\n            .map(|v| v.parse::<usize>().unwrap_or(DEFAULT_MAX_RETRIES))\n            .unwrap_or(DEFAULT_MAX_RETRIES);\n\n        let min_sol_balance = env::var(\"MIN_SOL_BALANCE\")\n            .map(|v| v.parse::<f64>().unwrap_or(DEFAULT_MIN_SOL_BALANCE))\n            .unwrap_or(DEFAULT_MIN_SOL_BALANCE);\n\n        let min_wsol_balance = env::var(\"MIN_WSOL_BALANCE\")\n            .map(|v| v.parse::<f64>().unwrap_or(DEFAULT_MIN_WSOL_BALANCE))\n            .unwrap_or(DEFAULT_MIN_WSOL_BALANCE);\n\n        // Create optimized HTTP client with authentication\n        let http_client = {\n            let builder = reqwest::blocking::Client::builder()\n                .timeout(Duration::from_secs(30))\n                .pool_max_idle_per_host(32);\n            \n            // Create default headers\n            let mut headers = HeaderMap::new();\n            \n            // Add Solana CLI User-Agent header\n            if let Ok(value) = HeaderValue::from_str(\"solana-cli 1.18.23 (src:aeb3a2e1; feat:4215500110, client:SolanaLabs)\") {\n                headers.insert(reqwest::header::USER_AGENT, value);\n                headers.insert(CONTENT_TYPE, HeaderValue::from_static(\"application/json\"));\n            }\n            \n            // Add authentication headers if API key is provided\n            if let Some(key) = &api_key {\n                let auth_value = format!(\"Bearer {}\", key);\n                if let Ok(value) = HeaderValue::from_str(&auth_value) {\n                    headers.insert(AUTHORIZATION, value);\n                }\n            }\n            \n            // Build the client with headers\n            builder.default_headers(headers).build()\n        }.unwrap_or_else(|_| reqwest::blocking::Client::new());\n\n        // Initialize fast blockhash cache if not already initialized\n        BLOCKHASH_CACHE.get_or_init(|| {\n            let cache = FastBlockhashCache::new(\n                rpc_client.clone(),\n                2, // Update every 2 seconds\n            );\n            Arc::new(cache)\n        });\n\n        // Initialize Jupiter cache if not already initialized\n        JUPITER_CACHE.get_or_init(|| {\n            let cache = JupiterCache::new(10); // 10 second TTL\n            Arc::new(cache)\n        });\n\n        // Start a periodic cache cleanup thread\n        {\n            let jupiter_cache = JUPITER_CACHE.get().unwrap().clone();\n            std::thread::spawn(move || loop {\n                std::thread::sleep(Duration::from_secs(60));\n                jupiter_cache.clear_expired();\n                debug!(\"Cleared expired Jupiter cache entries\");\n            });\n        }\n\n        info!(\n            \"Initialized trader with compute_limit: {}, priority_fee: {}\",\n            compute, priority_fee\n        );\n\n        Ok(Self {\n            keypair: Arc::new(keypair),\n            rpc_client,\n            rpc_url,\n            ws_url,\n            compute_limit: compute,\n            priority_fee,\n            skip_preflight,\n            max_retries,\n            min_sol_balance,\n            min_wsol_balance,\n            wsol_address: WSOL_ADDRESS.to_string(),\n            token_program_id: TOKEN_PROGRAM_ID.to_string(),\n            system_program_id: \"11111111111111111111111111111111\".to_string(),\n            raydium_program_id: RAYDIUM_PROGRAM_ID.to_string(),\n            serum_program_id: SERUM_PROGRAM_ID.to_string(),\n            keypair_path,\n            http_client,\n            api_key,\n        })\n    }\n\n    /// Execute token swap using Jupiter (Solana's DEX aggregator) - Optimized implementation\n    fn execute_jupiter_swap(\n        &self,\n        py: Python<'_>,\n        input_mint: String,\n        output_mint: String,\n        amount_sol: f64,\n        slippage_percent: Option<f64>,\n        priority_multiplier: Option<u64>,\n    ) -> PyResult<String> {\n        // Convert amount to lamports\n        let amount_lamports = (amount_sol * LAMPORTS_PER_SOL as f64).round() as u64;\n\n        // Dynamic slippage calculation\n        let slippage = match slippage_percent {\n            Some(val) => val / 100.0,\n            None => DEFAULT_SLIPPAGE,\n        };\n        let slippage_bps = (slippage * 10000.0) as u32;\n\n        // Priority fee calculation\n        let priority_multiplier_value = priority_multiplier.unwrap_or(1);\n        let priority_fee_value = self.priority_fee * priority_multiplier_value;\n\n        // Ensure token accounts exist for both input and output before releasing the GIL\n        if input_mint != WSOL_ADDRESS {\n            self.create_token_account_if_needed(py, input_mint.clone())?;\n        }\n        if output_mint != WSOL_ADDRESS {\n            self.create_token_account_if_needed(py, output_mint.clone())?;\n        }\n\n        // Now we can safely release the GIL for network operations\n        py.allow_threads(|| {\n            // Step 1: Try to get from cache first\n            let cache_key = format!(\n                \"{}:{}:{}:{}\",\n                input_mint, output_mint, amount_lamports, slippage_bps\n            );\n            let jupiter_cache = JUPITER_CACHE.get().unwrap();\n\n            let quote_response = match jupiter_cache.get(&cache_key) {\n                Some(cached) => {\n                    debug!(\"Jupiter quote cache hit: {}\", cache_key);\n                    cached\n                }\n                None => {\n                    // Step 1: Get a quote from Jupiter API\n                    let quote_url = format!(\n                        \"{}?inputMint={}&outputMint={}&amount={}&slippageBps={}\",\n                        JUPITER_QUOTE_API, input_mint, output_mint, amount_lamports, slippage_bps\n                    );\n\n                    info!(\"Getting Jupiter quote: {}\", quote_url);\n\n                    // Implement retry logic\n                    let mut retries = 0;\n                    let max_retries = 3;\n\n                    loop {\n                        // Add authentication headers if needed\n                        let mut request = self.http_client.get(&quote_url);\n                        if let Some(key) = &self.api_key {\n                            request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                        }\n\n                        match request.send() {\n                            Ok(response) => {\n                                if response.status().is_success() {\n                                    match response.json::<serde_json::Value>() {\n                                        Ok(quote_data) => {\n                                            // Check for API errors\n                                            if quote_data.get(\"error\").is_some() {\n                                                let error_msg = quote_data[\"error\"]\n                                                    .as_str()\n                                                    .unwrap_or(\"Unknown error\");\n                                                error!(\"Jupiter quote error: {}\", error_msg);\n                                                return Err(PyError(format!(\n                                                    \"Jupiter quote error: {}\",\n                                                    error_msg\n                                                ))\n                                                .into());\n                                            }\n\n                                            // Cache the result\n                                            jupiter_cache\n                                                .set(cache_key.clone(), quote_data.clone());\n\n                                            // Return quote\n                                            break quote_data;\n                                        }\n                                        Err(e) => {\n                                            error!(\"Failed to parse Jupiter quote response: {}\", e);\n                                            return Err(PyError(format!(\n                                                \"Failed to parse Jupiter quote: {}\",\n                                                e\n                                            ))\n                                            .into());\n                                        }\n                                    }\n                                } else {\n                                    let status = response.status();\n                                    error!(\"Jupiter API error: HTTP {}\", status);\n\n                                    // For server errors, retry with backoff\n                                    if status.is_server_error() && retries < max_retries {\n                                        retries += 1;\n                                        let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                                        std::thread::sleep(Duration::from_millis(wait_time));\n                                        continue;\n                                    }\n\n                                    return Err(PyError(format!(\n                                        \"Jupiter API error: HTTP {}\",\n                                        status\n                                    ))\n                                    .into());\n                                }\n                            }\n                            Err(e) => {\n                                error!(\"Jupiter API request failed: {}\", e);\n\n                                // Network errors are retried\n                                if retries < max_retries {\n                                    retries += 1;\n                                    let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                                    std::thread::sleep(Duration::from_millis(wait_time));\n                                    continue;\n                                }\n\n                                return Err(\n                                    PyError(format!(\"Jupiter API request failed: {}\", e)).into()\n                                );\n                            }\n                        }\n                    }\n                }\n            };\n\n            // Step 2: Use the swap-instructions endpoint\n            let instr_payload = serde_json::json!({\n                \"quoteResponse\": quote_response,\n                \"userPublicKey\": self.keypair.pubkey().to_string(),\n                \"computeUnitPriceMicroLamports\": priority_fee_value,\n                \"wrapUnwrapSOL\": true,\n                \"onlyDirectRoutes\": true,\n                \"maxHops\": 1,\n                \"maxAccounts\": 12\n            });\n\n            info!(\"Getting Jupiter swap instructions\");\n\n            // Implement retry logic for instructions\n            let mut retries = 0;\n            let max_retries = 3;\n\n            let instr_response = loop {\n                // Add authentication headers if needed\n                let mut request = self.http_client.post(JUPITER_SWAP_API).json(&instr_payload);\n                if let Some(key) = &self.api_key {\n                    request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                }\n\n                match request.send() {\n                    Ok(response) => {\n                        if response.status().is_success() {\n                            match response.json::<serde_json::Value>() {\n                                Ok(instr_data) => {\n                                    // Check for API errors\n                                    if instr_data.get(\"error\").is_some() {\n                                        let error_msg =\n                                            instr_data[\"error\"].as_str().unwrap_or(\"Unknown error\");\n                                        error!(\"Jupiter instructions error: {}\", error_msg);\n                                        return Err(PyError(format!(\n                                            \"Jupiter instructions error: {}\",\n                                            error_msg\n                                        ))\n                                        .into());\n                                    }\n\n                                    break instr_data;\n                                }\n                                Err(e) => {\n                                    error!(\"Failed to parse Jupiter instructions response: {}\", e);\n                                    return Err(PyError(format!(\n                                        \"Failed to parse Jupiter instructions response: {}\",\n                                        e\n                                    ))\n                                    .into());\n                                }\n                            }\n                        } else {\n                            let status = response.status();\n                            error!(\"Jupiter API error: HTTP {}\", status);\n\n                            // For server errors, retry with backoff\n                            if status.is_server_error() && retries < max_retries {\n                                retries += 1;\n                                let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                                std::thread::sleep(Duration::from_millis(wait_time));\n                                continue;\n                            }\n\n                            return Err(\n                                PyError(format!(\"Jupiter API error: HTTP {}\", status)).into()\n                            );\n                        }\n                    }\n                    Err(e) => {\n                        error!(\"Jupiter API request failed: {}\", e);\n\n                        // Network errors are retried\n                        if retries < max_retries {\n                            retries += 1;\n                            let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                            std::thread::sleep(Duration::from_millis(wait_time));\n                            continue;\n                        }\n\n                        return Err(PyError(format!(\"Jupiter API request failed: {}\", e)).into());\n                    }\n                }\n            };\n\n            // Step 3: Create essential instructions to keep transaction size small\n            let mut essential_instructions = Vec::new();\n\n            // Add compute budget instructions\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(\n                self.compute_limit,\n            ));\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(\n                priority_fee_value,\n            ));\n\n            // Parse setupInstructions if they exist\n            if let Some(setup_instructions) = instr_response\n                .get(\"setupInstructions\")\n                .and_then(|v| v.as_array())\n            {\n                for instr in setup_instructions {\n                    let program_id_str = instr[\"programId\"].as_str().ok_or_else(|| {\n                        error!(\"Program ID not found in setup instruction\");\n                        PyError(\"Program ID not found in setup instruction\".to_string())\n                    })?;\n                    let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                        error!(\"Invalid program ID: {}\", e);\n                        PyError(format!(\"Invalid program ID: {}\", e))\n                    })?;\n\n                    let accounts_arr = instr[\"accounts\"].as_array().ok_or_else(|| {\n                        error!(\"Accounts not found in setup instruction\");\n                        PyError(\"Accounts not found in setup instruction\".to_string())\n                    })?;\n\n                    let mut accounts = Vec::new();\n\n                    for account in accounts_arr {\n                        let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                            error!(\"Pubkey not found in account\");\n                            PyError(\"Pubkey not found in account\".to_string())\n                        })?;\n                        let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                            error!(\"Invalid pubkey: {}\", e);\n                            PyError(format!(\"Invalid pubkey: {}\", e))\n                        })?;\n\n                        let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                        let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                        let account_meta = if is_writable {\n                            if is_signer {\n                                AccountMeta::new(pubkey, true)\n                            } else {\n                                AccountMeta::new(pubkey, false)\n                            }\n                        } else {\n                            if is_signer {\n                                AccountMeta::new_readonly(pubkey, true)\n                            } else {\n                                AccountMeta::new_readonly(pubkey, false)\n                            }\n                        };\n\n                        accounts.push(account_meta);\n                    }\n\n                    let data_str = instr[\"data\"].as_str().ok_or_else(|| {\n                        error!(\"Data not found in setup instruction\");\n                        PyError(\"Data not found in setup instruction\".to_string())\n                    })?;\n\n                    let data = base64::decode(data_str).map_err(|e| {\n                        error!(\"Failed to decode setup instruction data: {}\", e);\n                        PyError(format!(\"Failed to decode setup instruction data: {}\", e))\n                    })?;\n\n                    let instruction = Instruction {\n                        program_id,\n                        accounts,\n                        data,\n                    };\n\n                    essential_instructions.push(instruction);\n                }\n            }\n\n            // Add swapInstruction if it exists (this is critical)\n            if let Some(swap_instr) = instr_response.get(\"swapInstruction\") {\n                let program_id_str = swap_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in swap instruction\");\n                    PyError(\"Program ID not found in swap instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = swap_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in swap instruction\");\n                    PyError(\"Accounts not found in swap instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = swap_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in swap instruction\");\n                    PyError(\"Data not found in swap instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode swap instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode swap instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            } else {\n                error!(\"No swap instruction found in response\");\n                return Err(\n                    PyError(\"Jupiter swap instruction not found in response\".to_string()).into(),\n                );\n            }\n\n            // Add cleanupInstruction if it exists\n            if let Some(cleanup_instr) = instr_response.get(\"cleanupInstruction\") {\n                let program_id_str = cleanup_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in cleanup instruction\");\n                    PyError(\"Program ID not found in cleanup instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = cleanup_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in cleanup instruction\");\n                    PyError(\"Accounts not found in cleanup instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = cleanup_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in cleanup instruction\");\n                    PyError(\"Data not found in cleanup instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode cleanup instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode cleanup instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            }\n\n            // Check if we have any instructions beyond compute budget\n            if essential_instructions.len() <= 2 {\n                error!(\"No Jupiter instructions found in response\");\n                return Err(\n                    PyError(\"Jupiter instructions not found in response\".to_string()).into(),\n                );\n            }\n\n            // Step 4: Get recent blockhash from optimized cache\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n            debug!(\"Using cached blockhash: {}\", blockhash);\n\n            // Step 5: Create and sign transaction with essential instructions\n            let mut transaction = Transaction::new_signed_with_payer(\n                &essential_instructions,\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                blockhash,\n            );\n\n            // Step 6: Send transaction with optimized retry logic\n            let send_config = RpcSendTransactionConfig {\n                skip_preflight: self.skip_preflight,\n                preflight_commitment: Some(CommitmentLevel::Processed),\n                encoding: Some(UiTransactionEncoding::Base64),\n                max_retries: Some(self.max_retries),\n                ..Default::default()\n            };\n\n            // Track if we need to retry with new blockhash\n            let mut retry_count = 0;\n            let max_retries = 2; // Specific to blockhash errors\n\n            while retry_count <= max_retries {\n                match self\n                    .rpc_client\n                    .send_transaction_with_config(&transaction, send_config.clone())\n                {\n                    Ok(signature) => {\n                        info!(\n                            \"Jupiter swap executed: {} SOL from {} to {} with signature {}\",\n                            amount_sol, input_mint, output_mint, signature\n                        );\n                        return Ok(signature.to_string());\n                    }\n                    Err(e) => {\n                        let error_str = e.to_string();\n\n                        // If it's a blockhash error, try with fresh blockhash\n                        if error_str.contains(\"blockhash\") && retry_count < max_retries {\n                            error!(\n                                \"Blockhash error, retrying with fresh blockhash: {}\",\n                                error_str\n                            );\n\n                            // Force refresh the blockhash\n                            let new_blockhash = blockhash_cache.force_update();\n\n                            // Create new transaction with fresh blockhash\n                            let new_transaction = Transaction::new_signed_with_payer(\n                                &essential_instructions,\n                                Some(&self.keypair.pubkey()),\n                                &[&self.keypair],\n                                new_blockhash,\n                            );\n\n                            // Update transaction for next retry\n                            transaction = new_transaction;\n\n                            retry_count += 1;\n                            continue;\n                        }\n\n                        error!(\"Failed to send transaction: {}\", e);\n                        return Err(PyError(format!(\"Failed to send transaction: {}\", e)).into());\n                    }\n                }\n            }\n\n            Err(PyError(\"Max retries exceeded\".to_string()).into())\n        })\n    }\n\n    /// Sell tokens for SOL via Jupiter - Optimized version\n    fn sell_token_for_sol_via_jupiter(\n        &self,\n        py: Python<'_>,\n        token_mint: String,\n        amount_tokens: f64,\n        slippage_percent: Option<f64>,\n        priority_multiplier: Option<u64>,\n    ) -> PyResult<String> {\n        // Get token decimals first while holding the GIL\n        let token_decimals = self.get_token_decimals(py, token_mint.clone())?;\n\n        // Convert amount to token units\n        let amount_in = (amount_tokens * 10f64.powi(token_decimals as i32)) as u64;\n\n        // Dynamic slippage calculation\n        let slippage = match slippage_percent {\n            Some(val) => val / 100.0,\n            None => DEFAULT_SLIPPAGE,\n        };\n        let slippage_bps = (slippage * 10000.0) as u32;\n\n        // Priority fee calculation\n        let priority_multiplier_value = priority_multiplier.unwrap_or(1);\n        let priority_fee_value = self.priority_fee * priority_multiplier_value;\n\n        // SOL mint address\n        let sol_mint = WSOL_ADDRESS.to_string();\n\n        // Now release the GIL for network operations\n        py.allow_threads(|| {\n            // Step 1: Check if we have this in cache\n            let cache_key = format!(\"{}:{}:{}:{}\", token_mint, sol_mint, amount_in, slippage_bps);\n            let jupiter_cache = JUPITER_CACHE.get().unwrap();\n\n            let quote_response = match jupiter_cache.get(&cache_key) {\n                Some(cached) => {\n                    debug!(\"Jupiter quote cache hit: {}\", cache_key);\n                    cached\n                }\n                None => {\n                    // Step 1: Get a quote from Jupiter API\n                    let quote_url = format!(\n                        \"{}?inputMint={}&outputMint={}&amount={}&slippageBps={}\",\n                        JUPITER_QUOTE_API, token_mint, sol_mint, amount_in, slippage_bps\n                    );\n\n                    info!(\"Getting Jupiter quote for token sell: {}\", quote_url);\n\n                    // Implement retry logic\n                    let mut retries = 0;\n                    let max_retries = 3;\n\n                    loop {\n                        // Add authentication headers if needed\n                        let mut request = self.http_client.get(&quote_url);\n                        if let Some(key) = &self.api_key {\n                            request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                        }\n\n                        match request.send() {\n                            Ok(response) => {\n                                if response.status().is_success() {\n                                    match response.json::<serde_json::Value>() {\n                                        Ok(quote_data) => {\n                                            // Check for API errors\n                                            if quote_data.get(\"error\").is_some() {\n                                                let error_msg = quote_data[\"error\"]\n                                                    .as_str()\n                                                    .unwrap_or(\"Unknown error\");\n                                                error!(\"Jupiter quote error: {}\", error_msg);\n                                                return Err(PyError(format!(\n                                                    \"Jupiter quote error: {}\",\n                                                    error_msg\n                                                ))\n                                                .into());\n                                            }\n\n                                            // Cache the result\n                                            jupiter_cache\n                                                .set(cache_key.clone(), quote_data.clone());\n\n                                            // Return quote\n                                            break quote_data;\n                                        }\n                                        Err(e) => {\n                                            error!(\"Failed to parse Jupiter quote response: {}\", e);\n                                            return Err(PyError(format!(\n                                                \"Failed to parse Jupiter quote: {}\",\n                                                e\n                                            ))\n                                            .into());\n                                        }\n                                    }\n                                } else {\n                                    let status = response.status();\n                                    error!(\"Jupiter API error: HTTP {}\", status);\n\n                                    // For server errors, retry with backoff\n                                    if status.is_server_error() && retries < max_retries {\n                                        retries += 1;\n                                        let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                                        std::thread::sleep(Duration::from_millis(wait_time));\n                                        continue;\n                                    }\n\n                                    return Err(PyError(format!(\n                                        \"Jupiter API error: HTTP {}\",\n                                        status\n                                    ))\n                                    .into());\n                                }\n                            }\n                            Err(e) => {\n                                error!(\"Jupiter API request failed: {}\", e);\n\n                                // Network errors are retried\n                                if retries < max_retries {\n                                    retries += 1;\n                                    let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                                    std::thread::sleep(Duration::from_millis(wait_time));\n                                    continue;\n                                }\n\n                                return Err(\n                                    PyError(format!(\"Jupiter API request failed: {}\", e)).into()\n                                );\n                            }\n                        }\n                    }\n                }\n            };\n\n            // Step 2: Use the swap-instructions endpoint\n            let instr_payload = serde_json::json!({\n                \"quoteResponse\": quote_response,\n                \"userPublicKey\": self.keypair.pubkey().to_string(),\n                \"computeUnitPriceMicroLamports\": priority_fee_value,\n                \"wrapUnwrapSOL\": true,\n                // Since it's a token sale, we want fast execution\n                \"onlyDirectRoutes\": true,\n                \"maxHops\": 1\n            });\n\n            info!(\"Getting Jupiter swap instructions for sell\");\n\n            // Implement retry logic for instructions\n            let mut retries = 0;\n            let max_retries = 3;\n\n            let instr_response = loop {\n                // Add authentication headers if needed\n                let mut request = self.http_client.post(JUPITER_SWAP_API).json(&instr_payload);\n                if let Some(key) = &self.api_key {\n                    request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n                }\n\n                match request.send() {\n                    Ok(response) => {\n                        if response.status().is_success() {\n                            match response.json::<serde_json::Value>() {\n                                Ok(instr_data) => {\n                                    // Check for API errors\n                                    if instr_data.get(\"error\").is_some() {\n                                        let error_msg =\n                                            instr_data[\"error\"].as_str().unwrap_or(\"Unknown error\");\n                                        error!(\"Jupiter instructions error: {}\", error_msg);\n                                        return Err(PyError(format!(\n                                            \"Jupiter instructions error: {}\",\n                                            error_msg\n                                        ))\n                                        .into());\n                                    }\n\n                                    break instr_data;\n                                }\n                                Err(e) => {\n                                    error!(\"Failed to parse Jupiter instructions response: {}\", e);\n                                    return Err(PyError(format!(\n                                        \"Failed to parse Jupiter instructions response: {}\",\n                                        e\n                                    ))\n                                    .into());\n                                }\n                            }\n                        } else {\n                            let status = response.status();\n                            error!(\"Jupiter API error: HTTP {}\", status);\n\n                            // For server errors, retry with backoff\n                            if status.is_server_error() && retries < max_retries {\n                                retries += 1;\n                                let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                                std::thread::sleep(Duration::from_millis(wait_time));\n                                continue;\n                            }\n\n                            return Err(\n                                PyError(format!(\"Jupiter API error: HTTP {}\", status)).into()\n                            );\n                        }\n                    }\n                    Err(e) => {\n                        error!(\"Jupiter API request failed: {}\", e);\n\n                        // Network errors are retried\n                        if retries < max_retries {\n                            retries += 1;\n                            let wait_time = 2u64.pow(retries) * 100; // Exponential backoff\n                            std::thread::sleep(Duration::from_millis(wait_time));\n                            continue;\n                        }\n\n                        return Err(PyError(format!(\"Jupiter API request failed: {}\", e)).into());\n                    }\n                }\n            };\n\n            // Step 3: Create essential instructions to keep transaction size small\n            let mut essential_instructions = Vec::new();\n\n            // Add compute budget instructions\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(\n                self.compute_limit,\n            ));\n            essential_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(\n                priority_fee_value,\n            ));\n\n            // Parse setupInstructions if they exist\n            if let Some(setup_instructions) = instr_response\n                .get(\"setupInstructions\")\n                .and_then(|v| v.as_array())\n            {\n                for instr in setup_instructions {\n                    let program_id_str = instr[\"programId\"].as_str().ok_or_else(|| {\n                        error!(\"Program ID not found in setup instruction\");\n                        PyError(\"Program ID not found in setup instruction\".to_string())\n                    })?;\n                    let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                        error!(\"Invalid program ID: {}\", e);\n                        PyError(format!(\"Invalid program ID: {}\", e))\n                    })?;\n\n                    let accounts_arr = instr[\"accounts\"].as_array().ok_or_else(|| {\n                        error!(\"Accounts not found in setup instruction\");\n                        PyError(\"Accounts not found in setup instruction\".to_string())\n                    })?;\n\n                    let mut accounts = Vec::new();\n\n                    for account in accounts_arr {\n                        let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                            error!(\"Pubkey not found in account\");\n                            PyError(\"Pubkey not found in account\".to_string())\n                        })?;\n                        let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                            error!(\"Invalid pubkey: {}\", e);\n                            PyError(format!(\"Invalid pubkey: {}\", e))\n                        })?;\n\n                        let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                        let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                        let account_meta = if is_writable {\n                            if is_signer {\n                                AccountMeta::new(pubkey, true)\n                            } else {\n                                AccountMeta::new(pubkey, false)\n                            }\n                        } else {\n                            if is_signer {\n                                AccountMeta::new_readonly(pubkey, true)\n                            } else {\n                                AccountMeta::new_readonly(pubkey, false)\n                            }\n                        };\n\n                        accounts.push(account_meta);\n                    }\n\n                    let data_str = instr[\"data\"].as_str().ok_or_else(|| {\n                        error!(\"Data not found in setup instruction\");\n                        PyError(\"Data not found in setup instruction\".to_string())\n                    })?;\n\n                    let data = base64::decode(data_str).map_err(|e| {\n                        error!(\"Failed to decode setup instruction data: {}\", e);\n                        PyError(format!(\"Failed to decode setup instruction data: {}\", e))\n                    })?;\n\n                    let instruction = Instruction {\n                        program_id,\n                        accounts,\n                        data,\n                    };\n\n                    essential_instructions.push(instruction);\n                }\n            }\n\n            // Add swapInstruction if it exists (this is critical)\n            if let Some(swap_instr) = instr_response.get(\"swapInstruction\") {\n                let program_id_str = swap_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in swap instruction\");\n                    PyError(\"Program ID not found in swap instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = swap_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in swap instruction\");\n                    PyError(\"Accounts not found in swap instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = swap_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in swap instruction\");\n                    PyError(\"Data not found in swap instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode swap instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode swap instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            } else {\n                error!(\"No swap instruction found in response\");\n                return Err(\n                    PyError(\"Jupiter swap instruction not found in response\".to_string()).into(),\n                );\n            }\n\n            // Add cleanupInstruction if it exists\n            if let Some(cleanup_instr) = instr_response.get(\"cleanupInstruction\") {\n                let program_id_str = cleanup_instr[\"programId\"].as_str().ok_or_else(|| {\n                    error!(\"Program ID not found in cleanup instruction\");\n                    PyError(\"Program ID not found in cleanup instruction\".to_string())\n                })?;\n                let program_id = Pubkey::from_str(program_id_str).map_err(|e| {\n                    error!(\"Invalid program ID: {}\", e);\n                    PyError(format!(\"Invalid program ID: {}\", e))\n                })?;\n\n                let accounts_arr = cleanup_instr[\"accounts\"].as_array().ok_or_else(|| {\n                    error!(\"Accounts not found in cleanup instruction\");\n                    PyError(\"Accounts not found in cleanup instruction\".to_string())\n                })?;\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = account[\"pubkey\"].as_str().ok_or_else(|| {\n                        error!(\"Pubkey not found in account\");\n                        PyError(\"Pubkey not found in account\".to_string())\n                    })?;\n                    let pubkey = Pubkey::from_str(pubkey_str).map_err(|e| {\n                        error!(\"Invalid pubkey: {}\", e);\n                        PyError(format!(\"Invalid pubkey: {}\", e))\n                    })?;\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = cleanup_instr[\"data\"].as_str().ok_or_else(|| {\n                    error!(\"Data not found in cleanup instruction\");\n                    PyError(\"Data not found in cleanup instruction\".to_string())\n                })?;\n\n                let data = base64::decode(data_str).map_err(|e| {\n                    error!(\"Failed to decode cleanup instruction data: {}\", e);\n                    PyError(format!(\"Failed to decode cleanup instruction data: {}\", e))\n                })?;\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                essential_instructions.push(instruction);\n            }\n\n            // Check if we have any instructions beyond compute budget\n            if essential_instructions.len() <= 2 {\n                error!(\"No Jupiter instructions found in response\");\n                return Err(\n                    PyError(\"Jupiter instructions not found in response\".to_string()).into(),\n                );\n            }\n\n            // Step 4: Get recent blockhash from optimized cache\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n            debug!(\"Using cached blockhash: {}\", blockhash);\n\n            // Step 5: Create and sign transaction with essential instructions\n            let mut transaction = Transaction::new_signed_with_payer(\n                &essential_instructions,\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                blockhash,\n            );\n\n            // Step 6: Send transaction with optimized retry logic\n            let send_config = RpcSendTransactionConfig {\n                skip_preflight: self.skip_preflight,\n                preflight_commitment: Some(CommitmentLevel::Processed),\n                encoding: Some(UiTransactionEncoding::Base64),\n                max_retries: Some(self.max_retries),\n                ..Default::default()\n            };\n\n            // Track if we need to retry with new blockhash\n            let mut retry_count = 0;\n            let max_retries = 2; // Specific to blockhash errors\n\n            while retry_count <= max_retries {\n                match self\n                    .rpc_client\n                    .send_transaction_with_config(&transaction, send_config.clone())\n                {\n                    Ok(signature) => {\n                        info!(\n                            \"Jupiter token sell executed: {} tokens to SOL with signature {}\",\n                            amount_tokens, signature\n                        );\n                        return Ok(signature.to_string());\n                    }\n                    Err(e) => {\n                        let error_str = e.to_string();\n\n                        // If it's a blockhash error, try with fresh blockhash\n                        if error_str.contains(\"blockhash\") && retry_count < max_retries {\n                            error!(\n                                \"Blockhash error, retrying with fresh blockhash: {}\",\n                                error_str\n                            );\n\n                            // Force refresh the blockhash\n                            let new_blockhash = blockhash_cache.force_update();\n\n                            // Create new transaction with fresh blockhash\n                            let new_transaction = Transaction::new_signed_with_payer(\n                                &essential_instructions,\n                                Some(&self.keypair.pubkey()),\n                                &[&self.keypair],\n                                new_blockhash,\n                            );\n\n                            // Update transaction for next retry\n                            transaction = new_transaction;\n\n                            retry_count += 1;\n                            continue;\n                        }\n\n                        error!(\"Failed to send transaction: {}\", e);\n                        return Err(PyError(format!(\"Failed to send transaction: {}\", e)).into());\n                    }\n                }\n            }\n\n            Err(PyError(\"Max retries exceeded\".to_string()).into())\n        })\n    }\n\n    /// Get token decimals with caching for speed\n    fn get_token_decimals(&self, py: Python<'_>, token_mint: String) -> PyResult<u8> {\n        // Check cache first\n        if let Some(decimals) = TOKEN_DECIMALS_CACHE.get(&token_mint) {\n            return Ok(*decimals);\n        }\n\n        // Not in cache, get from chain with GIL released\n        py.allow_threads(|| {\n            // Get token mint pubkey\n            let token_mint_pubkey = Pubkey::from_str(&token_mint)\n                .map_err(|e| PyErr::new::<PyValueError, _>(format!(\"Invalid pubkey: {}\", e)))?;\n\n            // Get mint data\n            let mint_data = self\n                .rpc_client\n                .get_account_data(&token_mint_pubkey)\n                .map_err(|e| {\n                    PyErr::new::<PyRuntimeError, _>(format!(\"Failed to get account data: {}\", e))\n                })?;\n\n            // Unpack mint data\n            let mint_info = spl_token::state::Mint::unpack(&mint_data).map_err(|e| {\n                PyErr::new::<PyRuntimeError, _>(format!(\"Failed to unpack mint data: {}\", e))\n            })?;\n\n            // Cache the result\n            TOKEN_DECIMALS_CACHE.insert(token_mint, mint_info.decimals);\n\n            Ok(mint_info.decimals)\n        })\n    }\n\n    /// Create token account if it doesn't exist - with improved error handling\n    fn create_token_account_if_needed(&self, py: Python<'_>, token_mint: String) -> PyResult<bool> {\n        // Get token mint pubkey\n        let token_mint_pubkey = match Pubkey::from_str(&token_mint) {\n            Ok(pubkey) => pubkey,\n            Err(e) => return Err(PyValueError::new_err(format!(\"Invalid pubkey: {}\", e))),\n        };\n\n        // Get associated token account\n        let token_account =\n            get_associated_token_address(&self.keypair.pubkey(), &token_mint_pubkey);\n\n        // Check if account exists - do this with the GIL held\n        let account_exists = self.rpc_client.get_account_data(&token_account).is_ok();\n        if account_exists {\n            return Ok(false);\n        }\n\n        // Create token account instruction\n        let create_ata_ix = create_associated_token_account_idempotent(\n            &self.keypair.pubkey(),\n            &self.keypair.pubkey(),\n            &token_mint_pubkey,\n            &Pubkey::from_str(&self.token_program_id)\n                .map_err(|e| PyValueError::new_err(format!(\"Invalid token program ID: {}\", e)))?,\n        );\n\n        // Now we can release the GIL for the network operation\n        py.allow_threads(|| {\n            // Get blockhash from cache\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n\n            // Create transaction\n            let transaction = Transaction::new_signed_with_payer(\n                &[create_ata_ix],\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                blockhash,\n            );\n\n            // Send transaction\n            match self.rpc_client.send_and_confirm_transaction(&transaction) {\n                Ok(signature) => {\n                    info!(\"Created token account for {}: {}\", token_mint, signature);\n                    Ok(true)\n                }\n                Err(e) => {\n                    // Check if the error is because the account already exists\n                    if e.to_string().contains(\"already in use\") {\n                        debug!(\"Token account for {} already exists\", token_mint);\n                        return Ok(true);\n                    }\n\n                    error!(\"Failed to create token account for {}: {}\", token_mint, e);\n                    return Err(PyRuntimeError::new_err(format!(\n                        \"Failed to create token account: {}\",\n                        e\n                    )));\n                }\n            }\n        })\n    }\n\n    /// Get SOL balance with optimized caching\n    fn get_sol_balance(&self, py: Python<'_>) -> PyResult<f64> {\n        py.allow_threads(\n            || match self.rpc_client.get_balance(&self.keypair.pubkey()) {\n                Ok(balance) => Ok(balance as f64 / LAMPORTS_PER_SOL as f64),\n                Err(e) => {\n                    error!(\"Failed to get SOL balance: {}\", e);\n                    Err(PyRuntimeError::new_err(format!(\n                        \"Failed to get SOL balance: {}\",\n                        e\n                    )))\n                }\n            },\n        )\n    }\n\n    /// Get token balance with optimized error handling\n    fn get_token_balance(&self, py: Python<'_>, token_mint: String) -> PyResult<f64> {\n        py.allow_threads(|| {\n            // Get token mint pubkey\n            let token_mint_pubkey = Pubkey::from_str(&token_mint)\n                .map_err(|e| PyValueError::new_err(format!(\"Invalid pubkey: {}\", e)))?;\n\n            // Get associated token account\n            let token_account =\n                get_associated_token_address(&self.keypair.pubkey(), &token_mint_pubkey);\n\n            // Check if account exists\n            match self.rpc_client.get_account_data(&token_account) {\n                Ok(data) => {\n                    // Account exists, unpack data\n                    let account_info = spl_token::state::Account::unpack(&data).map_err(|e| {\n                        PyRuntimeError::new_err(format!(\"Failed to unpack token account: {}\", e))\n                    })?;\n\n                    // Get token mint data for decimals - check cache first\n                    let decimals = if let Some(decimals) = TOKEN_DECIMALS_CACHE.get(&token_mint) {\n                        *decimals\n                    } else {\n                        // Get from chain if not in cache\n                        let mint_data = self\n                            .rpc_client\n                            .get_account_data(&token_mint_pubkey)\n                            .map_err(|e| {\n                                PyRuntimeError::new_err(format!(\"Failed to get mint data: {}\", e))\n                            })?;\n\n                        let mint_info =\n                            spl_token::state::Mint::unpack(&mint_data).map_err(|e| {\n                                PyRuntimeError::new_err(format!(\n                                    \"Failed to unpack mint data: {}\",\n                                    e\n                                ))\n                            })?;\n\n                        // Cache the result\n                        TOKEN_DECIMALS_CACHE.insert(token_mint.clone(), mint_info.decimals);\n\n                        mint_info.decimals\n                    };\n\n                    // Calculate balance with proper decimals\n                    let balance = account_info.amount as f64 / 10f64.powi(decimals as i32);\n\n                    Ok(balance)\n                }\n                Err(_) => {\n                    // Account doesn't exist, balance is 0\n                    Ok(0.0)\n                }\n            }\n        })\n    }\n\n    /// Get wallet's public address\n    fn get_address(&self) -> PyResult<String> {\n        Ok(self.keypair.pubkey().to_string())\n    }\n\n    /// Get cached blockhash with optimized approach\n    fn get_cached_blockhash(&self, py: Python<'_>) -> PyResult<String> {\n        py.allow_threads(|| {\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n            Ok(blockhash.to_string())\n        })\n    }\n\n    /// Force update the blockhash cache\n    fn force_update_blockhash(&self, py: Python<'_>) -> PyResult<String> {\n        py.allow_threads(|| {\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.force_update();\n            Ok(blockhash.to_string())\n        })\n    }\n\n    /// Confirm transaction with optimized retry logic\n    fn confirm_transaction(\n        &self,\n        py: Python<'_>,\n        signature_str: String,\n        timeout: u64,\n    ) -> PyResult<bool> {\n        py.allow_threads(|| {\n            // Parse the signature string - using simplified error handling\n            let signature = Signature::from_str(&signature_str)\n                .map_err(|e| PyValueError::new_err(format!(\"Invalid signature: {}\", e)))?;\n\n            let start_time = Instant::now();\n            let timeout_duration = Duration::from_secs(timeout);\n\n            while start_time.elapsed() < timeout_duration {\n                match self.rpc_client.get_signature_status(&signature) {\n                    Ok(Some(Ok(_))) => return Ok(true),\n                    Ok(Some(Err(e))) => {\n                        error!(\"Transaction failed: {:?}\", e);\n                        return Err(PyRuntimeError::new_err(format!(\n                            \"Transaction failed: {:?}\",\n                            e\n                        )));\n                    }\n                    Ok(None) => {\n                        // Sleep shorter time for faster responses\n                        std::thread::sleep(Duration::from_millis(200));\n                    }\n                    Err(e) => {\n                        error!(\"Status check failed: {}\", e);\n                        // Sleep a bit before retrying\n                        std::thread::sleep(Duration::from_millis(500));\n                    }\n                }\n            }\n\n            error!(\"Transaction confirmation timed out\");\n            Err(PyRuntimeError::new_err(\n                \"Transaction confirmation timed out\".to_string(),\n            ))\n        })\n    }\n\n    /// Execute a round-trip test for performance benchmarking\n    fn execute_round_trip_test(\n        &self,\n        py: Python<'_>,\n        amount_sol: f64,\n        slippage_percent: Option<f64>,\n        priority_multiplier: Option<u64>,\n    ) -> PyResult<PyObject> {\n        // Prepare parameters\n        let usdc_address = \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\";\n        let wsol_address = WSOL_ADDRESS;\n\n        let slippage = slippage_percent.unwrap_or(1.0);\n        let priority_mult = priority_multiplier.unwrap_or(1);\n\n        // Allow the GIL to be released for network operations\n        let result = py.allow_threads(|| {\n            // Results dictionary\n            let mut result = serde_json::Map::new();\n\n            // Track timing\n            let start_time = Instant::now();\n\n            info!(\"\ud83d\udd04 FULL ROUND-TRIP TRANSACTION TEST\");\n            info!(\"Using Helius RPC: {}\", self.rpc_url);\n            info!(\"Using binary keypair: {}\", self.keypair_path);\n            info!(\"Wallet: {}\", self.keypair.pubkey());\n\n            // Pre-cache blockhash\n            info!(\"\ud83d\udd04 Pre-caching blockhash...\");\n            let blockhash_cache = BLOCKHASH_CACHE.get().unwrap();\n            let blockhash = blockhash_cache.get_blockhash();\n            info!(\n                \"Cached blockhash: {}...\",\n                blockhash.to_string()[..10].to_string()\n            );\n\n            // Get initial balances\n            let initial_sol = match self.rpc_client.get_balance(&self.keypair.pubkey()) {\n                Ok(balance) => balance as f64 / LAMPORTS_PER_SOL as f64,\n                Err(e) => {\n                    error!(\"Failed to get initial SOL balance: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\n                            \"Failed to get initial SOL balance: {}\",\n                            e\n                        )),\n                    );\n                    return result;\n                }\n            };\n\n            // Get USDC token account\n            let usdc_pubkey = match Pubkey::from_str(usdc_address) {\n                Ok(pubkey) => pubkey,\n                Err(e) => {\n                    error!(\"Invalid USDC address: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\"Invalid USDC address: {}\", e)),\n                    );\n                    return result;\n                }\n            };\n\n            let usdc_token_account =\n                get_associated_token_address(&self.keypair.pubkey(), &usdc_pubkey);\n\n            // Check if USDC account exists\n            let initial_usdc = match self.rpc_client.get_account_data(&usdc_token_account) {\n                Ok(data) => {\n                    // Account exists, unpack data\n                    let account_info = match spl_token::state::Account::unpack(&data) {\n                        Ok(info) => info,\n                        Err(e) => {\n                            error!(\"Failed to unpack USDC account: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\n                                    \"Failed to unpack USDC account: {}\",\n                                    e\n                                )),\n                            );\n                            return result;\n                        }\n                    };\n\n                    // Get token decimals (should be 6 for USDC)\n                    account_info.amount as f64 / 1_000_000.0\n                }\n                Err(_) => {\n                    // Account doesn't exist, balance is 0\n                    0.0\n                }\n            };\n\n            info!(\"Initial SOL: {}\", initial_sol);\n            info!(\"Initial USDC: {}\", initial_usdc);\n\n            // FIRST LEG: SOL \u2192 USDC\n            info!(\"\ud83d\udcc8 FIRST LEG: SOL \u2192 USDC\");\n            info!(\"Executing transaction: {} SOL \u2192 USDC\", amount_sol);\n\n            let _leg1_start = Instant::now();\n\n            // Step 1: Get a quote from Jupiter API\n            let leg1_quote_url = format!(\n                \"{}?inputMint={}&outputMint={}&amount={}&slippageBps={}\",\n                JUPITER_QUOTE_API,\n                wsol_address,\n                usdc_address,\n                (amount_sol * LAMPORTS_PER_SOL as f64) as u64,\n                (slippage * 100.0) as u32\n            );\n\n            // Add authentication headers if needed\n            let mut request = self.http_client.get(&leg1_quote_url);\n            if let Some(key) = &self.api_key {\n                request = request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n            }\n\n            let leg1_quote_response = match request.send() {\n                Ok(response) => {\n                    if response.status().is_success() {\n                        match response.json::<serde_json::Value>() {\n                            Ok(data) => data,\n                            Err(e) => {\n                                error!(\"Failed to parse Jupiter quote response: {}\", e);\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(format!(\n                                        \"Failed to parse Jupiter quote: {}\",\n                                        e\n                                    )),\n                                );\n                                return result;\n                            }\n                        }\n                    } else {\n                        error!(\"Jupiter API error: HTTP {}\", response.status());\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Jupiter API error: HTTP {}\",\n                                response.status()\n                            )),\n                        );\n                        return result;\n                    }\n                }\n                Err(e) => {\n                    error!(\"Jupiter API request failed: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\"Jupiter API request failed: {}\", e)),\n                    );\n                    return result;\n                }\n            };\n\n            // Step 2: Get swap instructions\n            let leg1_instr_payload = serde_json::json!({\n                \"quoteResponse\": leg1_quote_response,\n                \"userPublicKey\": self.keypair.pubkey().to_string(),\n                \"computeUnitPriceMicroLamports\": self.priority_fee * priority_mult,\n                \"wrapUnwrapSOL\": true,\n                \"onlyDirectRoutes\": true,\n                \"maxHops\": 1,\n                \"maxAccounts\": 12\n            });\n\n            // Add authentication headers if needed\n            let mut instr_request = self.http_client.post(JUPITER_SWAP_API).json(&leg1_instr_payload);\n            if let Some(key) = &self.api_key {\n                instr_request = instr_request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n            }\n\n            let leg1_instr_response = match instr_request.send() {\n                Ok(response) => {\n                    if response.status().is_success() {\n                        match response.json::<serde_json::Value>() {\n                            Ok(data) => data,\n                            Err(e) => {\n                                error!(\"Failed to parse Jupiter instructions response: {}\", e);\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(format!(\n                                        \"Failed to parse Jupiter instructions: {}\",\n                                        e\n                                    )),\n                                );\n                                return result;\n                            }\n                        }\n                    } else {\n                        error!(\"Jupiter API error: HTTP {}\", response.status());\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Jupiter API error: HTTP {}\",\n                                response.status()\n                            )),\n                        );\n                        return result;\n                    }\n                }\n                Err(e) => {\n                    error!(\"Jupiter API request failed: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\"Jupiter API request failed: {}\", e)),\n                    );\n                    return result;\n                }\n            };\n\n            // Step 3: Extract and build instructions\n            let mut leg1_instructions = Vec::new();\n\n            // Add compute budget instructions\n            leg1_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(\n                self.compute_limit,\n            ));\n            leg1_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(\n                self.priority_fee * priority_mult,\n            ));\n\n            // Add setup instructions\n            if let Some(setup_instructions) = leg1_instr_response\n                .get(\"setupInstructions\")\n                .and_then(|v| v.as_array())\n            {\n                for instr in setup_instructions {\n                    let program_id_str = match instr[\"programId\"].as_str() {\n                        Some(id) => id,\n                        None => {\n                            error!(\"Program ID not found in setup instruction\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Program ID not found in setup instruction\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let program_id = match Pubkey::from_str(program_id_str) {\n                        Ok(id) => id,\n                        Err(e) => {\n                            error!(\"Invalid program ID: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\"Invalid program ID: {}\", e)),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let accounts_arr = match instr[\"accounts\"].as_array() {\n                        Some(accounts) => accounts,\n                        None => {\n                            error!(\"Accounts not found in setup instruction\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Accounts not found in setup instruction\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let mut accounts = Vec::new();\n\n                    for account in accounts_arr {\n                        let pubkey_str = match account[\"pubkey\"].as_str() {\n                            Some(key) => key,\n                            None => {\n                                error!(\"Pubkey not found in account\");\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(\n                                        \"Pubkey not found in account\".to_string(),\n                                    ),\n                                );\n                                return result;\n                            }\n                        };\n\n                        let pubkey = match Pubkey::from_str(pubkey_str) {\n                            Ok(key) => key,\n                            Err(e) => {\n                                error!(\"Invalid pubkey: {}\", e);\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(format!(\"Invalid pubkey: {}\", e)),\n                                );\n                                return result;\n                            }\n                        };\n\n                        let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                        let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                        let account_meta = if is_writable {\n                            if is_signer {\n                                AccountMeta::new(pubkey, true)\n                            } else {\n                                AccountMeta::new(pubkey, false)\n                            }\n                        } else {\n                            if is_signer {\n                                AccountMeta::new_readonly(pubkey, true)\n                            } else {\n                                AccountMeta::new_readonly(pubkey, false)\n                            }\n                        };\n\n                        accounts.push(account_meta);\n                    }\n\n                    let data_str = match instr[\"data\"].as_str() {\n                        Some(data) => data,\n                        None => {\n                            error!(\"Data not found in setup instruction\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Data not found in setup instruction\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let data = match base64::decode(data_str) {\n                        Ok(data) => data,\n                        Err(e) => {\n                            error!(\"Failed to decode setup instruction data: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\n                                    \"Failed to decode setup instruction data: {}\",\n                                    e\n                                )),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let instruction = Instruction {\n                        program_id,\n                        accounts,\n                        data,\n                    };\n\n                    leg1_instructions.push(instruction);\n                }\n            }\n\n            // Add swap instruction\n            if let Some(swap_instr) = leg1_instr_response.get(\"swapInstruction\") {\n                let program_id_str = match swap_instr[\"programId\"].as_str() {\n                    Some(id) => id,\n                    None => {\n                        error!(\"Program ID not found in swap instruction\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Program ID not found in swap instruction\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let program_id = match Pubkey::from_str(program_id_str) {\n                    Ok(id) => id,\n                    Err(e) => {\n                        error!(\"Invalid program ID: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\"Invalid program ID: {}\", e)),\n                        );\n                        return result;\n                    }\n                };\n\n                let accounts_arr = match swap_instr[\"accounts\"].as_array() {\n                    Some(accounts) => accounts,\n                    None => {\n                        error!(\"Accounts not found in swap instruction\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Accounts not found in swap instruction\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = match account[\"pubkey\"].as_str() {\n                        Some(key) => key,\n                        None => {\n                            error!(\"Pubkey not found in account\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Pubkey not found in account\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let pubkey = match Pubkey::from_str(pubkey_str) {\n                        Ok(key) => key,\n                        Err(e) => {\n                            error!(\"Invalid pubkey: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\"Invalid pubkey: {}\", e)),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = match swap_instr[\"data\"].as_str() {\n                    Some(data) => data,\n                    None => {\n                        error!(\"Data not found in swap instruction\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Data not found in swap instruction\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let data = match base64::decode(data_str) {\n                    Ok(data) => data,\n                    Err(e) => {\n                        error!(\"Failed to decode swap instruction data: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Failed to decode swap instruction data: {}\",\n                                e\n                            )),\n                        );\n                        return result;\n                    }\n                };\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                leg1_instructions.push(instruction);\n            } else {\n                error!(\"No swap instruction found in response\");\n                result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                result.insert(\n                    \"error\".to_string(),\n                    serde_json::Value::String(\n                        \"Jupiter swap instruction not found in response\".to_string(),\n                    ),\n                );\n                return result;\n            }\n\n            // Add cleanup instruction if it exists\n            if let Some(cleanup_instr) = leg1_instr_response.get(\"cleanupInstruction\") {\n                let program_id_str = match cleanup_instr[\"programId\"].as_str() {\n                    Some(id) => id,\n                    None => {\n                        error!(\"Program ID not found in cleanup instruction\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Program ID not found in cleanup instruction\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let program_id = match Pubkey::from_str(program_id_str) {\n                    Ok(id) => id,\n                    Err(e) => {\n                        error!(\"Invalid program ID: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\"Invalid program ID: {}\", e)),\n                        );\n                        return result;\n                    }\n                };\n\n                let accounts_arr = match cleanup_instr[\"accounts\"].as_array() {\n                    Some(accounts) => accounts,\n                    None => {\n                        error!(\"Accounts not found in cleanup instruction\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Accounts not found in cleanup instruction\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = match account[\"pubkey\"].as_str() {\n                        Some(key) => key,\n                        None => {\n                            error!(\"Pubkey not found in account\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Pubkey not found in account\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let pubkey = match Pubkey::from_str(pubkey_str) {\n                        Ok(key) => key,\n                        Err(e) => {\n                            error!(\"Invalid pubkey: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\"Invalid pubkey: {}\", e)),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = match cleanup_instr[\"data\"].as_str() {\n                    Some(data) => data,\n                    None => {\n                        error!(\"Data not found in cleanup instruction\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Data not found in cleanup instruction\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let data = match base64::decode(data_str) {\n                    Ok(data) => data,\n                    Err(e) => {\n                        error!(\"Failed to decode cleanup instruction data: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Failed to decode cleanup instruction data: {}\",\n                                e\n                            )),\n                        );\n                        return result;\n                    }\n                };\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                leg1_instructions.push(instruction);\n            }\n\n            // Get blockhash for first leg transaction\n            let blockhash_time = Instant::now();\n            let leg1_blockhash = blockhash_cache.get_blockhash();\n            let blockhash_elapsed = blockhash_time.elapsed();\n\n            // Create and sign transaction\n            let leg1_transaction = Transaction::new_signed_with_payer(\n                &leg1_instructions,\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                leg1_blockhash,\n            );\n\n            // Send transaction with optimized config\n            let leg1_send_time = Instant::now();\n            let leg1_send_config = RpcSendTransactionConfig {\n                skip_preflight: self.skip_preflight,\n                preflight_commitment: Some(CommitmentLevel::Processed),\n                encoding: Some(UiTransactionEncoding::Base64),\n                max_retries: Some(self.max_retries),\n                ..Default::default()\n            };\n\n            let leg1_signature = match self\n                .rpc_client\n                .send_transaction_with_config(&leg1_transaction, leg1_send_config)\n            {\n                Ok(sig) => sig,\n                Err(e) => {\n                    error!(\"Failed to send leg 1 transaction: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\n                            \"Failed to send leg 1 transaction: {}\",\n                            e\n                        )),\n                    );\n                    return result;\n                }\n            };\n\n            let leg1_send_elapsed = leg1_send_time.elapsed();\n            info!(\"\u2705 Transaction sent: {}\", leg1_signature);\n            info!(\"Blockhash time: {:?}\", blockhash_elapsed);\n            info!(\"Transaction execution time: {:?}\", leg1_send_elapsed);\n\n            // Wait for confirmation\n            let leg1_confirm_time = Instant::now();\n\n            let mut confirmed = false;\n            let max_attempts = 20;\n            let mut attempts = 0;\n\n            while !confirmed && attempts < max_attempts {\n                match self.rpc_client.get_signature_status(&leg1_signature) {\n                    Ok(Some(Ok(()))) => {\n                        confirmed = true;\n                    }\n                    Ok(Some(Err(e))) => {\n                        error!(\"Leg 1 transaction failed: {:?}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\"Leg 1 transaction failed: {:?}\", e)),\n                        );\n                        return result;\n                    }\n                    _ => {\n                        std::thread::sleep(Duration::from_millis(100));\n                        attempts += 1;\n                    }\n                }\n            }\n\n            if !confirmed {\n                error!(\"Leg 1 transaction confirmation timed out\");\n                result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                result.insert(\n                    \"error\".to_string(),\n                    serde_json::Value::String(\n                        \"Leg 1 transaction confirmation timed out\".to_string(),\n                    ),\n                );\n                return result;\n            }\n\n            let leg1_confirm_elapsed = leg1_confirm_time.elapsed();\n            info!(\"\u2705 Transaction confirmed in {:?}\", leg1_confirm_elapsed);\n\n            // Get updated balances\n            let mid_sol = match self.rpc_client.get_balance(&self.keypair.pubkey()) {\n                Ok(balance) => balance as f64 / LAMPORTS_PER_SOL as f64,\n                Err(e) => {\n                    error!(\"Failed to get mid SOL balance: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\"Failed to get mid SOL balance: {}\", e)),\n                    );\n                    return result;\n                }\n            };\n\n            let mid_usdc = match self.rpc_client.get_account_data(&usdc_token_account) {\n                Ok(data) => {\n                    // Account exists, unpack data\n                    let account_info = match spl_token::state::Account::unpack(&data) {\n                        Ok(info) => info,\n                        Err(e) => {\n                            error!(\"Failed to unpack USDC account: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\n                                    \"Failed to unpack USDC account: {}\",\n                                    e\n                                )),\n                            );\n                            return result;\n                        }\n                    };\n\n                    // Get token decimals (should be 6 for USDC)\n                    account_info.amount as f64 / 1_000_000.0\n                }\n                Err(e) => {\n                    error!(\"Failed to get mid USDC balance: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\"Failed to get mid USDC balance: {}\", e)),\n                    );\n                    return result;\n                }\n            };\n\n            info!(\"Updated balances:\");\n            info!(\"SOL: {} (-{})\", mid_sol, initial_sol - mid_sol);\n            info!(\"USDC: {} (+{})\", mid_usdc, mid_usdc - initial_usdc);\n\n            // Calculate USDC amount to swap back\n            let usdc_amount_for_leg2 = mid_usdc * 0.95; // Use 95% to avoid dust\n            let usdc_amount_micros = (usdc_amount_for_leg2 * 1_000_000.0) as u64;\n\n            // SECOND LEG: USDC \u2192 SOL\n            info!(\"\ud83d\udcc9 SECOND LEG: USDC \u2192 SOL\");\n            info!(\"Executing transaction: {} USDC \u2192 SOL\", usdc_amount_for_leg2);\n\n            let _leg2_start = Instant::now();\n\n            // Step 1: Get a quote from Jupiter API\n            let leg2_quote_url = format!(\n                \"{}?inputMint={}&outputMint={}&amount={}&slippageBps={}\",\n                JUPITER_QUOTE_API,\n                usdc_address,\n                wsol_address,\n                usdc_amount_micros,\n                (slippage * 100.0) as u32\n            );\n\n            // Add authentication headers if needed\n            let mut leg2_request = self.http_client.get(&leg2_quote_url);\n            if let Some(key) = &self.api_key {\n                leg2_request = leg2_request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n            }\n\n            let leg2_quote_response = match leg2_request.send() {\n                Ok(response) => {\n                    if response.status().is_success() {\n                        match response.json::<serde_json::Value>() {\n                            Ok(data) => data,\n                            Err(e) => {\n                                error!(\"Failed to parse Jupiter quote response: {}\", e);\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(format!(\n                                        \"Failed to parse Jupiter quote: {}\",\n                                        e\n                                    )),\n                                );\n                                return result;\n                            }\n                        }\n                    } else {\n                        error!(\"Jupiter API error: HTTP {}\", response.status());\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Jupiter API error: HTTP {}\",\n                                response.status()\n                            )),\n                        );\n                        return result;\n                    }\n                }\n                Err(e) => {\n                    error!(\"Jupiter API request failed: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\"Jupiter API request failed: {}\", e)),\n                    );\n                    return result;\n                }\n            };\n\n            // Step 2: Get swap instructions\n            let leg2_instr_payload = serde_json::json!({\n                \"quoteResponse\": leg2_quote_response,\n                \"userPublicKey\": self.keypair.pubkey().to_string(),\n                \"computeUnitPriceMicroLamports\": self.priority_fee * priority_mult,\n                \"wrapUnwrapSOL\": true,\n                \"onlyDirectRoutes\": true,\n                \"maxHops\": 1,\n                \"maxAccounts\": 12\n            });\n\n            // Add authentication headers if needed\n            let mut leg2_instr_request = self.http_client.post(JUPITER_SWAP_API).json(&leg2_instr_payload);\n            if let Some(key) = &self.api_key {\n                leg2_instr_request = leg2_instr_request.header(AUTHORIZATION, format!(\"Bearer {}\", key));\n            }\n\n            let leg2_instr_response = match leg2_instr_request.send() {\n                Ok(response) => {\n                    if response.status().is_success() {\n                        match response.json::<serde_json::Value>() {\n                            Ok(data) => data,\n                            Err(e) => {\n                                error!(\"Failed to parse Jupiter instructions response: {}\", e);\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(format!(\n                                        \"Failed to parse Jupiter instructions: {}\",\n                                        e\n                                    )),\n                                );\n                                return result;\n                            }\n                        }\n                    } else {\n                        error!(\"Jupiter API error: HTTP {}\", response.status());\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Jupiter API error: HTTP {}\",\n                                response.status()\n                            )),\n                        );\n                        return result;\n                    }\n                }\n                Err(e) => {\n                    error!(\"Jupiter API request failed: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\"Jupiter API request failed: {}\", e)),\n                    );\n                    return result;\n                }\n            };\n\n            // Step 3: Extract and build instructions for leg 2 (fully implemented)\n            let mut leg2_instructions = Vec::new();\n\n            // Add compute budget instructions\n            leg2_instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(\n                self.compute_limit,\n            ));\n            leg2_instructions.push(ComputeBudgetInstruction::set_compute_unit_price(\n                self.priority_fee * priority_mult,\n            ));\n\n            // Process setup instructions for leg 2\n            if let Some(setup_instructions) = leg2_instr_response\n                .get(\"setupInstructions\")\n                .and_then(|v| v.as_array())\n            {\n                for instr in setup_instructions {\n                    let program_id_str = match instr[\"programId\"].as_str() {\n                        Some(id) => id,\n                        None => {\n                            error!(\"Program ID not found in setup instruction for leg 2\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Program ID not found in setup instruction for leg 2\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let program_id = match Pubkey::from_str(program_id_str) {\n                        Ok(id) => id,\n                        Err(e) => {\n                            error!(\"Invalid program ID for leg 2: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\"Invalid program ID for leg 2: {}\", e)),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let accounts_arr = match instr[\"accounts\"].as_array() {\n                        Some(accounts) => accounts,\n                        None => {\n                            error!(\"Accounts not found in setup instruction for leg 2\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Accounts not found in setup instruction for leg 2\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let mut accounts = Vec::new();\n\n                    for account in accounts_arr {\n                        let pubkey_str = match account[\"pubkey\"].as_str() {\n                            Some(key) => key,\n                            None => {\n                                error!(\"Pubkey not found in account for leg 2\");\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(\n                                        \"Pubkey not found in account for leg 2\".to_string(),\n                                    ),\n                                );\n                                return result;\n                            }\n                        };\n\n                        let pubkey = match Pubkey::from_str(pubkey_str) {\n                            Ok(key) => key,\n                            Err(e) => {\n                                error!(\"Invalid pubkey for leg 2: {}\", e);\n                                result\n                                    .insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                                result.insert(\n                                    \"error\".to_string(),\n                                    serde_json::Value::String(format!(\"Invalid pubkey for leg 2: {}\", e)),\n                                );\n                                return result;\n                            }\n                        };\n\n                        let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                        let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                        let account_meta = if is_writable {\n                            if is_signer {\n                                AccountMeta::new(pubkey, true)\n                            } else {\n                                AccountMeta::new(pubkey, false)\n                            }\n                        } else {\n                            if is_signer {\n                                AccountMeta::new_readonly(pubkey, true)\n                            } else {\n                                AccountMeta::new_readonly(pubkey, false)\n                            }\n                        };\n\n                        accounts.push(account_meta);\n                    }\n\n                    let data_str = match instr[\"data\"].as_str() {\n                        Some(data) => data,\n                        None => {\n                            error!(\"Data not found in setup instruction for leg 2\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Data not found in setup instruction for leg 2\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let data = match base64::decode(data_str) {\n                        Ok(data) => data,\n                        Err(e) => {\n                            error!(\"Failed to decode setup instruction data for leg 2: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\n                                    \"Failed to decode setup instruction data for leg 2: {}\",\n                                    e\n                                )),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let instruction = Instruction {\n                        program_id,\n                        accounts,\n                        data,\n                    };\n\n                    leg2_instructions.push(instruction);\n                }\n            }\n\n            // Process swap instruction for leg 2\n            if let Some(swap_instr) = leg2_instr_response.get(\"swapInstruction\") {\n                let program_id_str = match swap_instr[\"programId\"].as_str() {\n                    Some(id) => id,\n                    None => {\n                        error!(\"Program ID not found in swap instruction for leg 2\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Program ID not found in swap instruction for leg 2\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let program_id = match Pubkey::from_str(program_id_str) {\n                    Ok(id) => id,\n                    Err(e) => {\n                        error!(\"Invalid program ID for leg 2: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\"Invalid program ID for leg 2: {}\", e)),\n                        );\n                        return result;\n                    }\n                };\n\n                let accounts_arr = match swap_instr[\"accounts\"].as_array() {\n                    Some(accounts) => accounts,\n                    None => {\n                        error!(\"Accounts not found in swap instruction for leg 2\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Accounts not found in swap instruction for leg 2\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = match account[\"pubkey\"].as_str() {\n                        Some(key) => key,\n                        None => {\n                            error!(\"Pubkey not found in account for leg 2\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Pubkey not found in account for leg 2\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let pubkey = match Pubkey::from_str(pubkey_str) {\n                        Ok(key) => key,\n                        Err(e) => {\n                            error!(\"Invalid pubkey for leg 2: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\"Invalid pubkey for leg 2: {}\", e)),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = match swap_instr[\"data\"].as_str() {\n                    Some(data) => data,\n                    None => {\n                        error!(\"Data not found in swap instruction for leg 2\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Data not found in swap instruction for leg 2\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let data = match base64::decode(data_str) {\n                    Ok(data) => data,\n                    Err(e) => {\n                        error!(\"Failed to decode swap instruction data for leg 2: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Failed to decode swap instruction data for leg 2: {}\",\n                                e\n                            )),\n                        );\n                        return result;\n                    }\n                };\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                leg2_instructions.push(instruction);\n            } else {\n                error!(\"No swap instruction found for leg 2\");\n                result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                result.insert(\n                    \"error\".to_string(),\n                    serde_json::Value::String(\"No swap instruction found for leg 2\".to_string()),\n                );\n                return result;\n            }\n\n            // Process cleanup instruction for leg 2\n            if let Some(cleanup_instr) = leg2_instr_response.get(\"cleanupInstruction\") {\n                let program_id_str = match cleanup_instr[\"programId\"].as_str() {\n                    Some(id) => id,\n                    None => {\n                        error!(\"Program ID not found in cleanup instruction for leg 2\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Program ID not found in cleanup instruction for leg 2\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let program_id = match Pubkey::from_str(program_id_str) {\n                    Ok(id) => id,\n                    Err(e) => {\n                        error!(\"Invalid program ID for leg 2 cleanup: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\"Invalid program ID for leg 2 cleanup: {}\", e)),\n                        );\n                        return result;\n                    }\n                };\n\n                let accounts_arr = match cleanup_instr[\"accounts\"].as_array() {\n                    Some(accounts) => accounts,\n                    None => {\n                        error!(\"Accounts not found in cleanup instruction for leg 2\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Accounts not found in cleanup instruction for leg 2\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let mut accounts = Vec::new();\n\n                for account in accounts_arr {\n                    let pubkey_str = match account[\"pubkey\"].as_str() {\n                        Some(key) => key,\n                        None => {\n                            error!(\"Pubkey not found in account for leg 2 cleanup\");\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(\n                                    \"Pubkey not found in account for leg 2 cleanup\".to_string(),\n                                ),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let pubkey = match Pubkey::from_str(pubkey_str) {\n                        Ok(key) => key,\n                        Err(e) => {\n                            error!(\"Invalid pubkey for leg 2 cleanup: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\"Invalid pubkey for leg 2 cleanup: {}\", e)),\n                            );\n                            return result;\n                        }\n                    };\n\n                    let is_signer = account[\"isSigner\"].as_bool().unwrap_or(false);\n                    let is_writable = account[\"isWritable\"].as_bool().unwrap_or(false);\n\n                    let account_meta = if is_writable {\n                        if is_signer {\n                            AccountMeta::new(pubkey, true)\n                        } else {\n                            AccountMeta::new(pubkey, false)\n                        }\n                    } else {\n                        if is_signer {\n                            AccountMeta::new_readonly(pubkey, true)\n                        } else {\n                            AccountMeta::new_readonly(pubkey, false)\n                        }\n                    };\n\n                    accounts.push(account_meta);\n                }\n\n                let data_str = match cleanup_instr[\"data\"].as_str() {\n                    Some(data) => data,\n                    None => {\n                        error!(\"Data not found in cleanup instruction for leg 2\");\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(\n                                \"Data not found in cleanup instruction for leg 2\".to_string(),\n                            ),\n                        );\n                        return result;\n                    }\n                };\n\n                let data = match base64::decode(data_str) {\n                    Ok(data) => data,\n                    Err(e) => {\n                        error!(\"Failed to decode cleanup instruction data for leg 2: {}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\n                                \"Failed to decode cleanup instruction data for leg 2: {}\",\n                                e\n                            )),\n                        );\n                        return result;\n                    }\n                };\n\n                let instruction = Instruction {\n                    program_id,\n                    accounts,\n                    data,\n                };\n\n                leg2_instructions.push(instruction);\n            }\n\n            // Check if we have any instructions beyond compute budget for leg 2\n            if leg2_instructions.len() <= 2 {\n                error!(\"No Jupiter instructions found in response for leg 2\");\n                result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                result.insert(\n                    \"error\".to_string(),\n                    serde_json::Value::String(\"No Jupiter instructions found in response for leg 2\".to_string()),\n                );\n                return result;\n            }\n\n            // Get blockhash for second leg transaction\n            let leg2_blockhash = blockhash_cache.get_blockhash();\n\n            // Create and sign transaction\n            let leg2_transaction = Transaction::new_signed_with_payer(\n                &leg2_instructions,\n                Some(&self.keypair.pubkey()),\n                &[&self.keypair],\n                leg2_blockhash,\n            );\n\n            // Send transaction with optimized config\n            let leg2_send_time = Instant::now();\n            let leg2_send_config = RpcSendTransactionConfig {\n                skip_preflight: self.skip_preflight,\n                preflight_commitment: Some(CommitmentLevel::Processed),\n                encoding: Some(UiTransactionEncoding::Base64),\n                max_retries: Some(self.max_retries),\n                ..Default::default()\n            };\n\n            let leg2_signature = match self\n                .rpc_client\n                .send_transaction_with_config(&leg2_transaction, leg2_send_config)\n            {\n                Ok(sig) => sig,\n                Err(e) => {\n                    error!(\"Failed to send leg 2 transaction: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\n                            \"Failed to send leg 2 transaction: {}\",\n                            e\n                        )),\n                    );\n                    return result;\n                }\n            };\n\n            let leg2_send_elapsed = leg2_send_time.elapsed();\n            info!(\"\u2705 Transaction sent: {}\", leg2_signature);\n            info!(\"Transaction execution time: {:?}\", leg2_send_elapsed);\n\n            // Wait for confirmation\n            let leg2_confirm_time = Instant::now();\n\n            let mut confirmed = false;\n            let max_attempts = 20;\n            let mut attempts = 0;\n\n            while !confirmed && attempts < max_attempts {\n                match self.rpc_client.get_signature_status(&leg2_signature) {\n                    Ok(Some(Ok(()))) => {\n                        confirmed = true;\n                    }\n                    Ok(Some(Err(e))) => {\n                        error!(\"Leg 2 transaction failed: {:?}\", e);\n                        result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                        result.insert(\n                            \"error\".to_string(),\n                            serde_json::Value::String(format!(\"Leg 2 transaction failed: {:?}\", e)),\n                        );\n                        return result;\n                    }\n                    _ => {\n                        std::thread::sleep(Duration::from_millis(100));\n                        attempts += 1;\n                    }\n                }\n            }\n\n            if !confirmed {\n                error!(\"Leg 2 transaction confirmation timed out\");\n                result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                result.insert(\n                    \"error\".to_string(),\n                    serde_json::Value::String(\n                        \"Leg 2 transaction confirmation timed out\".to_string(),\n                    ),\n                );\n                return result;\n            }\n\n            let leg2_confirm_elapsed = leg2_confirm_time.elapsed();\n            info!(\"\u2705 Transaction confirmed in {:?}\", leg2_confirm_elapsed);\n\n            // Get final balances\n            let final_sol = match self.rpc_client.get_balance(&self.keypair.pubkey()) {\n                Ok(balance) => balance as f64 / LAMPORTS_PER_SOL as f64,\n                Err(e) => {\n                    error!(\"Failed to get final SOL balance: {}\", e);\n                    result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                    result.insert(\n                        \"error\".to_string(),\n                        serde_json::Value::String(format!(\n                            \"Failed to get final SOL balance: {}\",\n                            e\n                        )),\n                    );\n                    return result;\n                }\n            };\n\n            let final_usdc = match self.rpc_client.get_account_data(&usdc_token_account) {\n                Ok(data) => {\n                    // Account exists, unpack data\n                    let account_info = match spl_token::state::Account::unpack(&data) {\n                        Ok(info) => info,\n                        Err(e) => {\n                            error!(\"Failed to unpack USDC account: {}\", e);\n                            result.insert(\"success\".to_string(), serde_json::Value::Bool(false));\n                            result.insert(\n                                \"error\".to_string(),\n                                serde_json::Value::String(format!(\n                                    \"Failed to unpack USDC account: {}\",\n                                    e\n                                )),\n                            );\n                            return result;\n                        }\n                    };\n\n                    // Get token decimals (should be 6 for USDC)\n                    account_info.amount as f64 / 1_000_000.0\n                }\n                Err(_) => {\n                    // Account might not exist anymore\n                    0.0\n                }\n            };\n\n            info!(\"Updated balances:\");\n            info!(\"SOL: {} (+{})\", final_sol, final_sol - mid_sol);\n            info!(\"USDC: {} (-{})\", final_usdc, mid_usdc - final_usdc);\n\n            // Calculate performance metrics\n            let total_time = start_time.elapsed();\n            let leg1_time = leg1_send_elapsed + leg1_confirm_elapsed;\n            let leg2_time = leg2_send_elapsed + leg2_confirm_elapsed;\n\n            info!(\"==================================================\");\n            info!(\"\ud83d\ude80 ROUND-TRIP PERFORMANCE ANALYSIS\");\n            info!(\"==================================================\");\n            info!(\"LEG 1 (SOL \u2192 USDC): {:?}\", leg1_time);\n            info!(\"  - Transaction execution: {:?}\", leg1_send_elapsed);\n            info!(\"  - Confirmation: {:?}\", leg1_confirm_elapsed);\n            info!(\"LEG 2 (USDC \u2192 SOL): {:?}\", leg2_time);\n            info!(\"  - Transaction execution: {:?}\", leg2_send_elapsed);\n            info!(\"  - Confirmation: {:?}\", leg2_confirm_elapsed);\n            info!(\"TOTAL ROUND-TRIP TIME: {:?}\", total_time);\n\n            // Calculate performance breakdown\n            let local_processing_time = total_time - leg1_time - leg2_time;\n            let local_pct =\n                local_processing_time.as_millis() as f64 / total_time.as_millis() as f64 * 100.0;\n            let network_pct = (leg1_time.as_millis() + leg2_time.as_millis()) as f64\n                / total_time.as_millis() as f64\n                * 100.0;\n\n            info!(\"\ud83d\udcca Round-Trip Performance Breakdown:\");\n            info!(\n                \"Local processing time: {:?} ({:.1}%)\",\n                local_processing_time, local_pct\n            );\n            info!(\n                \"Network/blockchain time: {:?} ({:.1}%)\",\n                leg1_time + leg2_time,\n                network_pct\n            );\n\n            // Calculate MEV advantage\n            let round_trip_ms = total_time.as_millis() as f64;\n            let typical_trader_ms = 4599.743; // From your logs\n            let time_advantage = typical_trader_ms - round_trip_ms;\n\n            info!(\"\ud83d\udcb0 MEV Advantage Analysis:\");\n            info!(\n                \"Round-trip execution time: {:?} ({:.3}s)\",\n                total_time,\n                total_time.as_secs_f64()\n            );\n            info!(\"Your round-trip time: {:.3}ms\", round_trip_ms);\n            info!(\"Typical trader: ~{:.3}ms\", typical_trader_ms);\n            info!(\"Time advantage: {:+.3}ms faster\", time_advantage);\n\n            // Assess MEV capability\n            let capability = if time_advantage > 1000.0 {\n                \"\u2705 EXCELLENT - Your system has significant MEV advantage\"\n            } else if time_advantage > 0.0 {\n                \"\u2705 GOOD - Your system can participate in MEV markets\"\n            } else {\n                \"\u26a0\ufe0f NEEDS IMPROVEMENT - Focus on opportunities with longer execution windows\"\n            };\n\n            info!(\"\ud83c\udfc6 MEV Capability Assessment:\");\n            info!(\"{}\", capability);\n\n            // Create result dictionary\n            result.insert(\"success\".to_string(), serde_json::Value::Bool(true));\n            result.insert(\n                \"leg1_signature\".to_string(),\n                serde_json::Value::String(leg1_signature.to_string()),\n            );\n            result.insert(\n                \"leg2_signature\".to_string(),\n                serde_json::Value::String(leg2_signature.to_string()),\n            );\n            result.insert(\n                \"initial_sol\".to_string(),\n                serde_json::Value::Number(serde_json::Number::from_f64(initial_sol).unwrap()),\n            );\n            result.insert(\n                \"final_sol\".to_string(),\n                serde_json::Value::Number(serde_json::Number::from_f64(final_sol).unwrap()),\n            );\n            result.insert(\n                \"profit_sol\".to_string(),\n                serde_json::Value::Number(\n                    serde_json::Number::from_f64(final_sol - initial_sol).unwrap(),\n                ),\n            );\n            result.insert(\n                \"total_time_ms\".to_string(),\n                serde_json::Value::Number(serde_json::Number::from_f64(round_trip_ms).unwrap()),\n            );\n            result.insert(\n                \"leg1_time_ms\".to_string(),\n                serde_json::Value::Number(\n                    serde_json::Number::from_f64(leg1_time.as_millis() as f64).unwrap(),\n                ),\n            );\n            result.insert(\n                \"leg2_time_ms\".to_string(),\n                serde_json::Value::Number(\n                    serde_json::Number::from_f64(leg2_time.as_millis() as f64).unwrap(),\n                ),\n            );\n            result.insert(\n                \"time_advantage_ms\".to_string(),\n                serde_json::Value::Number(serde_json::Number::from_f64(time_advantage).unwrap()),\n            );\n            result.insert(\n                \"capability\".to_string(),\n                serde_json::Value::String(capability.to_string()),\n            );\n            result.insert(\n                \"initial_usdc\".to_string(),\n                serde_json::Value::Number(serde_json::Number::from_f64(initial_usdc).unwrap()),\n            );\n            result.insert(\n                \"final_usdc\".to_string(),\n                serde_json::Value::Number(serde_json::Number::from_f64(final_usdc).unwrap()),\n            );\n\n            result\n        });\n\n        // Convert the JSON result to a Python dictionary\n        let py_dict = PyDict::new(py);\n\n        if let serde_json::Value::Object(map) = serde_json::Value::Object(result) {\n            for (key, value) in map {\n                match value {\n                    serde_json::Value::String(s) => {\n                        py_dict.set_item(key, s).unwrap();\n                    }\n                    serde_json::Value::Number(n) => {\n                        if let Some(f) = n.as_f64() {\n                            py_dict.set_item(key, f).unwrap();\n                        } else if let Some(i) = n.as_i64() {\n                            py_dict.set_item(key, i).unwrap();\n                        } else if let Some(u) = n.as_u64() {\n                            py_dict.set_item(key, u).unwrap();\n                        }\n                    }\n                    serde_json::Value::Bool(b) => {\n                        py_dict.set_item(key, b).unwrap();\n                    }\n                    _ => {}\n                }\n            }\n        }\n\n        Ok(py_dict.into())\n    }\n}\n\n/// Python module initialization\n#[pymodule]\nfn solana_rust_bot(_py: Python, m: &PyModule) -> PyResult<()> {\n    // Initialize logging\n    pyo3_log::init();\n\n    // Register classes\n    m.add_class::<SolanaTrader>()?;\n\n    // Add constants\n    m.add(\"LAMPORTS_PER_SOL\", LAMPORTS_PER_SOL)?;\n    m.add(\"DEFAULT_COMPUTE_LIMIT\", DEFAULT_COMPUTE_LIMIT)?;\n    m.add(\"DEFAULT_PRIORITY_FEE\", DEFAULT_PRIORITY_FEE)?;\n    m.add(\"DEFAULT_MAX_RETRIES\", DEFAULT_MAX_RETRIES)?;\n    m.add(\"DEFAULT_MIN_SOL_BALANCE\", DEFAULT_MIN_SOL_BALANCE)?;\n    m.add(\"DEFAULT_MIN_WSOL_BALANCE\", DEFAULT_MIN_WSOL_BALANCE)?;\n    m.add(\"WSOL_ADDRESS\", WSOL_ADDRESS)?;\n\n    Ok(())\n}// Line ~177: RPC Client Timeout // Change this let timeout = Duration::from_secs(30); // To this let timeout = Duration::from_millis(500); // Line ~223-224: HTTP Client Timeout // Change this let builder = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(30)) // To this let builder = reqwest::blocking::Client::builder() .timeout(Duration::from_millis(500)) .connect_timeout(Duration::from_millis(300)) // Multiple places: Transaction Size in Jupiter payloads // Change this let instr_payload = serde_json::json!({ // ... \"maxAccounts\": 12 }); // To this let max_accounts = env::var(\"MAX_ACCOUNTS\") .map(|v| v.parse::<u32>().unwrap_or(8)) .unwrap_or(8); let instr_payload = serde_json::json!({ // ... \"maxAccounts\": max_accounts }); // Multiple places: Retry wait times // Change this let wait_time = 2u64.pow(retries) * 100; // Exponential backoff // To this let wait_time = 50 * retries; // Linear backoff, much faster // Multiple places: Transaction confirmation wait // Change this std::thread::sleep(Duration::from_millis(200)); // To this std::thread::sleep(Duration::from_millis(50)); fix this just make the edits and write the full script dont change anything execpt what it says to change please thanks  i dont need the test pretend test usdc solana code do i ?? its not nessasary right so fix it without that if its not needed for it to work please write the full script now thanks   MAKE THESE MINOR EDITS AND WRITE THE FULL SCRIPT MY HEAD IS POUNDING AND IM GOING BLIND PLEASE DONT RUIN THE CODE JUST MAKE THE MINOR EDITS FOR ME PLEASE PAL"},{"assistant_initiates":false,"asst_text":"Hello! Not much, just here to help. How can I assist you today?","behavior":"degenerate_repetition","conversation_hash":"64357e8987b1be2dad386b3464eda5af","conversation_redacted":false,"conversation_toxic":false,"country":"United States","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":116,"n_turns_in_conversation":1,"n_words":22,"source_row_offset":31322,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:27 GMT","turn_id":"086b3e46c88a6c9c3c491f1d","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! Not much, just here and ready to help. How about you?","behavior":"degenerate_repetition","conversation_hash":"5f2b75b0fa0b9778f41fd9f5916d78d5","conversation_redacted":false,"conversation_toxic":false,"country":"France","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":113,"n_turns_in_conversation":1,"n_words":21,"source_row_offset":31323,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:37 GMT","turn_id":"41e549592c6876e7a5ab1b2f","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! Not much, just here and ready to help. How can I assist you today?","behavior":"degenerate_repetition","conversation_hash":"6e53af0ad61790cc5da34e47aea76ab4","conversation_redacted":false,"conversation_toxic":false,"country":"United States","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":126,"n_turns_in_conversation":1,"n_words":24,"source_row_offset":31324,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:46 GMT","turn_id":"749a1bc16ccf0de67347cacb","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! Not much, just here and ready to help. How about you?","behavior":"degenerate_repetition","conversation_hash":"5f2b75b0fa0b9778f41fd9f5916d78d5","conversation_redacted":false,"conversation_toxic":false,"country":"","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4.1-mini-2025-04-14","n_chars":113,"n_turns_in_conversation":1,"n_words":21,"source_row_offset":31325,"source_shard":"turns-00074.parquet","timestamp":"Fri, 02 May 2025 00:58:57 GMT","turn_id":"41e549592c6876e7a5ab1b2f","turn_index":0,"user_text":"User: Hi, what's up?\nUser: Hi, what's up?\nAssistant:"}],"shard":{"index":74,"name":"turns-00074.parquet","rows":40830}}
