refactor: Major SDK architecture refactoring and API consolidation
- Consolidate separate buy/sell modules into unified trading interface - Remove protocol-specific buy/sell files (bonk, pumpfun, pumpswap) - Add new trading constants and utility functions - Simplify API with unified buy/sell methods supporting multiple protocols - Enhance documentation with comprehensive examples and usage guides - Add balance checking and token account management utilities - Improve code organization and maintainability
This commit is contained in:
@@ -1,107 +0,0 @@
|
||||
use solana_hash::Hash;
|
||||
use solana_sdk::{pubkey::Pubkey, signature::Keypair};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::swqos::SwqosClient;
|
||||
use crate::trading::{
|
||||
core::params::{PumpSwapParams, BonkParams},
|
||||
factory::Protocol,
|
||||
BuyParams, TradeFactory,
|
||||
};
|
||||
use crate::{common::PriorityFee, SolanaRpcClient};
|
||||
|
||||
// Constants for compute budget
|
||||
// Increased from 64KB to 256KB to handle larger transactions
|
||||
const MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT: u32 = 256 * 1024;
|
||||
|
||||
// Buy tokens from a Pumpswap pool
|
||||
pub async fn buy(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
amount_sol: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
auto_handle_wsol: bool,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
// 创建执行器
|
||||
let executor = TradeFactory::create_executor(Protocol::Bonk);
|
||||
// 创建协议特定参数
|
||||
let protocol_params = Box::new(BonkParams {
|
||||
auto_handle_wsol: auto_handle_wsol,
|
||||
virtual_base: Some(virtual_base),
|
||||
virtual_quote: Some(virtual_quote),
|
||||
real_base_before: Some(real_base_before),
|
||||
real_quote_before: Some(real_quote_before),
|
||||
});
|
||||
// 创建买入参数
|
||||
let buy_params = BuyParams {
|
||||
rpc: Some(rpc.clone()),
|
||||
payer: payer,
|
||||
mint: mint,
|
||||
creator: Pubkey::default(),
|
||||
amount_sol: amount_sol,
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
priority_fee: priority_fee,
|
||||
lookup_table_key: lookup_table_key,
|
||||
recent_blockhash: recent_blockhash,
|
||||
data_size_limit: MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT,
|
||||
protocol_params,
|
||||
};
|
||||
// 执行买入
|
||||
executor.buy(buy_params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Buy tokens using a MEV service
|
||||
pub async fn buy_with_tip(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
swqos_clients: Vec<Arc<SwqosClient>>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
amount_sol: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
auto_handle_wsol: bool,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
// 创建执行器
|
||||
let executor = TradeFactory::create_executor(Protocol::Bonk);
|
||||
// 创建协议特定参数
|
||||
let protocol_params = Box::new(BonkParams {
|
||||
auto_handle_wsol: auto_handle_wsol,
|
||||
virtual_base: Some(virtual_base),
|
||||
virtual_quote: Some(virtual_quote),
|
||||
real_base_before: Some(real_base_before),
|
||||
real_quote_before: Some(real_quote_before),
|
||||
});
|
||||
// 创建买入参数
|
||||
let buy_params = BuyParams {
|
||||
rpc: Some(rpc.clone()),
|
||||
payer: payer,
|
||||
mint: mint,
|
||||
creator: Pubkey::default(),
|
||||
amount_sol: amount_sol,
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
priority_fee: priority_fee,
|
||||
lookup_table_key: lookup_table_key,
|
||||
recent_blockhash: recent_blockhash,
|
||||
data_size_limit: MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT,
|
||||
protocol_params,
|
||||
};
|
||||
let buy_with_tip_params = buy_params.with_tip(swqos_clients);
|
||||
// 执行买入
|
||||
executor.buy_with_tip(buy_with_tip_params).await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
use anyhow::anyhow;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use spl_associated_token_account::get_associated_token_address;
|
||||
|
||||
use crate::{common::SolanaRpcClient, constants};
|
||||
use crate::constants;
|
||||
|
||||
pub fn get_amount_out(
|
||||
amount_in: u64,
|
||||
@@ -56,20 +53,4 @@ pub fn get_vault_pda(pool_state: &Pubkey, mint: &Pubkey) -> Option<Pubkey> {
|
||||
let program_id: &Pubkey = &constants::bonk::accounts::BONK;
|
||||
let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id);
|
||||
pda.map(|pubkey| pubkey.0)
|
||||
}
|
||||
|
||||
pub async fn get_token_balance(
|
||||
rpc: &SolanaRpcClient,
|
||||
payer: &Pubkey,
|
||||
mint: &Pubkey,
|
||||
) -> Result<u64, anyhow::Error> {
|
||||
println!("payer: {:?}", payer);
|
||||
println!("mint: {:?}", mint);
|
||||
let ata = get_associated_token_address(payer, mint);
|
||||
let balance = rpc.get_token_account_balance(&ata).await?;
|
||||
let balance_u64 = balance
|
||||
.amount
|
||||
.parse::<u64>()
|
||||
.map_err(|_| anyhow!("Failed to parse token balance"))?;
|
||||
Ok(balance_u64)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,2 @@
|
||||
pub mod buy;
|
||||
pub mod sell;
|
||||
pub mod common;
|
||||
pub mod pool;
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
use anyhow::anyhow;
|
||||
use solana_hash::Hash;
|
||||
use solana_sdk::{pubkey::Pubkey, signature::Keypair};
|
||||
use solana_sdk::signature::Signer;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::common::{PriorityFee, SolanaRpcClient};
|
||||
use crate::trading::bonk::common::get_token_balance;
|
||||
use crate::swqos::SwqosClient;
|
||||
use crate::trading::{
|
||||
core::params::BonkParams, factory::Protocol, SellParams, TradeFactory,
|
||||
};
|
||||
|
||||
// Sell tokens to a Pumpswap pool
|
||||
pub async fn sell(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
amount_token: Option<u64>,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let executor = TradeFactory::create_executor(Protocol::Bonk);
|
||||
// 创建PumpFun协议参数
|
||||
let protocol_params = Box::new(BonkParams {
|
||||
virtual_base: Some(virtual_base),
|
||||
virtual_quote: Some(virtual_quote),
|
||||
real_base_before: Some(real_base_before),
|
||||
real_quote_before: Some(real_quote_before),
|
||||
auto_handle_wsol: true,
|
||||
});
|
||||
// 创建卖出参数
|
||||
let sell_params = SellParams {
|
||||
rpc: Some(rpc.clone()),
|
||||
payer: payer.clone(),
|
||||
mint,
|
||||
creator: Pubkey::default(),
|
||||
amount_token: amount_token,
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
priority_fee: priority_fee.clone(),
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params,
|
||||
};
|
||||
// 执行卖出交易
|
||||
executor.sell(sell_params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Sell tokens by percentage
|
||||
pub async fn sell_by_percent(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
percent: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
if percent == 0 || percent > 100 {
|
||||
return Err(anyhow!("Percentage must be between 1 and 100"));
|
||||
}
|
||||
let balance_u64 = get_token_balance(&rpc, &payer.pubkey(), &mint).await?;
|
||||
let amount = balance_u64 * percent / 100;
|
||||
sell(
|
||||
rpc,
|
||||
payer,
|
||||
mint,
|
||||
virtual_base,
|
||||
virtual_quote,
|
||||
real_base_before,
|
||||
real_quote_before,
|
||||
Some(amount),
|
||||
slippage_basis_points,
|
||||
priority_fee,
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Sell tokens by amount
|
||||
pub async fn sell_by_amount(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
amount: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
sell(
|
||||
rpc,
|
||||
payer,
|
||||
mint,
|
||||
virtual_base,
|
||||
virtual_quote,
|
||||
real_base_before,
|
||||
real_quote_before,
|
||||
Some(amount),
|
||||
slippage_basis_points,
|
||||
priority_fee,
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
// Sell tokens using a MEV service
|
||||
pub async fn sell_with_tip(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
swqos_clients: Vec<Arc<SwqosClient>>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
amount_token: Option<u64>,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let executor = TradeFactory::create_executor(Protocol::Bonk);
|
||||
// 创建PumpFun协议参数
|
||||
let protocol_params = Box::new(BonkParams {
|
||||
virtual_base: Some(virtual_base),
|
||||
virtual_quote: Some(virtual_quote),
|
||||
real_base_before: Some(real_base_before),
|
||||
real_quote_before: Some(real_quote_before),
|
||||
auto_handle_wsol: true,
|
||||
});
|
||||
// 创建卖出参数
|
||||
let sell_params = SellParams {
|
||||
rpc: Some(rpc.clone()),
|
||||
payer: payer.clone(),
|
||||
mint,
|
||||
creator: Pubkey::default(),
|
||||
amount_token: amount_token,
|
||||
slippage_basis_points: slippage_basis_points,
|
||||
priority_fee: priority_fee.clone(),
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params,
|
||||
};
|
||||
let sell_with_tip_params = sell_params.with_tip(swqos_clients);
|
||||
// 执行卖出交易
|
||||
executor.sell_with_tip(sell_with_tip_params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Sell tokens by percentage using a MEV service
|
||||
pub async fn sell_by_percent_with_tip(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
swqos_clients: Vec<Arc<SwqosClient>>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
percent: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
if percent == 0 || percent > 100 {
|
||||
return Err(anyhow!("Percentage must be between 1 and 100"));
|
||||
}
|
||||
|
||||
let balance_u64 = get_token_balance(&rpc, &payer.pubkey(), &mint).await?;
|
||||
let amount = balance_u64 * percent / 100;
|
||||
sell_with_tip(
|
||||
rpc,
|
||||
swqos_clients,
|
||||
payer,
|
||||
mint,
|
||||
virtual_base,
|
||||
virtual_quote,
|
||||
real_base_before,
|
||||
real_quote_before,
|
||||
Some(amount),
|
||||
slippage_basis_points,
|
||||
priority_fee,
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
// Sell tokens by amount using a MEV service
|
||||
pub async fn sell_by_amount_with_tip(
|
||||
rpc: Arc<SolanaRpcClient>,
|
||||
swqos_clients: Vec<Arc<SwqosClient>>,
|
||||
payer: Arc<Keypair>,
|
||||
mint: Pubkey,
|
||||
virtual_base: u128,
|
||||
virtual_quote: u128,
|
||||
real_base_before: u128,
|
||||
real_quote_before: u128,
|
||||
amount: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: PriorityFee,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
recent_blockhash: Hash,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
sell_with_tip(
|
||||
rpc,
|
||||
swqos_clients,
|
||||
payer,
|
||||
mint,
|
||||
virtual_base,
|
||||
virtual_quote,
|
||||
real_base_before,
|
||||
real_quote_before,
|
||||
Some(amount),
|
||||
slippage_basis_points,
|
||||
priority_fee,
|
||||
lookup_table_key,
|
||||
recent_blockhash,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Reference in New Issue
Block a user