use crate::state::Favorites; use borsh::BorshSerialize; use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, msg, program::invoke_signed, program_error::ProgramError, pubkey::Pubkey, rent::Rent, system_instruction, sysvar::Sysvar, }; pub fn create_pda(program_id: &Pubkey, accounts: &[AccountInfo], data: Favorites) -> ProgramResult { let account_iter = &mut accounts.iter(); let user = next_account_info(account_iter)?; // the user who's signing the transaction let favorite_account = next_account_info(account_iter)?; // The target account that will be created in the process let system_program = next_account_info(account_iter)?; // deriving the favorite pda let (favorite_pda, favorite_bump) = Pubkey::find_program_address(&[b"favorite", user.key.as_ref()], program_id); // Checking if the favorite account is same as the derived favorite pda if favorite_account.key != &favorite_pda { return Err(ProgramError::IncorrectProgramId); } // Checking if the pda is already initialized if favorite_account.data.borrow().len() == 0 { // Initialize the favorite account if it's not initialized let space = data.try_to_vec()?.len(); let lamports = (Rent::get()?).minimum_balance(space); let ix = system_instruction::create_account( user.key, favorite_account.key, lamports, space as u64, program_id, ); invoke_signed( &ix, &[ user.clone(), favorite_account.clone(), system_program.clone(), ], &[&[b"favorite", user.key.as_ref(), &[favorite_bump]]], )?; // Serialize and store the data data.serialize(&mut &mut favorite_account.data.borrow_mut()[..])?; msg!("{:#?}", data); } else { return Err(ProgramError::AccountAlreadyInitialized.into()); } Ok(()) }