Skip to content

Mobile Client Implementation Guide

Source of truth:

  • d3chat/frontend/src/store/*.ts
  • d3chat/frontend/src/crypto/*.ts
  • d3chat/backend/app/routers/*.py
  • d3chat/backend/app/websocket/*.py

This guide defines a practical mobile implementation contract so a native app can be built with no repository context.

Required Feature Phases

Phase 1 - Auth and Session

Implement:

  1. register/login flows
  2. token storage and refresh rotation
  3. logout + logout-all
  4. websocket ticket acquisition and connection

Acceptance criteria:

  • app survives process restart with session restore
  • 401 triggers refresh once then clean logout

Phase 2 - Core Messaging

Implement:

  1. channel list
  2. message pagination (before, limit)
  3. send/edit/delete
  4. typing indicators and membership list

Acceptance criteria:

  • no duplicate messages on ws + HTTP merge
  • pagination stable under high volume

Phase 3 - Encryption

Implement:

  1. device key bootstrap (/keys/upload)
  2. OTP replenishment (/keys/one-time)
  3. DM encryption via X3DH setup endpoints
  4. group encryption via sender keys and ratchet

Critical note:

  • sender-key decryption must be sequential per sender device due to ratchet semantics.

Phase 4 - Admin Surfaces (optional per app role)

Implement for admin-capable builds:

  1. dashboard stats and analytics
  2. user moderation
  3. channel moderation
  4. settings read/update
  5. audit log viewer

Local Persistence Contract

Persist at minimum:

  • access_token
  • refresh_token
  • device_id
  • user_id

And local crypto material equivalent to web IndexedDB key store:

  • identity key pair
  • signed pre-key
  • signing key pair
  • one-time prekeys
  • session keys per DM channel
  • sender chain keys per (channel_id, sender_device_id)
  • plaintext cache by message id (important for own sender-key messages)

Realtime Integration Pattern

Startup

  1. restore tokens
  2. fetch /users/me
  3. connect websocket via ticket
  4. load channels
  5. load active channel messages

On channel.new

  1. insert/update channel list
  2. optionally auto-subscribe explicitly using subscribe event

On message.new

  1. dedupe by message.id
  2. decrypt based on channel.encryption_type
  3. append chronologically

API Sequencing for DM Encryption

For first DM message in a channel:

  1. fetch members of DM
  2. fetch recipient key bundles
  3. establish initiator X3DH session
  4. store setup data /keys/channels/{id}/x3dh-setup
  5. encrypt and send message with protocol_version=2

Responder path:

  1. fetch setup data from endpoint
  2. derive responder session
  3. decrypt payload

API Sequencing for Group Encryption

  1. ensure sender key exists locally
  2. if missing, generate and POST /keys/channels/{id}/sender-keys
  3. encrypt with ratcheted message key
  4. send message with protocol_version=2 and sender_device_id
  5. on receive, decrypt sequentially by sender device

Known Edge Cases

  1. Own sender-key messages may be undecryptable if plaintext cache was lost, because ratchet is one-way.
  2. Federation-discovered users may appear after lookup and need local identity normalization.
  3. Network retries for message send should avoid duplicate submission unless server idempotency key is introduced.
  4. Background reconnect should back off exponentially.

Test Checklist for Mobile Readiness

  1. Fresh install, register, restart app, session restored.
  2. Two-device same user receives channel.new updates.
  3. DM first-message encryption/decryption succeeds both directions.
  4. Group message order maintained across reconnect.
  5. OTP low warning handling path (listen for keys.low_otp).
  6. Admin moderation actions reflected in UI and enforceable on subsequent login.