Documentation
Control Room
The Control Room (/admin) is the platform operator dashboard. It provides an overview of listed properties, rent distribution tooling, investor registry, and analytics. Access it from the top navigation or by visiting /admin directly.
Access
The admin panel is currently publicly accessible for hackathon demo purposes β there is no on-chain auth gate in this version. In a production build the panel would be restricted to wallets holding an admin NFT or mapped to a whitelisted deployer address.
Tabs
Properties
Live property roster and listing wizard
Displays all properties currently in the platform with their status, total supply, amount funded, and a primary action button. The table mirrors the data from app/lib/propertiesData.ts.
Listing Wizard β clicking "Add Property" opens a 5-step modal. Steps 1β4 collect metadata (name, location, description, token economics, document links). Step 5 shows a success screen. Note: the wizard does not call PropertyToken.deploy() in this version β it is a UI prototype for the listing flow.
Rent Distribution
USDT rent deposit and equal-share distribution
This panel is built around the RentDistributor contract. The workflow has two stages:
- UI only
1. Deposit Rent
Operator enters a USDT amount and clicks "Deposit Rent USDT". The UI shows a confirmation dialog. In this demo version the button has no on-chain handler attached β a production build would call RentDistributor.depositRent(propertyToken, amount).
- Simulated
2. Distribute Rent
After deposit, operator clicks "Distribute Rent". A simulated 6.5-second countdown runs (via setTimeout), then shows a success screen with a hardcoded transaction hash (0xabc...def). The real on-chain call would be RentDistributor.distributeRent(propertyToken).
On-chain contract: RentDistributor is fully deployed and tested. It splits USDT equally across all token holders using distributeRent(). 17 tests cover deposit, distribution, and edge cases. The admin UI front-end for this flow is a demo UI layer β the contract itself is production-ready.
Registry
Investor wallet list and KYC status
Shows a table of registered investor wallets with their KYC status, country, and token holdings. Operators can search and filter by status.
Demo data: The three wallet rows shown (0x1Abβ¦3F4, 0x5Cdβ¦8G9, 0x2Efβ¦1H2) are hardcoded placeholders with fake KYC states and countries. In production this panel would query the InvestorRegistry contract for real registered addresses and their approval status.
The InvestorRegistry contract is deployed on Arbitrum Sepolia. Functions: registerInvestor(wallet), approveInvestor(wallet), revokeInvestor(wallet), isApproved(wallet).
Analytics
Platform-wide performance metrics
Displays headline KPIs β total volume, active investors, properties funded, average transaction time.
Static figures: The "347 wallets" and "31 sec avg" values are hardcoded for the demo. A production build would derive these from on-chain event logs β indexing TokensPurchased, Transfer, and RentDistributed events.
Live vs Demo Summary
Listing Wizard β Step by Step
Basic Info
Property name, city, country, asset type (Residential / Commercial / Mixed). All fields required before advancing.
Description
Long-form description of the property. Min 50 characters enforced.
Token Economics
Total supply (USDT), price per token, target raise, expected annual yield %. Calculated fields shown live.
Documents
IPFS CID fields for SPV Agreement, Valuation Report, and Lease Agreement. Links are validated on-page.
Success Screen
Animated checkmark + "Property Listed Successfully!" message. No contract is called. Modal can be closed after this step.
Productionizing the Control Room
- βAuth gate: Require deployer wallet or admin NFT to access /admin β redirect others to /.
- βListing Wizard: Wire step 5 to deploy a new PropertyToken contract via ethers/wagmi writeContract, store address in deployments.json.
- βDeposit Rent: Add onClick that calls USDT.approve(RentDistributor, amount) then RentDistributor.depositRent(propertyToken, amount).
- βDistribute Rent: Replace setTimeout mock with waitForTransactionReceipt on the real distributeRent() tx hash.
- βRegistry: Replace hardcoded rows with useContractRead calls to InvestorRegistry.getRegisteredInvestors().
- βAnalytics: Index TokensPurchased + Transfer events (via The Graph or viem getLogs) and aggregate for real KPIs.