From 9d20d2281f4698024b7be67d1b86178b4e8e2484 Mon Sep 17 00:00:00 2001 From: Clawd Date: Mon, 16 Feb 2026 12:12:37 -0800 Subject: Clean up project structure - Add README.md - Move benchmark files to benchmarks/ - Move PLAN.md to .claude/ - Add .gitignore --- PLAN.md | 186 ---------------------------------------------------------------- 1 file changed, 186 deletions(-) delete mode 100644 PLAN.md (limited to 'PLAN.md') diff --git a/PLAN.md b/PLAN.md deleted file mode 100644 index 39d8318..0000000 --- a/PLAN.md +++ /dev/null @@ -1,186 +0,0 @@ -# Minimal Nostr Go Library - Implementation Plan - -## Overview - -Build a minimal Go library for Nostr split into two modules: - -**Module 1: Core** (`nostr-go` root) - 1 external dep -- Types, signing, serialization -- `github.com/btcsuite/btcd/btcec/v2` - BIP-340 Schnorr signatures - -**Module 2: Relay** (`nostr-go/relay`) - 1 additional dep -- WebSocket connection, pub/sub -- `github.com/coder/websocket` - WebSocket library -- Imports core module - -Users who only need types/signing don't pull in websocket dependencies. - -## Package Structure - -``` -nostr-go/ -├── go.mod # Core module -├── event.go # Event struct, ID computation, serialization -├── tags.go # Tag/Tags types and helpers -├── kinds.go # Event kind constants -├── filter.go # Filter struct and matching logic -├── keys.go # Key generation, signing, verification -├── bech32.go # Bech32 encoding/decoding (our impl, ~150 lines) -├── nip19.go # npub/nsec/note/nprofile encode/decode -├── envelope.go # Protocol messages (EVENT, REQ, OK, etc.) -├── *_test.go -│ -└── relay/ - ├── go.mod # Relay module (imports core) - ├── relay.go # WebSocket connection primitives - ├── subscription.go # Subscription handling - └── *_test.go -``` - -## Core Types - -### Event (event.go) -```go -type Event struct { - ID string `json:"id"` // 64-char hex (SHA256) - PubKey string `json:"pubkey"` // 64-char hex (x-only pubkey) - CreatedAt int64 `json:"created_at"` - Kind int `json:"kind"` - Tags Tags `json:"tags"` - Content string `json:"content"` - Sig string `json:"sig"` // 128-char hex (Schnorr sig) -} -``` - -**Design note**: Starting with hex strings for simplicity. Can evaluate byte arrays (`[32]byte`, `[64]byte`) later if type safety becomes important. - -Key methods: -- `Serialize() []byte` - Canonical JSON for ID computation: `[0,"pubkey",created_at,kind,tags,"content"]` -- `ComputeID() string` - SHA256 hash of serialized form -- `Sign(privKeyHex string) error` - Sign with Schnorr, sets PubKey/ID/Sig -- `Verify() bool` - Verify signature - -### Tags (tags.go) -```go -type Tag []string -type Tags []Tag -``` -Methods: `Key()`, `Value()`, `Find(key)`, `FindAll(key)`, `GetD()` - -### Filter (filter.go) -```go -type Filter struct { - IDs []string `json:"ids,omitempty"` - Kinds []int `json:"kinds,omitempty"` - Authors []string `json:"authors,omitempty"` - Tags map[string][]string `json:"-"` // Custom marshal for #e, #p - Since *int64 `json:"since,omitempty"` - Until *int64 `json:"until,omitempty"` - Limit int `json:"limit,omitempty"` -} -``` -Methods: `Matches(event) bool`, custom `MarshalJSON`/`UnmarshalJSON` for tag filters - -### Kinds (kinds.go) -Essential constants only: -```go -const ( - KindMetadata = 0 - KindTextNote = 1 - KindContactList = 3 - KindEncryptedDM = 4 - KindDeletion = 5 - KindRepost = 6 - KindReaction = 7 -) -``` -Helpers: `IsRegular()`, `IsReplaceable()`, `IsEphemeral()`, `IsAddressable()` - -### Envelopes (envelope.go) -Protocol messages as types with `Label()` and `MarshalJSON()`: -- Client→Relay: `EventEnvelope`, `ReqEnvelope`, `CloseEnvelope` -- Relay→Client: `EventEnvelope`, `OKEnvelope`, `EOSEEnvelope`, `ClosedEnvelope`, `NoticeEnvelope` -- `ParseEnvelope(data []byte) (Envelope, error)` - -## Keys & Signing (keys.go) - -Using `github.com/btcsuite/btcd/btcec/v2/schnorr`: -```go -func GenerateKey() (string, error) -func GetPublicKey(privKeyHex string) (string, error) -func (e *Event) Sign(privKeyHex string) error -func (e *Event) Verify() bool -``` - -## NIP-19 Encoding (nip19.go) - -Bech32 encoding for human-readable identifiers: -```go -func EncodePublicKey(pubKeyHex string) (string, error) // -> npub1... -func EncodeSecretKey(secKeyHex string) (string, error) // -> nsec1... -func EncodeNote(eventID string) (string, error) // -> note1... - -func DecodePublicKey(npub string) (string, error) // npub1... -> hex -func DecodeSecretKey(nsec string) (string, error) // nsec1... -> hex -func DecodeNote(note string) (string, error) // note1... -> hex - -// TLV-encoded types (nprofile, nevent, naddr) can be added later -``` - -## WebSocket Primitives (relay.go) - -Simple design - no complex goroutine orchestration: -```go -type Relay struct { - URL string - conn *websocket.Conn - mu sync.Mutex -} - -func Connect(ctx context.Context, url string) (*Relay, error) -func (r *Relay) Close() error -func (r *Relay) Send(ctx context.Context, env Envelope) error -func (r *Relay) Receive(ctx context.Context) (Envelope, error) -func (r *Relay) Publish(ctx context.Context, event *Event) error -func (r *Relay) Subscribe(ctx context.Context, id string, filters ...Filter) (*Subscription, error) - -type Subscription struct { - ID string - Events chan *Event - EOSE chan struct{} -} -func (s *Subscription) Listen() error -func (s *Subscription) Close() error -``` - -## Implementation Order - -### Phase 1: Core Module (nostr-go) -1. **go.mod** - Module definition with btcec/v2 dependency -2. **event.go, tags.go, kinds.go** - Core types, serialization, ID computation -3. **keys.go** - Schnorr signing with btcec/v2 -4. **bech32.go** - Bech32 encode/decode (~150 lines) -5. **nip19.go** - npub/nsec/note encoding -6. **filter.go** - Filter struct with custom JSON and matching -7. **envelope.go** - All envelope types and ParseEnvelope -8. **Core tests** - -### Phase 2: Relay Module (nostr-go/relay) -1. **relay/go.mod** - Module definition with websocket dep, imports core -2. **relay/relay.go** - WebSocket connection primitives -3. **relay/subscription.go** - Subscription handling -4. **Relay tests** - -## What's Omitted (v0.1) - -- NIP-42 AUTH -- NIP-04 encrypted DMs -- Connection pooling / relay pool -- Automatic reconnection -- Advanced kinds (10000+) - -## Verification - -1. Unit tests for each module -2. Integration test: connect to `wss://relay.damus.io`, publish event, subscribe -3. Verify signature interop with existing Nostr clients/libraries -- cgit v1.2.3