Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions contracts/identity-registry-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,37 @@ pub fn batch_ban_experts(env: Env, experts: Vec<Address>) -> Result<(), Registry
Ok(())
}

pub fn verify_expert(env: &Env, expert: &Address, data_uri: String) -> Result<(), RegistryError> {
/// Add a moderator (Admin only)
pub fn add_moderator(env: &Env, moderator: &Address) -> Result<(), RegistryError> {
let admin = storage::get_admin(env).ok_or(RegistryError::NotInitialized)?;
admin.require_auth();
storage::set_moderator(env, moderator);
Ok(())
}

/// Remove a moderator (Admin only)
pub fn remove_moderator(env: &Env, moderator: &Address) -> Result<(), RegistryError> {
let admin = storage::get_admin(env).ok_or(RegistryError::NotInitialized)?;
admin.require_auth();
storage::remove_moderator(env, moderator);
Ok(())
}

pub fn verify_expert(
env: &Env,
caller: &Address,
expert: &Address,
data_uri: String,
) -> Result<(), RegistryError> {
let admin = storage::get_admin(env).ok_or(RegistryError::NotInitialized)?;

if caller == &admin {
admin.require_auth();
} else if storage::is_moderator(env, caller) {
caller.require_auth();
} else {
return Err(RegistryError::Unauthorized);
}

let current_status = storage::get_expert_status(env, expert);

Expand All @@ -85,16 +112,23 @@ pub fn verify_expert(env: &Env, expert: &Address, data_uri: String) -> Result<()
expert.clone(),
current_status,
ExpertStatus::Verified,
admin,
caller.clone(),
);

Ok(())
}

/// Ban an expert by setting their status to Banned (Admin only)
pub fn ban_expert(env: &Env, expert: &Address) -> Result<(), RegistryError> {
/// Ban an expert by setting their status to Banned (Admin or Moderator)
pub fn ban_expert(env: &Env, caller: &Address, expert: &Address) -> Result<(), RegistryError> {
let admin = storage::get_admin(env).ok_or(RegistryError::NotInitialized)?;
admin.require_auth();

if caller == &admin {
admin.require_auth();
} else if storage::is_moderator(env, caller) {
caller.require_auth();
} else {
return Err(RegistryError::Unauthorized);
}

let current_status = storage::get_expert_status(env, expert);

Expand All @@ -111,7 +145,7 @@ pub fn ban_expert(env: &Env, expert: &Address) -> Result<(), RegistryError> {
expert.clone(),
current_status,
ExpertStatus::Banned,
admin,
caller.clone(),
);

Ok(())
Expand Down
1 change: 1 addition & 0 deletions contracts/identity-registry-contract/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ pub enum RegistryError {
NotVerified = 8,
UriTooLong = 9,
NotBanned = 10,
Unauthorized = 11,
}
27 changes: 21 additions & 6 deletions contracts/identity-registry-contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ impl IdentityRegistryContract {
contract::initialize_registry(&env, &admin)
}

/// Add a moderator (Admin only)
pub fn add_moderator(env: Env, moderator: Address) -> Result<(), RegistryError> {
contract::add_moderator(&env, &moderator)
}

/// Remove a moderator (Admin only)
pub fn remove_moderator(env: Env, moderator: Address) -> Result<(), RegistryError> {
contract::remove_moderator(&env, &moderator)
}

/// Batch Add an expert to the whitelist (Admin only)
pub fn batch_add_experts(env: Env, experts: Vec<Address>) -> Result<(), RegistryError> {
contract::batch_add_experts(env, experts)
Expand All @@ -32,15 +42,20 @@ impl IdentityRegistryContract {
contract::batch_ban_experts(env, experts)
}

/// Add an expert to the whitelist (Admin only)
/// Add an expert to the whitelist (Admin or Moderator)
/// Also saves a profile data_uri reference (e.g., ipfs://...)
pub fn add_expert(env: Env, expert: Address, data_uri: String) -> Result<(), RegistryError> {
contract::verify_expert(&env, &expert, data_uri)
pub fn add_expert(
env: Env,
caller: Address,
expert: Address,
data_uri: String,
) -> Result<(), RegistryError> {
contract::verify_expert(&env, &caller, &expert, data_uri)
}

/// Ban an expert and revoke their verification status (Admin only)
pub fn ban_expert(env: Env, expert: Address) -> Result<(), RegistryError> {
contract::ban_expert(&env, &expert)
/// Ban an expert and revoke their verification status (Admin or Moderator)
pub fn ban_expert(env: Env, caller: Address, expert: Address) -> Result<(), RegistryError> {
contract::ban_expert(&env, &caller, &expert)
}

/// Unban an expert and restore their verification status (Admin only)
Expand Down
25 changes: 25 additions & 0 deletions contracts/identity-registry-contract/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub enum DataKey {
Expert(Address),
VerifiedExpertIndex(u64),
TotalVerifiedCount,
Moderator(Address),
}

// Constants for TTL (Time To Live)
Expand Down Expand Up @@ -40,6 +41,30 @@ pub fn get_admin(env: &Env) -> Option<Address> {
env.storage().instance().get(&DataKey::Admin)
}

// ... [Moderator Helpers] ...

/// Check if an address is a moderator
pub fn is_moderator(env: &Env, address: &Address) -> bool {
env.storage()
.instance()
.get(&DataKey::Moderator(address.clone()))
.unwrap_or(false)
}

/// Set an address as a moderator
pub fn set_moderator(env: &Env, address: &Address) {
env.storage()
.instance()
.set(&DataKey::Moderator(address.clone()), &true);
}

/// Remove an address from moderators
pub fn remove_moderator(env: &Env, address: &Address) {
env.storage()
.instance()
.remove(&DataKey::Moderator(address.clone()));
}

// ... [Expert Helpers] ...

/// Set the expert record with status, data_uri and timestamp
Expand Down
Loading
Loading