damus

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

commit 679779ab3e7d7ca8d237bb7997e9f3153fa70dcd
parent 3da12e708fea0a6adabc8b8a6d32054bb93443fd
Author: William Casarin <jb55@jb55.com>
Date:   Tue,  4 Apr 2023 10:12:29 -0700

Get around CCP bootstrap relay banning by caching user's relays as their bootstrap relays

Changelog-Fixed: Get around CCP bootstrap relay banning by caching user's relays as their bootstrap relays

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 4++++
Mdamus/ContentView.swift | 13++++---------
Mdamus/Models/DamusState.swift | 4+++-
Mdamus/Models/HomeModel.swift | 3++-
Mdamus/Nostr/NostrEvent.swift | 9+++++++--
Adamus/Util/Relays/RelayBootstrap.swift | 44++++++++++++++++++++++++++++++++++++++++++++
Mdamus/Views/LoginView.swift | 8++++++--
Mdamus/Views/Relays/RelayConfigView.swift | 2+-
Mdamus/Views/SaveKeysView.swift | 3++-
9 files changed, 73 insertions(+), 17 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -164,6 +164,7 @@ 4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */; }; 4CB9D4A92992D2F400A9A7E4 /* FollowsYou.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */; }; 4CBCA930297DB57F00EC6B2F /* WebsiteLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */; }; + 4CC6193A29DC777C006A86D1 /* RelayBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC6193929DC777C006A86D1 /* RelayBootstrap.swift */; }; 4CC7AAE7297EFA7B00430951 /* Zap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAE6297EFA7B00430951 /* Zap.swift */; }; 4CC7AAEB297F0AEC00430951 /* BuilderEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */; }; 4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEC297F0B9E00430951 /* Highlight.swift */; }; @@ -555,6 +556,7 @@ 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNameView.swift; sourceTree = "<group>"; }; 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowsYou.swift; sourceTree = "<group>"; }; 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebsiteLink.swift; sourceTree = "<group>"; }; + 4CC6193929DC777C006A86D1 /* RelayBootstrap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayBootstrap.swift; sourceTree = "<group>"; }; 4CC7AAE6297EFA7B00430951 /* Zap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zap.swift; sourceTree = "<group>"; }; 4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuilderEventView.swift; sourceTree = "<group>"; }; 4CC7AAEC297F0B9E00430951 /* Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Highlight.swift; sourceTree = "<group>"; }; @@ -1164,6 +1166,7 @@ children = ( 4CE8794729941DA700F758CC /* RelayFilters.swift */, 4CE8794B2995B59E00F758CC /* RelayMetadatas.swift */, + 4CC6193929DC777C006A86D1 /* RelayBootstrap.swift */, ); path = Relays; sourceTree = "<group>"; @@ -1451,6 +1454,7 @@ 4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */, 4C363AA228296A7E006E126D /* SearchView.swift in Sources */, 4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */, + 4CC6193A29DC777C006A86D1 /* RelayBootstrap.swift in Sources */, 4C285C8A2838B985008A31F1 /* ProfilePictureSelector.swift in Sources */, 4C9F18E429ABDE6D008C55EC /* MaybeAnonPfpView.swift in Sources */, 4C75EFB92804A2740006080F /* EventView.swift in Sources */, diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -8,13 +8,6 @@ import SwiftUI import Starscream -var BOOTSTRAP_RELAYS = [ - "wss://relay.damus.io", - "wss://eden.nostr.land", - "wss://nostr.wine", - "wss://nos.lol", -] - struct TimestampedProfile { let profile: Profile let timestamp: Int64 @@ -605,9 +598,10 @@ struct ContentView: View { let pool = RelayPool() let metadatas = RelayMetadatas() let relay_filters = RelayFilters(our_pubkey: pubkey) + let bootstrap_relays = load_bootstrap_relays(pubkey: pubkey) let new_relay_filters = load_relay_filters(pubkey) == nil - for relay in BOOTSTRAP_RELAYS { + for relay in bootstrap_relays { if let url = URL(string: relay) { add_new_relay(relay_filters: relay_filters, metadatas: metadatas, pool: pool, url: url, info: .rw, new_relay_filters: new_relay_filters) } @@ -632,7 +626,8 @@ struct ContentView: View { drafts: Drafts(), events: EventCache(), bookmarks: BookmarksManager(pubkey: pubkey), - postbox: PostBox(pool: pool) + postbox: PostBox(pool: pool), + bootstrap_relays: bootstrap_relays ) home.damus_state = self.damus_state! diff --git a/damus/Models/DamusState.swift b/damus/Models/DamusState.swift @@ -28,6 +28,8 @@ struct DamusState { let bookmarks: BookmarksManager let postbox: PostBox + let bootstrap_relays: [String] + var pubkey: String { return keypair.pubkey } @@ -37,6 +39,6 @@ struct DamusState { } static var empty: DamusState { - return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""), relay_metadata: RelayMetadatas(), drafts: Drafts(), events: EventCache(), bookmarks: BookmarksManager(pubkey: ""), postbox: PostBox(pool: RelayPool())) + return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""), relay_metadata: RelayMetadatas(), drafts: Drafts(), events: EventCache(), bookmarks: BookmarksManager(pubkey: ""), postbox: PostBox(pool: RelayPool()), bootstrap_relays: []) } } diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift @@ -743,7 +743,7 @@ func process_contact_event(state: DamusState, ev: NostrEvent) { func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) { let bootstrap_dict: [String: RelayInfo] = [:] - let old_decoded = m_old_ev.flatMap { decode_json_relays($0.content) } ?? BOOTSTRAP_RELAYS.reduce(into: bootstrap_dict) { (d, r) in + let old_decoded = m_old_ev.flatMap { decode_json_relays($0.content) } ?? state.bootstrap_relays.reduce(into: bootstrap_dict) { (d, r) in d[r] = .rw } @@ -778,6 +778,7 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) { } if changed { + save_bootstrap_relays(pubkey: state.pubkey, relays: Array(new)) notify(.relays_changed, ()) } } diff --git a/damus/Nostr/NostrEvent.swift b/damus/Nostr/NostrEvent.swift @@ -538,16 +538,21 @@ func make_first_contact_event(keypair: Keypair) -> NostrEvent? { guard let privkey = keypair.privkey else { return nil } - + + let bootstrap_relays = load_bootstrap_relays(pubkey: keypair.pubkey) let rw_relay_info = RelayInfo(read: true, write: true) var relays: [String: RelayInfo] = [:] - for relay in BOOTSTRAP_RELAYS { + + for relay in bootstrap_relays { relays[relay] = rw_relay_info } + let relay_json = encode_json(relays)! let damus_pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681" + let jb55_pubkey = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" // lol let tags = [ ["p", damus_pubkey], + ["p", jb55_pubkey], ["p", keypair.pubkey] // you're a friend of yourself! ] let ev = NostrEvent(content: relay_json, diff --git a/damus/Util/Relays/RelayBootstrap.swift b/damus/Util/Relays/RelayBootstrap.swift @@ -0,0 +1,44 @@ +// +// RelayBootstrap.swift +// damus +// +// Created by William Casarin on 2023-04-04. +// + +import Foundation + +fileprivate let BOOTSTRAP_RELAYS = [ + "wss://relay.damus.io", + "wss://eden.nostr.land", + "wss://nostr.wine", + "wss://nos.lol", +] + +func bootstrap_relays_setting_key(pubkey: String) -> String { + return pk_setting_key(pubkey, key: "bootstrap_relays") +} + +func save_bootstrap_relays(pubkey: String, relays: [String]) { + let key = bootstrap_relays_setting_key(pubkey: pubkey) + + UserDefaults.standard.set(relays, forKey: key) +} + +func load_bootstrap_relays(pubkey: String) -> [String] { + let key = bootstrap_relays_setting_key(pubkey: pubkey) + + guard let relays = UserDefaults.standard.stringArray(forKey: key) else { + print("loading default bootstrap relays") + return BOOTSTRAP_RELAYS.map { $0 } + } + + if relays.count == 0 { + print("loading default bootstrap relays") + return BOOTSTRAP_RELAYS.map { $0 } + } + + let loaded_relays = Array(Set(relays + BOOTSTRAP_RELAYS)) + print("Loading custom bootstrap relays: \(loaded_relays)") + return loaded_relays +} + diff --git a/damus/Views/LoginView.swift b/damus/Views/LoginView.swift @@ -79,11 +79,15 @@ struct LoginView: View { return } + // this is a weird way to login anyways + /* + var bootstrap_relays = load_bootstrap_relays(pubkey: nip05.pubkey) for relay in nip05.relays { - if !(BOOTSTRAP_RELAYS.contains { $0 == relay }) { - BOOTSTRAP_RELAYS.append(relay) + if !(bootstrap_relays.contains { $0 == relay }) { + bootstrap_relays.append(relay) } } + */ save_pubkey(pubkey: nip05.pubkey) notify(.login, ()) diff --git a/damus/Views/Relays/RelayConfigView.swift b/damus/Views/Relays/RelayConfigView.swift @@ -22,7 +22,7 @@ struct RelayConfigView: View { var recommended: [RelayDescriptor] { let rs: [RelayDescriptor] = [] - return BOOTSTRAP_RELAYS.reduce(into: rs) { xs, x in + return state.bootstrap_relays.reduce(into: rs) { xs, x in if state.pool.get_relay(x) == nil { xs.append(RelayDescriptor(url: URL(string: x)!, info: .rw)) } diff --git a/damus/Views/SaveKeysView.swift b/damus/Views/SaveKeysView.swift @@ -90,7 +90,8 @@ struct SaveKeysView: View { } func complete_account_creation(_ account: CreateAccountModel) { - for relay in BOOTSTRAP_RELAYS { + let bootstrap_relays = load_bootstrap_relays(pubkey: account.pubkey) + for relay in bootstrap_relays { add_rw_relay(self.pool, relay) }