Add support for blocked relays
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman",
|
"name": "@welshman",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/app",
|
"name": "@welshman/app",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A collection of svelte stores for use in building nostr client applications.",
|
"description": "A collection of svelte stores for use in building nostr client applications.",
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import {BLOCKED_RELAYS, asDecryptedEvent, readList} from "@welshman/util"
|
||||||
|
import {TrustedEvent} from "@welshman/util"
|
||||||
|
import {
|
||||||
|
deriveItemsByKey,
|
||||||
|
deriveItems,
|
||||||
|
makeForceLoadItem,
|
||||||
|
makeLoadItem,
|
||||||
|
makeDeriveItem,
|
||||||
|
getter,
|
||||||
|
} from "@welshman/store"
|
||||||
|
import {repository} from "./core.js"
|
||||||
|
import {makeOutboxLoader} from "./relayLists.js"
|
||||||
|
|
||||||
|
export const blockedRelayListsByPubkey = deriveItemsByKey({
|
||||||
|
repository,
|
||||||
|
eventToItem: (event: TrustedEvent) => readList(asDecryptedEvent(event)),
|
||||||
|
filters: [{kinds: [BLOCKED_RELAYS]}],
|
||||||
|
getKey: blockedRelayLists => blockedRelayLists.event.pubkey,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const blockedRelayLists = deriveItems(blockedRelayListsByPubkey)
|
||||||
|
|
||||||
|
export const getBlockedRelayListsByPubkey = getter(blockedRelayListsByPubkey)
|
||||||
|
|
||||||
|
export const getBlockedRelayLists = getter(blockedRelayLists)
|
||||||
|
|
||||||
|
export const getBlockedRelayList = (pubkey: string) => getBlockedRelayListsByPubkey().get(pubkey)
|
||||||
|
|
||||||
|
export const forceLoadBlockedRelayList = makeForceLoadItem(
|
||||||
|
makeOutboxLoader(BLOCKED_RELAYS),
|
||||||
|
getBlockedRelayList,
|
||||||
|
)
|
||||||
|
|
||||||
|
export const loadBlockedRelayList = makeLoadItem(
|
||||||
|
makeOutboxLoader(BLOCKED_RELAYS),
|
||||||
|
getBlockedRelayList,
|
||||||
|
)
|
||||||
|
|
||||||
|
export const deriveBlockedRelayList = makeDeriveItem(
|
||||||
|
blockedRelayListsByPubkey,
|
||||||
|
loadBlockedRelayList,
|
||||||
|
)
|
||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
editProfile,
|
editProfile,
|
||||||
RelayMode,
|
RelayMode,
|
||||||
MESSAGING_RELAYS,
|
MESSAGING_RELAYS,
|
||||||
|
BLOCKED_RELAYS,
|
||||||
FOLLOWS,
|
FOLLOWS,
|
||||||
RELAYS,
|
RELAYS,
|
||||||
MUTES,
|
MUTES,
|
||||||
@@ -36,6 +37,8 @@ import {
|
|||||||
forceLoadUserRelayList,
|
forceLoadUserRelayList,
|
||||||
userMessagingRelayList,
|
userMessagingRelayList,
|
||||||
forceLoadUserMessagingRelayList,
|
forceLoadUserMessagingRelayList,
|
||||||
|
userBlockedRelayList,
|
||||||
|
forceLoadUserBlockedRelayList,
|
||||||
userFollowList,
|
userFollowList,
|
||||||
forceLoadUserFollowList,
|
forceLoadUserFollowList,
|
||||||
userMuteList,
|
userMuteList,
|
||||||
@@ -105,6 +108,28 @@ export const addMessagingRelay = async (url: string) => {
|
|||||||
return publishThunk({event, relays})
|
return publishThunk({event, relays})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NIP 51
|
||||||
|
|
||||||
|
export const removeBlockedRelay = async (url: string) => {
|
||||||
|
await forceLoadUserBlockedRelayList([])
|
||||||
|
|
||||||
|
const list = get(userBlockedRelayList) || makeList({kind: BLOCKED_RELAYS})
|
||||||
|
const event = await removeFromList(list, url).reconcile(nip44EncryptToSelf)
|
||||||
|
const relays = Router.get().FromUser().policy(addMaximalFallbacks).getUrls()
|
||||||
|
|
||||||
|
return publishThunk({event, relays})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const addBlockedRelay = async (url: string) => {
|
||||||
|
await forceLoadUserBlockedRelayList([])
|
||||||
|
|
||||||
|
const list = get(userBlockedRelayList) || makeList({kind: BLOCKED_RELAYS})
|
||||||
|
const event = await addToListPublicly(list, ["relay", url]).reconcile(nip44EncryptToSelf)
|
||||||
|
const relays = Router.get().FromUser().policy(addMaximalFallbacks).getUrls()
|
||||||
|
|
||||||
|
return publishThunk({event, relays})
|
||||||
|
}
|
||||||
|
|
||||||
// NIP 01
|
// NIP 01
|
||||||
|
|
||||||
export const setProfile = (profile: Profile) => {
|
export const setProfile = (profile: Profile) => {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export * from "./pins.js"
|
|||||||
export * from "./relays.js"
|
export * from "./relays.js"
|
||||||
export * from "./relayStats.js"
|
export * from "./relayStats.js"
|
||||||
export * from "./relayLists.js"
|
export * from "./relayLists.js"
|
||||||
|
export * from "./blockedRelayLists.js"
|
||||||
export * from "./messagingRelayLists.js"
|
export * from "./messagingRelayLists.js"
|
||||||
export * from "./search.js"
|
export * from "./search.js"
|
||||||
export * from "./session.js"
|
export * from "./session.js"
|
||||||
@@ -40,6 +41,7 @@ import {repository, tracker} from "./core.js"
|
|||||||
import {getRelays, loadRelay} from "./relays.js"
|
import {getRelays, loadRelay} from "./relays.js"
|
||||||
import {trackRelayStats, getRelayQuality} from "./relayStats.js"
|
import {trackRelayStats, getRelayQuality} from "./relayStats.js"
|
||||||
import {deriveRelayList, getRelayList} from "./relayLists.js"
|
import {deriveRelayList, getRelayList} from "./relayLists.js"
|
||||||
|
import {deriveBlockedRelayList, getBlockedRelayList} from "./blockedRelayLists.js"
|
||||||
import {deriveMessagingRelayList, getMessagingRelayList} from "./messagingRelayLists.js"
|
import {deriveMessagingRelayList, getMessagingRelayList} from "./messagingRelayLists.js"
|
||||||
|
|
||||||
// Sync relays with our database
|
// Sync relays with our database
|
||||||
@@ -84,15 +86,19 @@ const _relayGetter = (fn?: (relay: RelayProfile) => any) =>
|
|||||||
.map(r => r.url)
|
.map(r => r.url)
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getPubkeyRelays = (pubkey: string, mode?: RelayMode) =>
|
export const getPubkeyRelays = (pubkey: string, mode?: RelayMode) => {
|
||||||
mode === RelayMode.Messaging
|
if (mode === RelayMode.Blocked) return getRelaysFromList(getBlockedRelayList(pubkey))
|
||||||
? getRelaysFromList(getMessagingRelayList(pubkey))
|
if (mode === RelayMode.Messaging) return getRelaysFromList(getMessagingRelayList(pubkey))
|
||||||
: getRelaysFromList(getRelayList(pubkey), mode)
|
return getRelaysFromList(getRelayList(pubkey), mode)
|
||||||
|
}
|
||||||
|
|
||||||
export const derivePubkeyRelays = (pubkey: string, mode?: RelayMode) =>
|
export const derivePubkeyRelays = (pubkey: string, mode?: RelayMode) => {
|
||||||
mode === RelayMode.Messaging
|
if (mode === RelayMode.Blocked)
|
||||||
? derived(deriveMessagingRelayList(pubkey), list => getRelaysFromList(list))
|
return derived(deriveBlockedRelayList(pubkey), list => getRelaysFromList(list))
|
||||||
: derived(deriveRelayList(pubkey), list => getRelaysFromList(list, mode))
|
if (mode === RelayMode.Messaging)
|
||||||
|
return derived(deriveMessagingRelayList(pubkey), list => getRelaysFromList(list))
|
||||||
|
return derived(deriveRelayList(pubkey), list => getRelaysFromList(list, mode))
|
||||||
|
}
|
||||||
|
|
||||||
routerContext.getUserPubkey = () => pubkey.get()
|
routerContext.getUserPubkey = () => pubkey.get()
|
||||||
routerContext.getPubkeyRelays = getPubkeyRelays
|
routerContext.getPubkeyRelays = getPubkeyRelays
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import {writable, Subscriber} from "svelte/store"
|
import {writable, Subscriber} from "svelte/store"
|
||||||
import {getter, makeDeriveItem} from "@welshman/store"
|
import {getter, makeDeriveItem} from "@welshman/store"
|
||||||
import {groupBy, batch, now, uniq, ago, DAY, HOUR, MINUTE} from "@welshman/lib"
|
import {groupBy, batch, now, uniq, ago, DAY, HOUR, MINUTE} from "@welshman/lib"
|
||||||
import {isOnionUrl, isLocalUrl, isIPAddress, isRelayUrl} from "@welshman/util"
|
import {isOnionUrl, isLocalUrl, isIPAddress, isRelayUrl, getRelaysFromList} from "@welshman/util"
|
||||||
import {Pool, Socket, SocketStatus, SocketEvent, ClientMessage, RelayMessage} from "@welshman/net"
|
import {Pool, Socket, SocketStatus, SocketEvent, ClientMessage, RelayMessage} from "@welshman/net"
|
||||||
|
import {getBlockedRelayList} from "./blockedRelayLists.js"
|
||||||
|
import {pubkey} from "./session.js"
|
||||||
|
|
||||||
export type RelayStats = {
|
export type RelayStats = {
|
||||||
url: string
|
url: string
|
||||||
@@ -75,6 +77,10 @@ export const getRelayQuality = (url: string) => {
|
|||||||
// Skip non-relays entirely
|
// Skip non-relays entirely
|
||||||
if (!isRelayUrl(url)) return 0
|
if (!isRelayUrl(url)) return 0
|
||||||
|
|
||||||
|
const $pubkey = pubkey.get()
|
||||||
|
|
||||||
|
if ($pubkey && getRelaysFromList(getBlockedRelayList($pubkey)).includes(url)) return 0
|
||||||
|
|
||||||
const relayStats = getRelayStats(url)
|
const relayStats = getRelayStats(url)
|
||||||
|
|
||||||
// If we have recent errors, skip it
|
// If we have recent errors, skip it
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ import {
|
|||||||
forceLoadMessagingRelayList,
|
forceLoadMessagingRelayList,
|
||||||
loadMessagingRelayList,
|
loadMessagingRelayList,
|
||||||
} from "./messagingRelayLists.js"
|
} from "./messagingRelayLists.js"
|
||||||
|
import {
|
||||||
|
blockedRelayListsByPubkey,
|
||||||
|
forceLoadBlockedRelayList,
|
||||||
|
loadBlockedRelayList,
|
||||||
|
} from "./blockedRelayLists.js"
|
||||||
import {wotGraph, getWotGraph} from "./wot.js"
|
import {wotGraph, getWotGraph} from "./wot.js"
|
||||||
|
|
||||||
export const makeUserData = <T>(
|
export const makeUserData = <T>(
|
||||||
@@ -67,6 +72,10 @@ export const userMessagingRelayList = makeUserData(
|
|||||||
export const forceLoadUserMessagingRelayList = makeUserLoader(forceLoadMessagingRelayList)
|
export const forceLoadUserMessagingRelayList = makeUserLoader(forceLoadMessagingRelayList)
|
||||||
export const loadUserMessagingRelayList = makeUserLoader(loadMessagingRelayList)
|
export const loadUserMessagingRelayList = makeUserLoader(loadMessagingRelayList)
|
||||||
|
|
||||||
|
export const userBlockedRelayList = makeUserData(blockedRelayListsByPubkey, loadBlockedRelayList)
|
||||||
|
export const forceLoadUserBlockedRelayList = makeUserLoader(forceLoadBlockedRelayList)
|
||||||
|
export const loadUserBlockedRelayList = makeUserLoader(loadBlockedRelayList)
|
||||||
|
|
||||||
export const userBlossomServerList = makeUserData(blossomServerListsByPubkey, loadBlossomServerList)
|
export const userBlossomServerList = makeUserData(blossomServerListsByPubkey, loadBlossomServerList)
|
||||||
export const forceLoadUserBlossomServerList = makeUserLoader(forceLoadBlossomServerList)
|
export const forceLoadUserBlossomServerList = makeUserLoader(forceLoadBlossomServerList)
|
||||||
export const loadUserBlossomServerList = makeUserLoader(loadBlossomServerList)
|
export const loadUserBlossomServerList = makeUserLoader(loadBlossomServerList)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/content",
|
"name": "@welshman/content",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A collection of utilities for parsing nostr note content.",
|
"description": "A collection of utilities for parsing nostr note content.",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/editor",
|
"name": "@welshman/editor",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A batteries-included nostr editor.",
|
"description": "A batteries-included nostr editor.",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/feeds",
|
"name": "@welshman/feeds",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "Utilities for building dynamic nostr feeds.",
|
"description": "Utilities for building dynamic nostr feeds.",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/lib",
|
"name": "@welshman/lib",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A collection of utilities.",
|
"description": "A collection of utilities.",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/net",
|
"name": "@welshman/net",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "Utilities for connecting with nostr relays.",
|
"description": "Utilities for connecting with nostr relays.",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/router",
|
"name": "@welshman/router",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A collection of utilities for nostr relay selection.",
|
"description": "A collection of utilities for nostr relay selection.",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/signer",
|
"name": "@welshman/signer",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A nostr signer implemenation supporting several login methods.",
|
"description": "A nostr signer implemenation supporting several login methods.",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/store",
|
"name": "@welshman/store",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A collection of utilities based on svelte/store for use with welshman",
|
"description": "A collection of utilities based on svelte/store for use with welshman",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@welshman/util",
|
"name": "@welshman/util",
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"author": "hodlbod",
|
"author": "hodlbod",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A collection of nostr-related utilities.",
|
"description": "A collection of nostr-related utilities.",
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {last, normalizeUrl, stripProtocol} from "@welshman/lib"
|
|||||||
export enum RelayMode {
|
export enum RelayMode {
|
||||||
Read = "read",
|
Read = "read",
|
||||||
Write = "write",
|
Write = "write",
|
||||||
|
Search = "search",
|
||||||
|
Blocked = "blocked",
|
||||||
Messaging = "messaging",
|
Messaging = "messaging",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user