Repository: cutupdev/Solana-Raydium-Sniper-Bot Branch: main Commit: 829594cb9c47 Files: 17 Total size: 25.9 KB Directory structure: gitextract_3q5qaqtw/ ├── .gitignore ├── Cargo.toml ├── README.md ├── src/ │ ├── common/ │ │ ├── logger.rs │ │ ├── mod.rs │ │ └── utils.rs │ ├── core/ │ │ ├── mod.rs │ │ ├── token.rs │ │ └── tx.rs │ ├── dex/ │ │ ├── mod.rs │ │ └── raydium.rs │ ├── engine/ │ │ ├── mod.rs │ │ └── monitor/ │ │ └── mod.rs │ ├── lib.rs │ ├── main.rs │ └── services/ │ └── mod.rs └── trial/ └── blacklist.txt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .env target ================================================ FILE: Cargo.toml ================================================ [package] name = "raydium-sniper-bot" version = "0.1.0" edition = "2021" ================================================ FILE: README.md ================================================ # Solana Raydium Sniper Bot This bot fetches to new Raydium pools and buys as soon as possible. If RPC or node is good, it commonly buy tokens before token is availabel on Raydium UI, can buy tokens than the others. It's free, basic version, and I have advanced version for it. I updated codebase with Rust to boost speed and performance. Feel free to contact with me to get advanced version. [Telegram: https://t.me/DevCutup, Whatsapp: https://wa.me/13137423660]. This is just version to give vision about raydium dex and sniper bot. ## Features ### Speed and Efficiency - **Lightning-Quick Transactions**: Leveraging Rust's exceptional performance, our bot allows you to snipe new tokens almost instantly. Say goodbye to delays and seize opportunities as they arise! ### Safety First - **Robust Security**: Rust's safety guarantees minimize bugs and vulnerabilities, ensuring your trading activities are secure. Trade with confidence and peace of mind. ### Multiple gRPC Connections - **Stay Updated**: Effortlessly connect to top Solana data providers like **Helius** and **Yellowstone** through multiple gRPC connections. Get real-time updates and make informed trading decisions. ### User-Friendly Interface - **Intuitive Design**: My sniper bot features a clean and accessible interface, making it easy for users of all experience levels to navigate. Start trading in no time! ## Advanced Features - **jito-confirm**: Engage in low-latency transactions on platforms like Raydium and Pumpfun. - **jito-bundle**: Bundle buy/sell actions with up to **20 wallets** in Raydium/Pumpfun, enhancing your trading strategy and flexibility. --- ## Directory Structure ``` src/ ├── core/ │ ├── token.rs # Token definitions and handling │ └── tx.rs # Transaction handling | └── mod.rs # mod file | ├── engine/ │ ├── swap.rs # Token swap(buy/sell) functionalities in various Dexs │ └── monitor # New token monitoring(and parse tx) in Dexs using geyser rpc, and normal rpc │ └── helius.rs # Helius gRpc for tx listen and parse. │ └── yellowstone.rs # Yellowstone gRpc for tx listen and parse. | └── mod.rs # mod file | ├── dex/ │ ├── raydium.rs # Raydium | └── mod.rs # mod file │ ├── services/ │ ├── jito.rs # Jito service provides ultra-fast transaction confirmation │ ├── nozomi.rs # Jito service provides ultra-fast transaction confirmation │ ├── zeroslot.rs # Jito service provides ultra-fast transaction confirmation │ └── nextblock.rs # NextBlock service provides the ultra-fast transaction confirmation in unique way | └── mod.rs # mod file | ├── common/ │ ├── logger.rs # Logs to be clean and convenient to monitor. │ └── utils.rs # Utility functions used across the project | └── mod.rs # mod file │ ├── lib.rs └── main.rs ``` --- ### Setup 1. Environment Variables Settings ```plaintext PRIVATE_KEY= # your wallet priv_key RPC_API_KEY= #your helius rpc api-key (Please use premium version that has Geyser Enhanced Websocket) SLIPPAGE=10 JITO_BLOCK_ENGINE_URL=https://ny.mainnet.block-engine.jito.wtf JITO_TIP_VALUE=0.00927 TIME_EXCEED=60 # seconds; time limit for volume non-increasing TOKEN_AMOUNT=0.0000001 # token amount to purchase TP=3 #3 times SL=0.5 #50 percentage ``` 2. Add the wallet address you want to block on a new line and save the file. ``` 3NQmnSXfGqtgxFTZ82gS7Pwt2btn3fEPb6EiX5ax5bvr ``` 3. Run `trial/raydium-sniper.exe`. ### Test Result(Same Block) - Detect: https://solscan.io/tx/5o7ajnZ9CRf7FBYEvydu8vapJJDWtKCvRFiTUBmbeu2FmmDhAQQy3c9YFFhpTucr2SZcrf2aUsDanEVjYgwN9kBc - Bought: https://solscan.io/tx/3vgim3MwJsdtahXqfW2DrzTAWpVQ8EUTed2cjzHuqxSfUpfp72mgzZhiVosWaCUHdqJTDHpQaYh5xN7rkHGmzqWv - Dexscreener: https://dexscreener.com/solana/A1zZXCq2DmqwVD4fLDzmgQ3ceY6LQnMBVokejqnHpump ### Contact Information - Telegram: https://t.me/DevCutup - Whatsapp: https://wa.me/13137423660 - Twitter: https://x.com/devcutup ================================================ FILE: src/common/logger.rs ================================================ use chrono::Local; const LOG_LEVEL: &str = "LOG"; pub struct Logger { prefix: String, date_format: String, } impl Logger { // Constructor function to create a new Logger instance pub fn new(prefix: String) -> Self { Logger { prefix, date_format: String::from("%Y-%m-%d %H:%M:%S"), } } // Method to log a message with a prefix pub fn log(&self, message: String) -> String { let log = format!("{} {}", self.prefix_with_date(), message); println!("{}", log); log } pub fn debug(&self, message: String) -> String { let log = format!("{} [{}] {}", self.prefix_with_date(), "DEBUG", message); if LogLevel::new().is_debug() { println!("{}", log); } log } pub fn error(&self, message: String) -> String { let log = format!("{} [{}] {}", self.prefix_with_date(), "ERROR", message); println!("{}", log); log } fn prefix_with_date(&self) -> String { let date = Local::now(); format!( "[{}] {}", date.format(self.date_format.as_str()), self.prefix ) } } struct LogLevel<'a> { level: &'a str, } impl LogLevel<'_> { fn new() -> Self { let level = LOG_LEVEL; LogLevel { level } } fn is_debug(&self) -> bool { self.level.to_lowercase().eq("debug") } } ================================================ FILE: src/common/mod.rs ================================================ pub mod logger; pub mod utils; ================================================ FILE: src/common/utils.rs ================================================ use anyhow::Result; use solana_sdk::{commitment_config::CommitmentConfig, signature::Keypair}; use std::{env, sync::Arc}; #[derive(Clone)] pub struct AppState { pub rpc_client: Arc, pub rpc_nonblocking_client: Arc, pub wallet: Arc, } pub fn import_env_var(key: &str) -> String { env::var(key).unwrap_or_else(|_| panic!("Environment variable {} is not set", key)) } pub fn create_rpc_client() -> Result> { let rpc_https = import_env_var("RPC_HTTPS"); let rpc_client = solana_client::rpc_client::RpcClient::new_with_commitment( rpc_https, CommitmentConfig::processed(), ); Ok(Arc::new(rpc_client)) } pub async fn create_nonblocking_rpc_client( ) -> Result> { let rpc_https = import_env_var("RPC_HTTPS"); let rpc_client = solana_client::nonblocking::rpc_client::RpcClient::new_with_commitment( rpc_https, CommitmentConfig::processed(), ); Ok(Arc::new(rpc_client)) } pub fn import_wallet() -> Result> { let priv_key = import_env_var("PRIVATE_KEY"); let wallet: Keypair = Keypair::from_base58_string(priv_key.as_str()); Ok(Arc::new(wallet)) } ================================================ FILE: src/core/mod.rs ================================================ pub mod token; pub mod tx; ================================================ FILE: src/core/token.rs ================================================ use solana_sdk::{pubkey::Pubkey, signature::Keypair}; use spl_token_2022::{ extension::StateWithExtensionsOwned, state::{Account, Mint}, }; use spl_token_client::{ client::{ProgramClient, ProgramRpcClient, ProgramRpcClientSendTransaction}, token::{Token, TokenError, TokenResult}, }; use std::sync::Arc; pub fn get_associated_token_address( client: Arc, keypair: Arc, address: &Pubkey, owner: &Pubkey, ) -> Pubkey { let token_client = Token::new( Arc::new(ProgramRpcClient::new( client.clone(), ProgramRpcClientSendTransaction, )), &spl_token::ID, address, None, Arc::new(Keypair::from_bytes(&keypair.to_bytes()).expect("failed to copy keypair")), ); token_client.get_associated_token_address(owner) } pub async fn get_account_info( client: Arc, _keypair: Arc, address: &Pubkey, account: &Pubkey, ) -> TokenResult> { let program_client = Arc::new(ProgramRpcClient::new( client.clone(), ProgramRpcClientSendTransaction, )); let account = program_client .get_account(*account) .await .map_err(TokenError::Client)? .ok_or(TokenError::AccountNotFound) .inspect_err(|err| println!("get_account_info: {} {}: mint {}", account, err, address))?; if account.owner != spl_token::ID { return Err(TokenError::AccountInvalidOwner); } let account = StateWithExtensionsOwned::::unpack(account.data)?; if account.base.mint != *address { return Err(TokenError::AccountInvalidMint); } Ok(account) } pub async fn get_mint_info( client: Arc, _keypair: Arc, address: &Pubkey, ) -> TokenResult> { let program_client = Arc::new(ProgramRpcClient::new( client.clone(), ProgramRpcClientSendTransaction, )); let account = program_client .get_account(*address) .await .map_err(TokenError::Client)? .ok_or(TokenError::AccountNotFound) .inspect_err(|err| println!("{} {}: mint {}", address, err, address))?; if account.owner != spl_token::ID { return Err(TokenError::AccountInvalidOwner); } let mint_result = StateWithExtensionsOwned::::unpack(account.data).map_err(Into::into); let decimals: Option = None; if let (Ok(mint), Some(decimals)) = (&mint_result, decimals) { if decimals != mint.base.decimals { return Err(TokenError::InvalidDecimals); } } mint_result } ================================================ FILE: src/core/tx.rs ================================================ use std::{env, sync::Arc, time::Duration}; use anyhow::Result; use jito_json_rpc_client::jsonrpc_client::rpc_client::RpcClient as JitoRpcClient; use solana_client::rpc_client::RpcClient; use solana_sdk::{ instruction::Instruction, signature::Keypair, signer::Signer, system_transaction, transaction::{Transaction, VersionedTransaction}, }; use spl_token::ui_amount_to_amount; use std::str::FromStr; use tokio::time::Instant; use crate::{ common::logger::Logger, services::jito::{self, get_tip_account, get_tip_value, wait_for_bundle_confirmation}, }; // prioritization fee = UNIT_PRICE * UNIT_LIMIT fn get_unit_price() -> u64 { env::var("UNIT_PRICE") .ok() .and_then(|v| u64::from_str(&v).ok()) .unwrap_or(1) } fn get_unit_limit() -> u32 { env::var("UNIT_LIMIT") .ok() .and_then(|v| u32::from_str(&v).ok()) .unwrap_or(300_000) } pub async fn new_signed_and_send( client: &RpcClient, keypair: &Keypair, mut instructions: Vec, use_jito: bool, logger: &Logger, ) -> Result> { let unit_price = get_unit_price(); let unit_limit = get_unit_limit(); // If not using Jito, manually set the compute unit price and limit if !use_jito { let modify_compute_units = solana_sdk::compute_budget::ComputeBudgetInstruction::set_compute_unit_price( unit_price, ); let add_priority_fee = solana_sdk::compute_budget::ComputeBudgetInstruction::set_compute_unit_limit( unit_limit, ); instructions.insert(0, modify_compute_units); instructions.insert(1, add_priority_fee); } // send init tx let recent_blockhash = client.get_latest_blockhash()?; let txn = Transaction::new_signed_with_payer( &instructions, Some(&keypair.pubkey()), &vec![keypair], recent_blockhash, ); let start_time = Instant::now(); let mut txs = vec![]; if use_jito { // jito let tip_account = get_tip_account().await?; let jito_client = Arc::new(JitoRpcClient::new(format!( "{}/api/v1/bundles", *jito::BLOCK_ENGINE_URL ))); // jito tip, the upper limit is 0.1 let mut tip = get_tip_value().await?; tip = tip.min(0.1); let tip_lamports = ui_amount_to_amount(tip, spl_token::native_mint::DECIMALS); logger.log(format!( "tip account: {}, tip(sol): {}, lamports: {}", tip_account, tip, tip_lamports )); // tip tx let bundle: Vec = vec![ VersionedTransaction::from(txn), VersionedTransaction::from(system_transaction::transfer( keypair, &tip_account, tip_lamports, recent_blockhash, )), ]; let bundle_id = jito_client.send_bundle(&bundle).await?; logger.log(format!("bundle_id: {}", bundle_id)); txs = wait_for_bundle_confirmation( move |id: String| { let client = Arc::clone(&jito_client); async move { let response = client.get_bundle_statuses(&[id]).await; let statuses = response.inspect_err(|err| { logger.log(format!("Error fetching bundle status: {:?}", err)); })?; Ok(statuses.value) } }, bundle_id, Duration::from_millis(1000), Duration::from_secs(10), ) .await?; } else { let sig = common::rpc::send_txn(client, &txn, true)?; logger.log(format!("signature: {:#?}", sig)); txs.push(sig.to_string()); } logger.log(format!("tx ellapsed: {:?}", start_time.elapsed())); Ok(txs) } ================================================ FILE: src/dex/mod.rs ================================================ pub mod pump_fun; pub mod raydium; pub mod meteora; pub mod orca; ================================================ FILE: src/dex/raydium.rs ================================================ use crate::{ common::{ logger::Logger, utils::{import_env_var, SwapConfig}, }, core::{ token::{get_account_info, get_associated_token_address, get_mint_info}, tx, }, engine::swap::{SwapDirection, SwapInType}, }; use amm_cli::AmmSwapInfoResult; use anyhow::{anyhow, Context, Result}; use bytemuck; use raydium_amm::state::{AmmInfo, Loadable}; use reqwest::Proxy; use serde::Deserialize; use solana_client::rpc_filter::{Memcmp, RpcFilterType}; use solana_sdk::{ instruction::Instruction, program_pack::Pack, pubkey::Pubkey, signature::Keypair, signer::Signer, system_instruction, }; use spl_associated_token_account::instruction::create_associated_token_account; use spl_token::{amount_to_ui_amount, state::Account, ui_amount_to_amount}; use spl_token_client::token::TokenError; use std::{str::FromStr, sync::Arc}; pub const AMM_PROGRAM: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"; #[derive(Debug, Deserialize)] pub struct PoolInfo { pub success: bool, pub data: PoolData, } #[derive(Debug, Deserialize)] pub struct PoolData { // pub count: u32, pub data: Vec, } impl PoolData { pub fn get_pool(&self) -> Option { self.data.first().cloned() } } #[derive(Debug, Deserialize, Clone)] pub struct Pool { pub id: String, #[serde(rename = "programId")] pub program_id: String, #[serde(rename = "mintA")] pub mint_a: Mint, #[serde(rename = "mintB")] pub mint_b: Mint, #[serde(rename = "marketId")] pub market_id: String, } #[derive(Debug, Deserialize, Clone)] pub struct Mint { pub address: String, pub symbol: String, pub name: String, pub decimals: u8, } pub struct Raydium { pub rpc_nonblocking_client: Arc, pub rpc_client: Option>, pub keypair: Arc, pub pool_id: Option, } impl Raydium { pub fn new( rpc_nonblocking_client: Arc, rpc_client: Arc, keypair: Arc, ) -> Self { Self { rpc_nonblocking_client, keypair, rpc_client: Some(rpc_client), pool_id: None, } } pub async fn swap( &self, swap_config: SwapConfig, amm_pool_id: Pubkey, pool_state: AmmInfo, ) -> Result> { let logger = Logger::new(format!( "[SWAP IN RAYDIUM]({}) => ", chrono::Utc::now().timestamp() )); let slippage_bps = swap_config.slippage * 100; let owner = self.keypair.pubkey(); let program_id = spl_token::ID; let native_mint = spl_token::native_mint::ID; let mint = pool_state.coin_vault_mint; let (token_in, token_out, user_input_token, swap_base_in) = match ( swap_config.swap_direction.clone(), pool_state.coin_vault_mint == native_mint, ) { (SwapDirection::Buy, true) => (native_mint, mint, pool_state.coin_vault, true), (SwapDirection::Buy, false) => (native_mint, mint, pool_state.pc_vault, true), (SwapDirection::Sell, true) => (mint, native_mint, pool_state.pc_vault, true), (SwapDirection::Sell, false) => (mint, native_mint, pool_state.coin_vault, true), }; logger.log(format!( "token_in:{}, token_out:{}, user_input_token:{}, swap_base_in:{}", token_in, token_out, user_input_token, swap_base_in )); let in_ata = get_associated_token_address( self.rpc_nonblocking_client.clone(), self.keypair.clone(), &token_in, &owner, ); let out_ata = get_associated_token_address( self.rpc_nonblocking_client.clone(), self.keypair.clone(), &token_out, &owner, ); let mut create_instruction = None; let mut close_instruction = None; tx::new_signed_and_send( &client, &self.keypair, instructions, swap_config.use_jito, &logger, ) .await } } pub fn amm_swap( amm_program: &Pubkey, result: AmmSwapInfoResult, user_owner: &Pubkey, user_source: &Pubkey, user_destination: &Pubkey, amount_specified: u64, other_amount_threshold: u64, swap_base_in: bool, ) -> Result { let swap_instruction = if swap_base_in { raydium_amm::instruction::swap_base_in( amm_program, &result.pool_id, &result.amm_authority, &result.amm_open_orders, &result.amm_coin_vault, &result.amm_pc_vault, &result.market_program, &result.market, &result.market_bids, &result.market_asks, &result.market_event_queue, &result.market_coin_vault, &result.market_pc_vault, &result.market_vault_signer, user_source, user_destination, user_owner, amount_specified, other_amount_threshold, )? } else { raydium_amm::instruction::swap_base_out( amm_program, &result.pool_id, &result.amm_authority, &result.amm_open_orders, &result.amm_coin_vault, &result.amm_pc_vault, &result.market_program, &result.market, &result.market_bids, &result.market_asks, &result.market_event_queue, &result.market_coin_vault, &result.market_pc_vault, &result.market_vault_signer, user_source, user_destination, user_owner, other_amount_threshold, amount_specified, )? }; Ok(swap_instruction) } pub async fn get_pool_state( rpc_client: Arc, pool_id: Option<&str>, mint: Option<&str>, logger: &Logger, ) -> Result<(Pubkey, AmmInfo)> { if let Some(pool_id) = pool_id { logger.log(format!("[FIND POOL STATE BY pool_id]: {}", pool_id)); let amm_pool_id = Pubkey::from_str(pool_id)?; let pool_data = common::rpc::get_account(&rpc_client, &amm_pool_id)? .ok_or(anyhow!("NotFoundPool: pool state not found"))?; let pool_state: &AmmInfo = bytemuck::from_bytes(&pool_data[0..core::mem::size_of::()]); Ok((amm_pool_id, *pool_state)) } else if let Some(mint) = mint { // find pool by mint via rpc if let Ok(pool_state) = get_pool_state_by_mint(rpc_client.clone(), mint, logger).await { return Ok(pool_state); } // find pool by mint via raydium api let pool_data = get_pool_info(&spl_token::native_mint::ID.to_string(), mint).await; if let Ok(pool_data) = pool_data { let pool = pool_data .get_pool() .ok_or(anyhow!("NotFoundPool: pool not found in raydium api"))?; let amm_pool_id = Pubkey::from_str(&pool.id)?; logger.log(format!("[FIND POOL STATE BY raydium api]: {}", amm_pool_id)); let pool_data = common::rpc::get_account(&rpc_client, &amm_pool_id)? .ok_or(anyhow!("NotFoundPool: pool state not found"))?; let pool_state: &AmmInfo = bytemuck::from_bytes(&pool_data[0..core::mem::size_of::()]); return Ok((amm_pool_id, *pool_state)); } Err(anyhow!("NotFoundPool: pool state not found")) } else { Err(anyhow!("NotFoundPool: pool state not found")) } } pub async fn get_pool_state_by_mint( rpc_client: Arc, mint: &str, logger: &Logger, ) -> Result<(Pubkey, AmmInfo)> { logger.log(format!("[FIND POOL STATE BY mint]: {}", mint)); let pairs = vec![ // pump pool ( Some(spl_token::native_mint::ID), Pubkey::from_str(mint).ok(), ), // general pool ( Pubkey::from_str(mint).ok(), Some(spl_token::native_mint::ID), ), ]; let pool_len = core::mem::size_of::() as u64; let amm_program = Pubkey::from_str(AMM_PROGRAM)?; // Find matching AMM pool from mint pairs by filter let mut found_pools = None; for (coin_mint, pc_mint) in pairs { logger.log(format!( "get_pool_state_by_mint filter: coin_mint: {:?}, pc_mint: {:?}", coin_mint, pc_mint )); let filters = match (coin_mint, pc_mint) { (None, None) => Some(vec![RpcFilterType::DataSize(pool_len)]), (Some(coin_mint), None) => Some(vec![ RpcFilterType::Memcmp(Memcmp::new_base58_encoded(400, &coin_mint.to_bytes())), RpcFilterType::DataSize(pool_len), ]), (None, Some(pc_mint)) => Some(vec![ RpcFilterType::Memcmp(Memcmp::new_base58_encoded(432, &pc_mint.to_bytes())), RpcFilterType::DataSize(pool_len), ]), (Some(coin_mint), Some(pc_mint)) => Some(vec![ RpcFilterType::Memcmp(Memcmp::new_base58_encoded(400, &coin_mint.to_bytes())), RpcFilterType::Memcmp(Memcmp::new_base58_encoded(432, &pc_mint.to_bytes())), RpcFilterType::DataSize(pool_len), ]), }; let pools = common::rpc::get_program_accounts_with_filters(&rpc_client, amm_program, filters) .unwrap(); if !pools.is_empty() { found_pools = Some(pools); break; } } match found_pools { Some(pools) => { let pool = &pools[0]; let pool_state = AmmInfo::load_from_bytes(&pools[0].1.data)?; Ok((pool.0, *pool_state)) } None => Err(anyhow!("NotFoundPool: pool state not found")), } } // get pool info // https://api-v3.raydium.io/pools/info/mint?mint1=So11111111111111111111111111111111111111112&mint2=EzM2d8JVpzfhV7km3tUsR1U1S4xwkrPnWkM4QFeTpump&poolType=standard&poolSortField=default&sortType=desc&pageSize=10&page=1 pub async fn get_pool_info(mint1: &str, mint2: &str) -> Result { let mut client_builder = reqwest::Client::builder(); let http_proxy = import_env_var("HTTP_PROXY"); let proxy = Proxy::all(http_proxy)?; client_builder = client_builder.proxy(proxy); let client = client_builder.build()?; let result = client .get("https://api-v3.raydium.io/pools/info/mint") .query(&[ ("mint1", mint1), ("mint2", mint2), ("poolType", "standard"), ("poolSortField", "default"), ("sortType", "desc"), ("pageSize", "1"), ("page", "1"), ]) .send() .await? .json::() .await .context("Failed to parse pool info JSON")?; Ok(result.data) } ================================================ FILE: src/engine/mod.rs ================================================ pub mod monitor; pub mod swap; ================================================ FILE: src/engine/monitor/mod.rs ================================================ pub mod helius; pub mod yellowstone; ================================================ FILE: src/lib.rs ================================================ pub mod common; pub mod core; pub mod dex; pub mod engine; pub mod services; ================================================ FILE: src/main.rs ================================================ use dotenv::dotenv; use raydium_pump_snipe_bot::{ common::{ logger::Logger, utils::{ create_nonblocking_rpc_client, create_rpc_client, import_env_var, import_wallet, AppState, }, }, engine::monitor::{pumpfun_monitor, raydium_monitor}, services::jito, }; use solana_sdk::signer::Signer; #[tokio::main] async fn main() { let logger = Logger::new("[INIT] => ".to_string()); dotenv().ok(); let rpc_wss = import_env_var("RPC_WSS"); let rpc_client = create_rpc_client().unwrap(); let rpc_nonblocking_client = create_nonblocking_rpc_client().await.unwrap(); let wallet = import_wallet().unwrap(); let wallet_cloned = wallet.clone(); let state = AppState { rpc_client, rpc_nonblocking_client, wallet, }; let slippage = import_env_var("SLIPPAGE").parse::().unwrap_or(5); let use_jito = true; if use_jito { jito::init_tip_accounts().await.unwrap(); } logger.log(format!( "Successfully Set the environment variables.\n\t\t\t\t [Web Socket RPC]: {},\n\t\t\t\t [Wallet]: {:?},\n\t\t\t\t [Slippage]: {}\n", rpc_wss, wallet_cloned.pubkey(), slippage )); // raydium_monitor(&rpc_wss, state, slippage, use_jito).await; pumpfun_monitor(&rpc_wss, state, slippage, use_jito).await; } ================================================ FILE: src/services/mod.rs ================================================ pub mod jito; pub mod nextblock; ================================================ FILE: trial/blacklist.txt ================================================