1use borsh::BorshSerialize;
9use borsh::BorshDeserialize;
10
11pub const SETTLE_PNL_DISCRIMINATOR: [u8; 8] = [43, 61, 234, 45, 15, 95, 152, 153];
12
13#[derive(Debug)]
15pub struct SettlePnl {
16
17
18 pub settler: solana_pubkey::Pubkey,
19
20
21 pub main: solana_pubkey::Pubkey,
22
23
24 pub strategy_controller: solana_pubkey::Pubkey,
25
26
27 pub drift: solana_pubkey::Pubkey,
28
29
30 pub state: solana_pubkey::Pubkey,
31
32
33 pub user_account: solana_pubkey::Pubkey,
34
35
36 pub usdc_market_vault: solana_pubkey::Pubkey,
37 }
38
39impl SettlePnl {
40 pub fn instruction(&self) -> solana_instruction::Instruction {
41 self.instruction_with_remaining_accounts(&[])
42 }
43 #[allow(clippy::arithmetic_side_effects)]
44 #[allow(clippy::vec_init_then_push)]
45 pub fn instruction_with_remaining_accounts(&self, remaining_accounts: &[solana_instruction::AccountMeta]) -> solana_instruction::Instruction {
46 let mut accounts = Vec::with_capacity(7+ remaining_accounts.len());
47 accounts.push(solana_instruction::AccountMeta::new(
48 self.settler,
49 true
50 ));
51 accounts.push(solana_instruction::AccountMeta::new(
52 self.main,
53 false
54 ));
55 accounts.push(solana_instruction::AccountMeta::new(
56 self.strategy_controller,
57 false
58 ));
59 accounts.push(solana_instruction::AccountMeta::new_readonly(
60 self.drift,
61 false
62 ));
63 accounts.push(solana_instruction::AccountMeta::new(
64 self.state,
65 false
66 ));
67 accounts.push(solana_instruction::AccountMeta::new(
68 self.user_account,
69 false
70 ));
71 accounts.push(solana_instruction::AccountMeta::new(
72 self.usdc_market_vault,
73 false
74 ));
75 accounts.extend_from_slice(remaining_accounts);
76 let data = SettlePnlInstructionData::new().try_to_vec().unwrap();
77
78 solana_instruction::Instruction {
79 program_id: crate::REFLECT_MAIN_ID,
80 accounts,
81 data,
82 }
83 }
84}
85
86#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
87#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
88 pub struct SettlePnlInstructionData {
89 discriminator: [u8; 8],
90 }
91
92impl SettlePnlInstructionData {
93 pub fn new() -> Self {
94 Self {
95 discriminator: [43, 61, 234, 45, 15, 95, 152, 153],
96 }
97 }
98
99 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
100 borsh::to_vec(self)
101 }
102 }
103
104impl Default for SettlePnlInstructionData {
105 fn default() -> Self {
106 Self::new()
107 }
108}
109
110
111
112#[derive(Clone, Debug, Default)]
124pub struct SettlePnlBuilder {
125 settler: Option<solana_pubkey::Pubkey>,
126 main: Option<solana_pubkey::Pubkey>,
127 strategy_controller: Option<solana_pubkey::Pubkey>,
128 drift: Option<solana_pubkey::Pubkey>,
129 state: Option<solana_pubkey::Pubkey>,
130 user_account: Option<solana_pubkey::Pubkey>,
131 usdc_market_vault: Option<solana_pubkey::Pubkey>,
132 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
133}
134
135impl SettlePnlBuilder {
136 pub fn new() -> Self {
137 Self::default()
138 }
139 #[inline(always)]
140 pub fn settler(&mut self, settler: solana_pubkey::Pubkey) -> &mut Self {
141 self.settler = Some(settler);
142 self
143 }
144 #[inline(always)]
145 pub fn main(&mut self, main: solana_pubkey::Pubkey) -> &mut Self {
146 self.main = Some(main);
147 self
148 }
149 #[inline(always)]
150 pub fn strategy_controller(&mut self, strategy_controller: solana_pubkey::Pubkey) -> &mut Self {
151 self.strategy_controller = Some(strategy_controller);
152 self
153 }
154 #[inline(always)]
155 pub fn drift(&mut self, drift: solana_pubkey::Pubkey) -> &mut Self {
156 self.drift = Some(drift);
157 self
158 }
159 #[inline(always)]
160 pub fn state(&mut self, state: solana_pubkey::Pubkey) -> &mut Self {
161 self.state = Some(state);
162 self
163 }
164 #[inline(always)]
165 pub fn user_account(&mut self, user_account: solana_pubkey::Pubkey) -> &mut Self {
166 self.user_account = Some(user_account);
167 self
168 }
169 #[inline(always)]
170 pub fn usdc_market_vault(&mut self, usdc_market_vault: solana_pubkey::Pubkey) -> &mut Self {
171 self.usdc_market_vault = Some(usdc_market_vault);
172 self
173 }
174 #[inline(always)]
176 pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self {
177 self.__remaining_accounts.push(account);
178 self
179 }
180 #[inline(always)]
182 pub fn add_remaining_accounts(&mut self, accounts: &[solana_instruction::AccountMeta]) -> &mut Self {
183 self.__remaining_accounts.extend_from_slice(accounts);
184 self
185 }
186 #[allow(clippy::clone_on_copy)]
187 pub fn instruction(&self) -> solana_instruction::Instruction {
188 let accounts = SettlePnl {
189 settler: self.settler.expect("settler is not set"),
190 main: self.main.expect("main is not set"),
191 strategy_controller: self.strategy_controller.expect("strategy_controller is not set"),
192 drift: self.drift.expect("drift is not set"),
193 state: self.state.expect("state is not set"),
194 user_account: self.user_account.expect("user_account is not set"),
195 usdc_market_vault: self.usdc_market_vault.expect("usdc_market_vault is not set"),
196 };
197
198 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
199 }
200}
201
202 pub struct SettlePnlCpiAccounts<'a, 'b> {
204
205
206 pub settler: &'b solana_account_info::AccountInfo<'a>,
207
208
209 pub main: &'b solana_account_info::AccountInfo<'a>,
210
211
212 pub strategy_controller: &'b solana_account_info::AccountInfo<'a>,
213
214
215 pub drift: &'b solana_account_info::AccountInfo<'a>,
216
217
218 pub state: &'b solana_account_info::AccountInfo<'a>,
219
220
221 pub user_account: &'b solana_account_info::AccountInfo<'a>,
222
223
224 pub usdc_market_vault: &'b solana_account_info::AccountInfo<'a>,
225 }
226
227pub struct SettlePnlCpi<'a, 'b> {
229 pub __program: &'b solana_account_info::AccountInfo<'a>,
231
232
233 pub settler: &'b solana_account_info::AccountInfo<'a>,
234
235
236 pub main: &'b solana_account_info::AccountInfo<'a>,
237
238
239 pub strategy_controller: &'b solana_account_info::AccountInfo<'a>,
240
241
242 pub drift: &'b solana_account_info::AccountInfo<'a>,
243
244
245 pub state: &'b solana_account_info::AccountInfo<'a>,
246
247
248 pub user_account: &'b solana_account_info::AccountInfo<'a>,
249
250
251 pub usdc_market_vault: &'b solana_account_info::AccountInfo<'a>,
252 }
253
254impl<'a, 'b> SettlePnlCpi<'a, 'b> {
255 pub fn new(
256 program: &'b solana_account_info::AccountInfo<'a>,
257 accounts: SettlePnlCpiAccounts<'a, 'b>,
258 ) -> Self {
259 Self {
260 __program: program,
261 settler: accounts.settler,
262 main: accounts.main,
263 strategy_controller: accounts.strategy_controller,
264 drift: accounts.drift,
265 state: accounts.state,
266 user_account: accounts.user_account,
267 usdc_market_vault: accounts.usdc_market_vault,
268 }
269 }
270 #[inline(always)]
271 pub fn invoke(&self) -> solana_program_error::ProgramResult {
272 self.invoke_signed_with_remaining_accounts(&[], &[])
273 }
274 #[inline(always)]
275 pub fn invoke_with_remaining_accounts(&self, remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]) -> solana_program_error::ProgramResult {
276 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
277 }
278 #[inline(always)]
279 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
280 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
281 }
282 #[allow(clippy::arithmetic_side_effects)]
283 #[allow(clippy::clone_on_copy)]
284 #[allow(clippy::vec_init_then_push)]
285 pub fn invoke_signed_with_remaining_accounts(
286 &self,
287 signers_seeds: &[&[&[u8]]],
288 remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]
289 ) -> solana_program_error::ProgramResult {
290 let mut accounts = Vec::with_capacity(7+ remaining_accounts.len());
291 accounts.push(solana_instruction::AccountMeta::new(
292 *self.settler.key,
293 true
294 ));
295 accounts.push(solana_instruction::AccountMeta::new(
296 *self.main.key,
297 false
298 ));
299 accounts.push(solana_instruction::AccountMeta::new(
300 *self.strategy_controller.key,
301 false
302 ));
303 accounts.push(solana_instruction::AccountMeta::new_readonly(
304 *self.drift.key,
305 false
306 ));
307 accounts.push(solana_instruction::AccountMeta::new(
308 *self.state.key,
309 false
310 ));
311 accounts.push(solana_instruction::AccountMeta::new(
312 *self.user_account.key,
313 false
314 ));
315 accounts.push(solana_instruction::AccountMeta::new(
316 *self.usdc_market_vault.key,
317 false
318 ));
319 remaining_accounts.iter().for_each(|remaining_account| {
320 accounts.push(solana_instruction::AccountMeta {
321 pubkey: *remaining_account.0.key,
322 is_signer: remaining_account.1,
323 is_writable: remaining_account.2,
324 })
325 });
326 let data = SettlePnlInstructionData::new().try_to_vec().unwrap();
327
328 let instruction = solana_instruction::Instruction {
329 program_id: crate::REFLECT_MAIN_ID,
330 accounts,
331 data,
332 };
333 let mut account_infos = Vec::with_capacity(8 + remaining_accounts.len());
334 account_infos.push(self.__program.clone());
335 account_infos.push(self.settler.clone());
336 account_infos.push(self.main.clone());
337 account_infos.push(self.strategy_controller.clone());
338 account_infos.push(self.drift.clone());
339 account_infos.push(self.state.clone());
340 account_infos.push(self.user_account.clone());
341 account_infos.push(self.usdc_market_vault.clone());
342 remaining_accounts.iter().for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
343
344 if signers_seeds.is_empty() {
345 solana_cpi::invoke(&instruction, &account_infos)
346 } else {
347 solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds)
348 }
349 }
350}
351
352#[derive(Clone, Debug)]
364pub struct SettlePnlCpiBuilder<'a, 'b> {
365 instruction: Box<SettlePnlCpiBuilderInstruction<'a, 'b>>,
366}
367
368impl<'a, 'b> SettlePnlCpiBuilder<'a, 'b> {
369 pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self {
370 let instruction = Box::new(SettlePnlCpiBuilderInstruction {
371 __program: program,
372 settler: None,
373 main: None,
374 strategy_controller: None,
375 drift: None,
376 state: None,
377 user_account: None,
378 usdc_market_vault: None,
379 __remaining_accounts: Vec::new(),
380 });
381 Self { instruction }
382 }
383 #[inline(always)]
384 pub fn settler(&mut self, settler: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
385 self.instruction.settler = Some(settler);
386 self
387 }
388 #[inline(always)]
389 pub fn main(&mut self, main: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
390 self.instruction.main = Some(main);
391 self
392 }
393 #[inline(always)]
394 pub fn strategy_controller(&mut self, strategy_controller: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
395 self.instruction.strategy_controller = Some(strategy_controller);
396 self
397 }
398 #[inline(always)]
399 pub fn drift(&mut self, drift: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
400 self.instruction.drift = Some(drift);
401 self
402 }
403 #[inline(always)]
404 pub fn state(&mut self, state: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
405 self.instruction.state = Some(state);
406 self
407 }
408 #[inline(always)]
409 pub fn user_account(&mut self, user_account: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
410 self.instruction.user_account = Some(user_account);
411 self
412 }
413 #[inline(always)]
414 pub fn usdc_market_vault(&mut self, usdc_market_vault: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
415 self.instruction.usdc_market_vault = Some(usdc_market_vault);
416 self
417 }
418 #[inline(always)]
420 pub fn add_remaining_account(&mut self, account: &'b solana_account_info::AccountInfo<'a>, is_writable: bool, is_signer: bool) -> &mut Self {
421 self.instruction.__remaining_accounts.push((account, is_writable, is_signer));
422 self
423 }
424 #[inline(always)]
429 pub fn add_remaining_accounts(&mut self, accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]) -> &mut Self {
430 self.instruction.__remaining_accounts.extend_from_slice(accounts);
431 self
432 }
433 #[inline(always)]
434 pub fn invoke(&self) -> solana_program_error::ProgramResult {
435 self.invoke_signed(&[])
436 }
437 #[allow(clippy::clone_on_copy)]
438 #[allow(clippy::vec_init_then_push)]
439 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
440 let instruction = SettlePnlCpi {
441 __program: self.instruction.__program,
442
443 settler: self.instruction.settler.expect("settler is not set"),
444
445 main: self.instruction.main.expect("main is not set"),
446
447 strategy_controller: self.instruction.strategy_controller.expect("strategy_controller is not set"),
448
449 drift: self.instruction.drift.expect("drift is not set"),
450
451 state: self.instruction.state.expect("state is not set"),
452
453 user_account: self.instruction.user_account.expect("user_account is not set"),
454
455 usdc_market_vault: self.instruction.usdc_market_vault.expect("usdc_market_vault is not set"),
456 };
457 instruction.invoke_signed_with_remaining_accounts(signers_seeds, &self.instruction.__remaining_accounts)
458 }
459}
460
461#[derive(Clone, Debug)]
462struct SettlePnlCpiBuilderInstruction<'a, 'b> {
463 __program: &'b solana_account_info::AccountInfo<'a>,
464 settler: Option<&'b solana_account_info::AccountInfo<'a>>,
465 main: Option<&'b solana_account_info::AccountInfo<'a>>,
466 strategy_controller: Option<&'b solana_account_info::AccountInfo<'a>>,
467 drift: Option<&'b solana_account_info::AccountInfo<'a>>,
468 state: Option<&'b solana_account_info::AccountInfo<'a>>,
469 user_account: Option<&'b solana_account_info::AccountInfo<'a>>,
470 usdc_market_vault: Option<&'b solana_account_info::AccountInfo<'a>>,
471 __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>,
473}
474