use log::{info, warn};
use pyo3::{exceptions::PyValueError, prelude::*};
use pyo3_asyncio::tokio::future_into_py;
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::{
    commitment_config::{CommitmentConfig, CommitmentLevel},
    compute_budget::ComputeBudgetInstruction,
    instruction::Instruction,
    message::Message,
    pubkey::Pubkey,
    signature::{Keypair, Signer},
    transaction::Transaction,
};
use spl_associated_token_account::get_associated_token_address;
use spl_token;
use std::{env, str::FromStr, sync::Arc};
use base58::FromBase58;
use tokio::time::{sleep, Duration};
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};

// Constants for MEV optimization
const COMPUTE_UNITS: u32 = 50_000;
const PRIORITY_FEE: u64 = 750_000;

#[pyclass]
#[derive(Clone)]
pub struct TradeParams {
    #[pyo3(get, set)]
    pub accounts: Vec<String>,
    #[pyo3(get, set)]
    pub amount_in: Option<u64>,
    #[pyo3(get, set)]
    pub is_buy: bool,
    #[pyo3(get, set)]
    pub reuse_blockhash: bool,
    #[pyo3(get, set)]
    pub token_a_mint: String,
    #[pyo3(get, set)]
    pub token_b_mint: String,
    #[pyo3(get, set)]
    pub sell_all: bool,
    #[pyo3(get, set)]
    pub victim_data: Option<Vec<u8>>,
}

#[pyclass]
pub struct TradingCore {
    client: Arc<RpcClient>,
    keypair: Arc<Keypair>,
    active_trade: Arc<AtomicBool>,
    last_trade_time: Arc<AtomicU64>,
}

impl TradingCore {
    fn load_keypair() -> PyResult<Keypair> {
        let private_key = env::var("SOLANA_PRIVATE_KEY")
            .map_err(|_| PyValueError::new_err("SOLANA_PRIVATE_KEY not found in environment"))?;

        // Optional public key validation
        if let Ok(public_key) = env::var("SOLANA_PUBLIC_KEY") {
            let _pubkey = Pubkey::from_str(&public_key)
                .map_err(|e| PyValueError::new_err(format!("Invalid public key: {}", e)))?;
        }

        // Decode private key
        let secret_key_bytes = private_key
            .from_base58()
            .map_err(|e| PyValueError::new_err(format!("Invalid base58 encoding: {:?}", e)))?;

        match secret_key_bytes.len() {
            64 => Keypair::from_bytes(&secret_key_bytes)
                .map_err(|e| PyValueError::new_err(format!("Invalid 64-byte keypair: {}", e))),
            32 => {
                let mut full_keypair = [0u8; 64];
                full_keypair[..32].copy_from_slice(&secret_key_bytes);
                Keypair::from_bytes(&full_keypair)
                    .map_err(|e| PyValueError::new_err(format!("Invalid keypair from 32-byte secret: {}", e)))
            },
            len => Err(PyValueError::new_err(format!("Invalid key length: {} bytes", len)))
        }
    }

