commit 593d0e2abe61a5b2208214727e1747ba7ecf7888
parent 2f8aa29e92f9c5077936bf61b64a12d09ec0bd30
Author: William Casarin <jb55@jb55.com>
Date: Tue, 25 Jul 2023 16:22:25 -0700
ndb: sync up a few remaining NdbNote tag differences
Diffstat:
14 files changed, 93 insertions(+), 60 deletions(-)
diff --git a/damus/ContentParsing.swift b/damus/ContentParsing.swift
@@ -8,10 +8,15 @@
import Foundation
func tag_to_refid_ndb(_ tag: TagSequence) -> ReferencedId? {
- guard let ref_id = tag[1]?.string(),
- let key = tag[0]?.string() else { return nil }
+ guard tag.count >= 2 else { return nil }
- let relay_id = tag[2]?.string()
+ let key = tag[0].string()
+ let ref_id = tag[1].string()
+
+ var relay_id: String? = nil
+ if tag.count >= 3 {
+ relay_id = tag[2].string()
+ }
return ReferencedId(ref_id: ref_id, relay_id: relay_id, key: key)
}
@@ -123,7 +128,8 @@ func interp_event_refs_with_mentions_ndb(tags: TagsSequence, mention_indices: Se
var i: Int = 0
for tag in tags {
- if tag.count >= 2, let t = tag[0], t.matches_char("e"),
+ if tag.count >= 2,
+ tag[0].matches_char("e"),
let ref = tag_to_refid_ndb(tag)
{
if mention_indices.contains(i) {
diff --git a/damus/Models/Contacts.swift b/damus/Models/Contacts.swift
@@ -147,22 +147,22 @@ func unfollow_reference(postbox: PostBox, our_contacts: NostrEvent?, keypair: Fu
}
func unfollow_reference_event(our_contacts: NostrEvent, keypair: FullKeypair, unfollow: ReferencedId) -> NostrEvent? {
- let tags = our_contacts.tags.filter { tag in
- if let key = tag[safe: 0],
- let ref = tag[safe: 1],
+ let tags = our_contacts.tags.reduce(into: [[String]]()) { ts, tag in
+ if tag.count >= 2,
let fst = unfollow.key.first,
let afst = AsciiCharacter(fst),
- key.matches_char(afst),
- ref.string() == unfollow.ref_id
+ tag[0].matches_char(afst),
+ tag[1].matches_str(unfollow.ref_id)
{
- return false
+ return
}
- return true
+
+ ts.append(tag.strings())
}
-
+
let kind = NostrKind.contacts.rawValue
- return NostrEvent(content: our_contacts.content, keypair: keypair.to_keypair(), kind: kind, tags: tags)
+ return NostrEvent(content: our_contacts.content, keypair: keypair.to_keypair(), kind: kind, tags: Array(tags))
}
func follow_user_event(our_contacts: NostrEvent?, keypair: FullKeypair, follow: ReferencedId) -> NostrEvent? {
@@ -193,7 +193,7 @@ func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], keypair: Fu
return nil
}
- return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: 3, tags: ev.tags)
+ 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: String, info: RelayInfo) -> NostrEvent? {
@@ -209,7 +209,7 @@ func add_relay(ev: NostrEvent, keypair: FullKeypair, current_relays: [RelayDescr
return nil
}
- return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: 3, tags: ev.tags)
+ return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: 3, tags: ev.tags.strings())
}
func ensure_relay_info(relays: [RelayDescriptor], content: String) -> [String: RelayInfo] {
diff --git a/damus/Models/EventsModel.swift b/damus/Models/EventsModel.swift
@@ -45,7 +45,7 @@ class EventsModel: ObservableObject {
return
}
- guard last_etag(tags: ev.tags) == target else {
+ guard ev.referenced_ids.last?.ref_id.string() == target else {
return
}
diff --git a/damus/Models/NotificationsModel.swift b/damus/Models/NotificationsModel.swift
@@ -214,11 +214,11 @@ class NotificationsModel: ObservableObject, ScrollQueue {
let id = ref_id.id
- if let evgrp = self.reactions[id] {
+ if let evgrp = self.reactions[id.string()] {
return evgrp.insert(ev)
} else {
let evgrp = EventGroup()
- self.reactions[id] = evgrp
+ self.reactions[id.string()] = evgrp
return evgrp.insert(ev)
}
}
diff --git a/damus/Models/ProfileModel.swift b/damus/Models/ProfileModel.swift
@@ -35,13 +35,12 @@ class ProfileModel: ObservableObject, Equatable {
}
for tag in contacts.tags {
- guard tag.count >= 2 && tag[0].matches_char("p") else {
+ guard tag.count >= 2,
+ tag[0].matches_char("p"),
+ tag[1].matches_str(pubkey)
+ else {
continue
}
-
- if tag[1] == pubkey {
- return true
- }
}
return false
@@ -145,10 +144,10 @@ class ProfileModel: ObservableObject, Equatable {
}
-func count_pubkeys(_ tags: [[String]]) -> Int {
+func count_pubkeys(_ tags: Tags) -> Int {
var c: Int = 0
for tag in tags {
- if tag.count >= 2 && tag[0] == "p" {
+ if tag.count >= 2 && tag[0].matches_char("p") {
c += 1
}
}
diff --git a/damus/Nostr/NostrEvent.swift b/damus/Nostr/NostrEvent.swift
@@ -21,6 +21,8 @@ enum ValidationResult: Decodable {
}
//typealias NostrEvent = NdbNote
+//typealias Tags = TagsSequence
+typealias Tags = [[String]]
typealias NostrEvent = NostrEventOld
let MAX_NOTE_SIZE: Int = 2 << 18
@@ -54,7 +56,7 @@ class NostrEventOld: Codable, Identifiable, CustomStringConvertible, Equatable,
let id: String
let content: String
let sig: String
- let tags: [[String]]
+ let tags: Tags
//var boosted_by: String?
@@ -88,6 +90,18 @@ class NostrEventOld: Codable, Identifiable, CustomStringConvertible, Equatable,
hasher.combine(id)
}
+ static func owned_from_json(json: String) -> NostrEvent? {
+ let decoder = JSONDecoder()
+ guard let dat = json.data(using: .utf8) else {
+ return nil
+ }
+ guard let ev = try? decoder.decode(NostrEvent.self, from: dat) else {
+ return nil
+ }
+
+ return ev
+ }
+
init?(content: String, keypair: Keypair, kind: UInt32 = 1, tags: [[String]] = [], createdAt: UInt32 = UInt32(Date().timeIntervalSince1970)) {
self.content = content
@@ -937,16 +951,6 @@ func validate_event(ev: NostrEvent) -> ValidationResult {
return ok ? .ok : .bad_sig
}
-func last_etag(tags: [[String]]) -> String? {
- var e: String? = nil
- for tag in tags {
- if tag.count >= 2 && tag[0] == "e" {
- e = tag[1]
- }
- }
- return e
-}
-
func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? {
let blocks = ev.blocks(privkey).blocks.filter { block in
guard case .mention(let mention) = block else {
diff --git a/damus/Nostr/ReferencedId.swift b/damus/Nostr/ReferencedId.swift
@@ -29,9 +29,11 @@ struct References: Sequence, IteratorProtocol {
mutating func next() -> Reference? {
while let tag = tags_iter.next() {
- guard let key = tag[0], key.count == 1,
- let id = tag[1], tagref_should_be_id(key)
- else { continue }
+ guard tag.count >= 2 else { continue }
+ let key = tag[0]
+ let id = tag[1]
+
+ guard key.count == 1, tagref_should_be_id(id) else { continue }
for c in key {
guard let a = AsciiCharacter(c) else { break }
@@ -64,12 +66,21 @@ struct References: Sequence, IteratorProtocol {
}
}
+// TagsSequence transition helpers
extension [[String]] {
func strings() -> [[String]] {
return self
}
}
+// TagsSequence transition helpers
+extension [String] {
+ func strings() -> [String] {
+ return self
+ }
+}
+
+// NdbTagElem transition helpers
extension String {
func string() -> String {
return self
@@ -82,6 +93,10 @@ extension String {
func matches_char(_ c: AsciiCharacter) -> Bool {
return self.first == c.character
}
+
+ func matches_str(_ str: String) -> Bool {
+ return self == str
+ }
}
struct ReferencedId: Identifiable, Hashable, Equatable {
diff --git a/damus/Util/Images/ImageMetadata.swift b/damus/Util/Images/ImageMetadata.swift
@@ -170,8 +170,8 @@ func calculate_image_metadata(url: URL, img: UIImage, blurhash: String) -> Image
func event_image_metadata(ev: NostrEvent) -> [ImageMetadata] {
return ev.tags.reduce(into: [ImageMetadata]()) { meta, tag in
- guard tag.count >= 2 && tag[0] == "imeta",
- let data = ImageMetadata(tag: tag) else {
+ guard tag.count >= 2, tag[0].matches_str("imeta"),
+ let data = ImageMetadata(tag: tag.strings()) else {
return
}
diff --git a/damus/Util/WalletConnect.swift b/damus/Util/WalletConnect.swift
@@ -94,8 +94,8 @@ struct FullWalletResponse {
return nil
}
- self.req_id = req_id.ref_id
-
+ self.req_id = req_id.ref_id.string()
+
let ares = Task {
guard let json = decrypt_dm(nwc.keypair.privkey, pubkey: nwc.pubkey, content: from.content, encoding: .base64),
let resp: WalletResponse = decode_json(json)
diff --git a/damus/Util/Zap.swift b/damus/Util/Zap.swift
@@ -49,7 +49,7 @@ struct ZapRequest {
init(ev: NostrEvent) {
self.ev = ev
- self.marked_hidden = ev.tags.first(where: { t in t.count > 0 && t[0] == "hidden" }) != nil
+ self.marked_hidden = ev.tags.first(where: { t in t.count > 0 && t[0].matches_str("hidden") }) != nil
}
}
@@ -295,7 +295,7 @@ struct Zap {
guard let desc = get_zap_description(zap_ev, inv_desc: zap_invoice.description) else {
return nil
}
-
+
guard let zap_req = decode_nostr_event_json(desc) else {
return nil
}
@@ -392,8 +392,8 @@ func decode_bolt11(_ s: String) -> Invoice? {
func event_tag(_ ev: NostrEvent, name: String) -> String? {
for tag in ev.tags {
- if tag.count >= 2 && tag[0] == name {
- return tag[1]
+ if tag.count >= 2 && tag[0].matches_str(name) {
+ return tag[1].string()
}
}
@@ -401,15 +401,7 @@ func event_tag(_ ev: NostrEvent, name: String) -> String? {
}
func decode_nostr_event_json(_ desc: String) -> NostrEvent? {
- let decoder = JSONDecoder()
- guard let dat = desc.data(using: .utf8) else {
- return nil
- }
- guard let ev = try? decoder.decode(NostrEvent.self, from: dat) else {
- return nil
- }
-
- return ev
+ return NostrEvent.owned_from_json(json: desc)
}
diff --git a/nostrdb/NdbNote.swift b/nostrdb/NdbNote.swift
@@ -104,7 +104,7 @@ class NdbNote: Equatable, Hashable {
static let max_note_size: Int = 2 << 18
- init?(content: String, keypair: Keypair, kind: Int = 1, tags: [[String]] = [], createdAt: UInt32 = UInt32(Date().timeIntervalSince1970)) {
+ init?(content: String, keypair: Keypair, kind: UInt32 = 1, tags: [[String]] = [], createdAt: UInt32 = UInt32(Date().timeIntervalSince1970)) {
var builder = ndb_builder()
let buflen = MAX_NOTE_SIZE
diff --git a/nostrdb/NdbTagElem.swift b/nostrdb/NdbTagElem.swift
@@ -83,6 +83,19 @@ struct NdbTagElem: Sequence, Hashable {
return str.str[0] == c.cchar && str.str[1] == 0
}
+ func matches_str(_ s: String) -> Bool {
+ if str.flag == NDB_PACKED_ID,
+ s.utf8.count == 64,
+ var decoded = hex_decode(s), decoded.count == 32
+ {
+ return memcmp(&decoded, str.id, 32) == 0
+ }
+
+ let len = strlen(str.str)
+ guard len == s.utf8.count else { return false }
+ return s.withCString { cstr in memcmp(str.str, cstr, len) == 0 }
+ }
+
var ndbstr: ndb_str {
return ndb_tag_str(note.note, tag, index)
}
diff --git a/nostrdb/NdbTagIterator.swift b/nostrdb/NdbTagIterator.swift
@@ -15,8 +15,12 @@ struct TagSequence: Sequence {
tag.pointee.count
}
- subscript(index: Int) -> NdbTagElem? {
- guard index < count else { return nil }
+ func strings() -> [String] {
+ return self.map { $0.string() }
+ }
+
+ subscript(index: Int) -> NdbTagElem {
+ precondition(index < count, "Index out of bounds")
return NdbTagElem(note: note, tag: tag, index: Int32(index))
}
diff --git a/nostrdb/Test/NdbTests.swift b/nostrdb/Test/NdbTests.swift
@@ -52,7 +52,7 @@ final class NdbTests: XCTestCase {
}
if tags == 7 {
- XCTAssertEqual(tag[2]?.string(), "wss://nostr-pub.wellorder.net")
+ XCTAssertEqual(tag[2].string(), "wss://nostr-pub.wellorder.net")
}
for elem in tag {