Organize RelayPool namespace

This is a non-functional refactor that organizes some classes and
structs used by RelayPool under the same namespace.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
Daniel D’Aquino
2025-03-24 19:45:14 -03:00
parent 53e3f6d86b
commit 5b3fac70ed
15 changed files with 78 additions and 73 deletions

View File

@@ -669,7 +669,7 @@ struct ContentView: View {
let new_relay_filters = load_relay_filters(pubkey) == nil let new_relay_filters = load_relay_filters(pubkey) == nil
for relay in bootstrap_relays { for relay in bootstrap_relays {
let descriptor = RelayDescriptor(url: relay, info: .rw) let descriptor = RelayPool.RelayDescriptor(url: relay, info: .rw)
add_new_relay(model_cache: model_cache, relay_filters: relay_filters, pool: pool, descriptor: descriptor, new_relay_filters: new_relay_filters, logging_enabled: settings.developer_mode) add_new_relay(model_cache: model_cache, relay_filters: relay_filters, pool: pool, descriptor: descriptor, new_relay_filters: new_relay_filters, logging_enabled: settings.developer_mode)
} }

View File

@@ -67,7 +67,7 @@ func decode_json_relays(_ content: String) -> [RelayURL: LegacyKind3RelayRWConfi
return decode_json(content) return decode_json(content)
} }
func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], keypair: FullKeypair, relay: RelayURL) -> NostrEvent?{ func remove_relay(ev: NostrEvent, current_relays: [RelayPool.RelayDescriptor], keypair: FullKeypair, relay: RelayURL) -> NostrEvent?{
var relays = ensure_relay_info(relays: current_relays, content: ev.content) var relays = ensure_relay_info(relays: current_relays, content: ev.content)
relays.removeValue(forKey: relay) relays.removeValue(forKey: relay)
@@ -80,7 +80,7 @@ func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], keypair: Fu
} }
/// Handles the creation of a new `kind:3` contact list based on a previous contact list, with the specified relays /// 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: LegacyKind3RelayRWConfiguration) -> NostrEvent? { func add_relay(ev: NostrEvent, keypair: FullKeypair, current_relays: [RelayPool.RelayDescriptor], relay: RelayURL, info: LegacyKind3RelayRWConfiguration) -> NostrEvent? {
var relays = ensure_relay_info(relays: current_relays, content: ev.content) 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, // If kind:3 content is empty, or if the relay doesn't exist in the list,
@@ -98,7 +98,7 @@ func add_relay(ev: NostrEvent, keypair: FullKeypair, current_relays: [RelayDescr
return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: 3, tags: ev.tags.strings()) return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: 3, tags: ev.tags.strings())
} }
func ensure_relay_info(relays: [RelayDescriptor], content: String) -> [RelayURL: LegacyKind3RelayRWConfiguration] { func ensure_relay_info(relays: [RelayPool.RelayDescriptor], content: String) -> [RelayURL: LegacyKind3RelayRWConfiguration] {
return decode_json_relays(content) ?? make_contact_relays(relays) return decode_json_relays(content) ?? make_contact_relays(relays)
} }
@@ -129,13 +129,13 @@ func follow_with_existing_contacts(keypair: FullKeypair, our_contacts: NostrEven
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: tags)
} }
func make_contact_relays(_ relays: [RelayDescriptor]) -> [RelayURL: LegacyKind3RelayRWConfiguration] { func make_contact_relays(_ relays: [RelayPool.RelayDescriptor]) -> [RelayURL: LegacyKind3RelayRWConfiguration] {
return relays.reduce(into: [:]) { acc, relay in return relays.reduce(into: [:]) { acc, relay in
acc[relay.url] = relay.info acc[relay.url] = relay.info
} }
} }
func make_relay_metadata(relays: [RelayDescriptor], keypair: FullKeypair) -> NostrEvent? { func make_relay_metadata(relays: [RelayPool.RelayDescriptor], keypair: FullKeypair) -> NostrEvent? {
let tags = relays.compactMap { r -> [String]? in let tags = relays.compactMap { r -> [String]? in
var tag = ["r", r.url.absoluteString] var tag = ["r", r.url.absoluteString]
if (r.info.read ?? true) != (r.info.write ?? true) { if (r.info.read ?? true) != (r.info.write ?? true) {

View File

@@ -107,7 +107,7 @@ class DamusState: HeadlessDamusState {
let new_relay_filters = load_relay_filters(pubkey) == nil let new_relay_filters = load_relay_filters(pubkey) == nil
for relay in bootstrap_relays { for relay in bootstrap_relays {
let descriptor = RelayDescriptor(url: relay, info: .rw) let descriptor = RelayPool.RelayDescriptor(url: relay, info: .rw)
add_new_relay(model_cache: model_cache, relay_filters: relay_filters, pool: pool, descriptor: descriptor, new_relay_filters: new_relay_filters, logging_enabled: settings.developer_mode) add_new_relay(model_cache: model_cache, relay_filters: relay_filters, pool: pool, descriptor: descriptor, new_relay_filters: new_relay_filters, logging_enabled: settings.developer_mode)
} }

View File

@@ -984,7 +984,7 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
for d in diff { for d in diff {
changed = true changed = true
if new.contains(d) { if new.contains(d) {
let descriptor = RelayDescriptor(url: d, info: decoded[d] ?? .rw) let descriptor = RelayPool.RelayDescriptor(url: d, info: decoded[d] ?? .rw)
add_new_relay(model_cache: state.relay_model_cache, relay_filters: state.relay_filters, pool: state.pool, descriptor: descriptor, new_relay_filters: new_relay_filters, logging_enabled: state.settings.developer_mode) add_new_relay(model_cache: state.relay_model_cache, relay_filters: state.relay_filters, pool: state.pool, descriptor: descriptor, new_relay_filters: new_relay_filters, logging_enabled: state.settings.developer_mode)
} else { } else {
state.pool.remove_relay(d) state.pool.remove_relay(d)
@@ -998,7 +998,7 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
} }
} }
func add_new_relay(model_cache: RelayModelCache, relay_filters: RelayFilters, pool: RelayPool, descriptor: RelayDescriptor, new_relay_filters: Bool, logging_enabled: Bool) { func add_new_relay(model_cache: RelayModelCache, relay_filters: RelayFilters, pool: RelayPool, descriptor: RelayPool.RelayDescriptor, new_relay_filters: Bool, logging_enabled: Bool) {
try? pool.add_relay(descriptor) try? pool.add_relay(descriptor)
let url = descriptor.url let url = descriptor.url

View File

@@ -7,7 +7,7 @@
import Foundation import Foundation
func make_auth_request(keypair: FullKeypair, challenge_string: String, relay: Relay) -> NostrEvent? { func make_auth_request(keypair: FullKeypair, challenge_string: String, relay: RelayPool.Relay) -> NostrEvent? {
let tags: [[String]] = [["relay", relay.descriptor.url.absoluteString],["challenge", challenge_string]] let tags: [[String]] = [["relay", relay.descriptor.url.absoluteString],["challenge", challenge_string]]
let event = NostrEvent(content: "", keypair: keypair.to_keypair(), kind: 22242, tags: tags) let event = NostrEvent(content: "", keypair: keypair.to_keypair(), kind: 22242, tags: tags)
return event return event

View File

@@ -7,7 +7,7 @@
import Foundation import Foundation
func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> MakeZapRequest? { func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayPool.RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> MakeZapRequest? {
var tags = zap_target_to_tags(target) var tags = zap_target_to_tags(target)
var relay_tag = ["relays"] var relay_tag = ["relays"]
relay_tag.append(contentsOf: relays.map { $0.url.absoluteString }) relay_tag.append(contentsOf: relays.map { $0.url.absoluteString })

View File

@@ -25,30 +25,33 @@ enum RelayVariant {
case nwc case nwc
} }
public struct RelayDescriptor { extension RelayPool {
let url: RelayURL /// Describes a relay for use in `RelayPool`
let info: LegacyKind3RelayRWConfiguration public struct RelayDescriptor {
let variant: RelayVariant let url: RelayURL
var info: LegacyKind3RelayRWConfiguration
init(url: RelayURL, info: LegacyKind3RelayRWConfiguration, variant: RelayVariant = .regular) { let variant: RelayVariant
self.url = url
self.info = info init(url: RelayURL, info: LegacyKind3RelayRWConfiguration, variant: RelayVariant = .regular) {
self.variant = variant self.url = url
} self.info = info
self.variant = variant
var ephemeral: Bool { }
switch variant {
case .regular: var ephemeral: Bool {
return false switch variant {
case .ephemeral: case .regular:
return true return false
case .nwc: case .ephemeral:
return true return true
case .nwc:
return true
}
}
static func nwc(url: RelayURL) -> RelayDescriptor {
return RelayDescriptor(url: url, info: .rw, variant: .nwc)
} }
}
static func nwc(url: RelayURL) -> RelayDescriptor {
return RelayDescriptor(url: url, info: .rw, variant: .nwc)
} }
} }
@@ -129,30 +132,33 @@ struct RelayMetadata: Codable {
} }
} }
class Relay: Identifiable { extension RelayPool {
let descriptor: RelayDescriptor class Relay: Identifiable {
let connection: RelayConnection var descriptor: RelayDescriptor
var authentication_state: RelayAuthenticationState let connection: RelayConnection
var authentication_state: RelayAuthenticationState
var flags: Int
var flags: Int
init(descriptor: RelayDescriptor, connection: RelayConnection) {
self.flags = 0 init(descriptor: RelayDescriptor, connection: RelayConnection) {
self.descriptor = descriptor self.flags = 0
self.connection = connection self.descriptor = descriptor
self.authentication_state = RelayAuthenticationState.none self.connection = connection
self.authentication_state = RelayAuthenticationState.none
}
var is_broken: Bool {
return (flags & RelayFlags.broken.rawValue) == RelayFlags.broken.rawValue
}
var id: RelayURL {
return descriptor.url
}
} }
var is_broken: Bool {
return (flags & RelayFlags.broken.rawValue) == RelayFlags.broken.rawValue
}
var id: RelayURL {
return descriptor.url
}
} }
enum RelayError: Error { extension RelayPool {
case RelayAlreadyExists enum RelayError: Error {
case RelayAlreadyExists
}
} }

View File

@@ -356,7 +356,7 @@ class RelayPool {
} }
func add_rw_relay(_ pool: RelayPool, _ url: RelayURL) { func add_rw_relay(_ pool: RelayPool, _ url: RelayURL) {
try? pool.add_relay(RelayDescriptor(url: url, info: .rw)) try? pool.add_relay(RelayPool.RelayDescriptor(url: url, info: .rw))
} }

View File

@@ -89,13 +89,13 @@ struct AddRelayView: View {
} }
let info = LegacyKind3RelayRWConfiguration.rw let info = LegacyKind3RelayRWConfiguration.rw
let descriptor = RelayDescriptor(url: url, info: info) let descriptor = RelayPool.RelayDescriptor(url: url, info: info)
do { do {
try state.pool.add_relay(descriptor) try state.pool.add_relay(descriptor)
relayAddErrorTitle = nil // Clear error title relayAddErrorTitle = nil // Clear error title
relayAddErrorMessage = nil // Clear error message relayAddErrorMessage = nil // Clear error message
} catch RelayError.RelayAlreadyExists { } catch RelayPool.RelayError.RelayAlreadyExists {
relayAddErrorTitle = NSLocalizedString("Duplicate relay", comment: "Title of the duplicate relay error message.") relayAddErrorTitle = NSLocalizedString("Duplicate relay", comment: "Title of the duplicate relay error message.")
relayAddErrorMessage = NSLocalizedString("The relay you are trying to add is already added.\nYou're all set!", comment: "An error message that appears when the user attempts to add a relay that has already been added.") relayAddErrorMessage = NSLocalizedString("The relay you are trying to add is already added.\nYou're all set!", comment: "An error message that appears when the user attempts to add a relay that has already been added.")
return return

View File

@@ -18,7 +18,7 @@ struct RelayFilterView: View {
//_relays = State(initialValue: state.pool.descriptors) //_relays = State(initialValue: state.pool.descriptors)
} }
var relays: [RelayDescriptor] { var relays: [RelayPool.RelayDescriptor] {
return state.pool.our_descriptors return state.pool.our_descriptors
} }

View File

@@ -23,7 +23,7 @@ enum RelayTab: Int, CaseIterable{
struct RelayConfigView: View { struct RelayConfigView: View {
let state: DamusState let state: DamusState
@State var relays: [RelayDescriptor] @State var relays: [RelayPool.RelayDescriptor]
@State private var showActionButtons = false @State private var showActionButtons = false
@State var show_add_relay: Bool = false @State var show_add_relay: Bool = false
@State var selectedTab = 0 @State var selectedTab = 0
@@ -36,11 +36,11 @@ struct RelayConfigView: View {
UITabBar.appearance().isHidden = true UITabBar.appearance().isHidden = true
} }
var recommended: [RelayDescriptor] { var recommended: [RelayPool.RelayDescriptor] {
let rs: [RelayDescriptor] = [] let rs: [RelayPool.RelayDescriptor] = []
let recommended_relay_addresses = get_default_bootstrap_relays() let recommended_relay_addresses = get_default_bootstrap_relays()
return recommended_relay_addresses.reduce(into: rs) { xs, x in return recommended_relay_addresses.reduce(into: rs) { xs, x in
xs.append(RelayDescriptor(url: x, info: .rw)) xs.append(RelayPool.RelayDescriptor(url: x, info: .rw))
} }
} }
@@ -109,7 +109,7 @@ struct RelayConfigView: View {
.ignoresSafeArea(.all) .ignoresSafeArea(.all)
} }
func RelayList(title: String, relayList: [RelayDescriptor], recommended: Bool) -> some View { func RelayList(title: String, relayList: [RelayPool.RelayDescriptor], recommended: Bool) -> some View {
ScrollView(showsIndicators: false) { ScrollView(showsIndicators: false) {
HStack { HStack {
Text(title) Text(title)

View File

@@ -208,7 +208,7 @@ struct RelayDetailView: View {
} }
} }
private var relay_object: Relay? { private var relay_object: RelayPool.Relay? {
state.pool.get_relay(relay) state.pool.get_relay(relay)
} }

View File

@@ -98,7 +98,7 @@ final class AuthIntegrationTests: XCTestCase {
sent_messages.append(str) sent_messages.append(str)
} }
XCTAssertEqual(pool.relays.count, 0) XCTAssertEqual(pool.relays.count, 0)
let relay_descriptor = RelayDescriptor.init(url: relay_url, info: .rw) let relay_descriptor = RelayPool.RelayDescriptor.init(url: relay_url, info: .rw)
try! pool.add_relay(relay_descriptor) try! pool.add_relay(relay_descriptor)
XCTAssertEqual(pool.relays.count, 1) XCTAssertEqual(pool.relays.count, 1)
let connection_expectation = XCTestExpectation(description: "Waiting for connection") let connection_expectation = XCTestExpectation(description: "Waiting for connection")
@@ -142,7 +142,7 @@ final class AuthIntegrationTests: XCTestCase {
sent_messages.append(str) sent_messages.append(str)
} }
XCTAssertEqual(pool.relays.count, 0) XCTAssertEqual(pool.relays.count, 0)
let relay_descriptor = RelayDescriptor.init(url: relay_url, info: .rw) let relay_descriptor = RelayPool.RelayDescriptor.init(url: relay_url, info: .rw)
try! pool.add_relay(relay_descriptor) try! pool.add_relay(relay_descriptor)
XCTAssertEqual(pool.relays.count, 1) XCTAssertEqual(pool.relays.count, 1)
let connection_expectation = XCTestExpectation(description: "Waiting for connection") let connection_expectation = XCTestExpectation(description: "Waiting for connection")

View File

@@ -20,13 +20,12 @@ final class RequestTests: XCTestCase {
func testMakeAuthRequest() { func testMakeAuthRequest() {
let challenge_string = "8bc847dd-f2f6-4b3a-9c8a-71776ad9b071" let challenge_string = "8bc847dd-f2f6-4b3a-9c8a-71776ad9b071"
let url = RelayURL("wss://example.com")! let url = RelayURL("wss://example.com")!
let relayInfo = RelayInfo(read: true, write: true) let relayDescriptor = RelayPool.RelayDescriptor(url: url, info: .rw)
let relayDescriptor = RelayDescriptor(url: url, info: relayInfo)
let relayConnection = RelayConnection(url: url) { _ in let relayConnection = RelayConnection(url: url) { _ in
} processEvent: { _ in } processEvent: { _ in
} }
let relay = Relay(descriptor: relayDescriptor, connection: relayConnection) let relay = RelayPool.Relay(descriptor: relayDescriptor, connection: relayConnection)
let event = make_auth_request(keypair: FullKeypair.init(pubkey: Pubkey.empty, privkey: Privkey.empty), challenge_string: challenge_string, relay: relay)! let event = make_auth_request(keypair: FullKeypair.init(pubkey: Pubkey.empty, privkey: Privkey.empty), challenge_string: challenge_string, relay: relay)!
let result = make_nostr_auth_event(ev: event) let result = make_nostr_auth_event(ev: event)

View File

@@ -309,7 +309,7 @@ public func nscript_nostr_cmd(interp: UnsafeMutablePointer<wasm_interp>?, cmd: I
func nscript_add_relay(script: NostrScript, relay: String) -> Bool { func nscript_add_relay(script: NostrScript, relay: String) -> Bool {
guard let url = RelayURL(relay) else { return false } guard let url = RelayURL(relay) else { return false }
let desc = RelayDescriptor(url: url, info: .rw, variant: .ephemeral) let desc = RelayPool.RelayDescriptor(url: url, info: .rw, variant: .ephemeral)
return (try? script.pool.add_relay(desc)) != nil return (try? script.pool.add_relay(desc)) != nil
} }