    async fn ensure_ata_exists(
        &self, 
        owner: &Pubkey, 
        mint: &Pubkey
    ) -> PyResult<Pubkey> {
        // For WSOL, use predefined account
        if let Ok(wsol_address) = env::var("WSOL_ADDRESS") {
            if mint.to_string() == wsol_address {
                if let Ok(wsol_account) = env::var("WSOL_TOKEN_ACCOUNT") {
                    let wsol_pubkey = Pubkey::from_str(&wsol_account)
                        .map_err(|e| PyValueError::new_err(format!("Invalid WSOL account: {}", e)))?;
                    return Ok(wsol_pubkey);
                }
            }
        }

        let ata = get_associated_token_address(owner, mint);
        
        match self.client.get_account(&ata).await {
            Ok(_) => {
                info!("ATA exists: {}", ata);
                Ok(ata)
            }
            Err(_) => {
                warn!("Creating ATA for mint: {}", mint);
                
                let ix = spl_associated_token_account::instruction::create_associated_token_account_idempotent(
                    &self.keypair.pubkey(),
                    owner,
                    mint,
                    &spl_token::ID
                );

                let blockhash = self.client.get_latest_blockhash().await
                    .map_err(|e| PyValueError::new_err(format!("Failed to get blockhash: {}", e)))?;

                let mut tx = Transaction::new_with_payer(&[ix], Some(&self.keypair.pubkey()));
                tx.sign(&[self.keypair.as_ref()], blockhash);

                match self.client.send_transaction_with_config(
                    &tx,
                    solana_client::rpc_config::RpcSendTransactionConfig {
                        skip_preflight: true,
                        preflight_commitment: Some(CommitmentLevel::Confirmed),
                        encoding: None,
                        max_retries: Some(2),
                        min_context_slot: None,
                    },
                ).await {
                    Ok(_) => {
                        info!("ATA created successfully: {}", ata);
                        Ok(ata)
                    },
                    Err(e) => Err(PyValueError::new_err(format!("Failed to create ATA: {}", e)))
                }
            }
        }
    }fn create_swap_instruction(
        &self,
        program_id: &Pubkey,
        accounts: &[Pubkey],
        amount: u64,
        is_buy: bool,
        source_ata: Pubkey,
        destination_ata: Pubkey,
        victim_data: Option<&[u8]>,
    ) -> Instruction {
        let mut modified_accounts = accounts.to_vec();
        modified_accounts[1] = source_ata;
        modified_accounts[2] = destination_ata;

        let mut data = vec![if is_buy { 9u8 } else { 11u8 }];
        if is_buy && victim_data.is_some() {
            data.extend_from_slice(victim_data.unwrap());
        } else {
            data.extend_from_slice(&amount.to_le_bytes());
        }

        let account_metas = modified_accounts.iter().enumerate()
            .map(|(i, &pubkey)| {
                match i {
                    0 => solana_sdk::instruction::AccountMeta::new_readonly(pubkey, false),
                    1 | 2 => solana_sdk::instruction::AccountMeta::new(pubkey, false),
                    15..=17 => solana_sdk::instruction::AccountMeta::new(pubkey, true),
                    _ => solana_sdk::instruction::AccountMeta::new(pubkey, false),
                }
            })
            .collect();

        Instruction {
            program_id: *program_id,
            accounts: account_metas,
            data,
        }
    }

