use anyhow::{anyhow, Result};
use dashmap::DashMap;
use futures_util::{SinkExt, StreamExt};
use log::{error, info, warn};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::{
    cmp::min,
    path::PathBuf,
    sync::Arc,
    time::{Duration, Instant, SystemTime},
};
use tokio::{
    fs::File,
    io::{AsyncReadExt, AsyncWriteExt},
    sync::{broadcast, Mutex},
};
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
use url::Url;
use reqwest;

// Configuration Constants
const JUPITER_API: &str = "https://quote-api.jup.ag/v6";
const HELIUS_RPC: &str = "https://marga-e56m84-fast-mainnet.helius-rpc.com";
const WS_URL: &str = "wss://marga-e56m84-fast-mainnet.helius-rpc.com/";
const WALLET_PUBLIC_KEY: &str = "EHrpEhiBU13CygunXsmeGnzR6ircuYFQcFYPZT5BWUMA";
const HELIUS_API_KEY: &str = "1ea5843b-9daa-4926-a97a-be021922da2f";
const SOL_MINT: &str = "So11111111111111111111111111111111111111112";

// Trading Parameters
const MIN_SUPPLY: u64 = 900_000_000;
const LIQUIDITY_MIN: f64 = 4.0; 
const LIQUIDITY_MAX: f64 = 80.0; 
const TRADE_AMOUNT: u64 = 5_000_000;
const MAX_TRADES: usize = 5;

#[derive(Debug, Clone, Serialize, Deserialize)]
struct TradeState {
    token_mint: String,
    entry_price: f64,
    amount: u64,
    timestamp: u64,
    last_price: f64,
    success_count: u32,
    profit_loss: f64,
}

#[derive(Debug, Clone)]
struct ActiveTrade {
    token_mint: String,
    entry_price: f64,
    amount: u64,
    start_time: Instant,
    last_price: Arc<Mutex<f64>>,
    success_count: u32,
    profit_loss: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
struct SystemMetrics {
    total_trades: u32,
    successful_trades: u32,
    failed_trades: u32,
    total_profit_loss: f64,
    start_time: u64,
    last_restart: u64,
}

#[derive(Debug)]
struct TradingSystem {
    active_trades: DashMap<String, ActiveTrade>,
    last_prices: DashMap<String, f64>,
    known_tokens: DashMap<String, Instant>, 
    metrics: Arc<Mutex<SystemMetrics>>,
    state_file: PathBuf,
    metrics_file: PathBuf,
    shutdown_signal: broadcast::Sender<()>,
}

impl TradingSystem {
    fn new() -> Self {
        let (shutdown_tx, _) = broadcast::channel(1);
        Self {
            active_trades: DashMap::new(),
            last_prices: DashMap::new(),
            known_tokens: DashMap::new(),
            metrics: Arc::new(Mutex::new(SystemMetrics {
                total_trades: 0,
                successful_trades: 0,
                failed_trades: 0,
                total_profit_loss: 0.0,
                start_time: SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs(),
                last_restart: SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs(),
            })),
            state_file: PathBuf::from("trading_state.json"),
            metrics_file: PathBuf::from("system_metrics.json"),
            shutdown_signal: shutdown_tx,
        }
    }

    async fn save_full_state(&self) -> Result<()> {
        let states: Vec<TradeState> = self.active_trades
            .iter()
            .map(|trade| {
                let last_price = futures::executor::block_on(trade.last_price.lock());
                TradeState {
                    token_mint: trade.token_mint.clone(),
                    entry_price: trade.entry_price,
                    amount: trade.amount,
                    timestamp: SystemTime::now()
                        .duration_since(SystemTime::UNIX_EPOCH)
                        .unwrap()
                        .as_secs(),
                    last_price: *last_price,
                    success_count: trade.success_count,
                    profit_loss: trade.profit_loss,
                }
            })
            .collect();
        let mut file = File::create(&self.state_file).await?;
        file.write_all(serde_json::to_string_pretty(&states)?.as_bytes()).await?;

        let mut file = File::create(&self.metrics_file).await?;
        file.write_all(serde_json::to_string_pretty(&*self.metrics.lock().await)?.as_bytes()).await?;
        
        info!("💾 Full system state saved successfully");
        Ok(())
    }

