use pyo3::prelude::*;
use solana_client::rpc_client::RpcClient;
use solana_sdk::{
    commitment_config::CommitmentConfig,
    pubkey::Pubkey,
    signature::{Keypair, Signer},
    transaction::Transaction,
    instruction::Instruction,
    compute_budget::ComputeBudgetInstruction,
};
use std::{
    str::FromStr,
    collections::HashMap,
    sync::Arc,
    time::Duration,
    fs,
    path::Path,
    env,
};
use tokio::sync::RwLock;
use serde::{Deserialize, Serialize};
use serde_json;
use log::{info, debug};
use bs58;


#[derive(Debug, Serialize, Deserialize, Clone)]
struct PoolMetrics {
    pool_address: String,
    token_mint: String,
    volume_24h: f64,
    liquidity: f64,
    price: f64,
    buy_pressure: u64,
    sell_pressure: u64,
    mint_authority_revoked: bool,
    liquidity_locked_pct: f64,
    market_cap: f64,
}

#[derive(Debug, Deserialize, Clone)]
struct Config {
    rpc: RpcConfig,
    wallet: WalletConfig,
    trading: TradingConfig,
    system: SystemConfig,
    safety: SafetyConfig,
}

#[derive(Debug, Deserialize, Clone)]
struct RpcConfig {
    primary: PrimaryRpcConfig,
    secondary: SecondaryRpcConfig,
    websocket: WebsocketConfig,
}

#[derive(Debug, Deserialize, Clone)]
struct PrimaryRpcConfig {
    endpoint: String,
    timeout: u64,
    retry_count: u32,
}

#[derive(Debug, Deserialize, Clone)]
struct SecondaryRpcConfig {
    endpoint: String,
    api_key: String,
    timeout: u64,
    retry_count: u32,
}

#[derive(Debug, Deserialize, Clone)]
struct WebsocketConfig {
    endpoint: String,
    timeout: u64,
}

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

#[derive(Debug, Deserialize, Clone)]
struct TradingConfig {
    token_mint: String,
    position_size: f64,
    max_position: f64,
    gas_reserve: f64,
    priority_fee: u64,
    compute_limit: u32,
    min_volume: f64,
    min_bs_ratio: f64,
    min_liquidity: f64,
    max_liquidity: f64,
    liquidity_lock_min: f64,
    max_holder_pct: f64,
    trade_amount: u64,
    take_profit: f64,
    stop_loss: f64,
}

#[derive(Debug, Deserialize, Clone)]
struct SystemConfig {
    gpu_threads: u32,
    batch_size: u32,
    vector_dim: u32,
}

#[derive(Debug, Deserialize, Clone)]
struct SafetyConfig {
    mint_auth_required: bool,
    lp_lock_check: bool,
    holder_check: bool,
    max_holder_percent: f64,
    blacklist_threshold: u32,
    volume_spike_threshold: f64,
    price_spike_threshold: f64,
    market_cap_min: f64,
}

#[pyclass]
struct TradingCore {
    config: Arc<Config>,
    primary_rpc: RpcClient,
    secondary_rpc: RpcClient,
    keypair: Keypair,
    pool_metrics: Arc<RwLock<HashMap<String, PoolMetrics>>>,
}
fn parse_keypair_data(contents: &str) -> PyResult<[u8; 64]> {
    let trimmed = contents.trim();
    
    // Try base58 format first (from env var)
    if let Ok(bytes) = bs58::decode(trimmed).into_vec() {
        if bytes.len() == 64 {
            return bytes.try_into().map_err(|_| 
                PyErr::new::<pyo3::exceptions::PyValueError, _>("Invalid keypair length")
            );
        }
    }

    // Try JSON array format
    if trimmed.starts_with('[') && trimmed.ends_with(']') {
        if let Ok(bytes) = serde_json::from_str::<Vec<u8>>(trimmed) {
            if bytes.len() == 64 {
                return bytes.try_into().map_err(|_| 
                    PyErr::new::<pyo3::exceptions::PyValueError, _>("Invalid keypair length")
                );
            }
        }
    }
    
    // Try comma-separated values
    let bytes: Vec<u8> = trimmed
        .split(',')
        .filter_map(|s| s.trim().parse::<u8>().ok())
        .collect();
    
    if bytes.len() == 64 {
        return bytes.try_into().map_err(|_| 
            PyErr::new::<pyo3::exceptions::PyValueError, _>("Invalid keypair length")
        );
    }

    Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(
        "Could not parse keypair in any supported format"
    ))
}

