use crate::{constants, PumpFun};
use borsh::{BorshDeserialize, BorshSerialize};
use solana_sdk::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
signature::Keypair,
signer::Signer,
};
use spl_associated_token_account::get_associated_token_address;
#[derive(BorshSerialize, BorshDeserialize, Clone)]
pub struct Sell {
pub amount: u64,
pub min_sol_output: u64,
}
impl Sell {
pub const DISCRIMINATOR: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173];
pub fn data(&self) -> Vec<u8> {
let mut data = Vec::with_capacity(256);
data.extend_from_slice(&Self::DISCRIMINATOR);
self.serialize(&mut data).unwrap();
data
}
}
pub fn sell(
payer: &Keypair,
mint: &Pubkey,
fee_recipient: &Pubkey,
creator: &Pubkey,
args: Sell,
) -> Instruction {
let bonding_curve: Pubkey = PumpFun::get_bonding_curve_pda(mint).unwrap();
let creator_vault: Pubkey = PumpFun::get_creator_vault_pda(creator).unwrap();
Instruction::new_with_bytes(
constants::accounts::PUMPFUN,
&args.data(),
vec![
AccountMeta::new_readonly(PumpFun::get_global_pda(), false),
AccountMeta::new(*fee_recipient, false),
AccountMeta::new_readonly(*mint, false),
AccountMeta::new(bonding_curve, false),
AccountMeta::new(get_associated_token_address(&bonding_curve, mint), false),
AccountMeta::new(get_associated_token_address(&payer.pubkey(), mint), false),
AccountMeta::new(payer.pubkey(), true),
AccountMeta::new_readonly(constants::accounts::SYSTEM_PROGRAM, false),
AccountMeta::new(creator_vault, false),
AccountMeta::new_readonly(constants::accounts::TOKEN_PROGRAM, false),
AccountMeta::new_readonly(constants::accounts::EVENT_AUTHORITY, false),
AccountMeta::new_readonly(constants::accounts::PUMPFUN, false),
AccountMeta::new_readonly(constants::accounts::FEE_CONFIG, false),
AccountMeta::new_readonly(constants::accounts::FEE_CONFIG_PROGRAM, false),
],
)
}