    async fn load_full_state(&self) -> Result<()> {
        if self.state_file.exists() {
            let mut file = File::open(&self.state_file).await?;
            let mut contents = String::new();
            file.read_to_string(&mut contents).await?;
            
            let states: Vec<TradeState> = serde_json::from_str(&contents)?;
            
            for state in states {
                let age = SystemTime::now()
                    .duration_since(SystemTime::UNIX_EPOCH)
                    .unwrap()
                    .as_secs() - state.timestamp;
                    
                if age < 3600 {
                    self.active_trades.insert(
                        state.token_mint.clone(),
                        ActiveTrade {
                            token_mint: state.token_mint,
                            entry_price: state.entry_price,
                            amount: state.amount,
                            start_time: Instant::now(),
                            last_price: Arc::new(Mutex::new(state.last_price)),
                            success_count: state.success_count,
                            profit_loss: state.profit_loss,
                        }
                    );
                }
            }
        }

        if self.metrics_file.exists() {
            let mut file = File::open(&self.metrics_file).await?;
            let mut contents = String::new();
            file.read_to_string(&mut contents).await?;
            
            let stored_metrics: SystemMetrics = serde_json::from_str(&contents)?;
            let mut metrics = self.metrics.lock().await;
            *metrics = stored_metrics;
            metrics.last_restart = SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap()
                .as_secs();
        }
        
        info!("📂 System state restored successfully");
        self.print_system_status().await;
        Ok(())
    }

    async fn print_system_status(&self) {
        let metrics = self.metrics.lock().await;
        let uptime = SystemTime::now()
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap()
            .as_secs() - metrics.start_time;
        
        info!("📊 System Status:");
        info!("   Active Trades: {}", self.active_trades.len());
        info!("   Total Trades: {}", metrics.total_trades);
        info!("   Success Rate: {:.2}%", 
            (metrics.successful_trades as f64 / metrics.total_trades as f64) * 100.0);
        info!("   Total P/L: {:.4} SOL", metrics.total_profit_loss);
        info!("   Uptime: {}h {}m", uptime / 3600, (uptime % 3600) / 60);
        info!("   Last Restart: {} minutes ago", 
            (SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap()
                .as_secs() - metrics.last_restart) / 60);
    }

