Skip to main content

sealevel_tools/cpi/ata_program/
create.rs

1use crate::{
2    account::ata::ID,
3    cpi::{CpiAuthority, CpiInstruction},
4    entrypoint::NoStdAccountInfo,
5    pubkey::Pubkey,
6};
7
8/// Arguments for the create instruction on an Associated Token Account program, which creates a
9/// token account with an address seeded by its owner and mint.
10#[derive(Clone, PartialEq, Eq)]
11pub struct Create<'a, 'b: 'a> {
12    /// If your program interacts with a fork of the official ATA program, provide the ID here.
13    /// Otherwise, the official ATA program ID will be used by default for CPI.
14    pub ata_program_id: Option<&'a Pubkey>,
15
16    pub payer: CpiAuthority<'a, 'b>,
17    pub associated_account: &'b NoStdAccountInfo,
18    pub account_owner: &'b NoStdAccountInfo,
19    pub mint: &'b NoStdAccountInfo,
20    pub system_program: &'b NoStdAccountInfo,
21    pub token_program: &'b NoStdAccountInfo,
22    pub idempotent: bool,
23}
24
25impl<'a, 'b: 'a> Create<'a, 'b> {
26    /// Consume arguments to perform CPI call.
27    #[inline(always)]
28    pub fn into_invoke(self) {
29        if self.idempotent {
30            // Create idempotent selector == 1.
31            self._into_invoke(&[1]);
32        } else {
33            // Empty data for create.
34            self._into_invoke(&[]);
35        }
36    }
37
38    #[inline(always)]
39    fn _into_invoke(self, data: &[u8]) {
40        let Self {
41            ata_program_id,
42            payer,
43            associated_account,
44            account_owner,
45            mint,
46            system_program,
47            token_program,
48            idempotent: _,
49        } = self;
50
51        CpiInstruction {
52            program_id: ata_program_id.unwrap_or(&ID),
53            accounts: &[
54                payer.to_meta_c_signer(),
55                associated_account.to_meta_c(),
56                account_owner.to_meta_c(),
57                mint.to_meta_c(),
58                system_program.to_meta_c(),
59                token_program.to_meta_c(),
60            ],
61            data,
62        }
63        .invoke_possibly_signed(
64            &[
65                payer.to_info_c(),
66                associated_account.to_info_c(),
67                account_owner.to_info_c(),
68                mint.to_info_c(),
69                system_program.to_info_c(),
70                token_program.to_info_c(),
71            ],
72            &[payer.signer_seeds],
73        );
74    }
75}