fn load_keypair_with_fallback(config_keypair_path: &str) -> PyResult<(Keypair, Pubkey)> {
    // Try environment variables first
    if let (Ok(secret), Ok(public)) = (
        env::var("SOLANA_PRIVATE_KEY"),
        env::var("SOLANA_PUBLIC_KEY")
    ) {
        debug!("Found environment variables for keypair");
        
        if let Ok(keypair_data) = parse_keypair_data(&secret) {
            if let Ok(keypair) = Keypair::from_bytes(&keypair_data) {
                let pubkey = Pubkey::from_str(&public)
                    .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
                        format!("Invalid public key format: {}", e)
                    ))?;
                
                if keypair.pubkey() == pubkey {
                    info!("Successfully loaded keypair from environment variables");
                    return Ok((keypair, pubkey));
                }
            }
        }
    }

    // Fallback to file
    let path = Path::new(config_keypair_path);
    info!("Falling back to keypair file: {}", path.display());
    
    let contents = fs::read_to_string(path)
        .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Failed to read keypair file: {}", e)
        ))?;

    let keypair_data = parse_keypair_data(&contents)?;
    let keypair = Keypair::from_bytes(&keypair_data)
        .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Invalid keypair data: {}", e)
        ))?;

    Ok((keypair, keypair.pubkey()))
}

