From c5a55b1c145e2b93ea252a2d7a6ff18668afe681 Mon Sep 17 00:00:00 2001 From: ysq Date: Fri, 7 Nov 2025 16:57:28 +0800 Subject: [PATCH] feat: refactor seed optimization to global configuration in v3.2.0 - Remove open_seed_optimize parameter from TradeBuyParams and TradeSellParams structs - Add global use_seed_optimize configuration in TradeConfig with default value true - Add create_wsol_ata_on_startup configuration in TradeConfig with default value true - Implement automatic WSOL ATA creation and verification on SDK initialization - Add with_wsol_ata_config() builder method to TradeConfig for custom WSOL settings - Update all examples to remove open_seed_optimize parameter usage - Update documentation (README, TRADING_PARAMETERS) to reflect new configuration approach - Upgrade package version from 3.1.7 to 3.2.0 Breaking Changes: - open_seed_optimize parameter removed from trade parameters (now global setting) - Seed optimization is now enabled by default for all operations --- Cargo.toml | 2 +- README.md | 14 +++- README_CN.md | 14 +++- docs/TRADING_PARAMETERS.md | 16 +++- docs/TRADING_PARAMETERS_CN.md | 16 +++- examples/address_lookup/src/main.rs | 1 - examples/bonk_copy_trading/src/main.rs | 2 - examples/bonk_sniper_trading/src/main.rs | 2 - examples/cli_trading/src/main.rs | 10 --- .../src/main.rs | 2 - examples/middleware_system/src/main.rs | 1 - examples/nonce_cache/src/main.rs | 1 - examples/pumpfun_copy_trading/src/main.rs | 2 - examples/pumpfun_sniper_trading/src/main.rs | 2 - examples/pumpswap_direct_trading/src/main.rs | 2 - examples/pumpswap_trading/src/main.rs | 2 - examples/raydium_amm_v4_trading/src/main.rs | 2 - examples/raydium_cpmm_trading/src/main.rs | 2 - examples/seed_trading/src/main.rs | 2 - src/common/types.rs | 26 +++++- src/lib.rs | 84 +++++++++++++++++-- src/trading/common/wsol_manager.rs | 24 ++++++ src/trading/core/transaction_pool.rs | 18 ---- 23 files changed, 173 insertions(+), 74 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b8068ec..1f2d066 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sol-trade-sdk" -version = "3.1.7" +version = "3.2.0" edition = "2021" authors = [ "William ", diff --git a/README.md b/README.md index 348e8aa..f44a32b 100644 --- a/README.md +++ b/README.md @@ -87,14 +87,14 @@ Add the dependency to your `Cargo.toml`: ```toml # Add to your Cargo.toml -sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.1.7" } +sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.2.0" } ``` ### Use crates.io ```toml # Add to your Cargo.toml -sol-trade-sdk = "3.1.7" +sol-trade-sdk = "3.2.0" ``` ## 🛠️ Usage Examples @@ -126,6 +126,14 @@ let swqos_configs: Vec = vec![ ]; // Create TradeConfig instance let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); + +// Optional: Customize WSOL ATA and Seed optimization settings +// let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment) +// .with_wsol_ata_config( +// true, // create_wsol_ata_on_startup: Check and create WSOL ATA on startup (default: true) +// true // use_seed_optimize: Enable seed optimization globally for all ATA operations (default: true) +// ); + // Create SolanaTrade client let client = SolanaTrade::new(Arc::new(payer), trade_config).await; ``` @@ -159,8 +167,8 @@ let buy_params = sol_trade_sdk::TradeBuyParams { create_input_token_ata: true, close_input_token_ata: true, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, + // Note: seed optimization is now configured globally in TradeConfig }; ``` diff --git a/README_CN.md b/README_CN.md index 6dcdfc9..3b2978c 100755 --- a/README_CN.md +++ b/README_CN.md @@ -87,14 +87,14 @@ git clone https://github.com/0xfnzero/sol-trade-sdk ```toml # 添加到您的 Cargo.toml -sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.1.7" } +sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.2.0" } ``` ### 使用 crates.io ```toml # 添加到您的 Cargo.toml -sol-trade-sdk = "3.1.7" +sol-trade-sdk = "3.2.0" ``` ## 🛠️ 使用示例 @@ -126,6 +126,14 @@ let swqos_configs: Vec = vec![ ]; // 创建 TradeConfig 实例 let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment); + +// 可选:自定义 WSOL ATA 和 Seed 优化设置 +// let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment) +// .with_wsol_ata_config( +// true, // create_wsol_ata_on_startup: 启动时检查并创建 WSOL ATA(默认: true) +// true // use_seed_optimize: 全局启用所有 ATA 操作的 seed 优化(默认: true) +// ); + // 创建 SolanaTrade 客户端 let client = SolanaTrade::new(Arc::new(payer), trade_config).await; ``` @@ -159,8 +167,8 @@ let buy_params = sol_trade_sdk::TradeBuyParams { create_input_token_ata: true, close_input_token_ata: true, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, + // 注意:seed 优化现在在 TradeConfig 中全局配置 }; ``` diff --git a/docs/TRADING_PARAMETERS.md b/docs/TRADING_PARAMETERS.md index 6e09a25..debffd8 100644 --- a/docs/TRADING_PARAMETERS.md +++ b/docs/TRADING_PARAMETERS.md @@ -34,7 +34,6 @@ The `TradeBuyParams` struct contains all parameters required for executing buy o | `create_input_token_ata` | `bool` | ✅ | Whether to create input token Associated Token Account | | `close_input_token_ata` | `bool` | ✅ | Whether to close input token ATA after transaction | | `create_mint_ata` | `bool` | ✅ | Whether to create token mint ATA | -| `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 | @@ -66,7 +65,6 @@ The `TradeSellParams` struct contains all parameters required for executing sell | `wait_transaction_confirmed` | `bool` | ✅ | Whether to wait for transaction confirmation | | `create_output_token_ata` | `bool` | ✅ | Whether to create output token Associated Token Account | | `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) | @@ -105,7 +103,6 @@ These parameters control automatic account creation and management: These parameters enable advanced optimizations: - **address_lookup_table_account**: Use address lookup tables for reduced transaction size -- **open_seed_optimize**: Use seed-based account creation for lower CU consumption ### 🔄 Token Type Parameters @@ -123,7 +120,18 @@ When you need to use durable nonce, you need to fill in this parameter: ### 🌱 Seed Optimization -When `open_seed_optimize: true`: +Seed optimization is now configured globally in `TradeConfig` when creating the `SolanaTrade` instance: + +```rust +// Enable seed optimization globally (default: true) +let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment) + .with_wsol_ata_config( + true, // create_wsol_ata_on_startup: Check and create WSOL ATA on startup (default: true) + true // use_seed_optimize: Enable seed optimization for all ATA operations (default: true) + ); +``` + +When seed optimization is enabled: - ⚠️ **Warning**: Tokens purchased with seed optimization must be sold through this SDK - ⚠️ **Warning**: Official platform selling methods may fail - 📝 **Note**: Use `get_associated_token_address_with_program_id_fast_use_seed` to get ATA addresses diff --git a/docs/TRADING_PARAMETERS_CN.md b/docs/TRADING_PARAMETERS_CN.md index 1c6c880..e71e58b 100644 --- a/docs/TRADING_PARAMETERS_CN.md +++ b/docs/TRADING_PARAMETERS_CN.md @@ -34,7 +34,6 @@ | `create_input_token_ata` | `bool` | ✅ | 是否创建输入代币关联代币账户 | | `close_input_token_ata` | `bool` | ✅ | 交易后是否关闭输入代币 ATA | | `create_mint_ata` | `bool` | ✅ | 是否创建代币 mint ATA | -| `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 策略实例,用于控制交易费用和优先级 | @@ -66,7 +65,6 @@ | `wait_transaction_confirmed` | `bool` | ✅ | 是否等待交易确认 | | `create_output_token_ata` | `bool` | ✅ | 是否创建输出代币关联代币账户 | | `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 必需) | @@ -105,7 +103,6 @@ 这些参数启用高级优化: - **address_lookup_table_account**: 使用地址查找表减少交易大小 -- **open_seed_optimize**: 使用基于 seed 的账户创建以降低 CU 消耗 ### 🔄 代币类型参数 @@ -123,7 +120,18 @@ ### 🌱 Seed 优化 -当 `open_seed_optimize: true` 时: +Seed 优化现在在创建 `SolanaTrade` 实例时通过 `TradeConfig` 全局配置: + +```rust +// 全局启用 seed 优化(默认: true) +let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment) + .with_wsol_ata_config( + true, // create_wsol_ata_on_startup: 启动时检查并创建 WSOL ATA(默认: true) + true // use_seed_optimize: 为所有 ATA 操作启用 seed 优化(默认: true) + ); +``` + +当 seed 优化启用时: - ⚠️ **警告**: 使用 seed 优化购买的代币必须通过此 SDK 出售 - ⚠️ **警告**: 官方平台的出售方法可能会失败 - 📝 **注意**: 使用 `get_associated_token_address_with_program_id_fast_use_seed` 获取 ATA 地址 diff --git a/examples/address_lookup/src/main.rs b/examples/address_lookup/src/main.rs index df2858d..39b73d2 100644 --- a/examples/address_lookup/src/main.rs +++ b/examples/address_lookup/src/main.rs @@ -154,7 +154,6 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul create_input_token_ata: false, close_input_token_ata: false, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, diff --git a/examples/bonk_copy_trading/src/main.rs b/examples/bonk_copy_trading/src/main.rs index 2896512..9b0a62b 100644 --- a/examples/bonk_copy_trading/src/main.rs +++ b/examples/bonk_copy_trading/src/main.rs @@ -162,7 +162,6 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> create_input_token_ata: true, close_input_token_ata: false, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -204,7 +203,6 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> )), address_lookup_table_account: None, wait_transaction_confirmed: true, - open_seed_optimize: false, with_tip: false, durable_nonce: None, create_output_token_ata: false, diff --git a/examples/bonk_sniper_trading/src/main.rs b/examples/bonk_sniper_trading/src/main.rs index 3423587..ea3cf3a 100644 --- a/examples/bonk_sniper_trading/src/main.rs +++ b/examples/bonk_sniper_trading/src/main.rs @@ -132,7 +132,6 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult< create_input_token_ata: true, close_input_token_ata: true, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -170,7 +169,6 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult< 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, diff --git a/examples/cli_trading/src/main.rs b/examples/cli_trading/src/main.rs index 44fee86..40006fc 100644 --- a/examples/cli_trading/src/main.rs +++ b/examples/cli_trading/src/main.rs @@ -630,7 +630,6 @@ async fn handle_buy_pumpfun( create_input_token_ata: false, close_input_token_ata: false, create_mint_ata: create_mint_ata, - open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, @@ -685,7 +684,6 @@ async fn handle_buy_pumpswap( create_input_token_ata: true, close_input_token_ata: false, create_mint_ata: create_mint_ata, - open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, @@ -739,7 +737,6 @@ async fn handle_buy_bonk( create_input_token_ata: true, close_input_token_ata: false, create_mint_ata: create_mint_ata, - open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, @@ -797,7 +794,6 @@ async fn handle_buy_raydium_v4( create_input_token_ata: true, close_input_token_ata: false, create_mint_ata: create_mint_ata, - open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, @@ -855,7 +851,6 @@ async fn handle_buy_raydium_cpmm( create_input_token_ata: true, close_input_token_ata: false, create_mint_ata: create_mint_ata, - open_seed_optimize: use_seed, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, @@ -1024,7 +1019,6 @@ async fn handle_sell_pumpfun( 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, @@ -1083,7 +1077,6 @@ async fn handle_sell_pumpswap( 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, @@ -1141,7 +1134,6 @@ async fn handle_sell_bonk( 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, @@ -1202,7 +1194,6 @@ async fn handle_sell_raydium_v4( 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, @@ -1263,7 +1254,6 @@ async fn handle_sell_raydium_cpmm( 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, diff --git a/examples/meteora_damm_v2_direct_trading/src/main.rs b/examples/meteora_damm_v2_direct_trading/src/main.rs index 55284d1..d2e1664 100644 --- a/examples/meteora_damm_v2_direct_trading/src/main.rs +++ b/examples/meteora_damm_v2_direct_trading/src/main.rs @@ -43,7 +43,6 @@ async fn main() -> Result<(), Box> { create_input_token_ata: false, //if input token is SOL/WSOL,set to true,if input token is USDC,set to false. close_input_token_ata: false, //if input token is SOL/WSOL,set to true,if input token is USDC,set to false. create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: Some(1), gas_fee_strategy: gas_fee_strategy.clone(), @@ -77,7 +76,6 @@ async fn main() -> Result<(), Box> { 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, diff --git a/examples/middleware_system/src/main.rs b/examples/middleware_system/src/main.rs index ed6b268..b6eb4af 100644 --- a/examples/middleware_system/src/main.rs +++ b/examples/middleware_system/src/main.rs @@ -98,7 +98,6 @@ async fn test_middleware() -> AnyResult<()> { create_input_token_ata: true, close_input_token_ata: true, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, diff --git a/examples/nonce_cache/src/main.rs b/examples/nonce_cache/src/main.rs index b32718b..7531a80 100644 --- a/examples/nonce_cache/src/main.rs +++ b/examples/nonce_cache/src/main.rs @@ -154,7 +154,6 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul create_input_token_ata: false, close_input_token_ata: false, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: durable_nonce, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy, diff --git a/examples/pumpfun_copy_trading/src/main.rs b/examples/pumpfun_copy_trading/src/main.rs index 162f44b..4d7ac66 100644 --- a/examples/pumpfun_copy_trading/src/main.rs +++ b/examples/pumpfun_copy_trading/src/main.rs @@ -150,7 +150,6 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul create_input_token_ata: false, close_input_token_ata: false, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -194,7 +193,6 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul 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, diff --git a/examples/pumpfun_sniper_trading/src/main.rs b/examples/pumpfun_sniper_trading/src/main.rs index 3b212fd..231de9a 100644 --- a/examples/pumpfun_sniper_trading/src/main.rs +++ b/examples/pumpfun_sniper_trading/src/main.rs @@ -116,7 +116,6 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR create_input_token_ata: true, close_input_token_ata: true, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -149,7 +148,6 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR 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, diff --git a/examples/pumpswap_direct_trading/src/main.rs b/examples/pumpswap_direct_trading/src/main.rs index 282e437..432277d 100644 --- a/examples/pumpswap_direct_trading/src/main.rs +++ b/examples/pumpswap_direct_trading/src/main.rs @@ -43,7 +43,6 @@ async fn main() -> Result<(), Box> { create_input_token_ata: true, close_input_token_ata: true, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -76,7 +75,6 @@ async fn main() -> Result<(), Box> { 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, diff --git a/examples/pumpswap_trading/src/main.rs b/examples/pumpswap_trading/src/main.rs index f0fdc63..a71829f 100644 --- a/examples/pumpswap_trading/src/main.rs +++ b/examples/pumpswap_trading/src/main.rs @@ -212,7 +212,6 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) - create_input_token_ata: is_sol, close_input_token_ata: is_sol, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -247,7 +246,6 @@ async fn pumpswap_trade_with_grpc(mint_pubkey: Pubkey, params: PumpSwapParams) - 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, diff --git a/examples/raydium_amm_v4_trading/src/main.rs b/examples/raydium_amm_v4_trading/src/main.rs index e0857db..9772662 100644 --- a/examples/raydium_amm_v4_trading/src/main.rs +++ b/examples/raydium_amm_v4_trading/src/main.rs @@ -160,7 +160,6 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent) create_input_token_ata: is_wsol, close_input_token_ata: is_wsol, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -194,7 +193,6 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent) 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, diff --git a/examples/raydium_cpmm_trading/src/main.rs b/examples/raydium_cpmm_trading/src/main.rs index 4be1f73..5201df8 100644 --- a/examples/raydium_cpmm_trading/src/main.rs +++ b/examples/raydium_cpmm_trading/src/main.rs @@ -154,7 +154,6 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) -> create_input_token_ata: is_wsol, close_input_token_ata: is_wsol, create_mint_ata: true, - open_seed_optimize: false, durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -190,7 +189,6 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) -> 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, diff --git a/examples/seed_trading/src/main.rs b/examples/seed_trading/src/main.rs index 31ea304..2c8e302 100644 --- a/examples/seed_trading/src/main.rs +++ b/examples/seed_trading/src/main.rs @@ -42,7 +42,6 @@ async fn main() -> Result<(), Box> { create_input_token_ata: true, close_input_token_ata: true, create_mint_ata: true, - open_seed_optimize: true, // ❗️❗️❗️❗️ open seed optimize durable_nonce: None, fixed_output_token_amount: None, gas_fee_strategy: gas_fee_strategy.clone(), @@ -83,7 +82,6 @@ async fn main() -> Result<(), Box> { 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, diff --git a/src/common/types.rs b/src/common/types.rs index d36dea2..d6c6432 100755 --- a/src/common/types.rs +++ b/src/common/types.rs @@ -6,6 +6,11 @@ pub struct TradeConfig { pub rpc_url: String, pub swqos_configs: Vec, pub commitment: CommitmentConfig, + /// Whether to create WSOL ATA on startup (default: true) + /// If true, SDK will check WSOL ATA on initialization and create if not exists + pub create_wsol_ata_on_startup: bool, + /// Whether to use seed optimization for all ATA operations (default: true) + pub use_seed_optimize: bool, } impl TradeConfig { @@ -14,7 +19,26 @@ impl TradeConfig { swqos_configs: Vec, commitment: CommitmentConfig, ) -> Self { - Self { rpc_url, swqos_configs, commitment } + println!("🔧 TradeConfig create_wsol_ata_on_startup default value: true"); + println!("🔧 TradeConfig use_seed_optimize default value: true"); + Self { + rpc_url, + swqos_configs, + commitment, + create_wsol_ata_on_startup: true, // 默认:启动时检查并创建 + use_seed_optimize: true, // 默认:使用seed优化 + } + } + + /// Create a TradeConfig with custom WSOL ATA settings + pub fn with_wsol_ata_config( + mut self, + create_wsol_ata_on_startup: bool, + use_seed_optimize: bool, + ) -> Self { + self.create_wsol_ata_on_startup = create_wsol_ata_on_startup; + self.use_seed_optimize = use_seed_optimize; + self } } diff --git a/src/lib.rs b/src/lib.rs index e19b8ee..a356d68 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,6 +59,9 @@ pub struct SolanaTrade { pub swqos_clients: Vec>, /// Optional middleware manager for custom transaction processing pub middleware_manager: Option>, + /// Whether to use seed optimization for all ATA operations (default: true) + /// Applies to all token account creations across buy and sell operations + pub use_seed_optimize: bool, } static INSTANCE: Mutex>> = Mutex::new(None); @@ -70,6 +73,7 @@ impl Clone for SolanaTrade { rpc: self.rpc.clone(), swqos_clients: self.swqos_clients.clone(), middleware_manager: self.middleware_manager.clone(), + use_seed_optimize: self.use_seed_optimize, } } } @@ -106,8 +110,6 @@ pub struct TradeBuyParams { pub close_input_token_ata: bool, /// Whether to create token mint associated token account pub create_mint_ata: bool, - /// Whether to enable seed-based optimization for account creation - pub open_seed_optimize: bool, /// Durable nonce information 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) @@ -152,8 +154,6 @@ pub struct TradeSellParams { pub close_output_token_ata: bool, /// Whether to close mint token associated token account after trade pub close_mint_token_ata: bool, - /// Whether to enable seed-based optimization for account creation - pub open_seed_optimize: bool, /// Durable nonce information 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) @@ -204,7 +204,77 @@ impl SolanaTrade { common::seed::update_rents(&rpc).await.unwrap(); common::seed::start_rent_updater(rpc.clone()); - let instance = Self { payer, rpc, swqos_clients, middleware_manager: None }; + // 🔧 初始化WSOL ATA:如果配置为启动时创建,则检查并创建 + if trade_config.create_wsol_ata_on_startup { + // 根据seed配置计算WSOL ATA地址 + let wsol_ata = + crate::common::fast_fn::get_associated_token_address_with_program_id_fast( + &payer.pubkey(), + &WSOL_TOKEN_ACCOUNT, + &crate::constants::TOKEN_PROGRAM, + ); + + // 查询账户是否存在 + match rpc.get_account(&wsol_ata).await { + Ok(_) => { + // WSOL ATA已存在 + println!("✅ WSOL ATA已存在: {}", wsol_ata); + } + Err(_) => { + // WSOL ATA不存在,创建它 + println!("🔨 创建WSOL ATA: {}", wsol_ata); + // 使用seed优化创建WSOL ATA + let create_ata_ixs = + crate::trading::common::wsol_manager::create_wsol_ata(&payer.pubkey()); + + if !create_ata_ixs.is_empty() { + // 构建并发送交易 + use solana_sdk::transaction::Transaction; + let recent_blockhash = rpc.get_latest_blockhash().await.unwrap(); + let tx = Transaction::new_signed_with_payer( + &create_ata_ixs, + Some(&payer.pubkey()), + &[payer.as_ref()], + recent_blockhash, + ); + + match rpc.send_and_confirm_transaction(&tx).await { + Ok(signature) => { + println!("✅ WSOL ATA创建成功: {}", signature); + } + Err(e) => { + // 创建失败,检查是否是因为已存在 + match rpc.get_account(&wsol_ata).await { + Ok(_) => { + println!( + "✅ WSOL ATA已存在(交易失败但账户存在): {}", + wsol_ata + ); + } + Err(_) => { + // 账户不存在且创建失败 - 这是严重错误,应该让启动失败 + panic!( + "❌ WSOL ATA创建失败且账户不存在: {}. 错误: {}", + wsol_ata, e + ); + } + } + } + } + } else { + println!("ℹ️ WSOL ATA已存在(无需创建)"); + } + } + } + } + + let instance = Self { + payer, + rpc, + swqos_clients, + middleware_manager: None, + use_seed_optimize: trade_config.use_seed_optimize, + }; let mut current = INSTANCE.lock(); *current = Some(Arc::new(instance.clone())); @@ -313,7 +383,7 @@ impl SolanaTrade { data_size_limit: 256 * 1024, wait_transaction_confirmed: params.wait_transaction_confirmed, protocol_params: protocol_params.clone(), - open_seed_optimize: params.open_seed_optimize, + open_seed_optimize: self.use_seed_optimize, // 使用全局seed优化配置 swqos_clients: self.swqos_clients.clone(), middleware_manager: self.middleware_manager.clone(), durable_nonce: params.durable_nonce, @@ -410,7 +480,7 @@ impl SolanaTrade { wait_transaction_confirmed: params.wait_transaction_confirmed, protocol_params: protocol_params.clone(), with_tip: params.with_tip, - open_seed_optimize: params.open_seed_optimize, + open_seed_optimize: self.use_seed_optimize, // 使用全局seed优化配置 swqos_clients: self.swqos_clients.clone(), middleware_manager: self.middleware_manager.clone(), durable_nonce: params.durable_nonce, diff --git a/src/trading/common/wsol_manager.rs b/src/trading/common/wsol_manager.rs index 9b0d869..00cbe14 100644 --- a/src/trading/common/wsol_manager.rs +++ b/src/trading/common/wsol_manager.rs @@ -68,3 +68,27 @@ pub fn create_wsol_ata(payer: &Pubkey) -> Vec { &crate::constants::TOKEN_PROGRAM, ) } + +/// 只充值SOL到已存在的WSOL ATA(不创建账户)- 标准方式 +#[inline] +pub fn wrap_sol_only(payer: &Pubkey, amount_in: u64) -> SmallVec<[Instruction; 2]> { + let wsol_token_account = + crate::common::fast_fn::get_associated_token_address_with_program_id_fast( + &payer, + &crate::constants::WSOL_TOKEN_ACCOUNT, + &crate::constants::TOKEN_PROGRAM, + ); + + let mut insts = SmallVec::<[Instruction; 2]>::new(); + insts.extend([ + transfer(&payer, &wsol_token_account, amount_in), + // sync_native + Instruction { + program_id: crate::constants::TOKEN_PROGRAM, + accounts: vec![AccountMeta::new(wsol_token_account, false)], + data: vec![17], + }, + ]); + + insts +} diff --git a/src/trading/core/transaction_pool.rs b/src/trading/core/transaction_pool.rs index 11810ae..d8d0473 100644 --- a/src/trading/core/transaction_pool.rs +++ b/src/trading/core/transaction_pool.rs @@ -74,24 +74,6 @@ impl PreallocatedTxBuilder { // ✅ 如果有查找表,使用 V0 消息 if let Some(address_lookup_table_account) = address_lookup_table_account { - // self.lookup_tables.push(v0::MessageAddressTableLookup { - // account_key: table_key, - // writable_indexes: vec![], - // readonly_indexes: vec![], - // }); - - // // 使用 Message::new 创建 legacy 消息,然后提取编译后的指令 - // let legacy_msg = Message::new(&self.instructions, Some(payer)); - - // // 构建 V0 消息 - // let message = v0::Message { - // header: legacy_msg.header, - // account_keys: legacy_msg.account_keys, - // recent_blockhash, - // instructions: legacy_msg.instructions, - // address_table_lookups: self.lookup_tables.clone(), - // }; - let message = v0::Message::try_compile( payer, &self.instructions,