Skip to content

Commit 4b87477

Browse files
committed
Add create account helper
1 parent 05f74a9 commit 4b87477

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

programs/system/src/lib.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,81 @@
11
#![no_std]
22

3+
use pinocchio::{
4+
account_info::AccountInfo,
5+
instruction::Signer,
6+
pubkey::Pubkey,
7+
sysvars::{rent::Rent, Sysvar},
8+
ProgramResult,
9+
};
10+
11+
use crate::instructions::{Allocate, CreateAccount, Transfer};
12+
313
pub mod instructions;
414

515
pinocchio_pubkey::declare_id!("11111111111111111111111111111111");
16+
17+
/// Create an account with a minimal balance to be rent-exempt.
18+
///
19+
/// The account will be funded by the `payer` if its current lamports
20+
/// are insufficient for rent-exemption.
21+
///
22+
/// # Safety
23+
///
24+
/// This function assigns the `account` to the specified `owner` program.
25+
/// The caller must ensure that no references to the current account
26+
/// owner exist.
27+
#[inline(always)]
28+
pub unsafe fn create_account_with_minimal_balance(
29+
account: &AccountInfo,
30+
space: usize,
31+
owner: &Pubkey,
32+
payer: &AccountInfo,
33+
signers: &[Signer],
34+
rent_sysvar: Option<&AccountInfo>,
35+
) -> ProgramResult {
36+
let lamports = if let Some(rent_sysvar) = rent_sysvar {
37+
let rent = Rent::from_account_info(rent_sysvar)?;
38+
rent.minimum_balance(space)
39+
} else {
40+
Rent::get()?.minimum_balance(space)
41+
};
42+
43+
if account.lamports() == 0 {
44+
CreateAccount {
45+
from: payer,
46+
to: account,
47+
lamports,
48+
space: space as u64,
49+
owner,
50+
}
51+
.invoke_signed(signers)
52+
} else {
53+
let required_lamports = lamports.saturating_sub(account.lamports());
54+
55+
// Transfer lamports from `payer` to `account` if needed.
56+
if required_lamports > 0 {
57+
Transfer {
58+
from: payer,
59+
to: account,
60+
lamports: required_lamports,
61+
}
62+
.invoke()?;
63+
}
64+
65+
Allocate {
66+
account,
67+
space: space as u64,
68+
}
69+
.invoke_signed(signers)?;
70+
71+
// Assign `account` to the owner program.
72+
//
73+
// SAFETY: The caller guarantees no references to the current
74+
// account owner exist.
75+
unsafe {
76+
account.assign(owner);
77+
}
78+
79+
Ok(())
80+
}
81+
}

0 commit comments

Comments
 (0)