add nextblock, 0slot support

This commit is contained in:
William
2025-04-02 13:39:59 +08:00
parent 2dc15b9020
commit ec03ed8edc
59 changed files with 5315 additions and 1855 deletions
+169 -1
View File
@@ -10,7 +10,20 @@
//! - `buy`: Instruction to buy tokens from a bonding curve by providing SOL.
//! - `sell`: Instruction to sell tokens back to the bonding curve in exchange for SOL.
use crate::{constants, trade::common::{get_bonding_curve_pda, get_global_pda, get_metadata_pda, get_mint_authority_pda}, PumpFun};
use std::sync::Arc;
use spl_associated_token_account::instruction::create_associated_token_account;
use spl_token::instruction::close_account;
use crate::common::SolanaRpcClient;
use crate::constants::trade::DEFAULT_SLIPPAGE;
use crate::ipfs::TokenMetadataIPFS;
use crate::pumpfun::common::{calculate_with_slippage_buy, calculate_with_slippage_sell, get_bonding_curve_account, get_buy_amount_with_slippage, get_global_account, get_initial_buy_price, get_token_balance, get_token_balance_and_ata};
use crate::{
constants,
pumpfun::common::{
get_bonding_curve_pda, get_global_pda, get_metadata_pda, get_mint_authority_pda
},
};
use spl_associated_token_account::get_associated_token_address;
use solana_sdk::{
@@ -20,6 +33,7 @@ use solana_sdk::{
signer::Signer,
};
use anyhow::{anyhow, Result};
pub struct Create {
pub _name: String,
pub _symbol: String,
@@ -205,3 +219,157 @@ pub fn sell(
],
)
}
pub async fn build_create_and_buy_instructions(
rpc: Arc<SolanaRpcClient>,
payer: Arc<Keypair>,
mint: Arc<Keypair>,
ipfs: TokenMetadataIPFS,
amount_sol: u64,
slippage_basis_points: Option<u64>,
) -> Result<Vec<Instruction>, anyhow::Error> {
if amount_sol == 0 {
return Err(anyhow!("build_create_and_buy_instructions: Amount cannot be zero"));
}
let rpc = rpc.as_ref();
let global_account = get_global_account(&rpc).await?;
let buy_amount = global_account.get_initial_buy_price(amount_sol);
let buy_amount_with_slippage =
get_buy_amount_with_slippage(amount_sol, slippage_basis_points);
let mut instructions = vec![];
instructions.push(create(
payer.as_ref(),
mint.as_ref(),
Create {
_name: ipfs.metadata.name.clone(),
_symbol: ipfs.metadata.symbol.clone(),
_uri: ipfs.metadata_uri.clone(),
},
));
let ata = get_associated_token_address(&payer.pubkey(), &mint.pubkey());
instructions.push(create_associated_token_account(
&payer.pubkey(),
&payer.pubkey(),
&mint.pubkey(),
&constants::accounts::TOKEN_PROGRAM,
));
instructions.push(buy(
payer.as_ref(),
&mint.pubkey(),
&global_account.fee_recipient,
Buy {
_amount: buy_amount,
_max_sol_cost: buy_amount_with_slippage,
},
));
Ok(instructions)
}
pub async fn build_buy_instructions(
rpc: Arc<SolanaRpcClient>,
payer: Arc<Keypair>,
mint: Arc<Pubkey>,
amount_sol: u64,
slippage_basis_points: Option<u64>,
) -> Result<Vec<Instruction>, anyhow::Error> {
if amount_sol == 0 {
return Err(anyhow!("build_buy_instructions:Amount cannot be zero"));
}
let global_account = get_global_account(&rpc).await?;
let buy_amount = match get_bonding_curve_account(&rpc, mint.as_ref()).await {
Ok(account) => {
account.get_buy_price(amount_sol).map_err(|e| anyhow!(e))?
},
Err(_e) => {
let initial_buy_amount = get_initial_buy_price(&global_account, amount_sol).await?;
initial_buy_amount * 80 / 100
}
};
let buy_amount_with_slippage = calculate_with_slippage_buy(amount_sol, slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE));
let mut instructions = vec![];
// let ata = get_associated_token_address(&payer.pubkey(), &mint);
// match rpc.get_account(&ata).await {
// Ok(_) => {},
// Err(_) => {
// instructions.push(create_associated_token_account(
// &payer.pubkey(),
// &payer.pubkey(),
// &mint,
// &constants::accounts::TOKEN_PROGRAM,
// ));
// }
// }
instructions.push(create_associated_token_account(
&payer.pubkey(),
&payer.pubkey(),
&mint,
&constants::accounts::TOKEN_PROGRAM,
));
instructions.push(buy(
payer.as_ref(),
&mint,
&global_account.fee_recipient,
Buy {
_amount: buy_amount,
_max_sol_cost: buy_amount_with_slippage,
},
));
Ok(instructions)
}
pub async fn build_sell_instructions(
rpc: Arc<SolanaRpcClient>,
payer: Arc<Keypair>,
mint: Arc<Pubkey>,
amount_token: u64,
slippage_basis_points: Option<u64>,
) -> Result<Vec<Instruction>, anyhow::Error> {
if amount_token == 0 {
return Err(anyhow!("build_sell_instructions: Amount cannot be zero"));
}
let ata = get_associated_token_address(&payer.pubkey(), mint.as_ref());
let global_account = get_global_account(&rpc).await?;
let bonding_curve_account = get_bonding_curve_account(&rpc, mint.as_ref()).await?;
let min_sol_output = bonding_curve_account
.get_sell_price(amount_token, global_account.fee_basis_points)
.map_err(|e| anyhow!(e))?;
let min_sol_output_with_slippage = calculate_with_slippage_sell(
min_sol_output,
slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE),
);
let mut instructions = vec![];
instructions.push(sell(
payer.as_ref(),
&mint,
&global_account.fee_recipient,
Sell {
_amount: amount_token,
_min_sol_output: min_sol_output_with_slippage,
},
));
instructions.push(close_account(
&spl_token::ID,
&ata,
&payer.pubkey(),
&payer.pubkey(),
&[&payer.pubkey()],
)?);
Ok(instructions)
}