1#[cfg(feature = "anchor")]
9use anchor_lang::prelude::{AnchorDeserialize, AnchorSerialize};
10#[cfg(not(feature = "anchor"))]
11use borsh::{BorshDeserialize, BorshSerialize};
12
13pub struct ExecuteV1 {
15 pub asset: solana_program::pubkey::Pubkey,
17 pub collection: Option<solana_program::pubkey::Pubkey>,
19 pub asset_signer: solana_program::pubkey::Pubkey,
21 pub payer: (solana_program::pubkey::Pubkey, bool),
23 pub authority: Option<solana_program::pubkey::Pubkey>,
25 pub system_program: solana_program::pubkey::Pubkey,
27 pub program_id: solana_program::pubkey::Pubkey,
29}
30
31impl ExecuteV1 {
32 pub fn instruction(
33 &self,
34 args: ExecuteV1InstructionArgs,
35 ) -> solana_program::instruction::Instruction {
36 self.instruction_with_remaining_accounts(args, &[])
37 }
38 #[allow(clippy::vec_init_then_push)]
39 pub fn instruction_with_remaining_accounts(
40 &self,
41 args: ExecuteV1InstructionArgs,
42 remaining_accounts: &[solana_program::instruction::AccountMeta],
43 ) -> solana_program::instruction::Instruction {
44 let mut accounts = Vec::with_capacity(7 + remaining_accounts.len());
45 accounts.push(solana_program::instruction::AccountMeta::new(
46 self.asset, false,
47 ));
48 if let Some(collection) = self.collection {
49 accounts.push(solana_program::instruction::AccountMeta::new(
50 collection, false,
51 ));
52 } else {
53 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
54 crate::MPL_CORE_ID,
55 false,
56 ));
57 }
58 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
59 self.asset_signer,
60 false,
61 ));
62 accounts.push(solana_program::instruction::AccountMeta::new(
63 self.payer.0,
64 self.payer.1,
65 ));
66 if let Some(authority) = self.authority {
67 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
68 authority, true,
69 ));
70 } else {
71 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
72 crate::MPL_CORE_ID,
73 false,
74 ));
75 }
76 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
77 self.system_program,
78 false,
79 ));
80 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
81 self.program_id,
82 false,
83 ));
84 accounts.extend_from_slice(remaining_accounts);
85 let mut data = borsh::to_vec(&(ExecuteV1InstructionData::new())).unwrap();
86 let mut args = borsh::to_vec(&args).unwrap();
87 data.append(&mut args);
88
89 solana_program::instruction::Instruction {
90 program_id: crate::MPL_CORE_ID,
91 accounts,
92 data,
93 }
94 }
95}
96
97#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
98#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
99pub struct ExecuteV1InstructionData {
100 discriminator: u8,
101}
102
103impl ExecuteV1InstructionData {
104 pub fn new() -> Self {
105 Self { discriminator: 31 }
106 }
107}
108
109#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
110#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
111#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
112#[derive(Clone, Debug, Eq, PartialEq)]
113pub struct ExecuteV1InstructionArgs {
114 pub instruction_data: Vec<u8>,
115}
116
117#[derive(Default)]
129pub struct ExecuteV1Builder {
130 asset: Option<solana_program::pubkey::Pubkey>,
131 collection: Option<solana_program::pubkey::Pubkey>,
132 asset_signer: Option<solana_program::pubkey::Pubkey>,
133 payer: Option<(solana_program::pubkey::Pubkey, bool)>,
134 authority: Option<solana_program::pubkey::Pubkey>,
135 system_program: Option<solana_program::pubkey::Pubkey>,
136 program_id: Option<solana_program::pubkey::Pubkey>,
137 instruction_data: Option<Vec<u8>>,
138 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
139}
140
141impl ExecuteV1Builder {
142 pub fn new() -> Self {
143 Self::default()
144 }
145 #[inline(always)]
147 pub fn asset(&mut self, asset: solana_program::pubkey::Pubkey) -> &mut Self {
148 self.asset = Some(asset);
149 self
150 }
151 #[inline(always)]
154 pub fn collection(&mut self, collection: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
155 self.collection = collection;
156 self
157 }
158 #[inline(always)]
160 pub fn asset_signer(&mut self, asset_signer: solana_program::pubkey::Pubkey) -> &mut Self {
161 self.asset_signer = Some(asset_signer);
162 self
163 }
164 #[inline(always)]
166 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey, as_signer: bool) -> &mut Self {
167 self.payer = Some((payer, as_signer));
168 self
169 }
170 #[inline(always)]
173 pub fn authority(&mut self, authority: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
174 self.authority = authority;
175 self
176 }
177 #[inline(always)]
180 pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self {
181 self.system_program = Some(system_program);
182 self
183 }
184 #[inline(always)]
186 pub fn program_id(&mut self, program_id: solana_program::pubkey::Pubkey) -> &mut Self {
187 self.program_id = Some(program_id);
188 self
189 }
190 #[inline(always)]
191 pub fn instruction_data(&mut self, instruction_data: Vec<u8>) -> &mut Self {
192 self.instruction_data = Some(instruction_data);
193 self
194 }
195 #[inline(always)]
197 pub fn add_remaining_account(
198 &mut self,
199 account: solana_program::instruction::AccountMeta,
200 ) -> &mut Self {
201 self.__remaining_accounts.push(account);
202 self
203 }
204 #[inline(always)]
206 pub fn add_remaining_accounts(
207 &mut self,
208 accounts: &[solana_program::instruction::AccountMeta],
209 ) -> &mut Self {
210 self.__remaining_accounts.extend_from_slice(accounts);
211 self
212 }
213 #[allow(clippy::clone_on_copy)]
214 pub fn instruction(&self) -> solana_program::instruction::Instruction {
215 let accounts = ExecuteV1 {
216 asset: self.asset.expect("asset is not set"),
217 collection: self.collection,
218 asset_signer: self.asset_signer.expect("asset_signer is not set"),
219 payer: self.payer.expect("payer is not set"),
220 authority: self.authority,
221 system_program: self
222 .system_program
223 .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")),
224 program_id: self.program_id.expect("program_id is not set"),
225 };
226 let args = ExecuteV1InstructionArgs {
227 instruction_data: self
228 .instruction_data
229 .clone()
230 .expect("instruction_data is not set"),
231 };
232
233 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
234 }
235}
236
237pub struct ExecuteV1CpiAccounts<'a, 'b> {
239 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
241 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
243 pub asset_signer: &'b solana_program::account_info::AccountInfo<'a>,
245 pub payer: (&'b solana_program::account_info::AccountInfo<'a>, bool),
247 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
249 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
251 pub program_id: &'b solana_program::account_info::AccountInfo<'a>,
253}
254
255pub struct ExecuteV1Cpi<'a, 'b> {
257 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
259 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
261 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
263 pub asset_signer: &'b solana_program::account_info::AccountInfo<'a>,
265 pub payer: (&'b solana_program::account_info::AccountInfo<'a>, bool),
267 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
269 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
271 pub program_id: &'b solana_program::account_info::AccountInfo<'a>,
273 pub __args: ExecuteV1InstructionArgs,
275}
276
277impl<'a, 'b> ExecuteV1Cpi<'a, 'b> {
278 pub fn new(
279 program: &'b solana_program::account_info::AccountInfo<'a>,
280 accounts: ExecuteV1CpiAccounts<'a, 'b>,
281 args: ExecuteV1InstructionArgs,
282 ) -> Self {
283 Self {
284 __program: program,
285 asset: accounts.asset,
286 collection: accounts.collection,
287 asset_signer: accounts.asset_signer,
288 payer: accounts.payer,
289 authority: accounts.authority,
290 system_program: accounts.system_program,
291 program_id: accounts.program_id,
292 __args: args,
293 }
294 }
295 #[inline(always)]
296 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
297 self.invoke_signed_with_remaining_accounts(&[], &[])
298 }
299 #[inline(always)]
300 pub fn invoke_with_remaining_accounts(
301 &self,
302 remaining_accounts: &[(
303 &'b solana_program::account_info::AccountInfo<'a>,
304 bool,
305 bool,
306 )],
307 ) -> solana_program::entrypoint::ProgramResult {
308 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
309 }
310 #[inline(always)]
311 pub fn invoke_signed(
312 &self,
313 signers_seeds: &[&[&[u8]]],
314 ) -> solana_program::entrypoint::ProgramResult {
315 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
316 }
317 #[allow(clippy::clone_on_copy)]
318 #[allow(clippy::vec_init_then_push)]
319 pub fn invoke_signed_with_remaining_accounts(
320 &self,
321 signers_seeds: &[&[&[u8]]],
322 remaining_accounts: &[(
323 &'b solana_program::account_info::AccountInfo<'a>,
324 bool,
325 bool,
326 )],
327 ) -> solana_program::entrypoint::ProgramResult {
328 let mut accounts = Vec::with_capacity(7 + remaining_accounts.len());
329 accounts.push(solana_program::instruction::AccountMeta::new(
330 *self.asset.key,
331 false,
332 ));
333 if let Some(collection) = self.collection {
334 accounts.push(solana_program::instruction::AccountMeta::new(
335 *collection.key,
336 false,
337 ));
338 } else {
339 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
340 crate::MPL_CORE_ID,
341 false,
342 ));
343 }
344 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
345 *self.asset_signer.key,
346 false,
347 ));
348 accounts.push(solana_program::instruction::AccountMeta::new(
349 *self.payer.0.key,
350 self.payer.1,
351 ));
352 if let Some(authority) = self.authority {
353 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
354 *authority.key,
355 true,
356 ));
357 } else {
358 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
359 crate::MPL_CORE_ID,
360 false,
361 ));
362 }
363 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
364 *self.system_program.key,
365 false,
366 ));
367 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
368 *self.program_id.key,
369 false,
370 ));
371 remaining_accounts.iter().for_each(|remaining_account| {
372 accounts.push(solana_program::instruction::AccountMeta {
373 pubkey: *remaining_account.0.key,
374 is_writable: remaining_account.1,
375 is_signer: remaining_account.2,
376 })
377 });
378 let mut data = borsh::to_vec(&(ExecuteV1InstructionData::new())).unwrap();
379 let mut args = borsh::to_vec(&self.__args).unwrap();
380 data.append(&mut args);
381
382 let instruction = solana_program::instruction::Instruction {
383 program_id: crate::MPL_CORE_ID,
384 accounts,
385 data,
386 };
387 let mut account_infos = Vec::with_capacity(7 + 1 + remaining_accounts.len());
388 account_infos.push(self.__program.clone());
389 account_infos.push(self.asset.clone());
390 if let Some(collection) = self.collection {
391 account_infos.push(collection.clone());
392 }
393 account_infos.push(self.asset_signer.clone());
394 account_infos.push(self.payer.0.clone());
395 if let Some(authority) = self.authority {
396 account_infos.push(authority.clone());
397 }
398 account_infos.push(self.system_program.clone());
399 account_infos.push(self.program_id.clone());
400 remaining_accounts
401 .iter()
402 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
403
404 if signers_seeds.is_empty() {
405 solana_program::program::invoke(&instruction, &account_infos)
406 } else {
407 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
408 }
409 }
410}
411
412pub struct ExecuteV1CpiBuilder<'a, 'b> {
424 instruction: Box<ExecuteV1CpiBuilderInstruction<'a, 'b>>,
425}
426
427impl<'a, 'b> ExecuteV1CpiBuilder<'a, 'b> {
428 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
429 let instruction = Box::new(ExecuteV1CpiBuilderInstruction {
430 __program: program,
431 asset: None,
432 collection: None,
433 asset_signer: None,
434 payer: None,
435 authority: None,
436 system_program: None,
437 program_id: None,
438 instruction_data: None,
439 __remaining_accounts: Vec::new(),
440 });
441 Self { instruction }
442 }
443 #[inline(always)]
445 pub fn asset(&mut self, asset: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
446 self.instruction.asset = Some(asset);
447 self
448 }
449 #[inline(always)]
452 pub fn collection(
453 &mut self,
454 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
455 ) -> &mut Self {
456 self.instruction.collection = collection;
457 self
458 }
459 #[inline(always)]
461 pub fn asset_signer(
462 &mut self,
463 asset_signer: &'b solana_program::account_info::AccountInfo<'a>,
464 ) -> &mut Self {
465 self.instruction.asset_signer = Some(asset_signer);
466 self
467 }
468 #[inline(always)]
470 pub fn payer(
471 &mut self,
472 payer: &'b solana_program::account_info::AccountInfo<'a>,
473 as_signer: bool,
474 ) -> &mut Self {
475 self.instruction.payer = Some((payer, as_signer));
476 self
477 }
478 #[inline(always)]
481 pub fn authority(
482 &mut self,
483 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
484 ) -> &mut Self {
485 self.instruction.authority = authority;
486 self
487 }
488 #[inline(always)]
490 pub fn system_program(
491 &mut self,
492 system_program: &'b solana_program::account_info::AccountInfo<'a>,
493 ) -> &mut Self {
494 self.instruction.system_program = Some(system_program);
495 self
496 }
497 #[inline(always)]
499 pub fn program_id(
500 &mut self,
501 program_id: &'b solana_program::account_info::AccountInfo<'a>,
502 ) -> &mut Self {
503 self.instruction.program_id = Some(program_id);
504 self
505 }
506 #[inline(always)]
507 pub fn instruction_data(&mut self, instruction_data: Vec<u8>) -> &mut Self {
508 self.instruction.instruction_data = Some(instruction_data);
509 self
510 }
511 #[inline(always)]
513 pub fn add_remaining_account(
514 &mut self,
515 account: &'b solana_program::account_info::AccountInfo<'a>,
516 is_writable: bool,
517 is_signer: bool,
518 ) -> &mut Self {
519 self.instruction
520 .__remaining_accounts
521 .push((account, is_writable, is_signer));
522 self
523 }
524 #[inline(always)]
529 pub fn add_remaining_accounts(
530 &mut self,
531 accounts: &[(
532 &'b solana_program::account_info::AccountInfo<'a>,
533 bool,
534 bool,
535 )],
536 ) -> &mut Self {
537 self.instruction
538 .__remaining_accounts
539 .extend_from_slice(accounts);
540 self
541 }
542 #[inline(always)]
543 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
544 self.invoke_signed(&[])
545 }
546 #[allow(clippy::clone_on_copy)]
547 #[allow(clippy::vec_init_then_push)]
548 pub fn invoke_signed(
549 &self,
550 signers_seeds: &[&[&[u8]]],
551 ) -> solana_program::entrypoint::ProgramResult {
552 let args = ExecuteV1InstructionArgs {
553 instruction_data: self
554 .instruction
555 .instruction_data
556 .clone()
557 .expect("instruction_data is not set"),
558 };
559 let instruction = ExecuteV1Cpi {
560 __program: self.instruction.__program,
561
562 asset: self.instruction.asset.expect("asset is not set"),
563
564 collection: self.instruction.collection,
565
566 asset_signer: self
567 .instruction
568 .asset_signer
569 .expect("asset_signer is not set"),
570
571 payer: self.instruction.payer.expect("payer is not set"),
572
573 authority: self.instruction.authority,
574
575 system_program: self
576 .instruction
577 .system_program
578 .expect("system_program is not set"),
579
580 program_id: self.instruction.program_id.expect("program_id is not set"),
581 __args: args,
582 };
583 instruction.invoke_signed_with_remaining_accounts(
584 signers_seeds,
585 &self.instruction.__remaining_accounts,
586 )
587 }
588}
589
590struct ExecuteV1CpiBuilderInstruction<'a, 'b> {
591 __program: &'b solana_program::account_info::AccountInfo<'a>,
592 asset: Option<&'b solana_program::account_info::AccountInfo<'a>>,
593 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
594 asset_signer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
595 payer: Option<(&'b solana_program::account_info::AccountInfo<'a>, bool)>,
596 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
597 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
598 program_id: Option<&'b solana_program::account_info::AccountInfo<'a>>,
599 instruction_data: Option<Vec<u8>>,
600 __remaining_accounts: Vec<(
602 &'b solana_program::account_info::AccountInfo<'a>,
603 bool,
604 bool,
605 )>,
606}