Architecture Overview
DAO Launcher Kit uses a sophisticated multi-canister microservices architecture with 9 specialized canisters on the Internet Computer.
🏗️ Design Principle
Separation of Concerns: Each canister has a specific responsibility, enabling independent scaling, upgrades, and maintenance.
System Components
dao_backend (Coordinator)
The central coordination hub managing users, permissions, and orchestrating communication between other canisters.
Responsibilities:
- User profile management and registration
- Admin role assignment and permissions
- Inter-canister communication coordination
- DAO initialization and configuration
governance
Manages the complete proposal lifecycle including creation, voting, and execution.
Dependencies:
- dao_backend: User authentication and membership verification
- staking: Voting power calculation based on staked tokens
staking
Handles token locking, rewards distribution, and voting power calculations.
Key Features:
- Lock tokens for specified duration
- Calculate time-weighted voting power
- Distribute staking rewards proportionally
- Automatic reward compounding
treasury
Multi-signature wallet for DAO financial operations with balance tracking.
Security Features:
- Multi-signature approval requirements
- Transaction history and audit trail
- Role-based access control
- Automatic proposal execution integration
Support Canisters
dao_registry
Global DAO discovery system enabling search, categorization, and trending DAOs across the platform.
dao_analytics
Tracks platform-wide metrics including time-series data, growth rates, and governance statistics.
proposals
Manages proposal templates, categorization, and execution logic for different proposal types.
assets
File storage system with metadata, tags, and public/private access control.
icrc1_ledger
ICRC1 token standard implementation for balance tracking and token transfers.
Inter-Canister Communication
Canisters communicate using typed actor interfaces in Motoko:
// Example: dao_backend calling staking canister
let stakingActor = actor("canister:staking") : StakingService;
let votingPower = await stakingActor.getVotingPower(userPrincipal); Note: All inter-canister calls are asynchronous and type-safe, preventing runtime errors from incorrect message formats.
Upgrade Safety
Stable Storage Pattern
All canisters use upgrade-safe state management:
// Stable storage (persists across upgrades)
private stable var userEntries : [(Principal, UserProfile)] = [];
// Runtime optimization (rebuilt after upgrade)
private var users = HashMap.HashMap<Principal, UserProfile>(...);
system func preupgrade() {
userEntries := Iter.toArray(users.entries());
}
system func postupgrade() {
users := HashMap.fromIter(userEntries.vals(), ...);
} Deployment Order
Correct deployment order is critical due to dependencies:
- Base canisters: dao_backend, dao_registry, dao_analytics, staking, treasury, proposals, assets
- Governance: Requires dao_backend and staking Principal IDs as init args
- ICRC1 Ledger: Token standard with initialization parameters
- Wire connections: Set ledger canister ID in staking
- Frontend: Generate declarations, build, and deploy
💡 Use ./deploy.sh for local or
./scripts/deploy-mainnet.sh for production deployment.