nifty_asset_interface/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 borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10
11/// Accounts.
12pub struct Transfer {
13    /// Asset account
14    pub asset: solana_program::pubkey::Pubkey,
15    /// Current owner of the asset or transfer delegate
16    pub signer: solana_program::pubkey::Pubkey,
17    /// The recipient of the asset
18    pub recipient: solana_program::pubkey::Pubkey,
19    /// The asset defining the group, if applicable
20    pub group: Option<solana_program::pubkey::Pubkey>,
21}
22
23impl Transfer {
24    pub fn instruction(&self) -> solana_program::instruction::Instruction {
25        self.instruction_with_remaining_accounts(&[])
26    }
27    #[allow(clippy::vec_init_then_push)]
28    pub fn instruction_with_remaining_accounts(
29        &self,
30        remaining_accounts: &[solana_program::instruction::AccountMeta],
31    ) -> solana_program::instruction::Instruction {
32        let mut accounts = Vec::with_capacity(4 + remaining_accounts.len());
33        accounts.push(solana_program::instruction::AccountMeta::new(
34            self.asset, true,
35        ));
36        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
37            self.signer,
38            true,
39        ));
40        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
41            self.recipient,
42            false,
43        ));
44        if let Some(group) = self.group {
45            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
46                group, false,
47            ));
48        } else {
49            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
50                crate::INTERFACE_ID,
51                false,
52            ));
53        }
54        accounts.extend_from_slice(remaining_accounts);
55        let data = TransferInstructionData::new().try_to_vec().unwrap();
56
57        solana_program::instruction::Instruction {
58            program_id: crate::INTERFACE_ID,
59            accounts,
60            data,
61        }
62    }
63}
64
65#[derive(BorshDeserialize, BorshSerialize)]
66struct TransferInstructionData {
67    discriminator: u8,
68}
69
70impl TransferInstructionData {
71    fn new() -> Self {
72        Self { discriminator: 7 }
73    }
74}
75
76/// Instruction builder for `Transfer`.
77///
78/// ### Accounts:
79///
80///   0. `[writable, signer]` asset
81///   1. `[signer]` signer
82///   2. `[]` recipient
83///   3. `[optional]` group
84#[derive(Default)]
85pub struct TransferBuilder {
86    asset: Option<solana_program::pubkey::Pubkey>,
87    signer: Option<solana_program::pubkey::Pubkey>,
88    recipient: Option<solana_program::pubkey::Pubkey>,
89    group: Option<solana_program::pubkey::Pubkey>,
90    __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
91}
92
93impl TransferBuilder {
94    pub fn new() -> Self {
95        Self::default()
96    }
97    /// Asset account
98    #[inline(always)]
99    pub fn asset(&mut self, asset: solana_program::pubkey::Pubkey) -> &mut Self {
100        self.asset = Some(asset);
101        self
102    }
103    /// Current owner of the asset or transfer delegate
104    #[inline(always)]
105    pub fn signer(&mut self, signer: solana_program::pubkey::Pubkey) -> &mut Self {
106        self.signer = Some(signer);
107        self
108    }
109    /// The recipient of the asset
110    #[inline(always)]
111    pub fn recipient(&mut self, recipient: solana_program::pubkey::Pubkey) -> &mut Self {
112        self.recipient = Some(recipient);
113        self
114    }
115    /// `[optional account]`
116    /// The asset defining the group, if applicable
117    #[inline(always)]
118    pub fn group(&mut self, group: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
119        self.group = group;
120        self
121    }
122    /// Add an aditional account to the instruction.
123    #[inline(always)]
124    pub fn add_remaining_account(
125        &mut self,
126        account: solana_program::instruction::AccountMeta,
127    ) -> &mut Self {
128        self.__remaining_accounts.push(account);
129        self
130    }
131    /// Add additional accounts to the instruction.
132    #[inline(always)]
133    pub fn add_remaining_accounts(
134        &mut self,
135        accounts: &[solana_program::instruction::AccountMeta],
136    ) -> &mut Self {
137        self.__remaining_accounts.extend_from_slice(accounts);
138        self
139    }
140    #[allow(clippy::clone_on_copy)]
141    pub fn instruction(&self) -> solana_program::instruction::Instruction {
142        let accounts = Transfer {
143            asset: self.asset.expect("asset is not set"),
144            signer: self.signer.expect("signer is not set"),
145            recipient: self.recipient.expect("recipient is not set"),
146            group: self.group,
147        };
148
149        accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
150    }
151}
152
153/// `transfer` CPI accounts.
154pub struct TransferCpiAccounts<'a, 'b> {
155    /// Asset account
156    pub asset: &'b solana_program::account_info::AccountInfo<'a>,
157    /// Current owner of the asset or transfer delegate
158    pub signer: &'b solana_program::account_info::AccountInfo<'a>,
159    /// The recipient of the asset
160    pub recipient: &'b solana_program::account_info::AccountInfo<'a>,
161    /// The asset defining the group, if applicable
162    pub group: Option<&'b solana_program::account_info::AccountInfo<'a>>,
163}
164
165/// `transfer` CPI instruction.
166pub struct TransferCpi<'a, 'b> {
167    /// The program to invoke.
168    pub __program: &'b solana_program::account_info::AccountInfo<'a>,
169    /// Asset account
170    pub asset: &'b solana_program::account_info::AccountInfo<'a>,
171    /// Current owner of the asset or transfer delegate
172    pub signer: &'b solana_program::account_info::AccountInfo<'a>,
173    /// The recipient of the asset
174    pub recipient: &'b solana_program::account_info::AccountInfo<'a>,
175    /// The asset defining the group, if applicable
176    pub group: Option<&'b solana_program::account_info::AccountInfo<'a>>,
177}
178
179impl<'a, 'b> TransferCpi<'a, 'b> {
180    pub fn new(
181        program: &'b solana_program::account_info::AccountInfo<'a>,
182        accounts: TransferCpiAccounts<'a, 'b>,
183    ) -> Self {
184        Self {
185            __program: program,
186            asset: accounts.asset,
187            signer: accounts.signer,
188            recipient: accounts.recipient,
189            group: accounts.group,
190        }
191    }
192    #[inline(always)]
193    pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
194        self.invoke_signed_with_remaining_accounts(&[], &[])
195    }
196    #[inline(always)]
197    pub fn invoke_with_remaining_accounts(
198        &self,
199        remaining_accounts: &[(
200            &'b solana_program::account_info::AccountInfo<'a>,
201            bool,
202            bool,
203        )],
204    ) -> solana_program::entrypoint::ProgramResult {
205        self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
206    }
207    #[inline(always)]
208    pub fn invoke_signed(
209        &self,
210        signers_seeds: &[&[&[u8]]],
211    ) -> solana_program::entrypoint::ProgramResult {
212        self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
213    }
214    #[allow(clippy::clone_on_copy)]
215    #[allow(clippy::vec_init_then_push)]
216    pub fn invoke_signed_with_remaining_accounts(
217        &self,
218        signers_seeds: &[&[&[u8]]],
219        remaining_accounts: &[(
220            &'b solana_program::account_info::AccountInfo<'a>,
221            bool,
222            bool,
223        )],
224    ) -> solana_program::entrypoint::ProgramResult {
225        let mut accounts = Vec::with_capacity(4 + remaining_accounts.len());
226        accounts.push(solana_program::instruction::AccountMeta::new(
227            *self.asset.key,
228            true,
229        ));
230        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
231            *self.signer.key,
232            true,
233        ));
234        accounts.push(solana_program::instruction::AccountMeta::new_readonly(
235            *self.recipient.key,
236            false,
237        ));
238        if let Some(group) = self.group {
239            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
240                *group.key, false,
241            ));
242        } else {
243            accounts.push(solana_program::instruction::AccountMeta::new_readonly(
244                crate::INTERFACE_ID,
245                false,
246            ));
247        }
248        remaining_accounts.iter().for_each(|remaining_account| {
249            accounts.push(solana_program::instruction::AccountMeta {
250                pubkey: *remaining_account.0.key,
251                is_signer: remaining_account.1,
252                is_writable: remaining_account.2,
253            })
254        });
255        let data = TransferInstructionData::new().try_to_vec().unwrap();
256
257        let instruction = solana_program::instruction::Instruction {
258            program_id: crate::INTERFACE_ID,
259            accounts,
260            data,
261        };
262        let mut account_infos = Vec::with_capacity(4 + 1 + remaining_accounts.len());
263        account_infos.push(self.__program.clone());
264        account_infos.push(self.asset.clone());
265        account_infos.push(self.signer.clone());
266        account_infos.push(self.recipient.clone());
267        if let Some(group) = self.group {
268            account_infos.push(group.clone());
269        }
270        remaining_accounts
271            .iter()
272            .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
273
274        if signers_seeds.is_empty() {
275            solana_program::program::invoke(&instruction, &account_infos)
276        } else {
277            solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
278        }
279    }
280}
281
282/// Instruction builder for `Transfer` via CPI.
283///
284/// ### Accounts:
285///
286///   0. `[writable, signer]` asset
287///   1. `[signer]` signer
288///   2. `[]` recipient
289///   3. `[optional]` group
290pub struct TransferCpiBuilder<'a, 'b> {
291    instruction: Box<TransferCpiBuilderInstruction<'a, 'b>>,
292}
293
294impl<'a, 'b> TransferCpiBuilder<'a, 'b> {
295    pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
296        let instruction = Box::new(TransferCpiBuilderInstruction {
297            __program: program,
298            asset: None,
299            signer: None,
300            recipient: None,
301            group: None,
302            __remaining_accounts: Vec::new(),
303        });
304        Self { instruction }
305    }
306    /// Asset account
307    #[inline(always)]
308    pub fn asset(&mut self, asset: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
309        self.instruction.asset = Some(asset);
310        self
311    }
312    /// Current owner of the asset or transfer delegate
313    #[inline(always)]
314    pub fn signer(
315        &mut self,
316        signer: &'b solana_program::account_info::AccountInfo<'a>,
317    ) -> &mut Self {
318        self.instruction.signer = Some(signer);
319        self
320    }
321    /// The recipient of the asset
322    #[inline(always)]
323    pub fn recipient(
324        &mut self,
325        recipient: &'b solana_program::account_info::AccountInfo<'a>,
326    ) -> &mut Self {
327        self.instruction.recipient = Some(recipient);
328        self
329    }
330    /// `[optional account]`
331    /// The asset defining the group, if applicable
332    #[inline(always)]
333    pub fn group(
334        &mut self,
335        group: Option<&'b solana_program::account_info::AccountInfo<'a>>,
336    ) -> &mut Self {
337        self.instruction.group = group;
338        self
339    }
340    /// Add an additional account to the instruction.
341    #[inline(always)]
342    pub fn add_remaining_account(
343        &mut self,
344        account: &'b solana_program::account_info::AccountInfo<'a>,
345        is_writable: bool,
346        is_signer: bool,
347    ) -> &mut Self {
348        self.instruction
349            .__remaining_accounts
350            .push((account, is_writable, is_signer));
351        self
352    }
353    /// Add additional accounts to the instruction.
354    ///
355    /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not,
356    /// and a `bool` indicating whether the account is a signer or not.
357    #[inline(always)]
358    pub fn add_remaining_accounts(
359        &mut self,
360        accounts: &[(
361            &'b solana_program::account_info::AccountInfo<'a>,
362            bool,
363            bool,
364        )],
365    ) -> &mut Self {
366        self.instruction
367            .__remaining_accounts
368            .extend_from_slice(accounts);
369        self
370    }
371    #[inline(always)]
372    pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
373        self.invoke_signed(&[])
374    }
375    #[allow(clippy::clone_on_copy)]
376    #[allow(clippy::vec_init_then_push)]
377    pub fn invoke_signed(
378        &self,
379        signers_seeds: &[&[&[u8]]],
380    ) -> solana_program::entrypoint::ProgramResult {
381        let instruction = TransferCpi {
382            __program: self.instruction.__program,
383
384            asset: self.instruction.asset.expect("asset is not set"),
385
386            signer: self.instruction.signer.expect("signer is not set"),
387
388            recipient: self.instruction.recipient.expect("recipient is not set"),
389
390            group: self.instruction.group,
391        };
392        instruction.invoke_signed_with_remaining_accounts(
393            signers_seeds,
394            &self.instruction.__remaining_accounts,
395        )
396    }
397}
398
399struct TransferCpiBuilderInstruction<'a, 'b> {
400    __program: &'b solana_program::account_info::AccountInfo<'a>,
401    asset: Option<&'b solana_program::account_info::AccountInfo<'a>>,
402    signer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
403    recipient: Option<&'b solana_program::account_info::AccountInfo<'a>>,
404    group: Option<&'b solana_program::account_info::AccountInfo<'a>>,
405    /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`.
406    __remaining_accounts: Vec<(
407        &'b solana_program::account_info::AccountInfo<'a>,
408        bool,
409        bool,
410    )>,
411}