Add addresses chapter
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# Plan: Addresses
|
||||
|
||||
## Overview
|
||||
|
||||
This chapter introduces the `Address` struct — a stable reference to a replaceable or
|
||||
addressable event. Where an event ID is a hash of a specific version, an address is the
|
||||
triple `(kind, pubkey, identifier)` that names the *slot* a mutable event occupies.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Reader has already covered: keys (PublicKey, bech32), tags (Tags, d-tag access via
|
||||
`tags.value("d")`), events (Event struct), kinds (kind ranges, is_addressable,
|
||||
is_replaceable).
|
||||
|
||||
## Structure
|
||||
|
||||
### 1. Motivation (prose only)
|
||||
- Event IDs are hashes of content — they change when the content changes
|
||||
- For replaceable/addressable events, you need a stable reference
|
||||
- An address is `kind:pubkey:identifier` — it names the slot, not the version
|
||||
|
||||
### 2. The module
|
||||
- Register `pub mod addresses;` in lib.rs
|
||||
- Import dependencies: keys::PublicKey, tags::Tag, events::Event, kinds, bech32, std::fmt, std::str::FromStr
|
||||
|
||||
### 3. Error type
|
||||
- `AddressError` enum: InvalidFormat, InvalidBech32, WrongPrefix, InvalidKey, FieldMissing(&'static str), TlvError
|
||||
|
||||
### 4. The `Address` struct
|
||||
- Fields: `kind: u16`, `pubkey: PublicKey`, `identifier: String`
|
||||
- Constructor: `Address::new(kind, pubkey, identifier)`
|
||||
- `from_event(event) -> Option<Self>` — returns None for non-replaceable/non-addressable events. Uses `tags.value("d").unwrap_or("").to_string()` for identifier.
|
||||
- `to_tag(relay_hint: Option<&str>) -> Tag` — produces an `a` tag
|
||||
|
||||
### 5. Display / FromStr (kind:pubkey:identifier format)
|
||||
- `Display`: `write!(f, "{}:{}:{}", self.kind, self.pubkey, self.identifier)`
|
||||
- `FromStr`: split on `:`, take first two segments, join remainder as identifier (handles colons in d-tags)
|
||||
|
||||
### 6. NIP-19 naddr encoding
|
||||
- Introduce TLV format: type(1 byte) + length(1 byte) + value(N bytes)
|
||||
- Constants: SPECIAL=0, RELAY=1, AUTHOR=2, KIND=3
|
||||
- `to_naddr() -> String` — encode as bech32 with "naddr" prefix
|
||||
- `from_naddr(s: &str) -> Result<(Self, Vec<String>), AddressError>` — returns address + relay hints
|
||||
- TLV decode: while loop consuming bytes
|
||||
- SPECIAL=identifier (UTF-8), RELAY=URL string, AUTHOR=32-byte pubkey, KIND=u32 big-endian
|
||||
|
||||
### 7. What's next
|
||||
- Brief pointer to proof of work or filters chapter
|
||||
|
||||
## Code placement
|
||||
- All code in `coracle-lib/src/addresses.rs`
|
||||
- Module registered in `coracle-lib/src/lib.rs`
|
||||
|
||||
## Tests needed
|
||||
- `Address::new` basic construction
|
||||
- `from_event` for addressable event (returns Some)
|
||||
- `from_event` for regular event (returns None)
|
||||
- `from_event` for replaceable event (returns Some, empty identifier)
|
||||
- Display round-trip through FromStr
|
||||
- to_naddr / from_naddr round-trip
|
||||
- FromStr with identifier containing colons
|
||||
- to_tag produces correct `a` tag format
|
||||
Reference in New Issue
Block a user