|
| 1 | +//! # Event Registry Contract |
| 2 | +//! |
| 3 | +//! ## Overview |
| 4 | +//! |
| 5 | +//! The `event-registry` crate is the central on-chain registry for the Agora Events platform, |
| 6 | +//! deployed on the [Soroban](https://soroban.stellar.org) smart-contract runtime on Stellar. |
| 7 | +//! It is the single source of truth for every event that exists on the platform: creation, |
| 8 | +//! status transitions, inventory tracking, organizer management, and fee configuration all |
| 9 | +//! live here. |
| 10 | +//! |
| 11 | +//! ## Architecture |
| 12 | +//! |
| 13 | +//! The crate is organised into five focused modules: |
| 14 | +//! |
| 15 | +//! | Module | Responsibility | |
| 16 | +//! |--------|---------------| |
| 17 | +//! | [`lib`](crate) | Public contract entry-points exposed via `#[contractimpl]` | |
| 18 | +//! | [`types`] | All `#[contracttype]` structs and enums shared across modules | |
| 19 | +//! | [`storage`] | Thin wrappers around `env.storage()` – one function per data key | |
| 20 | +//! | [`events`] | Soroban event structs and the [`AgoraEvent`](crate::events::AgoraEvent) topic enum | |
| 21 | +//! | [`error`] | The [`EventRegistryError`](crate::error::EventRegistryError) enum returned by every fallible function | |
| 22 | +//! |
| 23 | +//! ### Key data types |
| 24 | +//! |
| 25 | +//! * [`EventInfo`](crate::types::EventInfo) – the full on-chain record for a registered event, |
| 26 | +//! including tiered pricing ([`TicketTier`](crate::types::TicketTier)), supply counters, |
| 27 | +//! milestone plans, and status flags. |
| 28 | +//! * [`MultiSigConfig`](crate::types::MultiSigConfig) – multi-admin governance configuration |
| 29 | +//! with a configurable approval threshold. |
| 30 | +//! * [`OrganizerStake`](crate::types::OrganizerStake) – collateral staked by organizers to |
| 31 | +//! unlock *Verified* status and earn proportional staking rewards. |
| 32 | +//! * [`GuestProfile`](crate::types::GuestProfile) – per-attendee loyalty score and spend history. |
| 33 | +//! * [`SeriesRegistry`](crate::types::SeriesRegistry) / [`SeriesPass`](crate::types::SeriesPass) – |
| 34 | +//! grouping of related events into a series with reusable season passes. |
| 35 | +//! |
| 36 | +//! ### Storage strategy |
| 37 | +//! |
| 38 | +//! All state is kept in **persistent** storage so that it survives ledger expiry. Large |
| 39 | +//! per-organizer lists (event IDs, receipts) are sharded into fixed-size buckets of 50 entries |
| 40 | +//! each to stay within Soroban's per-entry size limits. |
| 41 | +//! |
| 42 | +//! ## Usage |
| 43 | +//! |
| 44 | +//! ### Initialisation |
| 45 | +//! |
| 46 | +//! The contract must be initialised exactly once by calling [`EventRegistry::initialize`]: |
| 47 | +//! |
| 48 | +//! ```text |
| 49 | +//! EventRegistry::initialize(env, admin, platform_wallet, platform_fee_bps, usdc_token) |
| 50 | +//! ``` |
| 51 | +//! |
| 52 | +//! This sets the admin, platform wallet, default fee rate (in basis points), and automatically |
| 53 | +//! whitelists the provided USDC token for payments. |
| 54 | +//! |
| 55 | +//! ### Registering an event |
| 56 | +//! |
| 57 | +//! Organizers call [`EventRegistry::register_event`] with an |
| 58 | +//! [`EventRegistrationArgs`](crate::types::EventRegistrationArgs) struct that bundles the event |
| 59 | +//! ID, payment address, IPFS metadata CID, supply cap, and one or more |
| 60 | +//! [`TicketTier`](crate::types::TicketTier) entries. |
| 61 | +//! |
| 62 | +//! ### Interaction with TicketPayment |
| 63 | +//! |
| 64 | +//! `EventRegistry` and the companion `TicketPayment` contract work together to process ticket |
| 65 | +//! sales while keeping inventory consistent: |
| 66 | +//! |
| 67 | +//! 1. **Registration** – the platform admin calls |
| 68 | +//! [`EventRegistry::set_ticket_payment_contract`] once to record the `TicketPayment` |
| 69 | +//! contract address on-chain. |
| 70 | +//! 2. **Purchase flow** – when a buyer purchases a ticket, `TicketPayment` handles the token |
| 71 | +//! transfer and fee split, then calls [`EventRegistry::increment_inventory`] to atomically |
| 72 | +//! increment the per-tier and global supply counters. `EventRegistry` enforces that only |
| 73 | +//! the registered `TicketPayment` address may call this function |
| 74 | +//! (`ticket_payment_addr.require_auth()`), preventing unauthorised supply manipulation. |
| 75 | +//! 3. **Refund flow** – when a refund is approved, `TicketPayment` calls |
| 76 | +//! [`EventRegistry::decrement_inventory`] to roll back the supply counters, again gated |
| 77 | +//! behind the same address check. |
| 78 | +//! 4. **Payment info** – `TicketPayment` can query [`EventRegistry::get_event_payment_info`] |
| 79 | +//! to retrieve the current fee rates and tier pricing for a given event before processing |
| 80 | +//! a payment. |
| 81 | +//! |
| 82 | +//! This separation of concerns means `EventRegistry` never touches tokens directly; all |
| 83 | +//! financial logic lives in `TicketPayment`, while `EventRegistry` remains the authoritative |
| 84 | +//! registry for event state and inventory. |
| 85 | +
|
1 | 86 | #![no_std] |
2 | 87 |
|
3 | 88 | use crate::events::{ |
|
0 commit comments