If I write a solana program which creates PDAs based on a seed and user's public key, do I need to fund all such accounts with lamports beforehand so that my clients can store data in it without worrying about the rent?
-
2To clarify a little, you almost always DO need to fund the user's account with enough Sol to make the account rent-exempt, but this fee is usually paid by the USER, who signs the transaction to interact with your program. This is why the first time you use many defi apps you will incur a small Sol cost to pay these account opening fees. The program creator rarely pays rent fees for user accounts.– WhitesealCommented Aug 11, 2022 at 22:15
-
at present, there is no almost, it's always. the runtime will fail transactions that leave an account with a non-zero, but sub-rent-exempt lamports balance– trent.solCommented Aug 19, 2022 at 6:34
Add a comment
|
1 Answer
I would do this in the same Instruction Processing function, as the creation of an account under the PDA.
Let's say, you want to initiate the state account like this one in your state.rs:
pub struct StateAccount {
pub owner: Pubkey,
pub amount: u64,
}
impl StateAccount {
// this is the size (space) that needs to be allocated
pub const LEN: usize = 32 + 8;
}
When a user sends a CreateStateAccount instruction, the processor.rs will try to do something like this:
pub fn process_create_state_account (
accounts: &[AccountInfo],
amount: u64,
program_id: &Pubkey
) -> ProgramResult {
// get account infos
// do some checks
// find PDA. Here I say: I'm expecting the PDA to be derived from program_id
// with the b'some_seeds' and 'creator' Pubkey as the seeds.
let (pda_state, bump_seed) = Pubkey::find_program_address(
&[b"some_seeds", creator.key.as_ref()],
program_id
);
// This is where you are handling rent exemption stuff, without actually involving user interaction
let rent = Rent::get()?;
let rent_lamports = rent.minimum_balance(StateAccount::LEN);
// create_account INSTRUCTION for system_program.
let create_state_account_pda_ix = &system_instruction::create_account(
&creator.key,
&pda_state_account.key,
rent_lamports,
StateAccount::LEN.try_into().unwrap(),
program_id
);
msg!("Creating User's State Account");
// Now you send the instruction to the 'system_program'.
invoke_signed(...)?;
// Then you are modifying the state
}