# 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` — 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), 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