    async fn execute_trade(
        &self,
        params: &TradeParams,
    ) -> PyResult<String> {
        // Check if we're already in a trade
        if self.active_trade.load(Ordering::Relaxed) {
            return Err(PyValueError::new_err("Trade already in progress"));
        }

        // Check time since last trade
        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();
        let last_trade = self.last_trade_time.load(Ordering::Relaxed);
        
        if now - last_trade < 1 {  // Enforce 1 second between trades
            return Err(PyValueError::new_err("Too soon for new trade, respecting RPC limits"));
        }

        // Set active trade flag
        self.active_trade.store(true, Ordering::Relaxed);

        let result = async {
            let token_a_mint = Pubkey::from_str(&params.token_a_mint)?;
            let token_b_mint = Pubkey::from_str(&params.token_b_mint)?;

            let mut accounts = Vec::with_capacity(params.accounts.len());
            for acc in &params.accounts {
                accounts.push(Pubkey::from_str(acc)
                    .map_err(|e| PyValueError::new_err(format!("Invalid account: {} - {}", acc, e)))?);
            }

            // Handle different trade types
            if params.is_buy {
                // For new token buys
                let destination_ata = self.ensure_ata_exists(&self.keypair.pubkey(), &token_a_mint).await?;
                let source_ata = self.ensure_ata_exists(&self.keypair.pubkey(), &token_b_mint).await?;
                
                // Pause after ATA setup
                sleep(Duration::from_millis(100)).await;

                let mut instructions = vec![
                    ComputeBudgetInstruction::set_compute_unit_limit(COMPUTE_UNITS),
                    ComputeBudgetInstruction::set_compute_unit_price(PRIORITY_FEE),
                ];

                instructions.push(self.create_swap_instruction(
                    &accounts[0],
                    &accounts,
                    params.amount_in.unwrap(),
                    true,
                    source_ata,
                    destination_ata,
                    params.victim_data.as_deref(),
                ));

                let blockhash = self.client.get_latest_blockhash().await?;
                
                let message = Message::new_with_blockhash(
                    &instructions,
                    Some(&self.keypair.pubkey()),
                    &blockhash,
                );
                
                let mut tx = Transaction::new_unsigned(message);
                tx.try_sign(&[self.keypair.as_ref()], blockhash)?;

                let sig = self.client.send_transaction_with_config(
                    &tx,
                    solana_client::rpc_config::RpcSendTransactionConfig {
                        skip_preflight: true,
                        preflight_commitment: Some(CommitmentLevel::Confirmed),
                        encoding: None,
                        max_retries: Some(2),
                        min_context_slot: None,
                    },
                ).await?;

                Ok(sig.to_string())
            } else {
                // For exit trades
                sleep(Duration::from_millis(100)).await;
                
                let source_ata = get_associated_token_address(&self.keypair.pubkey(), &token_a_mint);
                let destination_ata = get_associated_token_address(&self.keypair.pubkey(), &token_b_mint);

                // Get full balance for exit
                let balance = self.client.get_token_account_balance(&source_ata)
                    .await?
                    .amount
                    .parse::<u64>()?;

                let mut instructions = vec![
                    ComputeBudgetInstruction::set_compute_unit_limit(COMPUTE_UNITS),
                    ComputeBudgetInstruction::set_compute_unit_price(PRIORITY_FEE),
                ];

                instructions.push(self.create_swap_instruction(
                    &accounts[0],
                    &accounts,
                    balance,
                    false,
                    source_ata,
                    destination_ata,
                    None,
                ));

                let blockhash = self.client.get_latest_blockhash().await?;
                
                let message = Message::new_with_blockhash(
                    &instructions,
                    Some(&self.keypair.pubkey()),
                    &blockhash,
                );
                
                let mut tx = Transaction::new_unsigned(message);
                tx.try_sign(&[self.keypair.as_ref()], blockhash)?;

                let sig = self.client.send_transaction_with_config(
                    &tx,
                    solana_client::rpc_config::RpcSendTransactionConfig {
                        skip_preflight: true,
                        preflight_commitment: Some(CommitmentLevel::Confirmed),
                        encoding: None,
                        max_retries: Some(2),
                        min_context_slot: None,
                    },
                ).await?;

                Ok(sig.to_string())
            }
        }.await;

        // Clear active trade flag and update last trade time
        self.active_trade.store(false, Ordering::Relaxed);
        self.last_trade_time.store(now, Ordering::Relaxed);

        result
    }
}

#[pymethods]
impl TradeParams {
    #[new]
    #[pyo3(signature = (
        accounts,
        amount_in=None,
        is_buy=false,
        reuse_blockhash=false,
        token_a_mint="".to_string(),
        token_b_mint="".to_string(),
        sell_all=false,
        victim_data=None,
    ))]
    fn new(
        accounts: Vec<String>,
        amount_in: Option<u64>,
        is_buy: bool,
        reuse_blockhash: bool,
        token_a_mint: String,
        token_b_mint: String,
        sell_all: bool,
        victim_data: Option<Vec<u8>>,
    ) -> Self {
        Self {
            accounts,
            amount_in,
            is_buy,
            reuse_blockhash,
            token_a_mint,
            token_b_mint,
            sell_all,
            victim_data,
        }
    }
}#[pymethods]
impl TradingCore {
    #[new]
    fn new(rpc_url: &str) -> PyResult<Self> {
        let keypair = Self::load_keypair()?;
        info!("Initialized with pubkey: {}", keypair.pubkey());
        
        Ok(Self {
            client: Arc::new(RpcClient::new_with_commitment(
                rpc_url.to_string(),
                CommitmentConfig::processed(),
            )),
            keypair: Arc::new(keypair),
        })
    }