#[pymethods]
impl TradingCore {
    #[new]
    fn new() -> PyResult<Self> {
        info!("Initializing TradingCore...");
        let config_path = "config.json";
        
        let config: Config = serde_json::from_str(
            &fs::read_to_string(config_path)
                .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
                    format!("Failed to read config: {}", e)
                ))?
        ).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Failed to parse config: {}", e)
        ))?;

        let (keypair, pubkey) = load_keypair_with_fallback(&config.wallet.keypair_path)?;
        info!("Loaded keypair with public key: {}", pubkey);

        let primary_rpc = RpcClient::new_with_timeout_and_commitment(
            &config.rpc.primary.endpoint,
            Duration::from_secs(config.rpc.primary.timeout),
            CommitmentConfig::confirmed(),
        );

        let secondary_rpc = RpcClient::new_with_timeout_and_commitment(
            &format!("{}?api-key={}", config.rpc.secondary.endpoint, config.rpc.secondary.api_key),
            Duration::from_secs(config.rpc.secondary.timeout),
            CommitmentConfig::confirmed(),
        );

        Ok(Self {
            config: Arc::new(config),
            primary_rpc,
            secondary_rpc,
            keypair,
            pool_metrics: Arc::new(RwLock::new(HashMap::new())),
        })
    }

    #[pymethods]
    impl TradingCore {
        #[getter]
        fn get_balance(&self) -> PyResult<f64> {
            let mut last_error = None;
            let pubkey = self.keypair.pubkey();
            
            // Try primary RPC
            for _ in 0..self.config.rpc.primary.retry_count {
                match self.primary_rpc.get_balance(&pubkey) {
                    Ok(balance) => {
                        info!("Balance retrieved: {} SOL", balance as f64 / 1e9);
                        return Ok(balance as f64 / 1e9);
                    },
                    Err(e) => {
                        error!("Primary RPC balance check failed: {:?}", e);
                        last_error = Some(e);
                        std::thread::sleep(Duration::from_millis(100));
                    }
                }
            }
    
            // Fallback to secondary RPC
            for _ in 0..self.config.rpc.secondary.retry_count {
                match self.secondary_rpc.get_balance(&pubkey) {
                    Ok(balance) => {
                        info!("Balance retrieved from secondary: {} SOL", balance as f64 / 1e9);
                        return Ok(balance as f64 / 1e9);
                    },
                    Err(e) => {
                        error!("Secondary RPC balance check failed: {:?}", e);
                        last_error = Some(e);
                        std::thread::sleep(Duration::from_millis(100));
                    }
                }
            }
    
            Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
                format!("Failed to get balance: {:?}", last_error)
            ))
        }
    
        fn update_pool_metrics(&self, pool_data: String) -> PyResult<bool> {
            debug!("Updating pool metrics: {}", pool_data);
            let metrics: PoolMetrics = serde_json::from_str(&pool_data)
                .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
                    format!("Failed to parse pool metrics: {}", e)
                ))?;
    
            if self.internal_validate_pool_metrics(&metrics) {
                let mut pools = self.pool_metrics.blocking_write();
                pools.insert(metrics.token_mint.clone(), metrics);
                info!("Pool metrics updated successfully");
                Ok(true)
            } else {
                warn!("Pool metrics validation failed");
                Ok(false)
            }
        }
    
        fn execute_trade(&self, instructions: String) -> PyResult<String> {
            debug!("Processing trade instructions: {}", instructions);
            let instructions: Vec<Instruction> = serde_json::from_str(&instructions)
                .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
                    format!("Invalid trade instructions: {}", e)
                ))?;
    
            let compute_ix = ComputeBudgetInstruction::set_compute_unit_limit(
                self.config.trading.compute_limit
            );
            let priority_ix = ComputeBudgetInstruction::set_compute_unit_price(
                self.config.trading.priority_fee
            );
    
            let mut final_instructions = vec![compute_ix, priority_ix];
            final_instructions.extend(instructions);
    
            self.internal_execute_trade_with_retry(&final_instructions)
        }
    
        fn get_status(&self) -> PyResult<String> {
            let pools = self.pool_metrics.blocking_read();
            let status = serde_json::json!({
                "active_pools": pools.len(),
                "wallet_balance": self.get_balance()?,
                "wallet_address": self.keypair.pubkey().to_string(),
                "position_size": self.config.trading.position_size,
                "max_position": self.config.trading.max_position,
                "gas_reserve": self.config.trading.gas_reserve,
                "compute_limit": self.config.trading.compute_limit,
                "priority_fee": self.config.trading.priority_fee,
                "primary_rpc": self.config.rpc.primary.endpoint,
                "secondary_rpc": self.config.rpc.secondary.endpoint
            });
            
            Ok(status.to_string())
        }
    }
    
    // Internal helper implementations
    impl TradingCore {
        fn internal_validate_pool_metrics(&self, metrics: &PoolMetrics) -> bool {
            metrics.market_cap >= self.config.safety.market_cap_min 
                && metrics.volume_24h >= self.config.trading.min_volume
                && metrics.liquidity >= self.config.trading.min_liquidity
                && metrics.liquidity <= self.config.trading.max_liquidity
                && (metrics.buy_pressure as f64 / metrics.sell_pressure.max(1) as f64) >= self.config.trading.min_bs_ratio
                && (!self.config.safety.mint_auth_required || metrics.mint_authority_revoked)
                && (!self.config.safety.lp_lock_check || metrics.liquidity_locked_pct >= self.config.trading.liquidity_lock_min)
        }
    
        fn internal_execute_trade_with_retry(&self, instructions: &[Instruction]) -> PyResult<String> {
            // Try primary RPC
            for retry in 0..self.config.rpc.primary.retry_count {
                match self.internal_try_execute_trade(instructions) {
                    Ok(sig) => {
                        info!("Trade executed on primary RPC: {}", sig);
                        return Ok(sig);
                    }
                    Err(e) => {
                        error!("Primary RPC trade failed (attempt {}/{}): {:?}", 
                            retry + 1, self.config.rpc.primary.retry_count, e);
                        std::thread::sleep(Duration::from_millis(100));
                    }
                }
            }
    
            // Fallback to secondary RPC
            for retry in 0..self.config.rpc.secondary.retry_count {
                match self.internal_try_execute_trade_secondary(instructions) {
                    Ok(sig) => {
                        info!("Trade executed on secondary RPC: {}", sig);
                        return Ok(sig);
                    }
                    Err(e) => {
                        error!("Secondary RPC trade failed (attempt {}/{}): {:?}", 
                            retry + 1, self.config.rpc.secondary.retry_count, e);
                        std::thread::sleep(Duration::from_millis(100));
                    }
                }
            }
    
            Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
                "Failed to execute trade after all retries"
            ))
        }
    
        fn internal_try_execute_trade(&self, instructions: &[Instruction]) -> Result<String, ClientError> {
            let recent_blockhash = self.primary_rpc.get_latest_blockhash()?;
            let tx = Transaction::new_signed_with_payer(
                instructions,
                Some(&self.keypair.pubkey()),
                &[&self.keypair],
                recent_blockhash,
            );
            let signature = self.primary_rpc.send_and_confirm_transaction(&tx)?;
            Ok(signature.to_string())
        }
    
        fn internal_try_execute_trade_secondary(&self, instructions: &[Instruction]) -> Result<String, ClientError> {
            let recent_blockhash = self.secondary_rpc.get_latest_blockhash()?;
            let tx = Transaction::new_signed_with_payer(
                instructions,
                Some(&self.keypair.pubkey()),
                &[&self.keypair],
                recent_blockhash,
            );
            let signature = self.secondary_rpc.send_and_confirm_transaction(&tx)?;
            Ok(signature.to_string())
        }
    }
    
    #[pymodule]
    fn solana_rust_bot(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
        m.add_class::<TradingCore>()?;
        Ok(())
    }
    
}   can u please write the the full script properly use pyo3::prelude::*;
use solana_client::{rpc_client::RpcClient, client_error::ClientError};
use solana_sdk::{
    commitment_config::CommitmentConfig,
    pubkey::Pubkey,
    signature::{Keypair, Signer},
    transaction::Transaction,
    instruction::Instruction,
    compute_budget::ComputeBudgetInstruction,
};
use std::{
    str::FromStr,
    collections::HashMap,
    sync::Arc,
    time::Duration,
    fs,
    path::Path,
    env,
};
use tokio::sync::RwLock;
use serde::{Deserialize, Serialize};
use serde_json;
use log::{info, debug, error, warn};
use bs58;

