Skip to content

[Frontend] Implement Centralized Toast/Notification System for Error and Success Messages #156

Description

@devJaja

🎯 Objective

Add configurable storage size limits per agent to prevent unbounded persistent storage growth in the agent_registry Soroban contract.


📁 Files to Modify

Action File Path Description
Modify smart-contracts/contracts/agent_registry/src/lib.rs Add max agent count, per-capability limits, and total_agents() read function

📁 Reference Files

File Path Purpose
smart-contracts/contracts/agent_registry/src/lib.rs (line ~183) append_capability_index — unbounded Vec growth
smart-contracts/contracts/agent_registry/src/lib.rs (line ~335) register_agent — where to add limit check
smart-contracts/contracts/agent_registry/src/lib.rs (GasConfig) Pattern for admin-configurable params

💥 Impact

  • Each agent record costs persistent storage rent on Stellar
  • Capability index Vec<Symbol> grows without limit per capability
  • lookup_agents iterates the entire vector — expensive for large sets
  • No way to know total agent count without full state scan

✅ Expected Implementation

1. Add Storage Config

#[contracttype]
pub struct StorageConfig {
    pub max_agents: u32,              // Global limit (0 = unlimited)
    pub max_per_capability: u32,      // Per-capability limit (0 = unlimited)
}

2. Add Storage Key

#[derive(Clone)]
pub enum DataKey {
    // ... existing ...
    StorageConfig,  // ADD
    TotalAgents,    // ADD: counter for fast total_agents() reads
}

3. Add Validation in register_agent

pub fn register_agent(env: Env, record: AgentParams) -> Result<(), Error> {
    // ... existing checks ...

    // Check global limit
    let config = get_storage_config(&env);
    if config.max_agents > 0 {
        let total = get_total_agents(&env);
        if total >= config.max_agents {
            return Err(Error::StorageLimitReached); // New error variant
        }
    }

    // Check per-capability limit
    if config.max_per_capability > 0 {
        let cap_index = get_capability_index(&env, &record.capability);
        if cap_index.len() >= config.max_per_capability {
            return Err(Error::CapabilityLimitReached); // New error variant
        }
    }

    // ... rest of registration ...
}

4. Add Read Function

pub fn total_agents(env: Env) -> u32 {
    get_total_agents(&env)
}

pub fn get_storage_config(env: Env) -> StorageConfig {
    env.storage()
        .instance()
        .get(&DataKey::StorageConfig)
        .unwrap_or(StorageConfig { max_agents: 0, max_per_capability: 0 })
}

5. Add Admin Configuration

pub fn set_storage_config(env: Env, config: StorageConfig) {
    let admin = get_admin(&env);
    admin.require_auth();
    env.storage().instance().set(&DataKey::StorageConfig, &config);
}

📁 Reference Patterns

File Path Pattern
smart-contracts/contracts/agent_registry/src/lib.rs (GasConfig) How admin-configurable params are stored
smart-contracts/contracts/agent_registry/src/lib.rs (set_gas_config) Admin auth pattern

✅ Acceptance Criteria

  • Add StorageConfig struct with max_agents and max_per_capability
  • Add DataKey::StorageConfig and DataKey::TotalAgents storage keys
  • Add total_agents() read-only function
  • Add get_storage_config() read-only function
  • Add set_storage_config(config) admin function
  • Add validation in register_agent for global limit
  • Add validation in register_agents batch for global limit
  • Add StorageLimitReached and CapabilityLimitReached error variants
  • Add unit tests for hitting limits
  • Add unit test: total_agents increments on registration
  • Add unit test: non-admin cannot set storage config

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions