phoenix/program/
system_utils.rs1use solana_program::{
2 account_info::AccountInfo,
3 entrypoint::ProgramResult,
4 program::{invoke, invoke_signed},
5 pubkey::Pubkey,
6 rent::Rent,
7 system_instruction,
8};
9
10pub fn create_account<'a, 'info>(
11 payer: &'a AccountInfo<'info>,
12 new_account: &'a AccountInfo<'info>,
13 system_program: &'a AccountInfo<'info>,
14 program_owner: &Pubkey,
15 rent: &Rent,
16 space: u64,
17 seeds: Vec<Vec<u8>>,
18) -> ProgramResult {
19 let current_lamports = **new_account.try_borrow_lamports()?;
20 if current_lamports == 0 {
21 invoke_signed(
23 &system_instruction::create_account(
24 payer.key,
25 new_account.key,
26 rent.minimum_balance(space as usize),
27 space,
28 program_owner,
29 ),
30 &[payer.clone(), new_account.clone(), system_program.clone()],
31 &[seeds
32 .iter()
33 .map(|seed| seed.as_slice())
34 .collect::<Vec<&[u8]>>()
35 .as_slice()],
36 )
37 } else {
38 let required_lamports = rent
40 .minimum_balance(space as usize)
41 .max(1)
42 .saturating_sub(current_lamports);
43 if required_lamports > 0 {
44 invoke(
45 &system_instruction::transfer(payer.key, new_account.key, required_lamports),
46 &[payer.clone(), new_account.clone(), system_program.clone()],
47 )?;
48 }
49 invoke_signed(
51 &system_instruction::allocate(new_account.key, space),
52 &[new_account.clone(), system_program.clone()],
53 &[seeds
54 .iter()
55 .map(|seed| seed.as_slice())
56 .collect::<Vec<&[u8]>>()
57 .as_slice()],
58 )?;
59 invoke_signed(
61 &system_instruction::assign(new_account.key, program_owner),
62 &[new_account.clone(), system_program.clone()],
63 &[seeds
64 .iter()
65 .map(|seed| seed.as_slice())
66 .collect::<Vec<&[u8]>>()
67 .as_slice()],
68 )
69 }
70}