#[derive(Debug, Serialize, Deserialize, Clone)]
struct PoolMetrics {
    pool_address: String,
    token_mint: String,
    volume_24h: f64,
    liquidity: f64,
    price: f64,
    buy_pressure: u64,
    sell_pressure: u64,
    mint_authority_revoked: bool,
    liquidity_locked_pct: f64,
    market_cap: f64,
}

#[derive(Debug, Deserialize, Clone)]
struct Config {
    rpc: RpcConfig,
    wallet: WalletConfig,
    trading: TradingConfig,
    system: SystemConfig,
    safety: SafetyConfig,
}

#[derive(Debug, Deserialize, Clone)]
struct RpcConfig {
    primary: PrimaryRpcConfig,
    secondary: SecondaryRpcConfig,
    websocket: WebsocketConfig,
}

#[derive(Debug, Deserialize, Clone)]
struct PrimaryRpcConfig {
    endpoint: String,
    timeout: u64,
    retry_count: u32,
}

#[derive(Debug, Deserialize, Clone)]
struct SecondaryRpcConfig {
    endpoint: String,
    api_key: String,
    timeout: u64,
    retry_count: u32,
}

#[derive(Debug, Deserialize, Clone)]
struct WebsocketConfig {
    endpoint: String,
    timeout: u64,
}

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

#[derive(Debug, Deserialize, Clone)]
struct TradingConfig {
    token_mint: String,
    position_size: f64,
    max_position: f64,
    gas_reserve: f64,
    priority_fee: u64,
    compute_limit: u32,
    min_volume: f64,
    min_bs_ratio: f64,
    min_liquidity: f64,
    max_liquidity: f64,
    liquidity_lock_min: f64,
    max_holder_pct: f64,
    trade_amount: u64,
    take_profit: f64,
    stop_loss: f64,
}

#[derive(Debug, Deserialize, Clone)]
struct SystemConfig {
    gpu_threads: u32,
    batch_size: u32,
    vector_dim: u32,
}

#[derive(Debug, Deserialize, Clone)]
struct SafetyConfig {
    mint_auth_required: bool,
    lp_lock_check: bool,
    holder_check: bool,
    max_holder_percent: f64,
    blacklist_threshold: u32,
    volume_spike_threshold: f64,
    price_spike_threshold: f64,
    market_cap_min: f64,
}

#[pyclass]
struct TradingCore {
    config: Arc<Config>,
    primary_rpc: RpcClient,
    secondary_rpc: RpcClient,
    keypair: Keypair,
    pool_metrics: Arc<RwLock<HashMap<String, PoolMetrics>>>,
}

