Skip to content

Core Concepts

Before building with the DAO MESSAGE SDK, understand these fundamental design principles.

Zero-Knowledge Architecture

┌──────────┐         ┌──────────────┐         ┌──────────┐
│  Alice   │ ──E2E──▶│ Relay Server │──E2E──▶ │   Bob    │
│ (Client) │  cipher │ (Zero Know.) │ cipher  │ (Client) │
└──────────┘         └──────────────┘         └──────────┘

The relay server:

  • ✅ Forwards encrypted messages between clients
  • ✅ Stores ciphertext temporarily (24h TTL)
  • Cannot read message content
  • Cannot access encryption keys

Key Hierarchy

Every account is derived from a single 12-word BIP-39 mnemonic:

Mnemonic (12 words)
├── Ed25519 Key Pair    → Identity & Authentication (Challenge-Response)
└── X25519 Key Pair     → ECDH Key Exchange (Message Encryption)
  • Ed25519: Signs authentication challenges. Proves "I own this account."
  • X25519: Performs Diffie-Hellman key exchange. Produces per-conversation AES-256 session keys.
typescript
import { newMnemonic, deriveIdentity } from '@daomessage_sdk/sdk';

const mnemonic = newMnemonic(); // "abandon ability able about ..."
const identity = deriveIdentity(mnemonic);
// identity.signingKey  → Ed25519 (auth)
// identity.ecdhKey     → X25519 (encryption)

Session Model

When two users become friends, a session is established:

Alice's X25519 Public Key  ─┐
                             ├── ECDH → Shared Secret → AES-256-GCM Session Key
Bob's X25519 Public Key    ─┘

Each session has:

FieldDescription
conversationIdUnique ID shared by both parties
sessionKeyBase64AES-256 key for encrypting messages
trustState'unverified' or 'verified' (security code check)

Sessions are stored locally in IndexedDB — the server never knows session keys.

Message Flow

1. Alice types "Hello"
2. SDK encrypts with AES-256-GCM using the session key
3. Ciphertext → WebSocket → Relay Server
4. Relay Server routes to Bob's WebSocket (or stores for offline delivery)
5. Bob's SDK decrypts with the same session key
6. Plaintext "Hello" displayed in UI

Alias ID

Every user gets an alias ID (e.g., u12345678) at registration:

  • Format: u + 8 random digits
  • This is the public identifier used for messaging, friend requests, and routing
  • Users can optionally purchase a vanity ID (e.g., 888) during onboarding
  • Once bound, an alias ID cannot be changed

SDK-First Architecture

The SDK handles everything except the UI:

ResponsibilityOwner
Key generation & derivationSDK
Message encryption/decryptionSDK
WebSocket connection & reconnectionSDK
IndexedDB storage (identity, sessions, messages)SDK
Authentication (Challenge-Response + JWT)SDK
UI renderingYour App
User preferences (theme, notification settings)Your App
Navigation & routingYour App

Your app is just a UI shell that calls SDK methods and displays results.

Data Storage

All sensitive data is stored client-side in IndexedDB:

StoreContentsManaged By
identityMnemonic, keys, alias IDSDK
sessionsPer-contact AES session keysSDK
messagesDecrypted message historySDK
offlineInboxQueued messages for offline deliverySDK

The server stores:

  • Public keys (for key exchange)
  • Encrypted messages (24h TTL, then deleted)
  • Friend relationships (metadata only)

Next Steps

Zero-Knowledge E2EE Protocol — Decentralized Communication