Created
April 7, 2026 11:54
-
-
Save allenhark/9937f3a546a6114f7903cdadfab1c410 to your computer and use it in GitHub Desktop.
Pumpfun 6024 error fix example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // test_pumpfun.rs - Integration test: buy a PumpFun token, verify balance, then sell | |
| // Usage: cargo run --bin test_pumpfun -- --token <MINT> [--amount <SOL>] | |
| use anyhow::{bail, Context, Result}; | |
| use colored::*; | |
| use dotenv::dotenv; | |
| use solana_sdk::{pubkey::Pubkey, signature::Signer}; | |
| use std::str::FromStr; | |
| use sniperbot::platform::{self, get_platform, PlatformData, PlatformId, TokenCreateEvent}; | |
| use sniperbot::rpc_helpers::*; | |
| #[tokio::main] | |
| async fn main() -> Result<()> { | |
| dotenv().ok(); | |
| let (keypair_path, rpc_url) = load_config()?; | |
| let args: Vec<String> = std::env::args().collect(); | |
| let mut token_address: Option<String> = None; | |
| let mut sol_amount: f64 = 0.001; | |
| let mut i = 1; | |
| while i < args.len() { | |
| match args[i].as_str() { | |
| "--token" | "-t" => { token_address = Some(args[i + 1].clone()); i += 2; } | |
| "--amount" | "-a" => { sol_amount = args[i + 1].parse()?; i += 2; } | |
| "--help" | "-h" => { | |
| println!("Usage: cargo run --bin test_pumpfun -- --token <MINT> [--amount <SOL>]"); | |
| return Ok(()); | |
| } | |
| _ => { | |
| if token_address.is_none() && !args[i].starts_with("--") { | |
| token_address = Some(args[i].clone()); | |
| } | |
| i += 1; | |
| } | |
| } | |
| } | |
| let mint_str = token_address.ok_or_else(|| anyhow::anyhow!("Token address required"))?; | |
| let mint = Pubkey::from_str(&mint_str).context("Invalid mint address")?; | |
| let payer = load_keypair(&keypair_path)?; | |
| let sol_lamports = (sol_amount * LAMPORTS_PER_SOL as f64) as u64; | |
| println!("{}", "═══════════════════════════════════════".cyan()); | |
| println!("{}", " PumpFun Buy + Sell Test".cyan().bold()); | |
| println!("{}", "═══════════════════════════════════════".cyan()); | |
| println!(" Payer: {}", payer.pubkey()); | |
| println!(" Token: {}", mint); | |
| println!(" Amount: {} SOL ({} lamports)", sol_amount, sol_lamports); | |
| println!(); | |
| // Detect token program | |
| let token_program = detect_token_program(&mint, &rpc_url).await?; | |
| let platform_impl = get_platform(PlatformId::PumpFun); | |
| let user_ata = platform_impl.user_token_account(&payer.pubkey(), &mint, &token_program); | |
| // Build PlatformData from on-chain bonding curve | |
| let bonding_curve = platform::pumpfun::derive_bonding_curve(&mint); | |
| let bc_data = get_account_info(&bonding_curve, &rpc_url) | |
| .await | |
| .context("Bonding curve not found — token may have migrated")?; | |
| if bc_data.len() < 81 { | |
| bail!("Bonding curve data too short"); | |
| } | |
| let creator_bytes: [u8; 32] = bc_data[49..81].try_into().unwrap(); | |
| let creator = Pubkey::new_from_array(creator_bytes); | |
| let cashback_enabled = bc_data.len() > 82 && bc_data[82] != 0; | |
| let platform_data = PlatformData::PumpFun { | |
| is_create_v2: false, | |
| token_program, | |
| bonding_curve, | |
| associated_bonding_curve: platform::pumpfun::get_associated_token_address( | |
| &bonding_curve, &mint, &token_program, | |
| ), | |
| creator_vault: platform::pumpfun::derive_creator_vault(&creator), | |
| fee_recipient: *platform::pumpfun::FEE_RECIPIENT, | |
| fee_config: platform::pumpfun::get_fee_config(), | |
| global_volume_accumulator: Pubkey::default(), | |
| user_volume_accumulator: platform::pumpfun::derive_user_volume_accumulator(&payer.pubkey()), | |
| bonding_curve_v2: platform::pumpfun::derive_bonding_curve_v2(&mint), | |
| cashback_enabled, | |
| }; | |
| // Check initial balance | |
| let initial_balance = get_token_account_balance(&user_ata, &rpc_url).await.unwrap_or(0); | |
| println!("{}", format!("Initial token balance: {}", initial_balance).dimmed()); | |
| // ── BUY ── | |
| println!(); | |
| println!("{}", "▸ BUYING...".green().bold()); | |
| // Build synthetic TokenCreateEvent for buy instruction | |
| let event = TokenCreateEvent { | |
| platform: PlatformId::PumpFun, | |
| slot: 0, | |
| signature: [0u8; 64], | |
| processed_at_ns: 0, | |
| mint, | |
| creator, | |
| name: None, | |
| symbol: None, | |
| uri: None, | |
| pool: bonding_curve, | |
| initial_buy: None, | |
| create_accounts: vec![], | |
| platform_data: platform_data.clone(), | |
| }; | |
| // PumpFun buy uses SOL directly (no WSOL wrapping needed) | |
| let buy_ix = platform_impl.build_buy_instruction( | |
| &payer.pubkey(), | |
| &event, | |
| sol_lamports, | |
| 1, // min_tokens = 1 (accept any) | |
| )?; | |
| let buy_sig = send_and_confirm(&payer, vec![buy_ix], &rpc_url).await?; | |
| println!("{}", format!(" Buy signature: {}", buy_sig).green()); | |
| println!("{}", format!(" https://solscan.io/tx/{}", buy_sig).dimmed()); | |
| // Wait and verify purchase | |
| println!("{}", " Waiting for confirmation...".yellow()); | |
| tokio::time::sleep(tokio::time::Duration::from_secs(3)).await; | |
| let post_buy_balance = get_token_account_balance(&user_ata, &rpc_url).await?; | |
| let tokens_bought = post_buy_balance.saturating_sub(initial_balance); | |
| if tokens_bought == 0 { | |
| bail!("❌ Buy failed — no tokens received"); | |
| } | |
| println!( | |
| "{}", | |
| format!( | |
| " ✅ Bought {} tokens ({:.6})", | |
| tokens_bought, | |
| tokens_bought as f64 / 1e6 | |
| ) | |
| .green() | |
| ); | |
| // ── SELL ── | |
| println!(); | |
| println!("{}", "▸ SELLING...".red().bold()); | |
| let sell_ix = platform_impl.build_sell_instruction( | |
| &payer.pubkey(), | |
| &platform_data, | |
| &mint, | |
| &user_ata, | |
| post_buy_balance, // sell entire balance | |
| 1, | |
| )?; | |
| let sell_sig = send_and_confirm(&payer, vec![sell_ix], &rpc_url).await?; | |
| println!("{}", format!(" Sell signature: {}", sell_sig).green()); | |
| println!("{}", format!(" https://solscan.io/tx/{}", sell_sig).dimmed()); | |
| // Verify sell | |
| println!("{}", " Waiting for confirmation...".yellow()); | |
| tokio::time::sleep(tokio::time::Duration::from_secs(3)).await; | |
| let final_balance = get_token_account_balance(&user_ata, &rpc_url).await.unwrap_or(0); | |
| if final_balance == 0 { | |
| println!("{}", " ✅ All tokens sold!".green()); | |
| } else { | |
| println!( | |
| "{}", | |
| format!(" ⚠️ Remaining: {} tokens", final_balance).yellow() | |
| ); | |
| } | |
| println!(); | |
| println!("{}", "═══════════════════════════════════════".cyan()); | |
| println!("{}", " Test Complete".cyan().bold()); | |
| println!("{}", "═══════════════════════════════════════".cyan()); | |
| Ok(()) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment