Build out Settings view: relay management + identity

- addRelay / removeRelay in nostr lib; relay list persisted to localStorage
- getNDK() seeds from localStorage instead of hardcoded list
- Settings > Relays: list with status dots, remove on hover, add with validation
- Settings > Identity: npub display with one-click copy
- Removed local umbrel relay from defaults (was a dev artifact)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jure
2026-03-09 17:33:27 +01:00
parent d52cfa5f75
commit 0a0a00a1b3
3 changed files with 166 additions and 9 deletions
+39 -4
View File
@@ -1,23 +1,58 @@
import NDK, { NDKEvent, NDKFilter, NDKKind, NDKSubscriptionCacheUsage } from "@nostr-dev-kit/ndk";
import NDK, { NDKEvent, NDKFilter, NDKKind, NDKRelay, NDKSubscriptionCacheUsage } from "@nostr-dev-kit/ndk";
const DEFAULT_RELAYS = [
"ws://umbrel.local:4848",
const RELAY_STORAGE_KEY = "wrystr_relays";
const FALLBACK_RELAYS = [
"wss://relay.damus.io",
"wss://nos.lol",
"wss://relay.snort.social",
];
export function getStoredRelayUrls(): string[] {
try {
const stored = localStorage.getItem(RELAY_STORAGE_KEY);
if (stored) return JSON.parse(stored);
} catch { /* ignore */ }
return FALLBACK_RELAYS;
}
function saveRelayUrls(urls: string[]) {
localStorage.setItem(RELAY_STORAGE_KEY, JSON.stringify(urls));
}
let ndk: NDK | null = null;
export function getNDK(): NDK {
if (!ndk) {
ndk = new NDK({
explicitRelayUrls: DEFAULT_RELAYS,
explicitRelayUrls: getStoredRelayUrls(),
});
}
return ndk;
}
export function addRelay(url: string): void {
const instance = getNDK();
const urls = getStoredRelayUrls();
if (!urls.includes(url)) {
saveRelayUrls([...urls, url]);
}
if (!instance.pool?.relays.has(url)) {
const relay = new NDKRelay(url, undefined, instance);
instance.pool?.addRelay(relay, true);
}
}
export function removeRelay(url: string): void {
const instance = getNDK();
const relay = instance.pool?.relays.get(url);
if (relay) {
relay.disconnect();
instance.pool?.relays.delete(url);
}
saveRelayUrls(getStoredRelayUrls().filter((u) => u !== url));
}
function waitForConnectedRelay(instance: NDK, timeoutMs = 10000): Promise<void> {
return new Promise((resolve, _reject) => {
const timer = setTimeout(() => {
+1 -1
View File
@@ -1 +1 @@
export { getNDK, connectToRelays, fetchGlobalFeed, fetchFollowFeed, fetchReplies, publishNote, publishArticle, publishProfile, publishReaction, publishReply, publishContactList, fetchReactionCount, fetchUserNotes, fetchProfile } from "./client";
export { getNDK, connectToRelays, fetchGlobalFeed, fetchFollowFeed, fetchReplies, publishNote, publishArticle, publishProfile, publishReaction, publishReply, publishContactList, fetchReactionCount, fetchUserNotes, fetchProfile, getStoredRelayUrls, addRelay, removeRelay } from "./client";