refactor: unify transaction building and execution architecture

- Remove redundant transaction builder functions and merge into single build_transaction()
- Simplify compute budget manager with unified add_compute_budget_instructions()
- Consolidate trade executor interface by removing separate buy/sell methods
- Unify BuyParams/SellParams usage, remove *WithTipParams structs
- Streamline parallel execution logic and remove TradeType parameter
- Delete obsolete files: address_lookup.rs, tip_cache.rs
- Clean up nonce manager by removing unused is_using_nonce() function

This refactoring reduces code duplication and provides a cleaner, more maintainable API
for transaction building and execution across all trading protocols.
This commit is contained in:
ysq
2025-09-07 17:22:58 +08:00
parent 6e04458659
commit 90fcd5ca01
15 changed files with 176 additions and 1069 deletions
+19 -64
View File
@@ -2,72 +2,27 @@ use solana_sdk::{compute_budget::ComputeBudgetInstruction, instruction::Instruct
use crate::common::PriorityFee;
/// 为RPC交易添加计算预算指令
pub fn add_rpc_compute_budget_instructions(
instructions: &mut Vec<Instruction>,
priority_fee: &PriorityFee,
data_size_limit: u32,
) {
instructions
.push(ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(data_size_limit));
instructions.push(ComputeBudgetInstruction::set_compute_unit_price(
priority_fee.rpc_unit_price,
));
instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(
priority_fee.rpc_unit_limit,
));
}
/// 为带小费的交易添加计算预算指令
pub fn add_tip_compute_budget_instructions(
instructions: &mut Vec<Instruction>,
priority_fee: &PriorityFee,
data_size_limit: u32,
) {
instructions
.push(ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(data_size_limit));
instructions.push(ComputeBudgetInstruction::set_compute_unit_price(
priority_fee.tip_unit_price,
));
instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(
priority_fee.tip_unit_limit,
));
}
/// 通用的计算预算指令添加函数
/// 为交易添加计算预算指令
pub fn add_compute_budget_instructions(
instructions: &mut Vec<Instruction>,
unit_price: u64,
unit_limit: u32,
priority_fee: &PriorityFee,
data_size_limit: u32,
is_rpc: bool,
is_buy: bool,
) {
instructions
.push(ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(data_size_limit));
instructions.push(ComputeBudgetInstruction::set_compute_unit_price(unit_price));
instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(unit_limit));
}
pub fn add_sell_compute_budget_instructions(
instructions: &mut Vec<Instruction>,
priority_fee: &PriorityFee,
) {
instructions.push(ComputeBudgetInstruction::set_compute_unit_price(
priority_fee.rpc_unit_price,
));
instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(
priority_fee.rpc_unit_limit,
));
}
/// 为带小费的交易添加计算预算指令
pub fn add_sell_tip_compute_budget_instructions(
instructions: &mut Vec<Instruction>,
priority_fee: &PriorityFee,
) {
instructions.push(ComputeBudgetInstruction::set_compute_unit_price(
priority_fee.tip_unit_price,
));
instructions.push(ComputeBudgetInstruction::set_compute_unit_limit(
priority_fee.tip_unit_limit,
));
if is_buy {
instructions
.push(ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(data_size_limit));
}
if is_rpc {
instructions
.push(ComputeBudgetInstruction::set_compute_unit_price(priority_fee.rpc_unit_price));
instructions
.push(ComputeBudgetInstruction::set_compute_unit_limit(priority_fee.rpc_unit_limit));
} else {
instructions
.push(ComputeBudgetInstruction::set_compute_unit_price(priority_fee.tip_unit_price));
instructions
.push(ComputeBudgetInstruction::set_compute_unit_limit(priority_fee.tip_unit_limit));
}
}
-7
View File
@@ -47,10 +47,3 @@ pub fn get_transaction_blockhash(recent_blockhash: Hash) -> Hash {
recent_blockhash
}
}
/// Check if using nonce account
pub fn is_using_nonce() -> bool {
let nonce_cache = NonceCache::get_instance();
let nonce_info = nonce_cache.get_nonce_info();
nonce_info.nonce_account.is_some()
}
+18 -197
View File
@@ -13,21 +13,13 @@ use std::sync::Arc;
use super::{
address_lookup_manager::get_address_lookup_table_accounts,
compute_budget_manager::{
add_rpc_compute_budget_instructions, add_tip_compute_budget_instructions,
},
compute_budget_manager::add_compute_budget_instructions,
nonce_manager::{add_nonce_instruction, get_transaction_blockhash},
};
use crate::{
common::PriorityFee,
trading::{
common::{add_sell_compute_budget_instructions, add_sell_tip_compute_budget_instructions},
MiddlewareManager,
},
};
use crate::{common::PriorityFee, trading::MiddlewareManager};
/// 构建标准的RPC交易
pub async fn build_rpc_transaction(
pub async fn build_transaction(
payer: Arc<Keypair>,
priority_fee: &PriorityFee,
business_instructions: Vec<Instruction>,
@@ -37,75 +29,37 @@ pub async fn build_rpc_transaction(
middleware_manager: Option<Arc<MiddlewareManager>>,
protocol_name: String,
is_buy: bool,
) -> Result<VersionedTransaction, anyhow::Error> {
let mut instructions = vec![];
// 添加nonce指令
if let Err(e) = add_nonce_instruction(&mut instructions, payer.as_ref()) {
return Err(e);
}
// 添加计算预算指令
add_rpc_compute_budget_instructions(&mut instructions, priority_fee, data_size_limit);
// 添加业务指令
instructions.extend(business_instructions);
// 获取交易使用的blockhash
let blockhash = get_transaction_blockhash(recent_blockhash);
// 获取地址查找表账户
let address_lookup_table_accounts = get_address_lookup_table_accounts(lookup_table_key).await;
// 构建交易
build_versioned_transaction(
payer,
instructions,
address_lookup_table_accounts,
blockhash,
middleware_manager,
protocol_name,
is_buy,
)
.await
}
/// 构建带小费的交易
pub async fn build_tip_transaction(
payer: Arc<Keypair>,
priority_fee: &PriorityFee,
business_instructions: Vec<Instruction>,
with_tip: bool,
tip_account: &Pubkey,
tip_amount: f64,
lookup_table_key: Option<Pubkey>,
recent_blockhash: Hash,
data_size_limit: u32,
middleware_manager: Option<Arc<MiddlewareManager>>,
protocol_name: String,
is_buy: bool,
) -> Result<VersionedTransaction, anyhow::Error> {
let mut instructions = vec![];
// 添加nonce指令
if let Err(e) = add_nonce_instruction(&mut instructions, payer.as_ref()) {
return Err(e);
if is_buy {
if let Err(e) = add_nonce_instruction(&mut instructions, payer.as_ref()) {
return Err(e);
}
}
// 添加计算预算指令
add_tip_compute_budget_instructions(&mut instructions, priority_fee, data_size_limit);
add_compute_budget_instructions(&mut instructions, priority_fee, data_size_limit, true, is_buy);
// 添加业务指令
instructions.extend(business_instructions);
// 添加小费转账指令
instructions.push(transfer(
&payer.pubkey(),
tip_account,
sol_str_to_lamports(tip_amount.to_string().as_str()).unwrap_or(0),
));
if with_tip {
instructions.push(transfer(
&payer.pubkey(),
tip_account,
sol_str_to_lamports(tip_amount.to_string().as_str()).unwrap_or(0),
));
}
// 获取交易使用的blockhash
let blockhash = get_transaction_blockhash(recent_blockhash);
let blockhash =
if is_buy { get_transaction_blockhash(recent_blockhash) } else { recent_blockhash };
// 获取地址查找表账户
let address_lookup_table_accounts = get_address_lookup_table_accounts(lookup_table_key).await;
@@ -150,136 +104,3 @@ async fn build_versioned_transaction(
Ok(transaction)
}
/// 构建带小费的交易(使用PriorityFee中的tip_fee
pub async fn build_tip_transaction_with_priority_fee(
payer: Arc<Keypair>,
priority_fee: &PriorityFee,
business_instructions: Vec<Instruction>,
tip_account: &Pubkey,
lookup_table_key: Option<Pubkey>,
recent_blockhash: Hash,
data_size_limit: u32,
middleware_manager: Option<Arc<MiddlewareManager>>,
protocol_name: String,
is_buy: bool,
) -> Result<VersionedTransaction, anyhow::Error> {
build_tip_transaction(
payer,
priority_fee,
business_instructions,
tip_account,
priority_fee.buy_tip_fee,
lookup_table_key,
recent_blockhash,
data_size_limit,
middleware_manager,
protocol_name,
is_buy,
)
.await
}
/// 构建标准的RPC交易
pub async fn build_sell_transaction(
payer: Arc<Keypair>,
priority_fee: &PriorityFee,
business_instructions: Vec<Instruction>,
lookup_table_key: Option<Pubkey>,
recent_blockhash: Hash,
middleware_manager: Option<Arc<MiddlewareManager>>,
protocol_name: String,
is_buy: bool,
) -> Result<VersionedTransaction, anyhow::Error> {
let mut instructions = vec![];
// 添加计算预算指令
add_sell_compute_budget_instructions(&mut instructions, priority_fee);
// 添加业务指令
instructions.extend(business_instructions);
// 获取地址查找表账户
let address_lookup_table_accounts = get_address_lookup_table_accounts(lookup_table_key).await;
// 构建交易
build_versioned_transaction(
payer,
instructions,
address_lookup_table_accounts,
recent_blockhash,
middleware_manager,
protocol_name,
is_buy,
)
.await
}
pub async fn build_sell_tip_transaction(
payer: Arc<Keypair>,
priority_fee: &PriorityFee,
business_instructions: Vec<Instruction>,
tip_account: &Pubkey,
tip_amount: f64,
lookup_table_key: Option<Pubkey>,
recent_blockhash: Hash,
middleware_manager: Option<Arc<MiddlewareManager>>,
protocol_name: String,
is_buy: bool,
) -> Result<VersionedTransaction, anyhow::Error> {
let mut instructions = vec![];
// 添加计算预算指令
add_sell_tip_compute_budget_instructions(&mut instructions, priority_fee);
// 添加业务指令
instructions.extend(business_instructions);
// 添加小费转账指令
instructions.push(transfer(
&payer.pubkey(),
tip_account,
sol_str_to_lamports(tip_amount.to_string().as_str()).unwrap_or(0),
));
// 获取地址查找表账户
let address_lookup_table_accounts = get_address_lookup_table_accounts(lookup_table_key).await;
// 构建交易
build_versioned_transaction(
payer,
instructions,
address_lookup_table_accounts,
recent_blockhash,
middleware_manager,
protocol_name,
is_buy,
)
.await
}
pub async fn build_sell_tip_transaction_with_priority_fee(
payer: Arc<Keypair>,
priority_fee: &PriorityFee,
business_instructions: Vec<Instruction>,
tip_account: &Pubkey,
lookup_table_key: Option<Pubkey>,
recent_blockhash: Hash,
middleware_manager: Option<Arc<MiddlewareManager>>,
protocol_name: String,
is_buy: bool,
) -> Result<VersionedTransaction, anyhow::Error> {
build_sell_tip_transaction(
payer,
priority_fee,
business_instructions,
tip_account,
priority_fee.sell_tip_fee,
lookup_table_key,
recent_blockhash,
middleware_manager,
protocol_name,
is_buy,
)
.await
}
+17 -121
View File
@@ -1,19 +1,13 @@
use anyhow::{anyhow, Result};
use anyhow::Result;
use std::sync::Arc;
use super::{
parallel::parallel_execute_with_tips,
params::{BuyParams, BuyWithTipParams, SellParams, SellWithTipParams},
params::{BuyParams, SellParams},
timer::TradeTimer,
traits::{InstructionBuilder, TradeExecutor},
};
use crate::{
swqos::TradeType,
trading::{
common::{build_rpc_transaction, build_sell_transaction},
middleware::MiddlewareManager,
},
};
use crate::{swqos::SwqosClient, trading::middleware::MiddlewareManager};
const MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT: u32 = 256 * 1024;
@@ -34,66 +28,15 @@ impl GenericTradeExecutor {
#[async_trait::async_trait]
impl TradeExecutor for GenericTradeExecutor {
async fn buy(
&self,
mut params: BuyParams,
middleware_manager: Option<Arc<MiddlewareManager>>,
) -> Result<()> {
if params.data_size_limit == 0 {
params.data_size_limit = MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT;
}
if params.rpc.is_none() {
return Err(anyhow!("RPC is not set"));
}
let rpc = params.rpc.as_ref().unwrap().clone();
let mut timer = TradeTimer::new("Building buy transaction instructions");
// Build instructions
let instructions = self.instruction_builder.build_buy_instructions(&params).await?;
let final_instructions = match middleware_manager.clone() {
Some(middleware_manager) => middleware_manager
.apply_middlewares_process_protocol_instructions(
instructions,
self.protocol_name.to_string(),
true,
)?,
None => instructions,
};
timer.stage("Building RPC transaction instructions");
// Build transaction
let transaction = build_rpc_transaction(
params.payer.clone(),
&params.priority_fee,
final_instructions,
params.lookup_table_key,
params.recent_blockhash,
params.data_size_limit,
middleware_manager,
self.protocol_name.to_string(),
true,
)
.await?;
timer.stage("RPC submission confirmation");
// Send transaction
if params.wait_transaction_confirmed {
rpc.send_and_confirm_transaction(&transaction).await?;
} else {
// Send transaction asynchronously
rpc.send_transaction(&transaction).await?;
}
timer.finish();
Ok(())
}
async fn buy_with_tip(
&self,
mut params: BuyWithTipParams,
params: BuyParams,
swqos_clients: Vec<Arc<SwqosClient>>,
middleware_manager: Option<Arc<MiddlewareManager>>,
) -> Result<()> {
if params.data_size_limit == 0 {
params.data_size_limit = MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT;
let mut data_size_limit = params.data_size_limit;
if data_size_limit == 0 {
data_size_limit = MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT;
}
let timer = TradeTimer::new("Building buy transaction instructions");
@@ -107,7 +50,7 @@ impl TradeExecutor for GenericTradeExecutor {
priority_fee: params.priority_fee.clone(),
lookup_table_key: params.lookup_table_key,
recent_blockhash: params.recent_blockhash,
data_size_limit: params.data_size_limit,
data_size_limit: data_size_limit,
wait_transaction_confirmed: params.wait_transaction_confirmed,
protocol_params: params.protocol_params.clone(),
};
@@ -128,76 +71,28 @@ impl TradeExecutor for GenericTradeExecutor {
// Execute transactions in parallel
parallel_execute_with_tips(
params.swqos_clients,
swqos_clients,
params.payer,
final_instructions,
params.priority_fee,
params.lookup_table_key,
params.recent_blockhash,
params.data_size_limit,
TradeType::Buy,
data_size_limit,
middleware_manager,
self.protocol_name.to_string(),
true,
params.wait_transaction_confirmed,
true,
)
.await?;
Ok(())
}
async fn sell(
&self,
params: SellParams,
middleware_manager: Option<Arc<MiddlewareManager>>,
) -> Result<()> {
if params.rpc.is_none() {
return Err(anyhow!("RPC is not set"));
}
let rpc = params.rpc.as_ref().unwrap().clone();
let mut timer = TradeTimer::new("Building sell transaction instructions");
// Build instructions
let instructions = self.instruction_builder.build_sell_instructions(&params).await?;
let final_instructions = match middleware_manager.clone() {
Some(middleware_manager) => middleware_manager
.apply_middlewares_process_protocol_instructions(
instructions,
self.protocol_name.to_string(),
false,
)?,
None => instructions,
};
timer.stage("Sell transaction instructions");
// Build transaction
let transaction = build_sell_transaction(
params.payer.clone(),
&params.priority_fee,
final_instructions,
params.lookup_table_key,
params.recent_blockhash,
middleware_manager,
self.protocol_name.to_string(),
false,
)
.await?;
timer.stage("Sell transaction signing");
// Send transaction
if params.wait_transaction_confirmed {
rpc.send_and_confirm_transaction(&transaction).await?;
} else {
rpc.send_transaction(&transaction).await?;
}
timer.finish();
Ok(())
}
async fn sell_with_tip(
&self,
params: SellWithTipParams,
params: SellParams,
swqos_clients: Vec<Arc<SwqosClient>>,
middleware_manager: Option<Arc<MiddlewareManager>>,
) -> Result<()> {
let timer = TradeTimer::new("Building sell transaction instructions");
@@ -214,6 +109,7 @@ impl TradeExecutor for GenericTradeExecutor {
recent_blockhash: params.recent_blockhash,
wait_transaction_confirmed: params.wait_transaction_confirmed,
protocol_params: params.protocol_params.clone(),
with_tip: params.with_tip,
};
// Build instructions
@@ -232,18 +128,18 @@ impl TradeExecutor for GenericTradeExecutor {
// Execute transactions in parallel
parallel_execute_with_tips(
params.swqos_clients,
swqos_clients,
params.payer,
final_instructions,
params.priority_fee,
params.lookup_table_key,
params.recent_blockhash,
0,
TradeType::Sell,
middleware_manager,
self.protocol_name.to_string(),
false,
params.wait_transaction_confirmed,
params.with_tip,
)
.await?;
+40 -74
View File
@@ -8,14 +8,7 @@ use tokio::task::JoinHandle;
use crate::{
common::PriorityFee,
swqos::{SwqosClient, SwqosType, TradeType},
trading::{
common::{
build_rpc_transaction, build_sell_tip_transaction_with_priority_fee,
build_sell_transaction, build_tip_transaction_with_priority_fee,
},
core::timer::TradeTimer,
MiddlewareManager,
},
trading::{common::build_transaction, core::timer::TradeTimer, MiddlewareManager},
};
/// Generic function for parallel transaction execution
@@ -27,20 +20,30 @@ pub async fn parallel_execute_with_tips(
lookup_table_key: Option<Pubkey>,
recent_blockhash: Hash,
data_size_limit: u32,
trade_type: TradeType,
middleware_manager: Option<Arc<MiddlewareManager>>,
protocol_name: String,
is_buy: bool,
wait_transaction_confirmed: bool,
with_tip: bool,
) -> Result<()> {
let cores = core_affinity::get_core_ids().unwrap();
let mut handles: Vec<JoinHandle<Result<()>>> = vec![];
if is_buy && swqos_clients.len() > priority_fee.buy_tip_fees.len() {
return Err(anyhow!("Number of tip clients exceeds the configured buy tip fees"));
}
if !is_buy && swqos_clients.len() > priority_fee.sell_tip_fees.len() {
return Err(anyhow!("Number of tip clients exceeds the configured sell tip fees"));
}
for i in 0..swqos_clients.len() {
let swqos_client = swqos_clients[i].clone();
if !with_tip && !matches!(swqos_client.get_swqos_type(), SwqosType::Default) {
continue;
}
let payer = payer.clone();
let instructions = instructions.clone();
let mut priority_fee = priority_fee.clone();
let priority_fee = priority_fee.clone();
let core_id = cores[i % cores.len()];
let middleware_manager = middleware_manager.clone();
@@ -54,77 +57,40 @@ pub async fn parallel_execute_with_tips(
swqos_client.get_swqos_type()
));
let transaction = if matches!(trade_type, TradeType::Sell)
&& swqos_client.get_swqos_type() == SwqosType::Default
{
build_sell_transaction(
payer,
&priority_fee,
instructions,
lookup_table_key,
recent_blockhash,
middleware_manager,
protocol_name,
is_buy,
)
.await?
} else if matches!(trade_type, TradeType::Sell)
&& swqos_client.get_swqos_type() != SwqosType::Default
{
let tip_account = swqos_client.get_tip_account()?;
let tip_account = Arc::new(Pubkey::from_str(&tip_account).map_err(|e| anyhow!(e))?);
build_sell_tip_transaction_with_priority_fee(
payer,
&priority_fee,
instructions,
&tip_account,
lookup_table_key,
recent_blockhash,
middleware_manager,
protocol_name,
is_buy,
)
.await?
} else if swqos_client.get_swqos_type() == SwqosType::Default {
build_rpc_transaction(
payer,
&priority_fee,
instructions,
lookup_table_key,
recent_blockhash,
data_size_limit,
middleware_manager,
protocol_name,
is_buy,
)
.await?
} else {
let tip_account = swqos_client.get_tip_account()?;
let tip_account = Arc::new(Pubkey::from_str(&tip_account).map_err(|e| anyhow!(e))?);
priority_fee.buy_tip_fee =
priority_fee.buy_tip_fees[i % priority_fee.buy_tip_fees.len()];
let tip_account = swqos_client.get_tip_account()?;
let tip_account = Arc::new(Pubkey::from_str(&tip_account).map_err(|e| anyhow!(e))?);
if priority_fee.buy_tip_fees.len() == 0 {
return Err(anyhow!("buy_tip_fees is empty"));
}
let tip_amount = priority_fee.buy_tip_fees[i];
build_tip_transaction_with_priority_fee(
payer,
&priority_fee,
instructions,
&tip_account,
lookup_table_key,
recent_blockhash,
data_size_limit,
middleware_manager,
protocol_name,
is_buy,
)
.await?
};
let transaction = build_transaction(
payer,
&priority_fee,
instructions,
lookup_table_key,
recent_blockhash,
data_size_limit,
middleware_manager,
protocol_name,
is_buy,
swqos_client.get_swqos_type() != SwqosType::Default,
&tip_account,
tip_amount,
)
.await?;
timer.stage(format!(
"Submitting transaction instructions: {:?}",
swqos_client.get_swqos_type()
));
swqos_client.send_transaction(trade_type, &transaction).await?;
swqos_client
.send_transaction(
if is_buy { TradeType::Buy } else { TradeType::Sell },
&transaction,
)
.await?;
timer.finish();
Ok::<(), anyhow::Error>(())
+3 -82
View File
@@ -15,7 +15,6 @@ use crate::constants::bonk::accounts::{
};
use crate::solana_streamer_sdk::streaming::event_parser::common::EventType;
use crate::solana_streamer_sdk::streaming::event_parser::protocols::bonk::BonkTradeEvent;
use crate::swqos::SwqosClient;
use crate::trading::bonk::common::{
get_amount_in, get_amount_in_net, get_amount_out, get_creator_associated_account,
get_platform_associated_account,
@@ -25,9 +24,7 @@ use crate::trading::pumpswap::common::{
coin_creator_vault_ata, coin_creator_vault_authority, get_token_balances,
};
use crate::trading::raydium_cpmm::common::get_pool_token_balances;
/// Common buy parameters
/// Contains all necessary information for executing buy transactions
/// Buy parameters
#[derive(Clone)]
pub struct BuyParams {
pub rpc: Option<Arc<SolanaRpcClient>>,
@@ -43,26 +40,7 @@ pub struct BuyParams {
pub protocol_params: Box<dyn ProtocolParams>,
}
/// Buy parameters with MEV service support
/// Extends BuyParams with MEV client configurations for transaction acceleration
#[derive(Clone)]
pub struct BuyWithTipParams {
pub rpc: Option<Arc<SolanaRpcClient>>,
pub swqos_clients: Vec<Arc<SwqosClient>>,
pub payer: Arc<Keypair>,
pub mint: Pubkey,
pub sol_amount: u64,
pub slippage_basis_points: Option<u64>,
pub priority_fee: PriorityFee,
pub lookup_table_key: Option<Pubkey>,
pub recent_blockhash: Hash,
pub data_size_limit: u32,
pub wait_transaction_confirmed: bool,
pub protocol_params: Box<dyn ProtocolParams>,
}
/// Common sell parameters
/// Contains all necessary information for executing sell transactions
/// Sell parameters
#[derive(Clone)]
pub struct SellParams {
pub rpc: Option<Arc<SolanaRpcClient>>,
@@ -74,23 +52,7 @@ pub struct SellParams {
pub lookup_table_key: Option<Pubkey>,
pub recent_blockhash: Hash,
pub wait_transaction_confirmed: bool,
pub protocol_params: Box<dyn ProtocolParams>,
}
/// Sell parameters with MEV service support
/// Extends SellParams with MEV client configurations for transaction acceleration
#[derive(Clone)]
pub struct SellWithTipParams {
pub rpc: Option<Arc<SolanaRpcClient>>,
pub swqos_clients: Vec<Arc<SwqosClient>>,
pub payer: Arc<Keypair>,
pub mint: Pubkey,
pub token_amount: Option<u64>,
pub slippage_basis_points: Option<u64>,
pub priority_fee: PriorityFee,
pub lookup_table_key: Option<Pubkey>,
pub recent_blockhash: Hash,
pub wait_transaction_confirmed: bool,
pub with_tip: bool,
pub protocol_params: Box<dyn ProtocolParams>,
}
@@ -532,44 +494,3 @@ impl ProtocolParams for RaydiumAmmV4Params {
Box::new(self.clone())
}
}
impl BuyParams {
/// Convert to BuyWithTipParams
/// Transforms basic buy parameters into MEV-enabled parameters
pub fn with_tip(self, swqos_clients: Vec<Arc<SwqosClient>>) -> BuyWithTipParams {
BuyWithTipParams {
rpc: self.rpc,
swqos_clients,
payer: self.payer,
mint: self.mint,
sol_amount: self.sol_amount,
slippage_basis_points: self.slippage_basis_points,
priority_fee: self.priority_fee,
lookup_table_key: self.lookup_table_key,
recent_blockhash: self.recent_blockhash,
data_size_limit: self.data_size_limit,
wait_transaction_confirmed: self.wait_transaction_confirmed,
protocol_params: self.protocol_params,
}
}
}
impl SellParams {
/// Convert to SellWithTipParams
/// Transforms basic sell parameters into MEV-enabled parameters
pub fn with_tip(self, swqos_clients: Vec<Arc<SwqosClient>>) -> SellWithTipParams {
SellWithTipParams {
rpc: self.rpc,
swqos_clients,
payer: self.payer,
mint: self.mint,
token_amount: self.token_amount,
slippage_basis_points: self.slippage_basis_points,
priority_fee: self.priority_fee,
lookup_table_key: self.lookup_table_key,
recent_blockhash: self.recent_blockhash,
wait_transaction_confirmed: self.wait_transaction_confirmed,
protocol_params: self.protocol_params,
}
}
}
+14 -12
View File
@@ -1,26 +1,28 @@
use std::sync::Arc;
use crate::{swqos::SwqosClient, trading::MiddlewareManager};
use anyhow::Result;
use solana_sdk::instruction::Instruction;
use crate::trading::MiddlewareManager;
use super::params::{BuyParams, BuyWithTipParams, SellParams, SellWithTipParams};
use super::params::{BuyParams, SellParams};
/// 交易执行器trait - 定义了所有交易协议都需要实现的核心方法
#[async_trait::async_trait]
pub trait TradeExecutor: Send + Sync {
/// 执行买入交易
async fn buy(&self, params: BuyParams, middleware_manager: Option<Arc<MiddlewareManager>>) -> Result<()>;
/// 使用MEV服务执行买入交易
async fn buy_with_tip(&self, params: BuyWithTipParams, middleware_manager: Option<Arc<MiddlewareManager>>) -> Result<()>;
/// 执行卖出交易
async fn sell(&self, params: SellParams, middleware_manager: Option<Arc<MiddlewareManager>>) -> Result<()>;
async fn buy_with_tip(
&self,
params: BuyParams,
swqos_clients: Vec<Arc<SwqosClient>>,
middleware_manager: Option<Arc<MiddlewareManager>>,
) -> Result<()>;
/// 使用MEV服务执行卖出交易
async fn sell_with_tip(&self, params: SellWithTipParams, middleware_manager: Option<Arc<MiddlewareManager>>) -> Result<()>;
async fn sell_with_tip(
&self,
params: SellParams,
swqos_clients: Vec<Arc<SwqosClient>>,
middleware_manager: Option<Arc<MiddlewareManager>>,
) -> Result<()>;
/// 获取协议名称
fn protocol_name(&self) -> &'static str;
}
+1 -1
View File
@@ -8,7 +8,7 @@ pub mod pumpswap;
pub mod raydium_amm_v4;
pub mod raydium_cpmm;
pub use core::params::{BuyParams, BuyWithTipParams, SellParams, SellWithTipParams};
pub use core::params::{BuyParams, SellParams};
pub use core::traits::{InstructionBuilder, TradeExecutor};
pub use factory::TradeFactory;
pub use middleware::{InstructionMiddleware, MiddlewareManager};