feat: implement Nostr NIP-01 WebSocket relay publishing #189
Reference in New Issue
Block a user
Delete Branch "feature/129-nostr-implementation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary\n\nImplements full Nostr protocol support (#129), replacing the stub with a working NIP-01 WebSocket relay publisher.\n\n- BIP-340 Schnorr signatures over secp256k1 using pure PHP + ext-gmp (no external dependencies)\n- Kind-1 text note events with SHA-256 event ID and BIP-340 tagged hashes for domain separation\n- Raw WebSocket client via
stream_socket_clientwith TLS support forwss://relays\n- Multi-relay failover: tries each configured relay until one accepts the event\n- Public key derivation from private key hex for account display in admin\n- Credential validation: 64-char hex private key format, wss:// relay URL scheme\n\n### Architecture\n\nUnlike all other service plugins (which use curl + REST APIs), Nostr is a cryptographic protocol:\n1. Private key stays on the server -- no API tokens sent to third parties\n2. Event is constructed, hashed (SHA-256), and signed (Schnorr) locally\n3. Signed event is pushed to relay(s) over WebSocket\n4. Relay responds with[\"OK\", event_id, true/false, message]\n\n### Requirements\n\n- PHP ext-gmp (for arbitrary-precision integer arithmetic in EC math)\n- Graceful error if ext-gmp is not installed\n\nCloses #129\n\n## Test plan\n\n- [ ] Verify PHP syntax check passes\n- [ ] Verify ext-gmp check returns clear error when extension is missing\n- [ ] Test credential validation with valid/invalid hex keys and relay URLs\n- [ ] Test publishing to a public Nostr relay (e.g., wss://relay.damus.io)\n- [ ] Verify event appears on a Nostr client (e.g., primal.net) under the derived pubkey\n- [ ] Test multi-relay failover with one invalid + one valid relay