feat(swqos): add Stellium support and update minimum tip requirements
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
# 更新日志
|
||||||
|
|
||||||
|
## [3.3.6] - 2025-01-30
|
||||||
|
|
||||||
|
### 新增
|
||||||
|
- **Stellium SWQOS 支持**:全新 Stellium 客户端实现
|
||||||
|
- 使用标准 Solana `sendTransaction` RPC 格式
|
||||||
|
- 自动连接保活,60 秒 ping 间隔
|
||||||
|
- 5 个小费账户用于负载分配
|
||||||
|
- 支持 8 个区域端点(纽约、法兰克福、阿姆斯特丹、东京、伦敦等)
|
||||||
|
- 最低小费要求:0.001 SOL
|
||||||
|
|
||||||
|
### 变更
|
||||||
|
- **更新最低小费要求**以提高交易成功率:
|
||||||
|
- NextBlock: 0.00001 → 0.001 SOL
|
||||||
|
- ZeroSlot: 0.00001 → 0.001 SOL
|
||||||
|
- Temporal: 0.00001 → 0.001 SOL
|
||||||
|
- BloxRoute: 0.00001 → 0.001 SOL
|
||||||
|
- FlashBlock: 0.00001 → 0.001 SOL
|
||||||
|
- BlockRazor: 0.00001 → 0.001 SOL
|
||||||
|
- 增强异步执行器,添加小费验证警告
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sol-trade-sdk"
|
name = "sol-trade-sdk"
|
||||||
version = "3.3.5"
|
version = "3.3.6"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = [
|
authors = [
|
||||||
"William <byteblock6@gmail.com>",
|
"William <byteblock6@gmail.com>",
|
||||||
|
|||||||
@@ -87,14 +87,14 @@ Add the dependency to your `Cargo.toml`:
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
# Add to your Cargo.toml
|
# Add to your Cargo.toml
|
||||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.3.5" }
|
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.3.6" }
|
||||||
```
|
```
|
||||||
|
|
||||||
### Use crates.io
|
### Use crates.io
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# Add to your Cargo.toml
|
# Add to your Cargo.toml
|
||||||
sol-trade-sdk = "3.3.5"
|
sol-trade-sdk = "3.3.6"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🛠️ Usage Examples
|
## 🛠️ Usage Examples
|
||||||
|
|||||||
+2
-2
@@ -87,14 +87,14 @@ git clone https://github.com/0xfnzero/sol-trade-sdk
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
# 添加到您的 Cargo.toml
|
# 添加到您的 Cargo.toml
|
||||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.3.5" }
|
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.3.6" }
|
||||||
```
|
```
|
||||||
|
|
||||||
### 使用 crates.io
|
### 使用 crates.io
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# 添加到您的 Cargo.toml
|
# 添加到您的 Cargo.toml
|
||||||
sol-trade-sdk = "3.3.5"
|
sol-trade-sdk = "3.3.6"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🛠️ 使用示例
|
## 🛠️ 使用示例
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ use std::sync::{
|
|||||||
Arc,
|
Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
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::TradeConfig;
|
||||||
|
use sol_trade_sdk::common::{
|
||||||
|
fast_fn::get_associated_token_address_with_program_id_fast_use_seed, GasFeeStrategy,
|
||||||
|
};
|
||||||
use sol_trade_sdk::{
|
use sol_trade_sdk::{
|
||||||
common::AnyResult,
|
common::AnyResult,
|
||||||
swqos::SwqosConfig,
|
swqos::SwqosConfig,
|
||||||
@@ -125,7 +127,16 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()>
|
|||||||
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
let gas_fee_strategy = GasFeeStrategy::new();
|
let gas_fee_strategy = GasFeeStrategy::new();
|
||||||
gas_fee_strategy.set_global_fee_strategy(150000,150000, 500000,500000, 0.001, 0.001, 256 * 1024, 0);
|
gas_fee_strategy.set_global_fee_strategy(
|
||||||
|
150000,
|
||||||
|
150000,
|
||||||
|
500000,
|
||||||
|
500000,
|
||||||
|
0.001,
|
||||||
|
0.001,
|
||||||
|
256 * 1024,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
// Buy tokens
|
// Buy tokens
|
||||||
println!("Buying tokens from Bonk...");
|
println!("Buying tokens from Bonk...");
|
||||||
@@ -174,7 +185,12 @@ async fn bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()>
|
|||||||
|
|
||||||
let rpc = client.rpc.clone();
|
let rpc = client.rpc.clone();
|
||||||
let payer = client.payer.pubkey();
|
let payer = client.payer.pubkey();
|
||||||
let account = get_associated_token_address(&payer, &mint_pubkey);
|
let account = get_associated_token_address_with_program_id_fast_use_seed(
|
||||||
|
&payer,
|
||||||
|
&mint_pubkey,
|
||||||
|
&trade_info.base_token_program,
|
||||||
|
client.use_seed_optimize,
|
||||||
|
);
|
||||||
let balance = rpc.get_token_account_balance(&account).await?;
|
let balance = rpc.get_token_account_balance(&account).await?;
|
||||||
println!("Balance: {:?}", balance);
|
println!("Balance: {:?}", balance);
|
||||||
let amount_token = balance.amount.parse::<u64>().unwrap();
|
let amount_token = balance.amount.parse::<u64>().unwrap();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use sol_trade_sdk::common::spl_associated_token_account::get_associated_token_address;
|
use sol_trade_sdk::common::fast_fn::get_associated_token_address_with_program_id_fast_use_seed;
|
||||||
use sol_trade_sdk::common::TradeConfig;
|
use sol_trade_sdk::common::TradeConfig;
|
||||||
use sol_trade_sdk::{
|
use sol_trade_sdk::{
|
||||||
common::AnyResult,
|
common::AnyResult,
|
||||||
@@ -95,7 +95,16 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<
|
|||||||
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
||||||
gas_fee_strategy.set_global_fee_strategy(150000,150000, 500000,500000, 0.001, 0.001, 256 * 1024, 0);
|
gas_fee_strategy.set_global_fee_strategy(
|
||||||
|
150000,
|
||||||
|
150000,
|
||||||
|
500000,
|
||||||
|
500000,
|
||||||
|
0.001,
|
||||||
|
0.001,
|
||||||
|
256 * 1024,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
let token_type = if trade_info.quote_token_mint == sol_trade_sdk::constants::USD1_TOKEN_ACCOUNT
|
let token_type = if trade_info.quote_token_mint == sol_trade_sdk::constants::USD1_TOKEN_ACCOUNT
|
||||||
{
|
{
|
||||||
@@ -144,7 +153,12 @@ async fn bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<
|
|||||||
|
|
||||||
let rpc = client.rpc.clone();
|
let rpc = client.rpc.clone();
|
||||||
let payer = client.payer.pubkey();
|
let payer = client.payer.pubkey();
|
||||||
let account = get_associated_token_address(&payer, &mint_pubkey);
|
let account = get_associated_token_address_with_program_id_fast_use_seed(
|
||||||
|
&payer,
|
||||||
|
&mint_pubkey,
|
||||||
|
&trade_info.base_token_program,
|
||||||
|
client.use_seed_optimize,
|
||||||
|
);
|
||||||
let balance = rpc.get_token_account_balance(&account).await?;
|
let balance = rpc.get_token_account_balance(&account).await?;
|
||||||
println!("Balance: {:?}", balance);
|
println!("Balance: {:?}", balance);
|
||||||
let amount_token = balance.amount.parse::<u64>().unwrap();
|
let amount_token = balance.amount.parse::<u64>().unwrap();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::sync::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use sol_trade_sdk::common::{
|
use sol_trade_sdk::common::{
|
||||||
spl_associated_token_account::get_associated_token_address, TradeConfig,
|
fast_fn::get_associated_token_address_with_program_id_fast_use_seed, TradeConfig,
|
||||||
};
|
};
|
||||||
use sol_trade_sdk::TradeTokenType;
|
use sol_trade_sdk::TradeTokenType;
|
||||||
use sol_trade_sdk::{
|
use sol_trade_sdk::{
|
||||||
@@ -121,7 +121,16 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
|
|||||||
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
||||||
gas_fee_strategy.set_global_fee_strategy(150000,150000, 500000,500000, 0.001, 0.001, 256 * 1024, 0);
|
gas_fee_strategy.set_global_fee_strategy(
|
||||||
|
150000,
|
||||||
|
150000,
|
||||||
|
500000,
|
||||||
|
500000,
|
||||||
|
0.001,
|
||||||
|
0.001,
|
||||||
|
256 * 1024,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
// Buy tokens
|
// Buy tokens
|
||||||
println!("Buying tokens from PumpFun...");
|
println!("Buying tokens from PumpFun...");
|
||||||
@@ -164,7 +173,12 @@ async fn pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResul
|
|||||||
|
|
||||||
let rpc = client.rpc.clone();
|
let rpc = client.rpc.clone();
|
||||||
let payer = client.payer.pubkey();
|
let payer = client.payer.pubkey();
|
||||||
let account = get_associated_token_address(&payer, &mint_pubkey);
|
let account = get_associated_token_address_with_program_id_fast_use_seed(
|
||||||
|
&payer,
|
||||||
|
&mint_pubkey,
|
||||||
|
&trade_info.token_program,
|
||||||
|
client.use_seed_optimize,
|
||||||
|
);
|
||||||
let balance = rpc.get_token_account_balance(&account).await?;
|
let balance = rpc.get_token_account_balance(&account).await?;
|
||||||
println!("Balance: {:?}", balance);
|
println!("Balance: {:?}", balance);
|
||||||
let amount_token = balance.amount.parse::<u64>().unwrap();
|
let amount_token = balance.amount.parse::<u64>().unwrap();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use sol_trade_sdk::common::spl_associated_token_account::get_associated_token_address;
|
use sol_trade_sdk::common::fast_fn::get_associated_token_address_with_program_id_fast_use_seed;
|
||||||
use sol_trade_sdk::common::TradeConfig;
|
use sol_trade_sdk::common::TradeConfig;
|
||||||
use sol_trade_sdk::TradeTokenType;
|
use sol_trade_sdk::TradeTokenType;
|
||||||
use sol_trade_sdk::{
|
use sol_trade_sdk::{
|
||||||
@@ -89,7 +89,16 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
|
|||||||
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
||||||
gas_fee_strategy.set_global_fee_strategy(150000,150000, 500000,500000, 0.001, 0.001, 256 * 1024, 0);
|
gas_fee_strategy.set_global_fee_strategy(
|
||||||
|
150000,
|
||||||
|
150000,
|
||||||
|
500000,
|
||||||
|
500000,
|
||||||
|
0.001,
|
||||||
|
0.001,
|
||||||
|
256 * 1024,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
// Buy tokens
|
// Buy tokens
|
||||||
println!("Buying tokens from PumpFun...");
|
println!("Buying tokens from PumpFun...");
|
||||||
@@ -130,7 +139,12 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
|
|||||||
|
|
||||||
let rpc = client.rpc.clone();
|
let rpc = client.rpc.clone();
|
||||||
let payer = client.payer.pubkey();
|
let payer = client.payer.pubkey();
|
||||||
let account = get_associated_token_address(&payer, &mint_pubkey);
|
let account = get_associated_token_address_with_program_id_fast_use_seed(
|
||||||
|
&payer,
|
||||||
|
&mint_pubkey,
|
||||||
|
&trade_info.token_program,
|
||||||
|
client.use_seed_optimize,
|
||||||
|
);
|
||||||
let balance = rpc.get_token_account_balance(&account).await?;
|
let balance = rpc.get_token_account_balance(&account).await?;
|
||||||
println!("Balance: {:?}", balance);
|
println!("Balance: {:?}", balance);
|
||||||
let amount_token = balance.amount.parse::<u64>().unwrap();
|
let amount_token = balance.amount.parse::<u64>().unwrap();
|
||||||
@@ -144,7 +158,11 @@ async fn pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyR
|
|||||||
slippage_basis_points: slippage_basis_points,
|
slippage_basis_points: slippage_basis_points,
|
||||||
recent_blockhash: Some(recent_blockhash),
|
recent_blockhash: Some(recent_blockhash),
|
||||||
with_tip: false,
|
with_tip: false,
|
||||||
extension_params: Box::new(PumpFunParams::immediate_sell(trade_info.creator_vault, trade_info.token_program, true)),
|
extension_params: Box::new(PumpFunParams::immediate_sell(
|
||||||
|
trade_info.creator_vault,
|
||||||
|
trade_info.token_program,
|
||||||
|
true,
|
||||||
|
)),
|
||||||
address_lookup_table_account: None,
|
address_lookup_table_account: None,
|
||||||
wait_transaction_confirmed: true,
|
wait_transaction_confirmed: true,
|
||||||
create_output_token_ata: true,
|
create_output_token_ata: true,
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
|
use sol_trade_sdk::common::fast_fn::get_associated_token_address_with_program_id_fast_use_seed;
|
||||||
use sol_trade_sdk::{
|
use sol_trade_sdk::{
|
||||||
common::TradeConfig, instruction::utils::raydium_amm_v4::fetch_amm_info,
|
common::AnyResult,
|
||||||
trading::common::get_multi_token_balances, TradeTokenType,
|
|
||||||
};
|
|
||||||
use sol_trade_sdk::{
|
|
||||||
common::{spl_associated_token_account::get_associated_token_address, AnyResult},
|
|
||||||
swqos::SwqosConfig,
|
swqos::SwqosConfig,
|
||||||
trading::{core::params::RaydiumAmmV4Params, factory::DexType},
|
trading::{core::params::RaydiumAmmV4Params, factory::DexType},
|
||||||
SolanaTrade,
|
SolanaTrade,
|
||||||
};
|
};
|
||||||
|
use sol_trade_sdk::{
|
||||||
|
common::TradeConfig, instruction::utils::raydium_amm_v4::fetch_amm_info,
|
||||||
|
trading::common::get_multi_token_balances, TradeTokenType,
|
||||||
|
};
|
||||||
use solana_commitment_config::CommitmentConfig;
|
use solana_commitment_config::CommitmentConfig;
|
||||||
use solana_sdk::signature::Keypair;
|
use solana_sdk::signature::Keypair;
|
||||||
use solana_sdk::signer::Signer;
|
use solana_sdk::signer::Signer;
|
||||||
@@ -123,8 +124,9 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
|
|||||||
let amm_info = fetch_amm_info(&client.rpc, trade_info.amm).await?;
|
let amm_info = fetch_amm_info(&client.rpc, trade_info.amm).await?;
|
||||||
let (coin_reserve, pc_reserve) =
|
let (coin_reserve, pc_reserve) =
|
||||||
get_multi_token_balances(&client.rpc, &amm_info.token_coin, &amm_info.token_pc).await?;
|
get_multi_token_balances(&client.rpc, &amm_info.token_coin, &amm_info.token_pc).await?;
|
||||||
let mint_pubkey = if amm_info.pc_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT
|
let mint_pubkey = if amm_info.pc_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT
|
||||||
|| amm_info.pc_mint == sol_trade_sdk::constants::USDC_TOKEN_ACCOUNT {
|
|| amm_info.pc_mint == sol_trade_sdk::constants::USDC_TOKEN_ACCOUNT
|
||||||
|
{
|
||||||
amm_info.coin_mint
|
amm_info.coin_mint
|
||||||
} else {
|
} else {
|
||||||
amm_info.pc_mint
|
amm_info.pc_mint
|
||||||
@@ -140,7 +142,16 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
|
|||||||
);
|
);
|
||||||
|
|
||||||
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
||||||
gas_fee_strategy.set_global_fee_strategy(150000,150000, 500000,500000, 0.001, 0.001, 256 * 1024, 0);
|
gas_fee_strategy.set_global_fee_strategy(
|
||||||
|
150000,
|
||||||
|
150000,
|
||||||
|
500000,
|
||||||
|
500000,
|
||||||
|
0.001,
|
||||||
|
0.001,
|
||||||
|
256 * 1024,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
// Buy tokens
|
// Buy tokens
|
||||||
println!("Buying tokens from Raydium_amm_v4...");
|
println!("Buying tokens from Raydium_amm_v4...");
|
||||||
@@ -172,7 +183,12 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
|
|||||||
|
|
||||||
let rpc = client.rpc.clone();
|
let rpc = client.rpc.clone();
|
||||||
let payer = client.payer.pubkey();
|
let payer = client.payer.pubkey();
|
||||||
let account = get_associated_token_address(&payer, &mint_pubkey);
|
let account = get_associated_token_address_with_program_id_fast_use_seed(
|
||||||
|
&payer,
|
||||||
|
&mint_pubkey,
|
||||||
|
&trade_info.token_program,
|
||||||
|
client.use_seed_optimize,
|
||||||
|
);
|
||||||
let balance = rpc.get_token_account_balance(&account).await?;
|
let balance = rpc.get_token_account_balance(&account).await?;
|
||||||
println!("Balance: {:?}", balance);
|
println!("Balance: {:?}", balance);
|
||||||
let amount_token = balance.amount.parse::<u64>().unwrap();
|
let amount_token = balance.amount.parse::<u64>().unwrap();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use sol_trade_sdk::common::spl_associated_token_account::get_associated_token_address;
|
use sol_trade_sdk::common::fast_fn::get_associated_token_address_with_program_id_fast_use_seed;
|
||||||
use sol_trade_sdk::common::TradeConfig;
|
use sol_trade_sdk::common::TradeConfig;
|
||||||
use sol_trade_sdk::constants::{WSOL_TOKEN_ACCOUNT, USDC_TOKEN_ACCOUNT};
|
use sol_trade_sdk::constants::{USDC_TOKEN_ACCOUNT, WSOL_TOKEN_ACCOUNT};
|
||||||
use sol_trade_sdk::trading::core::params::RaydiumCpmmParams;
|
use sol_trade_sdk::trading::core::params::RaydiumCpmmParams;
|
||||||
use sol_trade_sdk::trading::factory::DexType;
|
use sol_trade_sdk::trading::factory::DexType;
|
||||||
use sol_trade_sdk::TradeTokenType;
|
use sol_trade_sdk::TradeTokenType;
|
||||||
@@ -130,11 +130,20 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
|
|||||||
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
let gas_fee_strategy = sol_trade_sdk::common::GasFeeStrategy::new();
|
||||||
gas_fee_strategy.set_global_fee_strategy(150000,150000, 500000,500000, 0.001, 0.001, 256 * 1024, 0);
|
gas_fee_strategy.set_global_fee_strategy(
|
||||||
|
150000,
|
||||||
|
150000,
|
||||||
|
500000,
|
||||||
|
500000,
|
||||||
|
0.001,
|
||||||
|
0.001,
|
||||||
|
256 * 1024,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
let buy_params =
|
let buy_params =
|
||||||
RaydiumCpmmParams::from_pool_address_by_rpc(&client.rpc, &trade_info.pool_state).await?;
|
RaydiumCpmmParams::from_pool_address_by_rpc(&client.rpc, &trade_info.pool_state).await?;
|
||||||
|
|
||||||
let is_wsol = trade_info.input_token_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT
|
let is_wsol = trade_info.input_token_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT
|
||||||
|| trade_info.output_token_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT;
|
|| trade_info.output_token_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT;
|
||||||
|
|
||||||
@@ -166,7 +175,12 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
|
|||||||
|
|
||||||
let rpc = client.rpc.clone();
|
let rpc = client.rpc.clone();
|
||||||
let payer = client.payer.pubkey();
|
let payer = client.payer.pubkey();
|
||||||
let account = get_associated_token_address(&payer, &mint_pubkey);
|
let account = get_associated_token_address_with_program_id_fast_use_seed(
|
||||||
|
&payer,
|
||||||
|
&mint_pubkey,
|
||||||
|
&trade_info.output_token_program,
|
||||||
|
client.use_seed_optimize,
|
||||||
|
);
|
||||||
let balance = rpc.get_token_account_balance(&account).await?;
|
let balance = rpc.get_token_account_balance(&account).await?;
|
||||||
println!("Balance: {:?}", balance);
|
println!("Balance: {:?}", balance);
|
||||||
let amount_token = balance.amount.parse::<u64>().unwrap();
|
let amount_token = balance.amount.parse::<u64>().unwrap();
|
||||||
|
|||||||
@@ -5,6 +5,14 @@ use solana_sdk::{
|
|||||||
|
|
||||||
use crate::constants::{ASSOCIATED_TOKEN_PROGRAM_ID, SYSTEM_PROGRAM};
|
use crate::constants::{ASSOCIATED_TOKEN_PROGRAM_ID, SYSTEM_PROGRAM};
|
||||||
|
|
||||||
|
/// Get the associated token address with a specified token program ID.
|
||||||
|
///
|
||||||
|
/// # Warning
|
||||||
|
/// **This SDK enables seed optimization by default.** When seed is enabled, you should use
|
||||||
|
/// [`get_associated_token_address_with_program_id_fast_use_seed`] instead for better performance.
|
||||||
|
/// This function performs PDA derivation which is slower than the optimized version.
|
||||||
|
///
|
||||||
|
/// [`get_associated_token_address_with_program_id_fast_use_seed`]: crate::common::token_account::get_associated_token_address_with_program_id_fast_use_seed
|
||||||
pub fn get_associated_token_address_with_program_id(
|
pub fn get_associated_token_address_with_program_id(
|
||||||
wallet_address: &Pubkey,
|
wallet_address: &Pubkey,
|
||||||
token_mint_address: &Pubkey,
|
token_mint_address: &Pubkey,
|
||||||
@@ -17,6 +25,14 @@ pub fn get_associated_token_address_with_program_id(
|
|||||||
.0
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the associated token address for the default token program.
|
||||||
|
///
|
||||||
|
/// # Warning
|
||||||
|
/// **This SDK enables seed optimization by default.** When seed is enabled, you should use
|
||||||
|
/// [`get_associated_token_address_with_program_id_fast_use_seed`] instead for better performance.
|
||||||
|
/// This function performs PDA derivation which is slower than the optimized version.
|
||||||
|
///
|
||||||
|
/// [`get_associated_token_address_with_program_id_fast_use_seed`]: crate::common::token_account::get_associated_token_address_with_program_id_fast_use_seed
|
||||||
pub fn get_associated_token_address(
|
pub fn get_associated_token_address(
|
||||||
wallet_address: &Pubkey,
|
wallet_address: &Pubkey,
|
||||||
token_mint_address: &Pubkey,
|
token_mint_address: &Pubkey,
|
||||||
|
|||||||
+26
-6
@@ -109,6 +109,14 @@ pub const ASTRALANE_TIP_ACCOUNTS: &[Pubkey] = &[
|
|||||||
pubkey!("astrawVNP4xDBKT7rAdxrLYiTSTdqtUr63fSMduivXK"),
|
pubkey!("astrawVNP4xDBKT7rAdxrLYiTSTdqtUr63fSMduivXK"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub const STELLIUM_TIP_ACCOUNTS: &[Pubkey] = &[
|
||||||
|
pubkey!("ste11JV3MLMM7x7EJUM2sXcJC1H7F4jBLnP9a9PG8PH"),
|
||||||
|
pubkey!("ste11MWPjXCRfQryCshzi86SGhuXjF4Lv6xMXD2AoSt"),
|
||||||
|
pubkey!("ste11p5x8tJ53H1NbNQsRBg1YNRd4GcVpxtDw8PBpmb"),
|
||||||
|
pubkey!("ste11p7e2KLYou5bwtt35H7BM6uMdo4pvioGjJXKFcN"),
|
||||||
|
pubkey!("ste11TMV68LMi1BguM4RQujtbNCZvf1sjsASpqgAvSX"),
|
||||||
|
];
|
||||||
|
|
||||||
// NewYork,
|
// NewYork,
|
||||||
// Frankfurt,
|
// Frankfurt,
|
||||||
// Amsterdam,
|
// Amsterdam,
|
||||||
@@ -217,13 +225,25 @@ pub const SWQOS_ENDPOINTS_ASTRALANE: [&str; 8] = [
|
|||||||
"http://lim.gateway.astralane.io/iris",
|
"http://lim.gateway.astralane.io/iris",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub const SWQOS_ENDPOINTS_STELLIUM: [&str; 8] = [
|
||||||
|
"http://ewr1.flashrpc.com",
|
||||||
|
"http://fra1.flashrpc.com",
|
||||||
|
"http://ams1.flashrpc.com",
|
||||||
|
"http://ewr1.flashrpc.com",
|
||||||
|
"http://tyo1.flashrpc.com",
|
||||||
|
"http://lhr1.flashrpc.com",
|
||||||
|
"http://ewr1.flashrpc.com",
|
||||||
|
"http://fra1.flashrpc.com",
|
||||||
|
];
|
||||||
|
|
||||||
pub const SWQOS_MIN_TIP_DEFAULT: f64 = 0.00001; // 其它SWQOS默认最低小费
|
pub const SWQOS_MIN_TIP_DEFAULT: f64 = 0.00001; // 其它SWQOS默认最低小费
|
||||||
pub const SWQOS_MIN_TIP_JITO: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_JITO: f64 = SWQOS_MIN_TIP_DEFAULT;
|
||||||
pub const SWQOS_MIN_TIP_NEXTBLOCK: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_NEXTBLOCK: f64 = 0.001;
|
||||||
pub const SWQOS_MIN_TIP_ZERO_SLOT: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_ZERO_SLOT: f64 = 0.001;
|
||||||
pub const SWQOS_MIN_TIP_TEMPORAL: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_TEMPORAL: f64 = 0.001;
|
||||||
pub const SWQOS_MIN_TIP_BLOXROUTE: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_BLOXROUTE: f64 = 0.001;
|
||||||
pub const SWQOS_MIN_TIP_NODE1: f64 = 0.002; // 如需更高阈值可调整
|
pub const SWQOS_MIN_TIP_NODE1: f64 = 0.002; // 如需更高阈值可调整
|
||||||
pub const SWQOS_MIN_TIP_FLASHBLOCK: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_FLASHBLOCK: f64 = 0.001;
|
||||||
pub const SWQOS_MIN_TIP_BLOCKRAZOR: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_BLOCKRAZOR: f64 = 0.001;
|
||||||
pub const SWQOS_MIN_TIP_ASTRALANE: f64 = SWQOS_MIN_TIP_DEFAULT;
|
pub const SWQOS_MIN_TIP_ASTRALANE: f64 = SWQOS_MIN_TIP_DEFAULT;
|
||||||
|
pub const SWQOS_MIN_TIP_STELLIUM: f64 = 0.001; // Stellium requires minimum 0.001 SOL tip
|
||||||
|
|||||||
+36
-19
@@ -10,6 +10,7 @@ pub mod node1;
|
|||||||
pub mod flashblock;
|
pub mod flashblock;
|
||||||
pub mod blockrazor;
|
pub mod blockrazor;
|
||||||
pub mod astralane;
|
pub mod astralane;
|
||||||
|
pub mod stellium;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -20,29 +21,31 @@ use tokio::sync::RwLock;
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::SolanaRpcClient,
|
common::SolanaRpcClient,
|
||||||
constants::swqos::{
|
constants::swqos::{
|
||||||
SWQOS_ENDPOINTS_BLOX,
|
SWQOS_ENDPOINTS_BLOX,
|
||||||
SWQOS_ENDPOINTS_JITO,
|
SWQOS_ENDPOINTS_JITO,
|
||||||
SWQOS_ENDPOINTS_NEXTBLOCK,
|
SWQOS_ENDPOINTS_NEXTBLOCK,
|
||||||
SWQOS_ENDPOINTS_TEMPORAL,
|
SWQOS_ENDPOINTS_TEMPORAL,
|
||||||
SWQOS_ENDPOINTS_ZERO_SLOT,
|
SWQOS_ENDPOINTS_ZERO_SLOT,
|
||||||
SWQOS_ENDPOINTS_NODE1,
|
SWQOS_ENDPOINTS_NODE1,
|
||||||
SWQOS_ENDPOINTS_FLASHBLOCK,
|
SWQOS_ENDPOINTS_FLASHBLOCK,
|
||||||
SWQOS_ENDPOINTS_BLOCKRAZOR,
|
SWQOS_ENDPOINTS_BLOCKRAZOR,
|
||||||
SWQOS_ENDPOINTS_ASTRALANE
|
SWQOS_ENDPOINTS_ASTRALANE,
|
||||||
},
|
SWQOS_ENDPOINTS_STELLIUM
|
||||||
|
},
|
||||||
swqos::{
|
swqos::{
|
||||||
bloxroute::BloxrouteClient,
|
bloxroute::BloxrouteClient,
|
||||||
jito::JitoClient,
|
jito::JitoClient,
|
||||||
nextblock::NextBlockClient,
|
nextblock::NextBlockClient,
|
||||||
solana_rpc::SolRpcClient,
|
solana_rpc::SolRpcClient,
|
||||||
temporal::TemporalClient,
|
temporal::TemporalClient,
|
||||||
zeroslot::ZeroSlotClient,
|
zeroslot::ZeroSlotClient,
|
||||||
node1::Node1Client,
|
node1::Node1Client,
|
||||||
flashblock::FlashBlockClient,
|
flashblock::FlashBlockClient,
|
||||||
blockrazor::BlockRazorClient,
|
blockrazor::BlockRazorClient,
|
||||||
astralane::AstralaneClient
|
astralane::AstralaneClient,
|
||||||
|
stellium::StelliumClient
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,6 +84,7 @@ pub enum SwqosType {
|
|||||||
FlashBlock,
|
FlashBlock,
|
||||||
BlockRazor,
|
BlockRazor,
|
||||||
Astralane,
|
Astralane,
|
||||||
|
Stellium,
|
||||||
Default,
|
Default,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +100,7 @@ impl SwqosType {
|
|||||||
Self::FlashBlock,
|
Self::FlashBlock,
|
||||||
Self::BlockRazor,
|
Self::BlockRazor,
|
||||||
Self::Astralane,
|
Self::Astralane,
|
||||||
|
Self::Stellium,
|
||||||
Self::Default,
|
Self::Default,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -144,6 +149,8 @@ pub enum SwqosConfig {
|
|||||||
BlockRazor(String, SwqosRegion, Option<String>),
|
BlockRazor(String, SwqosRegion, Option<String>),
|
||||||
/// Astralane(api_token, region, custom_url)
|
/// Astralane(api_token, region, custom_url)
|
||||||
Astralane(String, SwqosRegion, Option<String>),
|
Astralane(String, SwqosRegion, Option<String>),
|
||||||
|
/// Stellium(api_token, region, custom_url)
|
||||||
|
Stellium(String, SwqosRegion, Option<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SwqosConfig {
|
impl SwqosConfig {
|
||||||
@@ -151,7 +158,7 @@ impl SwqosConfig {
|
|||||||
if let Some(custom_url) = url {
|
if let Some(custom_url) = url {
|
||||||
return custom_url;
|
return custom_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
match swqos_type {
|
match swqos_type {
|
||||||
SwqosType::Jito => SWQOS_ENDPOINTS_JITO[region as usize].to_string(),
|
SwqosType::Jito => SWQOS_ENDPOINTS_JITO[region as usize].to_string(),
|
||||||
SwqosType::NextBlock => SWQOS_ENDPOINTS_NEXTBLOCK[region as usize].to_string(),
|
SwqosType::NextBlock => SWQOS_ENDPOINTS_NEXTBLOCK[region as usize].to_string(),
|
||||||
@@ -162,6 +169,7 @@ impl SwqosConfig {
|
|||||||
SwqosType::FlashBlock => SWQOS_ENDPOINTS_FLASHBLOCK[region as usize].to_string(),
|
SwqosType::FlashBlock => SWQOS_ENDPOINTS_FLASHBLOCK[region as usize].to_string(),
|
||||||
SwqosType::BlockRazor => SWQOS_ENDPOINTS_BLOCKRAZOR[region as usize].to_string(),
|
SwqosType::BlockRazor => SWQOS_ENDPOINTS_BLOCKRAZOR[region as usize].to_string(),
|
||||||
SwqosType::Astralane => SWQOS_ENDPOINTS_ASTRALANE[region as usize].to_string(),
|
SwqosType::Astralane => SWQOS_ENDPOINTS_ASTRALANE[region as usize].to_string(),
|
||||||
|
SwqosType::Stellium => SWQOS_ENDPOINTS_STELLIUM[region as usize].to_string(),
|
||||||
SwqosType::Default => "".to_string(),
|
SwqosType::Default => "".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,11 +257,20 @@ impl SwqosConfig {
|
|||||||
);
|
);
|
||||||
Arc::new(astralane_client)
|
Arc::new(astralane_client)
|
||||||
},
|
},
|
||||||
|
SwqosConfig::Stellium(auth_token, region, url) => {
|
||||||
|
let endpoint = SwqosConfig::get_endpoint(SwqosType::Stellium, region, url);
|
||||||
|
let stellium_client = StelliumClient::new(
|
||||||
|
rpc_url.clone(),
|
||||||
|
endpoint.to_string(),
|
||||||
|
auth_token
|
||||||
|
);
|
||||||
|
Arc::new(stellium_client)
|
||||||
|
},
|
||||||
SwqosConfig::Default(endpoint) => {
|
SwqosConfig::Default(endpoint) => {
|
||||||
let rpc = SolanaRpcClient::new_with_commitment(
|
let rpc = SolanaRpcClient::new_with_commitment(
|
||||||
endpoint,
|
endpoint,
|
||||||
commitment
|
commitment
|
||||||
);
|
);
|
||||||
let rpc_client = SolRpcClient::new(Arc::new(rpc));
|
let rpc_client = SolRpcClient::new(Arc::new(rpc));
|
||||||
Arc::new(rpc_client)
|
Arc::new(rpc_client)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,190 @@
|
|||||||
|
use crate::swqos::common::{poll_transaction_confirmation, serialize_transaction_and_encode};
|
||||||
|
use rand::seq::IndexedRandom;
|
||||||
|
use reqwest::Client;
|
||||||
|
use serde_json::json;
|
||||||
|
use std::{sync::Arc, time::Instant};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
use solana_transaction_status::UiTransactionEncoding;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use solana_sdk::transaction::VersionedTransaction;
|
||||||
|
use crate::swqos::{SwqosType, TradeType};
|
||||||
|
use crate::swqos::SwqosClientTrait;
|
||||||
|
|
||||||
|
use crate::{common::SolanaRpcClient, constants::swqos::STELLIUM_TIP_ACCOUNTS};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct StelliumClient {
|
||||||
|
pub endpoint: String,
|
||||||
|
pub auth_token: String,
|
||||||
|
pub rpc_client: Arc<SolanaRpcClient>,
|
||||||
|
pub http_client: Client,
|
||||||
|
keep_alive_running: Arc<AtomicBool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl SwqosClientTrait for StelliumClient {
|
||||||
|
async fn send_transaction(&self, trade_type: TradeType, transaction: &VersionedTransaction) -> Result<()> {
|
||||||
|
self.send_transaction(trade_type, transaction).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_transactions(&self, trade_type: TradeType, transactions: &Vec<VersionedTransaction>) -> Result<()> {
|
||||||
|
self.send_transactions(trade_type, transactions).await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_tip_account(&self) -> Result<String> {
|
||||||
|
let tip_account = *STELLIUM_TIP_ACCOUNTS.choose(&mut rand::rng()).or_else(|| STELLIUM_TIP_ACCOUNTS.first()).unwrap();
|
||||||
|
Ok(tip_account.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_swqos_type(&self) -> SwqosType {
|
||||||
|
SwqosType::Stellium
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StelliumClient {
|
||||||
|
pub fn new(rpc_url: String, endpoint: String, auth_token: String) -> Self {
|
||||||
|
let rpc_client = SolanaRpcClient::new(rpc_url);
|
||||||
|
let http_client = Client::builder()
|
||||||
|
// Optimized connection pool settings for high performance
|
||||||
|
.pool_idle_timeout(Duration::from_secs(120))
|
||||||
|
.pool_max_idle_per_host(256) // Increased from 64 to 256
|
||||||
|
.tcp_keepalive(Some(Duration::from_secs(60))) // Reduced from 1200 to 60
|
||||||
|
.tcp_nodelay(true) // Disable Nagle's algorithm for lower latency
|
||||||
|
.http2_keep_alive_interval(Duration::from_secs(10))
|
||||||
|
.http2_keep_alive_timeout(Duration::from_secs(5))
|
||||||
|
.http2_adaptive_window(true) // Enable adaptive flow control
|
||||||
|
.timeout(Duration::from_millis(3000)) // Reduced from 10s to 3s
|
||||||
|
.connect_timeout(Duration::from_millis(2000)) // Reduced from 5s to 2s
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let keep_alive_running = Arc::new(AtomicBool::new(true));
|
||||||
|
|
||||||
|
let client = Self {
|
||||||
|
rpc_client: Arc::new(rpc_client),
|
||||||
|
endpoint: endpoint.clone(),
|
||||||
|
auth_token: auth_token.clone(),
|
||||||
|
http_client: http_client.clone(),
|
||||||
|
keep_alive_running: keep_alive_running.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start ping task
|
||||||
|
let client_clone = client.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
client_clone.start_ping_task().await;
|
||||||
|
});
|
||||||
|
|
||||||
|
client
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start periodic ping task to keep connections active
|
||||||
|
async fn start_ping_task(&self) {
|
||||||
|
let endpoint = self.endpoint.clone();
|
||||||
|
let auth_token = self.auth_token.clone();
|
||||||
|
let http_client = self.http_client.clone();
|
||||||
|
let stop_ping = self.keep_alive_running.clone();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut interval = tokio::time::interval(Duration::from_secs(60)); // Ping every 60 seconds
|
||||||
|
|
||||||
|
loop {
|
||||||
|
interval.tick().await;
|
||||||
|
|
||||||
|
if stop_ping.load(Ordering::Relaxed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send ping request
|
||||||
|
let url = format!("{}/{}", endpoint, auth_token);
|
||||||
|
match http_client.get(&url).send().await {
|
||||||
|
Ok(response) => {
|
||||||
|
if !response.status().is_success() {
|
||||||
|
eprintln!(" [Stellium] Ping failed with status: {}", response.status());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!(" [Stellium] Ping request error: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transaction(&self, trade_type: TradeType, transaction: &VersionedTransaction) -> Result<()> {
|
||||||
|
let start_time = Instant::now();
|
||||||
|
let (content, signature) = serialize_transaction_and_encode(transaction, UiTransactionEncoding::Base64).await?;
|
||||||
|
|
||||||
|
// Stellium uses standard Solana sendTransaction format
|
||||||
|
let request_body = serde_json::to_string(&json!({
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"method": "sendTransaction",
|
||||||
|
"params": [
|
||||||
|
content,
|
||||||
|
{ "encoding": "base64" }
|
||||||
|
]
|
||||||
|
}))?;
|
||||||
|
|
||||||
|
// Build the URL with the API key
|
||||||
|
let url = format!("{}/{}", self.endpoint, self.auth_token);
|
||||||
|
|
||||||
|
// Send request to Stellium
|
||||||
|
let response_text = self.http_client.post(&url)
|
||||||
|
.body(request_body)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("Connection", "keep-alive")
|
||||||
|
.header("Keep-Alive", "timeout=30, max=1000")
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.text()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Parse response
|
||||||
|
if let Ok(response_json) = serde_json::from_str::<serde_json::Value>(&response_text) {
|
||||||
|
if response_json.get("result").is_some() {
|
||||||
|
println!(" [Stellium] {} submitted: {:?}", trade_type, start_time.elapsed());
|
||||||
|
} else if let Some(_error) = response_json.get("error") {
|
||||||
|
eprintln!(" [Stellium] {} submission failed: {:?}", trade_type, _error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!(" [Stellium] {} submission failed: {:?}", trade_type, response_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
let start_time: Instant = Instant::now();
|
||||||
|
match poll_transaction_confirmation(&self.rpc_client, signature).await {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
println!(" signature: {:?}", signature);
|
||||||
|
println!(" [Stellium] {} confirmation failed: {:?}", trade_type, start_time.elapsed());
|
||||||
|
return Err(e);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
println!(" signature: {:?}", signature);
|
||||||
|
println!(" [Stellium] {} confirmed: {:?}", trade_type, start_time.elapsed());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transactions(&self, trade_type: TradeType, transactions: &Vec<VersionedTransaction>) -> Result<()> {
|
||||||
|
for transaction in transactions {
|
||||||
|
self.send_transaction(trade_type, transaction).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop the ping task
|
||||||
|
pub fn stop_ping_task(&self) {
|
||||||
|
self.keep_alive_running.store(false, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for StelliumClient {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Stop ping task when client is dropped
|
||||||
|
self.keep_alive_running.store(false, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ use crate::{
|
|||||||
SWQOS_MIN_TIP_FLASHBLOCK,
|
SWQOS_MIN_TIP_FLASHBLOCK,
|
||||||
SWQOS_MIN_TIP_BLOCKRAZOR,
|
SWQOS_MIN_TIP_BLOCKRAZOR,
|
||||||
SWQOS_MIN_TIP_ASTRALANE,
|
SWQOS_MIN_TIP_ASTRALANE,
|
||||||
|
SWQOS_MIN_TIP_STELLIUM,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,8 +168,15 @@ pub async fn execute_parallel(
|
|||||||
SwqosType::FlashBlock => SWQOS_MIN_TIP_FLASHBLOCK,
|
SwqosType::FlashBlock => SWQOS_MIN_TIP_FLASHBLOCK,
|
||||||
SwqosType::BlockRazor => SWQOS_MIN_TIP_BLOCKRAZOR,
|
SwqosType::BlockRazor => SWQOS_MIN_TIP_BLOCKRAZOR,
|
||||||
SwqosType::Astralane => SWQOS_MIN_TIP_ASTRALANE,
|
SwqosType::Astralane => SWQOS_MIN_TIP_ASTRALANE,
|
||||||
|
SwqosType::Stellium => SWQOS_MIN_TIP_STELLIUM,
|
||||||
SwqosType::Default => SWQOS_MIN_TIP_DEFAULT,
|
SwqosType::Default => SWQOS_MIN_TIP_DEFAULT,
|
||||||
};
|
};
|
||||||
|
if config.2.tip < min_tip {
|
||||||
|
println!(
|
||||||
|
"⚠️ Config filtered: {:?} tip {} is below minimum required tip {}",
|
||||||
|
config.0, config.2.tip, min_tip
|
||||||
|
);
|
||||||
|
}
|
||||||
config.2.tip >= min_tip
|
config.2.tip >= min_tip
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|||||||
Reference in New Issue
Block a user