    // Initial balance check - only called once at startup
    async fn check_initial_balances(&self) -> PyResult<()> {
        // Check SOL balance
        Self::check_rpc_limit().await?;
        let sol_balance = self.client.get_balance(&self.keypair.pubkey())
            .await
            .map_err(|e| PyValueError::new_err(format!("SOL balance check failed: {}", e)))?;
        info!("Initial SOL balance: {} SOL", (sol_balance as f64) / 1e9);

        // Check WSOL balance if account exists
        if let Ok(wsol_account) = env::var("WSOL_TOKEN_ACCOUNT") {
            Self::check_rpc_limit().await?;
            let wsol_pubkey = Pubkey::from_str(&wsol_account)
                .map_err(|e| PyValueError::new_err(format!("Invalid WSOL account: {}", e)))?;
            
            match self.client.get_token_account_balance(&wsol_pubkey).await {
                Ok(balance) => {
                    info!("Initial WSOL balance: {} WSOL", balance.amount);
                },
                Err(e) => {
                    warn!("Failed to get WSOL balance: {}", e);
                }
            }
        }

        Ok(())
    }

    fn execute_trade_py<'py>(&self, params: &TradeParams, py: Python<'py>) -> PyResult<&'py PyAny> {
        let params = params.clone();
        let self_clone = Self {
            client: self.client.clone(),
            keypair: self.keypair.clone(),
        };
        
        future_into_py(py, async move {
            // Convert accounts
            let mut accounts = Vec::with_capacity(params.accounts.len());
            for acc in &params.accounts {
                accounts.push(Pubkey::from_str(acc)
                    .map_err(|e| PyValueError::new_err(format!("Invalid account: {} - {}", acc, e)))?);
            }

            let token_a_mint = Pubkey::from_str(&params.token_a_mint)
                .map_err(|e| PyValueError::new_err(format!("Invalid Token A mint: {}", e)))?;
            let token_b_mint = Pubkey::from_str(&params.token_b_mint)
                .map_err(|e| PyValueError::new_err(format!("Invalid Token B mint: {}", e)))?;

            // Setup ATAs with RPC limit checking
            let (source_ata, destination_ata) = if params.is_buy {
                (
                    self_clone.ensure_ata_exists(&self_clone.keypair.pubkey(), &token_b_mint).await?,
                    self_clone.ensure_ata_exists(&self_clone.keypair.pubkey(), &token_a_mint).await?,
                )
            } else {
                (
                    self_clone.ensure_ata_exists(&self_clone.keypair.pubkey(), &token_a_mint).await?,
                    self_clone.ensure_ata_exists(&self_clone.keypair.pubkey(), &token_b_mint).await?,
                )
            };

            let mut instructions = vec![
                ComputeBudgetInstruction::set_compute_unit_limit(COMPUTE_UNITS),
                ComputeBudgetInstruction::set_compute_unit_price(PRIORITY_FEE),
            ];

            // Get amount (using existing ATA balance if selling all)
            let amount = match (params.amount_in, params.sell_all) {
                (Some(amount), _) => amount,
                (None, true) => {
                    Self::check_rpc_limit().await?;
                    self_clone.client.get_token_account_balance(&source_ata)
                        .await
                        .map_err(|e| PyValueError::new_err(format!("Balance check failed: {}", e)))?
                        .amount
                        .parse::<u64>()
                        .map_err(|e| PyValueError::new_err(format!("Invalid balance: {}", e)))?
                }
                _ => return Err(PyValueError::new_err("Missing trade amount"))?,
            };

            // Add swap instruction
            instructions.push(self_clone.create_swap_instruction(
                &accounts[0],
                &accounts,
                amount,
                params.is_buy,
                source_ata,
                destination_ata,
                params.victim_data.as_deref(),
            ));

            // Get blockhash with RPC limit check
            Self::check_rpc_limit().await?;
            let blockhash = self_clone.client.get_latest_blockhash().await
                .map_err(|e| PyValueError::new_err(format!("Blockhash error: {}", e)))?;
            
            let message = Message::new_with_blockhash(
                &instructions,
                Some(&self_clone.keypair.pubkey()),
                &blockhash,
            );
            
            let mut tx = Transaction::new_unsigned(message);
            tx.try_sign(&[self_clone.keypair.as_ref()], blockhash)
                .map_err(|e| PyValueError::new_err(format!("Signing failed: {:?}", e)))?;

            // Send transaction with RPC limit check
            Self::check_rpc_limit().await?;
            let signature = self_clone.client.send_transaction_with_config(
                &tx,
                solana_client::rpc_config::RpcSendTransactionConfig {
                    skip_preflight: true,
                    preflight_commitment: Some(CommitmentLevel::Confirmed),
                    encoding: None,
                    max_retries: Some(2),  // Limited retries to stay within RPC limits
                    min_context_slot: None,
                },
            )
            .await
            .map_err(|e| PyValueError::new_err(format!("Transaction failed: {}", e)))?;

            Ok(signature.to_string())
        })
    }

    #[pyo3(name = "get_sol_balance")]
    fn get_sol_balance_py<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> {
        let self_clone = Self {
            client: self.client.clone(),
            keypair: self.keypair.clone(),
        };
        
        future_into_py(py, async move {
            Self::check_rpc_limit().await?;
            let balance = self_clone.client.get_balance(&self_clone.keypair.pubkey())
                .await
                .map_err(|e| PyValueError::new_err(format!("Balance check failed: {}", e)))?;
            Ok((balance as f64) / 1e9)
        })
    }

    #[pyo3(name = "get_token_balance")]
    fn get_token_balance_py<'py>(&self, mint_address: String, py: Python<'py>) -> PyResult<&'py PyAny> {
        let self_clone = Self {
            client: self.client.clone(),
            keypair: self.keypair.clone(),
        };
        
        future_into_py(py, async move {
            let mint = Pubkey::from_str(&mint_address)
                .map_err(|e| PyValueError::new_err(format!("Invalid mint address: {}", e)))?;
            
            let ata = if mint.to_string() == env::var("WSOL_ADDRESS").unwrap_or_default() {
                Pubkey::from_str(&env::var("WSOL_TOKEN_ACCOUNT").unwrap_or_default())
                    .map_err(|e| PyValueError::new_err(format!("Invalid WSOL account: {}", e)))?
            } else {
                get_associated_token_address(&self_clone.keypair.pubkey(), &mint)
            };
            
            Self::check_rpc_limit().await?;
            let balance = self_clone.client.get_token_account_balance(&ata)
                .await
                .map_err(|e| PyValueError::new_err(format!("Balance check failed: {}", e)))?;
            
            balance.amount.parse::<f64>()
                .map_err(|e| PyValueError::new_err(format!("Invalid balance format: {}", e)))
        })
    }
}

