refactor: simplify trading API and improve configuration management
- Remove `with_tip` parameter from buy/sell methods, always use tip-enabled transactions - Fix variable naming inconsistencies (token_amount -> amount_token) - Add automatic padding logic for buy_tip_fees array to match swqos_configs length - Update README examples with corrected variable references and API usage - Fix bug in test_pumpswap() using wrong DexType (PumpFun -> PumpSwap) - Improve API documentation with clearer parameter descriptions - Clean up code formatting and remove unnecessary blank lines Breaking Changes: - buy() and sell() method signatures changed (removed with_tip parameter) - Variable naming standardized across codebase
This commit is contained in:
@@ -234,7 +234,7 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
||||
let dev_sol_amount = trade_info.max_sol_cost;
|
||||
let dev_token_amount = trade_info.token_amount;
|
||||
let slippage_basis_points = Some(100);
|
||||
let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?;
|
||||
let recent_blockhash = trade_client.rpc.get_latest_blockhash().await?;
|
||||
|
||||
println!("Buying tokens from PumpFun...");
|
||||
|
||||
@@ -248,7 +248,6 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
||||
|
||||
// my trade cost sol amount
|
||||
let buy_sol_amount = 100_000;
|
||||
|
||||
trade_client.buy(
|
||||
DexType::PumpFun,
|
||||
mint_pubkey,
|
||||
@@ -257,7 +256,6 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
Some(Box::new(PumpFunParams {
|
||||
bonding_curve: Some(Arc::new(bonding_curve.clone())),
|
||||
})),
|
||||
@@ -294,7 +292,6 @@ async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> An
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
Some(Box::new(PumpFunParams {
|
||||
bonding_curve: Some(Arc::new(bonding_curve.clone())),
|
||||
})),
|
||||
@@ -306,17 +303,15 @@ async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> An
|
||||
|
||||
// pumpfun sell token
|
||||
async fn test_pumpfun_sell() -> AnyResult<()> {
|
||||
let token_amount = 100_000_000;
|
||||
|
||||
let amount_token = 100_000_000;
|
||||
trade_client.sell(
|
||||
DexType::PumpFun,
|
||||
mint_pubkey,
|
||||
Some(creator),
|
||||
token_amount,
|
||||
amount_token,
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
@@ -331,13 +326,14 @@ async fn test_pumpswap() -> AnyResult<()> {
|
||||
|
||||
let trade_client = test_create_solana_trade_client().await?;
|
||||
|
||||
let mint_pubkey = Pubkey::from_str("xxxxxxxx")?; // token mint
|
||||
let creator = Pubkey::from_str("xxxxxxxxx")?; // dev account
|
||||
let buy_sol_amount = 100_000; // 0.0001 SOL
|
||||
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||
let creator = Pubkey::from_str("xxxxxx")?;
|
||||
let buy_sol_amount = 100_000;
|
||||
let slippage_basis_points = Some(100);
|
||||
let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?;
|
||||
let recent_blockhash = trade_client.rpc.get_latest_blockhash().await?;
|
||||
|
||||
println!("Buying tokens from PumpSwap...");
|
||||
// buy
|
||||
trade_client.buy(
|
||||
DexType::PumpSwap,
|
||||
mint_pubkey,
|
||||
@@ -346,23 +342,23 @@ async fn test_pumpswap() -> AnyResult<()> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
||||
|
||||
// sell
|
||||
println!("Selling tokens from PumpSwap...");
|
||||
let token_amount = 100_000;
|
||||
|
||||
let amount_token = 100_000;
|
||||
trade_client.sell(
|
||||
DexType::PumpSwap,
|
||||
mint_pubkey,
|
||||
Some(creator),
|
||||
token_amount,
|
||||
amount_token,
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
@@ -380,12 +376,12 @@ async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let trade_client = test_create_solana_trade_client().await?;
|
||||
|
||||
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||
let buy_sol_amount = 100_000; // 0.0001 SOL
|
||||
let buy_sol_amount = 100_000;
|
||||
let slippage_basis_points = Some(100); // 1%
|
||||
let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?;
|
||||
|
||||
let recent_blockhash = trade_client.rpc.get_latest_blockhash().await?;
|
||||
|
||||
println!("Buying tokens from letsbonk.fun...");
|
||||
|
||||
trade_client.buy(
|
||||
DexType::Bonk,
|
||||
mint_pubkey,
|
||||
@@ -394,23 +390,21 @@ async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
println!("Selling tokens from letsbonk.fun...");
|
||||
|
||||
let token_amount = 100_000;
|
||||
let amount_token = 100_000;
|
||||
trade_client.sell(
|
||||
DexType::Bonk,
|
||||
mint_pubkey,
|
||||
None,
|
||||
token_amount,
|
||||
amount_token,
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
@@ -449,7 +443,7 @@ let trade_config = TradeConfig {
|
||||
|
||||
- **PumpFun**: Primary meme coin trading platform
|
||||
- **PumpSwap**: PumpFun's swap protocol
|
||||
- **Bonk**: token launch platform (letsbonk.fun)
|
||||
- **Bonk**: Token launch platform (letsbonk.fun)
|
||||
|
||||
## MEV Protection Services
|
||||
|
||||
|
||||
@@ -256,7 +256,6 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
Some(Box::new(PumpFunParams {
|
||||
bonding_curve: Some(Arc::new(bonding_curve.clone())),
|
||||
})),
|
||||
@@ -292,7 +291,6 @@ async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> An
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
Some(Box::new(PumpFunParams {
|
||||
bonding_curve: Some(Arc::new(bonding_curve.clone())),
|
||||
})),
|
||||
@@ -313,7 +311,6 @@ async fn test_pumpfun_sell() -> AnyResult<()> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
@@ -344,7 +341,6 @@ async fn test_pumpswap() -> AnyResult<()> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
@@ -361,7 +357,6 @@ async fn test_pumpswap() -> AnyResult<()> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
@@ -393,7 +388,6 @@ async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
@@ -409,7 +403,6 @@ async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
+35
-40
@@ -48,7 +48,7 @@ impl Clone for SolanaTrade {
|
||||
|
||||
impl SolanaTrade {
|
||||
#[inline]
|
||||
pub async fn new(payer: Arc<Keypair>, trade_config: TradeConfig) -> Self {
|
||||
pub async fn new(payer: Arc<Keypair>, mut trade_config: TradeConfig) -> Self {
|
||||
if CryptoProvider::get_default().is_none() {
|
||||
let _ = default_provider()
|
||||
.install_default()
|
||||
@@ -57,8 +57,22 @@ impl SolanaTrade {
|
||||
|
||||
let rpc_url = trade_config.rpc_url.clone();
|
||||
let swqos_configs = trade_config.swqos_configs.clone();
|
||||
let priority_fee = trade_config.priority_fee.clone();
|
||||
let mut priority_fee = trade_config.priority_fee.clone();
|
||||
let commitment = trade_config.commitment.clone();
|
||||
if priority_fee.buy_tip_fees.len() < swqos_configs.len() {
|
||||
// 补齐数组,只补齐缺少的
|
||||
let mut buy_tip_fees = priority_fee.buy_tip_fees.clone();
|
||||
let default_fee = priority_fee.buy_tip_fee;
|
||||
// 计算需要补充的元素数量
|
||||
let missing_count = swqos_configs.len() - buy_tip_fees.len();
|
||||
// 添加缺少的元素,使用默认值
|
||||
for _ in 0..missing_count {
|
||||
buy_tip_fees.push(default_fee);
|
||||
}
|
||||
// 更新 priority_fee 中的 buy_tip_fees
|
||||
priority_fee.buy_tip_fees = buy_tip_fees;
|
||||
trade_config.priority_fee = priority_fee.clone();
|
||||
}
|
||||
|
||||
let mut swqos_clients: Vec<Arc<SwqosClient>> = vec![];
|
||||
|
||||
@@ -105,15 +119,14 @@ impl SolanaTrade {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `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)
|
||||
/// * `amount_sol` - Amount of SOL to spend on the purchase (in lamports)
|
||||
/// * `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
|
||||
/// * `custom_buy_tip_fee` - Optional custom tip fee for priority processing (in SOL)
|
||||
/// * `with_tip` - Whether to include tip for MEV protection and priority processing
|
||||
/// * `protocol` - Trading protocol to use (PumpFun, PumpSwap, or Bonk)
|
||||
/// * `protocol_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
/// * `extension_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@@ -132,22 +145,21 @@ impl SolanaTrade {
|
||||
/// ```rust
|
||||
/// use solana_sdk::pubkey::Pubkey;
|
||||
/// use solana_sdk::hash::Hash;
|
||||
/// use crate::trading::factory::TradingProtocol;
|
||||
/// use crate::trading::factory::DexType;
|
||||
///
|
||||
/// let mint = Pubkey::new_unique();
|
||||
/// let amount_sol = 1_000_000_000; // 1 SOL in lamports
|
||||
/// 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,
|
||||
/// amount_sol,
|
||||
/// sol_amount,
|
||||
/// slippage,
|
||||
/// recent_blockhash,
|
||||
/// None,
|
||||
/// true,
|
||||
/// TradingProtocol::PumpFun,
|
||||
/// None,
|
||||
/// ).await?;
|
||||
/// ```
|
||||
@@ -160,7 +172,6 @@ impl SolanaTrade {
|
||||
slippage_basis_points: Option<u64>,
|
||||
recent_blockhash: Hash,
|
||||
custom_buy_tip_fee: Option<f64>,
|
||||
with_tip: bool,
|
||||
extension_params: Option<Box<dyn ProtocolParams>>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let executor = TradeFactory::create_executor(dex_type.clone());
|
||||
@@ -222,27 +233,21 @@ impl SolanaTrade {
|
||||
return Err(anyhow::anyhow!("Invalid protocol params for Trade"));
|
||||
}
|
||||
|
||||
// Execute buy based on tip preference
|
||||
if with_tip {
|
||||
executor.buy_with_tip(buy_with_tip_params).await
|
||||
} else {
|
||||
executor.buy(buy_params).await
|
||||
}
|
||||
executor.buy_with_tip(buy_with_tip_params).await
|
||||
}
|
||||
|
||||
/// Execute a sell order for a specified token
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `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` - Amount of tokens to sell (in smallest token units)
|
||||
/// * `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
|
||||
/// * `custom_buy_tip_fee` - Optional custom tip fee for priority processing (in SOL)
|
||||
/// * `with_tip` - Whether to include tip for MEV protection and priority processing
|
||||
/// * `protocol` - Trading protocol to use (PumpFun, PumpSwap, or Bonk)
|
||||
/// * `protocol_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
/// * `extension_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@@ -265,19 +270,18 @@ impl SolanaTrade {
|
||||
/// use crate::trading::factory::DexType;
|
||||
///
|
||||
/// let mint = Pubkey::new_unique();
|
||||
/// let amount_token = 1_000_000; // Amount of tokens to sell
|
||||
/// 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,
|
||||
/// amount_token,
|
||||
/// token_amount,
|
||||
/// slippage,
|
||||
/// recent_blockhash,
|
||||
/// None,
|
||||
/// true,
|
||||
/// DexType::PumpFun,
|
||||
/// None,
|
||||
/// ).await?;
|
||||
/// ```
|
||||
@@ -290,7 +294,6 @@ impl SolanaTrade {
|
||||
slippage_basis_points: Option<u64>,
|
||||
recent_blockhash: Hash,
|
||||
custom_buy_tip_fee: Option<f64>,
|
||||
with_tip: bool,
|
||||
extension_params: Option<Box<dyn ProtocolParams>>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let executor = TradeFactory::create_executor(dex_type.clone());
|
||||
@@ -352,11 +355,7 @@ impl SolanaTrade {
|
||||
}
|
||||
|
||||
// Execute sell based on tip preference
|
||||
if with_tip {
|
||||
executor.sell_with_tip(sell_with_tip_params).await
|
||||
} else {
|
||||
executor.sell(sell_params).await
|
||||
}
|
||||
executor.sell_with_tip(sell_with_tip_params).await
|
||||
}
|
||||
|
||||
/// Execute a sell order for a percentage of the specified token amount
|
||||
@@ -366,6 +365,7 @@ impl SolanaTrade {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `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)
|
||||
@@ -373,9 +373,7 @@ impl SolanaTrade {
|
||||
/// * `slippage_basis_points` - Optional slippage tolerance in basis points (e.g., 100 = 1%)
|
||||
/// * `recent_blockhash` - Recent blockhash for transaction validity
|
||||
/// * `custom_buy_tip_fee` - Optional custom tip fee for priority processing (in SOL)
|
||||
/// * `with_tip` - Whether to include tip for MEV protection and priority processing
|
||||
/// * `protocol` - Trading protocol to use (PumpFun, PumpSwap, or Bonk)
|
||||
/// * `protocol_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
/// * `extension_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@@ -396,7 +394,7 @@ impl SolanaTrade {
|
||||
/// ```rust
|
||||
/// use solana_sdk::pubkey::Pubkey;
|
||||
/// use solana_sdk::hash::Hash;
|
||||
/// use crate::trading::factory::TradingProtocol;
|
||||
/// use crate::trading::factory::DexType;
|
||||
///
|
||||
/// let mint = Pubkey::new_unique();
|
||||
/// let total_tokens = 10_000_000; // Total tokens available
|
||||
@@ -406,6 +404,7 @@ impl SolanaTrade {
|
||||
///
|
||||
/// // This will sell 5_000_000 tokens (50% of 10_000_000)
|
||||
/// solana_trade.sell_by_percent(
|
||||
/// DexType::PumpFun,
|
||||
/// mint,
|
||||
/// None,
|
||||
/// total_tokens,
|
||||
@@ -413,8 +412,6 @@ impl SolanaTrade {
|
||||
/// slippage,
|
||||
/// recent_blockhash,
|
||||
/// None,
|
||||
/// true,
|
||||
/// DexType::PumpFun,
|
||||
/// None,
|
||||
/// ).await?;
|
||||
/// ```
|
||||
@@ -428,7 +425,6 @@ impl SolanaTrade {
|
||||
slippage_basis_points: Option<u64>,
|
||||
recent_blockhash: Hash,
|
||||
custom_buy_tip_fee: Option<f64>,
|
||||
with_tip: bool,
|
||||
extension_params: Option<Box<dyn ProtocolParams>>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
if percent == 0 || percent > 100 {
|
||||
@@ -443,7 +439,6 @@ impl SolanaTrade {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
custom_buy_tip_fee,
|
||||
with_tip,
|
||||
extension_params,
|
||||
)
|
||||
.await
|
||||
|
||||
+1
-9
@@ -91,7 +91,6 @@ async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> An
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
Some(Box::new(PumpFunParams {
|
||||
bonding_curve: Some(Arc::new(bonding_curve.clone())),
|
||||
})),
|
||||
@@ -108,7 +107,6 @@ async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> An
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
).await?;
|
||||
|
||||
@@ -146,7 +144,6 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
Some(Box::new(PumpFunParams {
|
||||
bonding_curve: Some(Arc::new(bonding_curve.clone())),
|
||||
})),
|
||||
@@ -163,7 +160,6 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
).await?;
|
||||
|
||||
@@ -183,14 +179,13 @@ async fn test_pumpswap() -> AnyResult<()> {
|
||||
// Buy tokens
|
||||
println!("Buying tokens from PumpSwap...");
|
||||
client.buy(
|
||||
DexType::PumpFun,
|
||||
DexType::PumpSwap,
|
||||
mint_pubkey,
|
||||
Some(creator),
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
).await?;
|
||||
|
||||
@@ -205,7 +200,6 @@ async fn test_pumpswap() -> AnyResult<()> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
).await?;
|
||||
|
||||
@@ -231,7 +225,6 @@ async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
).await?;
|
||||
|
||||
@@ -246,7 +239,6 @@ async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
).await?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user