SHORTWAVE

Run & Use

How to run Shortwave locally, run the de-risk script, use the chat UI, and install it on your phone.

Run & Use

Prerequisites

  • Node.js 20+
  • npm 10+
  • An internet connection (for Nostr relay access in dev)

Local development

# Clone
git clone git@github.com:mechaforge/shortwave.git
cd shortwave

# Install dependencies
npm install

# Start dev server
npm run dev

Open http://localhost:3000 — home / landing page.
Open http://localhost:3000/chat — the encrypted DM channel UI.
Open http://localhost:3000/docs — this docs site.


M0 de-risk script

Run this first. Proves the NIP-17/NIP-44/NIP-59 JS crypto end-to-end.

npx tsx scripts/derisk-nip17.ts

Expected output:

── NIP-17 DE-RISK ──────────────────────────────────────────
  Alice pubkey : bc171ef70cce34a3…
  Bob   pubkey : 4a9f2c81de053b7e…
  Wrapped event id : 7c3f1a92b0de45f1…
  Wrapped event kind : 1059
  Connected to 2/2 relay(s)
  Published to 2/2 relay(s)
  Bob received   : "shortwave-derisk-1749456000000"
  Content match  : YES

NIP-17 DERISK PASS

Using the chat UI (manual two-browser test)

The /chat route is the full Shortwave instrument UI (forged-2 design).

First visit — identity

On first load, the app generates a fresh Nostr keypair and persists it in localStorage.
Your pubkey appears in the bottom identity panel as npub1… and OP-XXXX.

Add a contact

  1. Click + Add in the operator rail (left sidebar)
  2. Paste the contact's npub1… or 64-char hex pubkey
  3. Enter an optional handle (e.g. DETHKLAW)
  4. Press Enter or click Add

The contact appears in the rail. Click them to open the channel.

Send a message

Type in the compose bar at the bottom right and press ↵ Enter or click Send.

The message is NIP-17 gift-wrapped and published to all connected relays. It appears immediately in your ledger thread with a sent state marker.

Receive a message

Have the other person add your npub as a contact and send you a message.
The /chat page subscribes to all incoming kind:1059 events for your pubkey on startup.
Incoming messages appear in the thread with a recv state marker.

Two-browser test

  1. Open Tab A at http://localhost:3000/chat. Copy your npub from the identity panel.
  2. Open Tab B at http://localhost:3000/chat (incognito/different browser to get a fresh keypair). Copy Tab B's npub.
  3. In Tab A: Add Tab B's npub as a contact → open channel → send a message.
  4. In Tab B: Add Tab A's npub as a contact → open channel.
  5. Tab B receives the message within a few seconds (relay round-trip ~2–10s).
  6. Reply from Tab B → Tab A receives.

Caveats:

  • Same-browser tabs share localStorage and therefore the same identity. Use a different browser or incognito for the second identity.
  • Relay connectivity varies; if one relay is down, the other handles delivery.
  • Messages are ephemeral — they exist in-memory only. Refreshing the page clears the thread (by design — no plaintext persistence).

Build

npm run build

Should exit with 0 errors and produce the route table showing /chat at ~40 kB.


Type-check

npm run typecheck

docker run -d \
  --name strfry \
  -p 7777:7777 \
  -v $(pwd)/strfry-data:/app/strfry-db \
  ghcr.io/hoytech/strfry:latest

# .env.local
NEXT_PUBLIC_LOCAL_RELAY=ws://127.0.0.1:7777

Shortwave connects to this relay in addition to the public relays, publishing to all simultaneously.



Install on your phone (PWA)

Shortwave is installable as a Progressive Web App on iOS and Android. Once installed it launches full-screen (no browser chrome) and works as a native-feeling app.

iOS (Safari)

  1. Open the deployed Shortwave URL in Safari on iPhone or iPad.
  2. Tap the Share button (rectangle with an arrow pointing up).
  3. Scroll down in the share sheet and tap Add to Home Screen.
  4. Edit the name if you wish, then tap Add.
  5. The Shortwave icon appears on your home screen. Tap it to launch standalone.

Note: Safari is required for PWA installation on iOS — Chrome/Firefox on iOS cannot install PWAs.

Android (Chrome)

  1. Open the deployed Shortwave URL in Chrome.
  2. Chrome will show an Install app banner at the bottom, or tap the three-dot menu → Add to home screen.
  3. Tap Install in the prompt.
  4. Shortwave appears in your app drawer and home screen.

Mobile UX (< 600px)

On mobile the app uses the mobile-1 layout:

  • Screen A — Operators list: lists all your added operators with a preview of the last message. Your identity strip is docked at the bottom. Tap + Add to add an operator by pubkey.
  • Screen B — Conversation: tap any operator to open the encrypted channel. Messages appear as stacked transmission cards. Outbound cards align right with a green right-rule; inbound left. The compose bar is pinned above the home indicator safe area.
  • Back affordance: tap ‹ in the top bar to return to the operators list.

All controls are ≥ 44px touch targets. The thread and operators list use momentum scroll.


Security notes

  • Rotate keys before sharing with your circle. The keys generated by scripts/derisk-nip17.ts are throwaway test keys.
  • localStorage is MVP-only. No passphrase protection yet (M5). Don't use on a device you don't trust.
  • Client-side crypto only. Keys and plaintext never leave the browser; no server involved.
  • For hardened use, run the rc-cli Rust core directly — no browser attack surface.