Make use_exact_sol_amount optional with true default for PumpFun/PumpSwap

- Change use_exact_sol_amount from bool to Option<bool>
- Default to true (via unwrap_or) for PumpFun and PumpSwap DEXes
- Option is ignored for other DEXes (Raydium, Bonk, Meteora)
- Update all examples to use None (which defaults to true for applicable DEXes)
- Update README documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
vibes
2026-01-06 11:53:09 +00:00
co-authored by Claude Opus 4.5
parent ea22d48919
commit c7f694e9a0
20 changed files with 31 additions and 9 deletions
+1
View File
@@ -178,6 +178,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
fixed_output_token_amount: None, // Optional: specify exact output amount fixed_output_token_amount: None, // Optional: specify exact output amount
gas_fee_strategy: gas_fee_strategy.clone(), // Gas fee strategy configuration gas_fee_strategy: gas_fee_strategy.clone(), // Gas fee strategy configuration
simulate: false, // Set to true for simulation only simulate: false, // Set to true for simulation only
use_exact_sol_amount: None, // Use exact SOL input for PumpFun/PumpSwap (defaults to true)
}; };
``` ```
+1
View File
@@ -174,6 +174,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams {
fixed_output_token_amount: None, // 可选:指定精确输出数量 fixed_output_token_amount: None, // 可选:指定精确输出数量
gas_fee_strategy: gas_fee_strategy.clone(), // Gas 费用策略配置 gas_fee_strategy: gas_fee_strategy.clone(), // Gas 费用策略配置
simulate: false, // 设为 true 仅进行模拟 simulate: false, // 设为 true 仅进行模拟
use_exact_sol_amount: None, // 对 PumpFun/PumpSwap 使用精确 SOL 输入(默认为 true)
}; };
``` ```
+1
View File
@@ -160,6 +160,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
+1
View File
@@ -175,6 +175,7 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()>
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
+1
View File
@@ -143,6 +143,7 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
+5
View File
@@ -634,6 +634,7 @@ async fn handle_buy_pumpfun(
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
match client.buy(buy_params).await { match client.buy(buy_params).await {
Ok((_, signature, _)) => { Ok((_, signature, _)) => {
@@ -688,6 +689,7 @@ async fn handle_buy_pumpswap(
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
match client.buy(buy_params).await { match client.buy(buy_params).await {
Ok((_, signature, _)) => { Ok((_, signature, _)) => {
@@ -741,6 +743,7 @@ async fn handle_buy_bonk(
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
match client.buy(buy_params).await { match client.buy(buy_params).await {
Ok((_, signature, _)) => { Ok((_, signature, _)) => {
@@ -798,6 +801,7 @@ async fn handle_buy_raydium_v4(
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
match client.buy(buy_params).await { match client.buy(buy_params).await {
Ok((_, signature, _)) => { Ok((_, signature, _)) => {
@@ -855,6 +859,7 @@ async fn handle_buy_raydium_cpmm(
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
match client.buy(buy_params).await { match client.buy(buy_params).await {
Ok((_, signature, _)) => { Ok((_, signature, _)) => {
@@ -43,6 +43,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
fixed_output_token_amount: Some(1), fixed_output_token_amount: Some(1),
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
+1
View File
@@ -102,6 +102,7 @@ async fn test_middleware() -> AnyResult<()> {
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
println!("tip: This transaction will not succeed because we're using a test account. You can modify the code to initialize the payer with your own private key"); println!("tip: This transaction will not succeed because we're using a test account. You can modify the code to initialize the payer with your own private key");
+1
View File
@@ -160,6 +160,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy, gas_fee_strategy: gas_fee_strategy,
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
@@ -163,6 +163,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
@@ -122,6 +122,7 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
@@ -43,6 +43,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
+1
View File
@@ -220,6 +220,7 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) -
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
@@ -173,6 +173,7 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
@@ -158,6 +158,7 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
+1
View File
@@ -46,6 +46,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
fixed_output_token_amount: None, fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(), gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false, simulate: false,
use_exact_sol_amount: None,
}; };
client.buy(buy_params).await?; client.buy(buy_params).await?;
+1 -1
View File
@@ -118,7 +118,7 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
} }
let mut buy_data = [0u8; 24]; let mut buy_data = [0u8; 24];
if params.use_exact_sol_amount { if params.use_exact_sol_amount.unwrap_or(true) {
// buy_exact_sol_in(spendable_sol_in: u64, min_tokens_out: u64) // buy_exact_sol_in(spendable_sol_in: u64, min_tokens_out: u64)
// Spend exactly the input SOL amount, get at least min_tokens_out // Spend exactly the input SOL amount, get at least min_tokens_out
let min_tokens_out = calculate_with_slippage_sell( let min_tokens_out = calculate_with_slippage_sell(
+1 -1
View File
@@ -187,7 +187,7 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
// Create instruction data // Create instruction data
let mut data = [0u8; 24]; let mut data = [0u8; 24];
if quote_is_wsol_or_usdc { if quote_is_wsol_or_usdc {
if params.use_exact_sol_amount { if params.use_exact_sol_amount.unwrap_or(true) {
// buy_exact_quote_in(spendable_quote_in: u64, min_base_amount_out: u64) // buy_exact_quote_in(spendable_quote_in: u64, min_base_amount_out: u64)
// Spend exactly the input SOL/quote amount, get at least min_base_amount_out // Spend exactly the input SOL/quote amount, get at least min_base_amount_out
let min_base_amount_out = crate::utils::calc::common::calculate_with_slippage_sell( let min_base_amount_out = crate::utils::calc::common::calculate_with_slippage_sell(
+5 -4
View File
@@ -188,9 +188,10 @@ pub struct TradeBuyParams {
/// Whether to simulate the transaction instead of executing it /// Whether to simulate the transaction instead of executing it
pub simulate: bool, pub simulate: bool,
/// Use exact SOL amount instructions (buy_exact_sol_in for PumpFun, buy_exact_quote_in for PumpSwap). /// Use exact SOL amount instructions (buy_exact_sol_in for PumpFun, buy_exact_quote_in for PumpSwap).
/// When true, the exact SOL/quote amount is spent and slippage is applied to output tokens. /// When Some(true) or None (default), the exact SOL/quote amount is spent and slippage is applied to output tokens.
/// When false (default), uses regular buy instruction where slippage is applied to SOL/quote input. /// When Some(false), uses regular buy instruction where slippage is applied to SOL/quote input.
pub use_exact_sol_amount: bool, /// This option only applies to PumpFun and PumpSwap DEXes; it is ignored for other DEXes.
pub use_exact_sol_amount: Option<bool>,
} }
/// Parameters for executing sell orders across different DEX protocols /// Parameters for executing sell orders across different DEX protocols
@@ -622,7 +623,7 @@ impl TradingClient {
fixed_output_amount: params.fixed_output_token_amount, fixed_output_amount: params.fixed_output_token_amount,
gas_fee_strategy: params.gas_fee_strategy, gas_fee_strategy: params.gas_fee_strategy,
simulate: params.simulate, simulate: params.simulate,
use_exact_sol_amount: false, use_exact_sol_amount: None,
}; };
// Validate protocol params // Validate protocol params
+4 -3
View File
@@ -68,9 +68,10 @@ pub struct SwapParams {
pub gas_fee_strategy: GasFeeStrategy, pub gas_fee_strategy: GasFeeStrategy,
pub simulate: bool, pub simulate: bool,
/// Use exact SOL amount instructions (buy_exact_sol_in for PumpFun, buy_exact_quote_in for PumpSwap). /// Use exact SOL amount instructions (buy_exact_sol_in for PumpFun, buy_exact_quote_in for PumpSwap).
/// When true, the exact SOL/quote amount is spent and slippage is applied to output tokens. /// When Some(true) or None (default), the exact SOL/quote amount is spent and slippage is applied to output tokens.
/// When false (default), uses regular buy instruction where slippage is applied to SOL/quote input. /// When Some(false), uses regular buy instruction where slippage is applied to SOL/quote input.
pub use_exact_sol_amount: bool, /// This option only applies to PumpFun and PumpSwap DEXes; it is ignored for other DEXes.
pub use_exact_sol_amount: Option<bool>,
} }
impl std::fmt::Debug for SwapParams { impl std::fmt::Debug for SwapParams {