typhoon-utility 0.2.2

Utility functions and helpers
Documentation
use {
    pinocchio::{cpi::Signer, sysvars::rent::Rent, AccountView, Address, ProgramResult},
    pinocchio_system::instructions::{Assign, CreateAccount, Transfer},
};

/// Create an account with a minimum balance to be rent-exempt.
///
/// When creating a PDA `account`, the PDA signer seeds must be provided
/// via the `signers`.
///
/// The account will be funded by the `payer` if its current lamports
/// are insufficient for rent-exemption. The payer can be a PDA signer
/// owned by the system program and its signer seeds can be provided
/// via the `signers`.
#[inline(always)]
pub fn create_account_with_minimum_balance_signed(
    account: &AccountView,
    space: usize,
    owner: &Address,
    payer: &AccountView,
    rent_sysvar: &Rent,
    signers: &[Signer],
) -> ProgramResult {
    let lamports = rent_sysvar.try_minimum_balance(space)?;

    if account.lamports() == 0 {
        // Create the account if it does not exist.
        CreateAccount {
            from: payer,
            to: account,
            lamports,
            space: space as u64,
            owner,
        }
        .invoke_signed(signers)
    } else {
        let required_lamports = lamports.saturating_sub(account.lamports());

        // Transfer lamports from `payer` to `account` if needed.
        if required_lamports > 0 {
            Transfer {
                from: payer,
                to: account,
                lamports: required_lamports,
            }
            .invoke_signed(signers)?;
        }

        // Assign the account to the specified owner.
        Assign { account, owner }.invoke_signed(signers)?;

        // Allocate the required space for the account.
        //
        // SAFETY: There are no active borrows of the `account`.
        // This was checked by the `Assign` CPI above.
        unsafe { account.resize_unchecked(space) }
    }
}