diff --git a/Cargo.toml b/Cargo.toml index 38f9280..799605e 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ members = [ "examples/wsol_wrapper", "examples/seed_trading", "examples/cli_trading", + "examples/gas_fee_strategy", ] [lib] diff --git a/README.md b/README.md index c5dd90c..e28f373 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,14 @@ let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let client = SolanaTrade::new(Arc::new(payer), trade_config).await; ``` -#### 2. Build Trading Parameters +#### 2. Configure Gas Fee Strategy + +For detailed information about Gas Fee Strategy, see the [Gas Fee Strategy Reference](docs/GAS_FEE_STRATEGY.md). +```rust +sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); +``` + +#### 3. Build Trading Parameters For detailed information about all trading parameters, see the [Trading Parameters Reference](docs/TRADING_PARAMETERS.md). @@ -151,7 +158,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams { }; ``` -#### 3. Execute Trading +#### 4. Execute Trading ```rust client.buy(buy_params).await?; @@ -184,6 +191,7 @@ Please ensure that the parameters your trading logic depends on are available in | Nonce example | `cargo run --package nonce_cache` | [examples/nonce_cache](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/nonce_cache/src/main.rs) | | Wrap/unwrap SOL to/from WSOL example | `cargo run --package wsol_wrapper` | [examples/wsol_wrapper](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/wsol_wrapper/src/main.rs) | | Seed trading example | `cargo run --package seed_trading` | [examples/seed_trading](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/seed_trading/src/main.rs) | +| Gas fee strategy example | `cargo run --package gas_fee_strategy` | [examples/gas_fee_strategy](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/gas_fee_strategy/src/main.rs) | ### ⚙️ SWQOS Service Configuration diff --git a/README_CN.md b/README_CN.md index 9e87077..119b939 100755 --- a/README_CN.md +++ b/README_CN.md @@ -130,7 +130,15 @@ let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); let client = SolanaTrade::new(Arc::new(payer), trade_config).await; ``` -#### 2. 构建交易参数 +#### 2. 配置 Gas Fee 策略 + +有关 Gas Fee 策略的详细信息,请参阅 [Gas Fee 策略参考手册](docs/GAS_FEE_STRATEGY_CN.md)。 +```rust +// 使用内置策略 +sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); +``` + +#### 3. 构建交易参数 有关所有交易参数的详细信息,请参阅 [交易参数参考手册](docs/TRADING_PARAMETERS_CN.md)。 @@ -151,7 +159,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams { }; ``` -#### 3. 执行交易 +#### 4. 执行交易 ```rust client.buy(buy_params).await?; @@ -184,6 +192,7 @@ client.buy(buy_params).await?; | Nonce示例 | `cargo run --package nonce_cache` | [examples/nonce_cache](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/nonce_cache/src/main.rs) | | SOL与WSOL相互转换示例 | `cargo run --package wsol_wrapper` | [examples/wsol_wrapper](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/wsol_wrapper/src/main.rs) | | Seed 优化交易示例 | `cargo run --package seed_trading` | [examples/seed_trading](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/seed_trading/src/main.rs) | +| Gas费用策略示例 | `cargo run --package gas_fee_strategy` | [examples/gas_fee_strategy](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/gas_fee_strategy/src/main.rs) | ### ⚙️ SWQOS 服务配置说明 diff --git a/docs/GAS_FEE_STRATEGY.md b/docs/GAS_FEE_STRATEGY.md new file mode 100644 index 0000000..390d15c --- /dev/null +++ b/docs/GAS_FEE_STRATEGY.md @@ -0,0 +1,65 @@ +# 📊 Gas Fee Strategy Guide + +This document introduces the Gas Fee strategy configuration and usage methods in Sol Trade SDK. + +## Basic Usage + +### 1. Overview + +This module supports users to configure strategies for SwqosType under different TradeType (buy/sell). + +- Normal strategy: One SwqosType sends one transaction, specifying cu_limit, cu_price, and tip. +- High-low fee strategy: One SwqosType sends two transactions simultaneously, one with low tip and high priority fee, another with high tip and low priority fee. + +Each (SwqosType, TradeType) combination can only configure one strategy. Subsequent strategy configurations will override previous ones. + +### 2. Using Built-in Strategies + +```rust +use sol_trade_sdk::common::gas_fee_strategy::GasFeeStrategy; +// Use built-in strategies (includes normal strategies for various SwqosTypes) +GasFeeStrategy::init_builtin_fee_strategies(); +``` + +### 3. Configuring Single Strategy + +```rust +// Configure normal strategy for SwqosType::Jito during Buy +GasFeeStrategy::add_normal_fee_strategy( + SwqosType::Jito, + TradeType::Buy, + xxxxx, // cu_limit + xxxx, // cu_price + xxxxx // tip +); +``` + +### 4. Configuring High-Low Fee Strategy + +```rust +// Configure high-low fee strategy for SwqosType::Jito during Buy +GasFeeStrategy::add_high_low_fee_strategy( + SwqosType::Jito, + TradeType::Buy, + xxxxx, // cu_limit + xxxxx, // low cu_price + xxxxx, // high cu_price + xxxxx, // low tip + xxxxx // high tip +); +``` + +### 5. Viewing and Cleanup + +```rust +// Remove a specific strategy +GasFeeStrategy::remove_strategy(SwqosType::Jito, TradeType::Buy); +// View all strategies +GasFeeStrategy::print_all_strategies(); +// Clear all strategies +GasFeeStrategy::clear(); +``` + +## 🔗 Related Documents + +- [Example: Gas Fee Strategy](../examples/gas_fee_strategy/) diff --git a/docs/GAS_FEE_STRATEGY_CN.md b/docs/GAS_FEE_STRATEGY_CN.md new file mode 100644 index 0000000..db70df0 --- /dev/null +++ b/docs/GAS_FEE_STRATEGY_CN.md @@ -0,0 +1,65 @@ +# 📊 Gas Fee 策略指南 + +本文档介绍 Sol Trade SDK 中的 Gas Fee 策略配置和使用方法。 + +## 基础使用 + +### 1. 说明 + +该模块支持用户配置 SwqosType 在不同 TradeType(buy/sell) 下的策略。 + +- normal 策略: 一个 SwqosType 发送一笔交易,指定 cu_limit、cu_price 和小费。 +- 高低费率策略: 一个 SwqosType 同时发送两笔交易,一笔低小费高优先费,一笔高小费低优先费。 + +每个 (SwqosType, TradeType) 的组合仅可配置一个策略。后续配置的策略会覆盖之前的策略。 + +### 2. 使用内置策略 + +```rust +use sol_trade_sdk::common::gas_fee_strategy::GasFeeStrategy; +// 使用内置策略(内置了各个 SwqosType 的 normal 策略) +GasFeeStrategy::init_builtin_fee_strategies(); +``` + +### 3. 配置单个策略 + +```rust +// 为 SwqosType::Jito 在 Buy 时配置 normal 策略 +GasFeeStrategy::add_normal_fee_strategy( + SwqosType::Jito, + TradeType::Buy, + xxxxx, // cu_limit + xxxx, // cu_price + xxxxx // tip +); +``` + +### 4. 配置高低费率策略 + +```rust +// 为 SwqosType::Jito 在 Buy 时配置高低费率策略 +GasFeeStrategy::add_high_low_fee_strategy( + SwqosType::Jito, + TradeType::Buy, + xxxxx, // cu_limit + xxxxx, // low cu_price + xxxxx, // high cu_price + xxxxx, // low tip + xxxxx // high tip +); +``` + +### 5. 查看和清理 + +```rust +// 移除某个策略 +GasFeeStrategy::remove_strategy(SwqosType::Jito, TradeType::Buy); +// 查看所有策略 +GasFeeStrategy::print_all_strategies(); +// 清空所有策略 +GasFeeStrategy::clear(); +``` + +## 🔗 相关文档 + +- [示例:Gas Fee 策略](../examples/gas_fee_strategy/) \ No newline at end of file diff --git a/docs/NONCE_CACHE.md b/docs/NONCE_CACHE.md index b6e6b1d..611962a 100644 --- a/docs/NONCE_CACHE.md +++ b/docs/NONCE_CACHE.md @@ -57,7 +57,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams { mint: mint_pubkey, sol_amount: buy_sol_amount, slippage_basis_points: Some(100), - recent_blockhash: current_nonce, // Use nonce as blockhash + recent_blockhash: current_nonce, // Use nonce as blockhash. Please use the latest nonce value for each transaction. extension_params: Box::new(PumpFunParams::from_trade(&trade_info, None)), lookup_table_key: None, wait_transaction_confirmed: true, diff --git a/docs/NONCE_CACHE_CN.md b/docs/NONCE_CACHE_CN.md index 2f56ca8..0411787 100644 --- a/docs/NONCE_CACHE_CN.md +++ b/docs/NONCE_CACHE_CN.md @@ -57,7 +57,7 @@ let buy_params = sol_trade_sdk::TradeBuyParams { mint: mint_pubkey, sol_amount: buy_sol_amount, slippage_basis_points: Some(100), - recent_blockhash: current_nonce, // 使用 nonce 作为 blockhash + recent_blockhash: current_nonce, // 使用 nonce 作为 blockhash。请在每次交易时,都使用最新的 nonce 值。 extension_params: Box::new(PumpFunParams::from_trade(&trade_info, None)), lookup_table_key: None, wait_transaction_confirmed: true, diff --git a/examples/address_lookup/src/main.rs b/examples/address_lookup/src/main.rs index 1c742bd..bd7b438 100644 --- a/examples/address_lookup/src/main.rs +++ b/examples/address_lookup/src/main.rs @@ -19,7 +19,6 @@ use sol_trade_sdk::{ }; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::PumpFunParams, factory::DexType}, SolanaTrade, @@ -125,6 +124,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/bonk_copy_trading/src/main.rs b/examples/bonk_copy_trading/src/main.rs index f7cb4e8..b61d643 100644 --- a/examples/bonk_copy_trading/src/main.rs +++ b/examples/bonk_copy_trading/src/main.rs @@ -14,7 +14,6 @@ use sol_trade_sdk::solana_streamer_sdk::streaming::yellowstone_grpc::{ use sol_trade_sdk::solana_streamer_sdk::streaming::YellowstoneGrpc; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::BonkParams, factory::DexType}, SolanaTrade, @@ -111,6 +110,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/bonk_sniper_trading/src/main.rs b/examples/bonk_sniper_trading/src/main.rs index 1fa0499..6611cdb 100644 --- a/examples/bonk_sniper_trading/src/main.rs +++ b/examples/bonk_sniper_trading/src/main.rs @@ -6,7 +6,6 @@ use sol_trade_sdk::solana_streamer_sdk::streaming::event_parser::{Protocol, Unif use sol_trade_sdk::solana_streamer_sdk::{match_event, streaming::ShredStreamGrpc}; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::BonkParams, factory::DexType}, SolanaTrade, @@ -80,6 +79,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/cli_trading/src/main.rs b/examples/cli_trading/src/main.rs index 71271ed..4363226 100644 --- a/examples/cli_trading/src/main.rs +++ b/examples/cli_trading/src/main.rs @@ -3,7 +3,6 @@ use sol_trade_sdk::{ common::{ fast_fn::get_associated_token_address_with_program_id_fast_use_seed, AnyResult, TradeConfig, }, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{ core::params::{ @@ -1285,6 +1284,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/gas_fee_strategy/Cargo.toml b/examples/gas_fee_strategy/Cargo.toml new file mode 100644 index 0000000..f8e43a8 --- /dev/null +++ b/examples/gas_fee_strategy/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "gas_fee_strategy" +version = "0.1.0" +edition = "2021" + +[dependencies] +sol-trade-sdk = { path = "../.." } +tokio = { version = "1.0", features = ["full"] } diff --git a/examples/gas_fee_strategy/src/main.rs b/examples/gas_fee_strategy/src/main.rs new file mode 100644 index 0000000..f6b22db --- /dev/null +++ b/examples/gas_fee_strategy/src/main.rs @@ -0,0 +1,72 @@ +use sol_trade_sdk::{ + common::gas_fee_strategy::GasFeeStrategy, + swqos::{SwqosType, TradeType}, +}; + +#[tokio::main] +async fn main() { + println!("🚀 Gas Fee Strategy Demo"); + println!("========================"); + + // Initialize builtin strategies + println!("1. Initialize builtin strategies"); + GasFeeStrategy::init_builtin_fee_strategies(); + + // Print all strategies + println!("\n2. Print all builtin strategies"); + GasFeeStrategy::print_all_strategies(); + + // Clear all strategies + println!("\n3. Clear all strategies"); + GasFeeStrategy::clear(); + + // Add normal fee strategy for SwqosType::Default on Buy + println!("\n4. Add normal fee strategy for SwqosType::Default on Buy"); + GasFeeStrategy::add_normal_fee_strategy( + SwqosType::Default, + TradeType::Buy, + 150000, // cu_limit + 500000, // cu_price + 0.0, // tip + ); + + // Add high-low fee strategy for SwqosType::Jito on Buy + println!("\n5. Add high-low fee strategy for SwqosType::Jito on Buy"); + GasFeeStrategy::add_high_low_fee_strategy( + SwqosType::Jito, + TradeType::Buy, + 150000, // cu_limit + 100, // low cu_price + 10 * 1_000_000, // high cu_price + 0.001, // low tip + 0.1, // high tip + ); + + // Print all strategies + println!("\n6. Print all current strategies"); + GasFeeStrategy::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 on Buy (will override previous high-low strategy)"); + GasFeeStrategy::add_normal_fee_strategy( + SwqosType::Jito, + TradeType::Buy, + 150000, // cu_limit + 500000, // cu_price + 0.0001, // tip + ); + + // Print all strategies + println!("\n8. Print all current strategies"); + GasFeeStrategy::print_all_strategies(); + + // Remove strategy for SwqosType::Jito on Buy + println!("\n9. Remove strategy for SwqosType::Jito on Buy"); + GasFeeStrategy::remove_strategy(SwqosType::Jito, TradeType::Buy); + + // Print all strategies + println!("\n10. Print all current strategies"); + GasFeeStrategy::print_all_strategies(); + + println!("\n✅ Gas Fee Strategy Demo completed!"); +} diff --git a/examples/middleware_system/src/main.rs b/examples/middleware_system/src/main.rs index 6be50eb..a02b704 100644 --- a/examples/middleware_system/src/main.rs +++ b/examples/middleware_system/src/main.rs @@ -1,7 +1,6 @@ use anyhow::Result; use sol_trade_sdk::{ common::{AnyResult, TradeConfig}, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::{SwqosConfig, SwqosRegion}, trading::{ core::params::PumpSwapParams, factory::DexType, middleware::builtin::LoggingMiddleware, @@ -67,6 +66,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/nonce_cache/src/main.rs b/examples/nonce_cache/src/main.rs index 260c285..d41a3ed 100644 --- a/examples/nonce_cache/src/main.rs +++ b/examples/nonce_cache/src/main.rs @@ -17,7 +17,6 @@ use sol_trade_sdk::{ }; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::PumpFunParams, factory::DexType}, SolanaTrade, @@ -106,6 +105,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/pumpfun_copy_trading/src/main.rs b/examples/pumpfun_copy_trading/src/main.rs index 5ed89b7..c621334 100644 --- a/examples/pumpfun_copy_trading/src/main.rs +++ b/examples/pumpfun_copy_trading/src/main.rs @@ -14,7 +14,6 @@ use sol_trade_sdk::solana_streamer_sdk::streaming::yellowstone_grpc::{ use sol_trade_sdk::solana_streamer_sdk::streaming::YellowstoneGrpc; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::PumpFunParams, factory::DexType}, SolanaTrade, @@ -105,6 +104,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/pumpfun_sniper_trading/src/main.rs b/examples/pumpfun_sniper_trading/src/main.rs index 1f786ae..90c0d23 100644 --- a/examples/pumpfun_sniper_trading/src/main.rs +++ b/examples/pumpfun_sniper_trading/src/main.rs @@ -6,7 +6,6 @@ use sol_trade_sdk::solana_streamer_sdk::streaming::event_parser::{Protocol, Unif use sol_trade_sdk::solana_streamer_sdk::{match_event, streaming::ShredStreamGrpc}; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::PumpFunParams, factory::DexType}, SolanaTrade, @@ -74,6 +73,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/pumpswap_direct_trading/src/main.rs b/examples/pumpswap_direct_trading/src/main.rs index ae7f7e0..f2b704d 100644 --- a/examples/pumpswap_direct_trading/src/main.rs +++ b/examples/pumpswap_direct_trading/src/main.rs @@ -1,6 +1,5 @@ use sol_trade_sdk::{ common::{AnyResult, TradeConfig}, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::PumpSwapParams, factory::DexType}, SolanaTrade, @@ -82,6 +81,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); 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 075559a..91edee2 100644 --- a/examples/pumpswap_trading/src/main.rs +++ b/examples/pumpswap_trading/src/main.rs @@ -13,7 +13,6 @@ use sol_trade_sdk::solana_streamer_sdk::{ }; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::PumpSwapParams, factory::DexType}, SolanaTrade, @@ -131,6 +130,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/raydium_amm_v4_trading/src/main.rs b/examples/raydium_amm_v4_trading/src/main.rs index e57bbbe..8cfe34f 100644 --- a/examples/raydium_amm_v4_trading/src/main.rs +++ b/examples/raydium_amm_v4_trading/src/main.rs @@ -14,7 +14,6 @@ use sol_trade_sdk::solana_streamer_sdk::streaming::yellowstone_grpc::{ use sol_trade_sdk::solana_streamer_sdk::streaming::YellowstoneGrpc; use sol_trade_sdk::{ common::AnyResult, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::RaydiumAmmV4Params, factory::DexType}, SolanaTrade, @@ -105,6 +104,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/raydium_cpmm_trading/src/main.rs b/examples/raydium_cpmm_trading/src/main.rs index c89b89a..c351ba0 100644 --- a/examples/raydium_cpmm_trading/src/main.rs +++ b/examples/raydium_cpmm_trading/src/main.rs @@ -3,6 +3,7 @@ use std::sync::{ Arc, }; +use sol_trade_sdk::solana_streamer_sdk::streaming::event_parser::{Protocol, UnifiedEvent}; use sol_trade_sdk::solana_streamer_sdk::streaming::YellowstoneGrpc; use sol_trade_sdk::solana_streamer_sdk::{ match_event, streaming::event_parser::protocols::raydium_cpmm::RaydiumCpmmSwapEvent, @@ -12,10 +13,6 @@ use sol_trade_sdk::{ common::TradeConfig, solana_streamer_sdk::streaming::yellowstone_grpc::{AccountFilter, TransactionFilter}, }; -use sol_trade_sdk::{ - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, - solana_streamer_sdk::streaming::event_parser::{Protocol, UnifiedEvent}, -}; use sol_trade_sdk::{ instruction::utils::raydium_cpmm::accounts, solana_streamer_sdk::streaming::event_parser::protocols::raydium_cpmm::parser::RAYDIUM_CPMM_PROGRAM_ID, @@ -114,6 +111,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); println!("✅ SolanaTrade client initialized successfully!"); Ok(solana_trade) } diff --git a/examples/seed_trading/src/main.rs b/examples/seed_trading/src/main.rs index 63f9cb4..21d7b29 100644 --- a/examples/seed_trading/src/main.rs +++ b/examples/seed_trading/src/main.rs @@ -2,7 +2,6 @@ use sol_trade_sdk::{ common::{ fast_fn::get_associated_token_address_with_program_id_fast_use_seed, AnyResult, TradeConfig, }, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, swqos::SwqosConfig, trading::{core::params::PumpSwapParams, factory::DexType}, SolanaTrade, @@ -91,6 +90,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); 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 5eae893..55c8e9c 100644 --- a/examples/trading_client/src/main.rs +++ b/examples/trading_client/src/main.rs @@ -35,6 +35,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); 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 fae0cb3..3ffeade 100644 --- a/examples/wsol_wrapper/src/main.rs +++ b/examples/wsol_wrapper/src/main.rs @@ -1,9 +1,4 @@ -use sol_trade_sdk::{ - common::TradeConfig, - constants::trade::trade::{DEFAULT_CU_LIMIT, DEFAULT_CU_PRICE}, - swqos::SwqosConfig, - SolanaTrade, -}; +use sol_trade_sdk::{common::TradeConfig, swqos::SwqosConfig, SolanaTrade}; use solana_sdk::{commitment_config::CommitmentConfig, signature::Keypair}; use std::sync::Arc; @@ -63,6 +58,8 @@ 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; + // init gas fee strategy + sol_trade_sdk::common::GasFeeStrategy::init_builtin_fee_strategies(); 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 a852dfd..26d0a30 100644 --- a/src/common/gas_fee_strategy.rs +++ b/src/common/gas_fee_strategy.rs @@ -1,3 +1,7 @@ +use crate::constants::trade::trade::{ + DEFAULT_BUY_TIP_FEE, DEFAULT_RPC_UNIT_LIMIT, DEFAULT_RPC_UNIT_PRICE, DEFAULT_SELL_TIP_FEE, + DEFAULT_TIP_UNIT_LIMIT, DEFAULT_TIP_UNIT_PRICE, +}; use crate::swqos::{SwqosType, TradeType}; use arc_swap::ArcSwap; use std::collections::HashMap; @@ -5,14 +9,14 @@ use std::sync::{Arc, LazyLock}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum GasFeeStrategyType { - Default, + Normal, LowTipHighCuPrice, HighTipLowCuPrice, } impl GasFeeStrategyType { pub fn values() -> Vec { - vec![Self::Default, Self::LowTipHighCuPrice, Self::HighTipLowCuPrice] + vec![Self::Normal, Self::LowTipHighCuPrice, Self::HighTipLowCuPrice] } } @@ -23,7 +27,6 @@ pub struct GasFeeStrategyValue { pub tip: f64, } -// 静态存储策略数据 static STRATEGIES: LazyLock< ArcSwap>, > = LazyLock::new(|| ArcSwap::from_pointee(HashMap::new())); @@ -31,6 +34,47 @@ static STRATEGIES: LazyLock< pub struct GasFeeStrategy; impl GasFeeStrategy { + /// 初始化内置策略。 + /// Initialize built-in strategies + pub fn init_builtin_fee_strategies() { + GasFeeStrategy::add_normal_fee_strategies( + &SwqosType::values() + .into_iter() + .filter(|swqos_type| !swqos_type.eq(&SwqosType::Default)) + .collect::>(), + TradeType::Buy, + DEFAULT_TIP_UNIT_PRICE, + DEFAULT_BUY_TIP_FEE, + DEFAULT_TIP_UNIT_LIMIT, + ); + GasFeeStrategy::add_normal_fee_strategies( + &SwqosType::values() + .into_iter() + .filter(|swqos_type| !swqos_type.eq(&SwqosType::Default)) + .collect::>(), + TradeType::Sell, + DEFAULT_TIP_UNIT_PRICE, + DEFAULT_SELL_TIP_FEE, + DEFAULT_TIP_UNIT_LIMIT, + ); + GasFeeStrategy::add_normal_fee_strategy( + SwqosType::Default, + TradeType::Buy, + DEFAULT_RPC_UNIT_LIMIT, + DEFAULT_RPC_UNIT_PRICE, + 0.0, + ); + GasFeeStrategy::add_normal_fee_strategy( + SwqosType::Default, + TradeType::Sell, + DEFAULT_RPC_UNIT_LIMIT, + DEFAULT_RPC_UNIT_PRICE, + 0.0, + ); + } + + /// 为多个服务类型添加高低费率策略,会移除(SwqosType,TradeType)的默认策略。 + /// Add high-low fee strategies for multiple service types, Will remove the default strategy of (SwqosType,TradeType) pub fn add_high_low_fee_strategies( swqos_types: &[SwqosType], trade_type: TradeType, @@ -62,6 +106,8 @@ impl GasFeeStrategy { }); } + /// 为单个服务类型添加高低费率策略,会移除(SwqosType,TradeType)的默认策略。 + /// Add high-low fee strategy for a single service type, Will remove the default strategy of (SwqosType,TradeType) pub fn add_high_low_fee_strategy( swqos_type: SwqosType, trade_type: TradeType, @@ -89,7 +135,9 @@ impl GasFeeStrategy { }); } - pub fn add_default_fee_strategies( + /// 为多个服务类型添加标准费率策略,会移除(SwqosType,TradeType)的高低价策略。 + /// Add normal fee strategies for multiple service types, Will remove the high-low strategies of (SwqosType,TradeType) + pub fn add_normal_fee_strategies( swqos_types: &[SwqosType], trade_type: TradeType, cu_price: u64, @@ -103,7 +151,7 @@ impl GasFeeStrategy { let mut new_map = (**current_map).clone(); for swqos_type in swqos_types { new_map.insert( - (*swqos_type, trade_type, GasFeeStrategyType::Default), + (*swqos_type, trade_type, GasFeeStrategyType::Normal), GasFeeStrategyValue { cu_limit, cu_price, tip }, ); } @@ -111,34 +159,40 @@ impl GasFeeStrategy { }); } - pub fn add_default_fee_strategy( + /// 为单个服务类型添加标准费率策略,会移除(SwqosType,TradeType)的高低价策略。 + /// Add normal fee strategy for a single service type, Will remove the high-low strategies of (SwqosType,TradeType) + pub fn add_normal_fee_strategy( swqos_type: SwqosType, trade_type: TradeType, + cu_limit: u32, cu_price: u64, tip: f64, - cu_limit: u32, ) { GasFeeStrategy::remove_strategy(swqos_type, trade_type); STRATEGIES.rcu(|current_map| { let mut new_map = (**current_map).clone(); new_map.insert( - (swqos_type, trade_type, GasFeeStrategyType::Default), + (swqos_type, trade_type, GasFeeStrategyType::Normal), GasFeeStrategyValue { cu_limit, cu_price, tip }, ); Arc::new(new_map) }); } + /// 移除指定(SwqosType,TradeType)的策略。 + /// Remove strategy for specified (SwqosType,TradeType) pub fn remove_strategy(swqos_type: SwqosType, trade_type: TradeType) { STRATEGIES.rcu(|current_map| { let mut new_map = (**current_map).clone(); - new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::Default)); + new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::Normal)); new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice)); new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::HighTipLowCuPrice)); Arc::new(new_map) }); } + /// 获取指定交易类型的所有策略。 + /// Get all strategies for specified trade type pub fn get_strategies( trade_type: TradeType, ) -> Vec<(SwqosType, GasFeeStrategyType, GasFeeStrategyValue)> { @@ -162,53 +216,20 @@ impl GasFeeStrategy { result } + /// 清空所有策略。 + /// Clear all strategies pub fn clear() { STRATEGIES.store(Arc::new(HashMap::new())); } -} -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn demo() { - // 给SwqosType::Default 在 Buy 时添加默认策略 - GasFeeStrategy::add_default_fee_strategy( - SwqosType::Default, - TradeType::Buy, - 100, - 0.0001, - 10, - ); - // 给SwqosType::Jito 在 Buy 时添加高低价策略 - GasFeeStrategy::add_high_low_fee_strategy( - SwqosType::Jito, - TradeType::Buy, - 10, - 100, - 10000, - 0.001, - 0.1, - ); - // 获取所有 Buy 策略 - let all_strategies = GasFeeStrategy::get_strategies(TradeType::Buy); - for strategy in all_strategies { - println!("strategy: {:?}", strategy); + /// 打印所有策略。 + /// Print all strategies + pub fn print_all_strategies() { + for strategy in GasFeeStrategy::get_strategies(TradeType::Buy) { + println!("[buy] - {:?}", strategy); } - println!("--------------------------------"); - // 给SwqosType::Jito 在 Buy 时添加默认策略(会删除 jito 的高低价策略) - GasFeeStrategy::add_default_fee_strategy(SwqosType::Jito, TradeType::Buy, 100, 0.0001, 10); - // 获取所有 Buy 策略 - let all_strategies = GasFeeStrategy::get_strategies(TradeType::Buy); - for strategy in all_strategies { - println!("strategy: {:?}", strategy); + for strategy in GasFeeStrategy::get_strategies(TradeType::Sell) { + println!("[sell] - {:?}", strategy); } - // 删除SwqosType::Jito 在 Buy 时的策略 - GasFeeStrategy::remove_strategy(SwqosType::Jito, TradeType::Buy); - // 清空策略 - GasFeeStrategy::clear(); - println!("--------------------------------"); - println!("strategy {:?}", GasFeeStrategy::get_strategies(TradeType::Buy)); } } diff --git a/src/constants/trade.rs b/src/constants/trade.rs index 4a96442..39936eb 100644 --- a/src/constants/trade.rs +++ b/src/constants/trade.rs @@ -1,9 +1,9 @@ pub mod trade { pub const DEFAULT_SLIPPAGE: u64 = 1000; // 10% - pub const DEFAULT_TIP_UNIT_LIMIT: u32 = 78000; + pub const DEFAULT_TIP_UNIT_LIMIT: u32 = 150000; pub const DEFAULT_TIP_UNIT_PRICE: u64 = 500000; pub const DEFAULT_BUY_TIP_FEE: f64 = 0.0006; pub const DEFAULT_SELL_TIP_FEE: f64 = 0.0001; - pub const DEFAULT_RPC_UNIT_LIMIT: u32 = 78000; + pub const DEFAULT_RPC_UNIT_LIMIT: u32 = 150000; pub const DEFAULT_RPC_UNIT_PRICE: u64 = 500000; } \ No newline at end of file diff --git a/src/trading/core/parallel.rs b/src/trading/core/parallel.rs index 1d62fdf..96981c6 100755 --- a/src/trading/core/parallel.rs +++ b/src/trading/core/parallel.rs @@ -78,7 +78,7 @@ async fn parallel_execute( .find(|swqos| matches!(swqos.get_swqos_type(), SwqosType::Default)) .is_none() { - return Err(anyhow!("No Rpc Default Swqos configured")); + return Err(anyhow!("No Rpc Default Swqos configured.")); } let cores = core_affinity::get_core_ids().unwrap(); let mut handles: Vec>> = Vec::with_capacity(swqos_clients.len()); @@ -106,7 +106,7 @@ async fn parallel_execute( .collect(); if task_configs.is_empty() { - return Err(anyhow!("No available gas fee strategy configs")); + return Err(anyhow!("No available gas fee strategy configs. Please configure GasFeeStrategy for specific SwqosType.")); } for (i, swqos_client, gas_fee_strategy_config) in task_configs {