Fix relay selection for groups and current user

This commit is contained in:
Jon Staab 2023-12-18 10:42:28 -08:00
parent cf1554e1c9
commit 212f3a5a97
16 changed files with 53 additions and 49 deletions

View File

@ -33,7 +33,7 @@
MembershipLevel, MembershipLevel,
publishToZeroOrMoreGroups, publishToZeroOrMoreGroups,
publishDeletionForEvent, publishDeletionForEvent,
getUserRelayUrls, getUserHints,
getPublishHints, getPublishHints,
getSetting, getSetting,
processZap, processZap,
@ -126,7 +126,7 @@
.open() .open()
const broadcast = () => { const broadcast = () => {
const relays = getUserRelayUrls("write") const relays = getUserHints("write")
const event = asNostrEvent(note) const event = asNostrEvent(note)
Publisher.publish({event, relays}) Publisher.publish({event, relays})

View File

@ -13,8 +13,8 @@
import RelayCard from "src/app/shared/RelayCard.svelte" import RelayCard from "src/app/shared/RelayCard.svelte"
import GroupSummary from "src/app/shared/GroupSummary.svelte" import GroupSummary from "src/app/shared/GroupSummary.svelte"
import RelaySearch from "src/app/shared/RelaySearch.svelte" import RelaySearch from "src/app/shared/RelaySearch.svelte"
import {mergeHints, displayRelay, getGroupRelayUrls} from "src/engine" import {getGroupPublishHints, displayRelay} from "src/engine"
import {env, getUserRelayUrls, deriveMembershipLevel, MembershipLevel} from "src/engine" import {env, deriveMembershipLevel, MembershipLevel} from "src/engine"
export let groupOptions = [] export let groupOptions = []
export let hideFields = [] export let hideFields = []
@ -59,11 +59,7 @@
} }
if (!relaysDirty) { if (!relaysDirty) {
if (values.groups.length > 0) { values.relays = getGroupPublishHints(values.groups)
values.relays = mergeHints(values.groups.map(getGroupRelayUrls))
} else {
values.relays = getUserRelayUrls("write")
}
} }
} }

View File

@ -13,7 +13,7 @@
unfollow, unfollow,
deriveMuted, deriveMuted,
deriveFollowing, deriveFollowing,
getUserRelayUrls, getUserHints,
} from "src/engine" } from "src/engine"
import {boot} from "src/app/state" import {boot} from "src/app/state"
import {router} from "src/app/router" import {router} from "src/app/router"
@ -32,8 +32,8 @@
if (!isSelf && $canSign) { if (!isSelf && $canSign) {
actions.push({ actions.push({
onClick: $muted ? unmutePerson : mutePerson, onClick: $muted ? unmutePerson : mutePerson,
label: $muted ? 'Unmute' : 'Mute', label: $muted ? "Unmute" : "Mute",
icon: $muted ? "microphone-slash" : 'microphone', icon: $muted ? "microphone-slash" : "microphone",
}) })
} }
@ -87,7 +87,10 @@
const mutePerson = () => mute("p", pubkey) const mutePerson = () => mute("p", pubkey)
const share = () => const share = () =>
router.at('qrcode').of(nip19.nprofileEncode({pubkey, relays: getUserRelayUrls('write')})).open() router
.at("qrcode")
.of(nip19.nprofileEncode({pubkey, relays: getUserHints("write")}))
.open()
</script> </script>
<div class="flex items-center gap-3" on:click|stopPropagation> <div class="flex items-center gap-3" on:click|stopPropagation>

View File

