feat: Add Raydium AMM V4 support and middleware system
- Add Raydium AMM V4 trading protocol support - Implement instruction middleware system for dynamic processing - Refactor trade executors to support middleware parameters - Add fee calculation and slippage protection mechanisms - Maintain backward compatibility with optional middleware
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
use crate::trading::middleware::traits::InstructionMiddleware;
|
||||
use anyhow::Result;
|
||||
use solana_sdk::instruction::Instruction;
|
||||
|
||||
/// Logging middleware - Records instruction information
|
||||
#[derive(Clone)]
|
||||
pub struct LoggingMiddleware;
|
||||
|
||||
impl InstructionMiddleware for LoggingMiddleware {
|
||||
fn name(&self) -> &'static str {
|
||||
"LoggingMiddleware"
|
||||
}
|
||||
|
||||
fn process_protocol_instructions(
|
||||
&self,
|
||||
protocol_instructions: Vec<Instruction>,
|
||||
protocol_name: String,
|
||||
is_buy: bool,
|
||||
) -> Result<Vec<Instruction>> {
|
||||
println!("-------------------[{}]-------------------", self.name());
|
||||
println!("process_protocol_instructions");
|
||||
println!("[{}] Instruction count: {}", self.name(), protocol_instructions.len());
|
||||
println!("[{}] Protocol name: {}\n", self.name(), protocol_name);
|
||||
println!("[{}] Is buy: {}", self.name(), is_buy);
|
||||
for (i, instruction) in protocol_instructions.iter().enumerate() {
|
||||
println!("Instruction {}:", i + 1);
|
||||
println!("{:?}\n", instruction);
|
||||
}
|
||||
Ok(protocol_instructions)
|
||||
}
|
||||
|
||||
fn process_full_instructions(
|
||||
&self,
|
||||
full_instructions: Vec<Instruction>,
|
||||
protocol_name: String,
|
||||
is_buy: bool,
|
||||
) -> Result<Vec<Instruction>> {
|
||||
println!("-------------------[{}]-------------------", self.name());
|
||||
println!("process_full_instructions");
|
||||
println!("[{}] Instruction count: {}", self.name(), full_instructions.len());
|
||||
println!("[{}] Protocol name: {}\n", self.name(), protocol_name);
|
||||
println!("[{}] Is buy: {}", self.name(), is_buy);
|
||||
for (i, instruction) in full_instructions.iter().enumerate() {
|
||||
println!("Instruction {}:", i + 1);
|
||||
println!("{:?}\n", instruction);
|
||||
}
|
||||
Ok(full_instructions)
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn InstructionMiddleware> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
pub mod traits;
|
||||
pub mod builtin;
|
||||
|
||||
pub use traits::{InstructionMiddleware, MiddlewareManager};
|
||||
@@ -0,0 +1,115 @@
|
||||
use anyhow::Result;
|
||||
use solana_sdk::instruction::Instruction;
|
||||
|
||||
/// Instruction middleware trait
|
||||
///
|
||||
/// Used to modify, add or remove protocol_instructions before transaction execution
|
||||
pub trait InstructionMiddleware: Send + Sync {
|
||||
/// Middleware name
|
||||
fn name(&self) -> &'static str;
|
||||
|
||||
/// Core method for processing protocol_instructions
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `protocol_instructions` - Current instruction list
|
||||
/// * `protocol_name` - Protocol name
|
||||
/// * `is_buy` - Whether the transaction is a buy transaction
|
||||
///
|
||||
/// # Returns
|
||||
/// Returns modified instruction list
|
||||
fn process_protocol_instructions(
|
||||
&self,
|
||||
protocol_instructions: Vec<Instruction>,
|
||||
protocol_name: String,
|
||||
is_buy: bool,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
|
||||
/// Core method for processing full_instructions
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `full_instructions` - Current instruction list
|
||||
/// * `protocol_name` - Protocol name
|
||||
/// * `is_buy` - Whether the transaction is a buy transaction
|
||||
///
|
||||
/// # Returns
|
||||
/// Returns modified instruction list
|
||||
fn process_full_instructions(
|
||||
&self,
|
||||
full_instructions: Vec<Instruction>,
|
||||
protocol_name: String,
|
||||
is_buy: bool,
|
||||
) -> Result<Vec<Instruction>>;
|
||||
|
||||
/// Clone middleware
|
||||
fn clone_box(&self) -> Box<dyn InstructionMiddleware>;
|
||||
}
|
||||
|
||||
/// Middleware manager
|
||||
pub struct MiddlewareManager {
|
||||
middlewares: Vec<Box<dyn InstructionMiddleware>>,
|
||||
}
|
||||
|
||||
impl Clone for MiddlewareManager {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
middlewares: self.middlewares.iter().map(|middleware| middleware.clone_box()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MiddlewareManager {
|
||||
/// Create new middleware manager
|
||||
pub fn new() -> Self {
|
||||
Self { middlewares: Vec::new() }
|
||||
}
|
||||
|
||||
/// Add middleware
|
||||
pub fn add_middleware(mut self, middleware: Box<dyn InstructionMiddleware>) -> Self {
|
||||
self.middlewares.push(middleware);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn apply_middlewares_process_full_instructions(
|
||||
&self,
|
||||
mut full_instructions: Vec<Instruction>,
|
||||
protocol_name: String,
|
||||
is_buy: bool,
|
||||
) -> Result<Vec<Instruction>> {
|
||||
for middleware in &self.middlewares {
|
||||
full_instructions = middleware.process_full_instructions(
|
||||
full_instructions,
|
||||
protocol_name.clone(),
|
||||
is_buy,
|
||||
)?;
|
||||
if full_instructions.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(full_instructions)
|
||||
}
|
||||
|
||||
/// Apply all middlewares to process protocol_instructions
|
||||
pub fn apply_middlewares_process_protocol_instructions(
|
||||
&self,
|
||||
mut protocol_instructions: Vec<Instruction>,
|
||||
protocol_name: String,
|
||||
is_buy: bool,
|
||||
) -> Result<Vec<Instruction>> {
|
||||
for middleware in &self.middlewares {
|
||||
protocol_instructions = middleware.process_protocol_instructions(
|
||||
protocol_instructions,
|
||||
protocol_name.clone(),
|
||||
is_buy,
|
||||
)?;
|
||||
if protocol_instructions.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(protocol_instructions)
|
||||
}
|
||||
|
||||
/// Create manager with common middlewares
|
||||
pub fn with_common_middlewares() -> Self {
|
||||
Self::new().add_middleware(Box::new(crate::trading::middleware::builtin::LoggingMiddleware))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user