mirror of
https://github.com/dergigi/boris.git
synced 2025-12-18 15:14:20 +01:00
feat: add local relay support and centralize relay configuration
This commit is contained in:
26
src/App.tsx
26
src/App.tsx
@@ -11,6 +11,7 @@ import { createAddressLoader } from 'applesauce-loaders/loaders'
|
||||
import Bookmarks from './components/Bookmarks'
|
||||
import Toast from './components/Toast'
|
||||
import { useToast } from './hooks/useToast'
|
||||
import { ALL_RELAYS, PROFILE_RELAYS } from './config/relays'
|
||||
|
||||
const DEFAULT_ARTICLE = import.meta.env.VITE_DEFAULT_ARTICLE_NADDR ||
|
||||
'naddr1qvzqqqr4gupzqmjxss3dld622uu8q25gywum9qtg4w4cv4064jmg20xsac2aam5nqqxnzd3cxqmrzv3exgmr2wfesgsmew'
|
||||
@@ -94,33 +95,16 @@ function App() {
|
||||
|
||||
const pool = new RelayPool()
|
||||
|
||||
// Define relay URLs for bookmark fetching
|
||||
const relayUrls = [
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.dergigi.com',
|
||||
'wss://wot.dergigi.com',
|
||||
'wss://relay.snort.social',
|
||||
'wss://relay.current.fyi',
|
||||
'wss://nostr-pub.wellorder.net'
|
||||
]
|
||||
|
||||
// Create a relay group for better event deduplication and management
|
||||
// This follows the applesauce-relay documentation pattern
|
||||
// Note: We could use pool.group(relayUrls) for direct requests in the future
|
||||
pool.group(relayUrls)
|
||||
console.log('Created relay group with', relayUrls.length, 'relays')
|
||||
console.log('Relay URLs:', relayUrls)
|
||||
pool.group(ALL_RELAYS)
|
||||
console.log('Created relay group with', ALL_RELAYS.length, 'relays (including local)')
|
||||
console.log('Relay URLs:', ALL_RELAYS)
|
||||
|
||||
// Attach address/replaceable loaders so ProfileModel can fetch profiles
|
||||
const addressLoader = createAddressLoader(pool, {
|
||||
eventStore: store,
|
||||
lookupRelays: [
|
||||
'wss://purplepag.es',
|
||||
'wss://relay.primal.net',
|
||||
'wss://relay.nostr.band'
|
||||
]
|
||||
lookupRelays: PROFILE_RELAYS
|
||||
})
|
||||
store.addressableLoader = addressLoader
|
||||
store.replaceableLoader = addressLoader
|
||||
|
||||
70
src/config/relays.ts
Normal file
70
src/config/relays.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Centralized relay configuration
|
||||
* All relay URLs used throughout the application
|
||||
*/
|
||||
|
||||
// Local relay URL (hardcoded for development)
|
||||
export const LOCAL_RELAY = 'ws://localhost:7777'
|
||||
|
||||
// Public relays for general use
|
||||
export const PUBLIC_RELAYS = [
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.dergigi.com',
|
||||
'wss://wot.dergigi.com',
|
||||
'wss://relay.snort.social',
|
||||
'wss://relay.current.fyi',
|
||||
'wss://nostr-pub.wellorder.net'
|
||||
]
|
||||
|
||||
// Relays for profile lookups
|
||||
export const PROFILE_RELAYS = [
|
||||
'wss://purplepag.es',
|
||||
'wss://relay.primal.net',
|
||||
'wss://relay.nostr.band'
|
||||
]
|
||||
|
||||
// Relays for highlights (read and write)
|
||||
export const HIGHLIGHT_RELAYS = [
|
||||
LOCAL_RELAY,
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.snort.social',
|
||||
'wss://purplepag.es'
|
||||
]
|
||||
|
||||
// Relays for articles
|
||||
export const ARTICLE_RELAYS = [
|
||||
LOCAL_RELAY,
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.primal.net'
|
||||
]
|
||||
|
||||
// Relays for settings (read and write)
|
||||
export const SETTINGS_RELAYS = [
|
||||
LOCAL_RELAY,
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.dergigi.com',
|
||||
'wss://wot.dergigi.com'
|
||||
]
|
||||
|
||||
// All relays including local (for general operations and relay pool initialization)
|
||||
export const ALL_RELAYS = [LOCAL_RELAY, ...PUBLIC_RELAYS]
|
||||
|
||||
// All write relays (where we publish events)
|
||||
export const WRITE_RELAYS = [
|
||||
LOCAL_RELAY,
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.snort.social',
|
||||
'wss://purplepag.es',
|
||||
'wss://relay.dergigi.com'
|
||||
]
|
||||
|
||||
@@ -5,11 +5,7 @@ import { EventFactory } from 'applesauce-factory'
|
||||
import { AccountManager } from 'applesauce-accounts'
|
||||
import { UserSettings, loadSettings, saveSettings, watchSettings } from '../services/settingsService'
|
||||
import { loadFont, getFontFamily } from '../utils/fontLoader'
|
||||
|
||||
const RELAY_URLS = [
|
||||
'wss://relay.damus.io', 'wss://nos.lol', 'wss://relay.nostr.band',
|
||||
'wss://relay.dergigi.com', 'wss://wot.dergigi.com'
|
||||
]
|
||||
import { SETTINGS_RELAYS } from '../config/relays'
|
||||
|
||||
interface UseSettingsParams {
|
||||
relayPool: RelayPool | null
|
||||
@@ -29,7 +25,7 @@ export function useSettings({ relayPool, eventStore, pubkey, accountManager }: U
|
||||
|
||||
const loadAndWatch = async () => {
|
||||
try {
|
||||
const loadedSettings = await loadSettings(relayPool, eventStore, pubkey, RELAY_URLS)
|
||||
const loadedSettings = await loadSettings(relayPool, eventStore, pubkey, SETTINGS_RELAYS)
|
||||
if (loadedSettings) setSettings(loadedSettings)
|
||||
} catch (err) {
|
||||
console.error('Failed to load settings:', err)
|
||||
@@ -65,7 +61,7 @@ export function useSettings({ relayPool, eventStore, pubkey, accountManager }: U
|
||||
const fullAccount = accountManager.getActive()
|
||||
if (!fullAccount) throw new Error('No active account')
|
||||
const factory = new EventFactory({ signer: fullAccount })
|
||||
await saveSettings(relayPool, eventStore, factory, newSettings, RELAY_URLS)
|
||||
await saveSettings(relayPool, eventStore, factory, newSettings, SETTINGS_RELAYS)
|
||||
setSettings(newSettings)
|
||||
setToastType('success')
|
||||
setToastMessage('Settings saved')
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
getArticlePublished,
|
||||
getArticleSummary
|
||||
} from 'applesauce-core/helpers'
|
||||
import { ARTICLE_RELAYS } from '../config/relays'
|
||||
|
||||
export interface ArticleContent {
|
||||
title: string
|
||||
@@ -95,15 +96,10 @@ export async function fetchArticleByNaddr(
|
||||
|
||||
const pointer = decoded.data as AddressPointer
|
||||
|
||||
// Define relays to query
|
||||
// Define relays to query - prefer relays from naddr, fallback to configured relays (including local)
|
||||
const relays = pointer.relays && pointer.relays.length > 0
|
||||
? pointer.relays
|
||||
: [
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.primal.net'
|
||||
]
|
||||
: ARTICLE_RELAYS
|
||||
|
||||
// Fetch the article event
|
||||
const filter = {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { RelayPool } from 'applesauce-relay'
|
||||
import { IAccount } from 'applesauce-accounts'
|
||||
import { AddressPointer } from 'nostr-tools/nip19'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { WRITE_RELAYS } from '../config/relays'
|
||||
|
||||
/**
|
||||
* Creates and publishes a highlight event (NIP-84)
|
||||
@@ -36,18 +37,10 @@ export async function createHighlight(
|
||||
// Sign the event
|
||||
const signedEvent = await factory.sign(highlightEvent)
|
||||
|
||||
// Publish to relays
|
||||
const relayUrls = [
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.snort.social',
|
||||
'wss://purplepag.es'
|
||||
]
|
||||
|
||||
await relayPool.publish(relayUrls, signedEvent)
|
||||
// Publish to relays (including local relay)
|
||||
await relayPool.publish(WRITE_RELAYS, signedEvent)
|
||||
|
||||
console.log('✅ Highlight published:', signedEvent)
|
||||
console.log('✅ Highlight published to', WRITE_RELAYS.length, 'relays (including local):', signedEvent)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
getHighlightAttributions
|
||||
} from 'applesauce-core/helpers'
|
||||
import { Highlight } from '../types/highlights'
|
||||
import { HIGHLIGHT_RELAYS } from '../config/relays'
|
||||
|
||||
/**
|
||||
* Deduplicate highlight events by ID
|
||||
@@ -42,18 +43,9 @@ export const fetchHighlightsForArticle = async (
|
||||
onHighlight?: (highlight: Highlight) => void
|
||||
): Promise<Highlight[]> => {
|
||||
try {
|
||||
// Use well-known relays for highlights even if user isn't logged in
|
||||
const highlightRelays = [
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.nostr.band',
|
||||
'wss://relay.snort.social',
|
||||
'wss://purplepag.es'
|
||||
]
|
||||
|
||||
console.log('🔍 Fetching highlights (kind 9802) for article:', articleCoordinate)
|
||||
console.log('🔍 Event ID:', eventId || 'none')
|
||||
console.log('🔍 From relays:', highlightRelays)
|
||||
console.log('🔍 From relays (including local):', HIGHLIGHT_RELAYS)
|
||||
|
||||
const seenIds = new Set<string>()
|
||||
const processEvent = (event: NostrEvent): Highlight | null => {
|
||||
@@ -89,7 +81,7 @@ export const fetchHighlightsForArticle = async (
|
||||
// Query for highlights that reference this article via the 'a' tag
|
||||
const aTagEvents = await lastValueFrom(
|
||||
relayPool
|
||||
.req(highlightRelays, { kinds: [9802], '#a': [articleCoordinate] })
|
||||
.req(HIGHLIGHT_RELAYS, { kinds: [9802], '#a': [articleCoordinate] })
|
||||
.pipe(
|
||||
onlyEvents(),
|
||||
tap((event: NostrEvent) => {
|
||||
@@ -111,7 +103,7 @@ export const fetchHighlightsForArticle = async (
|
||||
if (eventId) {
|
||||
eTagEvents = await lastValueFrom(
|
||||
relayPool
|
||||
.req(highlightRelays, { kinds: [9802], '#e': [eventId] })
|
||||
.req(HIGHLIGHT_RELAYS, { kinds: [9802], '#e': [eventId] })
|
||||
.pipe(
|
||||
onlyEvents(),
|
||||
tap((event: NostrEvent) => {
|
||||
|
||||
Reference in New Issue
Block a user