Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added ContactListEvent and tests #62

Merged
merged 1 commit into from
Aug 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions Sources/NostrSDK/Events/ContactListEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// ContactListEvent.swift
//
//
// Created by Bryan Montz on 8/3/23.
//

import Foundation

/// Describes the permissions that a user has for a given relay.
public struct RelayPermissions: Equatable {

/// Whether or not the user can read from the relay.
public let read: Bool

/// Whether or not the user cn write to the relay.
public let write: Bool

init(read: Bool, write: Bool) {
self.read = read
self.write = write
}

init(dictionary: [AnyHashable: Any]) {
read = dictionary["read"] as? Bool ?? false
write = dictionary["write"] as? Bool ?? false
}
}

/// A special event with kind 3, meaning "contact list" is defined as having a list of p tags, one for each of the followed/known profiles one is following.
///
/// > Note: [NIP-02 Specification](https://github.com/nostr-protocol/nips/blob/master/02.md#contact-list-and-petnames)
public final class ContactListEvent: NostrEvent {

/// Pubkeys for followed/known profiles.
var contactPubkeys: [String] {
tags.filter({ $0.name == .pubkey }).map { $0.value }
}

/// Pubkey tags for followed/known profiles.
var contactPubkeyTags: [Tag] {
tags.filter({ $0.name == .pubkey })
}

/// Relays the user knows about.
///
/// > Warning: This method of storing and accessing a user's relays is out of spec, not preferred,
/// and will be removed in the future. It is provided here for completeness and because of common usage.
@available(*, deprecated, message: "This method of storing and accessing a user's relays is out of spec, not preferred, and will be removed in the future.")
var relays: [String: RelayPermissions] {
guard let contentData = content.data(using: .utf8),
let contentDictionary = try? JSONSerialization.jsonObject(with: contentData) as? [String: [AnyHashable: Any]] else {
return [:]
}
return contentDictionary.reduce(into: [String: RelayPermissions]()) { partialResult, element in
let (key, value) = element
partialResult[key] = RelayPermissions(dictionary: value)
}
}
}
1 change: 1 addition & 0 deletions Sources/NostrSDK/RelayResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ fileprivate struct EventKindMapper: Decodable { // swiftlint:disable:this pr
case .setMetadata: return SetMetadataEvent.self
case .textNote: return TextNoteEvent.self
case .recommendServer: return RecommendServerEvent.self
case .contactList: return ContactListEvent.self
case .repost: return TextNoteRepostEvent.self
case .genericRepost: return GenericRepostEvent.self
default: return NostrEvent.self
Expand Down
29 changes: 28 additions & 1 deletion Tests/NostrSDKTests/EventDecodingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ final class EventDecodingTests: XCTestCase, FixtureLoading {

func testDecodeContactList() throws {

let event: NostrEvent = try decodeFixture(filename: "contact_list")
let event: ContactListEvent = try decodeFixture(filename: "contact_list")

XCTAssertEqual(event.id, "test-id")
XCTAssertEqual(event.pubkey, "test-pubkey")
Expand All @@ -93,6 +93,33 @@ final class EventDecodingTests: XCTestCase, FixtureLoading {
XCTAssertEqual(event.signature, "hex-signature")
}

func testDecodeContactListWithRelays() throws {
let event: ContactListEvent = try decodeFixture(filename: "contact_list_with_relays")

let expectedPubkeys = [
"3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681",
"07ecf9838136fe430fac43fa0860dbc62a0aac0729c5a33df1192ce75e330c9f",
"020f2d21ae09bf35fcdfb65decf1478b846f5f728ab30c5eaabcd6d081a81c3e",
"58c741aa630c2da35a56a77c1d05381908bd10504fdd2d8b43f725efa6d23196",
"59fbee7369df7713dbbfa9bbdb0892c62eba929232615c6ff2787da384cb770f"
]

XCTAssertEqual(event.contactPubkeys, expectedPubkeys)

let firstTag = Tag(name: .pubkey, value: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681")
XCTAssertEqual(event.contactPubkeyTags.first, firstTag)

let expectedRelays = [
"wss://relay.damus.io": RelayPermissions(read: true, write: true),
"wss://relay.current.fyi": RelayPermissions(read: false, write: true),
"wss://eden.nostr.land": RelayPermissions(read: true, write: true),
"wss://relay.snort.social": RelayPermissions(read: true, write: false),
"wss://nos.lol": RelayPermissions(read: true, write: true)
]

XCTAssertEqual(event.relays, expectedRelays)
}

func testDecodeRepost() throws {

let event: TextNoteRepostEvent = try decodeFixture(filename: "repost")
Expand Down
30 changes: 30 additions & 0 deletions Tests/NostrSDKTests/Fixtures/contact_list_with_relays.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"id": "367d16ca453b07552c3cd4cc553da62e5c6b20c59747417691b7fda4efdb055a",
"pubkey": "07ecf9838136fe430fac43fa0860dbc62a0aac0729c5a33df1192ce75e330c9f",
"created_at": 1681754187,
"kind": 3,
"tags": [
[
"p",
"3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
],
[
"p",
"07ecf9838136fe430fac43fa0860dbc62a0aac0729c5a33df1192ce75e330c9f"
],
[
"p",
"020f2d21ae09bf35fcdfb65decf1478b846f5f728ab30c5eaabcd6d081a81c3e"
],
[
"p",
"58c741aa630c2da35a56a77c1d05381908bd10504fdd2d8b43f725efa6d23196"
],
[
"p",
"59fbee7369df7713dbbfa9bbdb0892c62eba929232615c6ff2787da384cb770f"
]
],
"content": "{\"wss://relay.damus.io\":{\"write\":true,\"read\":true},\"wss://relay.current.fyi\":{\"write\":true,\"read\":false},\"wss://eden.nostr.land\":{\"write\":true,\"read\":true},\"wss://relay.snort.social\":{\"write\":false,\"read\":true},\"wss://nos.lol\":{\"write\":true,\"read\":true}}",
"sig": "c83838d776595b6b7f31fb11970891402fc69983f88321a19c7f4f2b8891675b4c1eede4d73dc920068d353c90bbd839a34b4b03ebde34a3295c1c4b79094043"
}
Loading