1use solana_program::instruction::Instruction;
2
3use crate::constants;
4use crate::math::QuoteResult;
5use crate::token::{
6 create_associated_token_account_idempotent, unwrap_sol_instruction, wrap_sol_instructions,
7};
8
9use super::{
10 AmmQuoteSource, PumpSdk, Quote, TradeQuoteParams, TradeTxParams, TradeTxWithVenueParams,
11 TradeVenue,
12};
13
14impl PumpSdk {
15 pub fn trade_tx_instructions_with_venue(
19 &self,
20 params: TradeTxWithVenueParams<'_>,
21 ) -> Option<Vec<Instruction>> {
22 let TradeTxWithVenueParams {
23 mint,
24 base_token_program,
25 quote_token_program,
26 user,
27 is_buy,
28 venue,
29 base_amount,
30 sol_amount_threshold,
31 } = params;
32
33 match venue {
34 TradeVenue::BondingCurve {
35 global,
36 bonding_curve,
37 } => {
38 if is_buy {
39 self.buy_v2_instructions(
40 global,
41 bonding_curve,
42 mint,
43 quote_token_program,
44 user,
45 base_amount,
46 sol_amount_threshold,
47 )
48 } else {
49 self.sell_v2_instructions(
50 global,
51 bonding_curve,
52 mint,
53 quote_token_program,
54 user,
55 base_amount,
56 sol_amount_threshold,
57 )
58 }
59 }
60 TradeVenue::Amm {
61 pool,
62 amm_global,
63 pool_state,
64 } => {
65 debug_assert_eq!(mint, pool_state.base_mint);
66 let base_mint = pool_state.base_mint;
67 let quote_mint = pool_state.quote_mint;
68 let (protocol_fee_recipient, buyback_fee_recipient) =
69 Self::amm_fee_recipients_pair(amm_global)?;
70 let coin_creator = pool_state.coin_creator;
71 let is_cashback_coin = pool_state.is_cashback_coin;
72 let uses_native_quote = quote_mint == constants::NATIVE_MINT;
73
74 let mut ixs: Vec<Instruction> = Vec::with_capacity(6);
75 if is_buy {
76 ixs.push(create_associated_token_account_idempotent(
77 &user,
78 &user,
79 &base_mint,
80 &base_token_program,
81 ));
82 ixs.push(create_associated_token_account_idempotent(
83 &user,
84 &user,
85 "e_mint,
86 "e_token_program,
87 ));
88 if uses_native_quote {
89 ixs.extend(wrap_sol_instructions(&user, sol_amount_threshold));
90 }
91 ixs.push(self.buy_amm_instruction_with_recipients(
92 pool,
93 base_mint,
94 quote_mint,
95 base_token_program,
96 quote_token_program,
97 user,
98 coin_creator,
99 protocol_fee_recipient,
100 buyback_fee_recipient,
101 is_cashback_coin,
102 base_amount,
103 sol_amount_threshold,
104 ));
105 } else {
106 ixs.push(create_associated_token_account_idempotent(
107 &user,
108 &user,
109 "e_mint,
110 "e_token_program,
111 ));
112 ixs.push(self.sell_amm_instruction_with_recipients(
113 pool,
114 base_mint,
115 quote_mint,
116 base_token_program,
117 quote_token_program,
118 user,
119 coin_creator,
120 protocol_fee_recipient,
121 buyback_fee_recipient,
122 is_cashback_coin,
123 base_amount,
124 sol_amount_threshold,
125 ));
126 }
127 if uses_native_quote {
128 ixs.push(unwrap_sol_instruction(&user));
129 }
130 Some(ixs)
131 }
132 }
133 }
134
135 pub fn trade_tx_instructions(&self, params: TradeTxParams<'_>) -> Option<Vec<Instruction>> {
137 let TradeTxParams {
138 mint,
139 base_token_program,
140 quote_token_program,
141 user,
142 is_buy,
143 base_amount,
144 sol_amount_threshold,
145 pump_global,
146 bonding_curve,
147 pump_pool,
148 } = params;
149
150 let venue = if bonding_curve.complete {
151 let p = pump_pool?;
152 TradeVenue::Amm {
153 pool: p.pool,
154 amm_global: p.amm_global,
155 pool_state: p.pool_state,
156 }
157 } else {
158 TradeVenue::BondingCurve {
159 global: pump_global,
160 bonding_curve,
161 }
162 };
163
164 self.trade_tx_instructions_with_venue(TradeTxWithVenueParams {
165 mint,
166 base_token_program,
167 quote_token_program,
168 user,
169 is_buy,
170 venue,
171 base_amount,
172 sol_amount_threshold,
173 })
174 }
175
176 pub fn quote_trade(&self, params: TradeQuoteParams<'_>) -> Option<QuoteResult<Quote>> {
181 let TradeQuoteParams {
182 is_buy,
183 base_amount,
184 slippage_bps,
185 base_mint_supply,
186 pump_global,
187 pump_fee_config,
188 bonding_curve,
189 pump_pool,
190 } = params;
191
192 if bonding_curve.complete {
193 let p = pump_pool?;
194 let source = AmmQuoteSource::Pool {
195 pool: p.pool_state,
196 base_reserve: p.base_reserve,
197 quote_reserve: p.quote_reserve,
198 base_mint_supply,
199 };
200 Some(if is_buy {
201 self.buy_quote_amm_token_out(
202 p.amm_global,
203 p.amm_fee_config,
204 source,
205 base_amount,
206 slippage_bps,
207 )
208 } else {
209 self.sell_quote_amm(
210 p.amm_global,
211 p.amm_fee_config,
212 source,
213 base_amount,
214 slippage_bps,
215 )
216 })
217 } else {
218 Some(if is_buy {
219 self.buy_quote_bonding_curve_token_out(
220 pump_global,
221 pump_fee_config,
222 bonding_curve,
223 base_mint_supply,
224 base_amount,
225 slippage_bps,
226 )
227 } else {
228 self.sell_quote_bonding_curve(
229 pump_global,
230 pump_fee_config,
231 bonding_curve,
232 base_mint_supply,
233 base_amount,
234 slippage_bps,
235 )
236 })
237 }
238 }
239}