From e95753a1afc1af96fddd03f807274acaed8da74f Mon Sep 17 00:00:00 2001 From: David Ojo Date: Fri, 27 Mar 2026 16:28:43 +0100 Subject: [PATCH] feat: add read-only protocol admin address view method #53 --- creator-keys/src/lib.rs | 21 ++++++++++++++++++++ creator-keys/src/test.rs | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/creator-keys/src/lib.rs b/creator-keys/src/lib.rs index 4638330..d9e63f2 100644 --- a/creator-keys/src/lib.rs +++ b/creator-keys/src/lib.rs @@ -159,6 +159,7 @@ pub enum DataKey { KeyPrice, KeyBalance(Address, Address), TreasuryAddress, + AdminAddress, } #[derive(Clone, Debug, PartialEq)] @@ -501,6 +502,26 @@ impl CreatorKeysContract { env.storage().persistent().get(&DataKey::TreasuryAddress) } + /// Sets the protocol admin address. + /// + /// Only callable by an authorized admin. Stores the admin address used + /// for protocol administration. + pub fn set_protocol_admin(env: Env, admin: Address, new_admin: Address) { + admin.require_auth(); + env.storage() + .persistent() + .set(&DataKey::AdminAddress, &new_admin); + } + + /// Read-only view: returns the current protocol admin address. + /// + /// Returns `None` if no admin address has been configured. + /// Use this method for indexers and read-only callers that need the current + /// protocol admin address. + pub fn get_protocol_admin(env: Env) -> Option
{ + env.storage().persistent().get(&DataKey::AdminAddress) + } + /// Read-only view: returns the current protocol fee configuration. /// /// Returns a stable [`ProtocolFeeView`] regardless of whether a fee config has been set. diff --git a/creator-keys/src/test.rs b/creator-keys/src/test.rs index 28f84c7..1c88cb9 100644 --- a/creator-keys/src/test.rs +++ b/creator-keys/src/test.rs @@ -430,3 +430,45 @@ fn test_quote_overflow_guards() { // To test subtraction overflow, we need fees > price. // Price must be positive per contract constraint. } + +#[test] +fn test_get_protocol_admin_returns_none_initially() { + let env = Env::default(); + let contract_id = env.register(CreatorKeysContract, ()); + let client = CreatorKeysContractClient::new(&env, &contract_id); + + let result = client.get_protocol_admin(); + assert_eq!(result, None); +} + +#[test] +fn test_get_protocol_admin_returns_set_address() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(CreatorKeysContract, ()); + let client = CreatorKeysContractClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let new_admin = Address::generate(&env); + client.set_protocol_admin(&admin, &new_admin); + + let result = client.get_protocol_admin(); + assert_eq!(result, Some(new_admin)); +} + +#[test] +fn test_get_protocol_admin_persists_across_reads() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(CreatorKeysContract, ()); + let client = CreatorKeysContractClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let new_admin = Address::generate(&env); + client.set_protocol_admin(&admin, &new_admin); + + let first_read = client.get_protocol_admin(); + let second_read = client.get_protocol_admin(); + assert_eq!(first_read, second_read); + assert_eq!(first_read, Some(new_admin)); +}