use super::raydium_cpmm::TokenTransferFee;
use super::{
MeteoraDlmmParams, RaydiumAmmV4Params, RaydiumClmmParams, RaydiumCpmmParams, WhirlpoolParams,
};
use solana_sdk::pubkey::Pubkey;
#[derive(Clone)]
pub enum StonkFunQuoteVenue {
PumpFunV3 {
mint: Pubkey,
params: super::PumpFunV3Params,
},
PumpFun {
mint: Pubkey,
curve: super::PumpFunParams,
quote_token_program: Pubkey,
base_transfer_fee: TokenTransferFee,
quote_transfer_fee: TokenTransferFee,
},
PumpSwap {
pool: super::PumpSwapParams,
base_transfer_fee: TokenTransferFee,
quote_transfer_fee: TokenTransferFee,
},
RaydiumCpmm(RaydiumCpmmParams),
RaydiumAmmV4(RaydiumAmmV4Params),
RaydiumClmm(RaydiumClmmParams),
OrcaWhirlpool(WhirlpoolParams),
MeteoraDlmm(MeteoraDlmmParams),
}
pub type PumpSwapQuoteRoute = StonkFunQuoteRoute;
pub type PumpSwapQuoteHop = StonkFunQuoteHop;
pub type PumpSwapQuoteVenue = StonkFunQuoteVenue;
pub type PumpFunQuoteRoute = StonkFunQuoteRoute;
pub type PumpFunQuoteHop = StonkFunQuoteHop;
pub type PumpFunQuoteVenue = StonkFunQuoteVenue;
#[derive(Clone)]
pub struct StonkFunQuoteHop {
pub venue: StonkFunQuoteVenue,
pub input_mint: Pubkey,
pub output_mint: Pubkey,
pub input_amount: Option<u64>,
pub minimum_amount_out: u64,
pub output_transfer_fee: Option<TokenTransferFee>,
}
impl StonkFunQuoteHop {
pub fn exact_in(
venue: StonkFunQuoteVenue,
input_mint: Pubkey,
output_mint: Pubkey,
minimum_amount_out: u64,
) -> Self {
Self {
venue,
input_mint,
output_mint,
input_amount: None,
minimum_amount_out,
output_transfer_fee: None,
}
}
pub fn with_input_amount(mut self, amount: u64) -> Self {
self.input_amount = Some(amount);
self
}
pub fn with_output_transfer_fee(mut self, fee: TokenTransferFee) -> Self {
self.output_transfer_fee = Some(fee);
self
}
pub async fn with_output_transfer_fee_by_rpc(
mut self,
rpc: &crate::common::SolanaRpcClient,
) -> anyhow::Result<Self> {
let mint = rpc.get_account(&self.output_mint).await?;
let epoch = rpc.get_epoch_info().await?.epoch;
self.output_transfer_fee =
Some(super::raydium_cpmm::token_transfer_fee_for_epoch(&mint.data, mint.owner, epoch)?);
Ok(self)
}
}
#[derive(Clone, Default)]
pub struct StonkFunQuoteRoute {
pub buy_hops: Vec<StonkFunQuoteHop>,
pub sell_hops: Vec<StonkFunQuoteHop>,
pub buy_execution: crate::PumpRouteOptions,
pub sell_execution: crate::PumpRouteOptions,
}
#[derive(Clone, Debug)]
pub struct StonkFunQuoteRoutePreview {
pub hops: Vec<StonkFunQuoteHopPreview>,
pub minimum_output_credit: u64,
}
#[derive(Clone, Debug)]
pub struct StonkFunQuoteHopPreview {
pub input_mint: Pubkey,
pub output_mint: Pubkey,
pub input_token_program: Pubkey,
pub output_token_program: Pubkey,
pub input_amount: u64,
pub minimum_amount_out: u64,
}
impl StonkFunQuoteRoute {
pub fn preview(
&self,
input_mint: Pubkey,
output_mint: Pubkey,
input_amount: u64,
slippage_basis_points: u64,
is_buy: bool,
) -> anyhow::Result<StonkFunQuoteRoutePreview> {
let plan = crate::instruction::stonkfun_quote_route::plan_route(
self,
input_mint,
output_mint,
input_amount,
slippage_basis_points,
is_buy,
)?;
Ok(StonkFunQuoteRoutePreview {
minimum_output_credit: plan.minimum_credit,
hops: plan
.hops
.iter()
.map(|hop| StonkFunQuoteHopPreview {
input_mint: hop.input,
output_mint: hop.output,
input_token_program: hop.input_program,
output_token_program: hop.output_program,
input_amount: hop.amount,
minimum_amount_out: hop.hop.minimum_amount_out,
})
.collect(),
})
}
pub fn buy(hops: Vec<StonkFunQuoteHop>) -> Self {
Self { buy_hops: hops, sell_hops: Vec::new(), ..Self::default() }
}
pub fn sell(hops: Vec<StonkFunQuoteHop>) -> Self {
Self { buy_hops: Vec::new(), sell_hops: hops, ..Self::default() }
}
pub fn with_sell_hops(mut self, hops: Vec<StonkFunQuoteHop>) -> Self {
self.sell_hops = hops;
self
}
pub fn with_buy_execution(mut self, options: crate::PumpRouteOptions) -> Self {
self.buy_execution = options;
self
}
pub fn with_sell_execution(mut self, options: crate::PumpRouteOptions) -> Self {
self.sell_execution = options;
self
}
}