refactor: Refactor SDK core architecture and trading parameter system
- Refactor SolanaTrade main class structure with improved modular design - Refactor trading parameter system: BuyParams/SellParams -> InternalBuyParams/InternalSellParams - Remove deprecated PriorityFee and related utility functions - Add SwqosSettings to replace legacy SwqosConfig - Add comprehensive technical documentation: • Address Lookup Table usage guide (EN/CN) • Nonce Cache mechanism documentation (EN/CN) • Trading Parameters documentation (EN/CN) - Refactor all example code to adapt to new API interfaces - Optimize public API design and code comments - Clean up redundant utility functions and type definitions Impact: 43 files changed, 2013 insertions(+), 1735 deletions(-)
This commit is contained in:
+223
-191
@@ -5,11 +5,8 @@ pub mod protos;
|
||||
pub mod swqos;
|
||||
pub mod trading;
|
||||
pub mod utils;
|
||||
use solana_sdk::signer::Signer;
|
||||
pub use solana_streamer_sdk;
|
||||
|
||||
use crate::constants::trade::trade::DEFAULT_SLIPPAGE;
|
||||
use crate::swqos::SwqosConfig;
|
||||
use crate::swqos::settings::SwqosSettings;
|
||||
use crate::trading::core::params::BonkParams;
|
||||
use crate::trading::core::params::PumpFunParams;
|
||||
use crate::trading::core::params::PumpSwapParams;
|
||||
@@ -17,24 +14,33 @@ use crate::trading::core::params::RaydiumAmmV4Params;
|
||||
use crate::trading::core::params::RaydiumCpmmParams;
|
||||
use crate::trading::core::traits::ProtocolParams;
|
||||
use crate::trading::factory::DexType;
|
||||
use crate::trading::BuyParams;
|
||||
use crate::trading::InternalBuyParams;
|
||||
use crate::trading::InternalSellParams;
|
||||
use crate::trading::MiddlewareManager;
|
||||
use crate::trading::SellParams;
|
||||
use crate::trading::TradeFactory;
|
||||
use common::{PriorityFee, SolanaRpcClient, TradeConfig};
|
||||
use common::SolanaRpcClient;
|
||||
use parking_lot::Mutex;
|
||||
use rustls::crypto::{ring::default_provider, CryptoProvider};
|
||||
use solana_sdk::commitment_config::CommitmentConfig;
|
||||
use solana_sdk::hash::Hash;
|
||||
use solana_sdk::signer::Signer;
|
||||
use solana_sdk::{pubkey::Pubkey, signature::Keypair, signature::Signature};
|
||||
pub use solana_streamer_sdk;
|
||||
use std::sync::Arc;
|
||||
use swqos::SwqosClient;
|
||||
|
||||
/// Main trading client for Solana DeFi protocols
|
||||
///
|
||||
/// `SolanaTrade` provides a unified interface for trading across multiple Solana DEXs
|
||||
/// including PumpFun, PumpSwap, Bonk, Raydium AMM V4, and Raydium CPMM.
|
||||
/// It manages RPC connections, transaction signing, and SWQOS (Solana Web Quality of Service) settings.
|
||||
pub struct SolanaTrade {
|
||||
/// The keypair used for signing all transactions
|
||||
pub payer: Arc<Keypair>,
|
||||
/// RPC client for blockchain interactions
|
||||
pub rpc: Arc<SolanaRpcClient>,
|
||||
pub rpc_client: Vec<Arc<SwqosClient>>,
|
||||
pub swqos_clients: Vec<Arc<SwqosClient>>,
|
||||
pub priority_fee: Arc<PriorityFee>,
|
||||
/// SWQOS settings for transaction priority and routing
|
||||
pub swqos_settings: Vec<Arc<SwqosSettings>>,
|
||||
/// Optional middleware manager for custom transaction processing
|
||||
pub middleware_manager: Option<Arc<MiddlewareManager>>,
|
||||
}
|
||||
|
||||
@@ -45,17 +51,105 @@ impl Clone for SolanaTrade {
|
||||
Self {
|
||||
payer: self.payer.clone(),
|
||||
rpc: self.rpc.clone(),
|
||||
rpc_client: self.rpc_client.clone(),
|
||||
swqos_clients: self.swqos_clients.clone(),
|
||||
priority_fee: self.priority_fee.clone(),
|
||||
swqos_settings: self.swqos_settings.clone(),
|
||||
middleware_manager: self.middleware_manager.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parameters for executing buy orders across different DEX protocols
|
||||
///
|
||||
/// Contains all necessary configuration for purchasing tokens, including
|
||||
/// protocol-specific settings, account management options, and transaction preferences.
|
||||
#[derive(Clone)]
|
||||
pub struct TradeBuyParams {
|
||||
// Trading configuration
|
||||
/// The DEX protocol to use for the trade
|
||||
pub dex_type: DexType,
|
||||
/// Public key of the token to purchase
|
||||
pub mint: Pubkey,
|
||||
/// Amount of SOL to spend (in lamports)
|
||||
pub sol_amount: u64,
|
||||
/// Optional slippage tolerance in basis points (e.g., 100 = 1%)
|
||||
pub slippage_basis_points: Option<u64>,
|
||||
/// Recent blockhash for transaction validity
|
||||
pub recent_blockhash: Hash,
|
||||
/// Protocol-specific parameters (PumpFun, Raydium, etc.)
|
||||
pub extension_params: Box<dyn ProtocolParams>,
|
||||
// Extended configuration
|
||||
/// Optional custom compute unit limit for the transaction
|
||||
pub custom_cu_limit: Option<u32>,
|
||||
/// Optional address lookup table for transaction size optimization
|
||||
pub lookup_table_key: Option<Pubkey>,
|
||||
/// Whether to wait for transaction confirmation before returning
|
||||
pub wait_transaction_confirmed: bool,
|
||||
/// Whether to create wrapped SOL associated token account
|
||||
pub create_wsol_ata: bool,
|
||||
/// Whether to close wrapped SOL associated token account after trade
|
||||
pub close_wsol_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,
|
||||
}
|
||||
|
||||
/// Parameters for executing sell orders across different DEX protocols
|
||||
///
|
||||
/// Contains all necessary configuration for selling tokens, including
|
||||
/// protocol-specific settings, tip preferences, account management options, and transaction preferences.
|
||||
#[derive(Clone)]
|
||||
pub struct TradeSellParams {
|
||||
// Trading configuration
|
||||
/// The DEX protocol to use for the trade
|
||||
pub dex_type: DexType,
|
||||
/// Public key of the token to sell
|
||||
pub mint: Pubkey,
|
||||
/// Amount of tokens to sell (in smallest token units)
|
||||
pub token_amount: u64,
|
||||
/// Optional slippage tolerance in basis points (e.g., 100 = 1%)
|
||||
pub slippage_basis_points: Option<u64>,
|
||||
/// Recent blockhash for transaction validity
|
||||
pub recent_blockhash: Hash,
|
||||
/// Whether to include tip for transaction priority
|
||||
pub with_tip: bool,
|
||||
/// Protocol-specific parameters (PumpFun, Raydium, etc.)
|
||||
pub extension_params: Box<dyn ProtocolParams>,
|
||||
// Extended configuration
|
||||
/// Optional custom compute unit limit for the transaction
|
||||
pub custom_cu_limit: Option<u32>,
|
||||
/// Optional address lookup table for transaction size optimization
|
||||
pub lookup_table_key: Option<Pubkey>,
|
||||
/// Whether to wait for transaction confirmation before returning
|
||||
pub wait_transaction_confirmed: bool,
|
||||
/// Whether to create wrapped SOL associated token account
|
||||
pub create_wsol_ata: bool,
|
||||
/// Whether to close wrapped SOL associated token account after trade
|
||||
pub close_wsol_ata: bool,
|
||||
/// Whether to enable seed-based optimization for account creation
|
||||
pub open_seed_optimize: bool,
|
||||
}
|
||||
|
||||
impl SolanaTrade {
|
||||
/// Creates a new SolanaTrade instance with the specified configuration
|
||||
///
|
||||
/// This function initializes the trading system with RPC connection, SWQOS settings,
|
||||
/// and sets up necessary components for trading operations.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `payer` - The keypair used for signing transactions
|
||||
/// * `rpc_url` - Solana RPC endpoint URL
|
||||
/// * `commitment` - Transaction commitment level for RPC calls
|
||||
/// * `swqos_settings` - List of SWQOS (Solana Web Quality of Service) configurations
|
||||
///
|
||||
/// # Returns
|
||||
/// Returns a configured `SolanaTrade` instance ready for trading operations
|
||||
#[inline]
|
||||
pub async fn new(payer: Arc<Keypair>, trade_config: TradeConfig) -> Self {
|
||||
pub async fn new(
|
||||
payer: Arc<Keypair>,
|
||||
rpc_url: String,
|
||||
commitment: CommitmentConfig,
|
||||
mut swqos_settings: Vec<SwqosSettings>,
|
||||
) -> Self {
|
||||
crate::common::fast_fn::fast_init(&payer.try_pubkey().unwrap());
|
||||
|
||||
if CryptoProvider::get_default().is_none() {
|
||||
@@ -64,34 +158,22 @@ impl SolanaTrade {
|
||||
.map_err(|e| anyhow::anyhow!("Failed to install crypto provider: {:?}", e));
|
||||
}
|
||||
|
||||
let rpc_url = trade_config.rpc_url.clone();
|
||||
let swqos_configs = trade_config.swqos_configs.clone();
|
||||
let priority_fee = Arc::new(trade_config.priority_fee.clone());
|
||||
let commitment = trade_config.commitment.clone();
|
||||
let mut swqos_clients: Vec<Arc<SwqosClient>> = vec![];
|
||||
let rpc_url = rpc_url.clone();
|
||||
let commitment = commitment.clone();
|
||||
|
||||
for swqos in swqos_configs {
|
||||
let swqos_client =
|
||||
SwqosConfig::get_swqos_client(rpc_url.clone(), commitment.clone(), swqos.clone());
|
||||
swqos_clients.push(swqos_client);
|
||||
for swqos in &mut swqos_settings {
|
||||
swqos.setup_swqos_client(rpc_url.clone(), commitment.clone());
|
||||
}
|
||||
|
||||
let rpc = Arc::new(SolanaRpcClient::new_with_commitment(rpc_url.clone(), commitment));
|
||||
let rpc =
|
||||
Arc::new(SolanaRpcClient::new_with_commitment(rpc_url.clone(), commitment.clone()));
|
||||
common::seed::update_rents(&rpc).await.unwrap();
|
||||
common::seed::start_rent_updater(rpc.clone());
|
||||
|
||||
let rpc_client = SwqosConfig::get_swqos_client(
|
||||
rpc_url.clone(),
|
||||
commitment,
|
||||
SwqosConfig::Default(rpc_url),
|
||||
);
|
||||
|
||||
let instance = Self {
|
||||
payer,
|
||||
rpc,
|
||||
rpc_client: vec![rpc_client],
|
||||
swqos_clients,
|
||||
priority_fee,
|
||||
swqos_settings: swqos_settings.into_iter().map(|s| Arc::new(s)).collect(),
|
||||
middleware_manager: None,
|
||||
};
|
||||
|
||||
@@ -101,22 +183,47 @@ impl SolanaTrade {
|
||||
instance
|
||||
}
|
||||
|
||||
/// Adds a middleware manager to the SolanaTrade instance
|
||||
///
|
||||
/// Middleware managers can be used to implement custom logic that runs before or after trading operations,
|
||||
/// such as logging, monitoring, or custom validation.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `middleware_manager` - The middleware manager to attach
|
||||
///
|
||||
/// # Returns
|
||||
/// Returns the modified SolanaTrade instance with middleware manager attached
|
||||
pub fn with_middleware_manager(mut self, middleware_manager: MiddlewareManager) -> Self {
|
||||
self.middleware_manager = Some(Arc::new(middleware_manager));
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the RPC client instance
|
||||
/// Gets the RPC client instance for direct Solana blockchain interactions
|
||||
///
|
||||
/// This provides access to the underlying Solana RPC client that can be used
|
||||
/// for custom blockchain operations outside of the trading framework.
|
||||
///
|
||||
/// # Returns
|
||||
/// Returns a reference to the Arc-wrapped SolanaRpcClient instance
|
||||
pub fn get_rpc(&self) -> &Arc<SolanaRpcClient> {
|
||||
&self.rpc
|
||||
}
|
||||
|
||||
/// Get the current instance
|
||||
/// Gets the current globally shared SolanaTrade instance
|
||||
///
|
||||
/// This provides access to the singleton instance that was created with `new()`.
|
||||
/// Useful for accessing the trading instance from different parts of the application.
|
||||
///
|
||||
/// # Returns
|
||||
/// Returns the Arc-wrapped SolanaTrade instance
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if no instance has been initialized yet. Make sure to call `new()` first.
|
||||
pub fn get_instance() -> Arc<Self> {
|
||||
let instance = INSTANCE.lock();
|
||||
instance
|
||||
.as_ref()
|
||||
.expect("PumpFun instance not initialized. Please call new() first.")
|
||||
.expect("SolanaTrade instance not initialized. Please call new() first.")
|
||||
.clone()
|
||||
}
|
||||
|
||||
@@ -124,80 +231,53 @@ impl SolanaTrade {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `dex_type` - The trading protocol to use (PumpFun, PumpSwap, or Bonk)
|
||||
/// * `mint` - The public key of the token mint to buy
|
||||
/// * `sol_amount` - Amount of SOL to spend on the purchase (in lamports)
|
||||
/// * `slippage_basis_points` - Optional slippage tolerance in basis points (e.g., 100 = 1%)
|
||||
/// * `recent_blockhash` - Recent blockhash for transaction validity
|
||||
/// * `custom_priority_fee` - Optional custom priority fee for priority processing
|
||||
/// * `extension_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
/// * `lookup_table_key` - Optional address lookup table key for transaction optimization
|
||||
/// * `wait_transaction_confirmed` - Whether to wait for the transaction to be confirmed
|
||||
/// * `create_wsol_ata` - Whether to create wSOL ATA account
|
||||
/// * `close_wsol_ata` - Whether to close wSOL ATA account
|
||||
/// * `open_seed_optimize` - Whether to open seed optimize
|
||||
/// * `params` - Buy trade parameters containing all necessary trading configuration
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns `Ok(())` if the buy order is successfully executed, or an error if the transaction fails.
|
||||
/// Returns `Ok(Signature)` with the transaction signature if the buy order is successfully executed,
|
||||
/// or an error if the transaction fails.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if:
|
||||
/// - Invalid protocol parameters are provided
|
||||
/// - Invalid protocol parameters are provided for the specified DEX type
|
||||
/// - The transaction fails to execute
|
||||
/// - Network or RPC errors occur
|
||||
/// - Insufficient SOL balance for the purchase
|
||||
pub async fn buy(
|
||||
&self,
|
||||
dex_type: DexType,
|
||||
mint: Pubkey,
|
||||
sol_amount: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
recent_blockhash: Hash,
|
||||
custom_priority_fee: Option<PriorityFee>,
|
||||
extension_params: Box<dyn ProtocolParams>,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
wait_transaction_confirmed: bool,
|
||||
create_wsol_ata: bool,
|
||||
close_wsol_ata: bool,
|
||||
create_mint_ata: bool,
|
||||
open_seed_optimize: bool,
|
||||
) -> Result<Signature, anyhow::Error> {
|
||||
if slippage_basis_points.is_none() {
|
||||
/// - Required accounts cannot be created or accessed
|
||||
pub async fn buy(&self, params: TradeBuyParams) -> Result<Signature, anyhow::Error> {
|
||||
if params.slippage_basis_points.is_none() {
|
||||
println!(
|
||||
"slippage_basis_points is none, use default slippage basis points: {}",
|
||||
DEFAULT_SLIPPAGE
|
||||
);
|
||||
}
|
||||
let executor = TradeFactory::create_executor(dex_type.clone());
|
||||
let protocol_params = extension_params;
|
||||
let executor = TradeFactory::create_executor(params.dex_type.clone());
|
||||
let protocol_params = params.extension_params;
|
||||
|
||||
let mut buy_params = BuyParams {
|
||||
let buy_params = InternalBuyParams {
|
||||
rpc: Some(self.rpc.clone()),
|
||||
payer: self.payer.clone(),
|
||||
mint: mint,
|
||||
sol_amount: sol_amount,
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
priority_fee: self.priority_fee.clone(),
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
mint: params.mint,
|
||||
sol_amount: params.sol_amount,
|
||||
slippage_basis_points: params.slippage_basis_points,
|
||||
lookup_table_key: params.lookup_table_key,
|
||||
recent_blockhash: params.recent_blockhash,
|
||||
data_size_limit: 256 * 1024,
|
||||
wait_transaction_confirmed: wait_transaction_confirmed,
|
||||
wait_transaction_confirmed: params.wait_transaction_confirmed,
|
||||
protocol_params: protocol_params.clone(),
|
||||
open_seed_optimize,
|
||||
create_wsol_ata,
|
||||
close_wsol_ata,
|
||||
create_mint_ata,
|
||||
swqos_clients: self.swqos_clients.clone(),
|
||||
open_seed_optimize: params.open_seed_optimize,
|
||||
create_wsol_ata: params.create_wsol_ata,
|
||||
close_wsol_ata: params.close_wsol_ata,
|
||||
create_mint_ata: params.create_mint_ata,
|
||||
swqos_settings: self.swqos_settings.clone(),
|
||||
middleware_manager: self.middleware_manager.clone(),
|
||||
custom_cu_limit: params.custom_cu_limit,
|
||||
};
|
||||
if custom_priority_fee.is_some() {
|
||||
buy_params.priority_fee = Arc::new(custom_priority_fee.unwrap());
|
||||
}
|
||||
|
||||
// Validate protocol params
|
||||
let is_valid_params = match dex_type {
|
||||
let is_valid_params = match params.dex_type {
|
||||
DexType::PumpFun => protocol_params.as_any().downcast_ref::<PumpFunParams>().is_some(),
|
||||
DexType::PumpSwap => {
|
||||
protocol_params.as_any().downcast_ref::<PumpSwapParams>().is_some()
|
||||
@@ -222,86 +302,53 @@ impl SolanaTrade {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `dex_type` - The trading protocol to use (PumpFun, PumpSwap, or Bonk)
|
||||
/// * `mint` - The public key of the token mint to sell
|
||||
/// * `token_amount` - Amount of tokens to sell (in smallest token units)
|
||||
/// * `slippage_basis_points` - Optional slippage tolerance in basis points (e.g., 100 = 1%)
|
||||
/// * `recent_blockhash` - Recent blockhash for transaction validity
|
||||
/// * `custom_priority_fee` - Optional custom priority fee for priority processing
|
||||
/// * `with_tip` - Optional boolean to indicate if the transaction should be sent with tip
|
||||
/// * `extension_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
/// * `lookup_table_key` - Optional address lookup table key for transaction optimization
|
||||
/// * `wait_transaction_confirmed` - Whether to wait for the transaction to be confirmed
|
||||
/// * `create_wsol_ata` - Whether to create wSOL ATA account
|
||||
/// * `close_wsol_ata` - Whether to close wSOL ATA account
|
||||
/// * `open_seed_optimize` - Whether to open seed optimize
|
||||
/// * `params` - Sell trade parameters containing all necessary trading configuration
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns `Ok(())` if the sell order is successfully executed, or an error if the transaction fails.
|
||||
/// Returns `Ok(Signature)` with the transaction signature if the sell order is successfully executed,
|
||||
/// or an error if the transaction fails.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if:
|
||||
/// - Invalid protocol parameters are provided
|
||||
/// - Invalid protocol parameters are provided for the specified DEX type
|
||||
/// - The transaction fails to execute
|
||||
/// - Network or RPC errors occur
|
||||
/// - Insufficient token balance for the sale
|
||||
/// - Token account doesn't exist or is not properly initialized
|
||||
pub async fn sell(
|
||||
&self,
|
||||
dex_type: DexType,
|
||||
mint: Pubkey,
|
||||
token_amount: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
recent_blockhash: Hash,
|
||||
custom_priority_fee: Option<PriorityFee>,
|
||||
with_tip: bool,
|
||||
extension_params: Box<dyn ProtocolParams>,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
wait_transaction_confirmed: bool,
|
||||
create_wsol_ata: bool,
|
||||
close_wsol_ata: bool,
|
||||
open_seed_optimize: bool,
|
||||
) -> Result<Signature, anyhow::Error> {
|
||||
if slippage_basis_points.is_none() {
|
||||
/// - Required accounts cannot be created or accessed
|
||||
pub async fn sell(&self, params: TradeSellParams) -> Result<Signature, anyhow::Error> {
|
||||
if params.slippage_basis_points.is_none() {
|
||||
println!(
|
||||
"slippage_basis_points is none, use default slippage basis points: {}",
|
||||
DEFAULT_SLIPPAGE
|
||||
);
|
||||
}
|
||||
let executor = TradeFactory::create_executor(dex_type.clone());
|
||||
let protocol_params = extension_params;
|
||||
let executor = TradeFactory::create_executor(params.dex_type.clone());
|
||||
let protocol_params = params.extension_params;
|
||||
|
||||
let mut sell_params = SellParams {
|
||||
let sell_params = InternalSellParams {
|
||||
rpc: Some(self.rpc.clone()),
|
||||
payer: self.payer.clone(),
|
||||
mint: mint,
|
||||
token_amount: Some(token_amount),
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
priority_fee: self.priority_fee.clone(),
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
wait_transaction_confirmed: wait_transaction_confirmed,
|
||||
mint: params.mint,
|
||||
token_amount: Some(params.token_amount),
|
||||
slippage_basis_points: params.slippage_basis_points,
|
||||
lookup_table_key: params.lookup_table_key,
|
||||
recent_blockhash: params.recent_blockhash,
|
||||
wait_transaction_confirmed: params.wait_transaction_confirmed,
|
||||
protocol_params: protocol_params.clone(),
|
||||
with_tip: with_tip,
|
||||
open_seed_optimize,
|
||||
swqos_clients: if !with_tip {
|
||||
self.rpc_client.clone()
|
||||
} else {
|
||||
self.swqos_clients.clone()
|
||||
},
|
||||
with_tip: params.with_tip,
|
||||
open_seed_optimize: params.open_seed_optimize,
|
||||
swqos_settings: self.swqos_settings.clone(),
|
||||
middleware_manager: self.middleware_manager.clone(),
|
||||
create_wsol_ata,
|
||||
close_wsol_ata,
|
||||
create_wsol_ata: params.create_wsol_ata,
|
||||
close_wsol_ata: params.close_wsol_ata,
|
||||
custom_cu_limit: params.custom_cu_limit,
|
||||
};
|
||||
|
||||
if custom_priority_fee.is_some() {
|
||||
sell_params.priority_fee = Arc::new(custom_priority_fee.unwrap());
|
||||
}
|
||||
|
||||
// Validate protocol params
|
||||
let is_valid_params = match dex_type {
|
||||
let is_valid_params = match params.dex_type {
|
||||
DexType::PumpFun => protocol_params.as_any().downcast_ref::<PumpFunParams>().is_some(),
|
||||
DexType::PumpSwap => {
|
||||
protocol_params.as_any().downcast_ref::<PumpSwapParams>().is_some()
|
||||
@@ -330,82 +377,59 @@ impl SolanaTrade {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `dex_type` - The trading protocol to use (PumpFun, PumpSwap, or Bonk)
|
||||
/// * `mint` - The public key of the token mint to sell
|
||||
/// * `params` - Sell trade parameters (will be modified with calculated token amount)
|
||||
/// * `amount_token` - Total amount of tokens available (in smallest token units)
|
||||
/// * `percent` - Percentage of tokens to sell (1-100, where 100 = 100%)
|
||||
/// * `slippage_basis_points` - Optional slippage tolerance in basis points (e.g., 100 = 1%)
|
||||
/// * `recent_blockhash` - Recent blockhash for transaction validity
|
||||
/// * `custom_priority_fee` - Optional custom priority fee for priority processing
|
||||
/// * `with_tip` - Whether to use tip for priority processing
|
||||
/// * `extension_params` - Optional protocol-specific parameters (uses defaults if None)
|
||||
/// * `lookup_table_key` - Optional lookup table key for address lookup optimization
|
||||
/// * `wait_transaction_confirmed` - Whether to wait for the transaction to be confirmed
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns `Ok(())` if the sell order is successfully executed, or an error if the transaction fails.
|
||||
/// Returns `Ok(Signature)` with the transaction signature if the sell order is successfully executed,
|
||||
/// or an error if the transaction fails.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if:
|
||||
/// - `percent` is 0 or greater than 100
|
||||
/// - Invalid protocol parameters are provided
|
||||
/// - Invalid protocol parameters are provided for the specified DEX type
|
||||
/// - The transaction fails to execute
|
||||
/// - Network or RPC errors occur
|
||||
/// - Insufficient token balance for the calculated sale amount
|
||||
/// - Token account doesn't exist or is not properly initialized
|
||||
/// - Required accounts cannot be created or accessed
|
||||
pub async fn sell_by_percent(
|
||||
&self,
|
||||
dex_type: DexType,
|
||||
mint: Pubkey,
|
||||
mut params: TradeSellParams,
|
||||
amount_token: u64,
|
||||
percent: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
recent_blockhash: Hash,
|
||||
custom_priority_fee: Option<PriorityFee>,
|
||||
with_tip: bool,
|
||||
extension_params: Box<dyn ProtocolParams>,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
wait_transaction_confirmed: bool,
|
||||
create_wsol_ata: bool,
|
||||
close_wsol_ata: bool,
|
||||
open_seed_optimize: bool,
|
||||
) -> Result<Signature, anyhow::Error> {
|
||||
if percent == 0 || percent > 100 {
|
||||
return Err(anyhow::anyhow!("Percentage must be between 1 and 100"));
|
||||
}
|
||||
let amount = amount_token * percent / 100;
|
||||
self.sell(
|
||||
dex_type,
|
||||
mint,
|
||||
amount,
|
||||
slippage_basis_points,
|
||||
recent_blockhash,
|
||||
custom_priority_fee,
|
||||
with_tip,
|
||||
extension_params,
|
||||
lookup_table_key,
|
||||
wait_transaction_confirmed,
|
||||
create_wsol_ata,
|
||||
close_wsol_ata,
|
||||
open_seed_optimize,
|
||||
)
|
||||
.await
|
||||
params.token_amount = amount;
|
||||
self.sell(params).await
|
||||
}
|
||||
|
||||
/// Wraps SOL into wSOL (Wrapped SOL)
|
||||
/// Wraps native SOL into wSOL (Wrapped SOL) for use in SPL token operations
|
||||
///
|
||||
/// This function creates a wSOL associated token account (if it doesn't exist),
|
||||
/// transfers the specified amount of SOL to that account, and then syncs the native
|
||||
/// token balance to make SOL usable as an SPL token.
|
||||
/// token balance to make SOL usable as an SPL token in trading operations.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `amount`: The amount of SOL to wrap (in lamports)
|
||||
/// * `amount` - The amount of SOL to wrap (in lamports)
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok(String)`: Transaction signature
|
||||
/// - `Err(anyhow::Error)`: If the transaction fails
|
||||
/// * `Ok(String)` - Transaction signature if successful
|
||||
/// * `Err(anyhow::Error)` - If the transaction fails to execute
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if:
|
||||
/// - Insufficient SOL balance for the wrap operation
|
||||
/// - wSOL associated token account creation fails
|
||||
/// - Transaction fails to execute or confirm
|
||||
/// - Network or RPC errors occur
|
||||
pub async fn wrap_sol_to_wsol(&self, amount: u64) -> Result<String, anyhow::Error> {
|
||||
use crate::trading::common::wsol_manager::handle_wsol;
|
||||
use solana_sdk::transaction::Transaction;
|
||||
@@ -417,15 +441,23 @@ impl SolanaTrade {
|
||||
let signature = self.rpc.send_and_confirm_transaction(&transaction).await?;
|
||||
Ok(signature.to_string())
|
||||
}
|
||||
/// Closes the wSOL account and unwraps SOL back to native SOL
|
||||
/// Closes the wSOL associated token account and unwraps remaining balance to native SOL
|
||||
///
|
||||
/// This function closes the wSOL associated token account, which automatically
|
||||
/// transfers any remaining wSOL balance back to the account owner as native SOL.
|
||||
/// This is useful for cleaning up wSOL accounts and recovering wrapped SOL.
|
||||
/// This is useful for cleaning up wSOL accounts and recovering wrapped SOL after trading operations.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Ok(String)`: Transaction signature
|
||||
/// - `Err(anyhow::Error)`: If the transaction fails
|
||||
/// * `Ok(String)` - Transaction signature if successful
|
||||
/// * `Err(anyhow::Error)` - If the transaction fails to execute
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if:
|
||||
/// - wSOL associated token account doesn't exist
|
||||
/// - Account closure fails due to insufficient permissions
|
||||
/// - Transaction fails to execute or confirm
|
||||
/// - Network or RPC errors occur
|
||||
pub async fn close_wsol(&self) -> Result<String, anyhow::Error> {
|
||||
use crate::trading::common::wsol_manager::close_wsol;
|
||||
use solana_sdk::transaction::Transaction;
|
||||
|
||||
Reference in New Issue
Block a user