instruction macro and simplification

This commit is contained in:
Hardhat Chad
2024-08-26 21:02:52 +00:00
parent 3a3550ced5
commit bff1868ccc
16 changed files with 217 additions and 170 deletions

View File

@@ -146,6 +146,30 @@ pub fn load_mint(
Ok(())
}
/// Errors if:
/// - Owner is not SPL token program.
/// - Data is empty.
/// - Data cannot deserialize into a mint account.
/// - Expected to be writable, but is not.
#[cfg(feature = "spl")]
pub fn load_any_mint(info: &AccountInfo<'_>, is_writable: bool) -> Result<(), ProgramError> {
if info.owner.ne(&spl_token::id()) {
return Err(ProgramError::InvalidAccountOwner);
}
if info.data_is_empty() {
return Err(ProgramError::UninitializedAccount);
}
Mint::unpack(&info.data.borrow())?;
if is_writable && !info.is_writable {
return Err(ProgramError::InvalidAccountData);
}
Ok(())
}
/// Errors if:
/// - Owner is not SPL token program.
/// - Data is empty.
@@ -187,3 +211,39 @@ pub fn load_token_account(
Ok(())
}
/// Errors if:
/// - Owner is not SPL token program.
/// - Data is empty.
/// - Data cannot deserialize into a token account.
/// - Address does not match the expected associated token address.
/// - Expected to be writable, but is not.
#[cfg(feature = "spl")]
pub fn load_associated_token_account(
info: &AccountInfo<'_>,
owner: &Pubkey,
mint: &Pubkey,
is_writable: bool,
) -> Result<(), ProgramError> {
if info.owner.ne(&spl_token::id()) {
return Err(ProgramError::InvalidAccountOwner);
}
if info.data_is_empty() {
return Err(ProgramError::UninitializedAccount);
}
let account_data = info.data.borrow();
let _ = spl_token::state::Account::unpack(&account_data)?;
let address = spl_associated_token_account::get_associated_token_address(owner, mint);
if info.key.ne(&address) {
return Err(ProgramError::InvalidSeeds);
}
if is_writable && !info.is_writable {
return Err(ProgramError::InvalidAccountData);
}
Ok(())
}

View File

@@ -98,8 +98,23 @@ macro_rules! event {
#[macro_export]
macro_rules! instruction {
($struct_name:ident) => {
$crate::impl_to_bytes!($struct_name);
($discriminator_name:ident, $struct_name:ident) => {
$crate::impl_instruction_from_bytes!($struct_name);
impl $crate::Discriminator for $struct_name {
fn discriminator() -> u8 {
$discriminator_name::$struct_name as u8
}
}
impl $struct_name {
pub fn to_bytes(&self) -> Vec<u8> {
[
[$discriminator_name::$struct_name as u8].to_vec(),
bytemuck::bytes_of(self).to_vec(),
]
.concat()
}
}
};
}

View File

@@ -1,10 +1,10 @@
use solana_program::program_error::ProgramError;
pub trait Discriminator {
fn discriminator() -> u8;
}
pub trait AccountDeserialize {
fn try_from_bytes(data: &[u8]) -> Result<&Self, ProgramError>;
fn try_from_bytes_mut(data: &mut [u8]) -> Result<&mut Self, ProgramError>;
}
pub trait Discriminator {
fn discriminator() -> u8;
}