Relay.swift (2993B)
1 // 2 // Relay.swift 3 // damus 4 // 5 // Created by William Casarin on 2022-04-11. 6 // 7 8 import Foundation 9 10 public struct RelayInfo: Codable { 11 let read: Bool? 12 let write: Bool? 13 14 init(read: Bool, write: Bool) { 15 self.read = read 16 self.write = write 17 } 18 19 static let rw = RelayInfo(read: true, write: true) 20 } 21 22 enum RelayVariant { 23 case regular 24 case ephemeral 25 case nwc 26 } 27 28 public struct RelayDescriptor { 29 let url: RelayURL 30 let info: RelayInfo 31 let variant: RelayVariant 32 33 init(url: RelayURL, info: RelayInfo, variant: RelayVariant = .regular) { 34 self.url = url 35 self.info = info 36 self.variant = variant 37 } 38 39 var ephemeral: Bool { 40 switch variant { 41 case .regular: 42 return false 43 case .ephemeral: 44 return true 45 case .nwc: 46 return true 47 } 48 } 49 50 static func nwc(url: RelayURL) -> RelayDescriptor { 51 return RelayDescriptor(url: url, info: .rw, variant: .nwc) 52 } 53 } 54 55 enum RelayFlags: Int { 56 case none = 0 57 case broken = 1 58 } 59 60 enum RelayAuthenticationError { 61 /// Only a public key was provided in keypair to sign challenge. 62 /// 63 /// A private key is required to sign `auth` challenge. 64 case no_private_key 65 /// No keypair was provided to sign challenge. 66 case no_key 67 } 68 enum RelayAuthenticationState: Equatable { 69 /// No `auth` request has been made from this relay 70 case none 71 /// We have received an `auth` challenge, but have not yet replied to the challenge 72 case pending 73 /// We have received an `auth` challenge and replied with an `auth` event 74 case verified 75 /// We received an `auth` challenge but failed to reply to the challenge 76 case error(RelayAuthenticationError) 77 } 78 79 struct Limitations: Codable { 80 let payment_required: Bool? 81 82 static var empty: Limitations { 83 Limitations(payment_required: nil) 84 } 85 } 86 87 struct RelayMetadata: Codable { 88 let name: String? 89 let description: String? 90 let pubkey: Pubkey? 91 let contact: String? 92 let supported_nips: [Int]? 93 let software: String? 94 let version: String? 95 let limitation: Limitations? 96 let payments_url: String? 97 let icon: String? 98 99 var is_paid: Bool { 100 return limitation?.payment_required ?? false 101 } 102 } 103 104 class Relay: Identifiable { 105 let descriptor: RelayDescriptor 106 let connection: RelayConnection 107 var authentication_state: RelayAuthenticationState 108 109 var flags: Int 110 111 init(descriptor: RelayDescriptor, connection: RelayConnection) { 112 self.flags = 0 113 self.descriptor = descriptor 114 self.connection = connection 115 self.authentication_state = RelayAuthenticationState.none 116 } 117 118 var is_broken: Bool { 119 return (flags & RelayFlags.broken.rawValue) == RelayFlags.broken.rawValue 120 } 121 122 var id: RelayURL { 123 return descriptor.url 124 } 125 126 } 127 128 enum RelayError: Error { 129 case RelayAlreadyExists 130 }