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
This commit is contained in:
ysq
2025-08-23 20:37:03 +08:00
parent 20767ae597
commit 90ea46ea3f
14 changed files with 128 additions and 203 deletions
+6 -2
View File
@@ -1,8 +1,12 @@
[package]
name = "sol-trade-sdk"
version = "0.4.7"
version = "0.5.0"
edition = "2021"
authors = ["William <byteblock6@gmail.com>", "sgxiang <sgxiang@gmail.com>", "wei <1415121722@qq.com>"]
authors = [
"William <byteblock6@gmail.com>",
"sgxiang <sgxiang@gmail.com>",
"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"
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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"
```
## 使用示例
+25 -20
View File
@@ -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<SwqosConfig>,
priority_fee: PriorityFee,
commitment: CommitmentConfig,
priority_fee: PriorityFee,
commitment: CommitmentConfig,
lookup_table_key: Option<Pubkey>,
) -> 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<Keypair>, rpc: Arc<RpcClient>, nonblocking_rpc: Arc<SolanaRpcClient>, jito_client: Arc<SwqosClient>) -> Self {
pub fn new(
payer: Arc<Keypair>,
rpc: Arc<RpcClient>,
nonblocking_rpc: Arc<SolanaRpcClient>,
jito_client: Arc<SwqosClient>,
) -> Self {
Self { payer, rpc, nonblocking_rpc, jito_client }
}
}
-4
View File
@@ -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
+2 -2
View File
@@ -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;
+18 -4
View File
@@ -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(&params.creator).unwrap();
let creator_vault_pda = protocol_params.creator_vault;
let ata = get_associated_token_address(&params.payer.pubkey(), &params.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(
+38 -12
View File
@@ -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<Vec<Instruction>> {
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,
&params.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,
&params.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<Vec<Instruction>> {
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,
&params.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,
&params.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(
-89
View File
@@ -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<Pubkey>,
sol_amount: u64,
slippage_basis_points: Option<u64>,
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<Pubkey>,
token_amount: u64,
slippage_basis_points: Option<u64>,
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<Pubkey>,
amount_token: u64,
percent: u64,
slippage_basis_points: Option<u64>,
@@ -447,7 +359,6 @@ impl SolanaTrade {
self.sell(
dex_type,
mint,
creator,
amount,
slippage_basis_points,
recent_blockhash,
+2 -35
View File
@@ -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<dyn std::error::Error>> {
.buy(
DexType::Bonk,
mint_pubkey,
None,
buy_sol_cost,
slippage_basis_points,
recent_blockhash,
@@ -427,7 +399,6 @@ async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
.sell(
DexType::Bonk,
mint_pubkey,
None,
amount_token,
slippage_basis_points,
recent_blockhash,
@@ -458,7 +429,6 @@ async fn test_raydium_cpmm() -> Result<(), Box<dyn std::error::Error>> {
.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<dyn std::error::Error>> {
.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<dyn std::error::Error>> {
.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<dyn std::error::Error>> {
.sell(
DexType::RaydiumAmmV4,
mint_pubkey,
None,
amount_token,
slippage_basis_points,
recent_blockhash,
+4 -4
View File
@@ -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,
));
}
-2
View File
@@ -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(),
+29 -16
View File
@@ -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<Arc<SolanaRpcClient>>,
pub payer: Arc<Keypair>,
pub mint: Pubkey,
pub creator: Pubkey,
pub sol_amount: u64,
pub slippage_basis_points: Option<u64>,
pub priority_fee: PriorityFee,
@@ -51,7 +51,6 @@ pub struct BuyWithTipParams {
pub swqos_clients: Vec<Arc<SwqosClient>>,
pub payer: Arc<Keypair>,
pub mint: Pubkey,
pub creator: Pubkey,
pub sol_amount: u64,
pub slippage_basis_points: Option<u64>,
pub priority_fee: PriorityFee,
@@ -69,7 +68,6 @@ pub struct SellParams {
pub rpc: Option<Arc<SolanaRpcClient>>,
pub payer: Arc<Keypair>,
pub mint: Pubkey,
pub creator: Pubkey,
pub token_amount: Option<u64>,
pub slippage_basis_points: Option<u64>,
pub priority_fee: PriorityFee,
@@ -87,7 +85,6 @@ pub struct SellWithTipParams {
pub swqos_clients: Vec<Arc<SwqosClient>>,
pub payer: Arc<Keypair>,
pub mint: Pubkey,
pub creator: Pubkey,
pub token_amount: Option<u64>,
pub slippage_basis_points: Option<u64>,
pub priority_fee: PriorityFee,
@@ -102,29 +99,33 @@ pub struct SellWithTipParams {
#[derive(Clone)]
pub struct PumpFunParams {
pub bonding_curve: Arc<BondingCurveAccount>,
pub creator_vault: Pubkey,
/// Whether to close token account when selling, only effective during sell operations
pub close_token_account_when_sell: Option<bool>,
}
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<bool>,
) -> 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,
-9
View File
@@ -16,15 +16,6 @@ lazy_static::lazy_static! {
static ref ACCOUNT_CACHE: RwLock<HashMap<Pubkey, Arc<GlobalAccount>>> = RwLock::new(HashMap::new());
}
#[inline]
pub fn create_priority_fee_instructions(priority_fee: PriorityFee) -> Vec<Instruction> {
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<Pubkey> = once_cell::sync::Lazy::new(|| {