feat: improve relay hint selection to exclude non-content relays

- Add NON_CONTENT_RELAYS list and isContentRelay helper to classify relays
- Update ContentPanel to filter out non-content relays (e.g., relay.nsec.app) from naddr hints
- Update HighlightItem to prefer publishedRelays/seenOnRelays and filter using isContentRelay
- Ensures relay.nsec.app and other auth/utility relays are never suggested as content hints
This commit is contained in:
Gigi
2025-11-15 20:26:37 +00:00
parent c1b171d188
commit 4d18c84243
3 changed files with 40 additions and 7 deletions

View File

@@ -12,6 +12,8 @@ import { nip19 } from 'nostr-tools'
import { getNostrUrl, getSearchUrl } from '../config/nostrGateways' import { getNostrUrl, getSearchUrl } from '../config/nostrGateways'
import { RelayPool } from 'applesauce-relay' import { RelayPool } from 'applesauce-relay'
import { getActiveRelayUrls } from '../services/relayManager' import { getActiveRelayUrls } from '../services/relayManager'
import { isContentRelay } from '../config/relays'
import { isLocalRelay } from '../utils/helpers'
import { IAccount } from 'applesauce-accounts' import { IAccount } from 'applesauce-accounts'
import { NostrEvent } from 'nostr-tools' import { NostrEvent } from 'nostr-tools'
import { Highlight } from '../types/highlights' import { Highlight } from '../types/highlights'
@@ -432,9 +434,10 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
const dTag = currentArticle.tags.find(t => t[0] === 'd')?.[1] || '' const dTag = currentArticle.tags.find(t => t[0] === 'd')?.[1] || ''
const activeRelays = relayPool ? getActiveRelayUrls(relayPool) : [] const activeRelays = relayPool ? getActiveRelayUrls(relayPool) : []
const relayHints = activeRelays.filter(r => const relayHints = activeRelays
!r.includes('localhost') && !r.includes('127.0.0.1') .filter(url => !isLocalRelay(url))
).slice(0, 3) .filter(url => isContentRelay(url))
.slice(0, 3)
const naddr = nip19.naddrEncode({ const naddr = nip19.naddrEncode({
kind: 30023, kind: 30023,

View File

@@ -10,6 +10,7 @@ import { Hooks } from 'applesauce-react'
import { onSyncStateChange, isEventSyncing, isEventOfflineCreated } from '../services/offlineSyncService' import { onSyncStateChange, isEventSyncing, isEventOfflineCreated } from '../services/offlineSyncService'
import { areAllRelaysLocal, isLocalRelay } from '../utils/helpers' import { areAllRelaysLocal, isLocalRelay } from '../utils/helpers'
import { getActiveRelayUrls } from '../services/relayManager' import { getActiveRelayUrls } from '../services/relayManager'
import { isContentRelay } from '../config/relays'
import { nip19 } from 'nostr-tools' import { nip19 } from 'nostr-tools'
import { formatDateCompact } from '../utils/bookmarkUtils' import { formatDateCompact } from '../utils/bookmarkUtils'
import { createDeletionRequest } from '../services/deletionService' import { createDeletionRequest } from '../services/deletionService'
@@ -224,11 +225,23 @@ export const HighlightItem: React.FC<HighlightItemProps> = ({
const getHighlightLinks = () => { const getHighlightLinks = () => {
// Encode the highlight event itself (kind 9802) as a nevent // Encode the highlight event itself (kind 9802) as a nevent
// Get non-local relays for the hint // Prefer relays we actually published to or saw the event on
const publishedRelays = highlight.publishedRelays || []
const seenOnRelays = highlight.seenOnRelays || []
// Use published relays if available, else seen relays, else fall back to active relays
const baseRelays = publishedRelays.length > 0
? publishedRelays
: (seenOnRelays.length > 0 ? seenOnRelays : [])
const activeRelays = relayPool ? getActiveRelayUrls(relayPool) : [] const activeRelays = relayPool ? getActiveRelayUrls(relayPool) : []
const relayHints = activeRelays.filter(r => const candidates = baseRelays.length > 0 ? baseRelays : activeRelays
!r.includes('localhost') && !r.includes('127.0.0.1')
).slice(0, 3) // Include up to 3 relay hints // Filter to content-capable remote relays
const relayHints = candidates
.filter(url => !isLocalRelay(url))
.filter(url => isContentRelay(url))
.slice(0, 3) // Include up to 3 relay hints
const nevent = nip19.neventEncode({ const nevent = nip19.neventEncode({
id: highlight.id, id: highlight.id,

View File

@@ -19,3 +19,20 @@ export const RELAYS = [
'wss://proxy.nostr-relay.app/5d0d38afc49c4b84ca0da951a336affa18438efed302aeedfa92eb8b0d3fcb87', 'wss://proxy.nostr-relay.app/5d0d38afc49c4b84ca0da951a336affa18438efed302aeedfa92eb8b0d3fcb87',
] ]
/**
* Relays that should NOT be used as content hints (auth/signer, etc.)
* These relays are fine for connection and other purposes, but shouldn't
* be suggested as places where posts/highlights are likely to be found.
*/
export const NON_CONTENT_RELAYS = [
'wss://relay.nsec.app',
]
/**
* Check if a relay URL is suitable for use as a content hint
* Returns true for remote relays that are reasonable for posts/highlights
*/
export function isContentRelay(url: string): boolean {
return !NON_CONTENT_RELAYS.includes(url)
}