#[pymodule]
fn solana_rust_bot(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    pyo3_log::init();
    m.add_class::<TradeParams>()?;
    m.add_class::<TradingCore>()?;
    Ok(())
}  Compiling solana_rust_bot v0.1.0 (C:\solana_rust_bot)
error: `async fn` is not yet supported for Python functions.

       Additional crates such as `pyo3-asyncio` can be used to integrate async Rust and Python. For more information, see https://github.com/PyO3/pyo3/issues/1632
   --> src\lib.rs:373:5
    |
373 |     async fn check_initial_balances(&self) -> PyResult<()> {
    |     ^^^^^

error: cannot find attribute `pyo3` in this scope
   --> src\lib.rs:514:7
    |
514 |     #[pyo3(name = "get_token_balance")]
    |       ^^^^
    |
    = note: `pyo3` is in scope, but it is a crate, not an attribute

error: cannot find attribute `pyo3` in this scope
   --> src\lib.rs:498:7
    |
498 |     #[pyo3(name = "get_sol_balance")]
    |       ^^^^
    |
    = note: `pyo3` is in scope, but it is a crate, not an attribute

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:204:70
    |
204 |             let token_a_mint = Pubkey::from_str(&params.token_a_mint)?;
    |                                                                      ^ the trait `From<ParsePubkeyError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, ParsePubkeyError>>`

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:205:70
    |
205 |             let token_b_mint = Pubkey::from_str(&params.token_b_mint)?;
    |                                                                      ^ the trait `From<ParsePubkeyError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, ParsePubkeyError>>`

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:237:73
    |
237 |                 let blockhash = self.client.get_latest_blockhash().await?;
    |                                                                         ^ the trait `From<solana_client::client_error::ClientError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, solana_client::client_error::ClientError>>`

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:246:65
    |
246 |                 tx.try_sign(&[self.keypair.as_ref()], blockhash)?;
    |                                                                 ^ the trait `From<solana_sdk::signature::SignerError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, solana_sdk::signature::SignerError>>`      

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:257:24
    |
257 |                 ).await?;
    |                        ^ the trait `From<solana_client::client_error::ClientError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, solana_client::client_error::ClientError>>`

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:269:27
    |
269 |                     .await?
    |                           ^ the trait `From<solana_client::client_error::ClientError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, solana_client::client_error::ClientError>>`

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:288:73
    |
288 |                 let blockhash = self.client.get_latest_blockhash().await?;
    |                                                                         ^ the trait `From<solana_client::client_error::ClientError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, solana_client::client_error::ClientError>>`

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:297:65
    |
297 |                 tx.try_sign(&[self.keypair.as_ref()], blockhash)?;
    |                                                                 ^ the trait `From<solana_sdk::signature::SignerError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, solana_sdk::signature::SignerError>>`      

error[E0277]: `?` couldn't convert the error to `PyErr`
   --> src\lib.rs:308:24
    |
308 |                 ).await?;
    |                        ^ the trait `From<solana_client::client_error::ClientError>` is not implemented for `PyErr`
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              `PyErr` implements `From<&CancelledError>`
              `PyErr` implements `From<&IncompleteReadError>`
              `PyErr` implements `From<&InvalidStateError>`
              `PyErr` implements `From<&LimitOverrunError>`
              `PyErr` implements `From<&PanicException>`
              `PyErr` implements `From<&PyArithmeticError>`
              `PyErr` implements `From<&PyAssertionError>`
              `PyErr` implements `From<&PyAttributeError>`
            and 88 others
    = note: required for `Result<String, PyErr>` to implement `FromResidual<Result<std::convert::Infallible, solana_client::client_error::ClientError>>`

error[E0599]: no function or associated item named `check_rpc_limit` found for struct `TradingCore` in the current scope
   --> src\lib.rs:375:15
    |
48  | pub struct TradingCore {
    | ---------------------- function or associated item `check_rpc_limit` not found for this struct
...
375 |         Self::check_rpc_limit().await?;
    |               ^^^^^^^^^^^^^^^ function or associated item not found in `TradingCore`
    |
note: if you're trying to build a new `TradingCore`, consider using `TradingCore::new` which returns `Result<TradingCore, PyErr>`
   --> src\lib.rs:359:5
    |
359 |     fn new(rpc_url: &str) -> PyResult<Self> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0599]: no function or associated item named `check_rpc_limit` found for struct `TradingCore` in the current scope
   --> src\lib.rs:383:19
    |
48  | pub struct TradingCore {
    | ---------------------- function or associated item `check_rpc_limit` not found for this struct
...
383 |             Self::check_rpc_limit().await?;
    |                   ^^^^^^^^^^^^^^^ function or associated item not found in `TradingCore`
    |
note: if you're trying to build a new `TradingCore`, consider using `TradingCore::new` which returns `Result<TradingCore, PyErr>`
   --> src\lib.rs:359:5
    |
359 |     fn new(rpc_url: &str) -> PyResult<Self> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0063]: missing fields `active_trade` and `last_trade_time` in initializer of `TradingCore`
   --> src\lib.rs:363:12
    |
