diff --git a/src/app/auth/create/step-3.tsx b/src/app/auth/create/step-3.tsx index 9b7940a6..647a19df 100644 --- a/src/app/auth/create/step-3.tsx +++ b/src/app/auth/create/step-3.tsx @@ -1,21 +1,22 @@ import { NDKEvent, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk'; import { Body, fetch } from '@tauri-apps/api/http'; -import { useContext, useState } from 'react'; +import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; +import { useNDK } from '@libs/ndk/provider'; + import { Button } from '@shared/button'; import { LoaderIcon } from '@shared/icons'; -import { RelayContext } from '@shared/relayProvider'; import { useOnboarding } from '@stores/onboarding'; import { useAccount } from '@utils/hooks/useAccount'; export function CreateStep3Screen() { - const ndk = useContext(RelayContext); const profile = useOnboarding((state: any) => state.profile); const navigate = useNavigate(); + const { ndk } = useNDK(); const { account } = useAccount(); const [username, setUsername] = useState(''); diff --git a/src/app/auth/create/step-4.tsx b/src/app/auth/create/step-4.tsx index 748104a6..aa1ecf35 100644 --- a/src/app/auth/create/step-4.tsx +++ b/src/app/auth/create/step-4.tsx @@ -1,10 +1,11 @@ import { NDKEvent, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useContext, useState } from 'react'; +import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { User } from '@app/auth/components/user'; +import { useNDK } from '@libs/ndk/provider'; import { updateAccount } from '@libs/storage'; import { CheckCircleIcon, LoaderIcon } from '@shared/icons'; @@ -113,13 +114,13 @@ const INITIAL_LIST = [ ]; export function CreateStep4Screen() { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); const navigate = useNavigate(); const [loading, setLoading] = useState(false); const [follows, setFollows] = useState([]); + const { ndk } = useNDK(); const { account } = useAccount(); const { status, data } = useQuery(['trending-profiles'], async () => { const res = await fetch('https://api.nostr.band/v0/trending/profiles'); diff --git a/src/app/auth/import/step-2.tsx b/src/app/auth/import/step-2.tsx index 33ac556c..fcb24168 100644 --- a/src/app/auth/import/step-2.tsx +++ b/src/app/auth/import/step-2.tsx @@ -1,24 +1,25 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { useContext, useState } from 'react'; +import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { User } from '@app/auth/components/user'; +import { useNDK } from '@libs/ndk/provider'; import { updateAccount } from '@libs/storage'; import { Button } from '@shared/button'; import { LoaderIcon } from '@shared/icons'; -import { RelayContext } from '@shared/relayProvider'; import { useAccount } from '@utils/hooks/useAccount'; import { setToArray } from '@utils/transform'; export function ImportStep2Screen() { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); const navigate = useNavigate(); const [loading, setLoading] = useState(false); + + const { ndk } = useNDK(); const { status, account } = useAccount(); const update = useMutation({ diff --git a/src/app/auth/onboarding.tsx b/src/app/auth/onboarding.tsx index aefe54ed..e25fbf2c 100644 --- a/src/app/auth/onboarding.tsx +++ b/src/app/auth/onboarding.tsx @@ -1,13 +1,12 @@ import { useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; -import { usePublish } from '@libs/ndk'; - import { LoaderIcon } from '@shared/icons'; import { ArrowRightCircleIcon } from '@shared/icons/arrowRightCircle'; import { User } from '@shared/user'; import { useAccount } from '@utils/hooks/useAccount'; +import { usePublish } from '@utils/hooks/usePublish'; export function OnboardingScreen() { const publish = usePublish(); diff --git a/src/app/chat/components/messages/form.tsx b/src/app/chat/components/messages/form.tsx index 68c17625..b3ed2b8e 100644 --- a/src/app/chat/components/messages/form.tsx +++ b/src/app/chat/components/messages/form.tsx @@ -1,11 +1,11 @@ import { nip04 } from 'nostr-tools'; import { useCallback, useState } from 'react'; -import { usePublish } from '@libs/ndk'; - import { EnterIcon } from '@shared/icons'; import { MediaUploader } from '@shared/mediaUploader'; +import { usePublish } from '@utils/hooks/usePublish'; + export function ChatMessageForm({ receiverPubkey, userPrivkey, diff --git a/src/app/chat/index.tsx b/src/app/chat/index.tsx index 159eb852..0c36e1ea 100644 --- a/src/app/chat/index.tsx +++ b/src/app/chat/index.tsx @@ -1,6 +1,6 @@ import { NDKSubscription } from '@nostr-dev-kit/ndk'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useCallback, useContext, useEffect, useRef } from 'react'; +import { useCallback, useEffect, useRef } from 'react'; import { useParams } from 'react-router-dom'; import { Virtuoso } from 'react-virtuoso'; @@ -8,17 +8,16 @@ import { ChatMessageForm } from '@app/chat/components/messages/form'; import { ChatMessageItem } from '@app/chat/components/messages/item'; import { ChatSidebar } from '@app/chat/components/sidebar'; +import { useNDK } from '@libs/ndk/provider'; import { createChat, getChatMessages } from '@libs/storage'; -import { RelayContext } from '@shared/relayProvider'; - import { useAccount } from '@utils/hooks/useAccount'; export function ChatScreen() { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); const virtuosoRef = useRef(null); + const { ndk } = useNDK(); const { pubkey } = useParams(); const { account } = useAccount(); const { status, data } = useQuery( diff --git a/src/app/root.tsx b/src/app/root.tsx index 9ea2b525..5b2a89d6 100644 --- a/src/app/root.tsx +++ b/src/app/root.tsx @@ -1,8 +1,9 @@ import { NDKFilter } from '@nostr-dev-kit/ndk'; -import { useContext, useEffect, useRef } from 'react'; +import { useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import { prefetchEvents } from '@libs/ndk'; +import { useNDK } from '@libs/ndk/provider'; import { countTotalNotes, createChat, @@ -12,7 +13,6 @@ import { } from '@libs/storage'; import { LoaderIcon, LumeIcon } from '@shared/icons'; -import { RelayContext } from '@shared/relayProvider'; import { dateToUnix, getHourAgo } from '@utils/date'; import { useAccount } from '@utils/hooks/useAccount'; @@ -21,10 +21,10 @@ const totalNotes = await countTotalNotes(); const lastLogin = await getLastLogin(); export function Root() { - const ndk = useContext(RelayContext); const now = useRef(new Date()); const navigate = useNavigate(); + const { ndk } = useNDK(); const { status, account } = useAccount(); async function fetchNotes() { diff --git a/src/app/space/components/addImage.tsx b/src/app/space/components/addImage.tsx index 40777f25..4f701b6f 100644 --- a/src/app/space/components/addImage.tsx +++ b/src/app/space/components/addImage.tsx @@ -3,15 +3,15 @@ import { NDKEvent, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { open } from '@tauri-apps/api/dialog'; import { Body, fetch } from '@tauri-apps/api/http'; -import { Fragment, useContext, useEffect, useRef, useState } from 'react'; +import { Fragment, useEffect, useRef, useState } from 'react'; import { useForm } from 'react-hook-form'; import { useHotkeys } from 'react-hotkeys-hook'; +import { useNDK } from '@libs/ndk/provider'; import { createBlock } from '@libs/storage'; import { CancelIcon, CommandIcon } from '@shared/icons'; import { Image } from '@shared/image'; -import { RelayContext } from '@shared/relayProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; import { ADD_IMAGEBLOCK_SHORTCUT } from '@stores/shortcuts'; @@ -21,13 +21,13 @@ import { dateToUnix } from '@utils/date'; import { useAccount } from '@utils/hooks/useAccount'; export function AddImageBlock() { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); const [loading, setLoading] = useState(false); const [isOpen, setIsOpen] = useState(false); const [image, setImage] = useState(''); + const { ndk } = useNDK(); const { account } = useAccount(); const tags = useRef(null); diff --git a/src/app/space/hooks/useLiveThread.tsx b/src/app/space/hooks/useLiveThread.tsx index fbdd7f18..4d7ee39f 100644 --- a/src/app/space/hooks/useLiveThread.tsx +++ b/src/app/space/hooks/useLiveThread.tsx @@ -1,16 +1,16 @@ import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'; import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { useContext, useEffect, useRef } from 'react'; +import { useEffect, useRef } from 'react'; +import { useNDK } from '@libs/ndk/provider'; import { createReplyNote } from '@libs/storage'; -import { RelayContext } from '@shared/relayProvider'; - export function useLiveThread(id: string) { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); const now = useRef(Math.floor(Date.now() / 1000)); + const { ndk } = useNDK(); + const thread = useMutation({ mutationFn: (data: NDKEvent) => { return createReplyNote( diff --git a/src/app/space/hooks/useNewsfeed.tsx b/src/app/space/hooks/useNewsfeed.tsx index fc2b3606..e95918b7 100644 --- a/src/app/space/hooks/useNewsfeed.tsx +++ b/src/app/space/hooks/useNewsfeed.tsx @@ -1,22 +1,22 @@ import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'; -import { useContext, useEffect, useRef } from 'react'; +import { useEffect, useRef } from 'react'; +import { useNDK } from '@libs/ndk/provider'; import { createNote } from '@libs/storage'; -import { RelayContext } from '@shared/relayProvider'; - import { useNote } from '@stores/note'; import { useAccount } from '@utils/hooks/useAccount'; export function useNewsfeed() { - const ndk = useContext(RelayContext); const sub = useRef(null); const now = useRef(Math.floor(Date.now() / 1000)); - const toggleHasNewNote = useNote((state) => state.toggleHasNewNote); + const { ndk } = useNDK(); const { status, account } = useAccount(); + const toggleHasNewNote = useNote((state) => state.toggleHasNewNote); + useEffect(() => { if (status === 'success' && account) { const follows = account ? JSON.parse(account.follows) : []; diff --git a/src/app/user/components/feed.tsx b/src/app/user/components/feed.tsx index 38ab6696..5778834a 100644 --- a/src/app/user/components/feed.tsx +++ b/src/app/user/components/feed.tsx @@ -1,15 +1,15 @@ import { NDKFilter } from '@nostr-dev-kit/ndk'; import { useQuery } from '@tanstack/react-query'; -import { useContext } from 'react'; + +import { useNDK } from '@libs/ndk/provider'; import { Note } from '@shared/notes/note'; -import { RelayContext } from '@shared/relayProvider'; import { dateToUnix, getHourAgo } from '@utils/date'; import { LumeEvent } from '@utils/types'; export function UserFeed({ pubkey }: { pubkey: string }) { - const ndk = useContext(RelayContext); + const { ndk } = useNDK(); const { status, data } = useQuery(['user-feed', pubkey], async () => { const now = new Date(); const filter: NDKFilter = { diff --git a/src/libs/ndk.tsx b/src/libs/ndk.tsx index 2a272f08..40bdb6b7 100644 --- a/src/libs/ndk.tsx +++ b/src/libs/ndk.tsx @@ -5,9 +5,8 @@ import NDK, { NDKKind, NDKPrivateKeySigner, } from '@nostr-dev-kit/ndk'; -import { useContext } from 'react'; -import { RelayContext } from '@shared/relayProvider'; +import { useNDK } from '@libs/ndk/provider'; import { FULL_RELAYS } from '@stores/constants'; @@ -46,34 +45,3 @@ export async function prefetchEvents( }); }); } - -export function usePublish() { - const ndk = useContext(RelayContext); - const { account } = useAccount(); - - const publish = async ({ - content, - kind, - tags, - }: { - content: string; - kind: NDKKind; - tags: string[][]; - }): Promise => { - const event = new NDKEvent(ndk); - const signer = new NDKPrivateKeySigner(account.privkey); - - event.content = content; - event.kind = kind; - event.created_at = Math.floor(Date.now() / 1000); - event.pubkey = account.pubkey; - event.tags = tags; - - await event.sign(signer); - await event.publish(); - - return event; - }; - - return publish; -} diff --git a/src/libs/ndk/instance.ts b/src/libs/ndk/instance.ts new file mode 100644 index 00000000..cbd3ecb5 --- /dev/null +++ b/src/libs/ndk/instance.ts @@ -0,0 +1,36 @@ +// source: https://github.com/nostr-dev-kit/ndk-react/ +import NDK from '@nostr-dev-kit/ndk'; +import { useEffect, useState } from 'react'; + +import { getSetting } from '@libs/storage'; + +const setting = await getSetting('relays'); +const relays = JSON.parse(setting); + +export const NDKInstance = () => { + const [ndk, setNDK] = useState(undefined); + const [relayUrls, setRelayUrls] = useState(relays); + + useEffect(() => { + loadNdk(relays); + }, []); + + async function loadNdk(explicitRelayUrls: string[]) { + const ndkInstance = new NDK({ explicitRelayUrls }); + + try { + await ndkInstance.connect(); + } catch (error) { + console.error('ERROR loading NDK NDKInstance', error); + } + + setNDK(ndkInstance); + setRelayUrls(explicitRelayUrls); + } + + return { + ndk, + relayUrls, + loadNdk, + }; +}; diff --git a/src/libs/ndk/provider.tsx b/src/libs/ndk/provider.tsx new file mode 100644 index 00000000..bb74bd49 --- /dev/null +++ b/src/libs/ndk/provider.tsx @@ -0,0 +1,44 @@ +// source: https://github.com/nostr-dev-kit/ndk-react/ +import NDK from '@nostr-dev-kit/ndk'; +import { PropsWithChildren, createContext, useContext } from 'react'; + +import { NDKInstance } from '@libs/ndk/instance'; + +interface NDKContext { + ndk: NDK; + relayUrls: string[]; + loadNdk: (_: string[]) => void; +} + +const NDKContext = createContext({ + ndk: new NDK({}), + relayUrls: [], + loadNdk: undefined, +}); + +const NDKProvider = ({ children }: PropsWithChildren) => { + const { ndk, relayUrls, loadNdk } = NDKInstance(); + + if (ndk) + return ( + + {children} + + ); +}; + +const useNDK = () => { + const context = useContext(NDKContext); + if (context === undefined) { + throw new Error('import NDKProvider to use useNDK'); + } + return context; +}; + +export { NDKProvider, useNDK }; diff --git a/src/main.tsx b/src/main.tsx index fa83da6f..2af63494 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,10 +2,9 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { createRoot } from 'react-dom/client'; +import { NDKProvider } from '@libs/ndk/provider'; import { getSetting } from '@libs/storage'; -import { RelayProvider } from '@shared/relayProvider'; - import App from './app'; const cacheTime = await getSetting('cache_time'); @@ -23,9 +22,9 @@ const root = createRoot(container); root.render( - + - + ); diff --git a/src/shared/accounts/active.tsx b/src/shared/accounts/active.tsx index 32f4c9a8..ec83e404 100644 --- a/src/shared/accounts/active.tsx +++ b/src/shared/accounts/active.tsx @@ -1,13 +1,13 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { produce } from 'immer'; -import { useContext, useEffect } from 'react'; +import { useEffect } from 'react'; import { Link } from 'react-router-dom'; +import { useNDK } from '@libs/ndk/provider'; import { createChat, getLastLogin } from '@libs/storage'; import { Image } from '@shared/image'; import { NetworkStatusIndicator } from '@shared/networkStatusIndicator'; -import { RelayContext } from '@shared/relayProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; @@ -17,9 +17,9 @@ import { sendNativeNotification } from '@utils/notification'; const lastLogin = await getLastLogin(); export function ActiveAccount({ data }: { data: any }) { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); + const { ndk } = useNDK(); const { status, user } = useProfile(data.pubkey); const chat = useMutation({ diff --git a/src/shared/composer/types/post.tsx b/src/shared/composer/types/post.tsx index 0ed67d1c..27d06f65 100644 --- a/src/shared/composer/types/post.tsx +++ b/src/shared/composer/types/post.tsx @@ -3,8 +3,6 @@ import { Node, Transforms, createEditor } from 'slate'; import { withHistory } from 'slate-history'; import { Editable, ReactEditor, Slate, useSlateStatic, withReact } from 'slate-react'; -import { usePublish } from '@libs/ndk'; - import { Button } from '@shared/button'; import { ImageUploader } from '@shared/composer/imageUploader'; import { CancelIcon, TrashIcon } from '@shared/icons'; @@ -13,6 +11,8 @@ import { MentionNote } from '@shared/notes/mentions/note'; import { useComposer } from '@stores/composer'; import { FULL_RELAYS } from '@stores/constants'; +import { usePublish } from '@utils/hooks/usePublish'; + const withImages = (editor) => { const { isVoid } = editor; diff --git a/src/shared/editProfileModal.tsx b/src/shared/editProfileModal.tsx index 5ab1a84f..a97ab1d5 100644 --- a/src/shared/editProfileModal.tsx +++ b/src/shared/editProfileModal.tsx @@ -5,8 +5,6 @@ import { fetch } from '@tauri-apps/api/http'; import { Fragment, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; -import { usePublish } from '@libs/ndk'; - import { AvatarUploader } from '@shared/avatarUploader'; import { BannerUploader } from '@shared/bannerUploader'; import { CancelIcon, CheckCircleIcon, LoaderIcon, UnverifiedIcon } from '@shared/icons'; @@ -15,6 +13,7 @@ import { Image } from '@shared/image'; import { DEFAULT_AVATAR } from '@stores/constants'; import { useAccount } from '@utils/hooks/useAccount'; +import { usePublish } from '@utils/hooks/usePublish'; export function EditProfileModal() { const queryClient = useQueryClient(); diff --git a/src/shared/notes/metadata.tsx b/src/shared/notes/metadata.tsx index e4fac5d3..7f39aec6 100644 --- a/src/shared/notes/metadata.tsx +++ b/src/shared/notes/metadata.tsx @@ -2,8 +2,8 @@ import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'; import * as Tooltip from '@radix-ui/react-tooltip'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { decode } from 'light-bolt11-decoder'; -import { useContext } from 'react'; +import { useNDK } from '@libs/ndk/provider'; import { createBlock, createReplyNote } from '@libs/storage'; import { LoaderIcon, ReplyIcon, RepostIcon, ZapIcon } from '@shared/icons'; @@ -11,7 +11,6 @@ import { ThreadIcon } from '@shared/icons/thread'; import { NoteReply } from '@shared/notes/metadata/reply'; import { NoteRepost } from '@shared/notes/metadata/repost'; import { NoteZap } from '@shared/notes/metadata/zap'; -import { RelayContext } from '@shared/relayProvider'; export function NoteMetadata({ id, @@ -22,9 +21,9 @@ export function NoteMetadata({ rootID?: string; eventPubkey: string; }) { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); + const { ndk } = useNDK(); const { status, data } = useQuery(['note-metadata', id], async () => { let replies = 0; let reposts = 0; diff --git a/src/shared/notes/metadata/repost.tsx b/src/shared/notes/metadata/repost.tsx index ff9b8000..84affa8d 100644 --- a/src/shared/notes/metadata/repost.tsx +++ b/src/shared/notes/metadata/repost.tsx @@ -1,11 +1,10 @@ import * as Tooltip from '@radix-ui/react-tooltip'; -import { usePublish } from '@libs/ndk'; - import { RepostIcon } from '@shared/icons'; import { FULL_RELAYS } from '@stores/constants'; +import { usePublish } from '@utils/hooks/usePublish'; import { compactNumber } from '@utils/number'; export function NoteRepost({ diff --git a/src/shared/notes/replies/form.tsx b/src/shared/notes/replies/form.tsx index dbb870c7..56339fa0 100644 --- a/src/shared/notes/replies/form.tsx +++ b/src/shared/notes/replies/form.tsx @@ -1,13 +1,12 @@ import { useState } from 'react'; -import { usePublish } from '@libs/ndk'; - import { Button } from '@shared/button'; import { Image } from '@shared/image'; import { DEFAULT_AVATAR, FULL_RELAYS } from '@stores/constants'; import { useProfile } from '@utils/hooks/useProfile'; +import { usePublish } from '@utils/hooks/usePublish'; import { shortenKey } from '@utils/shortenKey'; export function NoteReplyForm({ diff --git a/src/shared/notification/modal.tsx b/src/shared/notification/modal.tsx index 75ab4b75..0ddebff9 100644 --- a/src/shared/notification/modal.tsx +++ b/src/shared/notification/modal.tsx @@ -1,22 +1,21 @@ import { Dialog, Transition } from '@headlessui/react'; import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'; import { useQuery } from '@tanstack/react-query'; -import { Fragment, useContext, useRef, useState } from 'react'; +import { Fragment, useRef, useState } from 'react'; + +import { useNDK } from '@libs/ndk/provider'; import { BellIcon, CancelIcon, LoaderIcon } from '@shared/icons'; -import { RelayContext } from '@shared/relayProvider'; +import { NotificationUser } from '@shared/notification/user'; import { User } from '@shared/user'; import { dateToUnix, getHourAgo } from '@utils/date'; -import { NotificationUser } from './user'; - export function NotificationModal({ pubkey }: { pubkey: string }) { - const ndk = useContext(RelayContext); const now = useRef(new Date()); - const [isOpen, setIsOpen] = useState(false); + const { ndk } = useNDK(); const { status, data } = useQuery( ['user-notification', pubkey], async () => { diff --git a/src/utils/hooks/useEvent.tsx b/src/utils/hooks/useEvent.tsx index 3f57313e..4d8a07ad 100644 --- a/src/utils/hooks/useEvent.tsx +++ b/src/utils/hooks/useEvent.tsx @@ -1,14 +1,12 @@ import { useQuery } from '@tanstack/react-query'; -import { useContext } from 'react'; +import { useNDK } from '@libs/ndk/provider'; import { createNote, getNoteByID } from '@libs/storage'; -import { RelayContext } from '@shared/relayProvider'; - import { parser } from '@utils/parser'; export function useEvent(id: string) { - const ndk = useContext(RelayContext); + const { ndk } = useNDK(); const { status, data, error, isFetching } = useQuery( ['note', id], async () => { diff --git a/src/utils/hooks/useProfile.tsx b/src/utils/hooks/useProfile.tsx index 60884419..dbb077fd 100644 --- a/src/utils/hooks/useProfile.tsx +++ b/src/utils/hooks/useProfile.tsx @@ -1,12 +1,10 @@ import { useQuery } from '@tanstack/react-query'; -import { useContext } from 'react'; +import { useNDK } from '@libs/ndk/provider'; import { createMetadata, getUserMetadata } from '@libs/storage'; -import { RelayContext } from '@shared/relayProvider'; - export function useProfile(pubkey: string, fallback?: string) { - const ndk = useContext(RelayContext); + const { ndk } = useNDK(); const { status, data: user, diff --git a/src/utils/hooks/usePublish.tsx b/src/utils/hooks/usePublish.tsx new file mode 100644 index 00000000..cbb6b1ea --- /dev/null +++ b/src/utils/hooks/usePublish.tsx @@ -0,0 +1,36 @@ +import { NDKEvent, NDKKind, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk'; + +import { useNDK } from '@libs/ndk/provider'; + +import { useAccount } from '@utils/hooks/useAccount'; + +export function usePublish() { + const { ndk } = useNDK(); + const { account } = useAccount(); + + const publish = async ({ + content, + kind, + tags, + }: { + content: string; + kind: NDKKind; + tags: string[][]; + }): Promise => { + const event = new NDKEvent(ndk); + const signer = new NDKPrivateKeySigner(account.privkey); + + event.content = content; + event.kind = kind; + event.created_at = Math.floor(Date.now() / 1000); + event.pubkey = account.pubkey; + event.tags = tags; + + await event.sign(signer); + await event.publish(); + + return event; + }; + + return publish; +} diff --git a/src/utils/hooks/useSocial.tsx b/src/utils/hooks/useSocial.tsx index bdaa004e..5841c027 100644 --- a/src/utils/hooks/useSocial.tsx +++ b/src/utils/hooks/useSocial.tsx @@ -1,22 +1,19 @@ import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'; import { useQuery, useQueryClient } from '@tanstack/react-query'; -import { useContext } from 'react'; -import { usePublish } from '@libs/ndk'; +import { useNDK } from '@libs/ndk/provider'; import { createNote } from '@libs/storage'; -import { RelayContext } from '@shared/relayProvider'; - import { dateToUnix, getHourAgo } from '@utils/date'; +import { useAccount } from '@utils/hooks/useAccount'; +import { usePublish } from '@utils/hooks/usePublish'; import { nip02ToArray } from '@utils/transform'; -import { useAccount } from './useAccount'; - export function useSocial() { - const ndk = useContext(RelayContext); const queryClient = useQueryClient(); const publish = usePublish(); + const { ndk } = useNDK(); const { account } = useAccount(); const { status, data: userFollows } = useQuery( ['userFollows', account.pubkey],