use crate::common::bonding_curve::BondingCurveAccount;
use crate::common::spl_associated_token_account::get_associated_token_address_with_program_id;
use crate::common::SolanaRpcClient;
use crate::instruction::utils::pumpfun::reconcile_mayhem_mode_for_trade;
use solana_sdk::pubkey::Pubkey;
use std::sync::Arc;
#[derive(Clone)]
pub struct PumpFunParams {
pub bonding_curve: Arc<BondingCurveAccount>,
pub associated_bonding_curve: Pubkey,
pub observed_trade_creator: Option<Pubkey>,
pub creator_vault: Pubkey,
pub fee_sharing_creator_vault_if_active: Option<Pubkey>,
pub token_program: Pubkey,
pub close_token_account_when_sell: Option<bool>,
pub fee_recipient: Pubkey,
pub quote_mint: Pubkey,
pub use_v2_ix: bool,
}
impl PumpFunParams {
pub fn immediate_sell(
creator_vault: Pubkey,
token_program: Pubkey,
close_token_account_when_sell: bool,
) -> Self {
Self {
bonding_curve: Arc::new(BondingCurveAccount { ..Default::default() }),
associated_bonding_curve: Pubkey::default(),
observed_trade_creator: None,
creator_vault: creator_vault,
fee_sharing_creator_vault_if_active: None,
token_program: token_program,
close_token_account_when_sell: Some(close_token_account_when_sell),
fee_recipient: Pubkey::default(),
quote_mint: Pubkey::default(),
use_v2_ix: false,
}
}
pub fn from_dev_trade(
mint: Pubkey,
token_amount: u64,
max_sol_cost: u64,
creator: Pubkey,
bonding_curve: Pubkey,
associated_bonding_curve: Pubkey,
creator_vault: Pubkey,
close_token_account_when_sell: Option<bool>,
fee_recipient: Pubkey,
token_program: Pubkey,
is_cashback_coin: bool,
mayhem_mode: Option<bool>,
) -> Self {
let is_mayhem_mode = reconcile_mayhem_mode_for_trade(mayhem_mode, &fee_recipient);
let bonding_curve_account = BondingCurveAccount::from_dev_trade(
bonding_curve,
&mint,
token_amount,
max_sol_cost,
creator,
is_mayhem_mode,
is_cashback_coin,
);
let creator_vault_resolved =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve_account.creator,
creator_vault,
&mint,
None,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(
&bonding_curve_account.creator,
)
})
.unwrap_or_default();
Self {
bonding_curve: Arc::new(bonding_curve_account),
associated_bonding_curve: associated_bonding_curve,
observed_trade_creator: (creator != Pubkey::default()).then_some(creator),
creator_vault: creator_vault_resolved,
fee_sharing_creator_vault_if_active: None,
close_token_account_when_sell: close_token_account_when_sell,
token_program: token_program,
fee_recipient,
quote_mint: Pubkey::default(),
use_v2_ix: false,
}
}
pub fn from_trade(
bonding_curve: Pubkey,
associated_bonding_curve: Pubkey,
mint: Pubkey,
creator: Pubkey,
creator_vault: Pubkey,
virtual_token_reserves: u64,
virtual_sol_reserves: u64,
real_token_reserves: u64,
real_sol_reserves: u64,
close_token_account_when_sell: Option<bool>,
fee_recipient: Pubkey,
token_program: Pubkey,
is_cashback_coin: bool,
mayhem_mode: Option<bool>,
) -> Self {
let is_mayhem_mode = reconcile_mayhem_mode_for_trade(mayhem_mode, &fee_recipient);
let bonding_curve = BondingCurveAccount::from_trade(
bonding_curve,
mint,
creator,
virtual_token_reserves,
virtual_sol_reserves,
real_token_reserves,
real_sol_reserves,
is_mayhem_mode,
is_cashback_coin,
);
let creator_vault_resolved =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve.creator,
creator_vault,
&mint,
None,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve.creator)
})
.unwrap_or_default();
Self {
bonding_curve: Arc::new(bonding_curve),
associated_bonding_curve: associated_bonding_curve,
observed_trade_creator: (creator != Pubkey::default()).then_some(creator),
creator_vault: creator_vault_resolved,
fee_sharing_creator_vault_if_active: None,
close_token_account_when_sell: close_token_account_when_sell,
token_program: token_program,
fee_recipient,
quote_mint: Pubkey::default(),
use_v2_ix: false,
}
}
pub async fn from_mint_by_rpc(
rpc: &SolanaRpcClient,
mint: &Pubkey,
) -> Result<Self, anyhow::Error> {
let account =
crate::instruction::utils::pumpfun::fetch_bonding_curve_account(rpc, mint).await?;
let mint_account = rpc.get_account(&mint).await?;
let bonding_curve = BondingCurveAccount {
discriminator: 0,
account: account.1,
virtual_token_reserves: account.0.virtual_token_reserves,
virtual_sol_reserves: account.0.virtual_sol_reserves,
real_token_reserves: account.0.real_token_reserves,
real_sol_reserves: account.0.real_sol_reserves,
token_total_supply: account.0.token_total_supply,
complete: account.0.complete,
creator: account.0.creator,
is_mayhem_mode: account.0.is_mayhem_mode,
is_cashback_coin: account.0.is_cashback_coin,
};
let associated_bonding_curve = get_associated_token_address_with_program_id(
&bonding_curve.account,
mint,
&mint_account.owner,
);
let fee_sharing_creator_vault_if_active =
crate::instruction::utils::pumpfun::fetch_fee_sharing_creator_vault_if_active(
rpc, mint,
)
.await?;
let creator_vault =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve.creator,
Pubkey::default(),
mint,
fee_sharing_creator_vault_if_active,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve.creator)
})
.unwrap_or_default();
Ok(Self {
bonding_curve: Arc::new(bonding_curve),
associated_bonding_curve: associated_bonding_curve,
observed_trade_creator: None,
creator_vault,
fee_sharing_creator_vault_if_active,
close_token_account_when_sell: None,
token_program: mint_account.owner,
fee_recipient: Pubkey::default(),
quote_mint: Pubkey::default(),
use_v2_ix: false,
})
}
#[inline]
pub fn effective_creator_for_trade(&self) -> Pubkey {
self.observed_trade_creator
.filter(|c| *c != Pubkey::default())
.unwrap_or(self.bonding_curve.creator)
}
pub async fn refresh_fee_sharing_creator_vault_from_rpc(
mut self,
rpc: &SolanaRpcClient,
mint: &Pubkey,
) -> Result<Self, anyhow::Error> {
self.fee_sharing_creator_vault_if_active =
crate::instruction::utils::pumpfun::fetch_fee_sharing_creator_vault_if_active(
rpc, mint,
)
.await?;
let c = self.effective_creator_for_trade();
if let Some(v) =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&c,
self.creator_vault,
mint,
self.fee_sharing_creator_vault_if_active,
)
{
self.creator_vault = v;
}
Ok(self)
}
#[inline]
pub fn with_quote_mint(mut self, quote_mint: Pubkey) -> Self {
self.quote_mint = quote_mint;
self.use_v2_ix = quote_mint != Pubkey::default();
self
}
#[inline]
pub fn with_creator_vault(mut self, creator_vault: Pubkey) -> Self {
self.creator_vault = creator_vault;
self
}
#[inline]
pub fn with_observed_trade_creator(mut self, c: Option<Pubkey>) -> Self {
self.observed_trade_creator = c.filter(|x| *x != Pubkey::default());
self
}
#[inline]
pub fn with_fee_sharing_creator_vault_if_active(
mut self,
fee_sharing_creator_vault_if_active: Option<Pubkey>,
) -> Self {
self.fee_sharing_creator_vault_if_active = fee_sharing_creator_vault_if_active;
self
}
}