From 646fe948fb5d054a9fb1f82ec8cf9f4019201a7b Mon Sep 17 00:00:00 2001 From: austinkelsay Date: Sat, 20 Apr 2024 17:42:00 -0500 Subject: [PATCH] useNostr hook now uses a globalb pool instance provided via context --- src/context/NostrContext.js | 43 ++++++++++++++++++++++ src/hooks/useLogin.js | 4 +- src/hooks/useNostr.js | 73 +++++++------------------------------ src/pages/_app.js | 29 ++++++++------- src/pages/course/[slug].js | 1 + src/pages/details/[slug].js | 5 ++- 6 files changed, 79 insertions(+), 76 deletions(-) create mode 100644 src/context/NostrContext.js diff --git a/src/context/NostrContext.js b/src/context/NostrContext.js new file mode 100644 index 0000000..b4eb2f7 --- /dev/null +++ b/src/context/NostrContext.js @@ -0,0 +1,43 @@ +import { createContext, useState, useEffect } from 'react'; +import { SimplePool } from 'nostr-tools'; + +const defaultRelays = [ + "wss://nos.lol/", + "wss://relay.damus.io/", + "wss://relay.snort.social/", + "wss://relay.nostr.band/", + "wss://nostr.mutinywallet.com/", + "wss://relay.mutinywallet.com/", + "wss://relay.primal.net/" +]; + +export const NostrContext = createContext(); + +export const NostrProvider = ({ children }) => { + const [pool, setPool] = useState(null); + + useEffect(() => { + const newPool = new SimplePool({ verifyEvent: () => true }); + setPool(newPool); + + const connectRelays = async () => { + try { + await Promise.all(defaultRelays.map((url) => newPool.ensureRelay(url))); + } catch (error) { + console.error('Error connecting to relays:', error); + } + }; + + connectRelays(); + + return () => { + newPool.close(defaultRelays); + }; + }, []); + + return ( + + {children} + + ); +}; \ No newline at end of file diff --git a/src/hooks/useLogin.js b/src/hooks/useLogin.js index afd23e2..6a92b42 100644 --- a/src/hooks/useLogin.js +++ b/src/hooks/useLogin.js @@ -26,7 +26,7 @@ export const useLogin = () => { window.localStorage.setItem('user', JSON.stringify(response.data)); } else if (response.status === 204) { // User not found, create a new user - const kind0 = await fetchKind0([{ authors: [publicKey], kinds: [0] }], {}); + const kind0 = await fetchKind0(publicKey); console.log('kind0:', kind0); @@ -79,7 +79,7 @@ export const useLogin = () => { router.push('/').then(() => window.location.reload()); } catch (error) { // User not found, create a new user - const kind0 = await fetchKind0([{ authors: [publicKey], kinds: [0] }], {}); + const kind0 = await fetchKind0(publicKey); const fields = await findKind0Fields(kind0); const payload = { pubkey: publicKey, ...fields }; diff --git a/src/hooks/useNostr.js b/src/hooks/useNostr.js index 153435d..9731433 100644 --- a/src/hooks/useNostr.js +++ b/src/hooks/useNostr.js @@ -1,6 +1,7 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, useContext } from 'react'; import axios from 'axios'; -import { SimplePool, nip57 } from 'nostr-tools'; +import { nip57 } from 'nostr-tools'; +import { NostrContext } from '@/context/NostrContext'; const defaultRelays = [ "wss://nos.lol/", @@ -10,50 +11,19 @@ const defaultRelays = [ "wss://nostr.mutinywallet.com/", "wss://relay.mutinywallet.com/", "wss://relay.primal.net/" -]; + ]; export function useNostr() { - const [pool, setPool] = useState(null); - - useEffect(() => { - const newPool = new SimplePool({ verifyEvent: () => true }); - setPool(newPool); - - return () => { - newPool.close(defaultRelays); - }; - }, []); - - const connect = useCallback(async () => { - if (!pool) return; - - try { - await Promise.all(defaultRelays.map((url) => pool.ensureRelay(url))); - } catch (error) { - console.error('Error connecting to relays:', error); - } - }, [pool]); - - const disconnect = useCallback(() => { - if (!pool) return; - - pool.close(defaultRelays); - }, [pool]); + const pool = useContext(NostrContext); const subscribe = useCallback( (filters, opts) => { - if (!pool) return; - - return pool.subscribeMany(defaultRelays, filters, { - ...opts, - onclose: () => { - opts.onclose?.(); - connect(); - }, - }); + if (!pool) return; + + return pool.subscribeMany(defaultRelays, filters, opts); }, - [pool, connect] - ); + [pool] + ); const publish = useCallback( async (event) => { @@ -72,11 +42,6 @@ export function useNostr() { const fetchSingleEvent = useCallback( async (id) => { try { - if (!pool || !pool.connected) { - console.warn('Pool is not connected. Skipping fetchSingleEvent.'); - return null; - } - const event = await pool.get(defaultRelays, { ids: [id], }); @@ -92,12 +57,7 @@ export function useNostr() { const fetchZapsForEvent = useCallback( async (id) => { try { - if (!pool || !pool.connected) { - console.warn('Pool is not connected. Skipping fetchZapsForEvent.'); - return []; - } - - const filter = [{ kinds: [9735], '#e': [id] }]; + const filter = { kinds: [9735], '#e': [id] }; const zaps = await pool.querySync(defaultRelays, filter); console.log('zaps:', zaps); return zaps; @@ -112,14 +72,9 @@ export function useNostr() { const fetchKind0 = useCallback( async (publicKey) => { try { - if (!pool || !pool.connected) { - console.warn('Pool is not connected. Skipping fetchKind0.'); - return []; - } - - const filter = [{ authors: [publicKey], kinds: [0] }]; + const filter = { authors: [publicKey], kinds: [0] }; const kind0 = await pool.querySync(defaultRelays, filter); - return kind0; + return JSON.parse(kind0[0].content); } catch (error) { console.error('Failed to fetch kind 0 for event:', error); return []; @@ -303,5 +258,5 @@ export function useNostr() { }); }, [subscribe]); - return { subscribe, publish, fetchSingleEvent, fetchZapsForEvent, fetchResources, fetchWorkshops, fetchCourses, zapEvent }; + return { subscribe, publish, fetchSingleEvent, fetchZapsForEvent, fetchKind0, fetchResources, fetchWorkshops, fetchCourses, zapEvent }; } \ No newline at end of file diff --git a/src/pages/_app.js b/src/pages/_app.js index 82766eb..483e8ce 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -5,26 +5,29 @@ import Layout from '@/components/Layout'; import '@/styles/globals.css' import 'primereact/resources/themes/lara-dark-indigo/theme.css'; import Sidebar from '@/components/sidebar/Sidebar'; +import { NostrProvider } from '@/context/NostrContext'; export default function MyApp({ Component, pageProps: { ...pageProps } }) { return ( - - -
- - {/*
*/} - {/* */} - {/*
*/} -
- + + + +
+ + {/*
*/} + {/* */} + {/*
*/} +
+ +
+ {/*
*/}
- {/*
*/} -
- - + + + ); } \ No newline at end of file diff --git a/src/pages/course/[slug].js b/src/pages/course/[slug].js index 698647b..61a34b5 100644 --- a/src/pages/course/[slug].js +++ b/src/pages/course/[slug].js @@ -28,6 +28,7 @@ const Course = () => { const getCourse = async () => { if (slug) { const fetchedCourse = await fetchSingleEvent(slug); + console.log('fetched course:', fetchedCourse); const formattedCourse = parseEvent(fetchedCourse); setCourse(formattedCourse); } diff --git a/src/pages/details/[slug].js b/src/pages/details/[slug].js index 218b3d8..6f7e9df 100644 --- a/src/pages/details/[slug].js +++ b/src/pages/details/[slug].js @@ -76,8 +76,9 @@ export default function Details() { useEffect(() => { const fetchAuthor = async (pubkey) => { - const author = await fetchKind0([{ authors: [pubkey], kinds: [0] }], {}); + const author = await fetchKind0(pubkey); const fields = await findKind0Fields(author); + console.log('fields:', fields); if (fields) { setAuthor(fields); } @@ -85,7 +86,7 @@ export default function Details() { if (event) { fetchAuthor(event.pubkey); } - }, [event]); + }, [fetchKind0, event]); useEffect(() => { if (event) {