useNostr hook now uses a globalb pool instance provided via context

This commit is contained in:
austinkelsay 2024-04-20 17:42:00 -05:00
parent 8e8080eb09
commit 646fe948fb
6 changed files with 79 additions and 76 deletions

View File

@ -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 (
<NostrContext.Provider value={pool}>
{children}
</NostrContext.Provider>
);
};

View File

@ -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 };

View File

@ -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 };
}

View File

@ -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 (
<PrimeReactProvider>
<ToastProvider>
<Layout>
<div className="flex flex-col min-h-screen">
<Navbar />
{/* <div className='flex'> */}
{/* <Sidebar /> */}
{/* <div className='max-w-[100vw] pl-[15vw]'> */}
<div className='max-w-[100vw]'>
<Component {...pageProps} />
<NostrProvider>
<ToastProvider>
<Layout>
<div className="flex flex-col min-h-screen">
<Navbar />
{/* <div className='flex'> */}
{/* <Sidebar /> */}
{/* <div className='max-w-[100vw] pl-[15vw]'> */}
<div className='max-w-[100vw]'>
<Component {...pageProps} />
</div>
{/* </div> */}
</div>
{/* </div> */}
</div>
</Layout>
</ToastProvider>
</Layout>
</ToastProvider>
</NostrProvider>
</PrimeReactProvider>
);
}

View File

@ -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);
}

View File

@ -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) {