Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,089 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Armada

Canonical repository: gitworkshop.dev/soapbox.pub/armada — the GitLab repository is a read-only mirror.

Discord without the company. No host required. Your keys, your people.

Armada is an end-to-end encrypted community chat app built on Nostr — servers, channels, threads, voice, and moderation, everything you expect from a chat app. Nobody can read your messages, sell your data, or shut your community down.

Communities are serverless by default, built on Concord: a serverless, end-to-end encrypted community protocol. Spin up a community with nothing to set up and nobody in the middle — text channels, live voice rooms, and invites, all without running a server. Communities ride as gift-wrapped Nostr events over ordinary relays; only members can read them.

Armada also supports NIP-29 relay-based groups for operators who want a relay-backed server that owns membership, moderation, and data — point the client at any NIP-29 relay.

This repository is the client — the web app (React 19 + Vite + Tailwind + shadcn/ui + Nostrify), the Capacitor Android project (android/), and the Electron desktop shell (electron/). It does not depend on the backend at build time; it talks to relays and voice brokers over runtime-configurable URLs.

Concepts

  • Concord communities — serverless, E2EE. All control/chat/invite/rekey traffic is gift-wrapped (NIP-59) over generic Nostr relays; voice uses a blind LiveKit token broker (CORD-07) that learns nothing about the community. The full protocol lives client-side under src/concord-v2/. Armada's client-specific Concord conventions are documented in CORD.md, the CORD analog of a project's NIP.md.
  • NIP-29 servers — relays act as servers; channels are NIP-29 groups. Requires a relay to point at (use any external NIP-29 relay).
  • Auth — sign in with your key: nsec, NIP-07 extension, or NIP-46 bunker/nostrconnect. Your identity is portable across devices.
  • App relays — configurable general-purpose relays for non-community traffic (profiles, lists). Defaults to relay.ditto.pub + relay.dreamith.to; editable in Settings and at build time (VITE_APP_RELAYS).
  • Voice — WebRTC audio via LiveKit, E2E-encrypted client-side under per-sender keys.

Development

npm install
npm run dev        # http://localhost:8080
npm run test       # tsc + eslint + vitest + production build

Voice requires a secure context for microphone access: localhost works out of the box; other hostnames need HTTPS.

Configuration (build-time env)

  • VITE_KLIPY_API_KEYoptional. GIF search uses the keyless GIFverse provider by default. Set this to switch GIF search to KLIPY instead; leave it empty (the default) to keep GIFverse. KLIPY additionally sends a per-install customer_id on every request and injects sponsored results, which is why it is opt-in. Set it in CI as the repository secret KLIPY_API_KEY, or in .env.local for local development. Like every key used by a browser-only API integration, it is embedded in the compiled client bundle; keeping it in a secret keeps it out of source/history, not out of browser developer tools. Configure any available platform restrictions in KLIPY's partner panel.
  • VITE_PLATFORM_RELAYS — comma-separated pinned relay URLs. Empty by default (and in the shipped APK/desktop builds): a fresh client starts with no baked-in servers and the user adds their own. Never pin ws://localhost here — it's meaningless on a phone.
  • VITE_APP_RELAYS — default app relays for non-community traffic — profiles (kind 0), group lists (kind 10009) — in the style of Ditto's app relays (default wss://relay.ditto.pub,wss://relay.dreamith.to); users can edit the list in Settings, including removing all of them for air-gapped use.
  • VITE_SEARCH_RELAYS — relays used for NIP-50 full-text search (profile / mention autocomplete); search filters route only to these (default wss://relay.ditto.pub,wss://relay.dreamith.to). User-editable in Settings; when empty, search falls back to the app relays.
  • VITE_APP_BLOSSOM_SERVERS — comma-separated default Blossom media servers (BUD-03) uploads fall back to, in the style of VITE_APP_RELAYS (default https://blossom.ditto.pub/,https://blossom.dreamith.to/,https://blossom.primal.net/). User-editable in Settings, and can be turned off entirely with the "Use app media servers" toggle.
  • VITE_CONCORD_AV_SERVERS — fallback Concord voice (CORD-07) token brokers (default https://armada.buzz).
  • VITE_APP_NAME — display name.

Packaging

  • Android — Capacitor project in android/. npx vite build && npx cap sync android, then build with Gradle. CI produces a signed APK/AAB on vX.Y.Z tags.
  • Desktop — Electron shell in electron/. Bundles the web build and serves it over a custom secure scheme. CI produces Linux/Windows/macOS installers on tags.
  • WebDockerfile (nginx-served static build) + nginx.conf.

License

AGPL-3.0

Third-party assets

  • Disappearing-message timer icon — the 13 clock frames in src/components/chat/ExpirationTimerIcon.tsx are the ic_timer_NN_12 vector drawables from Signal-Android (app/src/main/res/drawable/), copyright Signal Messenger, LLC, converted from Android <vector> pathData to SVG d attributes with the geometry unchanged. Signal-Android is licensed AGPL-3.0, the same license as Armada, so the copy is license-compatible; the frames remain under their original copyright and license.

About

Encrypted communities with text and voice. No host required. Your keys, your fleet.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages