1use crate::generated::types::CompressionProof;
9#[cfg(feature = "anchor")]
10use anchor_lang::prelude::{AnchorDeserialize, AnchorSerialize};
11#[cfg(not(feature = "anchor"))]
12use borsh::{BorshDeserialize, BorshSerialize};
13
14pub struct TransferV1 {
16 pub asset: solana_program::pubkey::Pubkey,
18 pub collection: Option<solana_program::pubkey::Pubkey>,
20 pub payer: solana_program::pubkey::Pubkey,
22 pub authority: Option<solana_program::pubkey::Pubkey>,
24 pub new_owner: solana_program::pubkey::Pubkey,
26 pub system_program: Option<solana_program::pubkey::Pubkey>,
28 pub log_wrapper: Option<solana_program::pubkey::Pubkey>,
30}
31
32impl TransferV1 {
33 pub fn instruction(
34 &self,
35 args: TransferV1InstructionArgs,
36 ) -> solana_program::instruction::Instruction {
37 self.instruction_with_remaining_accounts(args, &[])
38 }
39 #[allow(clippy::vec_init_then_push)]
40 pub fn instruction_with_remaining_accounts(
41 &self,
42 args: TransferV1InstructionArgs,
43 remaining_accounts: &[solana_program::instruction::AccountMeta],
44 ) -> solana_program::instruction::Instruction {
45 let mut accounts = Vec::with_capacity(7 + remaining_accounts.len());
46 accounts.push(solana_program::instruction::AccountMeta::new(
47 self.asset, false,
48 ));
49 if let Some(collection) = self.collection {
50 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
51 collection, false,
52 ));
53 } else {
54 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
55 crate::MPL_CORE_ID,
56 false,
57 ));
58 }
59 accounts.push(solana_program::instruction::AccountMeta::new(
60 self.payer, true,
61 ));
62 if let Some(authority) = self.authority {
63 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
64 authority, true,
65 ));
66 } else {
67 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
68 crate::MPL_CORE_ID,
69 false,
70 ));
71 }
72 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
73 self.new_owner,
74 false,
75 ));
76 if let Some(system_program) = self.system_program {
77 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
78 system_program,
79 false,
80 ));
81 } else {
82 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
83 crate::MPL_CORE_ID,
84 false,
85 ));
86 }
87 if let Some(log_wrapper) = self.log_wrapper {
88 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
89 log_wrapper,
90 false,
91 ));
92 } else {
93 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
94 crate::MPL_CORE_ID,
95 false,
96 ));
97 }
98 accounts.extend_from_slice(remaining_accounts);
99 let mut data = TransferV1InstructionData::new().try_to_vec().unwrap();
100 let mut args = args.try_to_vec().unwrap();
101 data.append(&mut args);
102
103 solana_program::instruction::Instruction {
104 program_id: crate::MPL_CORE_ID,
105 accounts,
106 data,
107 }
108 }
109}
110
111#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
112#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
113pub struct TransferV1InstructionData {
114 discriminator: u8,
115}
116
117impl TransferV1InstructionData {
118 pub fn new() -> Self {
119 Self { discriminator: 14 }
120 }
121}
122
123#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
124#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
125#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
126#[derive(Clone, Debug, Eq, PartialEq)]
127pub struct TransferV1InstructionArgs {
128 pub compression_proof: Option<CompressionProof>,
129}
130
131#[derive(Default)]
143pub struct TransferV1Builder {
144 asset: Option<solana_program::pubkey::Pubkey>,
145 collection: Option<solana_program::pubkey::Pubkey>,
146 payer: Option<solana_program::pubkey::Pubkey>,
147 authority: Option<solana_program::pubkey::Pubkey>,
148 new_owner: Option<solana_program::pubkey::Pubkey>,
149 system_program: Option<solana_program::pubkey::Pubkey>,
150 log_wrapper: Option<solana_program::pubkey::Pubkey>,
151 compression_proof: Option<CompressionProof>,
152 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
153}
154
155impl TransferV1Builder {
156 pub fn new() -> Self {
157 Self::default()
158 }
159 #[inline(always)]
161 pub fn asset(&mut self, asset: solana_program::pubkey::Pubkey) -> &mut Self {
162 self.asset = Some(asset);
163 self
164 }
165 #[inline(always)]
168 pub fn collection(&mut self, collection: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
169 self.collection = collection;
170 self
171 }
172 #[inline(always)]
174 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
175 self.payer = Some(payer);
176 self
177 }
178 #[inline(always)]
181 pub fn authority(&mut self, authority: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
182 self.authority = authority;
183 self
184 }
185 #[inline(always)]
187 pub fn new_owner(&mut self, new_owner: solana_program::pubkey::Pubkey) -> &mut Self {
188 self.new_owner = Some(new_owner);
189 self
190 }
191 #[inline(always)]
194 pub fn system_program(
195 &mut self,
196 system_program: Option<solana_program::pubkey::Pubkey>,
197 ) -> &mut Self {
198 self.system_program = system_program;
199 self
200 }
201 #[inline(always)]
204 pub fn log_wrapper(
205 &mut self,
206 log_wrapper: Option<solana_program::pubkey::Pubkey>,
207 ) -> &mut Self {
208 self.log_wrapper = log_wrapper;
209 self
210 }
211 #[inline(always)]
213 pub fn compression_proof(&mut self, compression_proof: CompressionProof) -> &mut Self {
214 self.compression_proof = Some(compression_proof);
215 self
216 }
217 #[inline(always)]
219 pub fn add_remaining_account(
220 &mut self,
221 account: solana_program::instruction::AccountMeta,
222 ) -> &mut Self {
223 self.__remaining_accounts.push(account);
224 self
225 }
226 #[inline(always)]
228 pub fn add_remaining_accounts(
229 &mut self,
230 accounts: &[solana_program::instruction::AccountMeta],
231 ) -> &mut Self {
232 self.__remaining_accounts.extend_from_slice(accounts);
233 self
234 }
235 #[allow(clippy::clone_on_copy)]
236 pub fn instruction(&self) -> solana_program::instruction::Instruction {
237 let accounts = TransferV1 {
238 asset: self.asset.expect("asset is not set"),
239 collection: self.collection,
240 payer: self.payer.expect("payer is not set"),
241 authority: self.authority,
242 new_owner: self.new_owner.expect("new_owner is not set"),
243 system_program: self.system_program,
244 log_wrapper: self.log_wrapper,
245 };
246 let args = TransferV1InstructionArgs {
247 compression_proof: self.compression_proof.clone(),
248 };
249
250 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
251 }
252}
253
254pub struct TransferV1CpiAccounts<'a, 'b> {
256 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
258 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
260 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
262 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
264 pub new_owner: &'b solana_program::account_info::AccountInfo<'a>,
266 pub system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
268 pub log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
270}
271
272pub struct TransferV1Cpi<'a, 'b> {
274 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
276 pub asset: &'b solana_program::account_info::AccountInfo<'a>,
278 pub collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
280 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
282 pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
284 pub new_owner: &'b solana_program::account_info::AccountInfo<'a>,
286 pub system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
288 pub log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
290 pub __args: TransferV1InstructionArgs,
292}
293
294impl<'a, 'b> TransferV1Cpi<'a, 'b> {
295 pub fn new(
296 program: &'b solana_program::account_info::AccountInfo<'a>,
297 accounts: TransferV1CpiAccounts<'a, 'b>,
298 args: TransferV1InstructionArgs,
299 ) -> Self {
300 Self {
301 __program: program,
302 asset: accounts.asset,
303 collection: accounts.collection,
304 payer: accounts.payer,
305 authority: accounts.authority,
306 new_owner: accounts.new_owner,
307 system_program: accounts.system_program,
308 log_wrapper: accounts.log_wrapper,
309 __args: args,
310 }
311 }
312 #[inline(always)]
313 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
314 self.invoke_signed_with_remaining_accounts(&[], &[])
315 }
316 #[inline(always)]
317 pub fn invoke_with_remaining_accounts(
318 &self,
319 remaining_accounts: &[(
320 &'b solana_program::account_info::AccountInfo<'a>,
321 bool,
322 bool,
323 )],
324 ) -> solana_program::entrypoint::ProgramResult {
325 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
326 }
327 #[inline(always)]
328 pub fn invoke_signed(
329 &self,
330 signers_seeds: &[&[&[u8]]],
331 ) -> solana_program::entrypoint::ProgramResult {
332 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
333 }
334 #[allow(clippy::clone_on_copy)]
335 #[allow(clippy::vec_init_then_push)]
336 pub fn invoke_signed_with_remaining_accounts(
337 &self,
338 signers_seeds: &[&[&[u8]]],
339 remaining_accounts: &[(
340 &'b solana_program::account_info::AccountInfo<'a>,
341 bool,
342 bool,
343 )],
344 ) -> solana_program::entrypoint::ProgramResult {
345 let mut accounts = Vec::with_capacity(7 + remaining_accounts.len());
346 accounts.push(solana_program::instruction::AccountMeta::new(
347 *self.asset.key,
348 false,
349 ));
350 if let Some(collection) = self.collection {
351 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
352 *collection.key,
353 false,
354 ));
355 } else {
356 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
357 crate::MPL_CORE_ID,
358 false,
359 ));
360 }
361 accounts.push(solana_program::instruction::AccountMeta::new(
362 *self.payer.key,
363 true,
364 ));
365 if let Some(authority) = self.authority {
366 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
367 *authority.key,
368 true,
369 ));
370 } else {
371 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
372 crate::MPL_CORE_ID,
373 false,
374 ));
375 }
376 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
377 *self.new_owner.key,
378 false,
379 ));
380 if let Some(system_program) = self.system_program {
381 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
382 *system_program.key,
383 false,
384 ));
385 } else {
386 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
387 crate::MPL_CORE_ID,
388 false,
389 ));
390 }
391 if let Some(log_wrapper) = self.log_wrapper {
392 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
393 *log_wrapper.key,
394 false,
395 ));
396 } else {
397 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
398 crate::MPL_CORE_ID,
399 false,
400 ));
401 }
402 remaining_accounts.iter().for_each(|remaining_account| {
403 accounts.push(solana_program::instruction::AccountMeta {
404 pubkey: *remaining_account.0.key,
405 is_signer: remaining_account.1,
406 is_writable: remaining_account.2,
407 })
408 });
409 let mut data = TransferV1InstructionData::new().try_to_vec().unwrap();
410 let mut args = self.__args.try_to_vec().unwrap();
411 data.append(&mut args);
412
413 let instruction = solana_program::instruction::Instruction {
414 program_id: crate::MPL_CORE_ID,
415 accounts,
416 data,
417 };
418 let mut account_infos = Vec::with_capacity(7 + 1 + remaining_accounts.len());
419 account_infos.push(self.__program.clone());
420 account_infos.push(self.asset.clone());
421 if let Some(collection) = self.collection {
422 account_infos.push(collection.clone());
423 }
424 account_infos.push(self.payer.clone());
425 if let Some(authority) = self.authority {
426 account_infos.push(authority.clone());
427 }
428 account_infos.push(self.new_owner.clone());
429 if let Some(system_program) = self.system_program {
430 account_infos.push(system_program.clone());
431 }
432 if let Some(log_wrapper) = self.log_wrapper {
433 account_infos.push(log_wrapper.clone());
434 }
435 remaining_accounts
436 .iter()
437 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
438
439 if signers_seeds.is_empty() {
440 solana_program::program::invoke(&instruction, &account_infos)
441 } else {
442 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
443 }
444 }
445}
446
447pub struct TransferV1CpiBuilder<'a, 'b> {
459 instruction: Box<TransferV1CpiBuilderInstruction<'a, 'b>>,
460}
461
462impl<'a, 'b> TransferV1CpiBuilder<'a, 'b> {
463 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
464 let instruction = Box::new(TransferV1CpiBuilderInstruction {
465 __program: program,
466 asset: None,
467 collection: None,
468 payer: None,
469 authority: None,
470 new_owner: None,
471 system_program: None,
472 log_wrapper: None,
473 compression_proof: None,
474 __remaining_accounts: Vec::new(),
475 });
476 Self { instruction }
477 }
478 #[inline(always)]
480 pub fn asset(&mut self, asset: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
481 self.instruction.asset = Some(asset);
482 self
483 }
484 #[inline(always)]
487 pub fn collection(
488 &mut self,
489 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
490 ) -> &mut Self {
491 self.instruction.collection = collection;
492 self
493 }
494 #[inline(always)]
496 pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
497 self.instruction.payer = Some(payer);
498 self
499 }
500 #[inline(always)]
503 pub fn authority(
504 &mut self,
505 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
506 ) -> &mut Self {
507 self.instruction.authority = authority;
508 self
509 }
510 #[inline(always)]
512 pub fn new_owner(
513 &mut self,
514 new_owner: &'b solana_program::account_info::AccountInfo<'a>,
515 ) -> &mut Self {
516 self.instruction.new_owner = Some(new_owner);
517 self
518 }
519 #[inline(always)]
522 pub fn system_program(
523 &mut self,
524 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
525 ) -> &mut Self {
526 self.instruction.system_program = system_program;
527 self
528 }
529 #[inline(always)]
532 pub fn log_wrapper(
533 &mut self,
534 log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
535 ) -> &mut Self {
536 self.instruction.log_wrapper = log_wrapper;
537 self
538 }
539 #[inline(always)]
541 pub fn compression_proof(&mut self, compression_proof: CompressionProof) -> &mut Self {
542 self.instruction.compression_proof = Some(compression_proof);
543 self
544 }
545 #[inline(always)]
547 pub fn add_remaining_account(
548 &mut self,
549 account: &'b solana_program::account_info::AccountInfo<'a>,
550 is_writable: bool,
551 is_signer: bool,
552 ) -> &mut Self {
553 self.instruction
554 .__remaining_accounts
555 .push((account, is_writable, is_signer));
556 self
557 }
558 #[inline(always)]
563 pub fn add_remaining_accounts(
564 &mut self,
565 accounts: &[(
566 &'b solana_program::account_info::AccountInfo<'a>,
567 bool,
568 bool,
569 )],
570 ) -> &mut Self {
571 self.instruction
572 .__remaining_accounts
573 .extend_from_slice(accounts);
574 self
575 }
576 #[inline(always)]
577 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
578 self.invoke_signed(&[])
579 }
580 #[allow(clippy::clone_on_copy)]
581 #[allow(clippy::vec_init_then_push)]
582 pub fn invoke_signed(
583 &self,
584 signers_seeds: &[&[&[u8]]],
585 ) -> solana_program::entrypoint::ProgramResult {
586 let args = TransferV1InstructionArgs {
587 compression_proof: self.instruction.compression_proof.clone(),
588 };
589 let instruction = TransferV1Cpi {
590 __program: self.instruction.__program,
591
592 asset: self.instruction.asset.expect("asset is not set"),
593
594 collection: self.instruction.collection,
595
596 payer: self.instruction.payer.expect("payer is not set"),
597
598 authority: self.instruction.authority,
599
600 new_owner: self.instruction.new_owner.expect("new_owner is not set"),
601
602 system_program: self.instruction.system_program,
603
604 log_wrapper: self.instruction.log_wrapper,
605 __args: args,
606 };
607 instruction.invoke_signed_with_remaining_accounts(
608 signers_seeds,
609 &self.instruction.__remaining_accounts,
610 )
611 }
612}
613
614struct TransferV1CpiBuilderInstruction<'a, 'b> {
615 __program: &'b solana_program::account_info::AccountInfo<'a>,
616 asset: Option<&'b solana_program::account_info::AccountInfo<'a>>,
617 collection: Option<&'b solana_program::account_info::AccountInfo<'a>>,
618 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
619 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
620 new_owner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
621 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
622 log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
623 compression_proof: Option<CompressionProof>,
624 __remaining_accounts: Vec<(
626 &'b solana_program::account_info::AccountInfo<'a>,
627 bool,
628 bool,
629 )>,
630}