fn load_keypair() -> PyResult<(Keypair, Pubkey)> {
    // Get environment variables
    let secret = env::var("SOLANA_PRIVATE_KEY")
        .map_err(|_| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            "SOLANA_PRIVATE_KEY environment variable not found"
        ))?;
        
    let public = env::var("SOLANA_PUBLIC_KEY")
        .map_err(|_| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            "SOLANA_PUBLIC_KEY environment variable not found"
        ))?;

    // Decode base58 private key
    let keypair_bytes = bs58::decode(&secret)
        .into_vec()
        .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Invalid base58 private key: {}", e)
        ))?;

    // Create keypair
    let keypair = Keypair::from_bytes(&keypair_bytes)
        .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Invalid keypair data: {}", e)
        ))?;

    // Parse and verify public key
    let pubkey = Pubkey::from_str(&public)
        .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Invalid public key format: {}", e)
        ))?;

    // Verify keys match
    if keypair.pubkey() != pubkey {
        return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Keypair mismatch: {} != {}", keypair.pubkey(), pubkey)
        ));
    }

    info!("Successfully loaded keypair from environment variables");
    Ok((keypair, pubkey))
}

#[pymethods]
impl TradingCore {
    #[new]
    fn new() -> PyResult<Self> {
        info!("Initializing TradingCore...");
        let config_path = "config.json";
        
        // Load and parse config
        let config: Config = serde_json::from_str(
            &fs::read_to_string(config_path)
                .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
                    format!("Failed to read config: {}", e)
                ))?
        ).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
            format!("Failed to parse config: {}", e)
        ))?;

        // Load keypair from environment variables
        let (keypair, pubkey) = load_keypair()?;
        info!("Loaded keypair with public key: {}", pubkey);

        let primary_rpc = RpcClient::new_with_timeout_and_commitment(
            &config.rpc.primary.endpoint,
            Duration::from_secs(config.rpc.primary.timeout),
            CommitmentConfig::confirmed(),
        );

        let secondary_rpc = RpcClient::new_with_timeout_and_commitment(
            &format!("{}?api-key={}", config.rpc.secondary.endpoint, config.rpc.secondary.api_key),
            Duration::from_secs(config.rpc.secondary.timeout),
            CommitmentConfig::confirmed(),
        );

        Ok(Self {
            config: Arc::new(config),
            primary_rpc,
            secondary_rpc,
            keypair,
            pool_metrics: Arc::new(RwLock::new(HashMap::new())),
        })
    }

    #[getter]
    fn get_balance(&self) -> PyResult<f64> {
        let mut last_error = None;
        let pubkey = self.keypair.pubkey();
        
        // Try primary RPC
        for _ in 0..self.config.rpc.primary.retry_count {
            match self.primary_rpc.get_balance(&pubkey) {
                Ok(balance) => {
                    info!("Balance retrieved: {} SOL", balance as f64 / 1e9);
                    return Ok(balance as f64 / 1e9);
                },
                Err(e) => {
                    error!("Primary RPC balance check failed: {:?}", e);
                    last_error = Some(e);
                    std::thread::sleep(Duration::from_millis(100));
                }
            }
        }

        // Fallback to secondary RPC
        for _ in 0..self.config.rpc.secondary.retry_count {
            match self.secondary_rpc.get_balance(&pubkey) {
                Ok(balance) => {
                    info!("Balance retrieved from secondary: {} SOL", balance as f64 / 1e9);
                    return Ok(balance as f64 / 1e9);
                },
                Err(e) => {
                    error!("Secondary RPC balance check failed: {:?}", e);
                    last_error = Some(e);
                    std::thread::sleep(Duration::from_millis(100));
                }
            }
        }

        Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
            format!("Failed to get balance: {:?}", last_error)
        ))
    }

    fn update_pool_metrics(&self, pool_data: String) -> PyResult<bool> {
        debug!("Updating pool metrics: {}", pool_data);
        let metrics: PoolMetrics = serde_json::from_str(&pool_data)
            .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
                format!("Failed to parse pool metrics: {}", e)
            ))?;

        if self.validate_pool_metrics(&metrics) {
            let mut pools = self.pool_metrics.blocking_write();
            pools.insert(metrics.token_mint.clone(), metrics);
            info!("Pool metrics updated successfully");
            Ok(true)
        } else {
            warn!("Pool metrics validation failed");
            Ok(false)
        }
    }

    fn execute_trade(&self, instructions: String) -> PyResult<String> {
        debug!("Processing trade instructions: {}", instructions);
        let instructions: Vec<Instruction> = serde_json::from_str(&instructions)
            .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(
                format!("Invalid trade instructions: {}", e)
            ))?;

        let compute_ix = ComputeBudgetInstruction::set_compute_unit_limit(
            self.config.trading.compute_limit
        );
        let priority_ix = ComputeBudgetInstruction::set_compute_unit_price(
            self.config.trading.priority_fee
        );

        let mut final_instructions = vec![compute_ix, priority_ix];
        final_instructions.extend(instructions);

        self.execute_trade_with_retry(&final_instructions)
    }

    fn get_status(&self) -> PyResult<String> {
        let pools = self.pool_metrics.blocking_read();
        let status = serde_json::json!({
            "active_pools": pools.len(),
            "wallet_balance": self.get_balance()?,
            "wallet_address": self.keypair.pubkey().to_string(),
            "position_size": self.config.trading.position_size,
            "max_position": self.config.trading.max_position,
            "gas_reserve": self.config.trading.gas_reserve,
            "compute_limit": self.config.trading.compute_limit,
            "priority_fee": self.config.trading.priority_fee,
            "primary_rpc": self.config.rpc.primary.endpoint,
            "secondary_rpc": self.config.rpc.secondary.endpoint
        });
        
        Ok(status.to_string())
    }
}

