Skip to content

feat(rfp-001): add spel-admin-authority library and #[require_admin] macro#212

Draft
bristinWild wants to merge 3 commits into
logos-co:mainfrom
bristinWild:feat/rfp-001-admin-authority
Draft

feat(rfp-001): add spel-admin-authority library and #[require_admin] macro#212
bristinWild wants to merge 3 commits into
logos-co:mainfrom
bristinWild:feat/rfp-001-admin-authority

Conversation

@bristinWild
Copy link
Copy Markdown

Implements RFP-001: Admin Authority Library for LEZ programs.

What's included

spel-admin-authority crate

  • AdminState — core authority primitive (set, transfer, revoke)
  • AdminConfig — standard config PDA type for authority programs
  • 9 unit tests covering full authority lifecycle
  • Zero dependencies on spel-framework (no circular deps)

spel-admin-authority-sample — reference program

  • initialize — creates config PDA, sets admin authority
  • set_config_value — admin-gated privileged instruction
  • transfer_admin — rotate authority to new key
  • revoke_admin — permanently revoke (irreversible)
  • 8 tests covering all instructions + error cases

#[require_admin] macro in spel-framework-macros

  • New require_admin proc macro attribute
  • #[lez_program] detects #[require_admin(config)] on instructions
  • Injects AdminConfig::assert_admin() check before handler body
  • Single annotation gates any privileged instruction — no boilerplate

Usage

#[instruction]
#[require_admin(config)]
pub fn set_config_value(
    #[account(mut, pda = literal("config"))]
    config: AccountWithMetadata,
    #[account(signer)]
    admin: AccountWithMetadata,
    new_value: u64,
) -> SpelResult {
    // Admin check injected automatically before this body runs
}

Test results

  • spel-admin-authority: 9 tests
  • spel-admin-authority-sample: 8 tests
  • Full workspace: all existing tests pass, 0 regressions

Related

bristinWild added 2 commits May 20, 2026 02:35
- Add spel-admin-authority crate with AdminState core primitive
  - assert_admin(), transfer_admin(), revoke_admin() operations
  - Atomic mutations — state only changes after all checks pass
  - 9 unit tests covering all authority lifecycle scenarios
- Add spel-admin-authority-sample SPEL program demonstrating integration
  - initialize: creates config PDA, sets admin authority
  - set_config_value: admin-gated privileged instruction
  - transfer_admin: rotate authority to new key
  - revoke_admin: permanently revoke (irreversible)
  - 8 integration tests covering all 4 instructions + error cases
- Full workspace compiles clean, 17 tests passing

Addresses RFP-001: Admin Authority Library
- Add require_admin proc macro attribute to spel-framework-macros
- #[lez_program] now detects #[require_admin(config)] on instructions
  and injects AdminConfig::assert_admin() check before handler body runs
- Add AdminConfig to spel-admin-authority library (re-exported in sample)
- Update sample program to use #[require_admin(config)] annotation
- Full workspace: all tests passing, 0 failures

Usage:
  #[instruction]
  #[require_admin(config)]
  pub fn set_config_value(
      #[account(mut, pda = literal("config"))]
      config: AccountWithMetadata,
      #[account(signer)]
      admin: AccountWithMetadata,
      new_value: u64,
  ) -> SpelResult { ... }  // admin check injected automatically
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant