rialo-feature-management-program-interface 0.10.2

Rialo Feature Management Program Interface
Documentation
// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//! Instruction types for the Feature Management Program

extern crate alloc;
use alloc::{string::String, vec::Vec};

use borsh::{BorshDeserialize, BorshSerialize};
use rialo_s_pubkey::Pubkey;

/// Instructions supported by the Feature Management Program
#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub enum FeatureManagementInstruction {
    /// Enable one or more features by name.
    ///
    /// Idempotent: re-submitting an existing name is a no-op. Activation is
    /// presence-based — a feature is active iff its name is in
    /// `FeaturesState.entries`.
    ///
    /// Per-batch cap: `names.len()` MUST be `<= MAX_NAMES_PER_BATCH` and each
    /// name MUST satisfy `validate_feature_name` (which enforces
    /// `<= MAX_FEATURE_NAME_LENGTH` and the allowed character set). The
    /// `MAX_NAMES_PER_BATCH × MAX_FEATURE_NAME_LENGTH` payload is sized to
    /// fit inside the ~64 KB transaction limit alongside headers and
    /// signatures.
    ///
    /// Accounts expected:
    /// 0. `[writable]` Storage account (PDA)
    /// 1. `[signer]` The authority account
    Enable {
        /// One or more feature names to add to the active set. See the
        /// per-batch / per-name caps above.
        names: Vec<String>,
    },

    /// Update the authority. Single-step path.
    ///
    /// This instruction requires a valid signature from the current authority.
    ///
    /// Accounts expected:
    /// 0. `[writable]` Storage account (PDA)
    /// 1. `[signer]` The current authority account
    UpdateAuthority {
        /// The new authority that will control the feature management system.
        new_authority: Pubkey,
    },

    /// Step 1 of the two-step authority handshake: propose a transfer.
    ///
    /// Sets `pending_authority = Some(new_authority)`. Rejected with
    /// `PendingTransferExists` if a previous proposal is still outstanding;
    /// rejected with `InvalidTransferTarget` if `new_authority` equals the
    /// current authority.
    ///
    /// Accounts expected:
    /// 0. `[writable]` Storage account (PDA)
    /// 1. `[signer]` The current authority
    ProposeAuthorityTransfer {
        /// Pubkey that will become the next authority once it signs an
        /// `AcceptAuthorityTransfer` against this pending value.
        new_authority: Pubkey,
    },

    /// Step 2 of the two-step authority handshake: commit a previously
    /// proposed transfer.
    ///
    /// Requires the **pending** authority's signature. On success the
    /// authority field moves to the pending value and `pending_authority`
    /// clears. Rejected with `NoPendingTransfer` if nothing is pending,
    /// `Unauthorized` if the signer is not the pending authority.
    ///
    /// Accounts expected:
    /// 0. `[writable]` Storage account (PDA)
    /// 1. `[signer]` The pending authority
    AcceptAuthorityTransfer,

    /// Cancel a previously proposed authority transfer.
    ///
    /// Requires the **current** authority's signature. Clears
    /// `pending_authority`. Rejected with `NoPendingTransfer` if nothing
    /// is pending.
    ///
    /// Accounts expected:
    /// 0. `[writable]` Storage account (PDA)
    /// 1. `[signer]` The current authority
    CancelAuthorityTransfer,
}

#[cfg(not(target_os = "solana"))]
impl FeatureManagementInstruction {
    /// Serialize instruction data
    pub fn serialize(&self) -> Result<Vec<u8>, borsh::io::Error> {
        borsh::to_vec(self)
    }

    /// Deserialize instruction data
    pub fn deserialize(data: &[u8]) -> Result<Self, borsh::io::Error> {
        borsh::from_slice(data)
    }
}