@ -12,8 +12,7 @@
load, load,
groups, groups,
canUseGiftWrap, canUseGiftWrap,
getUserRelayUrls, getUserHints,
selectHints,
mergeHints, mergeHints,
getGroupReqInfo, getGroupReqInfo,
deriveMembershipLevel, deriveMembershipLevel,
@ -48,12 +47,12 @@
updateCurrentSession(assoc("groups_last_synced", now())) updateCurrentSession(assoc("groups_last_synced", now()))
load({ load({
relays: mergeHints([relays, getUserRelayUrls("read")]), relays: mergeHints([relays, getUserHints("read")]),
filters: [{kinds: [1059], "#p": recipients, since}], filters: [{kinds: [1059], "#p": recipients, since}],
}) })
load({ load({
relays: selectHints(getUserRelayUrls("read")), relays: getUserHints("read"),
filters: [ filters: [
{kinds: [34550], authors: admins}, {kinds: [34550], authors: admins},
{kinds: [34550], limit: 100}, {kinds: [34550], limit: 100},

View File

@ -34,9 +34,9 @@
session, session,
writable, writable,
getEventHints, getEventHints,
getUserRelayUrls,
publishToZeroOrMoreGroups, publishToZeroOrMoreGroups,
deriveMembershipLevel, deriveMembershipLevel,
getGroupPublishHints,
} from "src/engine" } from "src/engine"
export let type = "note" export let type = "note"
@ -58,8 +58,8 @@
summary: "", summary: "",
price: "", price: "",
currency: currencyOptions.find(whereEq({code: "SAT"})), currency: currencyOptions.find(whereEq({code: "SAT"})),
relays: getGroupPublishHints(defaultGroups),
groups: defaultGroups, groups: defaultGroups,
relays: getUserRelayUrls("write"),
shouldWrap: true, shouldWrap: true,
anonymous: false, anonymous: false,
location: null, location: null,

View File

@ -4,7 +4,7 @@ import {now} from "paravel"
import {sessions} from "src/engine/session/state" import {sessions} from "src/engine/session/state"
import {session} from "src/engine/session/derived" import {session} from "src/engine/session/derived"
import {loadPubkeys, subscribe} from "src/engine/network/utils" import {loadPubkeys, subscribe} from "src/engine/network/utils"
import {getPubkeyHints, getUserRelayUrls} from "src/engine/relays/utils" import {getPubkeyHints, getUserHints} from "src/engine/relays/utils"
import {channels} from "./state" import {channels} from "./state"
export const loadAllMessages = () => { export const loadAllMessages = () => {
@ -21,7 +21,7 @@ export const loadAllMessages = () => {
subscribe({ subscribe({
skipCache: true, skipCache: true,
timeout: 30_000, timeout: 30_000,
relays: getUserRelayUrls("read"), relays: getUserHints("read"),
filters: [ filters: [
{kinds: [4], authors: [pubkey], since}, {kinds: [4], authors: [pubkey], since},
{kinds: [4, 1059], "#p": [pubkey], since}, {kinds: [4, 1059], "#p": [pubkey], since},

View File

@ -1,6 +1,6 @@
import {prop} from "ramda" import {prop} from "ramda"
import {sessions} from "src/engine/session/state" import {sessions} from "src/engine/session/state"
import {getUserRelayUrls} from "src/engine/relays/utils" import {getUserHints} from "src/engine/relays/utils"
import {load} from "src/engine/network/utils" import {load} from "src/engine/network/utils"
import {deletesLastUpdated} from "./state" import {deletesLastUpdated} from "./state"
@ -9,7 +9,7 @@ export const loadDeletes = () => {
const authors = Object.values(sessions.get()).map(prop("pubkey")) const authors = Object.values(sessions.get()).map(prop("pubkey"))
return load({ return load({
relays: getUserRelayUrls("write"), relays: getUserHints("write"),
filters: [{kinds: [5], authors, since}], filters: [{kinds: [5], authors, since}],
}) })
} }

View File

@ -12,7 +12,7 @@ import {displayPubkey} from "src/engine/people/utils"
import {publishCommunitiesList} from "src/engine/lists/commands" import {publishCommunitiesList} from "src/engine/lists/commands"
import { import {
getPubkeyHints, getPubkeyHints,
getUserRelayUrls, getUserHints,
getGroupHints, getGroupHints,
getGroupRelayUrls, getGroupRelayUrls,
mergeHints, mergeHints,
@ -86,7 +86,7 @@ export const getGroupPublishRelays = (address, overrides = null) => {
export const publishToGroupAdmin = async (address, template) => { export const publishToGroupAdmin = async (address, template) => {
const group = groups.key(address).get() const group = groups.key(address).get()
const {pubkey} = Naddr.fromTagValue(address) const {pubkey} = Naddr.fromTagValue(address)
const relays = group?.relays || getUserRelayUrls("write") const relays = group?.relays || getUserHints("write")
const rumor = await nip59.get().wrap(template, { const rumor = await nip59.get().wrap(template, {
wrap: { wrap: {
author: generatePrivateKey(), author: generatePrivateKey(),

View File

@ -1,6 +1,6 @@
import {Naddr} from "src/util/nostr" import {Naddr} from "src/util/nostr"
import {groups} from "src/engine/groups/state" import {groups} from "src/engine/groups/state"
import {getUserRelayUrls} from "src/engine/relays/utils" import {getUserHints} from "src/engine/relays/utils"
import {load} from "src/engine/network/utils" import {load} from "src/engine/network/utils"
export const attemptedAddrs = new Map() export const attemptedAddrs = new Map()
@ -33,7 +33,7 @@ export const loadGroups = async (rawAddrs: string[]) => {
const identifiers = naddrs.map(naddr => naddr.identifier) const identifiers = naddrs.map(naddr => naddr.identifier)
return load({ return load({
relays: getUserRelayUrls('read'), relays: getUserHints("read"),
filters: [{kinds: [34550], authors, '#d': identifiers}], filters: [{kinds: [34550], authors, "#d": identifiers}],
}) })
} }

View File

@ -5,7 +5,7 @@ import {Naddr} from "src/util/nostr"
import type {GroupStatus} from "src/engine/session/model" import type {GroupStatus} from "src/engine/session/model"
import {pubkey} from "src/engine/session/state" import {pubkey} from "src/engine/session/state"
import {session} from "src/engine/session/derived" import {session} from "src/engine/session/derived"
import {getUserRelayUrls, mergeHints} from "src/engine/relays/utils" import {getUserRelayUrls, getGroupHints, mergeHints} from "src/engine/relays/utils"
import {groups, groupSharedKeys, groupAdminKeys} from "./state" import {groups, groupSharedKeys, groupAdminKeys} from "./state"
import type {Group} from "./model" import type {Group} from "./model"
import {MembershipLevel, GroupAccess, MemberAccess} from "./model" import {MembershipLevel, GroupAccess, MemberAccess} from "./model"
@ -57,22 +57,16 @@ export const getGroupReqInfo = (address = null) => {
since = Math.max(0, since - seconds(7, "day")) since = Math.max(0, since - seconds(7, "day"))
const admins = [] const admins = []
const addresses = []
const recipients = [pubkey.get()] const recipients = [pubkey.get()]
const relaysByGroup = []
for (const key of [...$groupSharedKeys, ...$groupAdminKeys]) { for (const key of [...$groupSharedKeys, ...$groupAdminKeys]) {
admins.push(Naddr.fromTagValue(key.group).pubkey) admins.push(Naddr.fromTagValue(key.group).pubkey)
addresses.push(key.group)
recipients.push(key.pubkey) recipients.push(key.pubkey)
const group = groups.key(key.group).get()
if (group?.relays) {
relaysByGroup[group.address] = group.relays
}
} }
const relays = mergeHints([getUserRelayUrls("read"), ...Object.values(relaysByGroup)]) const relays = mergeHints([getUserRelayUrls("read"), ...addresses.map(getGroupHints)])
return {admins, recipients, relays, since} return {admins, recipients, relays, since}
} }

View File

@ -1,7 +1,7 @@
import {now} from "paravel" import {now} from "paravel"
import {seconds} from "hurdak" import {seconds} from "hurdak"
import {generatePrivateKey} from "nostr-tools" import {generatePrivateKey} from "nostr-tools"
import {getUserRelayUrls} from "src/engine/relays/utils" import {getUserHints} from "src/engine/relays/utils"
import type {Event} from "src/engine/events/model" import type {Event} from "src/engine/events/model"
import {createAndPublish} from "./publish" import {createAndPublish} from "./publish"
import {subscribe} from "./subscribe" import {subscribe} from "./subscribe"
@ -24,7 +24,7 @@ export const dvmRequest = async ({
onProgress = null, onProgress = null,
}: DVMRequestOpts): Promise<Event> => { }: DVMRequestOpts): Promise<Event> => {
if (!relays) { if (!relays) {
relays = getUserRelayUrls() relays = getUserHints()
} }
if (typeof input !== "string") { if (typeof input !== "string") {

View File

@ -8,7 +8,7 @@ import {Naddr, isAddressable, getIdAndAddress} from "src/util/nostr"
import type {Event, NostrEvent} from "src/engine/events/model" import type {Event, NostrEvent} from "src/engine/events/model"
import {people} from "src/engine/people/state" import {people} from "src/engine/people/state"
import {displayPerson} from "src/engine/people/utils" import {displayPerson} from "src/engine/people/utils"
import {getUserRelayUrls, getEventHints, getPubkeyHint} from "src/engine/relays/utils" import {getUserHints, getEventHints, getPubkeyHint} from "src/engine/relays/utils"
import {env} from "src/engine/session/state" import {env} from "src/engine/session/state"
import {signer} from "src/engine/session/derived" import {signer} from "src/engine/session/derived"
import {projections} from "src/engine/core/projections" import {projections} from "src/engine/core/projections"
@ -143,7 +143,7 @@ export type PublishOpts = EventOpts & {
export const publish = async (template, {sk, relays}: PublishOpts) => { export const publish = async (template, {sk, relays}: PublishOpts) => {
return Publisher.publish({ return Publisher.publish({
timeout: 5000, timeout: 5000,
relays: relays || getUserRelayUrls("write"), relays: relays || getUserHints("write"),
event: sk event: sk
? await signer.get().signWithKey(template, sk) ? await signer.get().signWithKey(template, sk)
: await signer.get().signAsUser(template), : await signer.get().signAsUser(template),

View File

@ -1,6 +1,6 @@
import {createEvent} from "paravel" import {createEvent} from "paravel"
import {getIdAndAddress} from 'src/util/nostr' import {getIdAndAddress} from "src/util/nostr"
import {getUserRelayUrls} from "src/engine/relays/utils" import {getUserHints} from "src/engine/relays/utils"
import {createAndPublish, getReplyTags} from "src/engine/network/utils" import {createAndPublish, getReplyTags} from "src/engine/network/utils"
export const publishNote = (content, tags = [], relays = null) => export const publishNote = (content, tags = [], relays = null) =>
@ -8,7 +8,7 @@ export const publishNote = (content, tags = [], relays = null) =>
export const publishDeletion = (ids, relays = null) => export const publishDeletion = (ids, relays = null) =>
createAndPublish(5, { createAndPublish(5, {
relays: relays || getUserRelayUrls("write"), relays: relays || getUserHints("write"),
tags: ids.map(id => [id.includes(":") ? "a" : "e", id]), tags: ids.map(id => [id.includes(":") ? "a" : "e", id]),
}) })

View File

@ -1,6 +1,6 @@
import {debounce} from "throttle-debounce" import {debounce} from "throttle-debounce"
import {load} from "src/engine/network/utils" import {load} from "src/engine/network/utils"
import {getUserRelayUrls} from "src/engine/relays/utils" import {getUserHints} from "src/engine/relays/utils"
import {searchableRelays} from "src/engine/relays/derived" import {searchableRelays} from "src/engine/relays/derived"
import {people} from "./state" import {people} from "./state"
@ -14,7 +14,7 @@ export const loadPeople = debounce(500, search => {
}) })
} else if (people.get().length < 50) { } else if (people.get().length < 50) {
load({ load({
relays: getUserRelayUrls("read"), relays: getUserHints("read"),
filters: [{kinds: [0], limit: 50}], filters: [{kinds: [0], limit: 50}],
}) })
} }

View File

@ -170,6 +170,12 @@ export const getPubkeyHints = hintSelector(function* (pubkey: string, mode: Rela
export const getPubkeyHint = (pubkey: string): string => export const getPubkeyHint = (pubkey: string): string =>
first(getPubkeyHints(1, pubkey, "write")) || "" first(getPubkeyHints(1, pubkey, "write")) || ""
export const getUserHints = hintSelector(function* (mode: RelayMode) {
yield* getUserRelayUrls(mode)
})
export const getUserHint = (pubkey: string): string => first(getUserHints(1, "write")) || ""
export const getEventHints = hintSelector(function* (event: Event) { export const getEventHints = hintSelector(function* (event: Event) {
yield* getPubkeyRelayUrls(event.pubkey, RelayMode.Write) yield* getPubkeyRelayUrls(event.pubkey, RelayMode.Write)
yield* event.seen_on.filter(isShareableRelay) yield* event.seen_on.filter(isShareableRelay)
@ -217,6 +223,12 @@ export const getGroupHints = hintSelector(function* (address: string) {
yield* getPubkeyHints(Naddr.fromTagValue(address).pubkey) yield* getPubkeyHints(Naddr.fromTagValue(address).pubkey)
}) })
export const getGroupPublishHints = (addresses: string[]) => {
const urls = mergeHints(addresses.map(getGroupHints))
return urls.length === 0 ? getUserRelayUrls("write") : urls
}
export const mergeHints = (groups: string[][], limit: number = null) => { export const mergeHints = (groups: string[][], limit: number = null) => {
const scores = {} as Record<string, any> const scores = {} as Record<string, any>

View File

@ -1,12 +1,12 @@
import {createEvent} from "paravel" import {createEvent} from "paravel"
import {generatePrivateKey} from "nostr-tools" import {generatePrivateKey} from "nostr-tools"
import {signer} from "src/engine/session/derived" import {signer} from "src/engine/session/derived"
import {getUserRelayUrls} from "src/engine/relays/utils" import {getUserHints} from "src/engine/relays/utils"
import {Publisher} from "src/engine/network/utils" import {Publisher} from "src/engine/network/utils"
// Use an ephemeral private key for user privacy // Use an ephemeral private key for user privacy
export const publishReport = async (content = "", tags = [], relays = null) => export const publishReport = async (content = "", tags = [], relays = null) =>
Publisher.publish({ Publisher.publish({
relays: relays || getUserRelayUrls("write"), relays: relays || getUserHints("write"),
event: await signer.get().signWithKey(createEvent(1984, {content, tags}), generatePrivateKey()), event: await signer.get().signWithKey(createEvent(1984, {content, tags}), generatePrivateKey()),
}) })