From c8241d12d2aa6c575749b8ee1ba04897ed9e4663 Mon Sep 17 00:00:00 2001 From: ysq Date: Mon, 8 Sep 2025 21:54:05 +0800 Subject: [PATCH] feat: optimize PumpSwap instruction builder performance and caching - Add PumpSwapUserVolume PDA cache key support - Refactor PumpSwap instruction builder to simplify code logic - Optimize memory allocation with pre-allocated Vec capacity - Integrate fast_fn caching mechanism to replace redundant PDA calculations - Standardize account metadata construction and data serialization - Simplify wSOL handling logic by reusing common functions - Optimize import statements and remove unused dependencies - Add pool token account parameters to PumpSwapParams structure --- src/common/fast_fn.rs | 3 + src/instruction/pumpswap.rs | 287 ++++++++++-------------------- src/instruction/utils/pumpswap.rs | 23 ++- src/trading/core/params.rs | 10 ++ 4 files changed, 124 insertions(+), 199 deletions(-) diff --git a/src/common/fast_fn.rs b/src/common/fast_fn.rs index d87db04..eafddf5 100644 --- a/src/common/fast_fn.rs +++ b/src/common/fast_fn.rs @@ -110,6 +110,7 @@ pub enum PdaCacheKey { PumpFunCreatorVault(Pubkey), BonkPool(Pubkey, Pubkey), BonkVault(Pubkey, Pubkey), + PumpSwapUserVolume(Pubkey), } /// 全局 PDA 缓存,用于存储计算结果 @@ -196,6 +197,8 @@ pub fn get_associated_token_address_with_program_id_fast( pub fn fast_init(payer: &Pubkey) { // 获取 PumpFun 用户量累加器 PDA crate::instruction::utils::pumpfun::get_user_volume_accumulator_pda(payer); + // 获取 PumpSwap 用户量累加器 PDA + crate::instruction::utils::pumpswap::get_user_volume_accumulator_pda(payer); // 获取 wSOL ATA 地址 let wsol_token_account = get_associated_token_address_with_program_id_fast( payer, diff --git a/src/instruction/pumpswap.rs b/src/instruction/pumpswap.rs index 69b3c7f..1fc1014 100755 --- a/src/instruction/pumpswap.rs +++ b/src/instruction/pumpswap.rs @@ -1,14 +1,8 @@ -use anyhow::{anyhow, Result}; -use solana_sdk::{instruction::Instruction, pubkey::Pubkey, signer::Signer}; -use solana_system_interface::instruction::transfer; -use spl_associated_token_account::instruction::create_associated_token_account_idempotent; -use spl_token::instruction::close_account; - use crate::{ constants::trade::trade::DEFAULT_SLIPPAGE, instruction::utils::pumpswap::{ - accounts, coin_creator_vault_ata, fee_recipient_ata, get_user_volume_accumulator_pda, - BUY_DISCRIMINATOR, SELL_DISCRIMINATOR, + accounts, fee_recipient_ata, get_user_volume_accumulator_pda, BUY_DISCRIMINATOR, + SELL_DISCRIMINATOR, }, trading::core::{ params::{BuyParams, PumpSwapParams, SellParams}, @@ -16,6 +10,12 @@ use crate::{ }, utils::calc::pumpswap::{buy_quote_input_internal, sell_base_input_internal}, }; +use anyhow::{anyhow, Result}; +use solana_sdk::{ + instruction::{AccountMeta, Instruction}, + pubkey::Pubkey, + signer::Signer, +}; /// Instruction builder for PumpSwap protocol pub struct PumpSwapInstructionBuilder; @@ -45,24 +45,23 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { let auto_handle_wsol = protocol_params.auto_handle_wsol; let base_token_program = protocol_params.base_token_program; let quote_token_program = protocol_params.quote_token_program; + let pool_base_token_account = protocol_params.pool_base_token_account; + let pool_quote_token_account = protocol_params.pool_quote_token_account; if base_mint != crate::constants::WSOL_TOKEN_ACCOUNT && quote_mint != crate::constants::WSOL_TOKEN_ACCOUNT { return Err(anyhow!("Invalid base mint and quote mint")); } - if params.rpc.is_none() { - return Err(anyhow!("RPC is not set")); - } + let quote_mint_is_wsol = quote_mint == crate::constants::WSOL_TOKEN_ACCOUNT; let mut token_amount = 0; let mut sol_amount = 0; let mut creator = Pubkey::default(); - let default_creator_ata = coin_creator_vault_ata(creator, quote_mint); - if default_creator_ata != params_coin_creator_vault_ata { - creator = params_coin_creator_vault_ata; + if params_coin_creator_vault_authority != accounts::DEFAULT_COIN_CREATOR_VAULT_AUTHORITY { + creator = params_coin_creator_vault_authority; } if quote_mint_is_wsol { let result = buy_quote_input_internal( @@ -94,75 +93,27 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { // Create user token accounts let user_base_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( + crate::common::fast_fn::get_associated_token_address_with_program_id_fast( ¶ms.payer.pubkey(), &base_mint, &base_token_program, ); let user_quote_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( + crate::common::fast_fn::get_associated_token_address_with_program_id_fast( ¶ms.payer.pubkey(), "e_mint, "e_token_program, ); - // Get pool token accounts - let pool_base_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( - &pool, - &base_mint, - &base_token_program, - ); - - let pool_quote_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( - &pool, - "e_mint, - "e_token_program, - ); - - let mut instructions = vec![]; + let mut instructions = Vec::with_capacity(6); if auto_handle_wsol { - // Handle wSOL - instructions.push( - // Create wSOL ATA account if it doesn't exist - create_associated_token_account_idempotent( - ¶ms.payer.pubkey(), - ¶ms.payer.pubkey(), - &crate::constants::WSOL_TOKEN_ACCOUNT, - &crate::constants::TOKEN_PROGRAM, - ), - ); - instructions.push( - // Transfer SOL to wSOL ATA account - transfer( - ¶ms.payer.pubkey(), - if quote_mint_is_wsol { - &user_quote_token_account - } else { - &user_base_token_account - }, - sol_amount, - ), - ); - - // Sync wSOL balance - instructions.push( - spl_token::instruction::sync_native( - &crate::constants::TOKEN_PROGRAM, - if quote_mint_is_wsol { - &user_quote_token_account - } else { - &user_base_token_account - }, - ) - .unwrap(), - ); + instructions + .extend(crate::trading::common::handle_wsol(¶ms.payer.pubkey(), sol_amount)); } // Create user's base token account - instructions.push(create_associated_token_account_idempotent( + instructions.push(crate::common::fast_fn::create_associated_token_account_idempotent_fast( ¶ms.payer.pubkey(), ¶ms.payer.pubkey(), if quote_mint_is_wsol { &base_mint } else { "e_mint }, @@ -172,33 +123,31 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { let fee_recipient_ata = fee_recipient_ata(accounts::FEE_RECIPIENT, quote_mint); // Create buy instruction - let mut accounts = vec![ - solana_sdk::instruction::AccountMeta::new_readonly(pool, false), // pool_id (readonly) - solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // user (signer) - accounts::GLOBAL_ACCOUNT_META, // global (readonly) - solana_sdk::instruction::AccountMeta::new_readonly(base_mint, false), // base_mint (readonly) - solana_sdk::instruction::AccountMeta::new_readonly(quote_mint, false), // quote_mint (readonly) - solana_sdk::instruction::AccountMeta::new(user_base_token_account, false), // user_base_token_account - solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // user_quote_token_account - solana_sdk::instruction::AccountMeta::new(pool_base_token_account, false), // pool_base_token_account - solana_sdk::instruction::AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account - accounts::FEE_RECIPIENT_META, // fee_recipient (readonly) - solana_sdk::instruction::AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata - solana_sdk::instruction::AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly) - solana_sdk::instruction::AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS) - crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly) + let mut accounts = Vec::with_capacity(23); + accounts.extend([ + AccountMeta::new_readonly(pool, false), // pool_id (readonly) + AccountMeta::new(params.payer.pubkey(), true), // user (signer) + accounts::GLOBAL_ACCOUNT_META, // global (readonly) + AccountMeta::new_readonly(base_mint, false), // base_mint (readonly) + AccountMeta::new_readonly(quote_mint, false), // quote_mint (readonly) + AccountMeta::new(user_base_token_account, false), // user_base_token_account + AccountMeta::new(user_quote_token_account, false), // user_quote_token_account + AccountMeta::new(pool_base_token_account, false), // pool_base_token_account + AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account + accounts::FEE_RECIPIENT_META, // fee_recipient (readonly) + AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata + AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly) + AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS) + crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly) accounts::ASSOCIATED_TOKEN_PROGRAM_META, // ASSOCIATED_TOKEN_PROGRAM_ID (readonly) - accounts::EVENT_AUTHORITY_META, // event_authority (readonly) - accounts::AMM_PROGRAM_META, // PUMP_AMM_PROGRAM_ID (readonly) - solana_sdk::instruction::AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata - solana_sdk::instruction::AccountMeta::new_readonly( - params_coin_creator_vault_authority, - false, - ), // coin_creator_vault_authority (readonly) - ]; + accounts::EVENT_AUTHORITY_META, // event_authority (readonly) + accounts::AMM_PROGRAM_META, // PUMP_AMM_PROGRAM_ID (readonly) + AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata + AccountMeta::new_readonly(params_coin_creator_vault_authority, false), // coin_creator_vault_authority (readonly) + ]); if quote_mint_is_wsol { accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META); - accounts.push(solana_sdk::instruction::AccountMeta::new( + accounts.push(AccountMeta::new( get_user_volume_accumulator_pda(¶ms.payer.pubkey()).unwrap(), false, )); @@ -207,38 +156,29 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { accounts.push(accounts::FEE_PROGRAM_META); // Create instruction data - let mut data = vec![]; + let mut data = [0u8; 24]; if quote_mint_is_wsol { - data.extend_from_slice(&BUY_DISCRIMINATOR); + data[..8].copy_from_slice(&BUY_DISCRIMINATOR); // base_amount_out - data.extend_from_slice(&token_amount.to_le_bytes()); + data[8..16].copy_from_slice(&token_amount.to_le_bytes()); // max_quote_amount_in - data.extend_from_slice(&sol_amount.to_le_bytes()); + data[16..24].copy_from_slice(&sol_amount.to_le_bytes()); } else { - data.extend_from_slice(&SELL_DISCRIMINATOR); + data[..8].copy_from_slice(&SELL_DISCRIMINATOR); // base_amount_in - data.extend_from_slice(&sol_amount.to_le_bytes()); + data[8..16].copy_from_slice(&sol_amount.to_le_bytes()); // min_quote_amount_out - data.extend_from_slice(&token_amount.to_le_bytes()); + data[16..24].copy_from_slice(&token_amount.to_le_bytes()); } - instructions.push(Instruction { program_id: accounts::AMM_PROGRAM, accounts, data }); + instructions.push(Instruction { + program_id: accounts::AMM_PROGRAM, + accounts, + data: data.to_vec(), + }); if auto_handle_wsol { // Close wSOL ATA account, reclaim rent - instructions.push( - spl_token::instruction::close_account( - &crate::constants::TOKEN_PROGRAM, - if quote_mint_is_wsol { - &user_quote_token_account - } else { - &user_base_token_account - }, - ¶ms.payer.pubkey(), - ¶ms.payer.pubkey(), - &[¶ms.payer.pubkey()], - ) - .unwrap(), - ); + instructions.push(crate::trading::common::close_wsol(¶ms.payer.pubkey())); } Ok(instructions) } @@ -257,6 +197,8 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { let quote_mint = protocol_params.quote_mint; let pool_base_token_reserves = protocol_params.pool_base_token_reserves; let pool_quote_token_reserves = protocol_params.pool_quote_token_reserves; + let pool_base_token_account = protocol_params.pool_base_token_account; + let pool_quote_token_account = protocol_params.pool_quote_token_account; let params_coin_creator_vault_ata = protocol_params.coin_creator_vault_ata; let params_coin_creator_vault_authority = protocol_params.coin_creator_vault_authority; let auto_handle_wsol = protocol_params.auto_handle_wsol; @@ -268,9 +210,6 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { { return Err(anyhow!("Invalid base mint and quote mint")); } - if params.rpc.is_none() { - return Err(anyhow!("RPC is not set")); - } if params.token_amount.is_none() { return Err(anyhow!("Token amount is not set")); } @@ -281,9 +220,8 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { let mut sol_amount = 0; let mut creator = Pubkey::default(); - let default_creator_ata = coin_creator_vault_ata(creator, quote_mint); - if default_creator_ata != params_coin_creator_vault_ata { - creator = params_coin_creator_vault_ata; + if params_coin_creator_vault_authority != accounts::DEFAULT_COIN_CREATOR_VAULT_AUTHORITY { + creator = params_coin_creator_vault_authority; } if quote_mint_is_wsol { @@ -317,36 +255,24 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { let fee_recipient_ata = fee_recipient_ata(accounts::FEE_RECIPIENT, quote_mint); let user_base_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( + crate::common::fast_fn::get_associated_token_address_with_program_id_fast( ¶ms.payer.pubkey(), &base_mint, &base_token_program, ); let user_quote_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( + crate::common::fast_fn::get_associated_token_address_with_program_id_fast( ¶ms.payer.pubkey(), "e_mint, "e_token_program, ); - let pool_base_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( - &pool, - &base_mint, - &base_token_program, - ); - let pool_quote_token_account = - spl_associated_token_account::get_associated_token_address_with_program_id( - &pool, - "e_mint, - "e_token_program, - ); - let mut instructions = vec![]; + let mut instructions = Vec::with_capacity(3); // Insert wSOL instructions.push( // Create wSOL ATA account if it doesn't exist - create_associated_token_account_idempotent( + crate::common::fast_fn::create_associated_token_account_idempotent_fast( ¶ms.payer.pubkey(), ¶ms.payer.pubkey(), &crate::constants::WSOL_TOKEN_ACCOUNT, @@ -354,42 +280,32 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { ), ); - // Create user's token account - instructions.push(create_associated_token_account_idempotent( - ¶ms.payer.pubkey(), - ¶ms.payer.pubkey(), - if quote_mint_is_wsol { &base_mint } else { "e_mint }, - if quote_mint_is_wsol { &base_token_program } else { "e_token_program }, - )); - // Create sell instruction - let mut accounts = vec![ - solana_sdk::instruction::AccountMeta::new_readonly(pool, false), // pool_id (readonly) - solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // user (signer) - accounts::GLOBAL_ACCOUNT_META, // global (readonly) - solana_sdk::instruction::AccountMeta::new_readonly(base_mint, false), // mint (readonly) - solana_sdk::instruction::AccountMeta::new_readonly(quote_mint, false), // WSOL_TOKEN_ACCOUNT (readonly) - solana_sdk::instruction::AccountMeta::new(user_base_token_account, false), // user_base_token_account - solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // user_quote_token_account - solana_sdk::instruction::AccountMeta::new(pool_base_token_account, false), // pool_base_token_account - solana_sdk::instruction::AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account - accounts::FEE_RECIPIENT_META, // fee_recipient (readonly) - solana_sdk::instruction::AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata - solana_sdk::instruction::AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly) - solana_sdk::instruction::AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS) - crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly) + let mut accounts = Vec::with_capacity(23); + accounts.extend([ + AccountMeta::new_readonly(pool, false), // pool_id (readonly) + AccountMeta::new(params.payer.pubkey(), true), // user (signer) + accounts::GLOBAL_ACCOUNT_META, // global (readonly) + AccountMeta::new_readonly(base_mint, false), // mint (readonly) + AccountMeta::new_readonly(quote_mint, false), // WSOL_TOKEN_ACCOUNT (readonly) + AccountMeta::new(user_base_token_account, false), // user_base_token_account + AccountMeta::new(user_quote_token_account, false), // user_quote_token_account + AccountMeta::new(pool_base_token_account, false), // pool_base_token_account + AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account + accounts::FEE_RECIPIENT_META, // fee_recipient (readonly) + AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata + AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly) + AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS) + crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly) accounts::ASSOCIATED_TOKEN_PROGRAM_META, // ASSOCIATED_TOKEN_PROGRAM_ID (readonly) - accounts::EVENT_AUTHORITY_META, // event_authority (readonly) - accounts::AMM_PROGRAM_META, // PUMP_AMM_PROGRAM_ID (readonly) - solana_sdk::instruction::AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata - solana_sdk::instruction::AccountMeta::new_readonly( - params_coin_creator_vault_authority, - false, - ), // coin_creator_vault_authority (readonly) - ]; + accounts::EVENT_AUTHORITY_META, // event_authority (readonly) + accounts::AMM_PROGRAM_META, // PUMP_AMM_PROGRAM_ID (readonly) + AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata + AccountMeta::new_readonly(params_coin_creator_vault_authority, false), // coin_creator_vault_authority (readonly) + ]); if !quote_mint_is_wsol { accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META); - accounts.push(solana_sdk::instruction::AccountMeta::new( + accounts.push(AccountMeta::new( get_user_volume_accumulator_pda(¶ms.payer.pubkey()).unwrap(), false, )); @@ -399,38 +315,29 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { accounts.push(accounts::FEE_PROGRAM_META); // Create instruction data - let mut data = vec![]; + let mut data = [0u8; 24]; if quote_mint_is_wsol { - data.extend_from_slice(&SELL_DISCRIMINATOR); + data[..8].copy_from_slice(&SELL_DISCRIMINATOR); // base_amount_in - data.extend_from_slice(&token_amount.to_le_bytes()); + data[8..16].copy_from_slice(&token_amount.to_le_bytes()); // min_quote_amount_out - data.extend_from_slice(&sol_amount.to_le_bytes()); + data[16..24].copy_from_slice(&sol_amount.to_le_bytes()); } else { - data.extend_from_slice(&BUY_DISCRIMINATOR); + data[..8].copy_from_slice(&BUY_DISCRIMINATOR); // base_amount_out - data.extend_from_slice(&sol_amount.to_le_bytes()); + data[8..16].copy_from_slice(&sol_amount.to_le_bytes()); // max_quote_amount_in - data.extend_from_slice(&token_amount.to_le_bytes()); + data[16..24].copy_from_slice(&token_amount.to_le_bytes()); } - instructions.push(Instruction { program_id: accounts::AMM_PROGRAM, accounts, data }); + instructions.push(Instruction { + program_id: accounts::AMM_PROGRAM, + accounts, + data: data.to_vec(), + }); if auto_handle_wsol { - instructions.push( - close_account( - &crate::constants::TOKEN_PROGRAM, - if quote_mint_is_wsol { - &user_quote_token_account - } else { - &user_base_token_account - }, - ¶ms.payer.pubkey(), - ¶ms.payer.pubkey(), - &[¶ms.payer.pubkey()], - ) - .unwrap(), - ); + instructions.push(crate::trading::common::close_wsol(¶ms.payer.pubkey())); } Ok(instructions) } diff --git a/src/instruction/utils/pumpswap.rs b/src/instruction/utils/pumpswap.rs index ae71af9..54aacee 100644 --- a/src/instruction/utils/pumpswap.rs +++ b/src/instruction/utils/pumpswap.rs @@ -1,7 +1,4 @@ -use crate::{ - common::SolanaRpcClient, - constants::{self, TOKEN_PROGRAM}, -}; +use crate::{common::SolanaRpcClient, constants::TOKEN_PROGRAM}; use anyhow::anyhow; use solana_account_decoder::UiAccountEncoding; use solana_sdk::pubkey::Pubkey; @@ -60,6 +57,9 @@ pub mod accounts { pub const FEE_CONFIG: Pubkey = pubkey!("5PHirr8joyTMp9JMm6nW7hNDVyEYdkzDqazxPD7RaTjx"); // get_fee_config_pda().unwrap(); + pub const DEFAULT_COIN_CREATOR_VAULT_AUTHORITY: Pubkey = + pubkey!("8N3GDaZ2iwN65oxVatKTLPNooAVUJTbfiVJ1ahyqwjSk"); + // META pub const GLOBAL_ACCOUNT_META: solana_sdk::instruction::AccountMeta = @@ -149,7 +149,7 @@ pub(crate) fn coin_creator_vault_ata(coin_creator: Pubkey, quote_mint: Pubkey) - pub(crate) fn fee_recipient_ata(fee_recipient: Pubkey, quote_mint: Pubkey) -> Pubkey { let associated_token_fee_recipient = - spl_associated_token_account::get_associated_token_address_with_program_id( + crate::common::fast_fn::get_associated_token_address_with_program_id_fast( &fee_recipient, "e_mint, &TOKEN_PROGRAM, @@ -158,10 +158,15 @@ pub(crate) fn fee_recipient_ata(fee_recipient: Pubkey, quote_mint: Pubkey) -> Pu } pub fn get_user_volume_accumulator_pda(user: &Pubkey) -> Option { - let seeds: &[&[u8]; 2] = &[&seeds::USER_VOLUME_ACCUMULATOR_SEED, user.as_ref()]; - let program_id: &Pubkey = &&accounts::AMM_PROGRAM; - let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id); - pda.map(|pubkey| pubkey.0) + crate::common::fast_fn::get_cached_pda( + crate::common::fast_fn::PdaCacheKey::PumpSwapUserVolume(*user), + || { + let seeds: &[&[u8]; 2] = &[&seeds::USER_VOLUME_ACCUMULATOR_SEED, user.as_ref()]; + let program_id: &Pubkey = &&accounts::AMM_PROGRAM; + let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id); + pda.map(|pubkey| pubkey.0) + }, + ) } pub fn get_global_volume_accumulator_pda() -> Option { diff --git a/src/trading/core/params.rs b/src/trading/core/params.rs index 676796c..584546c 100755 --- a/src/trading/core/params.rs +++ b/src/trading/core/params.rs @@ -126,6 +126,10 @@ pub struct PumpSwapParams { /// Quote token mint address /// The mint account address of the quote token in the trading pair, usually SOL or USDC pub quote_mint: Pubkey, + /// Pool base token account + pub pool_base_token_account: Pubkey, + /// Pool quote token account + pub pool_quote_token_account: Pubkey, /// Base token reserves in the pool pub pool_base_token_reserves: u64, /// Quote token reserves in the pool @@ -149,6 +153,8 @@ impl PumpSwapParams { pool: event.pool, base_mint: event.base_mint, quote_mint: event.quote_mint, + pool_base_token_account: event.pool_base_token_account, + pool_quote_token_account: event.pool_quote_token_account, pool_base_token_reserves: event.pool_base_token_reserves, pool_quote_token_reserves: event.pool_quote_token_reserves, coin_creator_vault_ata: event.coin_creator_vault_ata, @@ -164,6 +170,8 @@ impl PumpSwapParams { pool: event.pool, base_mint: event.base_mint, quote_mint: event.quote_mint, + pool_base_token_account: event.pool_base_token_account, + pool_quote_token_account: event.pool_quote_token_account, pool_base_token_reserves: event.pool_base_token_reserves, pool_quote_token_reserves: event.pool_quote_token_reserves, coin_creator_vault_ata: event.coin_creator_vault_ata, @@ -206,6 +214,8 @@ impl PumpSwapParams { pool: pool_address.clone(), base_mint: pool_data.base_mint, quote_mint: pool_data.quote_mint, + pool_base_token_account: pool_data.pool_base_token_account, + pool_quote_token_account: pool_data.pool_quote_token_account, pool_base_token_reserves: pool_base_token_reserves, pool_quote_token_reserves: pool_quote_token_reserves, coin_creator_vault_ata: coin_creator_vault_ata,