use solana_program::pubkey::Pubkey;
use steel::*;
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
pub enum HookInstruction {
CreateGlobalKycRecord = 0,
CreateOfferingKycRecord = 1,
UpdateGlobalKycVerified = 2,
UpdateOfferingKycVerified = 3,
RegisterMint = 4,
RotateOpsAuthority = 5,
UpdateIssuerStatus = 6,
UpdateIssuerIdentity = 7,
Initialize = 100,
UpdatePlatformConfig = 101,
RegisterIssuer = 102,
UpdatePlatformAdmin = 103,
AcceptPlatformAdmin = 104,
CancelPlatformAdminProposal = 105,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Initialize {
pub platform_admin: Pubkey,
pub fee_recipient: Pubkey,
pub issuer_registration_fee_lamports: [u8; 8],
pub cluster: u8,
pub registration_mode: u8,
pub _padding: [u8; 6],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct UpdatePlatformConfig {
pub fee_recipient: Pubkey,
pub issuer_registration_fee_lamports: [u8; 8],
pub registration_mode: u8,
pub paused: u8,
pub _padding: [u8; 6],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct RegisterIssuer {
pub issuer_id: [u8; 16],
pub identity: Pubkey,
pub ops_authority: Pubkey,
pub registration_path: u8,
pub _padding: [u8; 7],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct CreateGlobalKycRecord {
pub user: Pubkey,
pub issuer_id: [u8; 16],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct CreateOfferingKycRecord {
pub user: Pubkey,
pub issuer_id: [u8; 16],
pub offering_id: [u8; 32],
pub offering_id_len: u8,
pub _padding: [u8; 7],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct UpdateGlobalKycVerified {
pub user: Pubkey,
pub issuer_id: [u8; 16],
pub is_kyc_verified: u8,
pub _padding: [u8; 7],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct UpdateOfferingKycVerified {
pub user: Pubkey,
pub issuer_id: [u8; 16],
pub offering_id: [u8; 32],
pub offering_id_len: u8,
pub is_kyc_verified: u8,
pub _padding: [u8; 6],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct RegisterMint {
pub mint: Pubkey,
pub issuer_id: [u8; 16],
pub offering_id: [u8; 32],
pub offering_id_len: u8,
pub kyc_policy: u8,
pub _padding: [u8; 6],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct RotateOpsAuthority {
pub issuer_id: [u8; 16],
pub new_ops_authority: Pubkey,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct UpdateIssuerStatus {
pub issuer_id: [u8; 16],
pub status: u8,
pub _padding: [u8; 7],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct UpdateIssuerIdentity {
pub issuer_id: [u8; 16],
pub new_identity: Pubkey,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct UpdatePlatformAdmin {
pub new_admin: Pubkey,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct AcceptPlatformAdmin {}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct CancelPlatformAdminProposal {}
instruction!(HookInstruction, Initialize);
instruction!(HookInstruction, UpdatePlatformConfig);
instruction!(HookInstruction, RegisterIssuer);
instruction!(HookInstruction, CreateGlobalKycRecord);
instruction!(HookInstruction, CreateOfferingKycRecord);
instruction!(HookInstruction, UpdateGlobalKycVerified);
instruction!(HookInstruction, UpdateOfferingKycVerified);
instruction!(HookInstruction, RegisterMint);
instruction!(HookInstruction, RotateOpsAuthority);
instruction!(HookInstruction, UpdateIssuerStatus);
instruction!(HookInstruction, UpdateIssuerIdentity);
instruction!(HookInstruction, UpdatePlatformAdmin);
instruction!(HookInstruction, AcceptPlatformAdmin);
instruction!(HookInstruction, CancelPlatformAdminProposal);
#[cfg(test)]
mod layout_tests {
use super::*;
macro_rules! assert_one_byte_aligned {
($($t:ty),+ $(,)?) => {$(
assert_eq!(
core::mem::align_of::<$t>(), 1,
"{} must be 1-byte aligned for opcode-prefixed instruction parsing",
stringify!($t)
);
)+};
}
#[test]
fn instruction_structs_are_one_byte_aligned() {
assert_one_byte_aligned!(
Initialize,
UpdatePlatformConfig,
RegisterIssuer,
CreateGlobalKycRecord,
CreateOfferingKycRecord,
UpdateGlobalKycVerified,
UpdateOfferingKycVerified,
RegisterMint,
RotateOpsAuthority,
UpdateIssuerStatus,
UpdateIssuerIdentity,
UpdatePlatformAdmin,
AcceptPlatformAdmin,
CancelPlatformAdminProposal,
);
}
#[test]
fn initialize_round_trips_through_opcode_prefixed_bytes() {
let ix = Initialize {
platform_admin: Pubkey::new_unique(),
fee_recipient: Pubkey::new_unique(),
issuer_registration_fee_lamports: 1_234_567_890u64.to_le_bytes(),
cluster: 1,
registration_mode: 2,
_padding: [0; 6],
};
let bytes = ix.to_bytes();
assert_eq!(bytes[0], HookInstruction::Initialize as u8);
let parsed = Initialize::try_from_bytes(&bytes[1..]).expect("parse");
assert_eq!(parsed.platform_admin, ix.platform_admin);
assert_eq!(
u64::from_le_bytes(parsed.issuer_registration_fee_lamports),
1_234_567_890
);
assert_eq!(parsed.cluster, 1);
}
}