363 |         Ok(Self {
    |            ^^^^ missing `active_trade` and `last_trade_time`

error[E0063]: missing fields `active_trade` and `last_trade_time` in initializer of `TradingCore`
   --> src\lib.rs:402:26
    |
402 |         let self_clone = Self {
    |                          ^^^^ missing `active_trade` and `last_trade_time`

error[E0599]: no function or associated item named `check_rpc_limit` found for struct `TradingCore` in the current scope
   --> src\lib.rs:442:27
    |
48  | pub struct TradingCore {
    | ---------------------- function or associated item `check_rpc_limit` not found for this struct
...
442 |                     Self::check_rpc_limit().await?;
    |                           ^^^^^^^^^^^^^^^ function or associated item not found in `TradingCore`
    |
note: if you're trying to build a new `TradingCore`, consider using `TradingCore::new` which returns `Result<TradingCore, PyErr>`
   --> src\lib.rs:359:5
    |
359 |     fn new(rpc_url: &str) -> PyResult<Self> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0599]: no function or associated item named `check_rpc_limit` found for struct `TradingCore` in the current scope
   --> src\lib.rs:465:19
    |
48  | pub struct TradingCore {
    | ---------------------- function or associated item `check_rpc_limit` not found for this struct
...
465 |             Self::check_rpc_limit().await?;
    |                   ^^^^^^^^^^^^^^^ function or associated item not found in `TradingCore`
    |
note: if you're trying to build a new `TradingCore`, consider using `TradingCore::new` which returns `Result<TradingCore, PyErr>`
   --> src\lib.rs:359:5
    |
359 |     fn new(rpc_url: &str) -> PyResult<Self> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0599]: no function or associated item named `check_rpc_limit` found for struct `TradingCore` in the current scope
   --> src\lib.rs:480:19
    |
48  | pub struct TradingCore {
    | ---------------------- function or associated item `check_rpc_limit` not found for this struct
...
480 |             Self::check_rpc_limit().await?;
    |                   ^^^^^^^^^^^^^^^ function or associated item not found in `TradingCore`
    |
note: if you're trying to build a new `TradingCore`, consider using `TradingCore::new` which returns `Result<TradingCore, PyErr>`
   --> src\lib.rs:359:5
    |
359 |     fn new(rpc_url: &str) -> PyResult<Self> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0063]: missing fields `active_trade` and `last_trade_time` in initializer of `TradingCore`
   --> src\lib.rs:500:26
    |
500 |         let self_clone = Self {
    |                          ^^^^ missing `active_trade` and `last_trade_time`

error[E0599]: no function or associated item named `check_rpc_limit` found for struct `TradingCore` in the current scope
   --> src\lib.rs:506:19
    |
48  | pub struct TradingCore {
    | ---------------------- function or associated item `check_rpc_limit` not found for this struct
...
506 |             Self::check_rpc_limit().await?;
    |                   ^^^^^^^^^^^^^^^ function or associated item not found in `TradingCore`
    |
note: if you're trying to build a new `TradingCore`, consider using `TradingCore::new` which returns `Result<TradingCore, PyErr>`
   --> src\lib.rs:359:5
    |
359 |     fn new(rpc_url: &str) -> PyResult<Self> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0063]: missing fields `active_trade` and `last_trade_time` in initializer of `TradingCore`
   --> src\lib.rs:516:26
    |
516 |         let self_clone = Self {
    |                          ^^^^ missing `active_trade` and `last_trade_time`

error[E0599]: no function or associated item named `check_rpc_limit` found for struct `TradingCore` in the current scope
   --> src\lib.rs:532:19
    |
48  | pub struct TradingCore {
    | ---------------------- function or associated item `check_rpc_limit` not found for this struct
...
532 |             Self::check_rpc_limit().await?;
    |                   ^^^^^^^^^^^^^^^ function or associated item not found in `TradingCore`
    |
note: if you're trying to build a new `TradingCore`, consider using `TradingCore::new` which returns `Result<TradingCore, PyErr>`
   --> src\lib.rs:359:5
    |
359 |     fn new(rpc_url: &str) -> PyResult<Self> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Some errors have detailed explanations: E0063, E0277, E0599.
For more information about an error, try `rustc --explain E0063`.
error: could not compile `solana_rust_bot` (lib) due to 23 previous errors
2025-02-17T05:54:14.526018Z  INFO build_wheels: maturin::build_context: close time.busy=887ms time.idle=1.20µs
💥 maturin failed
  Caused by: Failed to build a native library through cargo
  Caused by: Cargo build finished with "exit code: 101": `"cargo" "rustc" "--jobs" "16" "--message-format" "json-render-diagnostics" "--manifest-path" "C:\\solana_rust_bot\\Cargo.toml" "--release" "--lib" "--crate-type" "cdylib"`