feat: upgrade to v1.1.0 and add universal token swap functionality

- Version bump: upgrade from 1.0.2 to 1.1.0
- Add TradeSwapParams struct for universal token-to-token swapping
- Update bonk_copy_trading example to use new swap method instead of buy/sell
- Expand trading parameters documentation with TradeSwapParams details
- Fix SOL_TOKEN_ACCOUNT constant definition
- Add USD1 token support (Bonk protocol only)
- Enhance account management and optimization options for token swaps
This commit is contained in:
ysq
2025-09-22 01:09:41 +08:00
parent 4780e71c11
commit 334e685104
8 changed files with 276 additions and 22 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ pub const TOKEN_PROGRAM_2022_META: solana_sdk::instruction::AccountMeta =
is_writable: false,
};
pub const SOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const SOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111111");
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const WSOL_TOKEN_ACCOUNT_META: solana_sdk::instruction::AccountMeta =
+148
View File
@@ -9,6 +9,7 @@ use crate::common::nonce_cache::DurableNonceInfo;
use crate::common::TradeConfig;
use crate::constants::trade::trade::DEFAULT_SLIPPAGE;
use crate::constants::SOL_TOKEN_ACCOUNT;
use crate::constants::USD1_TOKEN_ACCOUNT;
use crate::constants::WSOL_TOKEN_ACCOUNT;
use crate::swqos::SwqosClient;
use crate::swqos::SwqosConfig;
@@ -60,6 +61,52 @@ impl Clone for SolanaTrade {
}
}
/// Parameters for executing swap orders across different DEX protocols
///
/// Contains all necessary configuration for swapping tokens, including
/// protocol-specific settings, account management options, and transaction preferences.
#[derive(Clone)]
pub struct TradeSwapParams {
// Trading configuration
/// The DEX protocol to use for the trade
pub dex_type: DexType,
/// Public key of the token to purchase
pub input_mint: Pubkey,
/// Public key of the token to sell
pub output_mint: Pubkey,
/// Public key of the token program to use for the input token
pub input_token_program: Pubkey,
/// Public key of the token program to use for the output token
pub output_token_program: Pubkey,
/// Amount of input token to spend (in lamports)
pub input_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: Option<Hash>,
/// Protocol-specific parameters (PumpFun, Raydium, etc.)
pub extension_params: Box<dyn ProtocolParams>,
// Extended configuration
/// 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_input_mint_ata: bool,
/// Whether to close wrapped SOL associated token account after trade
pub close_input_mint_ata: bool,
/// Whether to create token mint associated token account
pub create_output_mint_ata: bool,
/// Whether to close token mint associated token account after trade
pub close_output_mint_ata: bool,
/// Whether to enable seed-based optimization for account creation
pub open_seed_optimize: bool,
/// Durable nonce information
pub durable_nonce: Option<DurableNonceInfo>,
/// Whether to include tip for transaction priority
pub with_tip: bool,
}
/// Parameters for executing buy orders across different DEX protocols
///
/// Contains all necessary configuration for purchasing tokens, including
@@ -224,6 +271,107 @@ impl SolanaTrade {
.clone()
}
/// Execute a swap order for a specified token
///
/// # Arguments
///
/// * `params` - Swap trade parameters containing all necessary trading configuration
///
/// # Returns
///
/// Returns `Ok(Signature)` with the transaction signature if the swap order is successfully executed,
/// or an error if the transaction fails.
///
/// # Errors
///
/// This function will return an error if:
/// - 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
/// - Required accounts cannot be created or accessed
pub async fn swap(&self, params: TradeSwapParams) -> 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(params.dex_type.clone());
let protocol_params = params.extension_params;
let buy_params = SwapParams {
rpc: Some(self.rpc.clone()),
payer: self.payer.clone(),
input_mint: params.input_mint,
output_mint: params.output_mint,
input_token_program: Some(params.input_token_program),
output_token_program: Some(params.output_token_program),
input_amount: Some(params.input_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: params.wait_transaction_confirmed,
protocol_params: protocol_params.clone(),
open_seed_optimize: params.open_seed_optimize,
swqos_clients: self.swqos_clients.clone(),
middleware_manager: self.middleware_manager.clone(),
durable_nonce: params.durable_nonce,
with_tip: params.with_tip,
create_input_mint_ata: params.create_input_mint_ata,
close_input_mint_ata: params.close_input_mint_ata,
create_output_mint_ata: params.create_output_mint_ata,
close_output_mint_ata: params.close_output_mint_ata,
};
// Validate protocol params
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()
}
DexType::Bonk => protocol_params.as_any().downcast_ref::<BonkParams>().is_some(),
DexType::RaydiumCpmm => {
protocol_params.as_any().downcast_ref::<RaydiumCpmmParams>().is_some()
}
DexType::RaydiumAmmV4 => {
protocol_params.as_any().downcast_ref::<RaydiumAmmV4Params>().is_some()
}
};
if !is_valid_params {
return Err(anyhow::anyhow!("Invalid protocol params for Trade"));
}
let mut no_support_mint = false;
// 检查是否至少有一个代币是支持的基础代币(SOL、WSOL、USD1
let has_supported_base_token = params.input_mint == SOL_TOKEN_ACCOUNT
|| params.output_mint == SOL_TOKEN_ACCOUNT
|| params.input_mint == WSOL_TOKEN_ACCOUNT
|| params.output_mint == WSOL_TOKEN_ACCOUNT
|| params.input_mint == USD1_TOKEN_ACCOUNT
|| params.output_mint == USD1_TOKEN_ACCOUNT;
if !has_supported_base_token {
no_support_mint = true;
}
// USD1 代币暂支持在 Bonk 协议上交易
if (params.input_mint == USD1_TOKEN_ACCOUNT || params.output_mint == USD1_TOKEN_ACCOUNT)
&& params.dex_type != DexType::Bonk
{
no_support_mint = true;
}
if no_support_mint {
return Err(anyhow::anyhow!("Currently only supports swap trading between (SOL、WSOL、USD1) and other tokens. USD1 swap trading is currently only supported on the Bonk protocol."));
}
executor.swap(buy_params).await
}
/// Execute a buy order for a specified token
///
/// # Arguments