# areebahmeddd/airhop architecture

> Architecture diagram of the GitHub repository areebahmeddd/airhop, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-06). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/areebahmeddd/airhop
- Repository: https://github.com/areebahmeddd/airhop

## Overview

#### 1. Purpose and entry points
Airhop is an offline-first private messaging app for iOS and Android. It uses BLE mesh as its primary transport, with optional same-platform WiFi and Nostr internet bridging; it also supports Cashu ecash. The React Native/Expo application starts at `App.tsx`; native lifecycle hosts are `android/app/src/main/java/org/onemindlabs/airhop/MainApplication.kt` and `ios/Airhop/AppDelegate.swift`.

#### 2. UI and state boundary
Feature screens render chat, discovery, onboarding, settings, and wallet workflows over shared Zustand-backed client state. Stores hold conversations, contacts, mesh state, outbox, transfers, and wallet state; services own side effects and protocol orchestration rather than UI components.
- `src/features/chat/channel-list.tsx`
- `src/store/chat-store.ts`
- `src/store/mesh-state-store.ts`

#### 3. Messaging pipeline and mesh protocol
Outbound content is serialized into mesh packet formats, optionally compressed/fragmented, encrypted according to conversation type, then routed through the mesh. Inbound packets are decoded, deduplicated, reassembled, and synchronized into stores. Flood routing supports nearby multi-hop delivery; courier/prekey mechanisms cover delayed delivery.
- `src/services/mesh-service.ts`
- `src/core/mesh/packet-codec.ts`
- `src/core/mesh/flood-router.ts`

#### 4. Identity, sessions, and private groups
Device-local Ed25519 identity anchors contacts and signatures. Contact establishment uses Noise handshakes; DMs gain forward secrecy via Double Ratchet. Channel, group, private-channel, and direct-message payload layers are distinct protocol/security boundaries.
- `src/core/crypto/identity.ts`
- `src/core/crypto/noise-xx.ts`
- `src/core/crypto/double-ratchet.ts`

#### 5. Transport abstraction and native boundary
TypeScript services invoke React Native native modules for radios and media. BLE is cross-platform and protocol-compatible with bitchat. Android adds BLE, WiFi Aware, foreground-service support, and voice modules; iOS supplies BLE, MultipeerConnectivity, voice, and Tor modules. Native availability, permissions, lifecycle, and background execution are important boundaries.
- `src/bridge/NativeAirhopBLE.ts`
- `android/app/src/main/java/org/onemindlabs/airhop/ble/AirhopBLEModule.kt`
- `ios/Airhop/AirhopBLEModule.swift`

#### 6. Nostr, geolocation, and privacy routing
When internet is enabled, Nostr relays carry DMs, presence, bridge events, courier traffic, and geohash-channel events—not attachment bytes. Relay selection incorporates a bundled relay dataset. Nostr envelopes/gift wrapping protect payloads, while Tor routing uses Arti on iOS and Orbot integration on Android.
- `src/core/nostr/nostr-client.ts`
- `src/core/nostr/gift-wrap.ts`
- `src/core/nostr/tor-routing.ts`

#### 7. Attachments, voice, and payments
Files and voice are mesh/WiFi payloads managed separately from small-message routing, with transfer state and retention policy. Cashu tokens are scanned, verified, transferred offline, persisted in the wallet, and later reconciled with external Cashu mints/Lightning only when network access is available.
- `src/services/file-transfer-service.ts`
- `src/services/voice-audio.ts`
- `src/services/wallet-service.ts`

#### 8. Supporting products and delivery
The mobile app is the core product. A separate Vite-based static landing site presents project information, while Android/iOS projects compile the bare Expo application. Release and CI automation live in GitHub Actions. External dependencies are BLE hardware, same-platform WiFi APIs, distributed Nostr relays, Tor/Orbot or bundled Arti, and user-selected Cashu mints.
- `landing/src/main.tsx`
- `android/app/build.gradle`
- `ios/Frameworks/arti.xcframework`

