damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 09ce3af11efe4e079cf96feced06b8ba563ca444
parent e42c09883acf9b2810fee740be167d3296c967a0
Author: Daniel D’Aquino <daniel@daquino.me>
Date:   Fri, 21 Feb 2025 20:31:57 -0800

Add some miscellaneous documentation

This commit adds some documentation to miscellaneous functions and
classes.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>

Diffstat:
Mdamus/Models/Contacts+.swift | 3++-
Mdamus/Nostr/NostrKind.swift | 1+
Mdamus/Nostr/NostrRequest.swift | 13++++++++++++-
Mdamus/Nostr/ReferencedId.swift | 27++++++++++++++++++++++++++-
Mdamus/Nostr/RelayPool.swift | 10++++++----
Mdamus/Util/Relays/RelayModelCache.swift | 7+++++++
Mnostrdb/NdbTagIterator.swift | 12++++++++++++
7 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/damus/Models/Contacts+.swift b/damus/Models/Contacts+.swift @@ -79,7 +79,8 @@ func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], keypair: Fu return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: 3, tags: ev.tags.strings()) } -func add_relay(ev: NostrEvent, keypair: FullKeypair, current_relays: [RelayDescriptor], relay: RelayURL, info: RelayInfo) -> NostrEvent? { +/// Handles the creation of a new `kind:3` contact list based on a previous contact list, with the specified relays +func add_relay(ev: NostrEvent, keypair: FullKeypair, current_relays: [RelayDescriptor], relay: RelayURL, info: RelayRWConfiguration) -> NostrEvent? { var relays = ensure_relay_info(relays: current_relays, content: ev.content) // If kind:3 content is empty, or if the relay doesn't exist in the list, diff --git a/damus/Nostr/NostrKind.swift b/damus/Nostr/NostrKind.swift @@ -8,6 +8,7 @@ import Foundation +/// A known Nostr event kind, addressable by name, with the actual number assigned by the protocol as the value enum NostrKind: UInt32, Codable { case metadata = 0 case text = 1 diff --git a/damus/Nostr/NostrRequest.swift b/damus/Nostr/NostrRequest.swift @@ -12,11 +12,14 @@ struct NostrSubscribe { let sub_id: String } - +/// Models a request/message that is sent to a Nostr relay enum NostrRequestType { + /// A standard nostr request case typical(NostrRequest) + /// A customized nostr request. Generally used in the context of a nostrscript. case custom(String) + /// Whether this request is meant to write data to a relay var is_write: Bool { guard case .typical(let req) = self else { return true @@ -25,6 +28,7 @@ enum NostrRequestType { return req.is_write } + /// Whether this request is meant to read data from a relay var is_read: Bool { guard case .typical(let req) = self else { return true @@ -34,12 +38,18 @@ enum NostrRequestType { } } +/// Models a standard request/message that is sent to a Nostr relay. enum NostrRequest { + /// Subscribes to receive information from the relay case subscribe(NostrSubscribe) + /// Unsubscribes from an existing subscription, addressed by its id case unsubscribe(String) + /// Posts an event case event(NostrEvent) + /// Authenticate with the relay case auth(NostrEvent) + /// Whether this request is meant to write data to a relay var is_write: Bool { switch self { case .subscribe: @@ -53,6 +63,7 @@ enum NostrRequest { } } + /// Whether this request is meant to read data from a relay var is_read: Bool { return !is_write } diff --git a/damus/Nostr/ReferencedId.swift b/damus/Nostr/ReferencedId.swift @@ -115,6 +115,19 @@ enum FollowRef: TagKeys, Hashable, TagConvertible, Equatable { } } +/// Models common tag references defined by the Nostr protocol, and their associated values. +/// +/// For example, this raw JSON tag sequence: +/// ```json +/// ["p", "8b2be0a0ad34805d76679272c28a77dbede9adcbfdca48c681ec8b624a1208a6"] +/// ``` +/// +/// would be parsed into something equivalent to `.pubkey(Pubkey(hex: "8b2be0a0ad34805d76679272c28a77dbede9adcbfdca48c681ec8b624a1208a6"))` +/// +/// ## Notes +/// +/// - Not all tag information from all NIPs can be modelled using this alone, as some NIPs may define extra associated values for specific event types. You may need to use a specialized type for some event kinds +/// enum RefId: TagConvertible, TagKeys, Equatable, Hashable { case event(NoteId) case pubkey(Pubkey) @@ -124,6 +137,7 @@ enum RefId: TagConvertible, TagKeys, Equatable, Hashable { case naddr(NAddr) case reference(String) + /// The key that defines the type of reference being made var key: RefKey { switch self { case .event: return .e @@ -136,6 +150,14 @@ enum RefId: TagConvertible, TagKeys, Equatable, Hashable { } } + /// Defines the type of reference being made on a Nostr event tag + /// + /// Example: + /// ```json + /// ["p", "8b2be0a0ad34805d76679272c28a77dbede9adcbfdca48c681ec8b624a1208a6"] + /// ``` + /// + /// The `RefKey` is "p" enum RefKey: AsciiCharacter, TagKey, CustomStringConvertible { case e, p, t, d, q, a, r @@ -148,10 +170,12 @@ enum RefId: TagConvertible, TagKeys, Equatable, Hashable { } } + /// A raw nostr-style tag sequence representation of this object var tag: [String] { [self.key.description, self.description] } - + + /// Describes what is being referenced, as a `String` var description: String { switch self { case .event(let noteId): return noteId.hex() @@ -166,6 +190,7 @@ enum RefId: TagConvertible, TagKeys, Equatable, Hashable { } } + /// Parses a raw tag sequence static func from_tag(tag: TagSequence) -> RefId? { var i = tag.makeIterator() diff --git a/damus/Nostr/RelayPool.swift b/damus/Nostr/RelayPool.swift @@ -24,6 +24,7 @@ struct SeenEvent: Hashable { let evid: NoteId } +/// Establishes and manages connections and subscriptions to a list of relays. class RelayPool { var relays: [Relay] = [] var handlers: [RelayHandler] = [] @@ -31,6 +32,7 @@ class RelayPool { var seen: Set<SeenEvent> = Set() var counts: [RelayURL: UInt64] = [:] var ndb: Ndb + /// The keypair used to authenticate with relays var keypair: Keypair? var message_received_function: (((String, RelayDescriptor)) -> Void)? var message_sent_function: (((String, Relay)) -> Void)? @@ -243,19 +245,19 @@ class RelayPool { func send_raw(_ req: NostrRequestType, to: [RelayURL]? = nil, skip_ephemeral: Bool = true) { let relays = to.map{ get_relays($0) } ?? self.relays - self.send_raw_to_local_ndb(req) + self.send_raw_to_local_ndb(req) // Always send Nostr events and data to NostrDB for a local copy for relay in relays { if req.is_read && !(relay.descriptor.info.read ?? true) { - continue + continue // Do not send read requests to relays that are not READ relays } if req.is_write && !(relay.descriptor.info.write ?? true) { - continue + continue // Do not send write requests to relays that are not WRITE relays } if relay.descriptor.ephemeral && skip_ephemeral { - continue + continue // Do not send requests to ephemeral relays if we want to skip them } guard relay.connection.isConnected else { diff --git a/damus/Util/Relays/RelayModelCache.swift b/damus/Util/Relays/RelayModelCache.swift @@ -7,6 +7,13 @@ import Foundation +/// Stores information, metadata, and logs about different relays. Generally used as a singleton. +/// +/// # Discussion +/// +/// This class is primarily used as a shared singleton in `DamusState`, to allow other parts of the app to access information, metadata, and logs about relays without having to fetch it themselves. +/// +/// For example, it is used by `RelayView` to supplement information about the relay without having to fetch those again from the network, as well as to display logs collected throughout the use of the app. final class RelayModelCache: ObservableObject { private var models = [RelayURL: RelayModel]() diff --git a/nostrdb/NdbTagIterator.swift b/nostrdb/NdbTagIterator.swift @@ -7,6 +7,18 @@ import Foundation + +/// The sequence of strings in a single nostr event tag +/// +/// Example 1: +/// ```json +/// ["r", "wss://nostr-relay.example.com", "read"] +/// ``` +/// +/// Example 2: +/// ```json +/// ["p", "8b2be0a0ad34805d76679272c28a77dbede9adcbfdca48c681ec8b624a1208a6"] +/// ``` struct TagSequence: Sequence { let note: NdbNote let tag: UnsafeMutablePointer<ndb_tag>