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