damus

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

Relay.swift (3519B)


      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 Admission: Codable {
     88     let amount: Int64
     89     let unit: String
     90 }
     91 
     92 struct Subscription: Codable {
     93     let amount: Int64
     94     let unit: String
     95     let period: Int
     96 }
     97 
     98 struct Publication: Codable {
     99     let kinds: [Int]
    100     let amount: Int64
    101     let unit: String
    102 }
    103 
    104 struct Fees: Codable {
    105     let admission: [Admission]?
    106     let subscription: [Subscription]?
    107     let publication: [Publication]?
    108     
    109     static var empty: Fees {
    110         Fees(admission: nil, subscription: nil, publication: nil)
    111     }
    112 }
    113 
    114 struct RelayMetadata: Codable {
    115     let name: String?
    116     let description: String?
    117     let pubkey: Pubkey?
    118     let contact: String?
    119     let supported_nips: [Int]?
    120     let software: String?
    121     let version: String?
    122     let limitation: Limitations?
    123     let payments_url: String?
    124     let icon: String?
    125     let fees: Fees?
    126     
    127     var is_paid: Bool {
    128         return limitation?.payment_required ?? false
    129     }
    130 }
    131 
    132 class Relay: Identifiable {
    133     let descriptor: RelayDescriptor
    134     let connection: RelayConnection
    135     var authentication_state: RelayAuthenticationState
    136 
    137     var flags: Int
    138     
    139     init(descriptor: RelayDescriptor, connection: RelayConnection) {
    140         self.flags = 0
    141         self.descriptor = descriptor
    142         self.connection = connection
    143         self.authentication_state = RelayAuthenticationState.none
    144     }
    145     
    146     var is_broken: Bool {
    147         return (flags & RelayFlags.broken.rawValue) == RelayFlags.broken.rawValue
    148     }
    149 
    150     var id: RelayURL {
    151         return descriptor.url
    152     }
    153 
    154 }
    155 
    156 enum RelayError: Error {
    157     case RelayAlreadyExists
    158 }