63 lines
2.6 KiB
Markdown
63 lines
2.6 KiB
Markdown
# 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
|