// Internal implementations
impl TradingCore {
    fn validate_pool_metrics(&self, metrics: &PoolMetrics) -> bool {
        metrics.market_cap >= self.config.safety.market_cap_min 
            && metrics.volume_24h >= self.config.trading.min_volume
            && metrics.liquidity >= self.config.trading.min_liquidity
            && metrics.liquidity <= self.config.trading.max_liquidity
            && (metrics.buy_pressure as f64 / metrics.sell_pressure.max(1) as f64) >= self.config.trading.min_bs_ratio
            && (!self.config.safety.mint_auth_required || metrics.mint_authority_revoked)
            && (!self.config.safety.lp_lock_check || metrics.liquidity_locked_pct >= self.config.trading.liquidity_lock_min)
    }

    fn execute_trade_with_retry(&self, instructions: &[Instruction]) -> PyResult<String> {
        // Try primary RPC
        for retry in 0..self.config.rpc.primary.retry_count {
            match self.try_execute_trade(instructions) {
                Ok(sig) => {
                    info!("Trade executed on primary RPC: {}", sig);
                    return Ok(sig);
                }
                Err(e) => {
                    error!("Primary RPC trade failed (attempt {}/{}): {:?}", 
                        retry + 1, self.config.rpc.primary.retry_count, e);
                    std::thread::sleep(Duration::from_millis(100));
                }
            }
        }

        // Fallback to secondary RPC
        for retry in 0..self.config.rpc.secondary.retry_count {
            match self.try_execute_trade_secondary(instructions) {
                Ok(sig) => {
                    info!("Trade executed on secondary RPC: {}", sig);
                    return Ok(sig);
                }
                Err(e) => {
                    error!("Secondary RPC trade failed (attempt {}/{}): {:?}", 
                        retry + 1, self.config.rpc.secondary.retry_count, e);
                    std::thread::sleep(Duration::from_millis(100));
                }
            }
        }

        Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
            "Failed to execute trade after all retries"
        ))
    }

    fn try_execute_trade(&self, instructions: &[Instruction]) -> Result<String, ClientError> {
        let recent_blockhash = self.primary_rpc.get_latest_blockhash()?;
        let tx = Transaction::new_signed_with_payer(
            instructions,
            Some(&self.keypair.pubkey()),
            &[&self.keypair],
            recent_blockhash,
        );
        let signature = self.primary_rpc.send_and_confirm_transaction(&tx)?;
        Ok(signature.to_string())
    }

    fn try_execute_trade_secondary(&self, instructions: &[Instruction]) -> Result<String, ClientError> {
        let recent_blockhash = self.secondary_rpc.get_latest_blockhash()?;
        let tx = Transaction::new_signed_with_payer(
            instructions,
            Some(&self.keypair.pubkey()),
            &[&self.keypair],
            recent_blockhash,
        );
        let signature = self.secondary_rpc.send_and_confirm_transaction(&tx)?;
        Ok(signature.to_string())
    }
}

#[pymodule]
fn solana_rust_bot(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    m.add_class::<TradingCore>()?;
    Ok(())
} and include the key pair stuff from both files please to ensure my wallet and signer is working without a doubt please ??? and add maximum logging and write the full entire script in working formate please how it needs to be