From 85154f6c01689759fdae09e4c1d1efeaba937a93 Mon Sep 17 00:00:00 2001 From: ysq Date: Tue, 7 Oct 2025 23:12:37 +0800 Subject: [PATCH] refactor: Update GasFeeStrategy to instance-based API and update docs --- README.md | 6 +- README_CN.md | 5 +- docs/GAS_FEE_STRATEGY.md | 45 ++++++--- docs/GAS_FEE_STRATEGY_CN.md | 43 +++++--- docs/TRADING_PARAMETERS.md | 2 + docs/TRADING_PARAMETERS_CN.md | 2 + examples/address_lookup/src/main.rs | 8 +- examples/bonk_copy_trading/src/main.rs | 9 +- examples/bonk_sniper_trading/src/main.rs | 7 +- examples/cli_trading/src/main.rs | 42 +++++++- examples/gas_fee_strategy/src/main.rs | 22 +++-- .../src/main.rs | 7 +- examples/middleware_system/src/main.rs | 6 +- examples/nonce_cache/src/main.rs | 6 +- examples/pumpfun_copy_trading/src/main.rs | 7 +- examples/pumpfun_sniper_trading/src/main.rs | 7 +- examples/pumpswap_direct_trading/src/main.rs | 7 +- examples/pumpswap_trading/src/main.rs | 7 +- examples/raydium_amm_v4_trading/src/main.rs | 8 +- examples/raydium_cpmm_trading/src/main.rs | 9 +- examples/seed_trading/src/main.rs | 7 +- examples/trading_client/src/main.rs | 2 - examples/wsol_wrapper/src/main.rs | 2 - src/common/gas_fee_strategy.rs | 99 +++++++++++-------- src/lib.rs | 7 ++ src/trading/core/async_executor.rs | 13 +-- src/trading/core/executor.rs | 1 + src/trading/core/params.rs | 3 +- 28 files changed, 269 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index d12d0e5..e593c85 100644 --- a/README.md +++ b/README.md @@ -133,8 +133,12 @@ let client = SolanaTrade::new(Arc::new(payer), trade_config).await; #### 2. Configure Gas Fee Strategy For detailed information about Gas Fee Strategy, see the [Gas Fee Strategy Reference](docs/GAS_FEE_STRATEGY.md). + ```rust -GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); +// Create GasFeeStrategy instance +let gas_fee_strategy = GasFeeStrategy::new(); +// Set global strategy +gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); ``` #### 3. Build Trading Parameters diff --git a/README_CN.md b/README_CN.md index 722e548..6ae2bb7 100755 --- a/README_CN.md +++ b/README_CN.md @@ -133,9 +133,12 @@ let client = SolanaTrade::new(Arc::new(payer), trade_config).await; #### 2. 配置 Gas Fee 策略 有关 Gas Fee 策略的详细信息,请参阅 [Gas Fee 策略参考手册](docs/GAS_FEE_STRATEGY_CN.md)。 + ```rust +// 创建 GasFeeStrategy 实例 +let gas_fee_strategy = GasFeeStrategy::new(); // 设置全局策略 -GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); +gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); ``` #### 3. 构建交易参数 diff --git a/docs/GAS_FEE_STRATEGY.md b/docs/GAS_FEE_STRATEGY.md index a8a30e7..e243969 100644 --- a/docs/GAS_FEE_STRATEGY.md +++ b/docs/GAS_FEE_STRATEGY.md @@ -13,12 +13,20 @@ This module supports users to configure strategies for SwqosType under different Each (SwqosType, TradeType) combination can only configure one strategy. Subsequent strategy configurations will override previous ones. -### 2. Set Global Strategy (can also be configured individually) +### 2. Create GasFeeStrategy Instance + +```rust +use sol_trade_sdk::common::GasFeeStrategy; + +// Create a new GasFeeStrategy instance +let gas_fee_strategy = GasFeeStrategy::new(); +``` + +### 3. Set Global Strategy (can also be configured individually) ```rust -use sol_trade_sdk::common::{gas_fee_strategy::GasFeeStrategy}; // Set global strategy (normal strategy) -GasFeeStrategy::set_global_fee_strategy( +gas_fee_strategy.set_global_fee_strategy( 150000, // cu_limit 500000, // cu_price 0.001, // buy tip @@ -26,24 +34,24 @@ GasFeeStrategy::set_global_fee_strategy( ); ``` -### 3. Configuring Single Strategy +### 4. Configuring Single Strategy ```rust -// Configure normal strategy for SwqosType::Jito during Buy -GasFeeStrategy::set_normal_fee_strategy( +// Configure normal strategy for SwqosType::Jito +gas_fee_strategy.set_normal_fee_strategy( SwqosType::Jito, xxxxx, // cu_limit xxxx, // cu_price xxxxx, // buy_tip - xxxxx, // sell_tip + xxxxx // sell_tip ); ``` -### 4. Configuring High-Low Fee Strategy +### 5. Configuring High-Low Fee Strategy ```rust // Configure high-low fee strategy for SwqosType::Jito during Buy -GasFeeStrategy::set_high_low_fee_strategy( +gas_fee_strategy.set_high_low_fee_strategy( SwqosType::Jito, TradeType::Buy, xxxxx, // cu_limit @@ -54,15 +62,26 @@ GasFeeStrategy::set_high_low_fee_strategy( ); ``` -### 5. Viewing and Cleanup +### 6. Using in Trading Parameters + +```rust +use sol_trade_sdk::TradeBuyParams; + +let buy_params = TradeBuyParams { + // ... other parameters + gas_fee_strategy: gas_fee_strategy.clone(), +}; +``` + +### 7. Viewing and Cleanup ```rust // Remove a specific strategy -GasFeeStrategy::del(SwqosType::Jito, TradeType::Buy); +gas_fee_strategy.del_all(SwqosType::Jito, TradeType::Buy); // View all strategies -GasFeeStrategy::print_all_strategies(); +gas_fee_strategy.print_all_strategies(); // Clear all strategies -GasFeeStrategy::clear(); +gas_fee_strategy.clear(); ``` ## 🔗 Related Documents diff --git a/docs/GAS_FEE_STRATEGY_CN.md b/docs/GAS_FEE_STRATEGY_CN.md index 6264545..fa3e9e0 100644 --- a/docs/GAS_FEE_STRATEGY_CN.md +++ b/docs/GAS_FEE_STRATEGY_CN.md @@ -13,12 +13,20 @@ 每个 (SwqosType, TradeType) 的组合仅可配置一个策略。后续配置的策略会覆盖之前的策略。 -### 2. 设置全局策略(也可以不设置,单独去配置单个策略) +### 2. 创建 GasFeeStrategy 实例 + +```rust +use sol_trade_sdk::common::GasFeeStrategy; + +// 创建一个新的 GasFeeStrategy 实例 +let gas_fee_strategy = GasFeeStrategy::new(); +``` + +### 3. 设置全局策略(也可以不设置,单独去配置单个策略) ```rust -use sol_trade_sdk::common::{gas_fee_strategy::GasFeeStrategy}; // 设置全局策略(normal 策略) -GasFeeStrategy::set_global_fee_strategy( +gas_fee_strategy.set_global_fee_strategy( 150000, // cu_limit 500000, // cu_price 0.001, // buy tip @@ -26,11 +34,11 @@ GasFeeStrategy::set_global_fee_strategy( ); ``` -### 3. 配置单个策略 +### 4. 配置单个策略 ```rust -// 为 SwqosType::Jito 在 Buy 时配置 normal 策略 -GasFeeStrategy::set_normal_fee_strategy( +// 为 SwqosType::Jito 配置 normal 策略 +gas_fee_strategy.set_normal_fee_strategy( SwqosType::Jito, xxxxx, // cu_limit xxxx, // cu_price @@ -39,11 +47,11 @@ GasFeeStrategy::set_normal_fee_strategy( ); ``` -### 4. 配置高低费率策略 +### 5. 配置高低费率策略 ```rust // 为 SwqosType::Jito 在 Buy 时配置高低费率策略 -GasFeeStrategy::set_high_low_fee_strategy( +gas_fee_strategy.set_high_low_fee_strategy( SwqosType::Jito, TradeType::Buy, xxxxx, // cu_limit @@ -54,15 +62,26 @@ GasFeeStrategy::set_high_low_fee_strategy( ); ``` -### 5. 查看和清理 +### 6. 在交易参数中使用 + +```rust +use sol_trade_sdk::TradeBuyParams; + +let buy_params = TradeBuyParams { + // ... 其他参数 + gas_fee_strategy: gas_fee_strategy.clone(), +}; +``` + +### 7. 查看和清理 ```rust // 移除某个策略 -GasFeeStrategy::del(SwqosType::Jito, TradeType::Buy); +gas_fee_strategy.del_all(SwqosType::Jito, TradeType::Buy); // 查看所有策略 -GasFeeStrategy::print_all_strategies(); +gas_fee_strategy.print_all_strategies(); // 清空所有策略 -GasFeeStrategy::clear(); +gas_fee_strategy.clear(); ``` ## 🔗 相关文档 diff --git a/docs/TRADING_PARAMETERS.md b/docs/TRADING_PARAMETERS.md index 335c4cb..8ec4b4e 100644 --- a/docs/TRADING_PARAMETERS.md +++ b/docs/TRADING_PARAMETERS.md @@ -37,6 +37,7 @@ The `TradeBuyParams` struct contains all parameters required for executing buy o | `open_seed_optimize` | `bool` | ✅ | Whether to use seed optimization for reduced CU consumption | | `durable_nonce` | `Option` | ❌ | Durable nonce information containing nonce account and current nonce value | | `fixed_output_token_amount` | `Option` | ❌ | Optional fixed output token amount. If set, this value will be directly assigned to the output amount instead of being calculated (required for Meteora DAMM V2) | +| `gas_fee_strategy` | `GasFeeStrategy` | ✅ | Gas fee strategy instance for controlling transaction fees and priorities | ## TradeSellParams @@ -66,6 +67,7 @@ The `TradeSellParams` struct contains all parameters required for executing sell | `close_output_token_ata` | `bool` | ✅ | Whether to close output token ATA after transaction | | `open_seed_optimize` | `bool` | ✅ | Whether to use seed optimization for reduced CU consumption | | `durable_nonce` | `Option` | ❌ | Durable nonce information containing nonce account and current nonce value | +| `gas_fee_strategy` | `GasFeeStrategy` | ✅ | Gas fee strategy instance for controlling transaction fees and priorities | | `fixed_output_token_amount` | `Option` | ❌ | Optional fixed output token amount. If set, this value will be directly assigned to the output amount instead of being calculated (required for Meteora DAMM V2) | diff --git a/docs/TRADING_PARAMETERS_CN.md b/docs/TRADING_PARAMETERS_CN.md index 0db166e..7a212c6 100644 --- a/docs/TRADING_PARAMETERS_CN.md +++ b/docs/TRADING_PARAMETERS_CN.md @@ -37,6 +37,7 @@ | `open_seed_optimize` | `bool` | ✅ | 是否使用 seed 优化以减少 CU 消耗 | | `durable_nonce` | `Option` | ❌ | 持久 nonce 信息,包含 nonce 账户和当前 nonce 值 | | `fixed_output_token_amount` | `Option` | ❌ | 可选的固定输出代币数量。如果设置,此值将直接分配给输出数量而不是通过计算得出(Meteora DAMM V2 必需) | +| `gas_fee_strategy` | `GasFeeStrategy` | ✅ | Gas fee 策略实例,用于控制交易费用和优先级 | ## TradeSellParams @@ -66,6 +67,7 @@ | `close_output_token_ata` | `bool` | ✅ | 交易后是否关闭输出代币 ATA | | `open_seed_optimize` | `bool` | ✅ | 是否使用 seed 优化以减少 CU 消耗 | | `durable_nonce` | `Option` | ❌ | 持久 nonce 信息,包含 nonce 账户和当前 nonce 值 | +| `gas_fee_strategy` | `GasFeeStrategy` | ✅ | Gas fee 策略实例,用于控制交易费用和优先级 | | `fixed_output_token_amount` | `Option` | ❌ | 可选的固定输出代币数量。如果设置,此值将直接分配给输出数量而不是通过计算得出(Meteora DAMM V2 必需) | diff --git a/examples/address_lookup/src/main.rs b/examples/address_lookup/src/main.rs index 6d5a86a..2adc010 100644 --- a/examples/address_lookup/src/main.rs +++ b/examples/address_lookup/src/main.rs @@ -1,5 +1,5 @@ use sol_trade_sdk::common::address_lookup::fetch_address_lookup_table_account; -use sol_trade_sdk::common::TradeConfig; +use sol_trade_sdk::common::{gas_fee_strategy, GasFeeStrategy, TradeConfig}; use sol_trade_sdk::{ common::AnyResult, swqos::SwqosConfig, @@ -106,8 +106,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -126,6 +124,9 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul let address_lookup_table_account = fetch_address_lookup_table_account(&client.rpc, &lookup_table_key).await.ok(); + let gas_fee_strategy = GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from PumpFun..."); let buy_sol_amount = 100_000; @@ -156,6 +157,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.buy(buy_params).await?; diff --git a/examples/bonk_copy_trading/src/main.rs b/examples/bonk_copy_trading/src/main.rs index 148c54e..aa272d4 100644 --- a/examples/bonk_copy_trading/src/main.rs +++ b/examples/bonk_copy_trading/src/main.rs @@ -3,7 +3,7 @@ use std::sync::{ Arc, }; -use sol_trade_sdk::common::spl_associated_token_account::get_associated_token_address; +use sol_trade_sdk::common::{spl_associated_token_account::get_associated_token_address, GasFeeStrategy}; use sol_trade_sdk::common::TradeConfig; use sol_trade_sdk::{ common::AnyResult, @@ -110,8 +110,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -126,6 +124,9 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> let slippage_basis_points = Some(100); let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from Bonk..."); let input_token_type = @@ -164,6 +165,7 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -207,6 +209,7 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> create_output_token_ata: false, close_output_token_ata: false, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; diff --git a/examples/bonk_sniper_trading/src/main.rs b/examples/bonk_sniper_trading/src/main.rs index d04cec8..6c037ac 100644 --- a/examples/bonk_sniper_trading/src/main.rs +++ b/examples/bonk_sniper_trading/src/main.rs @@ -80,8 +80,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -96,6 +94,9 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult< let slippage_basis_points = Some(300); let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let token_type = if trade_info.quote_token_mint == sol_trade_sdk::constants::USD1_TOKEN_ACCOUNT { sol_trade_sdk::TradeTokenType::USD1 @@ -134,6 +135,7 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult< open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -170,6 +172,7 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult< with_tip: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; diff --git a/examples/cli_trading/src/main.rs b/examples/cli_trading/src/main.rs index 17bf067..7876900 100644 --- a/examples/cli_trading/src/main.rs +++ b/examples/cli_trading/src/main.rs @@ -614,6 +614,9 @@ async fn handle_buy_pumpfun( let recent_blockhash = client.rpc.get_latest_blockhash().await?; let sol_lamports = sol_str_to_lamports(sol_amount.to_string().as_str()).unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let buy_params = TradeBuyParams { dex_type: DexType::PumpFun, input_token_type: TradeTokenType::SOL, @@ -630,6 +633,7 @@ async fn handle_buy_pumpfun( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.buy(buy_params).await { Ok((_, signature)) => { @@ -664,6 +668,9 @@ async fn handle_buy_pumpswap( let recent_blockhash = client.rpc.get_latest_blockhash().await?; let sol_lamports = sol_str_to_lamports(sol_amount.to_string().as_str()).unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let buy_params = TradeBuyParams { dex_type: DexType::PumpSwap, input_token_type: TradeTokenType::WSOL, @@ -680,6 +687,7 @@ async fn handle_buy_pumpswap( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.buy(buy_params).await { Ok((_, signature)) => { @@ -713,6 +721,9 @@ async fn handle_buy_bonk( let recent_blockhash = client.rpc.get_latest_blockhash().await?; let sol_lamports = sol_str_to_lamports(sol_amount.to_string().as_str()).unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let buy_params = TradeBuyParams { dex_type: DexType::Bonk, input_token_type: TradeTokenType::WSOL, @@ -729,6 +740,7 @@ async fn handle_buy_bonk( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.buy(buy_params).await { Ok((_, signature)) => { @@ -766,6 +778,9 @@ async fn handle_buy_raydium_v4( let recent_blockhash = client.rpc.get_latest_blockhash().await?; let sol_lamports = sol_str_to_lamports(sol_amount.to_string().as_str()).unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let buy_params = TradeBuyParams { dex_type: DexType::RaydiumAmmV4, input_token_type: TradeTokenType::WSOL, @@ -782,6 +797,7 @@ async fn handle_buy_raydium_v4( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.buy(buy_params).await { Ok((_, signature)) => { @@ -819,6 +835,9 @@ async fn handle_buy_raydium_cpmm( let recent_blockhash = client.rpc.get_latest_blockhash().await?; let sol_lamports = sol_str_to_lamports(sol_amount.to_string().as_str()).unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let buy_params = TradeBuyParams { dex_type: DexType::RaydiumCpmm, input_token_type: TradeTokenType::WSOL, @@ -835,6 +854,7 @@ async fn handle_buy_raydium_cpmm( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.buy(buy_params).await { Ok((_, signature)) => { @@ -982,6 +1002,9 @@ async fn handle_sell_pumpfun( let param = PumpFunParams::from_mint_by_rpc(&client.rpc, &mint_pubkey).await?; let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let sell_params = TradeSellParams { dex_type: DexType::PumpFun, output_token_type: TradeTokenType::SOL, @@ -998,6 +1021,7 @@ async fn handle_sell_pumpfun( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.sell(sell_params).await { @@ -1035,6 +1059,9 @@ async fn handle_sell_pumpswap( let param = PumpSwapParams::from_mint_by_rpc(&client.rpc, &mint_pubkey).await?; let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let sell_params = TradeSellParams { dex_type: DexType::PumpSwap, output_token_type: TradeTokenType::WSOL, @@ -1051,6 +1078,7 @@ async fn handle_sell_pumpswap( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.sell(sell_params).await { Ok((_, signature)) => { @@ -1087,6 +1115,9 @@ async fn handle_sell_bonk( let param = BonkParams::from_mint_by_rpc(&client.rpc, &mint_pubkey, false).await?; let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let sell_params = TradeSellParams { dex_type: DexType::Bonk, output_token_type: TradeTokenType::WSOL, @@ -1103,6 +1134,7 @@ async fn handle_sell_bonk( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.sell(sell_params).await { Ok((_, signature)) => { @@ -1142,6 +1174,9 @@ async fn handle_sell_raydium_v4( let param = RaydiumAmmV4Params::from_amm_address_by_rpc(&client.rpc, amm_pubkey).await?; let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let sell_params = TradeSellParams { dex_type: DexType::RaydiumAmmV4, output_token_type: TradeTokenType::WSOL, @@ -1158,6 +1193,7 @@ async fn handle_sell_raydium_v4( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.sell(sell_params).await { Ok((_, signature)) => { @@ -1197,6 +1233,9 @@ async fn handle_sell_raydium_cpmm( let param = RaydiumCpmmParams::from_pool_address_by_rpc(&client.rpc, &pool_pubkey).await?; let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let sell_params = TradeSellParams { dex_type: DexType::RaydiumCpmm, output_token_type: TradeTokenType::WSOL, @@ -1213,6 +1252,7 @@ async fn handle_sell_raydium_cpmm( open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; match client.sell(sell_params).await { Ok((_, signature)) => { @@ -1325,8 +1365,6 @@ async fn initialize_real_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(payer, trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/gas_fee_strategy/src/main.rs b/examples/gas_fee_strategy/src/main.rs index c8c1c95..3ba62a9 100644 --- a/examples/gas_fee_strategy/src/main.rs +++ b/examples/gas_fee_strategy/src/main.rs @@ -8,21 +8,23 @@ async fn main() { println!("🚀 Gas Fee Strategy Demo"); println!("========================"); + let gas_fee_strategy = GasFeeStrategy::new(); + // Set global strategy println!("1. Set global strategy"); - GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); // Print all strategies println!("\n2. Print all strategies"); - GasFeeStrategy::print_all_strategies(); + gas_fee_strategy.print_all_strategies(); // Clear all strategies println!("\n3. Clear all strategies"); - GasFeeStrategy::clear(); + gas_fee_strategy.clear(); // Add normal fee strategy for SwqosType::Default println!("\n4. Add normal fee strategy for SwqosType::Default"); - GasFeeStrategy::set_normal_fee_strategy( + gas_fee_strategy.set_normal_fee_strategy( SwqosType::Default, 150000, // cu_limit 500000, // cu_price @@ -32,7 +34,7 @@ async fn main() { // Add high-low fee strategy for SwqosType::Jito on Buy println!("\n5. Add high-low fee strategy for SwqosType::Jito on Buy"); - GasFeeStrategy::set_high_low_fee_strategy( + gas_fee_strategy.set_high_low_fee_strategy( SwqosType::Jito, TradeType::Buy, 150000, // cu_limit @@ -44,11 +46,11 @@ async fn main() { // Print all strategies println!("\n6. Print all current strategies"); - GasFeeStrategy::print_all_strategies(); + gas_fee_strategy.print_all_strategies(); // Add normal fee strategy for SwqosType::Jito on Buy (will override previous high-low strategy) println!("\n7. Add normal fee strategy for SwqosType::Jito (will override previous high-low strategy)"); - GasFeeStrategy::set_normal_fee_strategy( + gas_fee_strategy.set_normal_fee_strategy( SwqosType::Jito, 150000, // cu_limit 500000, // cu_price @@ -58,15 +60,15 @@ async fn main() { // Print all strategies println!("\n8. Print all current strategies"); - GasFeeStrategy::print_all_strategies(); + gas_fee_strategy.print_all_strategies(); // Remove strategy for SwqosType::Jito on Buy println!("\n9. Remove strategy for SwqosType::Jito on Buy"); - GasFeeStrategy::del_all(SwqosType::Jito, TradeType::Buy); + gas_fee_strategy.del_all(SwqosType::Jito, TradeType::Buy); // Print all strategies println!("\n10. Print all current strategies"); - GasFeeStrategy::print_all_strategies(); + gas_fee_strategy.print_all_strategies(); println!("\n✅ Gas Fee Strategy Demo completed!"); } diff --git a/examples/meteora_damm_v2_direct_trading/src/main.rs b/examples/meteora_damm_v2_direct_trading/src/main.rs index 05d85c5..e7d788f 100644 --- a/examples/meteora_damm_v2_direct_trading/src/main.rs +++ b/examples/meteora_damm_v2_direct_trading/src/main.rs @@ -22,6 +22,9 @@ async fn main() -> Result<(), Box> { let pool = Pubkey::from_str("35EFyWd9cH8pdHxVgXHF68L1oZxSWd1FfJASSNTUtoTC").unwrap(); let mint_pubkey = Pubkey::from_str("FhTRoy63ZiLcjLEVCMCTLc5Cu5ozrzouNg6cDp1ASZMC").unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from Metaora Damm V2..."); let buy_sol_amount = 100_000; @@ -43,6 +46,7 @@ async fn main() -> Result<(), Box> { open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: Some(1), + gas_fee_strategy: gas_fee_strategy.clone() }; client.buy(buy_params).await?; @@ -74,6 +78,7 @@ async fn main() -> Result<(), Box> { open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: Some(1), + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; @@ -91,8 +96,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/middleware_system/src/main.rs b/examples/middleware_system/src/main.rs index 8a9c045..6b0798c 100644 --- a/examples/middleware_system/src/main.rs +++ b/examples/middleware_system/src/main.rs @@ -64,8 +64,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -82,6 +80,9 @@ async fn test_middleware() -> AnyResult<()> { let recent_blockhash = client.rpc.get_latest_blockhash().await?; let pool_address = Pubkey::from_str("539m4mVWt6iduB6W8rDGPMarzNCMesuqY5eUTiiYHAgR")?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let buy_params = sol_trade_sdk::TradeBuyParams { dex_type: DexType::PumpSwap, input_token_type: TradeTokenType::WSOL, @@ -100,6 +101,7 @@ async fn test_middleware() -> AnyResult<()> { open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; 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"); diff --git a/examples/nonce_cache/src/main.rs b/examples/nonce_cache/src/main.rs index d9bd3ac..5430403 100644 --- a/examples/nonce_cache/src/main.rs +++ b/examples/nonce_cache/src/main.rs @@ -106,8 +106,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -126,6 +124,9 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul let nonce_account_str = Pubkey::from_str("use_your_nonce_account_here")?; let durable_nonce = fetch_nonce_info(&client.rpc, nonce_account_str).await; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from PumpFun..."); let buy_sol_amount = 100_000; @@ -156,6 +157,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul open_seed_optimize: false, durable_nonce: durable_nonce, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.buy(buy_params).await?; diff --git a/examples/pumpfun_copy_trading/src/main.rs b/examples/pumpfun_copy_trading/src/main.rs index f4c7cbd..6ee0436 100644 --- a/examples/pumpfun_copy_trading/src/main.rs +++ b/examples/pumpfun_copy_trading/src/main.rs @@ -106,8 +106,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -122,6 +120,9 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul let slippage_basis_points = Some(100); let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from PumpFun..."); let buy_sol_amount = 100_000; @@ -152,6 +153,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -193,6 +195,7 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; diff --git a/examples/pumpfun_sniper_trading/src/main.rs b/examples/pumpfun_sniper_trading/src/main.rs index 455b313..afced86 100644 --- a/examples/pumpfun_sniper_trading/src/main.rs +++ b/examples/pumpfun_sniper_trading/src/main.rs @@ -74,8 +74,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -90,6 +88,9 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR let slippage_basis_points = Some(300); let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from PumpFun..."); let buy_sol_amount = 100_000; @@ -118,6 +119,7 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -148,6 +150,7 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; diff --git a/examples/pumpswap_direct_trading/src/main.rs b/examples/pumpswap_direct_trading/src/main.rs index 23b935d..0f445c2 100644 --- a/examples/pumpswap_direct_trading/src/main.rs +++ b/examples/pumpswap_direct_trading/src/main.rs @@ -22,6 +22,9 @@ async fn main() -> Result<(), Box> { let pool = Pubkey::from_str("539m4mVWt6iduB6W8rDGPMarzNCMesuqY5eUTiiYHAgR").unwrap(); let mint_pubkey = Pubkey::from_str("pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn").unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from PumpSwap..."); let buy_sol_amount = 100_000; @@ -43,6 +46,7 @@ async fn main() -> Result<(), Box> { open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -73,6 +77,7 @@ async fn main() -> Result<(), Box> { open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; @@ -90,8 +95,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/pumpswap_trading/src/main.rs b/examples/pumpswap_trading/src/main.rs index b4670bc..bc54226 100644 --- a/examples/pumpswap_trading/src/main.rs +++ b/examples/pumpswap_trading/src/main.rs @@ -124,8 +124,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -183,6 +181,9 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) - let slippage_basis_points = Some(500); let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from PumpSwap..."); let buy_sol_amount = 100_000; @@ -202,6 +203,7 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -234,6 +236,7 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; diff --git a/examples/raydium_amm_v4_trading/src/main.rs b/examples/raydium_amm_v4_trading/src/main.rs index 263ca70..72b144a 100644 --- a/examples/raydium_amm_v4_trading/src/main.rs +++ b/examples/raydium_amm_v4_trading/src/main.rs @@ -107,8 +107,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -139,6 +137,10 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent) coin_reserve, pc_reserve, ); + + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from Raydium_amm_v4..."); let buy_sol_amount = 100_000; @@ -158,6 +160,7 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent) open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -189,6 +192,7 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent) open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; diff --git a/examples/raydium_cpmm_trading/src/main.rs b/examples/raydium_cpmm_trading/src/main.rs index f7e9ee5..9499344 100644 --- a/examples/raydium_cpmm_trading/src/main.rs +++ b/examples/raydium_cpmm_trading/src/main.rs @@ -1,5 +1,5 @@ use sol_trade_sdk::common::spl_associated_token_account::get_associated_token_address; -use sol_trade_sdk::common::TradeConfig; +use sol_trade_sdk::common::{gas_fee_strategy, TradeConfig}; use sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT; use sol_trade_sdk::trading::core::params::RaydiumCpmmParams; use sol_trade_sdk::trading::factory::DexType; @@ -107,8 +107,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } @@ -128,6 +126,9 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) -> let slippage_basis_points = Some(100); let recent_blockhash = client.rpc.get_latest_blockhash().await?; + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + let buy_params = RaydiumCpmmParams::from_pool_address_by_rpc(&client.rpc, &trade_info.pool_state).await?; // Buy tokens @@ -149,6 +150,7 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) -> open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -182,6 +184,7 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) -> open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; diff --git a/examples/seed_trading/src/main.rs b/examples/seed_trading/src/main.rs index 2ee7745..3e75978 100644 --- a/examples/seed_trading/src/main.rs +++ b/examples/seed_trading/src/main.rs @@ -21,6 +21,9 @@ async fn main() -> Result<(), Box> { let pool = Pubkey::from_str("9qKxzRejsV6Bp2zkefXWCbGvg61c3hHei7ShXJ4FythA").unwrap(); let mint_pubkey = Pubkey::from_str("2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv").unwrap(); + let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new(); + gas_fee_strategy.set_global_fee_strategy(150000, 500000, 0.001, 0.001); + // Buy tokens println!("Buying tokens from PumpSwap..."); let buy_sol_amount = 100_000; @@ -42,6 +45,7 @@ async fn main() -> Result<(), Box> { open_seed_optimize: true, // ❗️❗️❗️❗️ open seed optimize durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy.clone(), }; client.buy(buy_params).await?; @@ -80,6 +84,7 @@ async fn main() -> Result<(), Box> { open_seed_optimize: true, // ❗️❗️❗️❗️ open seed optimize durable_nonce: None, fixed_output_token_amount: None, + gas_fee_strategy: gas_fee_strategy, }; client.sell(sell_params).await?; @@ -97,8 +102,6 @@ async fn create_solana_trade_client() -> AnyResult { let swqos_configs: Vec = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/trading_client/src/main.rs b/examples/trading_client/src/main.rs index 01747e3..16d3b5d 100644 --- a/examples/trading_client/src/main.rs +++ b/examples/trading_client/src/main.rs @@ -36,8 +36,6 @@ async fn create_solana_trade_client() -> AnyResult { ]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade_client = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("SolanaTrade client created successfully!"); Ok(solana_trade_client) } diff --git a/examples/wsol_wrapper/src/main.rs b/examples/wsol_wrapper/src/main.rs index c7d13ab..c99ecf9 100644 --- a/examples/wsol_wrapper/src/main.rs +++ b/examples/wsol_wrapper/src/main.rs @@ -59,8 +59,6 @@ async fn create_solana_trade_client() -> Result = vec![SwqosConfig::Default(rpc_url.clone())]; let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let solana_trade = SolanaTrade::new(Arc::new(payer), trade_config).await; - // set global strategy - sol_trade_sdk::common::GasFeeStrategy::set_global_fee_strategy(150000, 500000, 0.001, 0.001); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/src/common/gas_fee_strategy.rs b/src/common/gas_fee_strategy.rs index 0407837..8154e63 100644 --- a/src/common/gas_fee_strategy.rs +++ b/src/common/gas_fee_strategy.rs @@ -1,7 +1,7 @@ use crate::swqos::{SwqosType, TradeType}; use arc_swap::ArcSwap; use std::collections::HashMap; -use std::sync::{Arc, LazyLock}; +use std::sync::Arc; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum GasFeeStrategyType { @@ -23,21 +23,31 @@ pub struct GasFeeStrategyValue { pub tip: f64, } -static STRATEGIES: LazyLock< - ArcSwap>, -> = LazyLock::new(|| ArcSwap::from_pointee(HashMap::new())); - -pub struct GasFeeStrategy; +#[derive(Clone)] +pub struct GasFeeStrategy { + strategies: + Arc>>, +} impl GasFeeStrategy { + pub fn new() -> Self { + Self { strategies: Arc::new(ArcSwap::from_pointee(HashMap::new())) } + } + /// 设置全局费率策略 /// Set global fee strategy - pub fn set_global_fee_strategy(cu_limit: u32, cu_price: u64, buy_tip: f64, sell_tip: f64) { + pub fn set_global_fee_strategy( + &self, + cu_limit: u32, + cu_price: u64, + buy_tip: f64, + sell_tip: f64, + ) { for swqos_type in SwqosType::values() { if swqos_type.eq(&SwqosType::Default) { continue; } - GasFeeStrategy::set( + self.set( swqos_type, TradeType::Buy, GasFeeStrategyType::Normal, @@ -45,7 +55,7 @@ impl GasFeeStrategy { cu_price, buy_tip, ); - GasFeeStrategy::set( + self.set( swqos_type, TradeType::Sell, GasFeeStrategyType::Normal, @@ -54,7 +64,7 @@ impl GasFeeStrategy { sell_tip, ); } - GasFeeStrategy::set( + self.set( SwqosType::Default, TradeType::Buy, GasFeeStrategyType::Normal, @@ -62,7 +72,7 @@ impl GasFeeStrategy { cu_price, 0.0, ); - GasFeeStrategy::set( + self.set( SwqosType::Default, TradeType::Sell, GasFeeStrategyType::Normal, @@ -75,6 +85,7 @@ impl GasFeeStrategy { /// 为多个服务类型添加高低费率策略,会移除(SwqosType,TradeType)的默认策略。 /// Add high-low fee strategies for multiple service types, Will remove the default strategy of (SwqosType,TradeType) pub fn set_high_low_fee_strategies( + &self, swqos_types: &[SwqosType], trade_type: TradeType, cu_limit: u32, @@ -84,8 +95,8 @@ impl GasFeeStrategy { high_tip: f64, ) { for swqos_type in swqos_types { - GasFeeStrategy::del(*swqos_type, trade_type, GasFeeStrategyType::Normal); - GasFeeStrategy::set( + self.del(*swqos_type, trade_type, GasFeeStrategyType::Normal); + self.set( *swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice, @@ -93,7 +104,7 @@ impl GasFeeStrategy { high_cu_price, low_tip, ); - GasFeeStrategy::set( + self.set( *swqos_type, trade_type, GasFeeStrategyType::HighTipLowCuPrice, @@ -107,6 +118,7 @@ impl GasFeeStrategy { /// 为单个服务类型添加高低费率策略,会移除(SwqosType,TradeType)的默认策略。 /// Add high-low fee strategy for a single service type, Will remove the default strategy of (SwqosType,TradeType) pub fn set_high_low_fee_strategy( + &self, swqos_type: SwqosType, trade_type: TradeType, cu_limit: u32, @@ -118,8 +130,8 @@ impl GasFeeStrategy { if swqos_type.eq(&SwqosType::Default) { return; } - GasFeeStrategy::del(swqos_type, trade_type, GasFeeStrategyType::Normal); - GasFeeStrategy::set( + self.del(swqos_type, trade_type, GasFeeStrategyType::Normal); + self.set( swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice, @@ -127,7 +139,7 @@ impl GasFeeStrategy { high_cu_price, low_tip, ); - GasFeeStrategy::set( + self.set( swqos_type, trade_type, GasFeeStrategyType::HighTipLowCuPrice, @@ -140,6 +152,7 @@ impl GasFeeStrategy { /// 为多个服务类型添加标准费率策略,会移除(SwqosType,TradeType)的高低价策略。 /// Add normal fee strategies for multiple service types, Will remove the high-low strategies of (SwqosType,TradeType) pub fn set_normal_fee_strategies( + &self, swqos_types: &[SwqosType], cu_limit: u32, cu_price: u64, @@ -147,9 +160,9 @@ impl GasFeeStrategy { sell_tip: f64, ) { for swqos_type in swqos_types { - GasFeeStrategy::del_all(*swqos_type, TradeType::Buy); - GasFeeStrategy::del_all(*swqos_type, TradeType::Sell); - GasFeeStrategy::set( + self.del_all(*swqos_type, TradeType::Buy); + self.del_all(*swqos_type, TradeType::Sell); + self.set( *swqos_type, TradeType::Buy, GasFeeStrategyType::Normal, @@ -157,7 +170,7 @@ impl GasFeeStrategy { cu_price, buy_tip, ); - GasFeeStrategy::set( + self.set( *swqos_type, TradeType::Sell, GasFeeStrategyType::Normal, @@ -169,15 +182,16 @@ impl GasFeeStrategy { } pub fn set_normal_fee_strategy( + &self, swqos_type: SwqosType, cu_limit: u32, cu_price: u64, buy_tip: f64, sell_tip: f64, ) { - GasFeeStrategy::del_all(swqos_type, TradeType::Buy); - GasFeeStrategy::del_all(swqos_type, TradeType::Sell); - GasFeeStrategy::set( + self.del_all(swqos_type, TradeType::Buy); + self.del_all(swqos_type, TradeType::Sell); + self.set( swqos_type, TradeType::Buy, GasFeeStrategyType::Normal, @@ -185,7 +199,7 @@ impl GasFeeStrategy { cu_price, buy_tip, ); - GasFeeStrategy::set( + self.set( swqos_type, TradeType::Sell, GasFeeStrategyType::Normal, @@ -196,6 +210,7 @@ impl GasFeeStrategy { } pub fn set( + &self, swqos_type: SwqosType, trade_type: TradeType, strategy_type: GasFeeStrategyType, @@ -204,12 +219,12 @@ impl GasFeeStrategy { tip: f64, ) { if strategy_type == GasFeeStrategyType::Normal { - GasFeeStrategy::del(swqos_type, trade_type, GasFeeStrategyType::HighTipLowCuPrice); - GasFeeStrategy::del(swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice); + self.del(swqos_type, trade_type, GasFeeStrategyType::HighTipLowCuPrice); + self.del(swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice); } else { - GasFeeStrategy::del(swqos_type, trade_type, GasFeeStrategyType::Normal); + self.del(swqos_type, trade_type, GasFeeStrategyType::Normal); } - STRATEGIES.rcu(|current_map| { + self.strategies.rcu(|current_map| { let mut new_map = (**current_map).clone(); new_map.insert( (swqos_type, trade_type, strategy_type), @@ -221,8 +236,8 @@ impl GasFeeStrategy { /// 移除指定(SwqosType,TradeType)的策略。 /// Remove strategy for specified (SwqosType,TradeType) - pub fn del_all(swqos_type: SwqosType, trade_type: TradeType) { - STRATEGIES.rcu(|current_map| { + pub fn del_all(&self, swqos_type: SwqosType, trade_type: TradeType) { + self.strategies.rcu(|current_map| { let mut new_map = (**current_map).clone(); new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::Normal)); new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice)); @@ -233,8 +248,13 @@ impl GasFeeStrategy { /// 移除指定(SwqosType,TradeType,GasFeeStrategyType)的策略。 /// Remove strategy for specified (SwqosType,TradeType,GasFeeStrategyType) - pub fn del(swqos_type: SwqosType, trade_type: TradeType, strategy_type: GasFeeStrategyType) { - STRATEGIES.rcu(|current_map| { + pub fn del( + &self, + swqos_type: SwqosType, + trade_type: TradeType, + strategy_type: GasFeeStrategyType, + ) { + self.strategies.rcu(|current_map| { let mut new_map = (**current_map).clone(); new_map.remove(&(swqos_type, trade_type, strategy_type)); Arc::new(new_map) @@ -244,9 +264,10 @@ impl GasFeeStrategy { /// 获取指定交易类型的所有策略。 /// Get all strategies for specified trade type pub fn get_strategies( + &self, trade_type: TradeType, ) -> Vec<(SwqosType, GasFeeStrategyType, GasFeeStrategyValue)> { - let strategies = STRATEGIES.load(); + let strategies = self.strategies.load(); let mut result = Vec::new(); let mut swqos_types = std::collections::HashSet::new(); for (swqos_type, t_type, _) in strategies.keys() { @@ -268,17 +289,17 @@ impl GasFeeStrategy { /// 清空所有策略。 /// Clear all strategies - pub fn clear() { - STRATEGIES.store(Arc::new(HashMap::new())); + pub fn clear(&self) { + self.strategies.store(Arc::new(HashMap::new())); } /// 打印所有策略。 /// Print all strategies - pub fn print_all_strategies() { - for strategy in GasFeeStrategy::get_strategies(TradeType::Buy) { + pub fn print_all_strategies(&self) { + for strategy in self.get_strategies(TradeType::Buy) { println!("[buy] - {:?}", strategy); } - for strategy in GasFeeStrategy::get_strategies(TradeType::Sell) { + for strategy in self.get_strategies(TradeType::Sell) { println!("[sell] - {:?}", strategy); } } diff --git a/src/lib.rs b/src/lib.rs index 57c7d41..547f463 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub mod swqos; pub mod trading; pub mod utils; use crate::common::nonce_cache::DurableNonceInfo; +use crate::common::GasFeeStrategy; use crate::common::TradeConfig; use crate::constants::trade::trade::DEFAULT_SLIPPAGE; use crate::constants::SOL_TOKEN_ACCOUNT; @@ -109,6 +110,8 @@ pub struct TradeBuyParams { pub durable_nonce: Option, /// Optional fixed output token amount (If this value is set, it will be directly assigned to the output amount instead of being calculated) pub fixed_output_token_amount: Option, + /// Gas fee strategy + pub gas_fee_strategy: GasFeeStrategy, } /// Parameters for executing sell orders across different DEX protocols @@ -149,6 +152,8 @@ pub struct TradeSellParams { pub durable_nonce: Option, /// Optional fixed output token amount (If this value is set, it will be directly assigned to the output amount instead of being calculated) pub fixed_output_token_amount: Option, + /// Gas fee strategy + pub gas_fee_strategy: GasFeeStrategy, } impl SolanaTrade { @@ -308,6 +313,7 @@ impl SolanaTrade { create_output_mint_ata: params.create_mint_ata, close_output_mint_ata: false, fixed_output_amount: params.fixed_output_token_amount, + gas_fee_strategy: params.gas_fee_strategy, }; // Validate protocol params @@ -401,6 +407,7 @@ impl SolanaTrade { create_output_mint_ata: params.create_output_token_ata, close_output_mint_ata: params.close_output_token_ata, fixed_output_amount: params.fixed_output_token_amount, + gas_fee_strategy: params.gas_fee_strategy, }; // Validate protocol params diff --git a/src/trading/core/async_executor.rs b/src/trading/core/async_executor.rs index 65b61ac..e9a2306 100644 --- a/src/trading/core/async_executor.rs +++ b/src/trading/core/async_executor.rs @@ -7,8 +7,8 @@ use solana_sdk::message::AddressLookupTableAccount; use solana_sdk::{ instruction::Instruction, pubkey::Pubkey, signature::Keypair, signature::Signature, }; -use std::{str::FromStr, sync::Arc, time::Instant}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::{str::FromStr, sync::Arc, time::Instant}; use crate::{ common::nonce_cache::DurableNonceInfo, @@ -48,7 +48,7 @@ impl ResultCollector { let _ = self.results.push(result); if is_success { - self.success_flag.store(true, Ordering::Release); // Release 确保 push 可见 + self.success_flag.store(true, Ordering::Release); // Release 确保 push 可见 } self.completed_count.fetch_add(1, Ordering::Release); @@ -106,6 +106,7 @@ pub async fn execute_parallel( is_buy: bool, wait_transaction_confirmed: bool, with_tip: bool, + gas_fee_strategy: GasFeeStrategy, ) -> Result<(bool, Signature)> { let _exec_start = Instant::now(); @@ -133,7 +134,7 @@ pub async fn execute_parallel( with_tip || matches!(swqos_client.get_swqos_type(), SwqosType::Default) }) .flat_map(|(i, swqos_client)| { - let gas_fee_strategy_configs = GasFeeStrategy::get_strategies(if is_buy { + let gas_fee_strategy_configs = gas_fee_strategy.get_strategies(if is_buy { TradeType::Buy } else { TradeType::Sell @@ -229,11 +230,7 @@ pub async fn execute_parallel( // Transaction sent if let Some(signature) = transaction.signatures.first() { - collector.submit(TaskResult { - success, - signature: *signature, - _error: None, - }); + collector.submit(TaskResult { success, signature: *signature, _error: None }); } }); } diff --git a/src/trading/core/executor.rs b/src/trading/core/executor.rs index 59e80f6..8a6e4eb 100755 --- a/src/trading/core/executor.rs +++ b/src/trading/core/executor.rs @@ -96,6 +96,7 @@ impl TradeExecutor for GenericTradeExecutor { is_buy, params.wait_transaction_confirmed, if is_buy { true } else { params.with_tip }, + params.gas_fee_strategy, ) .await; let send_elapsed = send_start.elapsed(); diff --git a/src/trading/core/params.rs b/src/trading/core/params.rs index 08ae9e7..e359024 100755 --- a/src/trading/core/params.rs +++ b/src/trading/core/params.rs @@ -2,7 +2,7 @@ use super::traits::ProtocolParams; use crate::common::bonding_curve::BondingCurveAccount; use crate::common::nonce_cache::DurableNonceInfo; use crate::common::spl_associated_token_account::get_associated_token_address_with_program_id; -use crate::common::SolanaRpcClient; +use crate::common::{GasFeeStrategy, SolanaRpcClient}; use crate::constants::TOKEN_PROGRAM; use crate::swqos::{SwqosClient, TradeType}; use crate::trading::common::get_multi_token_balances; @@ -39,6 +39,7 @@ pub struct SwapParams { pub create_output_mint_ata: bool, pub close_output_mint_ata: bool, pub fixed_output_amount: Option, + pub gas_fee_strategy: GasFeeStrategy, } impl std::fmt::Debug for SwapParams {