Skip to main content

mpl_token_metadata/generated/instructions/
transfer.rs

1//! This code was AUTOGENERATED using the kinobi library.
2//! Please DO NOT EDIT THIS FILE, instead use visitors
3//! to add features, then rerun kinobi to update it.
4//!
5//! [https://github.com/metaplex-foundation/kinobi]
6//!
7
8use crate::generated::types::TransferArgs;
9use borsh::BorshDeserialize;
10use borsh::BorshSerialize;
11
12/// Accounts.
13pub struct Transfer {
14    /// Token account
15    pub token: solana_program::pubkey::Pubkey,
16    /// Token account owner
17    pub token_owner: solana_program::pubkey::Pubkey,
18    /// Destination token account
19    pub destination_token: solana_program::pubkey::Pubkey,
20    /// Destination token account owner
21    pub destination_owner: solana_program::pubkey::Pubkey,
22    /// Mint of token asset
23    pub mint: solana_program::pubkey::Pubkey,
24    /// Metadata (pda of ['metadata', program id, mint id])
25    pub metadata: solana_program::pubkey::Pubkey,
26    /// Edition of token asset
27    pub edition: Option<solana_program::pubkey::Pubkey>,
28    /// Owner token record account
29    pub token_record: Option<solana_program::pubkey::Pubkey>,
30    /// Destination token record account
31    pub destination_token_record: Option<solana_program::pubkey::Pubkey>,
32    /// Transfer authority (token owner or delegate)
33    pub authority: solana_program::pubkey::Pubkey,
34    /// Payer
35    pub payer: solana_program::pubkey::Pubkey,
36    /// System Program
37    pub system_program: solana_program::pubkey::Pubkey,
38    /// Instructions sysvar account
39    pub sysvar_instructions: solana_program::pubkey::Pubkey,
40    /// SPL Token Program
41    pub spl_token_program: solana_program::pubkey::Pubkey,
42    /// SPL Associated Token Account program
43    pub spl_ata_program: solana_program::pubkey::Pubkey,
44    /// Token Authorization Rules Program
45    pub authorization_rules_program: Option<solana_program::pubkey::Pubkey>,
46    /// Token Authorization Rules account
47    pub authorization_rules: Option<solana_program::pubkey::Pubkey>,
48}
49
50impl Transfer {
51    pub fn instruction(
52        &self,
53        args: TransferInstructionArgs,
54    ) -> solana_program::instruction::Instruction {
55        self.instruction_with_remaining_accounts(args, &[])
56    }
57    #[allow(clippy::vec_init_then_push)]
58    pub fn instruction_with_remaining_accounts(
59        &self,
60        args: TransferInstructionArgs,
61        remaining_accounts: &[solana_program::instruction::AccountMeta],
62    ) -> solana_program::instruction::Instruction {
63        let mut accounts = Vec::with_capacity(17 + remaining_accounts.len());
64        accounts.push(solana_program::instruction::AccountMeta::new(
65            self.token, false,
66        ));
67        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
68            self.token_owner,
69            false,
70        ));
71        accounts.push(solana_program::instruction::AccountMeta::new(
72            self.destination_token,
73            false,
74        ));
75        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
76            self.destination_owner,
77            false,
78        ));
79        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
80            self.mint, false,
81        ));
82        accounts.push(solana_program::instruction::AccountMeta::new(
83            self.metadata,
84            false,
85        ));
86        if let Some(edition) = self.edition {
87            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
88                edition, false,
89            ));
90        } else {
91            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
92                crate::MPL_TOKEN_METADATA_ID,
93                false,
94            ));
95        }
96        if let Some(token_record) = self.token_record {
97            accounts.push(solana_program::instruction::AccountMeta::new(
98                token_record,
99                false,
100            ));
101        } else {
102            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
103                crate::MPL_TOKEN_METADATA_ID,
104                false,
105            ));
106        }
107        if let Some(destination_token_record) = self.destination_token_record {
108            accounts.push(solana_program::instruction::AccountMeta::new(
109                destination_token_record,
110                false,
111            ));
112        } else {
113            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
114                crate::MPL_TOKEN_METADATA_ID,
115                false,
116            ));
117        }
118        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
119            self.authority,
120            true,
121        ));
122        accounts.push(solana_program::instruction::AccountMeta::new(
123            self.payer, true,
124        ));
125        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
126            self.system_program,
127            false,
128        ));
129        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
130            self.sysvar_instructions,
131            false,
132        ));
133        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
134            self.spl_token_program,
135            false,
136        ));
137        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
138            self.spl_ata_program,
139            false,
140        ));
141        if let Some(authorization_rules_program) = self.authorization_rules_program {
142            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
143                authorization_rules_program,
144                false,
145            ));
146        } else {
147            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
148                crate::MPL_TOKEN_METADATA_ID,
149                false,
150            ));
151        }
152        if let Some(authorization_rules) = self.authorization_rules {
153            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
154                authorization_rules,
155                false,
156            ));
157        } else {
158            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
159                crate::MPL_TOKEN_METADATA_ID,
160                false,
161            ));
162        }
163        accounts.extend_from_slice(remaining_accounts);
164        let mut data = TransferInstructionData::new().try_to_vec().unwrap();
165        let mut args = args.try_to_vec().unwrap();
166        data.append(&mut args);
167
168        solana_program::instruction::Instruction {
169            program_id: crate::MPL_TOKEN_METADATA_ID,
170            accounts,
171            data,
172        }
173    }
174}
175
176#[derive(BorshDeserialize, BorshSerialize)]
177struct TransferInstructionData {
178    discriminator: u8,
179}
180
181impl TransferInstructionData {
182    fn new() -> Self {
183        Self { discriminator: 49 }
184    }
185}
186
187#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
188#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
189pub struct TransferInstructionArgs {
190    pub transfer_args: TransferArgs,
191}
192
193/// Instruction builder for `Transfer`.
194///
195/// ### Accounts:
196///
197///   0. `[writable]` token
198///   1. `[]` token_owner
199///   2. `[writable]` destination_token
200///   3. `[]` destination_owner
201///   4. `[]` mint
202///   5. `[writable]` metadata
203///   6. `[optional]` edition
204///   7. `[writable, optional]` token_record
205///   8. `[writable, optional]` destination_token_record
206///   9. `[signer]` authority
207///   10. `[writable, signer]` payer
208///   11. `[optional]` system_program (default to `11111111111111111111111111111111`)
209///   12. `[optional]` sysvar_instructions (default to `Sysvar1nstructions1111111111111111111111111`)
210///   13. `[optional]` spl_token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`)
211///   14. `[optional]` spl_ata_program (default to `ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`)
212///   15. `[optional]` authorization_rules_program
213///   16. `[optional]` authorization_rules
214#[derive(Default)]
215pub struct TransferBuilder {
216    token: Option<solana_program::pubkey::Pubkey>,
217    token_owner: Option<solana_program::pubkey::Pubkey>,
218    destination_token: Option<solana_program::pubkey::Pubkey>,
219    destination_owner: Option<solana_program::pubkey::Pubkey>,
220    mint: Option<solana_program::pubkey::Pubkey>,
221    metadata: Option<solana_program::pubkey::Pubkey>,
222    edition: Option<solana_program::pubkey::Pubkey>,
223    token_record: Option<solana_program::pubkey::Pubkey>,
224    destination_token_record: Option<solana_program::pubkey::Pubkey>,
225    authority: Option<solana_program::pubkey::Pubkey>,
226    payer: Option<solana_program::pubkey::Pubkey>,
227    system_program: Option<solana_program::pubkey::Pubkey>,
228    sysvar_instructions: Option<solana_program::pubkey::Pubkey>,
229    spl_token_program: Option<solana_program::pubkey::Pubkey>,
230    spl_ata_program: Option<solana_program::pubkey::Pubkey>,
231    authorization_rules_program: Option<solana_program::pubkey::Pubkey>,
232    authorization_rules: Option<solana_program::pubkey::Pubkey>,
233    transfer_args: Option<TransferArgs>,
234    __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
235}
236
237impl TransferBuilder {
238    pub fn new() -> Self {
239        Self::default()
240    }
241    /// Token account
242    #[inline(always)]
243    pub fn token(&mut self, token: solana_program::pubkey::Pubkey) -> &mut Self {
244        self.token = Some(token);
245        self
246    }
247    /// Token account owner
248    #[inline(always)]
249    pub fn token_owner(&mut self, token_owner: solana_program::pubkey::Pubkey) -> &mut Self {
250        self.token_owner = Some(token_owner);
251        self
252    }
253    /// Destination token account
254    #[inline(always)]
255    pub fn destination_token(
256        &mut self,
257        destination_token: solana_program::pubkey::Pubkey,
258    ) -> &mut Self {
259        self.destination_token = Some(destination_token);
260        self
261    }
262    /// Destination token account owner
263    #[inline(always)]
264    pub fn destination_owner(
265        &mut self,
266        destination_owner: solana_program::pubkey::Pubkey,
267    ) -> &mut Self {
268        self.destination_owner = Some(destination_owner);
269        self
270    }
271    /// Mint of token asset
272    #[inline(always)]
273    pub fn mint(&mut self, mint: solana_program::pubkey::Pubkey) -> &mut Self {
274        self.mint = Some(mint);
275        self
276    }
277    /// Metadata (pda of ['metadata', program id, mint id])
278    #[inline(always)]
279    pub fn metadata(&mut self, metadata: solana_program::pubkey::Pubkey) -> &mut Self {
280        self.metadata = Some(metadata);
281        self
282    }
283    /// `[optional account]`
284    /// Edition of token asset
285    #[inline(always)]
286    pub fn edition(&mut self, edition: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
287        self.edition = edition;
288        self
289    }
290    /// `[optional account]`
291    /// Owner token record account
292    #[inline(always)]
293    pub fn token_record(
294        &mut self,
295        token_record: Option<solana_program::pubkey::Pubkey>,
296    ) -> &mut Self {
297        self.token_record = token_record;
298        self
299    }
300    /// `[optional account]`
301    /// Destination token record account
302    #[inline(always)]
303    pub fn destination_token_record(
304        &mut self,
305        destination_token_record: Option<solana_program::pubkey::Pubkey>,
306    ) -> &mut Self {
307        self.destination_token_record = destination_token_record;
308        self
309    }
310    /// Transfer authority (token owner or delegate)
311    #[inline(always)]
312    pub fn authority(&mut self, authority: solana_program::pubkey::Pubkey) -> &mut Self {
313        self.authority = Some(authority);
314        self
315    }
316    /// Payer
317    #[inline(always)]
318    pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
319        self.payer = Some(payer);
320        self
321    }
322    /// `[optional account, default to '11111111111111111111111111111111']`
323    /// System Program
324    #[inline(always)]
325    pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self {
326        self.system_program = Some(system_program);
327        self
328    }
329    /// `[optional account, default to 'Sysvar1nstructions1111111111111111111111111']`
330    /// Instructions sysvar account
331    #[inline(always)]
332    pub fn sysvar_instructions(
333        &mut self,
334        sysvar_instructions: solana_program::pubkey::Pubkey,
335    ) -> &mut Self {
336        self.sysvar_instructions = Some(sysvar_instructions);
337        self
338    }
339    /// `[optional account, default to 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA']`
340    /// SPL Token Program
341    #[inline(always)]
342    pub fn spl_token_program(
343        &mut self,
344        spl_token_program: solana_program::pubkey::Pubkey,
345    ) -> &mut Self {
346        self.spl_token_program = Some(spl_token_program);
347        self
348    }
349    /// `[optional account, default to 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL']`
350    /// SPL Associated Token Account program
351    #[inline(always)]
352    pub fn spl_ata_program(
353        &mut self,
354        spl_ata_program: solana_program::pubkey::Pubkey,
355    ) -> &mut Self {
356        self.spl_ata_program = Some(spl_ata_program);
357        self
358    }
359    /// `[optional account]`
360    /// Token Authorization Rules Program
361    #[inline(always)]
362    pub fn authorization_rules_program(
363        &mut self,
364        authorization_rules_program: Option<solana_program::pubkey::Pubkey>,
365    ) -> &mut Self {
366        self.authorization_rules_program = authorization_rules_program;
367        self
368    }
369    /// `[optional account]`
370    /// Token Authorization Rules account
371    #[inline(always)]
372    pub fn authorization_rules(
373        &mut self,
374        authorization_rules: Option<solana_program::pubkey::Pubkey>,
375    ) -> &mut Self {
376        self.authorization_rules = authorization_rules;
377        self
378    }
379    #[inline(always)]
380    pub fn transfer_args(&mut self, transfer_args: TransferArgs) -> &mut Self {
381        self.transfer_args = Some(transfer_args);
382        self
383    }
384    /// Add an aditional account to the instruction.
385    #[inline(always)]
386    pub fn add_remaining_account(
387        &mut self,
388        account: solana_program::instruction::AccountMeta,
389    ) -> &mut Self {
390        self.__remaining_accounts.push(account);
391        self
392    }
393    /// Add additional accounts to the instruction.
394    #[inline(always)]
395    pub fn add_remaining_accounts(
396        &mut self,
397        accounts: &[solana_program::instruction::AccountMeta],
398    ) -> &mut Self {
399        self.__remaining_accounts.extend_from_slice(accounts);
400        self
401    }
402    #[allow(clippy::clone_on_copy)]
403    pub fn instruction(&self) -> solana_program::instruction::Instruction {
404        let accounts = Transfer {
405            token: self.token.expect("token is not set"),
406            token_owner: self.token_owner.expect("token_owner is not set"),
407            destination_token: self
408                .destination_token
409                .expect("destination_token is not set"),
410            destination_owner: self
411                .destination_owner
412                .expect("destination_owner is not set"),
413            mint: self.mint.expect("mint is not set"),
414            metadata: self.metadata.expect("metadata is not set"),
415            edition: self.edition,
416            token_record: self.token_record,
417            destination_token_record: self.destination_token_record,
418            authority: self.authority.expect("authority is not set"),
419            payer: self.payer.expect("payer is not set"),
420            system_program: self
421                .system_program
422                .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")),
423            sysvar_instructions: self.sysvar_instructions.unwrap_or(solana_program::pubkey!(
424                "Sysvar1nstructions1111111111111111111111111"
425            )),
426            spl_token_program: self.spl_token_program.unwrap_or(solana_program::pubkey!(
427                "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
428            )),
429            spl_ata_program: self.spl_ata_program.unwrap_or(solana_program::pubkey!(
430                "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
431            )),
432            authorization_rules_program: self.authorization_rules_program,
433            authorization_rules: self.authorization_rules,
434        };
435        let args = TransferInstructionArgs {
436            transfer_args: self
437                .transfer_args
438                .clone()
439                .expect("transfer_args is not set"),
440        };
441
442        accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
443    }
444}
445
446/// `transfer` CPI accounts.
447pub struct TransferCpiAccounts<'a, 'b> {
448    /// Token account
449    pub token: &'b solana_program::account_info::AccountInfo<'a>,
450    /// Token account owner
451    pub token_owner: &'b solana_program::account_info::AccountInfo<'a>,
452    /// Destination token account
453    pub destination_token: &'b solana_program::account_info::AccountInfo<'a>,
454    /// Destination token account owner
455    pub destination_owner: &'b solana_program::account_info::AccountInfo<'a>,
456    /// Mint of token asset
457    pub mint: &'b solana_program::account_info::AccountInfo<'a>,
458    /// Metadata (pda of ['metadata', program id, mint id])
459    pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
460    /// Edition of token asset
461    pub edition: Option<&'b solana_program::account_info::AccountInfo<'a>>,
462    /// Owner token record account
463    pub token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
464    /// Destination token record account
465    pub destination_token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
466    /// Transfer authority (token owner or delegate)
467    pub authority: &'b solana_program::account_info::AccountInfo<'a>,
468    /// Payer
469    pub payer: &'b solana_program::account_info::AccountInfo<'a>,
470    /// System Program
471    pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
472    /// Instructions sysvar account
473    pub sysvar_instructions: &'b solana_program::account_info::AccountInfo<'a>,
474    /// SPL Token Program
475    pub spl_token_program: &'b solana_program::account_info::AccountInfo<'a>,
476    /// SPL Associated Token Account program
477    pub spl_ata_program: &'b solana_program::account_info::AccountInfo<'a>,
478    /// Token Authorization Rules Program
479    pub authorization_rules_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
480    /// Token Authorization Rules account
481    pub authorization_rules: Option<&'b solana_program::account_info::AccountInfo<'a>>,
482}
483
484/// `transfer` CPI instruction.
485pub struct TransferCpi<'a, 'b> {
486    /// The program to invoke.
487    pub __program: &'b solana_program::account_info::AccountInfo<'a>,
488    /// Token account
489    pub token: &'b solana_program::account_info::AccountInfo<'a>,
490    /// Token account owner
491    pub token_owner: &'b solana_program::account_info::AccountInfo<'a>,
492    /// Destination token account
493    pub destination_token: &'b solana_program::account_info::AccountInfo<'a>,
494    /// Destination token account owner
495    pub destination_owner: &'b solana_program::account_info::AccountInfo<'a>,
496    /// Mint of token asset
497    pub mint: &'b solana_program::account_info::AccountInfo<'a>,
498    /// Metadata (pda of ['metadata', program id, mint id])
499    pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
500    /// Edition of token asset
501    pub edition: Option<&'b solana_program::account_info::AccountInfo<'a>>,
502    /// Owner token record account
503    pub token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
504    /// Destination token record account
505    pub destination_token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
506    /// Transfer authority (token owner or delegate)
507    pub authority: &'b solana_program::account_info::AccountInfo<'a>,
508    /// Payer
509    pub payer: &'b solana_program::account_info::AccountInfo<'a>,
510    /// System Program
511    pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
512    /// Instructions sysvar account
513    pub sysvar_instructions: &'b solana_program::account_info::AccountInfo<'a>,
514    /// SPL Token Program
515    pub spl_token_program: &'b solana_program::account_info::AccountInfo<'a>,
516    /// SPL Associated Token Account program
517    pub spl_ata_program: &'b solana_program::account_info::AccountInfo<'a>,
518    /// Token Authorization Rules Program
519    pub authorization_rules_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
520    /// Token Authorization Rules account
521    pub authorization_rules: Option<&'b solana_program::account_info::AccountInfo<'a>>,
522    /// The arguments for the instruction.
523    pub __args: TransferInstructionArgs,
524}
525
526impl<'a, 'b> TransferCpi<'a, 'b> {
527    pub fn new(
528        program: &'b solana_program::account_info::AccountInfo<'a>,
529        accounts: TransferCpiAccounts<'a, 'b>,
530        args: TransferInstructionArgs,
531    ) -> Self {
532        Self {
533            __program: program,
534            token: accounts.token,
535            token_owner: accounts.token_owner,
536            destination_token: accounts.destination_token,
537            destination_owner: accounts.destination_owner,
538            mint: accounts.mint,
539            metadata: accounts.metadata,
540            edition: accounts.edition,
541            token_record: accounts.token_record,
542            destination_token_record: accounts.destination_token_record,
543            authority: accounts.authority,
544            payer: accounts.payer,
545            system_program: accounts.system_program,
546            sysvar_instructions: accounts.sysvar_instructions,
547            spl_token_program: accounts.spl_token_program,
548            spl_ata_program: accounts.spl_ata_program,
549            authorization_rules_program: accounts.authorization_rules_program,
550            authorization_rules: accounts.authorization_rules,
551            __args: args,
552        }
553    }
554    #[inline(always)]
555    pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
556        self.invoke_signed_with_remaining_accounts(&[], &[])
557    }
558    #[inline(always)]
559    pub fn invoke_with_remaining_accounts(
560        &self,
561        remaining_accounts: &[(
562            &'b solana_program::account_info::AccountInfo<'a>,
563            bool,
564            bool,
565        )],
566    ) -> solana_program::entrypoint::ProgramResult {
567        self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
568    }
569    #[inline(always)]
570    pub fn invoke_signed(
571        &self,
572        signers_seeds: &[&[&[u8]]],
573    ) -> solana_program::entrypoint::ProgramResult {
574        self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
575    }
576    #[allow(clippy::clone_on_copy)]
577    #[allow(clippy::vec_init_then_push)]
578    pub fn invoke_signed_with_remaining_accounts(
579        &self,
580        signers_seeds: &[&[&[u8]]],
581        remaining_accounts: &[(
582            &'b solana_program::account_info::AccountInfo<'a>,
583            bool,
584            bool,
585        )],
586    ) -> solana_program::entrypoint::ProgramResult {
587        let mut accounts = Vec::with_capacity(17 + remaining_accounts.len());
588        accounts.push(solana_program::instruction::AccountMeta::new(
589            *self.token.key,
590            false,
591        ));
592        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
593            *self.token_owner.key,
594            false,
595        ));
596        accounts.push(solana_program::instruction::AccountMeta::new(
597            *self.destination_token.key,
598            false,
599        ));
600        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
601            *self.destination_owner.key,
602            false,
603        ));
604        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
605            *self.mint.key,
606            false,
607        ));
608        accounts.push(solana_program::instruction::AccountMeta::new(
609            *self.metadata.key,
610            false,
611        ));
612        if let Some(edition) = self.edition {
613            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
614                *edition.key,
615                false,
616            ));
617        } else {
618            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
619                crate::MPL_TOKEN_METADATA_ID,
620                false,
621            ));
622        }
623        if let Some(token_record) = self.token_record {
624            accounts.push(solana_program::instruction::AccountMeta::new(
625                *token_record.key,
626                false,
627            ));
628        } else {
629            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
630                crate::MPL_TOKEN_METADATA_ID,
631                false,
632            ));
633        }
634        if let Some(destination_token_record) = self.destination_token_record {
635            accounts.push(solana_program::instruction::AccountMeta::new(
636                *destination_token_record.key,
637                false,
638            ));
639        } else {
640            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
641                crate::MPL_TOKEN_METADATA_ID,
642                false,
643            ));
644        }
645        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
646            *self.authority.key,
647            true,
648        ));
649        accounts.push(solana_program::instruction::AccountMeta::new(
650            *self.payer.key,
651            true,
652        ));
653        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
654            *self.system_program.key,
655            false,
656        ));
657        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
658            *self.sysvar_instructions.key,
659            false,
660        ));
661        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
662            *self.spl_token_program.key,
663            false,
664        ));
665        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
666            *self.spl_ata_program.key,
667            false,
668        ));
669        if let Some(authorization_rules_program) = self.authorization_rules_program {
670            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
671                *authorization_rules_program.key,
672                false,
673            ));
674        } else {
675            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
676                crate::MPL_TOKEN_METADATA_ID,
677                false,
678            ));
679        }
680        if let Some(authorization_rules) = self.authorization_rules {
681            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
682                *authorization_rules.key,
683                false,
684            ));
685        } else {
686            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
687                crate::MPL_TOKEN_METADATA_ID,
688                false,
689            ));
690        }
691        remaining_accounts.iter().for_each(|remaining_account| {
692            accounts.push(solana_program::instruction::AccountMeta {
693                pubkey: *remaining_account.0.key,
694                is_signer: remaining_account.1,
695                is_writable: remaining_account.2,
696            })
697        });
698        let mut data = TransferInstructionData::new().try_to_vec().unwrap();
699        let mut args = self.__args.try_to_vec().unwrap();
700        data.append(&mut args);
701
702        let instruction = solana_program::instruction::Instruction {
703            program_id: crate::MPL_TOKEN_METADATA_ID,
704            accounts,
705            data,
706        };
707        let mut account_infos = Vec::with_capacity(17 + 1 + remaining_accounts.len());
708        account_infos.push(self.__program.clone());
709        account_infos.push(self.token.clone());
710        account_infos.push(self.token_owner.clone());
711        account_infos.push(self.destination_token.clone());
712        account_infos.push(self.destination_owner.clone());
713        account_infos.push(self.mint.clone());
714        account_infos.push(self.metadata.clone());
715        if let Some(edition) = self.edition {
716            account_infos.push(edition.clone());
717        }
718        if let Some(token_record) = self.token_record {
719            account_infos.push(token_record.clone());
720        }
721        if let Some(destination_token_record) = self.destination_token_record {
722            account_infos.push(destination_token_record.clone());
723        }
724        account_infos.push(self.authority.clone());
725        account_infos.push(self.payer.clone());
726        account_infos.push(self.system_program.clone());
727        account_infos.push(self.sysvar_instructions.clone());
728        account_infos.push(self.spl_token_program.clone());
729        account_infos.push(self.spl_ata_program.clone());
730        if let Some(authorization_rules_program) = self.authorization_rules_program {
731            account_infos.push(authorization_rules_program.clone());
732        }
733        if let Some(authorization_rules) = self.authorization_rules {
734            account_infos.push(authorization_rules.clone());
735        }
736        remaining_accounts
737            .iter()
738            .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
739
740        if signers_seeds.is_empty() {
741            solana_program::program::invoke(&instruction, &account_infos)
742        } else {
743            solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
744        }
745    }
746}
747
748/// Instruction builder for `Transfer` via CPI.
749///
750/// ### Accounts:
751///
752///   0. `[writable]` token
753///   1. `[]` token_owner
754///   2. `[writable]` destination_token
755///   3. `[]` destination_owner
756///   4. `[]` mint
757///   5. `[writable]` metadata
758///   6. `[optional]` edition
759///   7. `[writable, optional]` token_record
760///   8. `[writable, optional]` destination_token_record
761///   9. `[signer]` authority
762///   10. `[writable, signer]` payer
763///   11. `[]` system_program
764///   12. `[]` sysvar_instructions
765///   13. `[]` spl_token_program
766///   14. `[]` spl_ata_program
767///   15. `[optional]` authorization_rules_program
768///   16. `[optional]` authorization_rules
769pub struct TransferCpiBuilder<'a, 'b> {
770    instruction: Box<TransferCpiBuilderInstruction<'a, 'b>>,
771}
772
773impl<'a, 'b> TransferCpiBuilder<'a, 'b> {
774    pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
775        let instruction = Box::new(TransferCpiBuilderInstruction {
776            __program: program,
777            token: None,
778            token_owner: None,
779            destination_token: None,
780            destination_owner: None,
781            mint: None,
782            metadata: None,
783            edition: None,
784            token_record: None,
785            destination_token_record: None,
786            authority: None,
787            payer: None,
788            system_program: None,
789            sysvar_instructions: None,
790            spl_token_program: None,
791            spl_ata_program: None,
792            authorization_rules_program: None,
793            authorization_rules: None,
794            transfer_args: None,
795            __remaining_accounts: Vec::new(),
796        });
797        Self { instruction }
798    }
799    /// Token account
800    #[inline(always)]
801    pub fn token(&mut self, token: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
802        self.instruction.token = Some(token);
803        self
804    }
805    /// Token account owner
806    #[inline(always)]
807    pub fn token_owner(
808        &mut self,
809        token_owner: &'b solana_program::account_info::AccountInfo<'a>,
810    ) -> &mut Self {
811        self.instruction.token_owner = Some(token_owner);
812        self
813    }
814    /// Destination token account
815    #[inline(always)]
816    pub fn destination_token(
817        &mut self,
818        destination_token: &'b solana_program::account_info::AccountInfo<'a>,
819    ) -> &mut Self {
820        self.instruction.destination_token = Some(destination_token);
821        self
822    }
823    /// Destination token account owner
824    #[inline(always)]
825    pub fn destination_owner(
826        &mut self,
827        destination_owner: &'b solana_program::account_info::AccountInfo<'a>,
828    ) -> &mut Self {
829        self.instruction.destination_owner = Some(destination_owner);
830        self
831    }
832    /// Mint of token asset
833    #[inline(always)]
834    pub fn mint(&mut self, mint: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
835        self.instruction.mint = Some(mint);
836        self
837    }
838    /// Metadata (pda of ['metadata', program id, mint id])
839    #[inline(always)]
840    pub fn metadata(
841        &mut self,
842        metadata: &'b solana_program::account_info::AccountInfo<'a>,
843    ) -> &mut Self {
844        self.instruction.metadata = Some(metadata);
845        self
846    }
847    /// `[optional account]`
848    /// Edition of token asset
849    #[inline(always)]
850    pub fn edition(
851        &mut self,
852        edition: Option<&'b solana_program::account_info::AccountInfo<'a>>,
853    ) -> &mut Self {
854        self.instruction.edition = edition;
855        self
856    }
857    /// `[optional account]`
858    /// Owner token record account
859    #[inline(always)]
860    pub fn token_record(
861        &mut self,
862        token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
863    ) -> &mut Self {
864        self.instruction.token_record = token_record;
865        self
866    }
867    /// `[optional account]`
868    /// Destination token record account
869    #[inline(always)]
870    pub fn destination_token_record(
871        &mut self,
872        destination_token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
873    ) -> &mut Self {
874        self.instruction.destination_token_record = destination_token_record;
875        self
876    }
877    /// Transfer authority (token owner or delegate)
878    #[inline(always)]
879    pub fn authority(
880        &mut self,
881        authority: &'b solana_program::account_info::AccountInfo<'a>,
882    ) -> &mut Self {
883        self.instruction.authority = Some(authority);
884        self
885    }
886    /// Payer
887    #[inline(always)]
888    pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
889        self.instruction.payer = Some(payer);
890        self
891    }
892    /// System Program
893    #[inline(always)]
894    pub fn system_program(
895        &mut self,
896        system_program: &'b solana_program::account_info::AccountInfo<'a>,
897    ) -> &mut Self {
898        self.instruction.system_program = Some(system_program);
899        self
900    }
901    /// Instructions sysvar account
902    #[inline(always)]
903    pub fn sysvar_instructions(
904        &mut self,
905        sysvar_instructions: &'b solana_program::account_info::AccountInfo<'a>,
906    ) -> &mut Self {
907        self.instruction.sysvar_instructions = Some(sysvar_instructions);
908        self
909    }
910    /// SPL Token Program
911    #[inline(always)]
912    pub fn spl_token_program(
913        &mut self,
914        spl_token_program: &'b solana_program::account_info::AccountInfo<'a>,
915    ) -> &mut Self {
916        self.instruction.spl_token_program = Some(spl_token_program);
917        self
918    }
919    /// SPL Associated Token Account program
920    #[inline(always)]
921    pub fn spl_ata_program(
922        &mut self,
923        spl_ata_program: &'b solana_program::account_info::AccountInfo<'a>,
924    ) -> &mut Self {
925        self.instruction.spl_ata_program = Some(spl_ata_program);
926        self
927    }
928    /// `[optional account]`
929    /// Token Authorization Rules Program
930    #[inline(always)]
931    pub fn authorization_rules_program(
932        &mut self,
933        authorization_rules_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
934    ) -> &mut Self {
935        self.instruction.authorization_rules_program = authorization_rules_program;
936        self
937    }
938    /// `[optional account]`
939    /// Token Authorization Rules account
940    #[inline(always)]
941    pub fn authorization_rules(
942        &mut self,
943        authorization_rules: Option<&'b solana_program::account_info::AccountInfo<'a>>,
944    ) -> &mut Self {
945        self.instruction.authorization_rules = authorization_rules;
946        self
947    }
948    #[inline(always)]
949    pub fn transfer_args(&mut self, transfer_args: TransferArgs) -> &mut Self {
950        self.instruction.transfer_args = Some(transfer_args);
951        self
952    }
953    /// Add an additional account to the instruction.
954    #[inline(always)]
955    pub fn add_remaining_account(
956        &mut self,
957        account: &'b solana_program::account_info::AccountInfo<'a>,
958        is_writable: bool,
959        is_signer: bool,
960    ) -> &mut Self {
961        self.instruction
962            .__remaining_accounts
963            .push((account, is_writable, is_signer));
964        self
965    }
966    /// Add additional accounts to the instruction.
967    ///
968    /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not,
969    /// and a `bool` indicating whether the account is a signer or not.
970    #[inline(always)]
971    pub fn add_remaining_accounts(
972        &mut self,
973        accounts: &[(
974            &'b solana_program::account_info::AccountInfo<'a>,
975            bool,
976            bool,
977        )],
978    ) -> &mut Self {
979        self.instruction
980            .__remaining_accounts
981            .extend_from_slice(accounts);
982        self
983    }
984    #[inline(always)]
985    pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
986        self.invoke_signed(&[])
987    }
988    #[allow(clippy::clone_on_copy)]
989    #[allow(clippy::vec_init_then_push)]
990    pub fn invoke_signed(
991        &self,
992        signers_seeds: &[&[&[u8]]],
993    ) -> solana_program::entrypoint::ProgramResult {
994        let args = TransferInstructionArgs {
995            transfer_args: self
996                .instruction
997                .transfer_args
998                .clone()
999                .expect("transfer_args is not set"),
1000        };
1001        let instruction = TransferCpi {
1002            __program: self.instruction.__program,
1003
1004            token: self.instruction.token.expect("token is not set"),
1005
1006            token_owner: self
1007                .instruction
1008                .token_owner
1009                .expect("token_owner is not set"),
1010
1011            destination_token: self
1012                .instruction
1013                .destination_token
1014                .expect("destination_token is not set"),
1015
1016            destination_owner: self
1017                .instruction
1018                .destination_owner
1019                .expect("destination_owner is not set"),
1020
1021            mint: self.instruction.mint.expect("mint is not set"),
1022
1023            metadata: self.instruction.metadata.expect("metadata is not set"),
1024
1025            edition: self.instruction.edition,
1026
1027            token_record: self.instruction.token_record,
1028
1029            destination_token_record: self.instruction.destination_token_record,
1030
1031            authority: self.instruction.authority.expect("authority is not set"),
1032
1033            payer: self.instruction.payer.expect("payer is not set"),
1034
1035            system_program: self
1036                .instruction
1037                .system_program
1038                .expect("system_program is not set"),
1039
1040            sysvar_instructions: self
1041                .instruction
1042                .sysvar_instructions
1043                .expect("sysvar_instructions is not set"),
1044
1045            spl_token_program: self
1046                .instruction
1047                .spl_token_program
1048                .expect("spl_token_program is not set"),
1049
1050            spl_ata_program: self
1051                .instruction
1052                .spl_ata_program
1053                .expect("spl_ata_program is not set"),
1054
1055            authorization_rules_program: self.instruction.authorization_rules_program,
1056
1057            authorization_rules: self.instruction.authorization_rules,
1058            __args: args,
1059        };
1060        instruction.invoke_signed_with_remaining_accounts(
1061            signers_seeds,
1062            &self.instruction.__remaining_accounts,
1063        )
1064    }
1065}
1066
1067struct TransferCpiBuilderInstruction<'a, 'b> {
1068    __program: &'b solana_program::account_info::AccountInfo<'a>,
1069    token: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1070    token_owner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1071    destination_token: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1072    destination_owner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1073    mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1074    metadata: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1075    edition: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1076    token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1077    destination_token_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1078    authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1079    payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1080    system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1081    sysvar_instructions: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1082    spl_token_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1083    spl_ata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1084    authorization_rules_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1085    authorization_rules: Option<&'b solana_program::account_info::AccountInfo<'a>>,
1086    transfer_args: Option<TransferArgs>,
1087    /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`.
1088    __remaining_accounts: Vec<(
1089        &'b solana_program::account_info::AccountInfo<'a>,
1090        bool,
1091        bool,
1092    )>,
1093}