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,
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, true,
64 ));
65 if let Some(authority) = self.authority {
66 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
67 authority, true,
68 ));
69 } else {
70 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
71 crate::MPL_CORE_ID,
72 false,
73 ));
74 }
75 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
76 self.system_program,
77 false,
78 ));
79 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
80 self.program_id,
81 false,
82 ));
83 accounts.extend_from_slice(remaining_accounts);
84 let mut data = ExecuteV1InstructionData::new().try_to_vec().unwrap();
85 let mut args = args.try_to_vec().unwrap();
86 data.append(&mut args);
87
88 solana_program::instruction::Instruction {
89 program_id: crate::MPL_CORE_ID,
90 accounts,
91 data,
92 }
93 }
94}
95
96#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
97#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
98pub struct ExecuteV1InstructionData {
99 discriminator: u8,
100}
101
102impl ExecuteV1InstructionData {
103 pub fn new() -> Self {
104 Self { discriminator: 31 }
105 }
106}
107
108#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
109#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
110#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
111#[derive(Clone, Debug, Eq, PartialEq)]
112pub struct ExecuteV1InstructionArgs {
113 pub instruction_data: Vec<u8>,
114}
115
116#[derive(Default)]
128pub struct ExecuteV1Builder {
129 asset: Option<solana_program::pubkey::Pubkey>,
130 collection: Option<solana_program::pubkey::Pubkey>,
131 asset_signer: Option<solana_program::pubkey::Pubkey>,
132 payer: Option<solana_program::pubkey::Pubkey>,
133 authority: Option<solana_program::pubkey::Pubkey>,
134 system_program: Option<solana_program::pubkey::Pubkey>,
135 program_id: Option<solana_program::pubkey::Pubkey>,
136 instruction_data: Option<Vec<u8>>,
137 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
138}
139
140impl ExecuteV1Builder {
141 pub fn new() -> Self {
142 Self::default()
143 }
144 #[inline(always)]
146 pub fn asset(&mut self, asset: solana_program::pubkey::Pubkey) -> &mut Self {
147 self.asset = Some(asset);
148 self
149 }
150 #[inline(always)]
153 pub fn collection(&mut self, collection: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
154 self.collection = collection;
155 self
156 }
157 #[inline(always)]
159 pub fn asset_signer(&mut self, asset_signer: solana_program::pubkey::Pubkey) -> &mut Self {
160 self.asset_signer = Some(asset_signer);
161 self
162 }
163 #[inline(always)]
165 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
166 self.payer = Some(payer);
167 self
168 }
169 #[inline(always)]
172 pub fn authority(&mut self, authority: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
173 self.authority = authority;
174 self
175 }
176 #[inline(always)]
179 pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self {
180 self.system_program = Some(system_program);
181 self
182 }
183 #[inline(always)]
185 pub fn program_id(&mut self, program_id: solana_program::pubkey::Pubkey) -> &mut Self {
186 self.program_id = Some(program_id);
187 self
188 }
189 #[inline(always)]
190 pub fn instruction_data(&mut self, instruction_data: Vec<u8>) -> &mut Self {
191 self.instruction_data = Some(instruction_data);
192 self
193 }
194 #[inline(always)]
196 pub fn add_remaining_account(
197 &mut self,
198 account: solana_program::instruction::AccountMeta,
199 ) -> &mut Self {
200 self.__remaining_accounts.push(account);
201 self
202 }
203 #[inline(always)]
205 pub fn add_remaining_accounts(
206 &mut self,
207 accounts: &[solana_program::instruction::AccountMeta],
208 ) -> &mut Self {
209 self.__remaining_accounts.extend_from_slice(accounts);
210 self
211 }
212 #[allow(clippy::clone_on_copy)]
213 pub fn instruction(&self) -> solana_program::instruction::Instruction {
214 let accounts = ExecuteV1 {
215 asset: self.asset.expect("asset is not set"),
216 collection: self.collection,
217 asset_signer: self.asset_signer.expect("asset_signer is not set"),
218 payer: self.payer.expect("payer is not set"),
219 authority: self.authority,
220 system_program: self
221 .system_program
222 .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")),
223 program_id: self.program_id.expect("program_id is not set"),
224 };
225 let args = ExecuteV1InstructionArgs {
226 instruction_data: self
227 .instruction_data
228 .clone()
229 .expect("instruction_data is not set"),
230 };
231
232 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
233 }
234}
235
236pub struct ExecuteV1CpiAccounts<'a, 'b> {
238 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
240 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
242 pub asset_signer: &'b solana_program::account_info::AccountInfo<'a>,
244 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
246 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
248 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
250 pub program_id: &'b solana_program::account_info::AccountInfo<'a>,
252}
253
254pub struct ExecuteV1Cpi<'a, 'b> {
256 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
258 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
260 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
262 pub asset_signer: &'b solana_program::account_info::AccountInfo<'a>,
264 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
266 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
268 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
270 pub program_id: &'b solana_program::account_info::AccountInfo<'a>,
272 pub __args: ExecuteV1InstructionArgs,
274}
275
276impl<'a, 'b> ExecuteV1Cpi<'a, 'b> {
277 pub fn new(
278 program: &'b solana_program::account_info::AccountInfo<'a>,
279 accounts: ExecuteV1CpiAccounts<'a, 'b>,
280 args: ExecuteV1InstructionArgs,
281 ) -> Self {
282 Self {
283 __program: program,
284 asset: accounts.asset,
285 collection: accounts.collection,
286 asset_signer: accounts.asset_signer,
287 payer: accounts.payer,
288 authority: accounts.authority,
289 system_program: accounts.system_program,
290 program_id: accounts.program_id,
291 __args: args,
292 }
293 }
294 #[inline(always)]
295 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
296 self.invoke_signed_with_remaining_accounts(&[], &[])
297 }
298 #[inline(always)]
299 pub fn invoke_with_remaining_accounts(
300 &self,
301 remaining_accounts: &[(
302 &'b solana_program::account_info::AccountInfo<'a>,
303 bool,
304 bool,
305 )],
306 ) -> solana_program::entrypoint::ProgramResult {
307 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
308 }
309 #[inline(always)]
310 pub fn invoke_signed(
311 &self,
312 signers_seeds: &[&[&[u8]]],
313 ) -> solana_program::entrypoint::ProgramResult {
314 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
315 }
316 #[allow(clippy::clone_on_copy)]
317 #[allow(clippy::vec_init_then_push)]
318 pub fn invoke_signed_with_remaining_accounts(
319 &self,
320 signers_seeds: &[&[&[u8]]],
321 remaining_accounts: &[(
322 &'b solana_program::account_info::AccountInfo<'a>,
323 bool,
324 bool,
325 )],
326 ) -> solana_program::entrypoint::ProgramResult {
327 let mut accounts = Vec::with_capacity(7 + remaining_accounts.len());
328 accounts.push(solana_program::instruction::AccountMeta::new(
329 *self.asset.key,
330 false,
331 ));
332 if let Some(collection) = self.collection {
333 accounts.push(solana_program::instruction::AccountMeta::new(
334 *collection.key,
335 false,
336 ));
337 } else {
338 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
339 crate::MPL_CORE_ID,
340 false,
341 ));
342 }
343 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
344 *self.asset_signer.key,
345 false,
346 ));
347 accounts.push(solana_program::instruction::AccountMeta::new(
348 *self.payer.key,
349 true,
350 ));
351 if let Some(authority) = self.authority {
352 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
353 *authority.key,
354 true,
355 ));
356 } else {
357 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
358 crate::MPL_CORE_ID,
359 false,
360 ));
361 }
362 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
363 *self.system_program.key,
364 false,
365 ));
366 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
367 *self.program_id.key,
368 false,
369 ));
370 remaining_accounts.iter().for_each(|remaining_account| {
371 accounts.push(solana_program::instruction::AccountMeta {
372 pubkey: *remaining_account.0.key,
373 is_signer: remaining_account.1,
374 is_writable: remaining_account.2,
375 })
376 });
377 let mut data = ExecuteV1InstructionData::new().try_to_vec().unwrap();
378 let mut args = self.__args.try_to_vec().unwrap();
379 data.append(&mut args);
380
381 let instruction = solana_program::instruction::Instruction {
382 program_id: crate::MPL_CORE_ID,
383 accounts,
384 data,
385 };
386 let mut account_infos = Vec::with_capacity(7 + 1 + remaining_accounts.len());
387 account_infos.push(self.__program.clone());
388 account_infos.push(self.asset.clone());
389 if let Some(collection) = self.collection {
390 account_infos.push(collection.clone());
391 }
392 account_infos.push(self.asset_signer.clone());
393 account_infos.push(self.payer.clone());
394 if let Some(authority) = self.authority {
395 account_infos.push(authority.clone());
396 }
397 account_infos.push(self.system_program.clone());
398 account_infos.push(self.program_id.clone());
399 remaining_accounts
400 .iter()
401 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
402
403 if signers_seeds.is_empty() {
404 solana_program::program::invoke(&instruction, &account_infos)
405 } else {
406 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
407 }
408 }
409}
410
411pub struct ExecuteV1CpiBuilder<'a, 'b> {
423 instruction: Box<ExecuteV1CpiBuilderInstruction<'a, 'b>>,
424}
425
426impl<'a, 'b> ExecuteV1CpiBuilder<'a, 'b> {
427 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
428 let instruction = Box::new(ExecuteV1CpiBuilderInstruction {
429 __program: program,
430 asset: None,
431 collection: None,
432 asset_signer: None,
433 payer: None,
434 authority: None,
435 system_program: None,
436 program_id: None,
437 instruction_data: None,
438 __remaining_accounts: Vec::new(),
439 });
440 Self { instruction }
441 }
442 #[inline(always)]
444 pub fn asset(&mut self, asset: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
445 self.instruction.asset = Some(asset);
446 self
447 }
448 #[inline(always)]
451 pub fn collection(
452 &mut self,
453 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
454 ) -> &mut Self {
455 self.instruction.collection = collection;
456 self
457 }
458 #[inline(always)]
460 pub fn asset_signer(
461 &mut self,
462 asset_signer: &'b solana_program::account_info::AccountInfo<'a>,
463 ) -> &mut Self {
464 self.instruction.asset_signer = Some(asset_signer);
465 self
466 }
467 #[inline(always)]
469 pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
470 self.instruction.payer = Some(payer);
471 self
472 }
473 #[inline(always)]
476 pub fn authority(
477 &mut self,
478 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
479 ) -> &mut Self {
480 self.instruction.authority = authority;
481 self
482 }
483 #[inline(always)]
485 pub fn system_program(
486 &mut self,
487 system_program: &'b solana_program::account_info::AccountInfo<'a>,
488 ) -> &mut Self {
489 self.instruction.system_program = Some(system_program);
490 self
491 }
492 #[inline(always)]
494 pub fn program_id(
495 &mut self,
496 program_id: &'b solana_program::account_info::AccountInfo<'a>,
497 ) -> &mut Self {
498 self.instruction.program_id = Some(program_id);
499 self
500 }
501 #[inline(always)]
502 pub fn instruction_data(&mut self, instruction_data: Vec<u8>) -> &mut Self {
503 self.instruction.instruction_data = Some(instruction_data);
504 self
505 }
506 #[inline(always)]
508 pub fn add_remaining_account(
509 &mut self,
510 account: &'b solana_program::account_info::AccountInfo<'a>,
511 is_writable: bool,
512 is_signer: bool,
513 ) -> &mut Self {
514 self.instruction
515 .__remaining_accounts
516 .push((account, is_writable, is_signer));
517 self
518 }
519 #[inline(always)]
524 pub fn add_remaining_accounts(
525 &mut self,
526 accounts: &[(
527 &'b solana_program::account_info::AccountInfo<'a>,
528 bool,
529 bool,
530 )],
531 ) -> &mut Self {
532 self.instruction
533 .__remaining_accounts
534 .extend_from_slice(accounts);
535 self
536 }
537 #[inline(always)]
538 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
539 self.invoke_signed(&[])
540 }
541 #[allow(clippy::clone_on_copy)]
542 #[allow(clippy::vec_init_then_push)]
543 pub fn invoke_signed(
544 &self,
545 signers_seeds: &[&[&[u8]]],
546 ) -> solana_program::entrypoint::ProgramResult {
547 let args = ExecuteV1InstructionArgs {
548 instruction_data: self
549 .instruction
550 .instruction_data
551 .clone()
552 .expect("instruction_data is not set"),
553 };
554 let instruction = ExecuteV1Cpi {
555 __program: self.instruction.__program,
556
557 asset: self.instruction.asset.expect("asset is not set"),
558
559 collection: self.instruction.collection,
560
561 asset_signer: self
562 .instruction
563 .asset_signer
564 .expect("asset_signer is not set"),
565
566 payer: self.instruction.payer.expect("payer is not set"),
567
568 authority: self.instruction.authority,
569
570 system_program: self
571 .instruction
572 .system_program
573 .expect("system_program is not set"),
574
575 program_id: self.instruction.program_id.expect("program_id is not set"),
576 __args: args,
577 };
578 instruction.invoke_signed_with_remaining_accounts(
579 signers_seeds,
580 &self.instruction.__remaining_accounts,
581 )
582 }
583}
584
585struct ExecuteV1CpiBuilderInstruction<'a, 'b> {
586 __program: &'b solana_program::account_info::AccountInfo<'a>,
587 asset: Option<&'b solana_program::account_info::AccountInfo<'a>>,
588 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
589 asset_signer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
590 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
591 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
592 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
593 program_id: Option<&'b solana_program::account_info::AccountInfo<'a>>,
594 instruction_data: Option<Vec<u8>>,
595 __remaining_accounts: Vec<(
597 &'b solana_program::account_info::AccountInfo<'a>,
598 bool,
599 bool,
600 )>,
601}