use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, msg,
program::invoke_signed, program_error::ProgramError, pubkey::Pubkey,
system_instruction::transfer, system_program,
};
use crate::{
ephemeral_balance_seeds_from_payer,
processor::utils::loaders::{load_pda, load_signer},
};
pub fn process_close_ephemeral_balance(
_program_id: &Pubkey,
accounts: &[AccountInfo],
data: &[u8],
) -> ProgramResult {
let index = *data.first().ok_or(ProgramError::InvalidInstructionData)?;
let [payer, ephemeral_balance_account, system_program] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};
load_signer(payer, "payer")?;
let ephemeral_balance_seeds: &[&[u8]] =
ephemeral_balance_seeds_from_payer!(payer.key, index);
let ephemeral_balance_bump = load_pda(
ephemeral_balance_account,
ephemeral_balance_seeds,
&crate::id(),
true,
"ephemeral balance",
)?;
if ephemeral_balance_account.owner != &system_program::id() {
msg!(
"ephemeral balance expected to be owned by system program. got: {}",
ephemeral_balance_account.owner
);
return Err(ProgramError::InvalidAccountOwner);
}
let amount = ephemeral_balance_account.lamports();
if amount == 0 {
return Ok(());
}
let ephemeral_balance_bump_slice: &[u8] = &[ephemeral_balance_bump];
let ephemeral_balance_signer_seeds =
[ephemeral_balance_seeds, &[ephemeral_balance_bump_slice]].concat();
invoke_signed(
&transfer(ephemeral_balance_account.key, payer.key, amount),
&[
ephemeral_balance_account.clone(),
payer.clone(),
system_program.clone(),
],
&[&ephemeral_balance_signer_seeds],
)?;
Ok(())
}