feat: add transaction simulation support and close_mint_token_ata parameter

- Add `simulate` parameter to TradeBuyParams and TradeSellParams for transaction simulation
- Add `close_mint_token_ata` parameter to TradeSellParams for closing mint token ATA
- Implement simulate_transaction function to validate transactions without blockchain submission
- Update all examples to include new parameters (simulate: false, close_mint_token_ata: false)
- Add comprehensive documentation for transaction simulation feature
- Show detailed simulation output including logs, compute units, and errors
- Print timing metrics in English for better international compatibility
This commit is contained in:
ysq
2025-10-30 22:11:55 +08:00
parent 11383a0492
commit d5834e056f
19 changed files with 307 additions and 27 deletions
+1
View File
@@ -158,6 +158,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.buy(buy_params).await?;
+3
View File
@@ -166,6 +166,7 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()>
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -208,8 +209,10 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()>
durable_nonce: None,
create_output_token_ata: false,
close_output_token_ata: false,
close_mint_token_ata: false,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
+3
View File
@@ -136,6 +136,7 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -168,11 +169,13 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: true,
close_mint_token_ata: false,
open_seed_optimize: false,
with_tip: false,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
+15
View File
@@ -634,6 +634,7 @@ async fn handle_buy_pumpfun(
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.buy(buy_params).await {
Ok((_, signature)) => {
@@ -688,6 +689,7 @@ async fn handle_buy_pumpswap(
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.buy(buy_params).await {
Ok((_, signature)) => {
@@ -741,6 +743,7 @@ async fn handle_buy_bonk(
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.buy(buy_params).await {
Ok((_, signature)) => {
@@ -798,6 +801,7 @@ async fn handle_buy_raydium_v4(
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.buy(buy_params).await {
Ok((_, signature)) => {
@@ -855,6 +859,7 @@ async fn handle_buy_raydium_cpmm(
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.buy(buy_params).await {
Ok((_, signature)) => {
@@ -1018,10 +1023,12 @@ async fn handle_sell_pumpfun(
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: false,
close_mint_token_ata: false,
open_seed_optimize: use_seed,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.sell(sell_params).await {
@@ -1075,10 +1082,12 @@ async fn handle_sell_pumpswap(
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: false,
close_mint_token_ata: false,
open_seed_optimize: use_seed,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.sell(sell_params).await {
Ok((_, signature)) => {
@@ -1131,10 +1140,12 @@ async fn handle_sell_bonk(
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: false,
close_mint_token_ata: false,
open_seed_optimize: use_seed,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.sell(sell_params).await {
Ok((_, signature)) => {
@@ -1190,10 +1201,12 @@ async fn handle_sell_raydium_v4(
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: false,
close_mint_token_ata: false,
open_seed_optimize: use_seed,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.sell(sell_params).await {
Ok((_, signature)) => {
@@ -1249,10 +1262,12 @@ async fn handle_sell_raydium_cpmm(
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: false,
close_mint_token_ata: false,
open_seed_optimize: use_seed,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
match client.sell(sell_params).await {
Ok((_, signature)) => {
@@ -46,7 +46,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: Some(1),
gas_fee_strategy: gas_fee_strategy.clone()
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -75,10 +76,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
wait_transaction_confirmed: true,
create_output_token_ata: false, //if output token is SOL/WSOL,set to true,if output token is USDC,set to false.
close_output_token_ata: false, //if output token is SOL/WSOL,set to true,if output token is USDC,set to false.
close_mint_token_ata: false,
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: Some(1),
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
+1
View File
@@ -102,6 +102,7 @@ async fn test_middleware() -> AnyResult<()> {
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
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");
+1
View File
@@ -158,6 +158,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
durable_nonce: durable_nonce,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.buy(buy_params).await?;
@@ -154,6 +154,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -192,10 +193,12 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
wait_transaction_confirmed: true,
create_output_token_ata: false,
close_output_token_ata: false,
close_mint_token_ata: false,
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
@@ -120,6 +120,7 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -147,10 +148,12 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: true,
close_mint_token_ata: false,
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
@@ -47,6 +47,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -74,10 +75,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: true,
close_mint_token_ata: false,
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
+3
View File
@@ -216,6 +216,7 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) -
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -245,10 +246,12 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) -
wait_transaction_confirmed: true,
create_output_token_ata: is_sol,
close_output_token_ata: is_sol,
close_mint_token_ata: false,
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
@@ -164,6 +164,7 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -192,10 +193,12 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
wait_transaction_confirmed: true,
create_output_token_ata: is_wsol,
close_output_token_ata: is_wsol,
close_mint_token_ata: false,
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
@@ -158,6 +158,7 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -188,10 +189,12 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
wait_transaction_confirmed: true,
create_output_token_ata: is_wsol,
close_output_token_ata: is_wsol,
close_mint_token_ata: false,
open_seed_optimize: false,
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;
+3
View File
@@ -46,6 +46,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy.clone(),
simulate: false,
};
client.buy(buy_params).await?;
@@ -81,10 +82,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
wait_transaction_confirmed: true,
create_output_token_ata: true,
close_output_token_ata: true,
close_mint_token_ata: false,
open_seed_optimize: true, // ❗️❗️❗️❗️ open seed optimize
durable_nonce: None,
fixed_output_token_amount: None,
gas_fee_strategy: gas_fee_strategy,
simulate: false,
};
client.sell(sell_params).await?;