Skip to content

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

CanisterPurposeKey Functions
auth-serviceSession management, authenticationlogin, validate_session, refresh_tokens
identity-gatewayInternet Identity integrationii_login_begin/complete, link_internet_identity

Core Services

CanisterPurposeKey Functions
user-serviceUser registration, profilescreate_account, get_user, begin_password_reset
membershipSoul-Bound Token credentialsmint_membership, verify_membership, renew_membership

Governance Layer

CanisterPurposeKey Functions
governanceProposals, voting (1M1V)create_proposal, cast_vote, finalize
treasuryPayment records, payoutsrecord_payment, propose_payout, execute_payout

Token Layer

CanisterPurposeKey Functions
dom-tokenICRC-1/2 token ledgericrc1_transfer, burn_with_policy
proof-nftsDeployment/Contributor NFTsmint_deployment_proof, mint_contributor_reward

Application Layer

CanisterPurposeKey Functions
otter-campCrowdfunding campaignscreate_campaign, contribute, process_donation
marketplaceVendor registry, productsregister_vendor, list_product, process_order
educationLearn-to-earn platformcreate_course, complete_lesson, mint_achievement

Data Flow Patterns

New Member Registration

User → Frontend → user-service → auth-service → membership
                      │                              │
                      ▼                              ▼
              Create account              Mint SBT (after payment)
  1. User submits registration form (email, password)
  2. user-service.create_account() validates and stores user
  3. auth-service creates session tokens
  4. 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:

  1. Email/Password (Argon2id hashing)
  2. Internet Identity (passkeys)
  3. 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:

ScenarioToken SharingNotes
Local DevelopmentAutomaticSame origin (127.0.0.1) shares localStorage
Production/StagingURL Token PassingDifferent 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 (in frontend/.env.local)
  • VITE_DAO_FRONTEND_URL - URL of DAO frontend (in foundery-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 ID

Voting 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% burn

Deflationary Mechanism:

  • Tokens burned are permanently removed from circulation
  • total_burned() query tracks cumulative burns
  • circulating_supply() = total - burned - treasury

Inter-Canister Communication

Session Validation Pattern

All session-protected operations validate through auth-service:

rust
// 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:

rust
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_transfer always returns NonTransferable error
  • 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:

rust
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:

rust
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

NetworkEndpointDomainPurpose
local127.0.0.1:4943-Development/testing
testnetic0.appstaging.helloworlddao.comTeam testing
mainnetic0.appwww.helloworlddao.comProduction

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

rust
// 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/CD

Each repository is independently versioned with its own git history.

Hello World Co-Op DAO