diff --git a/src/app/chat/pages/index.page.tsx b/src/app/chat/pages/index.page.tsx
index 4b752a25..9a6b0aad 100644
--- a/src/app/chat/pages/index.page.tsx
+++ b/src/app/chat/pages/index.page.tsx
@@ -1,18 +1,19 @@
import ChatMessageForm from '@lume/app/chat/components/messages/form';
+import { RelayContext } from '@lume/shared/relayProvider';
import { chatMessagesAtom } from '@lume/stores/chat';
-import { FULL_RELAYS } from '@lume/stores/constants';
+import { READONLY_RELAYS } from '@lume/stores/constants';
import { useActiveAccount } from '@lume/utils/hooks/useActiveAccount';
import { usePageContext } from '@lume/utils/hooks/usePageContext';
import { useSetAtom } from 'jotai';
import { useResetAtom } from 'jotai/utils';
-import { RelayPool } from 'nostr-relaypool';
-import { Suspense, lazy, useEffect } from 'react';
+import { Suspense, lazy, useContext, useEffect } from 'react';
import useSWRSubscription from 'swr/subscription';
const ChatMessageList = lazy(() => import('@lume/app/chat/components/messageList'));
export function Page() {
+ const pool: any = useContext(RelayContext);
const pageContext = usePageContext();
const searchParams: any = pageContext.urlParsed.search;
@@ -24,7 +25,6 @@ export function Page() {
const resetChatMessages = useResetAtom(chatMessagesAtom);
useSWRSubscription(pubkey ? ['chat', pubkey] : null, ([, key], {}: any) => {
- const pool = new RelayPool(FULL_RELAYS);
const unsubscribe = pool.subscribe(
[
{
@@ -40,7 +40,7 @@ export function Page() {
limit: 20,
},
],
- FULL_RELAYS,
+ READONLY_RELAYS,
(event: any) => {
setChatMessages((prev) => [...prev, event]);
}
diff --git a/src/app/inital-data/pages/index.page.tsx b/src/app/inital-data/pages/index.page.tsx
index 96a64e49..980d92b8 100644
--- a/src/app/inital-data/pages/index.page.tsx
+++ b/src/app/inital-data/pages/index.page.tsx
@@ -1,5 +1,6 @@
import LumeIcon from '@lume/shared/icons/lume';
-import { FULL_RELAYS } from '@lume/stores/constants';
+import { RelayContext } from '@lume/shared/relayProvider';
+import { READONLY_RELAYS } from '@lume/stores/constants';
import { dateToUnix, hoursAgo } from '@lume/utils/getDate';
import {
addToBlacklist,
@@ -12,11 +13,11 @@ import {
} from '@lume/utils/storage';
import { getParentID, nip02ToArray } from '@lume/utils/transform';
-import { RelayPool } from 'nostr-relaypool';
-import { useEffect, useRef } from 'react';
+import { useContext, useEffect, useRef } from 'react';
import { navigate } from 'vite-plugin-ssr/client/router';
export function Page() {
+ const pool: any = useContext(RelayContext);
const now = useRef(new Date());
useEffect(() => {
@@ -28,7 +29,6 @@ export function Page() {
const lastLogin = await getLastLogin();
const notes = await countTotalNotes();
- const pool = new RelayPool(FULL_RELAYS);
const follows = nip02ToArray(JSON.parse(account.follows));
const query = [];
@@ -71,7 +71,7 @@ export function Page() {
// subscribe relays
unsubscribe = pool.subscribe(
query,
- FULL_RELAYS,
+ READONLY_RELAYS,
(event: any) => {
switch (event.kind) {
// short text note
@@ -140,7 +140,7 @@ export function Page() {
}
clearTimeout(timeout);
};
- }, []);
+ }, [pool]);
return (
diff --git a/src/app/newsfeed/components/form.tsx b/src/app/newsfeed/components/form.tsx
index 5f7f50aa..039ed796 100644
--- a/src/app/newsfeed/components/form.tsx
+++ b/src/app/newsfeed/components/form.tsx
@@ -1,4 +1,5 @@
import { ImagePicker } from '@lume/shared/form/imagePicker';
+import { RelayContext } from '@lume/shared/relayProvider';
import { WRITEONLY_RELAYS } from '@lume/stores/constants';
import { noteContentAtom } from '@lume/stores/note';
import { dateToUnix } from '@lume/utils/getDate';
@@ -6,17 +7,17 @@ import { useActiveAccount } from '@lume/utils/hooks/useActiveAccount';
import { useAtom } from 'jotai';
import { useResetAtom } from 'jotai/utils';
-import { RelayPool } from 'nostr-relaypool';
import { getEventHash, signEvent } from 'nostr-tools';
+import { useContext } from 'react';
export default function NoteForm() {
+ const pool: any = useContext(RelayContext);
const { account, isLoading, isError } = useActiveAccount();
const [value, setValue] = useAtom(noteContentAtom);
const resetValue = useResetAtom(noteContentAtom);
const submitEvent = () => {
if (!isLoading && !isError && account) {
- const pool = new RelayPool(WRITEONLY_RELAYS);
const event: any = {
content: value,
created_at: dateToUnix(),
diff --git a/src/app/newsfeed/components/note/parent.tsx b/src/app/newsfeed/components/note/parent.tsx
index 466b3413..6e145466 100644
--- a/src/app/newsfeed/components/note/parent.tsx
+++ b/src/app/newsfeed/components/note/parent.tsx
@@ -1,14 +1,15 @@
import { contentParser } from '@lume/app/newsfeed/components/contentParser';
import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default';
+import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
-import { RelayPool } from 'nostr-relaypool';
-import { memo } from 'react';
+import { memo, useContext } from 'react';
import useSWRSubscription from 'swr/subscription';
export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
+ const pool: any = useContext(RelayContext);
+
const { data, error } = useSWRSubscription(id ? id : null, (key, { next }) => {
- const pool = new RelayPool(READONLY_RELAYS);
const unsubscribe = pool.subscribe(
[
{
diff --git a/src/app/newsfeed/components/note/quote.tsx b/src/app/newsfeed/components/note/quote.tsx
index 587d1fd2..2b2c1e87 100644
--- a/src/app/newsfeed/components/note/quote.tsx
+++ b/src/app/newsfeed/components/note/quote.tsx
@@ -1,41 +1,36 @@
import { contentParser } from '@lume/app/newsfeed/components/contentParser';
import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default';
+import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
-import { RelayPool } from 'nostr-relaypool';
-import { memo } from 'react';
+import { memo, useContext } from 'react';
import useSWRSubscription from 'swr/subscription';
export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) {
- const { data, error } = useSWRSubscription(
- id
- ? [
- {
- ids: [id],
- kinds: [1],
- },
- ]
- : null,
- (key, { next }) => {
- const pool = new RelayPool(READONLY_RELAYS);
- const unsubscribe = pool.subscribe(
- key,
- READONLY_RELAYS,
- (event: any) => {
- next(null, event);
- },
- undefined,
- undefined,
- {
- unsubscribeOnEose: true,
- }
- );
+ const pool: any = useContext(RelayContext);
- return () => {
- unsubscribe();
- };
- }
- );
+ const { data, error } = useSWRSubscription(id ? id : null, (key, { next }) => {
+ const unsubscribe = pool.subscribe(
+ [
+ {
+ ids: [key],
+ },
+ ],
+ READONLY_RELAYS,
+ (event: any) => {
+ next(null, event);
+ },
+ undefined,
+ undefined,
+ {
+ unsubscribeOnEose: true,
+ }
+ );
+
+ return () => {
+ unsubscribe();
+ };
+ });
return (
diff --git a/src/app/newsfeed/components/note/rootNote.tsx b/src/app/newsfeed/components/note/rootNote.tsx
index e3f9c4cb..117658b8 100644
--- a/src/app/newsfeed/components/note/rootNote.tsx
+++ b/src/app/newsfeed/components/note/rootNote.tsx
@@ -1,17 +1,17 @@
import { contentParser } from '@lume/app/newsfeed/components/contentParser';
import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default';
+import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
-import { RelayPool } from 'nostr-relaypool';
-import { memo } from 'react';
+import { memo, useContext } from 'react';
import useSWRSubscription from 'swr/subscription';
import { navigate } from 'vite-plugin-ssr/client/router';
export const RootNote = memo(function RootNote({ id, fallback }: { id: string; fallback?: any }) {
+ const pool: any = useContext(RelayContext);
const parseFallback = fallback.length > 0 ? JSON.parse(fallback) : null;
const { data, error } = useSWRSubscription(parseFallback ? null : id, (key, { next }) => {
- const pool = new RelayPool(READONLY_RELAYS);
const unsubscribe = pool.subscribe(
[
{
diff --git a/src/app/newsfeed/layout.tsx b/src/app/newsfeed/layout.tsx
index 64fe2983..0b260f69 100644
--- a/src/app/newsfeed/layout.tsx
+++ b/src/app/newsfeed/layout.tsx
@@ -10,7 +10,7 @@ export function LayoutNewsfeed({ children }: { children: React.ReactNode }) {
data-tauri-drag-region
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
>
-
+
diff --git a/src/auth/pages/create/step-3/index.page.tsx b/src/auth/pages/create/step-3/index.page.tsx
index fff851a4..46c26bd7 100644
--- a/src/auth/pages/create/step-3/index.page.tsx
+++ b/src/auth/pages/create/step-3/index.page.tsx
@@ -1,4 +1,5 @@
import User from '@lume/auth/components/user';
+import { RelayContext } from '@lume/shared/relayProvider';
import { WRITEONLY_RELAYS } from '@lume/stores/constants';
import { onboardingAtom } from '@lume/stores/onboarding';
import { createAccount, createPleb } from '@lume/utils/storage';
@@ -6,9 +7,8 @@ import { arrayToNIP02 } from '@lume/utils/transform';
import { CheckCircle } from 'iconoir-react';
import { useAtom } from 'jotai';
-import { RelayPool } from 'nostr-relaypool';
import { getEventHash, signEvent } from 'nostr-tools';
-import { useState } from 'react';
+import { useContext, useState } from 'react';
import { navigate } from 'vite-plugin-ssr/client/router';
const initialList = [
@@ -47,6 +47,8 @@ const initialList = [
];
export function Page() {
+ const pool: any = useContext(RelayContext);
+
const [loading, setLoading] = useState(false);
const [follows, setFollows] = useState([]);
const [onboarding] = useAtom(onboardingAtom);
@@ -58,7 +60,6 @@ export function Page() {
};
const broadcastAccount = () => {
- const pool = new RelayPool(WRITEONLY_RELAYS);
// build event
const event: any = {
content: JSON.stringify(onboarding.metadata),
@@ -74,7 +75,6 @@ export function Page() {
};
const broadcastContacts = () => {
- const pool = new RelayPool(WRITEONLY_RELAYS);
const nip02 = arrayToNIP02(follows);
// build event
const event: any = {
diff --git a/src/auth/pages/import/step-2/index.page.tsx b/src/auth/pages/import/step-2/index.page.tsx
index 78d9a33f..ca572cec 100644
--- a/src/auth/pages/import/step-2/index.page.tsx
+++ b/src/auth/pages/import/step-2/index.page.tsx
@@ -1,33 +1,32 @@
-import { DEFAULT_AVATAR, READONLY_RELAYS } from '@lume/stores/constants';
+import { RelayContext } from '@lume/shared/relayProvider';
+import { DEFAULT_AVATAR } from '@lume/stores/constants';
import { onboardingAtom } from '@lume/stores/onboarding';
import { shortenKey } from '@lume/utils/shortenKey';
import { createAccount, createPleb } from '@lume/utils/storage';
import { useAtom } from 'jotai';
-import { RelayPool } from 'nostr-relaypool';
import { getPublicKey } from 'nostr-tools';
-import { useMemo, useState } from 'react';
+import { useContext, useMemo, useState } from 'react';
import useSWRSubscription from 'swr/subscription';
import { navigate } from 'vite-plugin-ssr/client/router';
export function Page() {
+ const pool: any = useContext(RelayContext);
+
const [loading, setLoading] = useState(false);
const [onboarding, setOnboarding] = useAtom(onboardingAtom);
const pubkey = useMemo(() => (onboarding.privkey ? getPublicKey(onboarding.privkey) : ''), [onboarding.privkey]);
- const { data: user, error } = useSWRSubscription(
- pubkey && !loading
- ? [
- {
- kinds: [0, 3],
- authors: [pubkey],
- },
- ]
- : null,
- (key, { next }) => {
- const pool = new RelayPool(READONLY_RELAYS);
-
- const unsubscribe = pool.subscribe(key, READONLY_RELAYS, (event: any) => {
+ const { data: user, error } = useSWRSubscription(pubkey && !loading ? pubkey : null, (key, { next }) => {
+ const unsubscribe = pool.subscribe(
+ [
+ {
+ kinds: [0, 3],
+ authors: [key],
+ },
+ ],
+ null,
+ (event: any) => {
switch (event.kind) {
case 0:
// update state
@@ -41,13 +40,13 @@ export function Page() {
default:
break;
}
- });
+ }
+ );
- return () => {
- unsubscribe();
- };
- }
- );
+ return () => {
+ unsubscribe();
+ };
+ });
const submit = () => {
// show loading indicator
diff --git a/src/renderer/shell.tsx b/src/renderer/shell.tsx
index afc6d2ed..909ff9cb 100644
--- a/src/renderer/shell.tsx
+++ b/src/renderer/shell.tsx
@@ -1,4 +1,4 @@
-import AccountProvider from '@lume/shared/accountProvider';
+import RelayProvider from '@lume/shared/relayProvider';
import { PageContextProvider } from '@lume/utils/hooks/usePageContext';
import { PageContext } from '@renderer/types';
@@ -14,9 +14,9 @@ export function Shell({ children, pageContext }: { children: React.ReactNode; pa
return (
-
+
{children}
-
+
);
diff --git a/src/shared/accountProvider.tsx b/src/shared/accountProvider.tsx
deleted file mode 100644
index d882c406..00000000
--- a/src/shared/accountProvider.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { createContext } from 'react';
-
-export const AccountContext = createContext({});
-
-let activeAccount: any = { id: '', pubkey: '', follows: null, metadata: {} };
-
-if (typeof window !== 'undefined') {
- const { getActiveAccount } = await import('@lume/utils/storage');
- activeAccount = await getActiveAccount();
-}
-
-export default function AccountProvider({ children }: { children: React.ReactNode }) {
- return
{children};
-}
diff --git a/src/shared/appHeader.tsx b/src/shared/appHeader.tsx
index a5ebbac7..8f94c165 100644
--- a/src/shared/appHeader.tsx
+++ b/src/shared/appHeader.tsx
@@ -1,5 +1,3 @@
-import EventCollector from '@lume/shared/eventCollector';
-
import { ArrowLeft, ArrowRight, Refresh } from 'iconoir-react';
let platformName = 'darwin';
@@ -9,7 +7,7 @@ if (typeof window !== 'undefined') {
platformName = await platform();
}
-export default function AppHeader({ collector }: { collector: boolean }) {
+export default function AppHeader() {
const goBack = () => {
window.history.back();
};
@@ -46,7 +44,6 @@ export default function AppHeader({ collector }: { collector: boolean }) {
);
diff --git a/src/shared/eventCollector.tsx b/src/shared/eventCollector.tsx
index 15dd5c5f..81cd468b 100644
--- a/src/shared/eventCollector.tsx
+++ b/src/shared/eventCollector.tsx
@@ -1,4 +1,5 @@
import { NetworkStatusIndicator } from '@lume/shared/networkStatusIndicator';
+import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
import { hasNewerNoteAtom } from '@lume/stores/note';
import { dateToUnix } from '@lume/utils/getDate';
@@ -7,20 +8,19 @@ import { createChat, createNote, updateAccount } from '@lume/utils/storage';
import { getParentID, nip02ToArray } from '@lume/utils/transform';
import { useSetAtom } from 'jotai';
-import { RelayPool } from 'nostr-relaypool';
-import { useRef } from 'react';
+import { useContext, useRef } from 'react';
import useSWRSubscription from 'swr/subscription';
export default function EventCollector() {
+ const pool: any = useContext(RelayContext);
+
const setHasNewerNote = useSetAtom(hasNewerNoteAtom);
const now = useRef(new Date());
const { account, isLoading, isError } = useActiveAccount();
- useSWRSubscription(!isLoading && !isError ? account : null, () => {
- const follows = nip02ToArray(JSON.parse(account.follows));
-
- const pool = new RelayPool(READONLY_RELAYS);
+ useSWRSubscription(!isLoading && !isError && account ? ['eventCollector', account] : null, ([, key], {}) => {
+ const follows = nip02ToArray(JSON.parse(key.follows));
const unsubscribe = pool.subscribe(
[
{
@@ -30,11 +30,11 @@ export default function EventCollector() {
},
{
kinds: [0, 3],
- authors: [account.pubkey],
+ authors: [key.pubkey],
},
{
kinds: [4],
- '#p': [account.pubkey],
+ '#p': [key.pubkey],
since: dateToUnix(now.current),
},
],
@@ -68,15 +68,15 @@ export default function EventCollector() {
break;
// chat
case 4:
- if (event.pubkey !== account.pubkey) {
- createChat(account.id, event.pubkey, event.created_at);
+ if (event.pubkey !== key.pubkey) {
+ createChat(key.id, event.pubkey, event.created_at);
}
break;
// repost
case 6:
createNote(
event.id,
- account.id,
+ key.id,
event.pubkey,
event.kind,
event.tags,
diff --git a/src/shared/form/comment.tsx b/src/shared/form/comment.tsx
index 59732e8b..af9b9f09 100644
--- a/src/shared/form/comment.tsx
+++ b/src/shared/form/comment.tsx
@@ -1,20 +1,19 @@
+import { RelayContext } from '@lume/shared/relayProvider';
import { WRITEONLY_RELAYS } from '@lume/stores/constants';
import { dateToUnix } from '@lume/utils/getDate';
import { useActiveAccount } from '@lume/utils/hooks/useActiveAccount';
-import { RelayPool } from 'nostr-relaypool';
import { getEventHash, signEvent } from 'nostr-tools';
-import { useState } from 'react';
+import { useContext, useState } from 'react';
export default function FormComment({ eventID }: { eventID: any }) {
+ const pool: any = useContext(RelayContext);
const { account } = useActiveAccount();
const [value, setValue] = useState('');
-
const profile = JSON.parse(account.metadata);
const submitEvent = () => {
- const pool = new RelayPool(WRITEONLY_RELAYS);
const event: any = {
content: value,
created_at: dateToUnix(),
diff --git a/src/shared/relayProvider.tsx b/src/shared/relayProvider.tsx
new file mode 100644
index 00000000..023cc69d
--- /dev/null
+++ b/src/shared/relayProvider.tsx
@@ -0,0 +1,17 @@
+import { FULL_RELAYS } from '@lume/stores/constants';
+
+import { RelayPool } from 'nostr-relaypool';
+import { createContext } from 'react';
+
+export const RelayContext = createContext({});
+
+const pool = new RelayPool(FULL_RELAYS, {
+ useEventCache: false,
+ subscriptionCache: true,
+ logErrorsAndNotices: false,
+ logSubscriptions: false,
+});
+
+export default function RelayProvider({ children }: { children: React.ReactNode }) {
+ return
{children};
+}
diff --git a/src/stores/constants.tsx b/src/stores/constants.tsx
index a3840d86..81222042 100644
--- a/src/stores/constants.tsx
+++ b/src/stores/constants.tsx
@@ -15,18 +15,12 @@ export const METADATA_SERVICE = 'https://us.rbr.bio';
export const READONLY_RELAYS = ['wss://welcome.nostr.wine', 'wss://relay.nostr.band'];
// write-only relay list
-export const WRITEONLY_RELAYS = ['wss://nostr.mutinywallet.com', 'wss://relay.nostr.band'];
+export const WRITEONLY_RELAYS = ['wss://nostr.mutinywallet.com', 'wss://relay.nostr.band', 'wss://relay.damus.io'];
// full-relay list, used for inital page and chat/channel messages loading
export const FULL_RELAYS = [
+ 'wss://welcome.nostr.wine',
+ 'wss://relay.nostr.band',
+ 'wss://nostr.mutinywallet.com',
'wss://relay.damus.io',
- 'wss://nos.lol',
- 'wss://nostr.mom',
- 'wss://relay.plebstr.com',
- 'wss://nostr-pub.wellorder.net',
- 'wss://nostr.zebedee.cloud',
- 'wss://nostr.fmt.wiz.biz',
- 'wss://relay.snort.social',
- 'wss://offchain.pub',
- 'wss://relay.current.fyi',
];
diff --git a/src/utils/hooks/useChannelMetadata.tsx b/src/utils/hooks/useChannelMetadata.tsx
index 6bfb32b5..eb05eefe 100644
--- a/src/utils/hooks/useChannelMetadata.tsx
+++ b/src/utils/hooks/useChannelMetadata.tsx
@@ -1,15 +1,15 @@
+import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
import { updateChannelMetadata } from '@lume/utils/storage';
import { getChannel } from '@lume/utils/storage';
-import { RelayPool } from 'nostr-relaypool';
-import { useCallback, useEffect, useState } from 'react';
+import { useCallback, useContext, useEffect, useState } from 'react';
export const useChannelMetadata = (id: string, channelPubkey: string) => {
+ const pool: any = useContext(RelayContext);
const [metadata, setMetadata] = useState(null);
const fetchFromRelay = useCallback(() => {
- const pool = new RelayPool(READONLY_RELAYS);
const unsubscribe = pool.subscribe(
[
{
diff --git a/src/utils/hooks/useChannelProfile.tsx b/src/utils/hooks/useChannelProfile.tsx
index 5eadd35d..bad13cd9 100644
--- a/src/utils/hooks/useChannelProfile.tsx
+++ b/src/utils/hooks/useChannelProfile.tsx
@@ -1,11 +1,13 @@
-import { FULL_RELAYS } from '@lume/stores/constants';
+import { RelayContext } from '@lume/shared/relayProvider';
+import { READONLY_RELAYS } from '@lume/stores/constants';
-import { RelayPool } from 'nostr-relaypool';
+import { useContext } from 'react';
import useSWRSubscription from 'swr/subscription';
export const useChannelProfile = (id: string, channelPubkey: string) => {
+ const pool: any = useContext(RelayContext);
+
const { data } = useSWRSubscription(id ? id : null, (key, { next }) => {
- const pool = new RelayPool(FULL_RELAYS);
const unsubscribe = pool.subscribe(
[
{
@@ -17,7 +19,7 @@ export const useChannelProfile = (id: string, channelPubkey: string) => {
kinds: [40],
},
],
- FULL_RELAYS,
+ READONLY_RELAYS,
(event: { kind: number; pubkey: string; content: string }) => {
switch (event.kind) {
case 40: