feat: allow changing default relays
This commit is contained in:
parent
36959a1052
commit
53a67d8233
44 changed files with 356 additions and 92 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { BIG_RELAY_URLS, ExtendedKind, SEARCHABLE_RELAY_URLS } from '@/constants'
|
||||
import { ExtendedKind, SEARCHABLE_RELAY_URLS } from '@/constants'
|
||||
import {
|
||||
compareEvents,
|
||||
getReplaceableCoordinate,
|
||||
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from '@/lib/event'
|
||||
import { getProfileFromEvent, getRelayListFromEvent } from '@/lib/event-metadata'
|
||||
import { formatPubkey, isValidPubkey, pubkeyToNpub, userIdToPubkey } from '@/lib/pubkey'
|
||||
import { filterOutBigRelays } from '@/lib/relay'
|
||||
import { filterOutBigRelays, getDefaultRelayUrls } from '@/lib/relay'
|
||||
import { getPubkeysFromPTags, getServersFromServerTags, tagNameEquals } from '@/lib/tag'
|
||||
import { mergeTimelines } from '@/lib/timeline'
|
||||
import { isLocalNetworkUrl, isWebsocketUrl, normalizeUrl } from '@/lib/url'
|
||||
|
|
@ -97,6 +97,7 @@ class ClientService extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
const defaultRelays = getDefaultRelayUrls()
|
||||
const relaySet = new Set<string>()
|
||||
if (specifiedRelayUrls?.length) {
|
||||
specifiedRelayUrls.forEach((url) => relaySet.add(url))
|
||||
|
|
@ -137,20 +138,20 @@ class ClientService extends EventTarget {
|
|||
ExtendedKind.RELAY_REVIEW
|
||||
].includes(event.kind)
|
||||
) {
|
||||
BIG_RELAY_URLS.forEach((url) => relaySet.add(url))
|
||||
defaultRelays.forEach((url) => relaySet.add(url))
|
||||
}
|
||||
|
||||
if (event.kind === ExtendedKind.COMMENT) {
|
||||
const rootITag = event.tags.find(tagNameEquals('I'))
|
||||
if (rootITag) {
|
||||
// For external content comments, always publish to big relays
|
||||
BIG_RELAY_URLS.forEach((url) => relaySet.add(url))
|
||||
// For external content comments, always publish to default relays
|
||||
defaultRelays.forEach((url) => relaySet.add(url))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!relaySet.size) {
|
||||
BIG_RELAY_URLS.forEach((url) => relaySet.add(url))
|
||||
defaultRelays.forEach((url) => relaySet.add(url))
|
||||
}
|
||||
|
||||
return Array.from(relaySet)
|
||||
|
|
@ -166,7 +167,7 @@ class ClientService extends EventTarget {
|
|||
const relayLists = await this.fetchRelayLists(filter['#p'])
|
||||
return Array.from(new Set(relayLists.flatMap((list) => list.read.slice(0, 5))))
|
||||
}
|
||||
return BIG_RELAY_URLS
|
||||
return getDefaultRelayUrls()
|
||||
}
|
||||
|
||||
async publishEvent(relayUrls: string[], event: NEvent) {
|
||||
|
|
@ -807,7 +808,11 @@ class ClientService extends EventTarget {
|
|||
} = {}
|
||||
) {
|
||||
const relays = Array.from(new Set(urls))
|
||||
const events = await this.query(relays.length > 0 ? relays : BIG_RELAY_URLS, filter, onevent)
|
||||
const events = await this.query(
|
||||
relays.length > 0 ? relays : getDefaultRelayUrls(),
|
||||
filter,
|
||||
onevent
|
||||
)
|
||||
if (cache) {
|
||||
events.forEach((evt) => {
|
||||
this.addEventToCache(evt)
|
||||
|
|
@ -935,7 +940,7 @@ class ClientService extends EventTarget {
|
|||
}
|
||||
|
||||
private async fetchEventsFromBigRelays(ids: readonly string[]) {
|
||||
const events = await this.query(BIG_RELAY_URLS, {
|
||||
const events = await this.query(getDefaultRelayUrls(), {
|
||||
ids: Array.from(new Set(ids)),
|
||||
limit: ids.length
|
||||
})
|
||||
|
|
@ -961,7 +966,7 @@ class ClientService extends EventTarget {
|
|||
private async _fetchFollowingFavoriteRelays(pubkey: string) {
|
||||
const fetchNewData = async () => {
|
||||
const followings = await this.fetchFollowings(pubkey)
|
||||
const events = await this.fetchEvents(BIG_RELAY_URLS, {
|
||||
const events = await this.fetchEvents(getDefaultRelayUrls(), {
|
||||
authors: followings,
|
||||
kinds: [ExtendedKind.FAVORITE_RELAYS, kinds.Relaysets],
|
||||
limit: 1000
|
||||
|
|
@ -1182,9 +1187,10 @@ class ClientService extends EventTarget {
|
|||
if (event) {
|
||||
return getRelayListFromEvent(event, storage.getFilterOutOnionRelays())
|
||||
}
|
||||
const defaultRelays = getDefaultRelayUrls()
|
||||
return {
|
||||
write: BIG_RELAY_URLS,
|
||||
read: BIG_RELAY_URLS,
|
||||
write: defaultRelays,
|
||||
read: defaultRelays,
|
||||
originalRelays: []
|
||||
}
|
||||
})
|
||||
|
|
@ -1224,7 +1230,7 @@ class ClientService extends EventTarget {
|
|||
const eventsMap = new Map<string, NEvent>()
|
||||
await Promise.allSettled(
|
||||
Array.from(groups.entries()).map(async ([kind, pubkeys]) => {
|
||||
const events = await this.query(BIG_RELAY_URLS, {
|
||||
const events = await this.query(getDefaultRelayUrls(), {
|
||||
authors: pubkeys,
|
||||
kinds: [kind]
|
||||
})
|
||||
|
|
@ -1340,7 +1346,7 @@ class ClientService extends EventTarget {
|
|||
: { authors: [pubkey], kinds: [kind] }) as Filter
|
||||
)
|
||||
const relayList = await this.fetchRelayList(pubkey)
|
||||
const relays = relayList.write.concat(BIG_RELAY_URLS).slice(0, 5)
|
||||
const relays = relayList.write.concat(getDefaultRelayUrls()).slice(0, 5)
|
||||
const events = await this.query(relays, filters)
|
||||
|
||||
for (const event of events) {
|
||||
|
|
@ -1471,10 +1477,10 @@ class ClientService extends EventTarget {
|
|||
// If many websocket connections are initiated simultaneously, it will be
|
||||
// very slow on Safari (for unknown reason)
|
||||
if (isSafari()) {
|
||||
let urls = BIG_RELAY_URLS
|
||||
let urls = getDefaultRelayUrls()
|
||||
if (myPubkey) {
|
||||
const relayList = await this.fetchRelayList(myPubkey)
|
||||
urls = relayList.read.concat(BIG_RELAY_URLS).slice(0, 5)
|
||||
urls = relayList.read.concat(getDefaultRelayUrls()).slice(0, 5)
|
||||
}
|
||||
return [{ urls, filter: { authors: pubkeys } }]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { BIG_RELAY_URLS, CODY_PUBKEY, JUMBLE_PUBKEY } from '@/constants'
|
||||
import { CODY_PUBKEY, JUMBLE_PUBKEY } from '@/constants'
|
||||
import { getZapInfoFromEvent } from '@/lib/event-metadata'
|
||||
import { getDefaultRelayUrls } from '@/lib/relay'
|
||||
import { TProfile } from '@/types'
|
||||
import { init, launchPaymentModal } from '@getalby/bitcoin-connect-react'
|
||||
import { Invoice } from '@getalby/lightning-tools'
|
||||
|
|
@ -52,7 +53,7 @@ class LightningService {
|
|||
client.fetchRelayList(recipient),
|
||||
sender
|
||||
? client.fetchRelayList(sender)
|
||||
: Promise.resolve({ read: BIG_RELAY_URLS, write: BIG_RELAY_URLS })
|
||||
: Promise.resolve({ read: getDefaultRelayUrls(), write: getDefaultRelayUrls() })
|
||||
])
|
||||
if (!profile) {
|
||||
throw new Error('Recipient not found')
|
||||
|
|
@ -69,7 +70,7 @@ class LightningService {
|
|||
relays: receiptRelayList.read
|
||||
.slice(0, 4)
|
||||
.concat(senderRelayList.write.slice(0, 3))
|
||||
.concat(BIG_RELAY_URLS),
|
||||
.concat(getDefaultRelayUrls()),
|
||||
comment
|
||||
})
|
||||
const zapRequest = await client.signer.signEvent(zapRequestDraft)
|
||||
|
|
@ -134,7 +135,7 @@ class LightningService {
|
|||
filter['#e'] = [event.id]
|
||||
}
|
||||
subCloser = client.subscribe(
|
||||
senderRelayList.write.concat(BIG_RELAY_URLS).slice(0, 4),
|
||||
senderRelayList.write.concat(getDefaultRelayUrls()).slice(0, 4),
|
||||
filter,
|
||||
{
|
||||
onevent: (evt) => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
ALLOWED_FILTER_KINDS,
|
||||
BIG_RELAY_URLS,
|
||||
DEFAULT_FAVICON_URL_TEMPLATE,
|
||||
DEFAULT_NIP_96_SERVICE,
|
||||
ExtendedKind,
|
||||
|
|
@ -21,9 +22,9 @@ import {
|
|||
TMediaAutoLoadPolicy,
|
||||
TMediaUploadServiceConfig,
|
||||
TNoteListMode,
|
||||
TProfilePictureAutoLoadPolicy,
|
||||
TNsfwDisplayPolicy,
|
||||
TNotificationStyle,
|
||||
TNsfwDisplayPolicy,
|
||||
TProfilePictureAutoLoadPolicy,
|
||||
TRelaySet,
|
||||
TThemeSetting,
|
||||
TTranslationServiceConfig
|
||||
|
|
@ -65,6 +66,7 @@ class LocalStorageService {
|
|||
private nsfwDisplayPolicy: TNsfwDisplayPolicy = NSFW_DISPLAY_POLICY.HIDE_CONTENT
|
||||
private minTrustScore: number = 40
|
||||
private enableLiveFeed: boolean = false
|
||||
private defaultRelayUrls: string[] = BIG_RELAY_URLS
|
||||
|
||||
constructor() {
|
||||
if (!LocalStorageService.instance) {
|
||||
|
|
@ -278,6 +280,22 @@ class LocalStorageService {
|
|||
|
||||
this.enableLiveFeed = window.localStorage.getItem(StorageKey.ENABLE_LIVE_FEED) === 'true'
|
||||
|
||||
const defaultRelayUrlsStr = window.localStorage.getItem(StorageKey.DEFAULT_RELAY_URLS)
|
||||
if (defaultRelayUrlsStr) {
|
||||
try {
|
||||
const urls = JSON.parse(defaultRelayUrlsStr)
|
||||
if (
|
||||
Array.isArray(urls) &&
|
||||
urls.length > 0 &&
|
||||
urls.every((url) => typeof url === 'string')
|
||||
) {
|
||||
this.defaultRelayUrls = urls
|
||||
}
|
||||
} catch {
|
||||
// Invalid JSON, use default
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up deprecated data
|
||||
window.localStorage.removeItem(StorageKey.PINNED_PUBKEYS)
|
||||
window.localStorage.removeItem(StorageKey.ACCOUNT_PROFILE_EVENT_MAP)
|
||||
|
|
@ -624,6 +642,15 @@ class LocalStorageService {
|
|||
this.enableLiveFeed = enable
|
||||
window.localStorage.setItem(StorageKey.ENABLE_LIVE_FEED, enable.toString())
|
||||
}
|
||||
|
||||
getDefaultRelayUrls() {
|
||||
return this.defaultRelayUrls
|
||||
}
|
||||
|
||||
setDefaultRelayUrls(urls: string[]) {
|
||||
this.defaultRelayUrls = urls
|
||||
window.localStorage.setItem(StorageKey.DEFAULT_RELAY_URLS, JSON.stringify(urls))
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new LocalStorageService()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { BIG_RELAY_URLS, ExtendedKind } from '@/constants'
|
||||
import { ExtendedKind } from '@/constants'
|
||||
import { getEventKey, getReplaceableCoordinateFromEvent, isReplaceableEvent } from '@/lib/event'
|
||||
import { getZapInfoFromEvent } from '@/lib/event-metadata'
|
||||
import { getDefaultRelayUrls } from '@/lib/relay'
|
||||
import { getEmojiInfosFromEmojiTags, tagNameEquals } from '@/lib/tag'
|
||||
import client from '@/services/client.service'
|
||||
import { TEmoji } from '@/types'
|
||||
|
|
@ -150,7 +151,9 @@ class StuffStatsService {
|
|||
})
|
||||
}
|
||||
|
||||
const relays = relayList ? relayList.read.concat(BIG_RELAY_URLS).slice(0, 5) : BIG_RELAY_URLS
|
||||
const relays = relayList
|
||||
? relayList.read.concat(getDefaultRelayUrls()).slice(0, 5)
|
||||
: getDefaultRelayUrls()
|
||||
|
||||
const events: Event[] = []
|
||||
await client.fetchEvents(relays, filters, {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BIG_RELAY_URLS, ExtendedKind } from '@/constants'
|
||||
import { ExtendedKind } from '@/constants'
|
||||
import {
|
||||
getEventKey,
|
||||
getKeyFromTag,
|
||||
|
|
@ -9,6 +9,7 @@ import {
|
|||
isReplaceableEvent,
|
||||
isReplyNoteEvent
|
||||
} from '@/lib/event'
|
||||
import { getDefaultRelayUrls } from '@/lib/relay'
|
||||
import { generateBech32IdFromETag } from '@/lib/tag'
|
||||
import client from '@/services/client.service'
|
||||
import dayjs from 'dayjs'
|
||||
|
|
@ -69,7 +70,7 @@ class ThreadService {
|
|||
const relayList = await client.fetchRelayList(rootPubkey)
|
||||
relayUrls = relayList.read
|
||||
}
|
||||
relayUrls = relayUrls.concat(BIG_RELAY_URLS).slice(0, 4)
|
||||
relayUrls = relayUrls.concat(getDefaultRelayUrls()).slice(0, 4)
|
||||
|
||||
// If current event is protected, we can assume its replies are also protected and stored on the same relays
|
||||
if (event && isProtectedEvent(event)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue