impl Bot {

    // All functions need to be inside here

    async fn verify_setup(&self) -> Result<()> { ... }

    async fn save_state(&self) -> Result<()> { ... }

    async fn load_state(&self) -> Result<()> { ... }

    async fn execute_sell(&self, ...) -> Result<()> { ... }

    async fn process_token_info(&self, ...) -> Result<()> { ... }

}// Remove these unused imports

instruction::Instruction,

message::Message,

pubkey::Pubkey,

str::FromStr,

transaction::Transaction,// Change from:

bot.save_state().await

// To:

bot.as_ref().save_state().await  Functions being outside the impl Bot block

Not properly handling Arc<Bot> references

Unused imports at the top        use {
    anyhow::{anyhow, Result},
    colored::*,
    config::{Config, File},
    env_logger::Env,
    futures_util::{SinkExt, StreamExt},
    log::{error, info, warn, debug},
    reqwest::Client as HttpClient,
    serde::{Deserialize, Serialize},
    serde_json::{json, Value},
    solana_client::rpc_client::RpcClient,
    solana_sdk::{
        commitment_config::CommitmentConfig,
        instruction::Instruction,
        message::Message,
        pubkey::Pubkey,
        signature::{Keypair, Signer},
        transaction::Transaction,
    },
    std::{
        collections::HashMap,
        fs,
        str::FromStr,
        sync::Arc,
        time::{Duration, Instant},
    },
    tokio::{
        sync::{Mutex, broadcast},
        time::interval,
    },
    tokio_tungstenite::{
        connect_async,
        tungstenite::protocol::Message as WsMessage,
    },
    url::Url,
};

// Constants
const JUPITER_API: &str = "https://quote-api.jup.ag/v6";
const SOL_MINT: &str = "So11111111111111111111111111111111111111112";
const RAYDIUM_V4: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
const MIN_PRIORITY_FEE: u64 = 15000;
const STATE_SAVE_INTERVAL: u64 = 30;
const MAX_RETRIES: u8 = 3;

// Log prefixes
const LOG_PREFIX_TRADE: &str = "💱 TRADE";
const LOG_PREFIX_ERROR: &str = "❌ ERROR";
const LOG_PREFIX_WALLET: &str = "👛 WALLET";
const LOG_PREFIX_WS: &str = "🔌 WS";
const LOG_PREFIX_DEBUG: &str = "🔍 DEBUG";
const LOG_PREFIX_METRIC: &str = "📊 METRICS";
const LOG_PREFIX_STATE: &str = "💾 STATE";

#[derive(Debug, Clone, Serialize, Deserialize)]
struct TradeState {
    active_trades: HashMap<String, Trade>,
    last_update: chrono::DateTime<chrono::Utc>,
    metrics: BotMetrics,
}

#[derive(Debug, Deserialize, Clone)]
struct BotConfig {
    rpc: RpcConfig,
    wallet: WalletConfig,
    trading: TradingConfig,
    token_requirements: TokenRequirements,
    logging: LoggingConfig,
    websocket: WebsocketConfig,
}

#[derive(Debug, Deserialize, Clone)]
struct RpcConfig {
    solana_rpc_url: String,
    fallback_url: String,
    ws_url: String,
    api_key: String,
}

#[derive(Debug, Deserialize, Clone)]
struct WalletConfig {
    keypair_path: String,
    public_key: String,
}

#[derive(Debug, Deserialize, Clone)]
struct TradingConfig {
    snipe_amount: u64,
    max_slippage: f64,
    priority_fee: u64,
    profit_target_percent: f64,
    stop_loss_percent: f64,
    max_concurrent_trades: usize,
    retry_interval: u64,      // How long to wait between trade attempts
    max_buy_attempts: u32,    // Maximum number of buy attempts per token
}

#[derive(Debug, Deserialize, Clone)]
struct TokenRequirements {
    min_supply: u64,
    mutable: bool,
    burnt: bool,
    frozen: bool,
}

#[derive(Debug, Deserialize, Clone)]
struct WebsocketConfig {
    reconnect_interval: u64,
    heartbeat_interval: u64,
}

#[derive(Debug, Deserialize, Clone)]
struct LoggingConfig {
    show_balances: bool,
    debug_mode: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
struct Trade {
    token_address: String,
    amount: u64,
    buy_price: f64,
    take_profit_price: f64,
    stop_loss_price: f64,
    timestamp: i64,
    status: TradeStatus,
    signature: String,
    last_price_check: Option<i64>,
    attempts: u32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
enum TradeStatus {
    Active,
    Pending,              // Attempting to execute trade
    PendingSell(String),  // Reason for selling
    Completed(f64),       // Final profit/loss
    Failed(String),       // Error message
}

#[derive(Debug, Clone, Serialize, Deserialize)]
struct BotMetrics {
    total_trades: u32,
    successful_trades: u32,
    failed_trades: u32,
    total_profit: f64,
    last_update: i64,
    last_heartbeat: i64,
    total_ws_reconnects: u32,
    avg_execution_time: f64,
}

impl BotMetrics {
    fn new() -> Self {
        Self {
            total_trades: 0,
            successful_trades: 0,
            failed_trades: 0,
            total_profit: 0.0,
            last_update: chrono::Utc::now().timestamp(),
            last_heartbeat: chrono::Utc::now().timestamp(),
            total_ws_reconnects: 0,
            avg_execution_time: 0.0,
        }
    }

    fn log_metrics(&self) {
        info!("{} ==================", LOG_PREFIX_METRIC);
        info!("{} Total Trades: {}", LOG_PREFIX_METRIC, self.total_trades);
        info!("{} Successful: {}", LOG_PREFIX_METRIC, self.successful_trades);
        info!("{} Failed: {}", LOG_PREFIX_METRIC, self.failed_trades);
        info!("{} Total Profit: {:.4} SOL", LOG_PREFIX_METRIC, self.total_profit);
        info!("{} Avg Execution: {:.2}ms", LOG_PREFIX_METRIC, self.avg_execution_time);
    }
}

struct Bot {
    config: BotConfig,
    rpc_client: Arc<RpcClient>,
    fallback_rpc: Arc<RpcClient>,
    keypair: Arc<Keypair>,
    active_trades: Arc<Mutex<HashMap<String, Trade>>>,
    pending_trades: Arc<Mutex<HashMap<String, Trade>>>, // For tokens we're attempting to buy
    http_client: HttpClient,
    metrics: Arc<Mutex<BotMetrics>>,
    shutdown_sender: broadcast::Sender<()>,
}
impl Bot {
    async fn new() -> Result<Self> {
        println!("{}", "\n🚀 INITIALIZING SOLANA SNIPER ELITE v5.0".bright_green().bold());

        // Load configuration
        let config = Config::builder()
            .add_source(File::with_name("config.toml"))
            .build()?
            .try_deserialize::<BotConfig>()?;

        // Initialize RPC clients
        info!("{} Initializing RPC connections", LOG_PREFIX_WALLET);
        let rpc_client = Arc::new(RpcClient::new_with_commitment(
            &config.rpc.solana_rpc_url,
            CommitmentConfig::confirmed(),
        ));

        let fallback_rpc = Arc::new(RpcClient::new_with_commitment(
            &config.rpc.fallback_url,
            CommitmentConfig::confirmed(),
        ));

        // Load keypair
        info!("{} Loading wallet keypair", LOG_PREFIX_WALLET);
        let key_file_content = fs::read_to_string(&config.wallet.keypair_path)?;
        let key_bytes: Vec<u8> = serde_json::from_str(&key_file_content)?;

        if key_bytes.len() != 64 {
            return Err(anyhow!("Invalid keypair length: expected 64 bytes, got {}", key_bytes.len()));
        }

        let keypair = Arc::new(Keypair::from_bytes(&key_bytes)?);
        
        // Verify pubkey
        let loaded_pubkey = keypair.pubkey().to_string();
        if loaded_pubkey != config.wallet.public_key {
            return Err(anyhow!("Keypair mismatch: loaded {} but config specified {}", 
                loaded_pubkey, config.wallet.public_key));
        }

        info!("{} Loaded wallet: {}", LOG_PREFIX_WALLET, keypair.pubkey());

        // Initialize HTTP client with Helius API key
        let http_client = HttpClient::builder()
            .timeout(Duration::from_secs(5))
            .pool_idle_timeout(Duration::from_secs(30))
            .pool_max_idle_per_host(32)
            .default_headers({
                let mut headers = reqwest::header::HeaderMap::new();
                headers.insert(
                    "Authorization",
                    format!("Bearer {}", config.rpc.api_key).parse()?,
                );
                headers
            })
            .build()?;

        let (shutdown_sender, _) = broadcast::channel(1);

        Ok(Self {
            config,
            rpc_client,
            fallback_rpc,
            keypair,
            active_trades: Arc::new(Mutex::new(HashMap::new())),
            pending_trades: Arc::new(Mutex::new(HashMap::new())),
            http_client,
            metrics: Arc::new(Mutex::new(BotMetrics::new())),
            shutdown_sender,
        })
    }

    async fn execute_trade(&self, token_address: &str, is_buy: bool) -> Result<String> {
        let start = Instant::now();
        let trade_type = if is_buy { "BUY" } else { "SELL" };
        
        info!("{} Attempting {} for {}", LOG_PREFIX_TRADE, trade_type, token_address);

        // Check SOL balance for buys
        if is_buy {
            let sol_balance = self.rpc_client.get_balance(&self.keypair.pubkey())? as f64 / 1e9;
            let required_sol = (self.config.trading.snipe_amount as f64 / 1e9) + 0.01;
            
            if sol_balance < required_sol {
                return Err(anyhow!("Insufficient SOL balance for trade. Have: {} SOL, Need: {} SOL", 
                    sol_balance, required_sol));
            }
        }

        let (input_mint, output_mint, amount) = if is_buy {
            (SOL_MINT, token_address, self.config.trading.snipe_amount)
        } else {
            (token_address, SOL_MINT, self.config.trading.snipe_amount)
        };

        // Try to get quote - this might fail if no liquidity
        info!("🚀 Getting quote...");
        let quote = match self.get_jupiter_quote(input_mint, output_mint, amount).await {
            Ok(q) => q,
            Err(e) => {
                // No liquidity or other quote error - not fatal
                debug!("{} Quote failed: {}", LOG_PREFIX_DEBUG, e);
                return Err(anyhow!("Quote unavailable: {}", e));
            }
        };

        // Check if route exists
        if !quote["data"]["routesInfos"].as_array().map_or(false, |r| !r.is_empty()) {
            return Err(anyhow!("No valid routes found - possible liquidity issue"));
        }

        // Build swap
        info!("🔄 Building swap...");
        let swap_data = self.build_atomic_swap(&quote).await?;
        
        // Send priority transaction
        info!("💨 Sending priority transaction...");
        let signature = self.send_priority_transaction(swap_data).await?;
        
        let elapsed = start.elapsed();
        info!("✨ {} executed in {:?}", trade_type, elapsed);
        
        // Update metrics
        let mut metrics = self.metrics.lock().await;
        metrics.avg_execution_time = (metrics.avg_execution_time + elapsed.as_millis() as f64) / 2.0;
        
        if is_buy {
            metrics.total_trades += 1;
        }
        
        Ok(signature)
    }

    async fn get_jupiter_quote(&self, input_mint: &str, output_mint: &str, amount: u64) -> Result<Value> {
        let url = format!(
            "{}/quote?inputMint={}&outputMint={}&amount={}&slippageBps={}&onlyDirectRoutes=true",
            JUPITER_API,
            input_mint,
            output_mint,
            amount,
            (self.config.trading.max_slippage * 100.0) as u64
        );

        let response = self.http_client
            .get(&url)
            .send()
            .await?
            .json::<Value>()
            .await?;

        if response["data"]["routesInfos"].as_array().map_or(true, |r| r.is_empty()) {
            return Err(anyhow!("No routes available"));
        }

        Ok(response)
    }

    async fn build_atomic_swap(&self, quote: &Value) -> Result<String> {
        let swap_request = json!({
            "quoteResponse": quote,
            "userPublicKey": self.config.wallet.public_key,
            "computeUnitPriceMicroLamports": MIN_PRIORITY_FEE,
            "priorityFeeLamports": MIN_PRIORITY_FEE,
            "asLegacyTransaction": false,
            "maxAccounts": 64,
            "verifyWallet": true
        });

        let response = self.http_client
            .post(format!("{}/swap", JUPITER_API))
            .json(&swap_request)
            .send()
            .await?
            .json::<Value>()
            .await?;

        match response.get("swapTransaction") {
            Some(tx) => Ok(tx.as_str()
                .ok_or_else(|| anyhow!("Invalid transaction format"))?
                .to_string()),
            None => {
                error!("{} Swap Response: {:?}", LOG_PREFIX_ERROR, response);
                Err(anyhow!("No swap transaction in response"))
            }
        }
    }

    async fn send_priority_transaction(&self, transaction_data: String) -> Result<String> {
        let helius_request = json!({
            "jsonrpc": "2.0",
            "id": "helius-priority",
            "method": "sendTransaction",
            "params": [
                transaction_data,
                {
                    "encoding": "base64",
                    "maxRetries": 0,
                    "skipPreflight": true,
                    "preflightCommitment": "processed",
                    "priorityFee": MIN_PRIORITY_FEE,
                    "minContextSlot": "max",
                    "maxAccountLocks": 64
                }
            ]
        });

        let response = self.http_client
            .post(&self.config.rpc.solana_rpc_url)
            .header("Authorization", format!("Bearer {}", self.config.rpc.api_key))
            .json(&helius_request)
            .send()
            .await?
            .json::<Value>()
            .await?;

        match response.get("result") {
            Some(result) => {
                let signature = result.as_str().unwrap_or_default().to_string();
                info!("{} Priority TX sent: {}", LOG_PREFIX_TRADE, signature);
                Ok(signature)
            },
            None => {
                if let Some(error) = response.get("error") {
                    Err(anyhow!("Helius error: {:?}", error))
                } else {
                    Err(anyhow!("Transaction failed without error details"))
                }
            }
        }
    }
    async fn validate_token(
        &self,
        token_address: &str,
        supply: u64,
        mutable: bool,
        burnt: bool,
        frozen: bool,
    ) -> Result<bool> {
        info!("{} New token detected:", LOG_PREFIX_TRADE);
        info!("📍 Address: {}", token_address);
        info!("💰 Supply: {}", supply);
        info!("🔒 Burnt: {}", burnt);
        info!("🔑 Mutable: {}", mutable);
        info!("❄️ Frozen: {}", frozen);

        // Basic requirements check
        if supply < self.config.token_requirements.min_supply {
            debug!("{} Rejected: Supply {} < minimum {}", 
                LOG_PREFIX_DEBUG, supply, self.config.token_requirements.min_supply);
            return Ok(false);
        }

        if mutable != self.config.token_requirements.mutable {
            debug!("{} Rejected: Wrong mutability", LOG_PREFIX_DEBUG);
            return Ok(false);
        }

        if burnt != self.config.token_requirements.burnt {
            debug!("{} Rejected: Wrong burn status", LOG_PREFIX_DEBUG);
            return Ok(false);
        }

        if frozen != self.config.token_requirements.frozen {
            debug!("{} Rejected: Wrong freeze status", LOG_PREFIX_DEBUG);
            return Ok(false);
        }

        Ok(true)
    }

    async fn process_new_token(
        &self,
        token_address: &str,
        supply: u64,
        mutable: bool,
        burnt: bool,
        frozen: bool,
    ) -> Result<()> {
        // Check if we're already handling this token
        {
            let pending = self.pending_trades.lock().await;
            let active = self.active_trades.lock().await;
            
            if pending.contains_key(token_address) || active.contains_key(token_address) {
                return Ok(());
            }
        }

        // First validate token attributes
        if !self.validate_token(token_address, supply, mutable, burnt, frozen).await? {
            return Ok(());
        }

        // Check trade slot availability
        let trades = self.active_trades.lock().await;
        if trades.len() >= self.config.trading.max_concurrent_trades {
            debug!("{} Maximum concurrent trades reached", LOG_PREFIX_DEBUG);
            return Ok(());
        }
        drop(trades);

        // Add to pending trades and start retry process
        let trade = Trade {
            token_address: token_address.to_string(),
            amount: self.config.trading.snipe_amount,
            buy_price: 0.0,  // Will be set after successful buy
            take_profit_price: 0.0,
            stop_loss_price: 0.0,
            timestamp: chrono::Utc::now().timestamp(),
            status: TradeStatus::Pending,
            signature: String::new(),
            last_price_check: None,
            attempts: 0,
        };

        let mut pending = self.pending_trades.lock().await;
        pending.insert(token_address.to_string(), trade);
        drop(pending);

        // Start retry task for this token
        self.start_buy_retry(token_address.to_string()).await;

        Ok(())
    }

    async fn start_buy_retry(&self, token_address: String) {
        let bot = self.clone();
        tokio::spawn(async move {
            loop {
                // Check if we should continue retrying
                let should_continue = {
                    let pending = bot.pending_trades.lock().await;
                    if let Some(trade) = pending.get(&token_address) {
                        trade.attempts < bot.config.trading.max_buy_attempts
                    } else {
                        false
                    }
                };

                if !should_continue {
                    // Remove from pending if max attempts reached
                    let mut pending = bot.pending_trades.lock().await;
                    pending.remove(&token_address);
                    break;
                }

                // Attempt buy
                match bot.execute_trade(&token_address, true).await {
                    Ok(signature) => {
                        info!("{} Buy successful! TX: {}", LOG_PREFIX_TRADE, signature);
                        
                        // Get entry price
                        if let Ok(entry_price) = bot.get_token_price(&token_address).await {
                            let trade = Trade {
                                token_address: token_address.clone(),
                                amount: bot.config.trading.snipe_amount,
                                buy_price: entry_price,
                                take_profit_price: entry_price * (1.0 + bot.config.trading.profit_target_percent / 100.0),
                                stop_loss_price: entry_price * (1.0 - bot.config.trading.stop_loss_percent / 100.0),
                                timestamp: chrono::Utc::now().timestamp(),
                                status: TradeStatus::Active,
                                signature,
                                last_price_check: Some(chrono::Utc::now().timestamp()),
                                attempts: 1,
                            };

                            // Move from pending to active trades
                            let mut pending = bot.pending_trades.lock().await;
                            pending.remove(&token_address);
                            
                            let mut active = bot.active_trades.lock().await;
                            active.insert(token_address.clone(), trade);
                            
                            bot.save_state().await.ok();
                        }
                        break;
                    }
                    Err(e) => {
                        // Update attempt count
                        let mut pending = bot.pending_trades.lock().await;
                        if let Some(trade) = pending.get_mut(&token_address) {
                            trade.attempts += 1;
                            debug!("{} Buy attempt {} failed: {}", LOG_PREFIX_DEBUG, trade.attempts, e);
                        }
                        drop(pending);
                        
                        // Wait before retry
                        tokio::time::sleep(Duration::from_secs(bot.config.trading.retry_interval)).await;
                    }
                }
            }
        });
    }

    async fn monitor_trades(&self) -> Result<()> {
        let trades = self.active_trades.lock().await;
        let trade_list = trades.clone();
        drop(trades);

        for (token_address, trade) in trade_list {
            match trade.status {
                TradeStatus::Active => {
                    match self.get_token_price(&token_address).await {
                        Ok(current_price) => {
                            let profit_percent = ((current_price - trade.buy_price) / trade.buy_price * 100.0).round();

                            let status = if profit_percent >= 0.0 {
                                format!("📈 +{:.2}%", profit_percent).green()
                            } else {
                                format!("📉 {:.2}%", profit_percent).red()
                            };

                            info!("{} {}: {}", LOG_PREFIX_TRADE, token_address, status);

                            // Check take profit
                            if current_price >= trade.take_profit_price {
                                info!("{} Take profit triggered for {}", LOG_PREFIX_TRADE, token_address);
                                self.execute_sell(&token_address, &trade, "Take Profit").await?;
                            }
                            // Check stop loss
                            else if current_price <= trade.stop_loss_price {
                                warn!("{} Stop loss triggered for {}", LOG_PREFIX_TRADE, token_address);
                                self.execute_sell(&token_address, &trade, "Stop Loss").await?;
                            }
                        }
                        Err(e) => {
                            warn!("{} Failed to get price for {}: {}", LOG_PREFIX_ERROR, token_address, e);
                            // Don't exit - continue monitoring other trades
                        }
                    }
                }
                _ => continue,
            }
        }

        Ok(())
    }

