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
16 changes: 15 additions & 1 deletion contracts/payment-vault-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ use crate::error::VaultError;
use crate::events;
use crate::storage;
use crate::types::{BookingRecord, BookingStatus};
use soroban_sdk::{token, Address, Env};
use soroban_sdk::{token, Address, Env, Symbol};

pub fn initialize_vault(
env: &Env,
admin: &Address,
token: &Address,
oracle: &Address,
registry: &Address,
) -> Result<(), VaultError> {
// 1. Check if already initialized
if storage::has_admin(env) {
Expand All @@ -19,6 +20,7 @@ pub fn initialize_vault(
storage::set_admin(env, admin);
storage::set_token(env, token);
storage::set_oracle(env, oracle);
storage::set_registry_address(env, registry);

Ok(())
}
Expand Down Expand Up @@ -65,6 +67,18 @@ pub fn book_session(
// Require authorization from the user creating the booking
user.require_auth();

// Verify expert is verified via Identity Registry cross-contract call
let registry_address = storage::get_registry_address(env).ok_or(VaultError::NotInitialized)?;
let is_verified: bool = env.invoke_contract(
&registry_address,
&Symbol::new(env, "is_verified"),
soroban_sdk::vec![env, expert.to_val()],
);

if !is_verified {
return Err(VaultError::ExpertNotVerified);
}

// Fetch the expert's rate
let rate_per_second =
storage::get_expert_rate(env, expert).ok_or(VaultError::ExpertRateNotSet)?;
Expand Down
1 change: 1 addition & 0 deletions contracts/payment-vault-contract/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ pub enum VaultError {
ReclaimTooEarly = 7,
ContractPaused = 8,
ExpertRateNotSet = 9,
ExpertNotVerified = 10,
}
5 changes: 3 additions & 2 deletions contracts/payment-vault-contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ pub struct PaymentVaultContract;

#[contractimpl]
impl PaymentVaultContract {
/// Initialize the vault with the Admin, the Payment Token, and the Oracle (Backend)
/// Initialize the vault with the Admin, the Payment Token, the Oracle (Backend), and the Identity Registry
pub fn init(
env: Env,
admin: Address,
token: Address,
oracle: Address,
registry: Address,
) -> Result<(), VaultError> {
contract::initialize_vault(&env, &admin, &token, &oracle)
contract::initialize_vault(&env, &admin, &token, &oracle, &registry)
}

/// Pause the contract (Admin-only)
Expand Down
20 changes: 16 additions & 4 deletions contracts/payment-vault-contract/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ pub enum DataKey {
Admin,
Token,
Oracle,
Booking(u64), // Booking ID -> BookingRecord
BookingCounter, // Counter for generating unique booking IDs
RegistryAddress,
Booking(u64), // Booking ID -> BookingRecord
BookingCounter, // Counter for generating unique booking IDs
UserBookings(Address), // User Address -> Vec<u64> of booking IDs
ExpertBookings(Address), // Expert Address -> Vec<u64> of booking IDs
IsPaused, // Circuit breaker flag
// ── Indexed User Booking List ──────────────────────────────────────────
// Replaces the old Vec<u64> approach with O(1) per-write composite keys.
UserBooking(Address, u32), // (user, index) -> booking_id
UserBookingCount(Address), // user -> total count (u32)
// ── Indexed Expert Booking List ────────────────────────────────────────
ExpertBooking(Address, u32), // (expert, index) -> booking_id
ExpertBookingCount(Address), // expert -> total count (u32)
IsPaused, // Circuit breaker flag
ExpertRate(Address), // Expert Address -> rate per second (i128)
ExpertRate(Address), // Expert Address -> rate per second (i128)
}

// --- Admin ---
Expand Down Expand Up @@ -52,6 +55,15 @@ pub fn get_oracle(env: &Env) -> Address {
env.storage().instance().get(&DataKey::Oracle).unwrap()
}

// --- Registry (Identity) ---
pub fn set_registry_address(env: &Env, registry: &Address) {
env.storage().instance().set(&DataKey::RegistryAddress, registry);
}

pub fn get_registry_address(env: &Env) -> Option<Address> {
env.storage().instance().get(&DataKey::RegistryAddress)
}

// --- Pause (Circuit Breaker) ---
pub fn set_paused(env: &Env, paused: bool) {
env.storage().instance().set(&DataKey::IsPaused, &paused);
Expand Down
Loading
Loading