use num_enum::{IntoPrimitive, TryFromPrimitive}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, rent::Rent, sysvar::Sysvar, }; /// Creates a new pda #[inline(always)] pub(crate) fn create_pda<'a, 'info>( target_account: &'a AccountInfo<'info>, owner: &Pubkey, space: usize, pda_seeds: &[&[u8]], system_program: &'a AccountInfo<'info>, payer: &'a AccountInfo<'info>, ) -> ProgramResult { let rent = Rent::get()?; solana_program::program::invoke_signed( &solana_program::system_instruction::create_account( payer.key, target_account.key, rent.minimum_balance(space as usize), space as u64, owner, ), &[ payer.clone(), target_account.clone(), system_program.clone(), ], &[pda_seeds], )?; Ok(()) } #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] pub enum AccountDiscriminator { Bus = 100, Proof = 101, Treasury = 102, } pub trait Discriminator { fn discriminator() -> AccountDiscriminator; } #[macro_export] macro_rules! impl_to_bytes { ($struct_name:ident) => { impl $struct_name { pub fn to_bytes(&self) -> &[u8] { bytemuck::bytes_of(self) } } }; } pub trait AccountDeserialize { fn try_from_bytes(data: &[u8]) -> Result<&Self, ProgramError>; fn try_from_bytes_mut(data: &mut [u8]) -> Result<&mut Self, ProgramError>; } #[macro_export] macro_rules! impl_account_from_bytes { ($struct_name:ident) => { impl crate::utils::AccountDeserialize for $struct_name { fn try_from_bytes( data: &[u8], ) -> Result<&Self, solana_program::program_error::ProgramError> { if (Self::discriminator() as u8).ne(&data[0]) { return Err(solana_program::program_error::ProgramError::InvalidAccountData); } bytemuck::try_from_bytes::(&data[8..]).or(Err( solana_program::program_error::ProgramError::InvalidAccountData, )) } fn try_from_bytes_mut( data: &mut [u8], ) -> Result<&mut Self, solana_program::program_error::ProgramError> { if (Self::discriminator() as u8).ne(&data[0]) { return Err(solana_program::program_error::ProgramError::InvalidAccountData); } bytemuck::try_from_bytes_mut::(&mut data[8..]).or(Err( solana_program::program_error::ProgramError::InvalidAccountData, )) } } }; } #[macro_export] macro_rules! impl_instruction_from_bytes { ($struct_name:ident) => { impl $struct_name { pub fn try_from_bytes( data: &[u8], ) -> Result<&Self, solana_program::program_error::ProgramError> { bytemuck::try_from_bytes::(data).or(Err( solana_program::program_error::ProgramError::InvalidInstructionData, )) } } }; }