Skip to main content

name_tokenizer/
cpi.rs

1use solana_program::{
2    account_info::AccountInfo, entrypoint::ProgramResult, msg, program::invoke_signed,
3    program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, rent::Rent,
4    system_instruction, system_instruction::create_account, sysvar::Sysvar,
5};
6
7#[allow(missing_docs)]
8pub struct Cpi {}
9
10impl Cpi {
11    #[allow(missing_docs)]
12    pub fn create_account<'a>(
13        program_id: &Pubkey,
14        system_program: &AccountInfo<'a>,
15        fee_payer: &AccountInfo<'a>,
16        account_to_create: &AccountInfo<'a>,
17        signer_seeds: &[&[u8]],
18        space: usize,
19    ) -> ProgramResult {
20        let account_lamports = account_to_create.lamports();
21        if account_lamports != 0 && account_to_create.data_is_empty() {
22            let defund_created_account = system_instruction::transfer(
23                account_to_create.key,
24                fee_payer.key,
25                account_lamports,
26            );
27            invoke_signed(
28                &defund_created_account,
29                &[
30                    system_program.clone(),
31                    fee_payer.clone(),
32                    account_to_create.clone(),
33                ],
34                &[signer_seeds],
35            )?;
36        }
37        let create_state_instruction = create_account(
38            fee_payer.key,
39            account_to_create.key,
40            Rent::get()?.minimum_balance(space),
41            space as u64,
42            program_id,
43        );
44
45        invoke_signed(
46            &create_state_instruction,
47            &[
48                system_program.clone(),
49                fee_payer.clone(),
50                account_to_create.clone(),
51            ],
52            &[signer_seeds],
53        )
54    }
55
56    #[allow(clippy::too_many_arguments)]
57    pub fn allocate_and_create_token_account<'a>(
58        token_account_owner: &Pubkey,
59        spl_token_program: &AccountInfo<'a>,
60        payer_info: &AccountInfo<'a>,
61        signer_seeds: &[&[u8]],
62        token_account: &AccountInfo<'a>,
63        mint_account: &AccountInfo<'a>,
64        rent_account: &AccountInfo<'a>,
65        system_program_info: &AccountInfo<'a>,
66    ) -> Result<(), ProgramError> {
67        msg!("Initializing token account");
68        let size = spl_token::state::Account::LEN;
69        let required_lamports = Rent::get()?.minimum_balance(size);
70        let ix_allocate = create_account(
71            payer_info.key,
72            token_account.key,
73            required_lamports,
74            size as u64,
75            &spl_token::ID,
76        );
77        invoke_signed(
78            &ix_allocate,
79            &[
80                system_program_info.clone(),
81                payer_info.clone(),
82                token_account.clone(),
83            ],
84            &[signer_seeds],
85        )?;
86        let ix_initialize = spl_token::instruction::initialize_account2(
87            &spl_token::ID,
88            token_account.key,
89            mint_account.key,
90            token_account_owner,
91        )?;
92        invoke_signed(
93            &ix_initialize,
94            &[
95                spl_token_program.clone(),
96                token_account.clone(),
97                mint_account.clone(),
98                rent_account.clone(),
99            ],
100            &[signer_seeds],
101        )?;
102        Ok(())
103    }
104}