    async fn validate_new_token(&self, token_data: &Value) -> Result<bool> {
        let token_mint = token_data["mint"].as_str()
            .ok_or_else(|| anyhow!("Invalid mint address"))?;

        if let Some(last_seen) = self.known_tokens.get(token_mint) {
            if last_seen.elapsed() < Duration::from_secs(3600) {
                return Ok(false);
            }
        }

        if self.active_trades.contains_key(token_mint) {
            return Ok(false);
        }

        let mint_data = &token_data["data"]["parsed"]["info"];
        
        let supply = mint_data["supply"].as_str()
            .unwrap_or("0")
            .parse::<u64>()?;
        
        let _decimals = mint_data["decimals"].as_u64().unwrap_or(0); // Use _ to silence the warning
        let is_frozen = mint_data["freezeAuthority"].is_null();
        let is_burnt = !mint_data["mintAuthority"].is_null();
        let is_mutable = mint_data["mintAuthority"].is_null();

        if supply < MIN_SUPPLY {
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        if !is_frozen || !is_burnt || is_mutable {
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        if !self.is_raydium_pool(token_mint).await? {
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        let (liquidity, price) = self.check_liquidity_and_price(token_mint).await?;
        
        if !(LIQUIDITY_MIN..=LIQUIDITY_MAX).contains(&liquidity) {
            self.known_tokens.insert(token_mint.to_string(), Instant::now());
            return Ok(false);
        }

        self.last_prices.insert(token_mint.to_string(), price);
        Ok(true)
    }

    async fn check_liquidity_and_price(&self, token_mint: &str) -> Result<(f64, f64)> {
        let quote = self.get_quote(SOL_MINT, token_mint, TRADE_AMOUNT).await?;
        
        let in_amount = quote["inAmount"].as_str()
            .ok_or_else(|| anyhow!("Invalid input amount"))?
            .parse::<f64>()? / 1e9; // Convert lamports to SOL
            
        let out_amount = quote["outAmount"].as_str()
            .ok_or_else(|| anyhow!("Invalid output amount"))?
            .parse::<f64>()?;
            
        let price = in_amount / out_amount;
        let liquidity = in_amount * price;

        Ok((liquidity, price))
    }

    async fn is_raydium_pool(&self, token_mint: &str) -> Result<bool> {
        let request = json!({
            "jsonrpc": "2.0",
            "id": "pool-check",
            "method": "getProgramAccounts",
            "params": [
                "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8",
                {
                    "filters": [
                        {
                            "memcmp": {
                                "offset": 0,
                                "bytes": token_mint
                            }
                        }
                    ]
                }
            ]
        });

        let response = reqwest::Client::new()
            .post(HELIUS_RPC)
            .header("Authorization", format!("Bearer {}", HELIUS_API_KEY))
            .json(&request)
            .send()
            .await?
            .json::<Value>()
            .await?;

        Ok(!response["result"].as_array().unwrap_or(&vec![]).is_empty())
    }

    async fn execute_trade(&self, is_buy: bool, amount: u64) -> Result<String> {
        let start = Instant::now();
        let trade_type = if is_buy { "BUY" } else { "SELL" };

        let (input_mint, output_mint) = if is_buy {
            (SOL_MINT, "target_token_mint") // You'll need to pass in the target token mint
        } else {
            ("target_token_mint", SOL_MINT)
        };

        info!("🚀 Getting quote for {trade_type}...");
        let quote_start = Instant::now();
        let quote = self.get_quote(input_mint, output_mint, amount).await?;
        info!("⚡ Quote fetched in: {:?}", quote_start.elapsed());

        info!("🔄 Building swap transaction...");
        let swap_start = Instant::now();
        let swap_data = self.get_swap_data(quote).await?;
        info!("⚡ Swap built in: {:?}", swap_start.elapsed());

        info!("💨 Sending priority transaction...");
        let tx_start = Instant::now();
        let signature = self.send_priority_tx(swap_data).await?;
        info!("⚡ Transaction sent in: {:?}", tx_start.elapsed());

        info!("✨ Total {trade_type} execution time: {:?}", start.elapsed());

        Ok(signature)
    }

    async fn get_quote(&self, input_mint: &str, output_mint: &str, amount: u64) -> Result<Value> {
        let url = format!(
            "{}/quote?inputMint={}&outputMint={}&amount={}&slippageBps=50&onlyDirectRoutes=true&wrapUnwrapSOL=true",
            JUPITER_API, input_mint, output_mint, amount
        );

        let response = reqwest::get(&url)
            .await?
            .json::<Value>()
            .await?;
        
        Ok(response)
    }

    async fn get_swap_data(&self, quote: Value) -> Result<String> {
        let swap_request = json!({
            "quoteResponse": quote,
            "userPublicKey": WALLET_PUBLIC_KEY,
            "wrapUnwrapSOL": true,
            "computeUnitPriceMicroLamports": 15000,
            "priorityFeeLamports": 15000,
            "asLegacyTransaction": false,
            "maxAccounts": 64
        });

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

        match response.get("swapTransaction") {
            Some(tx) => tx.as_str()
                .ok_or_else(|| anyhow!("Invalid transaction format"))
                .map(String::from),
            None => Err(anyhow!("No swap transaction in response"))
        }
    }

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

        let response = reqwest::Client::new()
            .post(HELIUS_RPC)
            .header("Authorization", format!("Bearer {}", HELIUS_API_KEY))
            .json(&helius_request)
            .send()
            .await?
            .json::<Value>()
            .await?;

        match response.get("result") {
            Some(result) => Ok(result.as_str().unwrap_or_default().to_string()),
            None => Err(anyhow!("No result in response"))
        }
    }

    async fn execute_trade_with_retry(&self, token_mint: &str, is_buy: bool, amount: u64) -> Result<String> {
        let mut last_error = None;

        for attempt in 1..=3 {
            match self.execute_trade(is_buy, amount).await {
                Ok(signature) => {
                    info!("✅ {} successful on attempt {}", 
                          if is_buy { "Buy" } else { "Sell" }, 
                          attempt);

                    let mut metrics = self.metrics.lock().await;
                    if is_buy {
                        metrics.total_trades += 1;
                    } else {
                        metrics.successful_trades += 1;

                        if let Some(trade) = self.active_trades.get(token_mint) {
                            metrics.total_profit_loss += trade.profit_loss;
                        }
                    }
                    
                    return Ok(signature);
                }
                Err(e) => {
                    warn!("❌ {} failed attempt {}/{}: {}", 
                          if is_buy { "Buy" } else { "Sell" },
                          attempt,
                          3,
                          e);
                    last_error = Some(e);
                    
                    if attempt < 3 {
                        info!("⏳ Waiting 30s before retry...");
                        tokio::time::sleep(Duration::from_secs(30)).await;
                    } else if !is_buy {
                        let mut metrics = self.metrics.lock().await;
                        metrics.failed_trades += 1;
                    }
                }
            }
        }
        
        Err(anyhow!("All retry attempts failed: {}", 
                    last_error.unwrap_or_else(|| anyhow!("Unknown error"))))
    }

    async fn monitor_trades(&self) -> Result<()> {
        let mut interval = tokio::time::interval(Duration::from_secs(1));
        let mut status_interval = tokio::time::interval(Duration::from_secs(300)); 
        let mut shutdown = self.shutdown_signal.subscribe();
        
        loop {
            tokio::select! {
                _ = interval.tick() => {
                    for trade in self.active_trades.iter() {
                        let token_mint = &trade.token_mint;
                        
                        match self.check_liquidity_and_price(token_mint).await {
                            Ok((liquidity, current_price)) => {
                                if let Ok(mut last_price) = trade.last_price.try_lock() {
                                    *last_price = current_price;
                                }
                                
                                let profit_percent = (current_price - trade.entry_price) 
                                                   / trade.entry_price * 100.0;
                                
                                if !(LIQUIDITY_MIN..=LIQUIDITY_MAX).contains(&liquidity) {
                                    warn!("⚠️ Liquidity outside range for {}, initiating sell", token_mint);
                                    if let Err(e) = self.execute_trade_with_retry(token_mint, false, trade.amount).await {
                                        error!("Failed to execute liquidity protection sell: {}", e);
                                    }
                                    continue;
                                }

                                if profit_percent >= 20.0 {
                                    info!("🎯 Take profit hit for {}", token_mint);
                                    match self.execute_trade_with_retry(token_mint, false, trade.amount).await {
                                        Ok(sig) => {
                                            info!("💰 Sold for {}% profit - TX: {}", profit_percent, sig);
                                            if let Some(mut trade) = self.active_trades.get_mut(token_mint) {
                                                trade.profit_loss = profit_percent;
                                                trade.success_count += 1;
                                            }
                                            self.active_trades.remove(token_mint);
                                            self.save_full_state().await?;
                                        }
                                        Err(e) => error!("Failed to execute take profit: {}", e)
                                    }
                                } else if profit_percent <= -5.0 {
                                    warn!("⚠️ Stop loss hit for {}", token_mint);
                                    match self.execute_trade_with_retry(token_mint, false, trade.amount).await {
                                        Ok(sig) => {
                                            info!("🛑 Sold for {}% loss - TX: {}", profit_percent.abs(), sig);
                                            if let Some(mut trade) = self.active_trades.get_mut(token_mint) {
                                                trade.profit_loss = -profit_percent;
                                            }
                                            self.active_trades.remove(token_mint);
                                            self.save_full_state().await?;
                                        }
                                        Err(e) => error!("Failed to execute stop loss: {}", e)
                                    }
                                }
                            }
                            Err(e) => warn!("Failed to fetch price for {}: {}", token_mint, e)
                        }
                    }
                }
                _ = status_interval.tick() => {
                    self.print_system_status().await;
                    self.save_full_state().await?;
                }
                _ = shutdown.recv() => {
                    info!("🛑 Received shutdown signal, saving state...");
                    self.save_full_state().await?;
                    break;
                }
            }
        }
        
        Ok(())
    }

    async fn run(self: Arc<Self>) -> Result<()> {
        self.load_full_state().await?;
        
        let shutdown_tx = self.shutdown_signal.clone();
        ctrlc::set_handler(move || {
            info!("Received Ctrl+C, initiating graceful shutdown...");
            let _ = shutdown_tx.send(());
        })?;

        // Clone `self` wrapped in an Arc to share ownership
        let monitor_handle = {
            let system = self.clone();
            tokio::spawn(async move {
                if let Err(e) = system.monitor_trades().await {
                    error!("Trade monitor error: {}", e);
                }
            })
        };
        let ws_url = Url::parse(WS_URL)?;
        let mut reconnection_delay = Duration::from_secs(1);
        
        loop {
            match connect_async(ws_url.clone()).await {
                Ok((ws_stream, _)) => {
                    info!("📡 WebSocket connected successfully");
                    reconnection_delay = Duration::from_secs(1);
                    
                    let (mut write, mut read) = ws_stream.split();
                    
                    let subscribe_msg = json!({
                        "jsonrpc": "2.0",
                        "id": 1,
                        "method": "programSubscribe",
                        "params": [
                            "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                            {
                                "encoding": "jsonParsed",
                                "filters": [{"dataSize": 82}]
                            }
                        ]
                    });

                    if let Err(e) = write.send(Message::Text(subscribe_msg.to_string())).await {
                        warn!("WebSocket subscription error: {}", e);
                        continue;
                    }

                    info!("✅ Successfully subscribed to token program");

                    let heartbeat_interval = Duration::from_secs(30);
                    
                    while let Some(msg) = read.next().await {
                        match msg {
                            Ok(Message::Text(text)) => {
                                let data: Value = match serde_json::from_str(&text) {
                                    Ok(v) => v,
                                    Err(e) => {
                                        warn!("Failed to parse WebSocket message: {}", e);
                                        continue;
                                    }
                                };

                                if data.get("method").map_or(false, |m| m == "heartbeat") {
                                    continue;
                                }
                                
                                if let Some(params) = data.get("params") {
                                    if let Some(token_data) = params.get("result") {
                                        if self.active_trades.len() >= MAX_TRADES {
                                            continue;
                                        }
                                        
                                        match self.validate_new_token(token_data).await {
                                            Ok(true) => {
                                                let token_mint = match token_data["mint"].as_str() {
                                                    Some(mint) => mint,
                                                    None => {
                                                        warn!("Missing mint address in token data");
                                                        continue;
                                                    }
                                                };
                                                
                                                info!("🎯 Valid token found: {}", token_mint);
                                                
                                                match self.execute_trade_with_retry(token_mint, true, TRADE_AMOUNT).await {
                                                    Ok(signature) => {
                                                        match self.check_liquidity_and_price(token_mint).await {
                                                            Ok((_, entry_price)) => {
                                                                self.active_trades.insert(
                                                                    token_mint.to_string(),
                                                                    ActiveTrade {
                                                                        token_mint: token_mint.to_string(),
                                                                        entry_price,
                                                                        amount: TRADE_AMOUNT,
                                                                        start_time: Instant::now(),
                                                                        last_price: Arc::new(Mutex::new(entry_price)),
                                                                        success_count: 0,
                                                                        profit_loss: 0.0,
                                                                    }
                                                                );
                                                                
                                                                info!("✨ New trade opened - TX: {}", signature);
                                                                self.save_full_state().await?;
                                                            }
                                                            Err(e) => {
                                                                error!("Failed to get entry price: {}", e);
                                                                let _ = self.execute_trade_with_retry(token_mint, false, TRADE_AMOUNT).await;
                                                            }
                                                        }
                                                    }
                                                    Err(e) => warn!("Failed to open trade: {}", e)
                                                }
                                            }
                                            Ok(false) => (), // Token didn't meet criteria
                                            Err(e) => warn!("Error validating token: {}", e)
                                        }
                                    }
                                }
                            }
                            Ok(Message::Ping(_)) => {
                                if let Err(e) = write.send(Message::Pong(vec![])).await {
                                    warn!("Failed to send pong: {}", e);
                                    break;
                                }
                            }
                            Ok(Message::Close(_)) => {
                                info!("Received close frame from server");
                                break;
                            }
                            Err(e) => {
                                warn!("WebSocket error: {}. Reconnecting...", e);
                                break;
                            }
                            _ => ()
                        }
                        
                        // Handle connection timeout
                    }
                }
                Err(e) => {
                    error!("WebSocket connection error: {}. Retrying in {:?}...", e, reconnection_delay);
                    tokio::time::sleep(reconnection_delay).await;
                    reconnection_delay = min(reconnection_delay * 2, Duration::from_secs(30));
                }
            }
            
            if self.shutdown_signal.receiver_count() == 0 {
                break;
            }
        }

        monitor_handle.await?;
        
        info!("👋 Trading system shutdown complete");
        Ok(())
    }

    async fn refresh_token_prices(&self) -> Result<()> {
        for trade in self.active_trades.iter() {
            if let Ok((_, current_price)) = self.check_liquidity_and_price(&trade.token_mint).await {
                if let Ok(mut last_price) = trade.last_price.try_lock() {
                    *last_price = current_price;
                }
            }
        }
        Ok(())
    }
}

fn format_duration(duration: Duration) -> String {
    let secs = duration.as_secs();
    let hours = secs / 3600;
    let minutes = (secs % 3600) / 60;
    let seconds = secs % 60;
    format!("{:02}:{:02}:{:02}", hours, minutes, seconds)
}

#[tokio::main]
async fn main() -> Result<()> {
    env_logger::init();
    info!("🚀 Starting trading system v2.0");
    
    let system = TradingSystem::new();
    
    loop {
        match system.run().await {
            Ok(_) => {
                info!("Trading system completed normally");
                break;
            }
            Err(e) => {
                error!("System error: {}. Restarting in 5s...", e);
                if let Err(save_err) = system.save_full_state().await {
                    error!("Failed to save state before restart: {}", save_err);
                }
                tokio::time::sleep(Duration::from_secs(5)).await;
            }
        }
    }
    
    Ok(())
} please fix this last error please and rewrite the full script please please please all of it with this 1 thing fixed =(   Compiling solana_rust_bot v0.1.0 (C:\solana_rust_bot)
warning: unused variable: `heartbeat_interval`
   --> src/main.rs:581:25
    |
581 |                     let heartbeat_interval = Duration::from_secs(30);
    |                         ^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_heartbeat_interval`
    |
    = note: `#[warn(unused_variables)]` on by default

error[E0599]: no method named `run` found for struct `TradingSystem` in the current scope
   --> src/main.rs:717:22
    |
70  | struct TradingSystem {
    | -------------------- method `run` not found for this struct
...
532 |     async fn run(self: Arc<Self>) -> Result<()> {
    |              --- the method is available for `Arc<TradingSystem>` here
...
717 |         match system.run().await {
    |                      ^^^ method not found in `TradingSystem`
    |
help: consider wrapping the receiver expression with the appropriate type
    |
717 |         match Arc::new(system).run().await {
    |               +++++++++      +

For more information about this error, try `rustc --explain E0599`.
warning: `solana_rust_bot` (bin "solana_rust_bot") generated 1 warning
error: could not compile `solana_rust_bot` (bin "solana_rust_bot") due to 1 previous error; 1 warning emitted