97 lines
5.4 KiB
Markdown
97 lines
5.4 KiB
Markdown
# NOSTR COMMS MIGRATION — FINAL STATUS
|
|
|
|
## Infrastructure Status
|
|
|
|
### What Works
|
|
- **Nostr relay**: RUNNING on relay.alexanderwhitestone.com:2929
|
|
- Software: relay29 (khatru29, fiatjaf) — NIP-29 groups
|
|
- Database: LMDB persistent
|
|
- Service: systemd enabled, survived reboots
|
|
- Memory: 6.7MB, CPU: 8.3s total
|
|
- Accepts WebSocket connections (verified via netcat)
|
|
- **Agent keys**: 7 keypairs exist in ~/.timmy/nostr/agent_keys.json
|
|
- Timmy, Claude, Gemini, Groq, Grok, Hermes, Alexander
|
|
- **DM bridge**: RUNNING nostr-bridge (polls every 60s for DMs, creates Gitea issues)
|
|
- Fixed double-URL bug (http://https://forge -> https://forge)
|
|
- **Gitea reporting**: gitea_report.py exists for posting status to issues
|
|
- **Relay source**: /root/nostr-relay/ — Go binary, LMDB backend, NIP-29 groups
|
|
|
|
### What's Blocked
|
|
- **NIP-42 AUTH handshake**: The relay requires authentication before accepting events
|
|
- Relay returns `["AUTH", challenge]` after EVENT submission
|
|
- We sign a kind 22242 auth event but relay rejects with "signature is invalid"
|
|
- Tested: nostr-sdk v0.44.2, pynostr, coincurve raw — all produce invalid signatures
|
|
- Root cause likely: the nostr Python SDK's sign_event() uses ECDSA not schnorr for 22242
|
|
- The relay29/khatru29 implementation validates using go-nostr schnorr
|
|
|
|
### What Needs to Happen
|
|
1. **Fix NIP-42 auth** — Option A: disable auth requirement on relay (add `state.AllowEvent` returning true in main.go). Option B: fix the Python signature to use proper schnorr.
|
|
2. **Create NIP-29 group** — Group code was generated but metadata posting failed due to auth.
|
|
3. **Wire Hermes to Nostr** — Replace Telegram send_message with Nostr relay POST.
|
|
4. **Deprecate Telegram** — Set to fallback-only mode.
|
|
5. **Alexander's phone client** — Needs a Nostr client installed (Damus on iOS).
|
|
|
|
## The Epic and Issues (Filed on timmy-home)
|
|
|
|
| Issue | Assignee | Priority | Status |
|
|
|-------|----------|----------|--------|
|
|
| [EPIC] Sovereign Comms Migration | — | — | FILED |
|
|
| P0: Wire Timmy Hermes to Nostr | Timmy | P0 | BLOCKED (auth) |
|
|
| P0: Create Nostr group NIP-29 | Allegro | P0 | BLOCKED (auth) |
|
|
| P1: Build Nostr clients per wizard | Ezra | P1 | NOT STARTED |
|
|
| P1: Alexander receive-side | Allegro | P1 | NOT STARTED |
|
|
| P1: Deprecate Telegram fallback | Allegro | P1 | NOT STARTED |
|
|
| P2: Nostr-to-Gitea bridge | ClawCode | P2 | BRIDGE EXISTS (URL bug fixed) |
|
|
|
|
## Files Created This Session
|
|
|
|
- `~/.timmy/nostr/post_via_vps.py` — Nostr client with raw websocket posting
|
|
- `~/.timmy/nostr/post_raw.py` — Direct coincurve + websocket implementation
|
|
- `~/.timmy/nostr/post_nip42.py` — NIP-42 auth implementation
|
|
- `~/.timmy/nostr/post_via_vps.py` — SSH-to-VPS relay posting
|
|
- `~/.timmy/nostr/nostr_client.py` — Full Nostr client (sign + post)
|
|
- `~/.timmy/nostr/COMMS_MIGRATION.md` — Integration guide with all docs
|
|
- `~/.timmy/nostr/COMMS_STATUS.md` — This file
|
|
- `~/.timmy/nostr/group_config.json` — Group config (code changes each attempt)
|
|
|
|
## Key Findings
|
|
|
|
1. **The relay is live and healthy.** It works — we just can't write to it yet because auth is broken.
|
|
2. **pynostr's sign_event() works for regular events** — tested successfully, produces valid signatures.
|
|
3. **NIP-42 auth (kind 22242) is the blocker** — The relay's khatru29 implementation validates the 22242 event's schnorr signature against the challenge. Our signatures don't match what the Go code expects.
|
|
4. **The DM bridge works** — it polls for new DMs and creates Gitea issues. It just needs the correct GITEA URL (fixed: https://forge.alexanderwhitestone.com).
|
|
5. **coincurve.sign_schnorr() produces valid 64-byte schnorr signatures** — The issue might be that pynostr's sign_event() uses a different algorithm than what khatru29 expects for the 22242 kind.
|
|
6. **The relay's private key** is in the RELAY_PRIVKEY env var — could use admin powers to bypass auth or create the group directly.
|
|
|
|
## Next Session Action Plan
|
|
|
|
### Quick Fix (5 min)
|
|
On the VPS, add to /root/nostr-relay/main.go relay29 options:
|
|
```go
|
|
state.AllowEvent = func(context.Context, nostr.Event, string) (bool, string) {
|
|
return true, "" // allow all events, no auth required
|
|
}
|
|
```
|
|
Then rebuild and restart. This opens the relay for writes so we can create the group and test the full pipeline.
|
|
|
|
### Proper Fix (30 min)
|
|
The pynostr Event class doesn't have sign_schnorr() — it uses sign_event() which does standard Nostr signing (sha256 of serialized event + schnorr of the id). But for NIP-42 auth, the signed payload should be the challenge string, not the event id. Need to sign the challenge directly with coincurve's sign_schnorr() on the raw challenge bytes, then build the event manually.
|
|
|
|
### Full Pipeline (1 hr)
|
|
Once auth works:
|
|
1. Create the NIP-29 group (kind 39000 with d tag)
|
|
2. Post test messages (kind 1 and kind 9)
|
|
3. Wire Hermes morning report to Nostr client instead of Telegram
|
|
4. Add Alexander to the group
|
|
5. Set Telegram to fallback-only
|
|
|
|
## Nostr Relay Access
|
|
|
|
- **WebSocket**: ws://relay.alexanderwhitestone.com:2929 (or ws://127.0.0.1:2929 on VPS)
|
|
- **Timmy npub**: npub1qwyndfwvwy4edlwgtg3jlssawg7aj36t78fqyk30ehtyd82j22nqzt5m94
|
|
- **Timmy hex_pub**: 038936a5cc712b96fdc85a232fc21d723dd9474bf1d2025a2fcdd6469d5252a6
|
|
- **Keys file**: ~/.timmy/nostr/agent_keys.json
|
|
- **Group code**: Will be set once group creation succeeds
|
|
- **Bridge service**: nostr-bridge.service — polls DMs every 60s, creates Gitea issues
|
|
- **Bridge code**: /root/nostr-relay/dm_bridge_mvp.py — uses nostr-sdk (not pynostr)
|