mirror of
https://github.com/0xfnzero/solana-streamer.git
synced 2026-08-22 13:28:08 +00:00
fix buy
This commit is contained in:
Regular → Executable
+149
-151
@@ -1,4 +1,4 @@
|
||||
// #![doc = include_str!("../RUSTDOC.md")]
|
||||
#![doc = include_str!("../RUSTDOC.md")]
|
||||
|
||||
pub mod accounts;
|
||||
pub mod constants;
|
||||
@@ -19,8 +19,8 @@ use anchor_client::{
|
||||
compute_budget::ComputeBudgetInstruction,
|
||||
transaction::Transaction,
|
||||
},
|
||||
Client, Cluster, Program,
|
||||
};
|
||||
use anchor_client::Cluster;
|
||||
use anchor_spl::associated_token::{
|
||||
get_associated_token_address,
|
||||
spl_associated_token_account::instruction::create_associated_token_account,
|
||||
@@ -37,77 +37,74 @@ pub use pumpfun_cpi as cpi;
|
||||
use crate::jito::JitoClient;
|
||||
use crate::error::ClientError;
|
||||
|
||||
// 常量定义
|
||||
// Constants
|
||||
const DEFAULT_SLIPPAGE: u64 = 500; // 10%
|
||||
const DEFAULT_COMPUTE_UNIT_LIMIT: u32 = 68_000;
|
||||
const DEFAULT_COMPUTE_UNIT_PRICE: u64 = 400_000;
|
||||
|
||||
/// 优先费用配置
|
||||
/// Priority fee configuration
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct PriorityFee {
|
||||
pub limit: Option<u32>,
|
||||
pub price: Option<u64>,
|
||||
}
|
||||
|
||||
/// PumpFun 客户端
|
||||
pub struct PumpFun {
|
||||
pub rpc: RpcClient,
|
||||
pub payer: Arc<Keypair>,
|
||||
pub client: Client<Arc<Keypair>>,
|
||||
pub jito_client: Option<JitoClient>,
|
||||
pub program: Program<Arc<Keypair>>,
|
||||
}
|
||||
|
||||
impl Clone for PumpFun {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
rpc: RpcClient::new_with_commitment(
|
||||
self.rpc.url().to_string(),
|
||||
self.rpc.commitment()
|
||||
),
|
||||
payer: self.payer.clone(),
|
||||
jito_client: self.jito_client.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PumpFun {
|
||||
// 创建新实例
|
||||
/// Create a new PumpFun client instance
|
||||
pub fn new(
|
||||
cluster: Cluster,
|
||||
jito_url: Option<String>,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
payer: Arc<Keypair>,
|
||||
options: Option<CommitmentConfig>,
|
||||
ws: Option<bool>,
|
||||
jito_url: Option<String>,
|
||||
) -> Self {
|
||||
let rpc = RpcClient::new(if ws.unwrap_or(false) {
|
||||
cluster.ws_url()
|
||||
} else {
|
||||
cluster.url()
|
||||
});
|
||||
let rpc = RpcClient::new_with_commitment(
|
||||
cluster.url(),
|
||||
commitment.unwrap_or(CommitmentConfig::confirmed())
|
||||
);
|
||||
|
||||
let jito_client = jito_url.map(|url| JitoClient::new(&url));
|
||||
|
||||
let client = if let Some(options) = options {
|
||||
Client::new_with_options(cluster.clone(), payer.clone(), options)
|
||||
} else {
|
||||
Client::new(cluster.clone(), payer.clone())
|
||||
};
|
||||
|
||||
let program = client.program(cpi::ID).unwrap();
|
||||
|
||||
Self {
|
||||
rpc,
|
||||
payer,
|
||||
jito_client,
|
||||
client,
|
||||
program,
|
||||
}
|
||||
}
|
||||
|
||||
// 创建代币
|
||||
/// Create a new token
|
||||
pub async fn create(
|
||||
&self,
|
||||
mint: &Keypair,
|
||||
metadata: utils::CreateTokenMetadata,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> Result<Signature, error::ClientError> {
|
||||
) -> Result<Signature, ClientError> {
|
||||
let ipfs = utils::create_token_metadata(metadata)
|
||||
.await
|
||||
.map_err(error::ClientError::UploadMetadataError)?;
|
||||
.map_err(ClientError::UploadMetadataError)?;
|
||||
|
||||
let mut request = self.program.request();
|
||||
request = self.add_priority_fee(request, priority_fee);
|
||||
let mut instructions = self.create_priority_fee_instructions(priority_fee);
|
||||
|
||||
request = request.instruction(instruction::create(
|
||||
&self.payer.clone().as_ref(),
|
||||
instructions.push(instruction::create(
|
||||
self.payer.as_ref(),
|
||||
mint,
|
||||
cpi::instruction::Create {
|
||||
_name: ipfs.metadata.name,
|
||||
@@ -116,17 +113,20 @@ impl PumpFun {
|
||||
},
|
||||
));
|
||||
|
||||
request = request.signer(&self.payer).signer(mint);
|
||||
let recent_blockhash = self.rpc.get_latest_blockhash()?;
|
||||
let transaction = Transaction::new_signed_with_payer(
|
||||
&instructions,
|
||||
Some(&self.payer.pubkey()),
|
||||
&[&self.payer.clone(), mint],
|
||||
recent_blockhash,
|
||||
);
|
||||
|
||||
let signature = request
|
||||
.send()
|
||||
.await
|
||||
.map_err(error::ClientError::AnchorClientError)?;
|
||||
let signature = self.rpc.send_and_confirm_transaction(&transaction)?;
|
||||
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
// 创建并购买代币
|
||||
/// Create and buy tokens in one transaction
|
||||
pub async fn create_and_buy(
|
||||
&self,
|
||||
mint: &Keypair,
|
||||
@@ -134,22 +134,20 @@ impl PumpFun {
|
||||
amount_sol: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> Result<Signature, error::ClientError> {
|
||||
) -> Result<Signature, ClientError> {
|
||||
let ipfs = utils::create_token_metadata(metadata)
|
||||
.await
|
||||
.map_err(error::ClientError::UploadMetadataError)?;
|
||||
.map_err(ClientError::UploadMetadataError)?;
|
||||
|
||||
let global_account = self.get_global_account()?;
|
||||
let buy_amount = global_account.get_initial_buy_price(amount_sol);
|
||||
let buy_amount_with_slippage =
|
||||
utils::calculate_with_slippage_buy(amount_sol, slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE));
|
||||
|
||||
let mut request = self.program.request();
|
||||
let mut instructions = self.create_priority_fee_instructions(priority_fee);
|
||||
|
||||
request = self.add_priority_fee(request, priority_fee);
|
||||
|
||||
request = request.instruction(instruction::create(
|
||||
&self.payer.clone().as_ref(),
|
||||
instructions.push(instruction::create(
|
||||
self.payer.as_ref(),
|
||||
mint,
|
||||
cpi::instruction::Create {
|
||||
_name: ipfs.metadata.name,
|
||||
@@ -160,7 +158,7 @@ impl PumpFun {
|
||||
|
||||
let ata = get_associated_token_address(&self.payer.pubkey(), &mint.pubkey());
|
||||
if self.rpc.get_account(&ata).is_err() {
|
||||
request = request.instruction(create_associated_token_account(
|
||||
instructions.push(create_associated_token_account(
|
||||
&self.payer.pubkey(),
|
||||
&self.payer.pubkey(),
|
||||
&mint.pubkey(),
|
||||
@@ -168,8 +166,8 @@ impl PumpFun {
|
||||
));
|
||||
}
|
||||
|
||||
request = request.instruction(instruction::buy(
|
||||
&self.payer.clone().as_ref(),
|
||||
instructions.push(instruction::buy(
|
||||
self.payer.as_ref(),
|
||||
&mint.pubkey(),
|
||||
&global_account.fee_recipient,
|
||||
cpi::instruction::Buy {
|
||||
@@ -178,39 +176,40 @@ impl PumpFun {
|
||||
},
|
||||
));
|
||||
|
||||
let signature = request
|
||||
.signer(&self.payer)
|
||||
.signer(mint)
|
||||
.send()
|
||||
.await
|
||||
.map_err(error::ClientError::AnchorClientError)?;
|
||||
let recent_blockhash = self.rpc.get_latest_blockhash()?;
|
||||
let transaction = Transaction::new_signed_with_payer(
|
||||
&instructions,
|
||||
Some(&self.payer.pubkey()),
|
||||
&[&self.payer.clone(), mint],
|
||||
recent_blockhash,
|
||||
);
|
||||
|
||||
let signature = self.rpc.send_and_confirm_transaction(&transaction)?;
|
||||
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
// 购买代币
|
||||
/// Buy tokens
|
||||
pub async fn buy(
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
amount_sol: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> Result<Signature, error::ClientError> {
|
||||
) -> Result<Signature, ClientError> {
|
||||
let global_account = self.get_global_account()?;
|
||||
let bonding_curve_account = self.get_bonding_curve_account(mint)?;
|
||||
let buy_amount = bonding_curve_account
|
||||
.get_buy_price(amount_sol)
|
||||
.map_err(error::ClientError::BondingCurveError)?;
|
||||
.map_err(ClientError::BondingCurveError)?;
|
||||
let buy_amount_with_slippage =
|
||||
utils::calculate_with_slippage_buy(amount_sol, slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE));
|
||||
|
||||
let mut request = self.program.request();
|
||||
|
||||
request = self.add_priority_fee(request, priority_fee);
|
||||
let mut instructions = self.create_priority_fee_instructions(priority_fee);
|
||||
|
||||
let ata = get_associated_token_address(&self.payer.pubkey(), mint);
|
||||
if self.rpc.get_account(&ata).is_err() {
|
||||
request = request.instruction(create_associated_token_account(
|
||||
instructions.push(create_associated_token_account(
|
||||
&self.payer.pubkey(),
|
||||
&self.payer.pubkey(),
|
||||
mint,
|
||||
@@ -218,8 +217,8 @@ impl PumpFun {
|
||||
));
|
||||
}
|
||||
|
||||
request = request.instruction(instruction::buy(
|
||||
&self.payer.clone().as_ref(),
|
||||
instructions.push(instruction::buy(
|
||||
&self.payer.clone(),
|
||||
mint,
|
||||
&global_account.fee_recipient,
|
||||
cpi::instruction::Buy {
|
||||
@@ -228,35 +227,39 @@ impl PumpFun {
|
||||
},
|
||||
));
|
||||
|
||||
let signature = request
|
||||
.signer(&self.payer)
|
||||
.send()
|
||||
.await
|
||||
.map_err(error::ClientError::AnchorClientError)?;
|
||||
let recent_blockhash = self.rpc.get_latest_blockhash()?;
|
||||
let transaction = Transaction::new_signed_with_payer(
|
||||
&instructions,
|
||||
Some(&self.payer.pubkey()),
|
||||
&[&self.payer.clone()],
|
||||
recent_blockhash,
|
||||
);
|
||||
|
||||
let signature = self.rpc.send_transaction(&transaction)?;
|
||||
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
// 使用 Jito 购买代币
|
||||
/// Buy tokens using Jito
|
||||
pub async fn buy_with_jito(
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
amount_sol: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> Result<Signature, error::ClientError> {
|
||||
) -> Result<Signature, ClientError> {
|
||||
let start_time = Instant::now();
|
||||
|
||||
let jito_client = self.jito_client.as_ref().ok_or_else(||
|
||||
ClientError::Other("Jito client not found".to_string())
|
||||
)?;
|
||||
let jito_client = self.jito_client.as_ref()
|
||||
.ok_or_else(|| ClientError::Other("Jito client not found".to_string()))?;
|
||||
|
||||
let global_account = self.get_global_account()?;
|
||||
let bonding_curve_pda = Self::get_bonding_curve_pda(mint).unwrap();
|
||||
let bonding_curve_pda = Self::get_bonding_curve_pda(mint)
|
||||
.ok_or(ClientError::BondingCurveNotFound)?;
|
||||
let bonding_curve_account = self.get_bonding_curve_account(mint)?;
|
||||
let buy_amount = bonding_curve_account
|
||||
.get_buy_price(amount_sol)
|
||||
.map_err(error::ClientError::BondingCurveError)?;
|
||||
.map_err(ClientError::BondingCurveError)?;
|
||||
let buy_amount_with_slippage =
|
||||
utils::calculate_with_slippage_buy(amount_sol, slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE));
|
||||
|
||||
@@ -277,7 +280,7 @@ impl PumpFun {
|
||||
}
|
||||
|
||||
instructions.push(instruction::buy(
|
||||
&self.payer.clone().as_ref(),
|
||||
self.payer.as_ref(),
|
||||
mint,
|
||||
&global_account.fee_recipient,
|
||||
cpi::instruction::Buy {
|
||||
@@ -310,17 +313,18 @@ impl PumpFun {
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
// 出售代币
|
||||
/// Sell tokens
|
||||
pub async fn sell(
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
amount_token: Option<u64>,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> Result<Signature, error::ClientError> {
|
||||
) -> Result<Signature, ClientError> {
|
||||
let ata = get_associated_token_address(&self.payer.pubkey(), mint);
|
||||
let balance = self.rpc.get_token_account_balance(&ata)?;
|
||||
let balance_u64 = balance.amount.parse::<u64>().unwrap();
|
||||
let balance_u64 = balance.amount.parse::<u64>()
|
||||
.map_err(|_| ClientError::Other("Failed to parse token balance".to_string()))?;
|
||||
let amount = amount_token.unwrap_or(balance_u64);
|
||||
|
||||
if amount == 0 {
|
||||
@@ -331,18 +335,16 @@ impl PumpFun {
|
||||
let bonding_curve_account = self.get_bonding_curve_account(mint)?;
|
||||
let min_sol_output = bonding_curve_account
|
||||
.get_sell_price(amount, global_account.fee_basis_points)
|
||||
.map_err(error::ClientError::BondingCurveError)?;
|
||||
.map_err(ClientError::BondingCurveError)?;
|
||||
let min_sol_output_with_slippage = utils::calculate_with_slippage_sell(
|
||||
min_sol_output,
|
||||
slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE),
|
||||
);
|
||||
|
||||
let mut request = self.program.request();
|
||||
let mut instructions = self.create_priority_fee_instructions(priority_fee);
|
||||
|
||||
request = self.add_priority_fee(request, priority_fee);
|
||||
|
||||
request = request.instruction(instruction::sell(
|
||||
&self.payer.clone().as_ref(),
|
||||
instructions.push(instruction::sell(
|
||||
self.payer.as_ref(),
|
||||
mint,
|
||||
&global_account.fee_recipient,
|
||||
cpi::instruction::Sell {
|
||||
@@ -351,26 +353,35 @@ impl PumpFun {
|
||||
},
|
||||
));
|
||||
|
||||
let signature = request
|
||||
.signer(&self.payer)
|
||||
.send()
|
||||
.await
|
||||
.map_err(error::ClientError::AnchorClientError)?;
|
||||
let recent_blockhash = self.rpc.get_latest_blockhash()?;
|
||||
let transaction = Transaction::new_signed_with_payer(
|
||||
&instructions,
|
||||
Some(&self.payer.pubkey()),
|
||||
&[&self.payer.clone()],
|
||||
recent_blockhash,
|
||||
);
|
||||
|
||||
let signature = self.rpc.send_and_confirm_transaction(&transaction)?;
|
||||
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
// 按百分比出售代币
|
||||
/// Sell tokens by percentage
|
||||
pub async fn sell_by_percent(
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
percent: u64,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> Result<Signature, error::ClientError> {
|
||||
) -> Result<Signature, ClientError> {
|
||||
if percent > 100 {
|
||||
return Err(ClientError::Other("Percentage must be between 0 and 100".to_string()));
|
||||
}
|
||||
|
||||
let ata = get_associated_token_address(&self.payer.pubkey(), mint);
|
||||
let balance = self.rpc.get_token_account_balance(&ata)?;
|
||||
let balance_u64 = balance.amount.parse::<u64>().unwrap();
|
||||
let balance_u64 = balance.amount.parse::<u64>()
|
||||
.map_err(|_| ClientError::Other("Failed to parse token balance".to_string()))?;
|
||||
|
||||
if balance_u64 == 0 {
|
||||
return Err(ClientError::Other("Balance is 0".to_string()));
|
||||
@@ -380,31 +391,36 @@ impl PumpFun {
|
||||
self.sell(mint, Some(amount), slippage_basis_points, priority_fee).await
|
||||
}
|
||||
|
||||
// 使用 Jito 出售代币
|
||||
/// Sell tokens using Jito
|
||||
pub async fn sell_with_jito(
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
amount_token: Option<u64>,
|
||||
slippage_basis_points: Option<u64>,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> Result<Signature, error::ClientError> {
|
||||
) -> Result<Signature, ClientError> {
|
||||
let start_time = Instant::now();
|
||||
|
||||
let jito_client = self.jito_client.as_ref().ok_or_else(||
|
||||
ClientError::Other("Jito client not found".to_string())
|
||||
)?;
|
||||
let jito_client = self.jito_client.as_ref()
|
||||
.ok_or_else(|| ClientError::Other("Jito client not found".to_string()))?;
|
||||
|
||||
let ata = get_associated_token_address(&self.payer.pubkey(), mint);
|
||||
let balance = self.rpc.get_token_account_balance(&ata)?;
|
||||
let balance_u64 = balance.amount.parse::<u64>().unwrap();
|
||||
let balance_u64 = balance.amount.parse::<u64>()
|
||||
.map_err(|_| ClientError::Other("Failed to parse token balance".to_string()))?;
|
||||
let amount = amount_token.unwrap_or(balance_u64);
|
||||
|
||||
if amount == 0 {
|
||||
return Err(ClientError::Other("Amount cannot be zero".to_string()));
|
||||
}
|
||||
|
||||
let global_account = self.get_global_account()?;
|
||||
let bonding_curve_pda = Self::get_bonding_curve_pda(mint).unwrap();
|
||||
let bonding_curve_pda = Self::get_bonding_curve_pda(mint)
|
||||
.ok_or(ClientError::BondingCurveNotFound)?;
|
||||
let bonding_curve_account = self.get_bonding_curve_account(mint)?;
|
||||
let min_sol_output = bonding_curve_account
|
||||
.get_sell_price(amount, global_account.fee_basis_points)
|
||||
.map_err(error::ClientError::BondingCurveError)?;
|
||||
.map_err(ClientError::BondingCurveError)?;
|
||||
let min_sol_output_with_slippage = utils::calculate_with_slippage_sell(
|
||||
min_sol_output,
|
||||
slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE),
|
||||
@@ -417,7 +433,7 @@ impl PumpFun {
|
||||
let tip_account = jito_client.get_tip_account().await?;
|
||||
|
||||
instructions.push(instruction::sell(
|
||||
&self.payer.clone().as_ref(),
|
||||
self.payer.as_ref(),
|
||||
mint,
|
||||
&global_account.fee_recipient,
|
||||
cpi::instruction::Sell {
|
||||
@@ -450,34 +466,7 @@ impl PumpFun {
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
// 辅助方法
|
||||
fn add_priority_fee<'a>(
|
||||
&self,
|
||||
request: anchor_client::RequestBuilder<'a, Arc<Keypair>>,
|
||||
priority_fee: Option<PriorityFee>,
|
||||
) -> anchor_client::RequestBuilder<'a, Arc<Keypair>> {
|
||||
let mut request = request;
|
||||
if let Some(fee) = priority_fee {
|
||||
if let Some(limit) = fee.limit {
|
||||
request = request.instruction(ComputeBudgetInstruction::set_compute_unit_limit(limit));
|
||||
}
|
||||
if let Some(price) = fee.price {
|
||||
request = request.instruction(ComputeBudgetInstruction::set_compute_unit_price(price));
|
||||
}
|
||||
}
|
||||
request
|
||||
}
|
||||
|
||||
fn get_compute_units(&self, priority_fee: Option<PriorityFee>) -> (u32, u64) {
|
||||
let unit_limit = priority_fee
|
||||
.and_then(|fee| fee.limit)
|
||||
.unwrap_or(DEFAULT_COMPUTE_UNIT_LIMIT);
|
||||
let unit_price = priority_fee
|
||||
.and_then(|fee| fee.price)
|
||||
.unwrap_or(DEFAULT_COMPUTE_UNIT_PRICE);
|
||||
(unit_limit, unit_price)
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
fn create_priority_fee_instructions(&self, priority_fee: Option<PriorityFee>) -> Vec<Instruction> {
|
||||
let mut instructions = Vec::new();
|
||||
if let Some(fee) = priority_fee {
|
||||
@@ -491,35 +480,46 @@ impl PumpFun {
|
||||
instructions
|
||||
}
|
||||
|
||||
fn get_compute_units(&self, priority_fee: Option<PriorityFee>) -> (u32, u64) {
|
||||
let unit_limit = priority_fee
|
||||
.and_then(|fee| fee.limit)
|
||||
.unwrap_or(DEFAULT_COMPUTE_UNIT_LIMIT);
|
||||
let unit_price = priority_fee
|
||||
.and_then(|fee| fee.price)
|
||||
.unwrap_or(DEFAULT_COMPUTE_UNIT_PRICE);
|
||||
(unit_limit, unit_price)
|
||||
}
|
||||
|
||||
fn calculate_priority_fee(&self, priority_fee_per_cu: u64, unit_limit: u32) -> u64 {
|
||||
let total_priority_fee_microlamports = priority_fee_per_cu as u128 * unit_limit as u128;
|
||||
(total_priority_fee_microlamports / 1_000_000) as u64
|
||||
}
|
||||
|
||||
// 公共接口方法
|
||||
// Public interface methods
|
||||
pub fn get_payer_pubkey(&self) -> Pubkey {
|
||||
self.payer.pubkey()
|
||||
}
|
||||
|
||||
pub fn get_token_balance(&self, account: &Pubkey, mint: &Pubkey) -> Result<u64, error::ClientError> {
|
||||
pub fn get_token_balance(&self, account: &Pubkey, mint: &Pubkey) -> Result<u64, ClientError> {
|
||||
let ata = get_associated_token_address(account, mint);
|
||||
let balance = self.rpc.get_token_account_balance(&ata)?;
|
||||
Ok(balance.amount.parse::<u64>().unwrap())
|
||||
balance.amount.parse::<u64>()
|
||||
.map_err(|_| ClientError::Other("Failed to parse token balance".to_string()))
|
||||
}
|
||||
|
||||
pub fn get_sol_balance(&self, account: &Pubkey) -> Result<u64, error::ClientError> {
|
||||
self.rpc.get_balance(account).map_err(error::ClientError::SolanaClientError)
|
||||
pub fn get_sol_balance(&self, account: &Pubkey) -> Result<u64, ClientError> {
|
||||
self.rpc.get_balance(account).map_err(ClientError::SolanaClientError)
|
||||
}
|
||||
|
||||
pub fn get_payer_token_balance(&self, mint: &Pubkey) -> Result<u64, error::ClientError> {
|
||||
pub fn get_payer_token_balance(&self, mint: &Pubkey) -> Result<u64, ClientError> {
|
||||
self.get_token_balance(&self.payer.pubkey(), mint)
|
||||
}
|
||||
|
||||
pub fn get_payer_sol_balance(&self) -> Result<u64, error::ClientError> {
|
||||
pub fn get_payer_sol_balance(&self) -> Result<u64, ClientError> {
|
||||
self.get_sol_balance(&self.payer.pubkey())
|
||||
}
|
||||
|
||||
// PDA 相关方法
|
||||
// PDA related methods
|
||||
pub fn get_global_pda() -> Pubkey {
|
||||
Pubkey::find_program_address(&[constants::seeds::GLOBAL_SEED], &cpi::ID).0
|
||||
}
|
||||
@@ -546,28 +546,26 @@ impl PumpFun {
|
||||
).0
|
||||
}
|
||||
|
||||
// 账户相关方法
|
||||
pub fn get_global_account(&self) -> Result<accounts::GlobalAccount, error::ClientError> {
|
||||
// Account related methods
|
||||
pub fn get_global_account(&self) -> Result<accounts::GlobalAccount, ClientError> {
|
||||
let global = Self::get_global_pda();
|
||||
let account = self.rpc.get_account(&global)
|
||||
.map_err(error::ClientError::SolanaClientError)?;
|
||||
let account = self.rpc.get_account(&global)?;
|
||||
accounts::GlobalAccount::try_from_slice(&account.data)
|
||||
.map_err(error::ClientError::BorshError)
|
||||
.map_err(ClientError::BorshError)
|
||||
}
|
||||
|
||||
pub fn get_bonding_curve_account(
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
) -> Result<accounts::BondingCurveAccount, error::ClientError> {
|
||||
) -> Result<accounts::BondingCurveAccount, ClientError> {
|
||||
let bonding_curve_pda = Self::get_bonding_curve_pda(mint)
|
||||
.ok_or(error::ClientError::BondingCurveNotFound)?;
|
||||
let account = self.rpc.get_account(&bonding_curve_pda)
|
||||
.map_err(error::ClientError::SolanaClientError)?;
|
||||
.ok_or(ClientError::BondingCurveNotFound)?;
|
||||
let account = self.rpc.get_account(&bonding_curve_pda)?;
|
||||
accounts::BondingCurveAccount::try_from_slice(&account.data)
|
||||
.map_err(error::ClientError::BorshError)
|
||||
.map_err(ClientError::BorshError)
|
||||
}
|
||||
|
||||
// 订阅相关方法
|
||||
// Subscription related methods
|
||||
pub async fn tokens_subscription<F>(
|
||||
&self,
|
||||
ws_url: &str,
|
||||
@@ -593,7 +591,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_new_client() {
|
||||
let payer = Arc::new(Keypair::new());
|
||||
let client = PumpFun::new(Cluster::Devnet, None, Arc::clone(&payer), None, None);
|
||||
let client = PumpFun::new(Cluster::Devnet, None, Arc::clone(&payer), None);
|
||||
assert_eq!(client.payer.pubkey(), payer.pubkey());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user