Architecture Overview
The Hello World Co-Op DAO platform is built on the Internet Computer Protocol (ICP) using a multi-canister architecture. This document covers the system design, data flows, and integration patterns.
System Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ Frontend Applications │
│ ┌─────────────────────────────────────────────────────────────────────┐│
│ │ frontend/ (DAO Dashboard, Otter Camp, Marketplace, Education) ││
│ └─────────────────────────────────────────────────────────────────────┘│
│ ┌─────────────────────────────────────────────────────────────────────┐│
│ │ foundery-os-suite/ (Productivity: Capture, Chat, Backlog, Fleet) ││
│ └─────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────┬───────────────────────────────────────┘
│ IC Agent / HTTP
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Internet Computer (IC) │
│ │
│ ┌─────────────────────────────┐ ┌────────────────────────────────────┐│
│ │ Authentication Layer │ │ Core Services ││
│ │ ┌───────────┐ ┌──────────┐ │ │ ┌────────────┐ ┌───────────────┐ ││
│ │ │auth-service│ │identity- │ │ │ │user-service│ │ membership │ ││
│ │ │ │ │ gateway │ │ │ │ │ │ (SBT NFT) │ ││
│ │ └───────────┘ └──────────┘ │ │ └────────────┘ └───────────────┘ ││
│ └─────────────────────────────┘ └────────────────────────────────────┘│
│ │
│ ┌─────────────────────────────┐ ┌────────────────────────────────────┐│
│ │ Governance Layer │ │ Token Layer ││
│ │ ┌───────────┐ ┌──────────┐ │ │ ┌────────────┐ ┌───────────────┐ ││
│ │ │governance │ │ treasury │ │ │ │ dom-token │ │ proof-nfts │ ││
│ │ │(Vote NFTs)│ │ │ │ │ │(ICRC-1/2) │ │ (ICRC-7/37) │ ││
│ │ └───────────┘ └──────────┘ │ │ └────────────┘ └───────────────┘ ││
│ └─────────────────────────────┘ └────────────────────────────────────┘│
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐│
│ │ Application Layer ││
│ │ ┌───────────┐ ┌────────────┐ ┌────────────┐ ││
│ │ │otter-camp │ │ marketplace│ │ education │ ││
│ │ │(Campaigns)│ │ (Commerce) │ │ (Learning) │ ││
│ │ └───────────┘ └────────────┘ └────────────┘ ││
│ └─────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Off-Chain Services │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ oracle-bridge │ │
│ │ • Stripe payment confirmation • Price feeds • Fiat gateway │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘Canister Responsibilities
Authentication Layer
| Canister | Purpose | Key Functions |
|---|---|---|
| auth-service | Session management, authentication | login, validate_session, refresh_tokens |
| identity-gateway | Internet Identity integration | ii_login_begin/complete, link_internet_identity |
Core Services
| Canister | Purpose | Key Functions |
|---|---|---|
| user-service | User registration, profiles | create_account, get_user, begin_password_reset |
| membership | Soul-Bound Token credentials | mint_membership, verify_membership, renew_membership |
Governance Layer
| Canister | Purpose | Key Functions |
|---|---|---|
| governance | Proposals, voting (1M1V) | create_proposal, cast_vote, finalize |
| treasury | Payment records, payouts | record_payment, propose_payout, execute_payout |
Token Layer
| Canister | Purpose | Key Functions |
|---|---|---|
| dom-token | ICRC-1/2 token ledger | icrc1_transfer, burn_with_policy |
| proof-nfts | Deployment/Contributor NFTs | mint_deployment_proof, mint_contributor_reward |
Application Layer
| Canister | Purpose | Key Functions |
|---|---|---|
| otter-camp | Crowdfunding campaigns | create_campaign, contribute, process_donation |
| marketplace | Vendor registry, products | register_vendor, list_product, process_order |
| education | Learn-to-earn platform | create_course, complete_lesson, mint_achievement |
Data Flow Patterns
New Member Registration
User → Frontend → user-service → auth-service → membership
│ │
▼ ▼
Create account Mint SBT (after payment)- User submits registration form (email, password)
user-service.create_account()validates and stores userauth-servicecreates session tokens- After KYC + payment,
membership.mint_membership()issues SBT
Authentication Flow
┌─────────────────────────────────────────────────────────────────────┐
│ Frontend Applications │
│ ┌───────────────────┐ ┌────────────────────────────┐ │
│ │ frontend/ │ │ foundery-os-suite/ │ │
│ │ (DAO Dashboard) │ │ (Productivity Suite) │ │
│ └─────────┬─────────┘ └─────────────┬──────────────┘ │
│ │ │ │
│ │ Shared Authentication │ │
│ └────────────────┬──────────────────────┘ │
│ ▼ │
└─────────────────────────────┬────────────────────────────────────────┘
│
▼
┌──────────────┐
│ auth-service │
│ (canister) │
└──────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────────┐
│ Email/Pass │ │Device Track│ │identity-gateway│
│ (Argon2id) │ │Rate Limit │ │(Internet ID) │
└────────────┘ └────────────┘ └────────────────┘Supported Auth Methods:
- Email/Password (Argon2id hashing)
- Internet Identity (passkeys)
- OAuth: Google, Apple, Microsoft, GitHub, Discord
Cross-App Authentication and Navigation (FOS-1.2.7): Both frontend/ and foundery-os-suite/ authenticate against the same auth-service canister and share authentication state:
| Scenario | Token Sharing | Notes |
|---|---|---|
| Local Development | Automatic | Same origin (127.0.0.1) shares localStorage |
| Production/Staging | URL Token Passing | Different canister URLs require token in URL param |
Navigation Links:
- DAO Dashboard → FounderyOS: "FounderyOS" card on Dashboard page
- FounderyOS → DAO Dashboard: "Back to DAO" link in sidebar footer
Environment Variables:
VITE_FOUNDERY_OS_URL- URL of foundery-os-suite (infrontend/.env.local)VITE_DAO_FRONTEND_URL- URL of DAO frontend (infoundery-os-suite/.env.local)
Token Storage Keys (shared between apps):
auth_access_token - JWT access token
auth_refresh_token - JWT refresh token
auth_access_expires - Access token expiry (ms)
auth_refresh_expires - Refresh token expiry (ms)
auth_user_id - User ID
auth_session_id - Session IDVoting Flow (1M1V)
Member → governance.create_proposal() → Draft (24h review)
│
▼
Active (voting)
│
┌─────────────────────────────────┴─────────────────────────────────┐
▼ ▼ ▼
cast_vote(Yes) cast_vote(No) cast_vote(Abstain)
+ Mint Vote-Pass NFT + Mint Vote-Pass NFT + Mint Vote-Pass NFT
│ │ │
└─────────────────────────────────┴─────────────────────────────────┘
│
▼
finalize() → Burn all Vote-Pass NFTs
│
▼
Approved/Rejected → execute_proposal()Key Points:
- 1 Member = 1 Vote (regardless of token holdings)
- Vote-Pass NFTs are Soul-Bound (non-transferable)
- NFTs burned after proposal finalization (audit trail preserved)
Token Burn Flow
User Action dom-token Burn Result
─────────────────────────────────────────────────────────────────
General Donation ──► burn_with_policy() ──► 1:1 burn rate
Ecological Donation ──► burn_with_policy() ──► 5:1 amplified
Marketplace < $50k ──► burn_with_policy() ──► 5% burn
Marketplace > $50k ──► burn_with_policy() ──► 7% burn
In-Game Purchase ──► burn_with_policy() ──► 5% burnDeflationary Mechanism:
- Tokens burned are permanently removed from circulation
total_burned()query tracks cumulative burnscirculating_supply()= total - burned - treasury
Inter-Canister Communication
Session Validation Pattern
All session-protected operations validate through auth-service:
// In any canister needing session validation
pub async fn protected_operation(session_token: String) -> Result<(), String> {
// Call auth-service to validate session
let validation: Result<SessionValidation, _> = ic_cdk::call(
AUTH_SERVICE_PRINCIPAL,
"validate_session",
(session_token,)
).await;
match validation {
Ok(Ok(session)) => {
// Session valid, proceed with operation
perform_operation(session.user_id)
}
_ => Err("Invalid session".to_string())
}
}Membership Verification Pattern
Canisters check membership status before privileged operations:
pub async fn member_only_action(caller: Principal) -> Result<(), String> {
let is_member: bool = ic_cdk::call(
MEMBERSHIP_PRINCIPAL,
"is_member",
(caller,)
).await.map_err(|_| "Membership check failed")?;
if !is_member {
return Err("Not a member".to_string());
}
// Proceed with member-only action
Ok(())
}ICRC Token Standards
ICRC-1/2 (Fungible Tokens - dom-token)
┌─────────────────────────────────────────────┐
│ dom-token │
│ │
│ ICRC-1: Basic token operations │
│ ├─ icrc1_transfer │
│ ├─ icrc1_balance_of │
│ └─ icrc1_total_supply │
│ │
│ ICRC-2: Approve/TransferFrom │
│ ├─ icrc2_approve │
│ └─ icrc2_transfer_from │
│ │
│ Custom: Burn policies │
│ └─ burn_with_policy (deflationary) │
└─────────────────────────────────────────────┘ICRC-7/37 (NFTs - membership, governance, proof-nfts, education)
┌─────────────────────────────────────────────┐
│ ICRC-7 NFT Standard │
│ │
│ Collection: icrc7_name, icrc7_symbol │
│ Ownership: icrc7_owner_of, icrc7_balance_of│
│ Transfer: icrc7_transfer (SBT: disabled) │
│ │
│ ICRC-37: Metadata extensions │
│ └─ icrc7_token_metadata │
└─────────────────────────────────────────────┘Soul-Bound Token (SBT) Implementation:
icrc7_transferalways returnsNonTransferableerror- Tokens bound to principal forever (or until burned)
- Used for: Membership, Vote-Passes, Achievements
State Management
Canister State Pattern
Each canister uses thread-local storage with RefCell:
use std::cell::RefCell;
thread_local! {
static STATE: RefCell<State> = RefCell::new(State::default());
}
#[derive(Default)]
struct State {
users: HashMap<Principal, User>,
sessions: HashMap<String, Session>,
config: Config,
}
// Safe state access
fn with_state<R>(f: impl FnOnce(&State) -> R) -> R {
STATE.with(|s| f(&s.borrow()))
}
fn with_state_mut<R>(f: impl FnOnce(&mut State) -> R) -> R {
STATE.with(|s| f(&mut s.borrow_mut()))
}Stable Storage
For upgrade-safe persistence:
use ic_cdk::storage;
#[ic_cdk::pre_upgrade]
fn pre_upgrade() {
let state = STATE.with(|s| s.borrow().clone());
storage::stable_save((state,)).expect("Failed to save state");
}
#[ic_cdk::post_upgrade]
fn post_upgrade() {
let (state,): (State,) = storage::stable_restore()
.expect("Failed to restore state");
STATE.with(|s| *s.borrow_mut() = state);
}Network Configuration
| Network | Endpoint | Domain | Purpose |
|---|---|---|---|
| local | 127.0.0.1:4943 | - | Development/testing |
| testnet | ic0.app | staging.helloworlddao.com | Team testing |
| mainnet | ic0.app | www.helloworlddao.com | Production |
Note: IC has no separate testnet. Both staging and production deploy to IC mainnet with different canister IDs.
Security Architecture
Authentication Security
┌──────────────────────────────────────────────────────────┐
│ Security Layers │
├──────────────────────────────────────────────────────────┤
│ 1. Password Hashing: Argon2id (memory-hard) │
│ 2. Session Tokens: Dual-token (access + refresh) │
│ 3. Device Tracking: Fingerprint + IP-based │
│ 4. Rate Limiting: Per-IP and per-user │
│ 5. Email Enumeration Prevention: Generic responses │
└──────────────────────────────────────────────────────────┘Inter-Canister Authorization
// Controller-only operations
fn require_controller() -> Result<(), String> {
let caller = ic_cdk::caller();
let controllers = ic_cdk::api::canister_self().controllers();
if !controllers.contains(&caller) {
return Err("Unauthorized: controller only".to_string());
}
Ok(())
}Deployment Architecture
GitHub Repository
│
▼
GitHub Actions (CI/CD)
│
├─► Build WASM + Candid metadata
│
├─► Run tests
│
└─► Deploy to IC
│
├─► Staging (auto on main merge)
│
└─► Production (manual /deploy command)All deployments use GitHub Actions - manual dfx deploy is prohibited.
Repository Structure
~/git/
├── hello-world-workspace/ # VS Code workspace config
├── docs/ # Documentation (577+ files)
├── auth-service/ # Session management canister
├── user-service/ # User registration canister
├── membership/ # SBT membership canister
├── governance/ # Proposal/voting canister
├── treasury/ # Payment/payout canister
├── dom-token/ # ICRC-1/2 token ledger
├── identity-gateway/ # Internet Identity canister
├── otter-camp/ # Crowdfunding canister
├── marketplace/ # Commerce canister
├── proof-nfts/ # Achievement NFT canister
├── education/ # Learn-to-earn canister
├── frontend/ # DAO Dashboard React application
├── foundery-os-suite/ # Productivity Suite React application
├── foundery-os-core/ # Productivity data canister (captures, sprints)
├── foundery-os-agents/ # AI Agent service (off-chain)
├── oracle-bridge/ # Off-chain signer service
└── ops-infra/ # Infrastructure & CI/CDEach repository is independently versioned with its own git history.