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
111 changes: 109 additions & 2 deletions contracts/aid-contract/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
#![no_std]
7-aid-initialization
use soroban_sdk::{
contract, contractimpl, contracterror, panic_with_error, token, symbol_short, Address, Env, Symbol, Map,
};
use shared::events::{emit_aid_created, emit_action_executed, emit_module_initialized, emit_permission_changed};
use shared::{emit, AID_CLAIMED, AID_CREATED, AID_REFUNDED, AID_SETTLED, Error};
use shared::storage::is_paused;

const KEY_AIDS: Symbol = symbol_short!("aids");

main

use shared::events::{
emit_action_executed, emit_aid_created, emit_module_initialized, emit_permission_changed,
Expand Down Expand Up @@ -50,21 +61,117 @@ impl AidContract {
// Lifecycle
// -----------------------------------------------------------------------

/// Initialise the contract with an admin and the escrow token.
/// Initialize the contract with configuration.
///
/// Must be called exactly once immediately after deployment.
pub fn initialize(env: Env, admin: Address, token: Address) {
///
/// # Arguments
/// * `admin` - The admin address with governance privileges.
/// * `treasury` - The treasury address for fees or emergency withdrawals.
/// * `token` - The accepted escrow token address.
/// * `default_expiry_secs` - Default expiration time in seconds for new aids.
///
/// # Errors
/// * [`shared::Error::AlreadyInitialized`] - If called more than once.
pub fn initialize(
env: Env,
admin: Address,
treasury: Address,
token: Address,
default_expiry_secs: u64,
) -> Result<(), shared::Error> {
// Guard against re-initialization
if storage::is_initialized(&env) {
return Err(shared::Error::AlreadyInitialized);
}

admin.require_auth();

// Store configuration
shared::auth::set_admin(&env, &admin);
7-aid-initialization
storage::set_treasury(&env, &treasury);
storage::set_token(&env, &token);
storage::set_default_expiry(&env, default_expiry_secs);
storage::set_initialized(&env);


main
emit_module_initialized(
&env,
symbol_short!("aid"),
1,
&admin,
env.ledger().timestamp(),
);
7-aid-initialization

Ok(())
}

/// Get the admin address.
pub fn get_admin(env: Env) -> Address {
shared::auth::get_admin(&env)
}

/// Get the treasury address.
pub fn get_treasury(env: Env) -> Option<Address> {
storage::get_treasury(&env)
}

/// Get the escrow token address.
pub fn get_token(env: Env) -> Option<Address> {
storage::get_token(&env)
}

/// Get the default expiry in seconds.
pub fn get_default_expiry(env: Env) -> Option<u64> {
storage::get_default_expiry(&env)
}

/// Check if the contract is initialized.
pub fn is_initialized(env: Env) -> bool {
storage::is_initialized(&env)
}

/// Update configuration (admin only).
///
/// # Arguments
/// * `admin` - Must be the current admin.
/// * `treasury` - New treasury address (None = keep existing).
/// * `default_expiry_secs` - New default expiry (None = keep existing).
///
/// # Errors
/// * [`shared::Error::Unauthorized`] - If caller is not admin.
pub fn update_config(
env: Env,
admin: Address,
treasury: Option<Address>,
default_expiry_secs: Option<u64>,
) -> Result<(), shared::Error> {
// Verify admin authorization
let current_admin = shared::auth::get_admin(&env);
if admin != current_admin {
return Err(shared::Error::Unauthorized);
}
admin.require_auth();

// Update treasury if provided
if let Some(t) = treasury {
storage::set_treasury(&env, &t);
}

// Update default expiry if provided
if let Some(e) = default_expiry_secs {
storage::set_default_expiry(&env, e);
}

Ok(())

env.storage()
.instance()
.set(&storage::DataKey::Token, &token);
main
}

// -----------------------------------------------------------------------
Expand Down
48 changes: 48 additions & 0 deletions contracts/aid-contract/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ pub enum DataKey {
AidCounter,
/// Token address escrowed by this contract (instance).
Token,
/// Treasury address (instance).
Treasury,
/// Default expiry in seconds (instance).
DefaultExpiry,
/// Configuration marker (instance) - set on initialize.
Initialized,
/// Append-only list of aid IDs created by a donor (persistent).
DonorIndex(Address),
/// Append-only list of aid IDs assigned to a recipient (persistent).
Expand Down Expand Up @@ -139,4 +145,46 @@ pub fn append_recipient_index(env: &Env, recipient: &Address, aid_id: u64) {
let mut ids = get_recipient_index(env, recipient);
ids.push_back(aid_id);
persistent_set(env, &DataKey::RecipientIndex(recipient.clone()), &ids);


// ---------------------------------------------------------------------------
// Treasury address — instance storage
// ---------------------------------------------------------------------------

/// Read the configured treasury address, if initialised.
pub fn get_treasury(env: &Env) -> Option<Address> {
instance_get(env, &DataKey::Treasury)
}

/// Store the treasury address (initialisation only).
pub fn set_treasury(env: &Env, treasury: &Address) {
instance_set(env, &DataKey::Treasury, treasury);
}

// ---------------------------------------------------------------------------
// Default expiry — instance storage
// ---------------------------------------------------------------------------

/// Read the default expiry in seconds, if set.
pub fn get_default_expiry(env: &Env) -> Option<u64> {
instance_get(env, &DataKey::DefaultExpiry)
}

/// Store the default expiry in seconds.
pub fn set_default_expiry(env: &Env, expiry_secs: u64) {
instance_set(env, &DataKey::DefaultExpiry, &expiry_secs);
}

// ---------------------------------------------------------------------------
// Initialization flag — instance storage
// ---------------------------------------------------------------------------

/// Check if the contract has been initialized.
pub fn is_initialized(env: &Env) -> bool {
instance_get::<DataKey, bool>(env, &DataKey::Initialized).unwrap_or(false)
}

/// Mark the contract as initialized.
pub fn set_initialized(env: &Env) {
instance_set(env, &DataKey::Initialized, &true);
}}
11 changes: 11 additions & 0 deletions contracts/aid-contract/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
use soroban_sdk::{contracttype, Address, Vec};


/// Contract configuration stored in instance storage.
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Config {
pub admin: Address,
pub treasury: Address,
pub token: Address,
pub default_expiry_secs: u64,
}

/// Lifecycle state of an aid record.
#[contracttype]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
Expand Down
Loading