Main entry points: [`src/bridge/NativeAirhopBLE.ts`](https://github.com/areebahmeddd/airhop/blob/main/src/bridge/NativeAirhopBLE.ts) (Native BLE bridge), [`src/features/chat/channel-list.tsx`](https://github.com/areebahmeddd/airhop/blob/main/src/features/chat/channel-list.tsx) (Feature screens), [`src/services/mesh-service.ts`](https://github.com/areebahmeddd/airhop/blob/main/src/services/mesh-service.ts) (Mesh service), [`src/core/mesh/packet-codec.ts`](https://github.com/areebahmeddd/airhop/blob/main/src/core/mesh/packet-codec.ts) (Packet codec)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_mobile["Mobile app"]
  node_app["Expo app entry<br/>React Native<br/>[App.tsx]"]
  node_ui["Feature screens<br/>UI<br/>[channel-list.tsx]"]
  node_chat_store[("Chat state<br/>Zustand store<br/>[chat-store.ts]")]
  node_mesh_store[("Mesh state<br/>Zustand store")]
end

subgraph group_mesh["Mesh messaging"]
  node_mesh_service["Mesh service<br/>protocol orchestration<br/>[mesh-service.ts]"]
  node_packet_codec["Packet codec<br/>mesh protocol<br/>[packet-codec.ts]"]
  node_flood_router["Flood router<br/>mesh routing<br/>[flood-router.ts]"]
end

subgraph group_security["Identity &amp; security"]
  node_identity["Device identity<br/>Ed25519 identity<br/>[identity.ts]"]
  node_noise["Contact handshake<br/>Noise XX<br/>[noise-xx.ts]"]
  node_ratchet["DM sessions<br/>Double Ratchet<br/>[double-ratchet.ts]"]
end

subgraph group_network["Internet bridging"]
  node_nostr_client["Nostr bridge<br/>relay client<br/>[nostr-client.ts]"]
  node_gift_wrap["Nostr envelopes<br/>gift wrap<br/>[gift-wrap.ts]"]
  node_tor["Tor routing<br/>privacy transport<br/>[tor-routing.ts]"]
  node_nostr_relays(("Nostr relays<br/>external network"))
end

subgraph group_media["Media &amp; payments"]
  node_file_transfer["File transfers<br/>payload service"]
  node_voice["Voice audio<br/>media service<br/>[voice-audio.ts]"]
  node_wallet["Cashu wallet<br/>payment service<br/>[wallet-service.ts]"]
  node_cashu_mints(("Cashu mints &amp; Lightning<br/>external payment network"))
end

subgraph group_platform["Native platforms"]
  node_native_bridge["Native BLE bridge<br/>React Native module<br/>[NativeAirhopBLE.ts]"]
  node_android_ble["Android native radios<br/>Kotlin native module<br/>[AirhopBLEModule.kt]"]
  node_ios_ble["iOS native radios<br/>Swift native module"]
end

node_landing["Landing site<br/>Vite static site<br/>[main.tsx]"]

node_app -->|"renders"| node_ui
node_ui -->|"reads and updates"| node_chat_store
node_ui -->|"observes"| node_mesh_store
node_ui -->|"wallet workflows"| node_wallet
node_chat_store -->|"outbox"| node_mesh_service
node_mesh_service -->|"encodes and decodes"| node_packet_codec
node_packet_codec -->|"encrypts DMs"| node_ratchet
node_ratchet -->|"established by"| node_noise
node_noise -->|"authenticates contacts"| node_identity
node_packet_codec -->|"routes packets"| node_flood_router
node_flood_router -->|"sends nearby"| node_native_bridge
node_native_bridge -->|"Android"| node_android_ble
node_native_bridge -->|"iOS"| node_ios_ble
node_mesh_service -->|"syncs inbound state"| node_mesh_store
node_mesh_service -.->|"optional internet bridge"| node_nostr_client
node_nostr_client -->|"wraps payloads"| node_gift_wrap
node_nostr_client -.->|"optional privacy route"| node_tor
node_tor -->|"connects"| node_nostr_relays
node_gift_wrap -->|"publishes"| node_nostr_relays
node_file_transfer -->|"mesh/WiFi payloads"| node_native_bridge
node_voice -->|"voice transport"| node_native_bridge
node_wallet -.->|"online reconciliation"| node_cashu_mints

click node_app "https://github.com/areebahmeddd/airhop/blob/main/App.tsx"
click node_ui "https://github.com/areebahmeddd/airhop/blob/main/src/features/chat/channel-list.tsx"
click node_chat_store "https://github.com/areebahmeddd/airhop/blob/main/src/store/chat-store.ts"
click node_mesh_store "https://github.com/areebahmeddd/airhop/blob/main/src/store/mesh-state-store.ts"
click node_mesh_service "https://github.com/areebahmeddd/airhop/blob/main/src/services/mesh-service.ts"
click node_packet_codec "https://github.com/areebahmeddd/airhop/blob/main/src/core/mesh/packet-codec.ts"
click node_flood_router "https://github.com/areebahmeddd/airhop/blob/main/src/core/mesh/flood-router.ts"
click node_identity "https://github.com/areebahmeddd/airhop/blob/main/src/core/crypto/identity.ts"
click node_noise "https://github.com/areebahmeddd/airhop/blob/main/src/core/crypto/noise-xx.ts"
click node_ratchet "https://github.com/areebahmeddd/airhop/blob/main/src/core/crypto/double-ratchet.ts"
click node_native_bridge "https://github.com/areebahmeddd/airhop/blob/main/src/bridge/NativeAirhopBLE.ts"
click node_android_ble "https://github.com/areebahmeddd/airhop/blob/main/android/app/src/main/java/org/onemindlabs/airhop/ble/AirhopBLEModule.kt"
click node_ios_ble "https://github.com/areebahmeddd/airhop/blob/main/ios/Airhop/AirhopBLEModule.swift"
click node_nostr_client "https://github.com/areebahmeddd/airhop/blob/main/src/core/nostr/nostr-client.ts"
click node_gift_wrap "https://github.com/areebahmeddd/airhop/blob/main/src/core/nostr/gift-wrap.ts"
click node_tor "https://github.com/areebahmeddd/airhop/blob/main/src/core/nostr/tor-routing.ts"
click node_file_transfer "https://github.com/areebahmeddd/airhop/blob/main/src/services/file-transfer-service.ts"
click node_voice "https://github.com/areebahmeddd/airhop/blob/main/src/services/voice-audio.ts"
click node_wallet "https://github.com/areebahmeddd/airhop/blob/main/src/services/wallet-service.ts"
click node_landing "https://github.com/areebahmeddd/airhop/blob/main/landing/src/main.tsx"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_ui,node_chat_store,node_mesh_store toneBlue
class node_mesh_service,node_packet_codec,node_flood_router toneAmber
class node_identity,node_noise,node_ratchet toneMint
class node_nostr_client,node_gift_wrap,node_tor,node_nostr_relays toneRose
class node_file_transfer,node_voice,node_wallet,node_cashu_mints toneIndigo
class node_native_bridge,node_android_ble,node_ios_ble toneTeal
class node_landing toneNeutral
```

## Components

### Mobile app

- [Expo app entry](https://github.com/areebahmeddd/airhop/blob/main/App.tsx): React Native · `App.tsx`
- [Feature screens](https://github.com/areebahmeddd/airhop/blob/main/src/features/chat/channel-list.tsx): UI · Chat, discovery, onboarding, settings, and wallet flows. · `src/features/chat/channel-list.tsx`
- [Chat state](https://github.com/areebahmeddd/airhop/blob/main/src/store/chat-store.ts): Zustand store · `src/store/chat-store.ts`
- [Mesh state](https://github.com/areebahmeddd/airhop/blob/main/src/store/mesh-state-store.ts): Zustand store · `src/store/mesh-state-store.ts`

### Mesh messaging

- [Mesh service](https://github.com/areebahmeddd/airhop/blob/main/src/services/mesh-service.ts): protocol orchestration · `src/services/mesh-service.ts`
- [Packet codec](https://github.com/areebahmeddd/airhop/blob/main/src/core/mesh/packet-codec.ts): mesh protocol · Serializes, compresses, fragments, decodes, deduplicates, and reassembles packets. · `src/core/mesh/packet-codec.ts`
- [Flood router](https://github.com/areebahmeddd/airhop/blob/main/src/core/mesh/flood-router.ts): mesh routing · Handles nearby multi-hop delivery and delayed courier paths. · `src/core/mesh/flood-router.ts`

### Identity & security

- [Device identity](https://github.com/areebahmeddd/airhop/blob/main/src/core/crypto/identity.ts): Ed25519 identity · Local identity anchors contacts and signatures. · `src/core/crypto/identity.ts`
- [Contact handshake](https://github.com/areebahmeddd/airhop/blob/main/src/core/crypto/noise-xx.ts): Noise XX · `src/core/crypto/noise-xx.ts`
- [DM sessions](https://github.com/areebahmeddd/airhop/blob/main/src/core/crypto/double-ratchet.ts): Double Ratchet · Provides forward secrecy for direct messages. · `src/core/crypto/double-ratchet.ts`

### Internet bridging

- [Nostr bridge](https://github.com/areebahmeddd/airhop/blob/main/src/core/nostr/nostr-client.ts): relay client · Carries wrapped messaging, presence, courier, and geohash events, not attachments. · `src/core/nostr/nostr-client.ts`
- [Nostr envelopes](https://github.com/areebahmeddd/airhop/blob/main/src/core/nostr/gift-wrap.ts): gift wrap · `src/core/nostr/gift-wrap.ts`
- [Tor routing](https://github.com/areebahmeddd/airhop/blob/main/src/core/nostr/tor-routing.ts): privacy transport · Uses Arti on iOS and Orbot on Android. · `src/core/nostr/tor-routing.ts`
- **Nostr relays**: external network

### Media & payments

- [File transfers](https://github.com/areebahmeddd/airhop/blob/main/src/services/file-transfer-service.ts): payload service · Manages mesh/WiFi attachment transfer state and retention. · `src/services/file-transfer-service.ts`
- [Voice audio](https://github.com/areebahmeddd/airhop/blob/main/src/services/voice-audio.ts): media service · `src/services/voice-audio.ts`
- [Cashu wallet](https://github.com/areebahmeddd/airhop/blob/main/src/services/wallet-service.ts): payment service · Verifies and transfers offline ecash, then reconciles with mints when online. · `src/services/wallet-service.ts`
- **Cashu mints & Lightning**: external payment network

### Native platforms

- [Native BLE bridge](https://github.com/areebahmeddd/airhop/blob/main/src/bridge/NativeAirhopBLE.ts): React Native module · `src/bridge/NativeAirhopBLE.ts`
- [Android native radios](https://github.com/areebahmeddd/airhop/blob/main/android/app/src/main/java/org/onemindlabs/airhop/ble/AirhopBLEModule.kt): Kotlin native module · BLE plus Android WiFi Aware, background service, and voice support. · `android/app/src/main/java/org/onemindlabs/airhop/ble/AirhopBLEModule.kt`
- [iOS native radios](https://github.com/areebahmeddd/airhop/blob/main/ios/Airhop/AirhopBLEModule.swift): Swift native module · BLE plus MultipeerConnectivity, voice, and Tor support. · `ios/Airhop/AirhopBLEModule.swift`

### Other components

- [Landing site](https://github.com/areebahmeddd/airhop/blob/main/landing/src/main.tsx): Vite static site · Separate project-information site. · `landing/src/main.tsx`

## Connections

- Expo app entry → Feature screens: renders
- Feature screens → Chat state: reads and updates
- Feature screens → Mesh state: observes
- Feature screens → Cashu wallet: wallet workflows
- Chat state → Mesh service: outbox
- Mesh service → Packet codec: encodes and decodes
- Packet codec → DM sessions: encrypts DMs
- DM sessions → Contact handshake: established by
- Contact handshake → Device identity: authenticates contacts
- Packet codec → Flood router: routes packets
- Flood router → Native BLE bridge: sends nearby
- Native BLE bridge → Android native radios: Android
- Native BLE bridge → iOS native radios: iOS
- Mesh service → Mesh state: syncs inbound state
- Mesh service → Nostr bridge: optional internet bridge
- Nostr bridge → Nostr envelopes: wraps payloads
- Nostr bridge → Tor routing: optional privacy route
- Tor routing → Nostr relays: connects
- Nostr envelopes → Nostr relays: publishes
- File transfers → Native BLE bridge: mesh/WiFi payloads
- Voice audio → Native BLE bridge: voice transport
- Cashu wallet → Cashu mints & Lightning: online reconciliation