    async fn get_token_price(&self, token_address: &str) -> Result<f64> {
        let url = format!(
            "https://price.jup.ag/v6/price?ids={}&vsToken=SOL",
            token_address
        );

        let response = self.http_client
            .get(&url)
            .send()
            .await?
            .json::<Value>()
            .await?;

        response["data"][token_address]["price"]
            .as_f64()
            .ok_or_else(|| anyhow!("Price not found"))
    }
    async fn run_websocket(&self) -> Result<()> {
        info!("{} Connecting to WebSocket...", LOG_PREFIX_WS);
        
        let ws_url = Url::parse(&self.config.rpc.ws_url)?;
        let (ws_stream, _) = connect_async(&ws_url).await?;
        let (mut write, mut read) = ws_stream.split();

        // Subscribe to Raydium program
        let subscribe_msg = json!({
            "jsonrpc": "2.0",
            "id": 1,
            "method": "programSubscribe",
            "params": [
                RAYDIUM_V4,
                {
                    "encoding": "jsonParsed",
                    "commitment": "processed"
                }
            ]
        });

        write.send(WsMessage::Text(subscribe_msg.to_string())).await?;
        info!("{} Subscribed to Raydium program", LOG_PREFIX_WS);

        // Heartbeat tracking
        let last_msg = Arc::new(Mutex::new(Instant::now()));
        let last_msg_clone = last_msg.clone();

        // Start heartbeat monitor
        let heartbeat_handle = {
            let max_interval = Duration::from_secs(self.config.websocket.heartbeat_interval);
            tokio::spawn(async move {
                let mut interval = interval(Duration::from_secs(1));
                loop {
                    interval.tick().await;
                    let elapsed = last_msg_clone.lock().await.elapsed();
                    if elapsed > max_interval {
                        error!("{} WebSocket timeout after {:?}", LOG_PREFIX_ERROR, elapsed);
                        break;
                    }
                }
            })
        };

        // Main message processing loop
        let mut message_counter = 0u64;
        while let Some(msg_result) = read.next().await {
            *last_msg.lock().await = Instant::now();
            message_counter += 1;

            if message_counter % 1000 == 0 {
                info!("{} Processed {} messages", LOG_PREFIX_WS, message_counter);
            }

            match msg_result {
                Ok(msg) => match msg {
                    WsMessage::Text(text) => {
                        // Don't let message processing errors break the loop
                        if let Err(e) = self.handle_ws_message(&text).await {
                            warn!("{} Message processing error: {}", LOG_PREFIX_ERROR, e);
                        }
                    }
                    WsMessage::Ping(_) => {
                        if let Err(e) = write.send(WsMessage::Pong(vec![])).await {
                            warn!("Failed to respond to ping: {}", e);
                        }
                    }
                    WsMessage::Close(frame) => {
                        info!("{} WebSocket closed: {:?}", LOG_PREFIX_WS, frame);
                        break;
                    }
                    _ => {}
                },
                Err(e) => {
                    error!("{} WebSocket error: {}", LOG_PREFIX_ERROR, e);
                    break;
                }
            }
        }

        heartbeat_handle.abort();
        Err(anyhow!("WebSocket connection terminated"))
    }

    async fn handle_ws_message(&self, text: &str) -> Result<()> {
        let value: Value = serde_json::from_str(text)?;
        
        if let Some(result) = value.get("params").and_then(|p| p.get("result")) {
            if let Some(data) = result.get("value") {
                if let Some(token_info) = self.extract_token_info(data)? {
                    self.process_token_info(token_info).await?;
                }
            }
        }

        Ok(())
    }

    fn extract_token_info(&self, data: &Value) -> Result<Option<TokenInfo>> {
        if let Some(account_data) = data.get("account").and_then(|a| a.get("data")) {
            if let Some(parsed) = account_data.get("parsed") {
                let token_info = TokenInfo {
                    address: parsed["info"]["mint"]
                        .as_str()
                        .ok_or_else(|| anyhow!("Missing mint address"))?
                        .to_string(),
                    supply: parsed["info"]["supply"]
                        .as_str()
                        .and_then(|s| s.parse::<u64>().ok())
                        .unwrap_or(0),
                    decimals: parsed["info"]["decimals"]
                        .as_u64()
                        .unwrap_or(0) as u8,
                    is_mutable: !parsed["info"]["mintAuthority"].is_null(),
                    is_burnt: parsed["info"]["mintAuthority"].is_null(),
                    is_frozen: parsed["info"]["freezeAuthority"].is_null(),
                };
                return Ok(Some(token_info));
            }
        }
        Ok(None)
    }

