spherenet-program-whitelist-interface 0.1.0

Interface of SphereNet's Program Whitelist Program
Documentation
//! Instruction types

use {
    pinocchio::{
        program_error::ProgramError,
        pubkey::{Pubkey, PUBKEY_BYTES},
    },
    shank::ShankInstruction,
};
/// Instructions supported by the program whitelist program.
#[repr(C)]
#[derive(Clone, Debug, PartialEq, ShankInstruction)]
pub enum ProgramWhitelistInstruction {
    /// Initializes the program whitelist account, setting its initial state
    /// with the initial authority.
    ///
    /// Accounts expected by this instruction:
    ///
    ///   0. `[writable]` The whitelist account to initialize
    ///   1. `[signer]` The authority that will control the whitelist
    ///   2. `[signer]` Account that will pay for the account creation
    ///   3. `[]` The system program
    #[account(
        0,
        writable,
        name = "whitelist_account",
        desc = "The whitelist account to initialize"
    )]
    #[account(
        1,
        signer,
        name = "whitelist_authority",
        desc = "The authority that will control the whitelist"
    )]
    #[account(
        2,
        signer,
        name = "funder",
        desc = "Account that will pay for the account creation"
    )]
    #[account(3, name = "system_program", desc = "System program")]
    CreateWhitelist {},

    /// Accepts the pending authority transfer for the program whitelist. The
    /// `pending_whitelist_authority` must sign this instruction to assume
    /// authority over the whitelist.
    ///
    /// Accounts expected by this instruction:
    ///
    ///   0. `[writable]` The whitelist account
    ///   1. `[signer]` The pending whitelist authority
    #[account(
        0,
        writable,
        name = "whitelist_account",
        desc = "The whitelist account"
    )]
    #[account(
        1,
        signer,
        name = "pending_whitelist_authority",
        desc = "The pending whitelist authority"
    )]
    AcceptAuthorityTransfer,

    /// Proposes a new authority for the program whitelist. The current
    /// `whitelist_authority` must sign this instruction. The proposed
    /// `new_authority` must then sign an `AcceptAuthorityTransfer`
    /// instruction to finalize the transfer.
    ///
    /// Accounts expected by this instruction:
    ///
    ///   0. `[writable]` The whitelist account
    ///   1. `[signer]` The current whitelist authority
    #[account(
        0,
        writable,
        name = "whitelist_account",
        desc = "The whitelist account"
    )]
    #[account(
        1,
        signer,
        name = "whitelist_authority",
        desc = "The whitelist authority"
    )]
    InitiateAuthorityTransfer { new_authority: Pubkey },

    /// Cancels a pending authority transfer for the program whitelist. The
    /// current `whitelist_authority` must sign this instruction.
    ///
    /// Accounts expected by this instruction:
    ///
    ///   0. `[writable]` The whitelist account
    ///   1. `[signer]` The current whitelist authority
    #[account(
        0,
        writable,
        name = "whitelist_account",
        desc = "The whitelist account"
    )]
    #[account(
        1,
        signer,
        name = "whitelist_authority",
        desc = "The whitelist authority"
    )]
    CancelAuthorityTransfer {},

    /// Adds an address to the program whitelist or unrevokes a previously
    /// revoked address. If the `whitelist_entry_account` does not exist,
    /// this instruction creates and initializes it. If the account already
    /// exists and is marked as revoked, this instruction marks it as active
    /// again. The `whitelist_authority` must sign.
    ///
    /// Accounts expected by this instruction:
    ///
    ///   0. `[]` The whitelist account (Used for validation/derivation)
    ///   1. `[signer]` The whitelist authority
    ///   2. `[writable]` The whitelist entry account to be created/initialized
    ///      or updated
    ///   3. `[writable, signer]` Payer account (must be a system account)
    ///   4. `[]` System program
    #[account(0, name = "whitelist_account", desc = "The whitelist account")]
    #[account(
        1,
        signer,
        name = "whitelist_authority",
        desc = "The whitelist authority"
    )]
    #[account(
        2,
        writable,
        name = "whitelist_entry_account",
        desc = "The whitelist entry account"
    )]
    #[account(
        3,
        writable,
        signer,
        name = "payer",
        desc = "Payer account (must be a system account)"
    )]
    #[account(4, name = "system_program", desc = "System program")]
    AddEntry { program_authority: Pubkey },

    /// Closes a specific whitelist entry account, transferring its rent
    /// lamports to a designated destination account. The `whitelist_authority`
    /// must sign this instruction.
    ///
    /// Accounts expected by this instruction:
    ///
    ///   0. `[]` The whitelist account (Used for validation)
    ///   1. `[signer]` The whitelist authority
    ///   2. `[writable]` The whitelist entry account to close
    ///   3. `[writable]` The destination account for reclaimed lamports
    ///   4. `[]` System program
    #[account(0, name = "whitelist_account", desc = "The whitelist account")]
    #[account(
        1,
        signer,
        name = "whitelist_authority",
        desc = "The whitelist authority"
    )]
    #[account(
        2,
        writable,
        name = "whitelist_entry_account",
        desc = "The whitelist entry account to close"
    )]
    #[account(
        3,
        writable,
        name = "destination_account",
        desc = "The destination account for reclaimed lamports"
    )]
    #[account(4, name = "system_program", desc = "System program")]
    RemoveEntry { program_authority: Pubkey },
}

impl ProgramWhitelistInstruction {
    /// Unpack a program whitelist instruction from a byte slice.
    pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
        // Use the pattern matching style from the example
        match input.split_first() {
            Some((&0, [])) => Ok(Self::CreateWhitelist {}),
            Some((&1, remaining)) if remaining.len() == PUBKEY_BYTES => {
                let new_authority = Pubkey::try_from(remaining).unwrap();
                Ok(Self::InitiateAuthorityTransfer { new_authority })
            }
            Some((&2, [])) => Ok(Self::AcceptAuthorityTransfer),
            Some((&3, [])) => Ok(Self::CancelAuthorityTransfer {}),
            Some((&4, remaining)) if remaining.len() == PUBKEY_BYTES => {
                let program_authority = Pubkey::try_from(remaining).unwrap();
                Ok(Self::AddEntry { program_authority })
            }
            Some((&5, remaining)) if remaining.len() == PUBKEY_BYTES => {
                let program_authority = Pubkey::try_from(remaining).unwrap();
                Ok(Self::RemoveEntry { program_authority })
            }
            _ => Err(ProgramError::InvalidInstructionData),
        }
    }
}