Architecture Overview
The multi-tenant system is built on a singleton pattern that loads tenant-specific configurations at runtime based on theNEXT_PUBLIC_AGORA_INSTANCE_NAME environment variable.
Key Components
The tenant system consists of four main factories:- TenantContractFactory - Loads blockchain contracts (governor, token, timelock)
- TenantUIFactory - Loads UI customization (colors, logos, copy)
- TenantTokenFactory - Configures governance token details
- TenantSlugFactory - Maps namespace to database slug
Configuration Structure
Environment Setup
Set the tenant namespace to determine which DAO configuration loads:Available tenant namespaces include:
optimism, ens, uniswap, etherfi, cyber, scroll, linea, boost, xai, b3, protocol-guild, towns, syndicate, and derive.Contract Configuration
Each tenant defines its contract addresses insrc/lib/tenant/configs/contracts/{namespace}.ts:
UI Configuration
Customize the UI for each tenant insrc/lib/tenant/configs/ui/{namespace}.ts:
Adding a New Tenant
Follow these steps to add a new DAO to Agora:1
Add namespace constant
Add your DAO to
src/lib/constants.ts:2
Create contract configuration
Create
src/lib/tenant/configs/contracts/your-dao.ts with your contract addresses, ABIs, and delegation model.3
Create UI configuration
Create
src/lib/tenant/configs/ui/your-dao.ts with branding, colors, and feature toggles.4
Update factories
Add cases to
TenantContractFactory and TenantUIFactory in their respective files to handle your new namespace.5
Configure environment
Set
NEXT_PUBLIC_AGORA_INSTANCE_NAME=your-dao in your .env.local file.Accessing Tenant Data
Access tenant configuration anywhere in your application:Brand Name Mapping
Customize how your DAO name appears throughout the UI:Delegation Models
Agora supports different delegation models per tenant:- FULL - Standard delegation (one delegatee)
- PARTIAL - Split delegation across multiple delegates
- ADVANCED - Alligator-style subdelegation chains
Database Namespacing
Each tenant has its own database schema for isolation:Feature Toggles
Control features per tenant using the toggle system:proposals- Enable/disable proposals pagedelegates- Enable/disable delegates pageproposal-lifecycle- Draft proposal systemdelegation-encouragement- Delegation CTAsproposal-execute- On-chain execution
Multi-Chain Support
Tenants can support tokens across multiple chains:src/lib/votingPowerUtils.ts:68 for implementation details.
Production Considerations
Best Practices
- Separate deployments - Deploy each tenant to its own domain for isolation
- Environment variables - Use different
.envfiles per tenant - Database isolation - Ensure proper schema separation in your database
- Contract verification - Always verify mainnet/testnet contract addresses
- Testing - Test tenant switching locally before deploying
Example Deployment
Troubleshooting
Tenant not loading
Ensure your namespace is defined inTENANT_NAMESPACES and has cases in both factory classes.
Wrong contracts loading
CheckNEXT_PUBLIC_AGORA_ENV - it controls prod vs dev contract addresses.
UI not updating
Restart dev server after changing tenant configuration files.Related Resources
- Governance Tokens - Token delegation mechanics
- Gasless Transactions - Relay system configuration
- Environment Variables - Full environment documentation