ore_utils/
cpi.rs

1use solana_program::{
2    account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey, rent::Rent,
3    sysvar::Sysvar,
4};
5
6/// Creates a new pda.
7#[inline(always)]
8pub fn create_pda<'a, 'info>(
9    target_account: &'a AccountInfo<'info>,
10    owner: &Pubkey,
11    space: usize,
12    pda_seeds: &[&[u8]],
13    system_program: &'a AccountInfo<'info>,
14    payer: &'a AccountInfo<'info>,
15) -> ProgramResult {
16    let rent = Rent::get()?;
17    if target_account.lamports().eq(&0) {
18        // If balance is zero, create account
19        solana_program::program::invoke_signed(
20            &solana_program::system_instruction::create_account(
21                payer.key,
22                target_account.key,
23                rent.minimum_balance(space),
24                space as u64,
25                owner,
26            ),
27            &[
28                payer.clone(),
29                target_account.clone(),
30                system_program.clone(),
31            ],
32            &[pda_seeds],
33        )?;
34    } else {
35        // Otherwise, if balance is nonzero:
36
37        // 1) transfer sufficient lamports for rent exemption
38        let rent_exempt_balance = rent
39            .minimum_balance(space)
40            .saturating_sub(target_account.lamports());
41        if rent_exempt_balance.gt(&0) {
42            solana_program::program::invoke(
43                &solana_program::system_instruction::transfer(
44                    payer.key,
45                    target_account.key,
46                    rent_exempt_balance,
47                ),
48                &[
49                    payer.clone(),
50                    target_account.clone(),
51                    system_program.clone(),
52                ],
53            )?;
54        }
55
56        // 2) allocate space for the account
57        solana_program::program::invoke_signed(
58            &solana_program::system_instruction::allocate(target_account.key, space as u64),
59            &[target_account.clone(), system_program.clone()],
60            &[pda_seeds],
61        )?;
62
63        // 3) assign our program as the owner
64        solana_program::program::invoke_signed(
65            &solana_program::system_instruction::assign(target_account.key, owner),
66            &[target_account.clone(), system_program.clone()],
67            &[pda_seeds],
68        )?;
69    }
70
71    Ok(())
72}
73
74#[cfg(feature = "spl")]
75#[inline(always)]
76pub fn create_ata<'info>(
77    funder_info: &AccountInfo<'info>,
78    owner_info: &AccountInfo<'info>,
79    token_account_info: &AccountInfo<'info>,
80    mint_info: &AccountInfo<'info>,
81    system_program: &AccountInfo<'info>,
82    token_program: &AccountInfo<'info>,
83    associated_token_program: &AccountInfo<'info>,
84) -> ProgramResult {
85    solana_program::program::invoke(
86        &spl_associated_token_account::instruction::create_associated_token_account(
87            funder_info.key,
88            owner_info.key,
89            mint_info.key,
90            &spl_token::id(),
91        ),
92        &[
93            funder_info.clone(),
94            token_account_info.clone(),
95            owner_info.clone(),
96            mint_info.clone(),
97            system_program.clone(),
98            token_program.clone(),
99            associated_token_program.clone(),
100        ],
101    )
102}
103
104#[cfg(feature = "spl")]
105#[inline(always)]
106pub fn transfer<'info>(
107    authority_info: &AccountInfo<'info>,
108    from_info: &AccountInfo<'info>,
109    to_info: &AccountInfo<'info>,
110    token_program: &AccountInfo<'info>,
111    amount: u64,
112) -> ProgramResult {
113    solana_program::program::invoke(
114        &spl_token::instruction::transfer(
115            &spl_token::id(),
116            from_info.key,
117            to_info.key,
118            authority_info.key,
119            &[authority_info.key],
120            amount,
121        )?,
122        &[
123            token_program.clone(),
124            from_info.clone(),
125            to_info.clone(),
126            authority_info.clone(),
127        ],
128    )
129}
130
131#[cfg(feature = "spl")]
132#[inline(always)]
133pub fn transfer_signed<'info>(
134    authority_info: &AccountInfo<'info>,
135    from_info: &AccountInfo<'info>,
136    to_info: &AccountInfo<'info>,
137    token_program: &AccountInfo<'info>,
138    amount: u64,
139    signer_seeds: &[&[&[u8]]],
140) -> ProgramResult {
141    solana_program::program::invoke_signed(
142        &spl_token::instruction::transfer(
143            &spl_token::id(),
144            from_info.key,
145            to_info.key,
146            authority_info.key,
147            &[authority_info.key],
148            amount,
149        )?,
150        &[
151            token_program.clone(),
152            from_info.clone(),
153            to_info.clone(),
154            authority_info.clone(),
155        ],
156        signer_seeds,
157    )
158}
159
160#[cfg(feature = "spl")]
161#[inline(always)]
162pub fn mint_to_signed<'info>(
163    mint_info: &AccountInfo<'info>,
164    to_info: &AccountInfo<'info>,
165    authority_info: &AccountInfo<'info>,
166    token_program: &AccountInfo<'info>,
167    amount: u64,
168    signer_seeds: &[&[&[u8]]],
169) -> ProgramResult {
170    solana_program::program::invoke_signed(
171        &spl_token::instruction::mint_to(
172            &spl_token::id(),
173            mint_info.key,
174            to_info.key,
175            authority_info.key,
176            &[authority_info.key],
177            amount,
178        )?,
179        &[
180            token_program.clone(),
181            mint_info.clone(),
182            to_info.clone(),
183            authority_info.clone(),
184        ],
185        signer_seeds,
186    )
187}
188
189#[cfg(feature = "spl")]
190#[inline(always)]
191pub fn burn<'info>(
192    token_account_info: &AccountInfo<'info>,
193    mint_info: &AccountInfo<'info>,
194    authority_info: &AccountInfo<'info>,
195    token_program: &AccountInfo<'info>,
196    amount: u64,
197) -> ProgramResult {
198    solana_program::program::invoke(
199        &spl_token::instruction::burn(
200            &spl_token::id(),
201            token_account_info.key,
202            mint_info.key,
203            authority_info.key,
204            &[authority_info.key],
205            amount,
206        )?,
207        &[
208            token_program.clone(),
209            token_account_info.clone(),
210            mint_info.clone(),
211            authority_info.clone(),
212        ],
213    )
214}