rwa-kyc-hook-api 0.2.0

Token-2022 KYC Transfer Hook for RWA primary issuance on x402
Documentation
use super::{HookAccount, KycPolicy};
use solana_program::program_error::ProgramError;
use static_assertions::const_assert_eq;
use steel::*;

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct MintConfig {
    pub mint: Pubkey,
    pub issuer_id: [u8; 16],
    pub offering_id: [u8; 32],
    pub offering_id_len: u8,
    pub kyc_policy: u8,
    pub bump: u8,
    pub _padding: [u8; 5],
}

const_assert_eq!(core::mem::size_of::<MintConfig>() % 8, 0);

account!(HookAccount, MintConfig);

impl MintConfig {
    pub fn policy(&self) -> Result<KycPolicy, ProgramError> {
        KycPolicy::try_from(self.kyc_policy).map_err(|_| ProgramError::InvalidAccountData)
    }

    pub fn issuer_id_matches(&self, expected: &[u8; 16]) -> bool {
        &self.issuer_id == expected
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::consts::{
        MINT_CONFIG_ISSUER_ID_OFFSET, MINT_CONFIG_OFFERING_ID_OFFSET,
        STEEL_ACCOUNT_DISCRIMINATOR_LEN,
    };

    // `Seed::AccountData` indexes RAW account data, and Steel stores the struct body
    // after an 8-byte discriminator prefix. The resolution offsets must therefore be
    // `STEEL_ACCOUNT_DISCRIMINATOR_LEN + offset_of!(field)`, NOT the bare struct offset.
    #[test]
    fn issuer_and_offering_id_offsets_for_extra_account_meta() {
        assert_eq!(
            STEEL_ACCOUNT_DISCRIMINATOR_LEN + core::mem::offset_of!(MintConfig, issuer_id) as u8,
            MINT_CONFIG_ISSUER_ID_OFFSET
        );
        assert_eq!(
            STEEL_ACCOUNT_DISCRIMINATOR_LEN + core::mem::offset_of!(MintConfig, offering_id) as u8,
            MINT_CONFIG_OFFERING_ID_OFFSET
        );
    }
}