From e5efbe8a27a62c563fc81282e36627d4676e62e4 Mon Sep 17 00:00:00 2001 From: Michael Victor Date: Thu, 28 May 2026 03:47:51 +0100 Subject: [PATCH] feat: add get_pending_admin view to settlement Exposes the pending admin slot so integrators can detect an in-flight two-step admin handover without watching events. - Add get_pending_admin(env) -> Option
: returns Some when set_admin has been called and accept_admin has not yet completed, None otherwise - Add test_get_pending_admin_none_before_nomination: asserts None when no transfer is in progress - Add test_get_pending_admin_some_after_nomination: asserts Some after set_admin, then None again after accept_admin - Existing test_accept_admin_fails_if_not_nominated covers the accept-without-pending panic path - Document get_pending_admin in docs/interfaces/settlement.json --- contracts/settlement/src/lib.rs | 13 +++++++++++++ contracts/settlement/src/test.rs | 32 ++++++++++++++++++++++++++++++++ docs/interfaces/settlement.json | 10 ++++++++++ 3 files changed, 55 insertions(+) diff --git a/contracts/settlement/src/lib.rs b/contracts/settlement/src/lib.rs index e18826a..24a7b14 100644 --- a/contracts/settlement/src/lib.rs +++ b/contracts/settlement/src/lib.rs @@ -405,6 +405,19 @@ impl CalloraSettlement { result } + /// Return the pending admin address, or `None` if no transfer is in progress. + /// + /// Integrators can poll this to detect an in-flight two-step admin handover + /// before `accept_admin` is called. + /// + /// # Returns + /// `Some(Address)` of the nominated admin, or `None` when no transfer is pending. + pub fn get_pending_admin(env: Env) -> Option
{ + env.storage() + .instance() + .get(&StorageKey::PendingAdmin) + } + /// Nominate a new admin (admin only). /// /// # Arguments diff --git a/contracts/settlement/src/test.rs b/contracts/settlement/src/test.rs index d426bab..9882d40 100644 --- a/contracts/settlement/src/test.rs +++ b/contracts/settlement/src/test.rs @@ -324,6 +324,38 @@ mod settlement_tests { assert_eq!(client.get_admin(), new_admin); } + #[test] + fn test_get_pending_admin_none_before_nomination() { + let env = Env::default(); + env.mock_all_auths(); + let admin = Address::generate(&env); + let vault = Address::generate(&env); + let addr = env.register(CalloraSettlement, ()); + let client = CalloraSettlementClient::new(&env, &addr); + client.init(&admin, &vault); + + assert_eq!(client.get_pending_admin(), None); + } + + #[test] + fn test_get_pending_admin_some_after_nomination() { + let env = Env::default(); + env.mock_all_auths(); + let admin = Address::generate(&env); + let vault = Address::generate(&env); + let new_admin = Address::generate(&env); + let addr = env.register(CalloraSettlement, ()); + let client = CalloraSettlementClient::new(&env, &addr); + client.init(&admin, &vault); + + client.set_admin(&admin, &new_admin); + assert_eq!(client.get_pending_admin(), Some(new_admin.clone())); + + // clears after acceptance + client.accept_admin(); + assert_eq!(client.get_pending_admin(), None); + } + #[test] #[should_panic(expected = "no admin transfer pending")] fn test_accept_admin_fails_if_not_nominated() { diff --git a/docs/interfaces/settlement.json b/docs/interfaces/settlement.json index ff3be12..a0989e0 100644 --- a/docs/interfaces/settlement.json +++ b/docs/interfaces/settlement.json @@ -137,6 +137,16 @@ "events": [] }, + { + "name": "get_pending_admin", + "description": "Return the pending admin address, or null if no two-step transfer is in progress. Integrators can poll this to detect an in-flight admin handover before accept_admin is called.", + "access": "any", + "params": [], + "returns": "Address | null", + "panics": [], + "events": [] + }, + { "name": "get_vault", "description": "Return the registered vault contract address.",