    async fn run(self: Arc<Self>) -> Result<()> {
        info!("🚀 Starting Solana Sniper Elite v5.0");
        
        // Load previous state
        self.load_state().await?;
        
        // Start monitoring tasks
        let trade_monitor = {
            let bot = self.clone();
            tokio::spawn(async move {
                let mut interval = interval(Duration::from_secs(1));
                loop {
                    interval.tick().await;
                    if let Err(e) = bot.monitor_trades().await {
                        error!("{} Trade monitoring error: {}", LOG_PREFIX_ERROR, e);
                    }
                }
            })
        };

        // State saving task
        let state_saver = {
            let bot = self.clone();
            tokio::spawn(async move {
                let mut interval = interval(Duration::from_secs(STATE_SAVE_INTERVAL));
                loop {
                    interval.tick().await;
                    if let Err(e) = bot.save_state().await {
                        error!("{} State saving error: {}", LOG_PREFIX_ERROR, e);
                    }
                }
            })
        };

        // Run WebSocket with automatic reconnection
        let mut consecutive_failures = 0u32;
        loop {
            match self.run_websocket().await {
                Ok(_) => {
                    consecutive_failures = 0;
                    continue;
                }
                Err(e) => {
                    consecutive_failures += 1;
                    error!("{} WebSocket error (attempt {}): {}", LOG_PREFIX_ERROR, consecutive_failures, e);
                    
                    if consecutive_failures >= 3 {
                        error!("🔄 Too many consecutive failures, saving state and restarting...");
                        if let Err(e) = self.save_state().await {
                            error!("{} Failed to save state: {}", LOG_PREFIX_ERROR, e);
                        }
                        break;
                    }
                    
                    let delay = self.config.websocket.reconnect_interval * consecutive_failures as u64;
                    info!("⏳ Waiting {} seconds before reconnect...", delay);
                    tokio::time::sleep(Duration::from_secs(delay)).await;
                }
            }
        }

        // Cleanup
        trade_monitor.abort();
        state_saver.abort();

        Ok(())
    }
}

#[derive(Debug)]
struct TokenInfo {
    address: String,
    supply: u64,
    decimals: u8,
    is_mutable: bool,
    is_burnt: bool,
    is_frozen: bool,
}

async fn verify_setup(&self) -> Result<()> {
    info!("🔍 Verifying setup...");

    // Check RPC connections
    info!("Testing RPC connections...");
    match self.rpc_client.get_slot() {
        Ok(slot) => info!("✅ Marga Fast RPC connected (slot: {})", slot),
        Err(e) => {
            error!("❌ Primary RPC connection failed: {}", e);
            info!("Trying fallback RPC...");
            match self.fallback_rpc.get_slot() {
                Ok(slot) => info!("✅ Fallback RPC connected (slot: {})", slot),
                Err(e) => return Err(anyhow!("All RPC connections failed: {}", e)),
            }
        }
    }

    // Check SOL balance
    let sol_balance = self.rpc_client.get_balance(&self.keypair.pubkey())? as f64 / 1e9;
    info!("💰 SOL Balance: {} SOL", sol_balance);

    let min_required = (self.config.trading.snipe_amount as f64 / 1e9) + 0.01;
    if sol_balance < min_required {
        warn!("⚠️ Low SOL balance! Have: {} SOL, Need: {} SOL", sol_balance, min_required);
    }

    // Print trading settings
    info!("📊 Trading Configuration:");
    info!("   Buy Amount: {} SOL", self.config.trading.snipe_amount as f64 / 1e9);
    info!("   Max Slippage: {}%", self.config.trading.max_slippage);
    info!("   Priority Fee: {} lamports", self.config.trading.priority_fee);
    info!("   Take Profit: {}%", self.config.trading.profit_target_percent);
    info!("   Stop Loss: {}%", self.config.trading.stop_loss_percent);
    info!("   Max Concurrent: {}", self.config.trading.max_concurrent_trades);
    info!("   Retry Interval: {}s", self.config.trading.retry_interval);
    info!("   Max Buy Attempts: {}", self.config.trading.max_buy_attempts);

    info!("🔒 Token Requirements:");
    info!("   Min Supply: {}", self.config.token_requirements.min_supply);
    info!("   Mutable: {}", self.config.token_requirements.mutable);
    info!("   Burnt: {}", self.config.token_requirements.burnt);
    info!("   Frozen: {}", self.config.token_requirements.frozen);

    Ok(())
}

async fn save_state(&self) -> Result<()> {
    let trades = self.active_trades.lock().await;
    let metrics = self.metrics.lock().await;
    
    let state = TradeState {
        active_trades: trades.clone(),
        last_update: chrono::Utc::now(),
        metrics: metrics.clone(),
    };

    let state_json = serde_json::to_string_pretty(&state)?;
    tokio::fs::write("bot_state.json", state_json).await?;
    debug!("{} State saved successfully", LOG_PREFIX_STATE);
    Ok(())
}

async fn load_state(&self) -> Result<()> {
    match tokio::fs::read_to_string("bot_state.json").await {
        Ok(content) => {
            let state: TradeState = serde_json::from_str(&content)?;
            
            let mut trades = self.active_trades.lock().await;
            *trades = state.active_trades;
            
            let mut metrics = self.metrics.lock().await;
            *metrics = state.metrics;
            
            info!("{} Loaded {} active trades", LOG_PREFIX_STATE, trades.len());
            metrics.log_metrics();
            Ok(())
        }
        Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
            info!("{} No existing state found", LOG_PREFIX_STATE);
            self.save_state().await
        }
        Err(e) => Err(anyhow!(e)),
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize logging with colored output
    env_logger::Builder::from_env(Env::default().default_filter_or("info"))
        .format(|buf, record| {
            use std::io::Write;
            writeln!(
                buf,
                "{} [{}] {}",
                chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
                record.level(),
                record.args()
            )
        })
        .init();

    println!("{}", "=====================================".bright_blue());
    println!("{}", "🔫 SOLANA SNIPER ELITE v5.0 🎯".bright_green().bold());
    println!("{}", "=====================================".bright_blue());
    println!("{}", "Starting with Marga Fast + Helius Pro...".bright_yellow());

    // Create and verify bot setup
    let bot = match Bot::new().await {
        Ok(b) => {
            let bot = Arc::new(b);
            if let Err(e) = bot.verify_setup().await {
                error!("Setup verification failed: {}", e);
                std::process::exit(1);
            }
            bot
        }
        Err(e) => {
            error!("Failed to initialize bot: {}", e);
            std::process::exit(1);
        }
    };

    // Set up graceful shutdown
    let shutdown_bot = bot.clone();
    ctrlc::set_handler(move || {
        let bot = shutdown_bot.clone();
        tokio::runtime::Runtime::new().unwrap().block_on(async move {
            info!("{} Initiating graceful shutdown...", LOG_PREFIX_STATE);
            if let Err(e) = bot.save_state().await {
                error!("{} Failed to save state during shutdown: {}", LOG_PREFIX_ERROR, e);
            }
            println!("{}", "\n👋 Saving state and shutting down...".bright_yellow());
            std::process::exit(0);
        });
    })?;

    // Main bot loop with automatic restart
    let mut consecutive_errors = 0;
    loop {
        info!("🚀 Starting bot cycle...");

        match bot.clone().run().await {
            Ok(_) => {
                consecutive_errors = 0;
            }
            Err(e) => {
                error!("{} Bot error: {}", LOG_PREFIX_ERROR, e);
                consecutive_errors += 1;

                if consecutive_errors >= 3 {
                    error!("🔄 Too many consecutive errors, forcing restart...");
                    if let Err(e) = bot.save_state().await {
                        error!("{} Failed to save state before restart: {}", LOG_PREFIX_ERROR, e);
                    }
                    std::process::exit(1);
                }

                info!("⏳ Waiting 5 seconds before retry...");
                tokio::time::sleep(Duration::from_secs(5)).await;
            }
        }
    }
}      WRITE THE ENTIRE SCRIPT PLEASE WITH THE EDITS FROM ABOVE PROPERLY DO NOT REMOVE OR WEAKEN OR RUIN OR CHANGE OR ALTER ANYTHING OTHER THEN FIXING THE PROBLEMS I STATED IN THE BEGINING PLEASE PROVIDE THE FULL ENTIRETY OF THE SCRIPT MY EYES ARE GOING BAD PLEASE ASISST ME