From 90ea46ea3faec09596e7dca9b978390ee3394b2b Mon Sep 17 00:00:00 2001 From: ysq Date: Sat, 23 Aug 2025 20:37:03 +0800 Subject: [PATCH] feat: This update includes the following changes: 1. Upgrade version from 0.4.7 to 0.5.0 2. Rename compute unit parameters from unit_limit/unit_price to tip_unit_limit/tip_unit_price 3. Remove creator parameter from API to simplify trading interface 4. Optimize PumpFun and PumpSwap protocol parameter structures with creator_vault support 5. Remove unnecessary constants and functions like TOTAL_SUPPLY and BONDING_CURVE_SUPPLY 6. Improve code formatting and documentation --- Cargo.toml | 8 +- README.md | 4 +- README_CN.md | 4 +- src/common/types.rs | 45 +++++----- src/constants/pumpfun.rs | 4 - src/constants/trade.rs | 4 +- src/instruction/pumpfun.rs | 22 ++++- src/instruction/pumpswap.rs | 50 ++++++++--- src/lib.rs | 89 -------------------- src/main.rs | 37 +------- src/trading/common/compute_budget_manager.rs | 8 +- src/trading/core/executor.rs | 2 - src/trading/core/params.rs | 45 ++++++---- src/trading/pumpfun/common.rs | 9 -- 14 files changed, 128 insertions(+), 203 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a98ec50..0f53f3d 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,12 @@ [package] name = "sol-trade-sdk" -version = "0.4.7" +version = "0.5.0" edition = "2021" -authors = ["William ", "sgxiang ", "wei <1415121722@qq.com>"] +authors = [ + "William ", + "sgxiang ", + "wei <1415121722@qq.com>", +] repository = "https://github.com/0xfnzero/sol-trade-sdk" description = "Rust SDK to interact with the dex trade Solana program." license = "MIT" diff --git a/README.md b/README.md index 0ab1d38..3583f14 100755 --- a/README.md +++ b/README.md @@ -33,14 +33,14 @@ Add the dependency to your `Cargo.toml`: ```toml # Add to your Cargo.toml -sol-trade-sdk = { path = "./sol-trade-sdk", version = "0.4.7" } +sol-trade-sdk = { path = "./sol-trade-sdk", version = "0.5.0" } ``` ### Use crates.io ```toml # Add to your Cargo.toml -sol-trade-sdk = "0.4.7" +sol-trade-sdk = "0.5.0" ``` ## Usage Examples diff --git a/README_CN.md b/README_CN.md index 061be43..3f751b1 100755 --- a/README_CN.md +++ b/README_CN.md @@ -33,14 +33,14 @@ git clone https://github.com/0xfnzero/sol-trade-sdk ```toml # 添加到您的 Cargo.toml -sol-trade-sdk = { path = "./sol-trade-sdk", version = "0.4.7" } +sol-trade-sdk = { path = "./sol-trade-sdk", version = "0.5.0" } ``` ### 使用 crates.io ```toml # 添加到您的 Cargo.toml -sol-trade-sdk = "0.4.7" +sol-trade-sdk = "0.5.0" ``` ## 使用示例 diff --git a/src/common/types.rs b/src/common/types.rs index 75c9e1a..4fa109d 100755 --- a/src/common/types.rs +++ b/src/common/types.rs @@ -1,9 +1,15 @@ use std::sync::Arc; +use crate::{ + constants::trade::trade::{ + DEFAULT_BUY_TIP_FEE, DEFAULT_RPC_UNIT_LIMIT, DEFAULT_RPC_UNIT_PRICE, DEFAULT_SELL_TIP_FEE, + DEFAULT_TIP_UNIT_LIMIT, DEFAULT_TIP_UNIT_PRICE, + }, + swqos::{SwqosClient, SwqosConfig}, +}; +use serde::Deserialize; use solana_client::rpc_client::RpcClient; use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signature::Keypair}; -use serde::Deserialize; -use crate::{constants::trade::trade::{DEFAULT_BUY_TIP_FEE, DEFAULT_COMPUTE_UNIT_LIMIT, DEFAULT_COMPUTE_UNIT_PRICE, DEFAULT_RPC_UNIT_LIMIT, DEFAULT_RPC_UNIT_PRICE, DEFAULT_SELL_TIP_FEE}, swqos::{SwqosClient, SwqosConfig}}; #[derive(Debug, Clone)] pub struct TradeConfig { @@ -16,26 +22,20 @@ pub struct TradeConfig { impl TradeConfig { pub fn new( - rpc_url: String, + rpc_url: String, swqos_configs: Vec, - priority_fee: PriorityFee, - commitment: CommitmentConfig, + priority_fee: PriorityFee, + commitment: CommitmentConfig, lookup_table_key: Option, ) -> Self { - Self { - rpc_url, - swqos_configs, - priority_fee, - commitment, - lookup_table_key, - } + Self { rpc_url, swqos_configs, priority_fee, commitment, lookup_table_key } } } #[derive(Debug, Deserialize, Clone, PartialEq)] pub struct PriorityFee { - pub unit_limit: u32, - pub unit_price: u64, + pub tip_unit_limit: u32, + pub tip_unit_price: u64, pub rpc_unit_limit: u32, pub rpc_unit_price: u64, pub buy_tip_fee: f64, @@ -46,15 +46,15 @@ pub struct PriorityFee { impl Default for PriorityFee { fn default() -> Self { - Self { - unit_limit: DEFAULT_COMPUTE_UNIT_LIMIT, - unit_price: DEFAULT_COMPUTE_UNIT_PRICE, + Self { + tip_unit_limit: DEFAULT_TIP_UNIT_LIMIT, + tip_unit_price: DEFAULT_TIP_UNIT_PRICE, rpc_unit_limit: DEFAULT_RPC_UNIT_LIMIT, rpc_unit_price: DEFAULT_RPC_UNIT_PRICE, - buy_tip_fee: DEFAULT_BUY_TIP_FEE, + buy_tip_fee: DEFAULT_BUY_TIP_FEE, buy_tip_fees: vec![], smart_buy_tip_fee: 0.0, - sell_tip_fee: DEFAULT_SELL_TIP_FEE + sell_tip_fee: DEFAULT_SELL_TIP_FEE, } } } @@ -69,7 +69,12 @@ pub struct MethodArgs { } impl MethodArgs { - pub fn new(payer: Arc, rpc: Arc, nonblocking_rpc: Arc, jito_client: Arc) -> Self { + pub fn new( + payer: Arc, + rpc: Arc, + nonblocking_rpc: Arc, + jito_client: Arc, + ) -> Self { Self { payer, rpc, nonblocking_rpc, jito_client } } } diff --git a/src/constants/pumpfun.rs b/src/constants/pumpfun.rs index bb21d66..79677bb 100755 --- a/src/constants/pumpfun.rs +++ b/src/constants/pumpfun.rs @@ -57,10 +57,6 @@ pub mod global_constants { pub const LAMPORTS_PER_SOL: u64 = 1_000_000_000; // 10^9 for solana lamports - pub const TOTAL_SUPPLY: u64 = 1_000_000_000 * SCALE; // 1 billion tokens - - pub const BONDING_CURVE_SUPPLY: u64 = 793_100_000 * SCALE; // total supply of bonding curve tokens - pub const COMPLETION_LAMPORTS: u64 = 85 * LAMPORTS_PER_SOL; // ~ 85 SOL /// Public key for the fee recipient diff --git a/src/constants/trade.rs b/src/constants/trade.rs index 1278f57..043ba09 100644 --- a/src/constants/trade.rs +++ b/src/constants/trade.rs @@ -1,7 +1,7 @@ pub mod trade { pub const DEFAULT_SLIPPAGE: u64 = 1000; // 10% - pub const DEFAULT_COMPUTE_UNIT_LIMIT: u32 = 78000; - pub const DEFAULT_COMPUTE_UNIT_PRICE: u64 = 500000; + pub const DEFAULT_TIP_UNIT_LIMIT: u32 = 78000; + pub const DEFAULT_TIP_UNIT_PRICE: u64 = 500000; pub const DEFAULT_BUY_TIP_FEE: f64 = 0.0006; pub const DEFAULT_SELL_TIP_FEE: f64 = 0.0001; pub const DEFAULT_RPC_UNIT_LIMIT: u32 = 78000; diff --git a/src/instruction/pumpfun.rs b/src/instruction/pumpfun.rs index e3d19be..498e993 100755 --- a/src/instruction/pumpfun.rs +++ b/src/instruction/pumpfun.rs @@ -51,13 +51,20 @@ impl InstructionBuilder for PumpFunInstructionBuilder { params.sol_amount, params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE), ); - let creator_vault_pda = bonding_curve.get_creator_vault_pda(); + let creator_vault_pda = protocol_params.creator_vault; + + let mut creator = Pubkey::default(); + if let Some(default_creator_ata) = get_creator_vault_pda(&creator) { + if default_creator_ata != creator_vault_pda { + creator = creator_vault_pda; + } + } let buy_token_amount = get_buy_token_amount_from_sol_amount( bonding_curve.virtual_token_reserves as u128, bonding_curve.virtual_sol_reserves as u128, bonding_curve.real_token_reserves as u128, - bonding_curve.creator, + creator, params.sol_amount, ); @@ -102,13 +109,20 @@ impl InstructionBuilder for PumpFunInstructionBuilder { } else { return Err(anyhow!("Amount token is required")); }; - let creator_vault_pda = get_creator_vault_pda(¶ms.creator).unwrap(); + let creator_vault_pda = protocol_params.creator_vault; let ata = get_associated_token_address(¶ms.payer.pubkey(), ¶ms.mint); + let mut creator = Pubkey::default(); + if let Some(default_creator_ata) = get_creator_vault_pda(&creator) { + if default_creator_ata != creator_vault_pda { + creator = creator_vault_pda; + } + } + let sol_amount = get_sell_sol_amount_from_token_amount( bonding_curve.virtual_token_reserves as u128, bonding_curve.virtual_sol_reserves as u128, - bonding_curve.creator, + creator, token_amount, ); let min_sol_output = calculate_with_slippage_sell( diff --git a/src/instruction/pumpswap.rs b/src/instruction/pumpswap.rs index 74c05dd..4bb899d 100755 --- a/src/instruction/pumpswap.rs +++ b/src/instruction/pumpswap.rs @@ -44,6 +44,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 coin_creator_vault_ata = protocol_params.coin_creator_vault_ata; + let coin_creator_vault_authority = protocol_params.coin_creator_vault_authority; self.build_buy_instructions_with_accounts( params, @@ -52,6 +54,8 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { quote_mint, pool_base_token_reserves, pool_quote_token_reserves, + coin_creator_vault_ata, + coin_creator_vault_authority, protocol_params.auto_handle_wsol, ) .await @@ -69,6 +73,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 coin_creator_vault_ata = protocol_params.coin_creator_vault_ata; + let coin_creator_vault_authority = protocol_params.coin_creator_vault_authority; self.build_sell_instructions_with_accounts( params, @@ -77,6 +83,8 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { quote_mint, pool_base_token_reserves, pool_quote_token_reserves, + coin_creator_vault_ata, + coin_creator_vault_authority, protocol_params.auto_handle_wsol, ) .await @@ -93,6 +101,8 @@ impl PumpSwapInstructionBuilder { quote_mint: Pubkey, pool_base_token_reserves: u64, pool_quote_token_reserves: u64, + params_coin_creator_vault_ata: Pubkey, + params_coin_creator_vault_authority: Pubkey, auto_handle_wsol: bool, ) -> Result> { if params.rpc.is_none() { @@ -102,13 +112,19 @@ impl PumpSwapInstructionBuilder { 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 quote_mint_is_wsol { let result = buy_quote_input_internal( params.sol_amount, params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE), pool_base_token_reserves, pool_quote_token_reserves, - ¶ms.creator, + &creator, ) .unwrap(); // base_amount_out @@ -121,7 +137,7 @@ impl PumpSwapInstructionBuilder { params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE), pool_base_token_reserves, pool_quote_token_reserves, - ¶ms.creator, + &creator, ) .unwrap(); // min_quote_amount_out @@ -203,8 +219,6 @@ impl PumpSwapInstructionBuilder { &accounts::TOKEN_PROGRAM, )); - let coin_creator_vault_ata = coin_creator_vault_ata(params.creator, quote_mint); - let coin_creator_vault_authority = coin_creator_vault_authority(params.creator); let fee_recipient_ata = fee_recipient_ata(accounts::FEE_RECIPIENT, quote_mint); // Create buy instruction @@ -229,8 +243,11 @@ impl PumpSwapInstructionBuilder { ), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly) solana_sdk::instruction::AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false), // event_authority (readonly) solana_sdk::instruction::AccountMeta::new_readonly(accounts::AMM_PROGRAM, false), // PUMP_AMM_PROGRAM_ID (readonly) - solana_sdk::instruction::AccountMeta::new(coin_creator_vault_ata, false), // coin_creator_vault_ata - solana_sdk::instruction::AccountMeta::new_readonly(coin_creator_vault_authority, false), // coin_creator_vault_authority (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) ]; if quote_mint_is_wsol { accounts.push(solana_sdk::instruction::AccountMeta::new( @@ -289,6 +306,8 @@ impl PumpSwapInstructionBuilder { quote_mint: Pubkey, pool_base_token_reserves: u64, pool_quote_token_reserves: u64, + params_coin_creator_vault_ata: Pubkey, + params_coin_creator_vault_authority: Pubkey, auto_handle_wsol: bool, ) -> Result> { if params.rpc.is_none() { @@ -303,13 +322,19 @@ impl PumpSwapInstructionBuilder { 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 quote_mint_is_wsol { let result = sell_base_input_internal( params.token_amount.unwrap(), params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE), pool_base_token_reserves, pool_quote_token_reserves, - ¶ms.creator, + &creator, ) .unwrap(); // base_amount_in @@ -322,7 +347,7 @@ impl PumpSwapInstructionBuilder { params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE), pool_base_token_reserves, pool_quote_token_reserves, - ¶ms.creator, + &creator, ) .unwrap(); // max_quote_amount_in @@ -331,8 +356,6 @@ impl PumpSwapInstructionBuilder { sol_amount = result.base; } - let coin_creator_vault_ata = coin_creator_vault_ata(params.creator, quote_mint); - let coin_creator_vault_authority = coin_creator_vault_authority(params.creator); 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( @@ -399,8 +422,11 @@ impl PumpSwapInstructionBuilder { ), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly) solana_sdk::instruction::AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false), // event_authority (readonly) solana_sdk::instruction::AccountMeta::new_readonly(accounts::AMM_PROGRAM, false), // PUMP_AMM_PROGRAM_ID (readonly) - solana_sdk::instruction::AccountMeta::new(coin_creator_vault_ata, false), // coin_creator_vault_ata - solana_sdk::instruction::AccountMeta::new_readonly(coin_creator_vault_authority, false), // coin_creator_vault_authority (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) ]; if !quote_mint_is_wsol { accounts.push(solana_sdk::instruction::AccountMeta::new( diff --git a/src/lib.rs b/src/lib.rs index 0ef4ab1..827f6b5 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,7 +129,6 @@ impl SolanaTrade { /// /// * `dex_type` - The trading protocol to use (PumpFun, PumpSwap, or Bonk) /// * `mint` - The public key of the token mint to buy - /// * `creator` - Optional creator public key for the token (defaults to Pubkey::default() if None) /// * `sol_amount` - Amount of SOL to spend on the purchase (in lamports) /// * `slippage_basis_points` - Optional slippage tolerance in basis points (e.g., 100 = 1%) /// * `recent_blockhash` - Recent blockhash for transaction validity @@ -149,36 +148,10 @@ impl SolanaTrade { /// - The transaction fails to execute /// - Network or RPC errors occur /// - Insufficient SOL balance for the purchase - /// - /// # Example - /// - /// ```rust - /// use solana_sdk::pubkey::Pubkey; - /// use solana_sdk::hash::Hash; - /// use crate::trading::factory::DexType; - /// - /// let mint = Pubkey::new_unique(); - /// let sol_amount = 1_000_000_000; // 1 SOL in lamports - /// let slippage = Some(500); // 5% slippage - /// let recent_blockhash = Hash::default(); - /// - /// solana_trade.buy( - /// DexType::PumpFun, - /// mint, - /// None, - /// sol_amount, - /// slippage, - /// recent_blockhash, - /// None, - /// None, - /// Some(lookup_table_pubkey), - /// ).await?; - /// ``` pub async fn buy( &self, dex_type: DexType, mint: Pubkey, - creator: Option, sol_amount: u64, slippage_basis_points: Option, recent_blockhash: Hash, @@ -196,7 +169,6 @@ impl SolanaTrade { rpc: Some(self.rpc.clone()), payer: self.payer.clone(), mint: mint, - creator: creator.unwrap_or(Pubkey::default()), sol_amount: sol_amount, slippage_basis_points: slippage_basis_points, priority_fee: self.trade_config.priority_fee.clone(), @@ -245,7 +217,6 @@ impl SolanaTrade { /// /// * `dex_type` - The trading protocol to use (PumpFun, PumpSwap, or Bonk) /// * `mint` - The public key of the token mint to sell - /// * `creator` - Optional creator public key for the token (defaults to Pubkey::default() if None) /// * `token_amount` - Amount of tokens to sell (in smallest token units) /// * `slippage_basis_points` - Optional slippage tolerance in basis points (e.g., 100 = 1%) /// * `recent_blockhash` - Recent blockhash for transaction validity @@ -267,37 +238,10 @@ impl SolanaTrade { /// - Network or RPC errors occur /// - Insufficient token balance for the sale /// - Token account doesn't exist or is not properly initialized - /// - /// # Example - /// - /// ```rust - /// use solana_sdk::pubkey::Pubkey; - /// use solana_sdk::hash::Hash; - /// use crate::trading::factory::DexType; - /// - /// let mint = Pubkey::new_unique(); - /// let token_amount = 1_000_000; // Amount of tokens to sell - /// let slippage = Some(500); // 5% slippage - /// let recent_blockhash = Hash::default(); - /// - /// solana_trade.sell( - /// DexType::PumpFun, - /// mint, - /// None, - /// token_amount, - /// slippage, - /// recent_blockhash, - /// None, - /// false, - /// None, - /// Some(lookup_table_pubkey), - /// ).await?; - /// ``` pub async fn sell( &self, dex_type: DexType, mint: Pubkey, - creator: Option, token_amount: u64, slippage_basis_points: Option, recent_blockhash: Hash, @@ -316,7 +260,6 @@ impl SolanaTrade { rpc: Some(self.rpc.clone()), payer: self.payer.clone(), mint: mint, - creator: creator.unwrap_or(Pubkey::default()), token_amount: Some(token_amount), slippage_basis_points: slippage_basis_points, priority_fee: self.trade_config.priority_fee.clone(), @@ -372,7 +315,6 @@ impl SolanaTrade { /// /// * `dex_type` - The trading protocol to use (PumpFun, PumpSwap, or Bonk) /// * `mint` - The public key of the token mint to sell - /// * `creator` - Optional creator public key for the token (defaults to Pubkey::default() if None) /// * `amount_token` - Total amount of tokens available (in smallest token units) /// * `percent` - Percentage of tokens to sell (1-100, where 100 = 100%) /// * `slippage_basis_points` - Optional slippage tolerance in basis points (e.g., 100 = 1%) @@ -396,40 +338,10 @@ impl SolanaTrade { /// - Network or RPC errors occur /// - Insufficient token balance for the calculated sale amount /// - Token account doesn't exist or is not properly initialized - /// - /// # Example - /// - /// ```rust - /// use solana_sdk::pubkey::Pubkey; - /// use solana_sdk::hash::Hash; - /// use crate::trading::factory::DexType; - /// - /// let mint = Pubkey::new_unique(); - /// let total_tokens = 10_000_000; // Total tokens available - /// let percent = 50; // Sell 50% of tokens - /// let slippage = Some(500); // 5% slippage - /// let recent_blockhash = Hash::default(); - /// - /// // This will sell 5_000_000 tokens (50% of 10_000_000) - /// solana_trade.sell_by_percent( - /// DexType::PumpFun, - /// mint, - /// None, - /// total_tokens, - /// percent, - /// slippage, - /// recent_blockhash, - /// None, - /// false, - /// None, - /// None, - /// ).await?; - /// ``` pub async fn sell_by_percent( &self, dex_type: DexType, mint: Pubkey, - creator: Option, amount_token: u64, percent: u64, slippage_basis_points: Option, @@ -447,7 +359,6 @@ impl SolanaTrade { self.sell( dex_type, mint, - creator, amount, slippage_basis_points, recent_blockhash, diff --git a/src/main.rs b/src/main.rs index e1d6bd0..e2fdcec 100755 --- a/src/main.rs +++ b/src/main.rs @@ -101,7 +101,6 @@ async fn test_middleware() -> AnyResult<()> { // You can reference LoggingMiddleware to implement the InstructionMiddleware trait for your own middleware let middleware_manager = MiddlewareManager::new().add_middleware(Box::new(LoggingMiddleware)); client = client.with_middleware_manager(middleware_manager); - let creator = Pubkey::from_str("11111111111111111111111111111111")?; let mint_pubkey = Pubkey::from_str("xxxxx")?; let buy_sol_cost = 100_000; let slippage_basis_points = Some(100); @@ -113,7 +112,6 @@ async fn test_middleware() -> AnyResult<()> { .buy( DexType::PumpSwap, mint_pubkey, - Some(creator), buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -131,7 +129,6 @@ async fn test_pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> Any println!("Testing PumpFun trading..."); let client = test_create_solana_trade_client().await?; - let creator = Pubkey::from_str("xxxxxx")?; let mint_pubkey = Pubkey::from_str("xxxxxx")?; let buy_sol_cost = 100_000; let slippage_basis_points = Some(100); @@ -143,7 +140,6 @@ async fn test_pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> Any .buy( DexType::PumpFun, mint_pubkey, - Some(creator), buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -161,7 +157,6 @@ async fn test_pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> Any .sell( DexType::PumpFun, mint_pubkey, - Some(creator), amount_token, slippage_basis_points, recent_blockhash, @@ -185,7 +180,6 @@ async fn test_pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> let client = test_create_solana_trade_client().await?; let mint_pubkey = trade_info.mint; - let creator = trade_info.creator; let slippage_basis_points = Some(100); let recent_blockhash = client.rpc.get_latest_blockhash().await?; @@ -196,18 +190,11 @@ async fn test_pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> .buy( DexType::PumpFun, mint_pubkey, - Some(creator), buy_sol_amount, slippage_basis_points, recent_blockhash, None, - Box::new(PumpFunParams::from_dev_trade( - &mint_pubkey, - trade_info.token_amount, - trade_info.max_sol_cost, - creator, - None, - )), + Box::new(PumpFunParams::from_trade(&trade_info, None)), None, true, ) @@ -220,19 +207,12 @@ async fn test_pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> .sell( DexType::PumpFun, mint_pubkey, - Some(creator), amount_token, slippage_basis_points, recent_blockhash, None, false, - Box::new(PumpFunParams::from_dev_trade( - &mint_pubkey, - trade_info.token_amount, - trade_info.max_sol_cost, - creator, - None, - )), + Box::new(PumpFunParams::from_trade(&trade_info, None)), None, true, ) @@ -245,7 +225,6 @@ async fn test_pumpswap() -> AnyResult<()> { println!("Testing PumpSwap trading..."); let client = test_create_solana_trade_client().await?; - let creator = Pubkey::from_str("11111111111111111111111111111111")?; let mint_pubkey = Pubkey::from_str("2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv")?; let buy_sol_cost = 100_000; let slippage_basis_points = Some(100); @@ -258,7 +237,6 @@ async fn test_pumpswap() -> AnyResult<()> { .buy( DexType::PumpSwap, mint_pubkey, - Some(creator), buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -277,7 +255,6 @@ async fn test_pumpswap() -> AnyResult<()> { .sell( DexType::PumpSwap, mint_pubkey, - Some(creator), amount_token, slippage_basis_points, recent_blockhash, @@ -308,7 +285,6 @@ async fn test_bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult .buy( DexType::Bonk, mint_pubkey, - None, buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -326,7 +302,6 @@ async fn test_bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult .sell( DexType::Bonk, mint_pubkey, - None, amount_token, slippage_basis_points, recent_blockhash, @@ -360,7 +335,6 @@ async fn test_bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyRe .buy( DexType::Bonk, mint_pubkey, - None, buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -378,7 +352,6 @@ async fn test_bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyRe .sell( DexType::Bonk, mint_pubkey, - None, amount_token, slippage_basis_points, recent_blockhash, @@ -408,7 +381,6 @@ async fn test_bonk() -> Result<(), Box> { .buy( DexType::Bonk, mint_pubkey, - None, buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -427,7 +399,6 @@ async fn test_bonk() -> Result<(), Box> { .sell( DexType::Bonk, mint_pubkey, - None, amount_token, slippage_basis_points, recent_blockhash, @@ -458,7 +429,6 @@ async fn test_raydium_cpmm() -> Result<(), Box> { .buy( DexType::RaydiumCpmm, mint_pubkey, - None, buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -479,7 +449,6 @@ async fn test_raydium_cpmm() -> Result<(), Box> { .sell( DexType::RaydiumCpmm, mint_pubkey, - None, amount_token, slippage_basis_points, recent_blockhash, @@ -512,7 +481,6 @@ async fn test_raydium_amm_v4() -> Result<(), Box> { .buy( DexType::RaydiumAmmV4, mint_pubkey, - None, buy_sol_cost, slippage_basis_points, recent_blockhash, @@ -531,7 +499,6 @@ async fn test_raydium_amm_v4() -> Result<(), Box> { .sell( DexType::RaydiumAmmV4, mint_pubkey, - None, amount_token, slippage_basis_points, recent_blockhash, diff --git a/src/trading/common/compute_budget_manager.rs b/src/trading/common/compute_budget_manager.rs index f92d481..61b2217 100755 --- a/src/trading/common/compute_budget_manager.rs +++ b/src/trading/common/compute_budget_manager.rs @@ -27,10 +27,10 @@ pub fn add_tip_compute_budget_instructions( instructions .push(ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(data_size_limit)); instructions.push(ComputeBudgetInstruction::set_compute_unit_price( - priority_fee.unit_price, + priority_fee.tip_unit_price, )); instructions.push(ComputeBudgetInstruction::set_compute_unit_limit( - priority_fee.unit_limit, + priority_fee.tip_unit_limit, )); } @@ -65,9 +65,9 @@ pub fn add_sell_tip_compute_budget_instructions( priority_fee: &PriorityFee, ) { instructions.push(ComputeBudgetInstruction::set_compute_unit_price( - priority_fee.unit_price, + priority_fee.tip_unit_price, )); instructions.push(ComputeBudgetInstruction::set_compute_unit_limit( - priority_fee.unit_limit, + priority_fee.tip_unit_limit, )); } diff --git a/src/trading/core/executor.rs b/src/trading/core/executor.rs index 0fffcca..192f398 100755 --- a/src/trading/core/executor.rs +++ b/src/trading/core/executor.rs @@ -102,7 +102,6 @@ impl TradeExecutor for GenericTradeExecutor { rpc: params.rpc, payer: params.payer.clone(), mint: params.mint, - creator: params.creator, sol_amount: params.sol_amount, slippage_basis_points: params.slippage_basis_points, priority_fee: params.priority_fee.clone(), @@ -208,7 +207,6 @@ impl TradeExecutor for GenericTradeExecutor { rpc: params.rpc, payer: params.payer.clone(), mint: params.mint, - creator: params.creator, token_amount: params.token_amount, slippage_basis_points: params.slippage_basis_points, priority_fee: params.priority_fee.clone(), diff --git a/src/trading/core/params.rs b/src/trading/core/params.rs index 4c4ac29..5804b86 100755 --- a/src/trading/core/params.rs +++ b/src/trading/core/params.rs @@ -5,7 +5,6 @@ use solana_streamer_sdk::streaming::event_parser::protocols::pumpswap::{ PumpSwapBuyEvent, PumpSwapSellEvent, }; use solana_streamer_sdk::streaming::event_parser::protocols::raydium_amm_v4::types::AmmInfo; -use solana_streamer_sdk::streaming::event_parser::protocols::raydium_amm_v4::RaydiumAmmV4SwapEvent; use std::sync::Arc; use super::traits::ProtocolParams; @@ -22,7 +21,9 @@ use crate::trading::bonk::common::{ get_platform_associated_account, }; use crate::trading::common::get_multi_token_balances; -use crate::trading::pumpswap::common::get_token_balances; +use crate::trading::pumpswap::common::{ + coin_creator_vault_ata, coin_creator_vault_authority, get_token_balances, +}; use crate::trading::raydium_cpmm::common::get_pool_token_balances; /// Common buy parameters @@ -32,7 +33,6 @@ pub struct BuyParams { pub rpc: Option>, pub payer: Arc, pub mint: Pubkey, - pub creator: Pubkey, pub sol_amount: u64, pub slippage_basis_points: Option, pub priority_fee: PriorityFee, @@ -51,7 +51,6 @@ pub struct BuyWithTipParams { pub swqos_clients: Vec>, pub payer: Arc, pub mint: Pubkey, - pub creator: Pubkey, pub sol_amount: u64, pub slippage_basis_points: Option, pub priority_fee: PriorityFee, @@ -69,7 +68,6 @@ pub struct SellParams { pub rpc: Option>, pub payer: Arc, pub mint: Pubkey, - pub creator: Pubkey, pub token_amount: Option, pub slippage_basis_points: Option, pub priority_fee: PriorityFee, @@ -87,7 +85,6 @@ pub struct SellWithTipParams { pub swqos_clients: Vec>, pub payer: Arc, pub mint: Pubkey, - pub creator: Pubkey, pub token_amount: Option, pub slippage_basis_points: Option, pub priority_fee: PriorityFee, @@ -102,29 +99,33 @@ pub struct SellWithTipParams { #[derive(Clone)] pub struct PumpFunParams { pub bonding_curve: Arc, + pub creator_vault: Pubkey, /// Whether to close token account when selling, only effective during sell operations pub close_token_account_when_sell: Option, } impl PumpFunParams { - pub fn immediate_sell(creator: Pubkey, close_token_account_when_sell: bool) -> Self { + pub fn immediate_sell(creator_vault: Pubkey, close_token_account_when_sell: bool) -> Self { Self { - bonding_curve: Arc::new(BondingCurveAccount { creator, ..Default::default() }), + bonding_curve: Arc::new(BondingCurveAccount { ..Default::default() }), + creator_vault: creator_vault, close_token_account_when_sell: Some(close_token_account_when_sell), } } pub fn from_dev_trade( - mint: &Pubkey, - dev_token_amount: u64, - dev_sol_amount: u64, - creator: Pubkey, + event: &PumpFunTradeEvent, close_token_account_when_sell: Option, ) -> Self { - let bonding_curve = - BondingCurveAccount::from_dev_trade(mint, dev_token_amount, dev_sol_amount, creator); + let bonding_curve = BondingCurveAccount::from_dev_trade( + &event.mint, + event.token_amount, + event.max_sol_cost, + event.creator, + ); Self { bonding_curve: Arc::new(bonding_curve), + creator_vault: event.creator_vault, close_token_account_when_sell: close_token_account_when_sell, } } @@ -136,6 +137,7 @@ impl PumpFunParams { let bonding_curve = BondingCurveAccount::from_trade(event); Self { bonding_curve: Arc::new(bonding_curve), + creator_vault: event.creator_vault, close_token_account_when_sell: close_token_account_when_sell, } } @@ -173,6 +175,10 @@ pub struct PumpSwapParams { pub pool_base_token_reserves: u64, /// Quote token reserves in the pool pub pool_quote_token_reserves: u64, + /// Coin creator vault ATA + pub coin_creator_vault_ata: Pubkey, + /// Coin creator vault authority + pub coin_creator_vault_authority: Pubkey, /// Automatically handle WSOL wrapping /// When true, automatically handles wrapping and unwrapping operations between SOL and WSOL pub auto_handle_wsol: bool, @@ -186,6 +192,8 @@ impl PumpSwapParams { quote_mint: event.quote_mint, 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, + coin_creator_vault_authority: event.coin_creator_vault_authority, auto_handle_wsol: true, } } @@ -197,6 +205,8 @@ impl PumpSwapParams { quote_mint: event.quote_mint, 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, + coin_creator_vault_authority: event.coin_creator_vault_authority, auto_handle_wsol: true, } } @@ -208,12 +218,17 @@ impl PumpSwapParams { let pool_data = crate::trading::pumpswap::common::fetch_pool(rpc, pool_address).await?; let (pool_base_token_reserves, pool_quote_token_reserves) = get_token_balances(&pool_data, rpc).await?; + let creator = pool_data.creator; + let coin_creator_vault_ata = coin_creator_vault_ata(creator, pool_data.quote_mint); + let coin_creator_vault_authority = coin_creator_vault_authority(creator); Ok(Self { pool: pool_address.clone(), base_mint: pool_data.base_mint, quote_mint: pool_data.quote_mint, pool_base_token_reserves: pool_base_token_reserves, pool_quote_token_reserves: pool_quote_token_reserves, + coin_creator_vault_ata: coin_creator_vault_ata, + coin_creator_vault_authority: coin_creator_vault_authority, auto_handle_wsol: true, }) } @@ -495,7 +510,6 @@ impl BuyParams { swqos_clients, payer: self.payer, mint: self.mint, - creator: self.creator, sol_amount: self.sol_amount, slippage_basis_points: self.slippage_basis_points, priority_fee: self.priority_fee, @@ -517,7 +531,6 @@ impl SellParams { swqos_clients, payer: self.payer, mint: self.mint, - creator: self.creator, token_amount: self.token_amount, slippage_basis_points: self.slippage_basis_points, priority_fee: self.priority_fee, diff --git a/src/trading/pumpfun/common.rs b/src/trading/pumpfun/common.rs index 9d07769..429816a 100755 --- a/src/trading/pumpfun/common.rs +++ b/src/trading/pumpfun/common.rs @@ -16,15 +16,6 @@ lazy_static::lazy_static! { static ref ACCOUNT_CACHE: RwLock>> = RwLock::new(HashMap::new()); } -#[inline] -pub fn create_priority_fee_instructions(priority_fee: PriorityFee) -> Vec { - let mut instructions = Vec::with_capacity(2); - instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(priority_fee.unit_limit)); - instructions.push(ComputeBudgetInstruction::set_compute_unit_price(priority_fee.unit_price)); - - instructions -} - #[inline] pub fn get_global_pda() -> Pubkey { static GLOBAL_PDA: once_cell::sync::Lazy = once_cell::sync::Lazy::new(|| {