diff --git a/apps/desktop/package.json b/apps/desktop/package.json index d998f392..8d6374d5 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -17,6 +17,7 @@ "@getalby/sdk": "^3.2.3", "@lume/ark": "workspace:^", "@lume/icons": "workspace:^", + "@lume/storage": "workspace:^", "@lume/ui": "workspace:^", "@lume/utils": "workspace:^", "@nostr-dev-kit/ndk": "^2.3.2", @@ -79,6 +80,7 @@ "tailwindcss": "^3.4.1", "typescript": "^5.3.3", "vite": "^5.0.11", + "vite-plugin-top-level-await": "^1.4.1", "vite-tsconfig-paths": "^4.2.3" } } diff --git a/apps/desktop/src/app.tsx b/apps/desktop/src/app.tsx index 1c342ab0..64a7f3c3 100644 --- a/apps/desktop/src/app.tsx +++ b/apps/desktop/src/app.tsx @@ -1,4 +1,5 @@ import { ColumnProvider, LumeProvider } from "@lume/ark"; +import { StorageProvider } from "@lume/storage"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { Toaster } from "sonner"; import Router from "./router"; @@ -15,11 +16,13 @@ export default function App() { return ( - - - - - + + + + + + + ); } diff --git a/apps/desktop/src/router.tsx b/apps/desktop/src/router.tsx index 1aabdd5f..86dbde34 100644 --- a/apps/desktop/src/router.tsx +++ b/apps/desktop/src/router.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { AppLayout, AuthLayout, HomeLayout, SettingsLayout } from "@lume/ui"; import { fetch } from "@tauri-apps/plugin-http"; import { @@ -23,7 +24,7 @@ export default function Router() { element: , errorElement: , loader: async () => { - if (!storage.account) return redirect("auth"); + if (!ark.account) return redirect("auth"); return null; }, children: [ diff --git a/apps/desktop/src/routes/auth/create.tsx b/apps/desktop/src/routes/auth/create.tsx index 027d24a4..af56b9b7 100644 --- a/apps/desktop/src/routes/auth/create.tsx +++ b/apps/desktop/src/routes/auth/create.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { CheckIcon, ChevronDownIcon, LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { onboardingAtom } from "@lume/utils"; import NDK, { NDKEvent, diff --git a/apps/desktop/src/routes/auth/login-key.tsx b/apps/desktop/src/routes/auth/login-key.tsx index 34c50684..26a7333f 100644 --- a/apps/desktop/src/routes/auth/login-key.tsx +++ b/apps/desktop/src/routes/auth/login-key.tsx @@ -1,5 +1,5 @@ -import { useStorage } from "@lume/ark"; import { EyeOffIcon, EyeOnIcon, LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { getPublicKey, nip19 } from "nostr-tools"; import { useState } from "react"; import { useForm } from "react-hook-form"; diff --git a/apps/desktop/src/routes/auth/login-nsecbunker.tsx b/apps/desktop/src/routes/auth/login-nsecbunker.tsx index a7c49bb0..61f09ef3 100644 --- a/apps/desktop/src/routes/auth/login-nsecbunker.tsx +++ b/apps/desktop/src/routes/auth/login-nsecbunker.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import NDK, { NDKNip46Signer, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk"; import { nip19 } from "nostr-tools"; import { useState } from "react"; diff --git a/apps/desktop/src/routes/auth/login-oauth.tsx b/apps/desktop/src/routes/auth/login-oauth.tsx index 9da971d0..53e266a3 100644 --- a/apps/desktop/src/routes/auth/login-oauth.tsx +++ b/apps/desktop/src/routes/auth/login-oauth.tsx @@ -1,10 +1,10 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { NIP05 } from "@lume/types"; import NDK, { NDKNip46Signer, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk"; import { Window } from "@tauri-apps/api/window"; import { fetch } from "@tauri-apps/plugin-http"; -import { nip19 } from "nostr-tools"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { useNavigate } from "react-router-dom"; @@ -30,6 +30,13 @@ export function LoginWithOAuth() { try { setLoading(true); + if (!emailRegex.test(data.nip05)) { + setLoading(false); + return toast.error( + "Cannot verify your NIP-05 address, please try again later.", + ); + } + const localPath = data.nip05.split("@")[0]; const service = data.nip05.split("@")[1]; diff --git a/apps/desktop/src/routes/auth/onboarding.tsx b/apps/desktop/src/routes/auth/onboarding.tsx index fda75e0d..77d6ab4b 100644 --- a/apps/desktop/src/routes/auth/onboarding.tsx +++ b/apps/desktop/src/routes/auth/onboarding.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { InfoIcon, LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { FETCH_LIMIT } from "@lume/utils"; import { NDKKind } from "@nostr-dev-kit/ndk"; import * as Switch from "@radix-ui/react-switch"; @@ -57,7 +58,7 @@ export function OnboardingScreen() { setLoading(true); // get account contacts - await ark.getUserContacts(storage.account.pubkey); + await ark.getUserContacts(ark.account.pubkey); // refetch newsfeed await queryClient.prefetchInfiniteQuery({ @@ -73,7 +74,7 @@ export function OnboardingScreen() { const events = await ark.getInfiniteEvents({ filter: { kinds: [NDKKind.Text, NDKKind.Repost], - authors: storage.account.contacts, + authors: ark.account.contacts, }, limit: FETCH_LIMIT, pageParam, diff --git a/apps/desktop/src/routes/depot/components/contact.tsx b/apps/desktop/src/routes/depot/components/contact.tsx index f19953f1..e456e6c6 100644 --- a/apps/desktop/src/routes/depot/components/contact.tsx +++ b/apps/desktop/src/routes/depot/components/contact.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { LoaderIcon, RunIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { User } from "@lume/ui"; import { NDKKind } from "@nostr-dev-kit/ndk"; import { useState } from "react"; @@ -17,7 +18,7 @@ export function DepotContactCard() { const event = await ark.getEventByFilter({ filter: { - authors: [storage.account.pubkey], + authors: [ark.account.pubkey], kinds: [NDKKind.Contacts], }, }); @@ -39,13 +40,13 @@ export function DepotContactCard() {
- {storage.account.contacts?.slice(0, 8).map((item) => ( + {ark.account.contacts?.slice(0, 8).map((item) => ( ))} - {storage.account.contacts?.length > 8 ? ( + {ark.account.contacts?.length > 8 ? (
- +{storage.account.contacts?.length - 8} + +{ark.account.contacts?.length - 8}
) : null} diff --git a/apps/desktop/src/routes/depot/components/profile.tsx b/apps/desktop/src/routes/depot/components/profile.tsx index 5f138173..a44c478a 100644 --- a/apps/desktop/src/routes/depot/components/profile.tsx +++ b/apps/desktop/src/routes/depot/components/profile.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { LoaderIcon, RunIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { User } from "@lume/ui"; import { NDKKind } from "@nostr-dev-kit/ndk"; import { useState } from "react"; @@ -17,7 +18,7 @@ export function DepotProfileCard() { const event = await ark.getEventByFilter({ filter: { - authors: [storage.account.pubkey], + authors: [ark.account.pubkey], kinds: [NDKKind.Metadata], }, }); @@ -38,7 +39,7 @@ export function DepotProfileCard() { return (
- +
Profile
diff --git a/apps/desktop/src/routes/depot/components/relays.tsx b/apps/desktop/src/routes/depot/components/relays.tsx index d80d668a..0ef3cdee 100644 --- a/apps/desktop/src/routes/depot/components/relays.tsx +++ b/apps/desktop/src/routes/depot/components/relays.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { LoaderIcon, RunIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { NDKKind } from "@nostr-dev-kit/ndk"; import { useEffect, useState } from "react"; import { toast } from "sonner"; @@ -17,7 +18,7 @@ export function DepotRelaysCard() { const event = await ark.getEventByFilter({ filter: { - authors: [storage.account.pubkey], + authors: [ark.account.pubkey], kinds: [NDKKind.RelayList], }, }); @@ -39,7 +40,7 @@ export function DepotRelaysCard() { async function loadRelays() { const event = await ark.getEventByFilter({ filter: { - authors: [storage.account.pubkey], + authors: [ark.account.pubkey], kinds: [NDKKind.RelayList], }, }); diff --git a/apps/desktop/src/routes/depot/index.tsx b/apps/desktop/src/routes/depot/index.tsx index f27493d1..c9dac648 100644 --- a/apps/desktop/src/routes/depot/index.tsx +++ b/apps/desktop/src/routes/depot/index.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { ChevronDownIcon, DepotIcon, GossipIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { NDKKind } from "@nostr-dev-kit/ndk"; import * as Collapsible from "@radix-ui/react-collapsible"; import { invoke } from "@tauri-apps/api/core"; @@ -36,7 +37,7 @@ export function DepotScreen() { const relayEvent = await ark.getEventByFilter({ filter: { - authors: [storage.account.pubkey], + authors: [ark.account.pubkey], kinds: [NDKKind.RelayList], }, }); diff --git a/apps/desktop/src/routes/depot/onboarding.tsx b/apps/desktop/src/routes/depot/onboarding.tsx index 365405df..6267a30d 100644 --- a/apps/desktop/src/routes/depot/onboarding.tsx +++ b/apps/desktop/src/routes/depot/onboarding.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { delay } from "@lume/utils"; import { resolveResource } from "@tauri-apps/api/path"; import { readTextFile, writeTextFile } from "@tauri-apps/plugin-fs"; @@ -26,9 +27,7 @@ export function DepotOnboardingScreen() { // add current user to whitelist // biome-ignore lint/complexity/useLiteralKeys: - parsedConfig.authorization["pubkey_whitelist"].push( - storage.account.pubkey, - ); + parsedConfig.authorization["pubkey_whitelist"].push(ark.account.pubkey); // update new config const newConfig = stringify(parsedConfig); diff --git a/apps/desktop/src/routes/error.tsx b/apps/desktop/src/routes/error.tsx index 4601c6df..9351d05d 100644 --- a/apps/desktop/src/routes/error.tsx +++ b/apps/desktop/src/routes/error.tsx @@ -1,4 +1,4 @@ -import { useStorage } from "@lume/ark"; +import { useStorage } from "@lume/storage"; import { downloadDir } from "@tauri-apps/api/path"; import { message, save } from "@tauri-apps/plugin-dialog"; import { writeTextFile } from "@tauri-apps/plugin-fs"; @@ -25,18 +25,18 @@ export function ErrorScreen() { const filePath = await save({ defaultPath: `${downloadPath}/${fileName}`, }); - const nsec = await storage.loadPrivkey(storage.account.pubkey); + const nsec = await storage.loadPrivkey(ark.account.pubkey); if (filePath) { if (nsec) { await writeTextFile( filePath, - `Nostr account, generated by Lume (lume.nu)\nPublic key: ${storage.account.id}\nPrivate key: ${nsec}`, + `Nostr account, generated by Lume (lume.nu)\nPublic key: ${ark.account.id}\nPrivate key: ${nsec}`, ); } else { await writeTextFile( filePath, - `Nostr account, generated by Lume (lume.nu)\nPublic key: ${storage.account.id}`, + `Nostr account, generated by Lume (lume.nu)\nPublic key: ${ark.account.id}`, ); } } // else { user cancel action } diff --git a/apps/desktop/src/routes/nwc/components/form.tsx b/apps/desktop/src/routes/nwc/components/form.tsx index aed87d85..c173cac7 100644 --- a/apps/desktop/src/routes/nwc/components/form.tsx +++ b/apps/desktop/src/routes/nwc/components/form.tsx @@ -1,5 +1,5 @@ -import { useStorage } from "@lume/ark"; import { LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { useState } from "react"; import { toast } from "sonner"; @@ -25,7 +25,7 @@ export function NWCForm({ setWalletConnectURL }) { const params = new URLSearchParams(uriObj.search); if (params.has("relay") && params.has("secret")) { - await storage.createPrivkey(`${storage.account.pubkey}-nwc`, uri); + await storage.createPrivkey(`${ark.account.pubkey}-nwc`, uri); setWalletConnectURL(uri); setLoading(false); } else { diff --git a/apps/desktop/src/routes/nwc/index.tsx b/apps/desktop/src/routes/nwc/index.tsx index 2c8a3345..96ac0efd 100644 --- a/apps/desktop/src/routes/nwc/index.tsx +++ b/apps/desktop/src/routes/nwc/index.tsx @@ -1,5 +1,5 @@ -import { useStorage } from "@lume/ark"; import { CheckCircleIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { useEffect, useState } from "react"; import { NWCForm } from "./components/form"; @@ -8,13 +8,13 @@ export function NWCScreen() { const [walletConnectURL, setWalletConnectURL] = useState(null); const remove = async () => { - await storage.removePrivkey(`${storage.account.pubkey}-nwc`); + await storage.removePrivkey(`${ark.account.pubkey}-nwc`); setWalletConnectURL(null); }; useEffect(() => { async function getNWC() { - const nwc = await storage.loadPrivkey(`${storage.account.pubkey}-nwc`); + const nwc = await storage.loadPrivkey(`${ark.account.pubkey}-nwc`); if (nwc) setWalletConnectURL(nwc); } getNWC(); diff --git a/apps/desktop/src/routes/relays/components/userRelayList.tsx b/apps/desktop/src/routes/relays/components/userRelayList.tsx index c24c3add..cf6617ad 100644 --- a/apps/desktop/src/routes/relays/components/userRelayList.tsx +++ b/apps/desktop/src/routes/relays/components/userRelayList.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { CancelIcon, RefreshIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { NDKKind } from "@nostr-dev-kit/ndk"; import { useQuery } from "@tanstack/react-query"; import { RelayForm } from "./relayForm"; @@ -9,12 +10,12 @@ export function UserRelayList() { const storage = useStorage(); const { status, data, refetch } = useQuery({ - queryKey: ["relays", storage.account.pubkey], + queryKey: ["relays", ark.account.pubkey], queryFn: async () => { const event = await ark.getEventByFilter({ filter: { kinds: [NDKKind.RelayList], - authors: [storage.account.pubkey], + authors: [ark.account.pubkey], }, }); diff --git a/apps/desktop/src/routes/settings/advanced.tsx b/apps/desktop/src/routes/settings/advanced.tsx index 630daa95..23f1a619 100644 --- a/apps/desktop/src/routes/settings/advanced.tsx +++ b/apps/desktop/src/routes/settings/advanced.tsx @@ -1,4 +1,4 @@ -import { useStorage } from "@lume/ark"; +import { useStorage } from "@lume/storage"; export function AdvancedSettingScreen() { const storage = useStorage(); diff --git a/apps/desktop/src/routes/settings/backup.tsx b/apps/desktop/src/routes/settings/backup.tsx index 3efb1bdb..036c69f7 100644 --- a/apps/desktop/src/routes/settings/backup.tsx +++ b/apps/desktop/src/routes/settings/backup.tsx @@ -1,5 +1,5 @@ -import { useStorage } from "@lume/ark"; import { EyeOffIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { nip19 } from "nostr-tools"; import { useEffect, useState } from "react"; @@ -10,12 +10,12 @@ export function BackupSettingScreen() { const [showPassword, setShowPassword] = useState(false); const removePrivkey = async () => { - await storage.removePrivkey(storage.account.pubkey); + await storage.removePrivkey(ark.account.pubkey); }; useEffect(() => { async function loadPrivkey() { - const key = await storage.loadPrivkey(storage.account.pubkey); + const key = await storage.loadPrivkey(ark.account.pubkey); if (key) setPrivkey(key); } diff --git a/apps/desktop/src/routes/settings/components/postCard.tsx b/apps/desktop/src/routes/settings/components/postCard.tsx index 6acdf1bf..f0496075 100644 --- a/apps/desktop/src/routes/settings/components/postCard.tsx +++ b/apps/desktop/src/routes/settings/components/postCard.tsx @@ -1,5 +1,5 @@ -import { useStorage } from "@lume/ark"; import { LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { compactNumber } from "@lume/utils"; import { useQuery } from "@tanstack/react-query"; import { fetch } from "@tauri-apps/plugin-http"; @@ -8,10 +8,10 @@ import { Link } from "react-router-dom"; export function PostCard() { const storage = useStorage(); const { status, data } = useQuery({ - queryKey: ["user-stats", storage.account.pubkey], + queryKey: ["user-stats", ark.account.pubkey], queryFn: async ({ signal }: { signal: AbortSignal }) => { const res = await fetch( - `https://api.nostr.band/v0/stats/profile/${storage.account.pubkey}`, + `https://api.nostr.band/v0/stats/profile/${ark.account.pubkey}`, { signal, }, @@ -39,7 +39,7 @@ export function PostCard() {

{compactNumber.format( - data.stats[storage.account.pubkey].pub_note_count, + data.stats[ark.account.pubkey].pub_note_count, )}

@@ -47,7 +47,7 @@ export function PostCard() { Posts

View diff --git a/apps/desktop/src/routes/settings/components/profileCard.tsx b/apps/desktop/src/routes/settings/components/profileCard.tsx index 97e8528c..8dc18b3e 100644 --- a/apps/desktop/src/routes/settings/components/profileCard.tsx +++ b/apps/desktop/src/routes/settings/components/profileCard.tsx @@ -1,5 +1,6 @@ -import { useProfile, useStorage } from "@lume/ark"; +import { useProfile } from "@lume/ark"; import { EditIcon, LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { displayNpub } from "@lume/utils"; import * as Avatar from "@radix-ui/react-avatar"; import { writeText } from "@tauri-apps/plugin-clipboard-manager"; @@ -10,13 +11,13 @@ import { Link } from "react-router-dom"; export function ProfileCard() { const storage = useStorage(); const svgURI = `data:image/svg+xml;utf8,${encodeURIComponent( - minidenticon(storage.account.pubkey, 90, 50), + minidenticon(ark.account.pubkey, 90, 50), )}`; - const { isLoading, user } = useProfile(storage.account.pubkey); + const { isLoading, user } = useProfile(ark.account.pubkey); const copyNpub = async () => { - return await writeText(nip19.npubEncode(storage.account.pubkey)); + return await writeText(nip19.npubEncode(ark.account.pubkey)); }; return ( @@ -47,7 +48,7 @@ export function ProfileCard() { {storage.account.pubkey} @@ -66,7 +67,7 @@ export function ProfileCard() { {user?.display_name || user?.name}

- {user?.nip05 || displayNpub(storage.account.pubkey, 16)} + {user?.nip05 || displayNpub(ark.account.pubkey, 16)}

diff --git a/apps/desktop/src/routes/settings/components/relayCard.tsx b/apps/desktop/src/routes/settings/components/relayCard.tsx index 1af6ea6b..132d506b 100644 --- a/apps/desktop/src/routes/settings/components/relayCard.tsx +++ b/apps/desktop/src/routes/settings/components/relayCard.tsx @@ -1,5 +1,6 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { EditIcon, LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { compactNumber } from "@lume/utils"; import { useQuery } from "@tanstack/react-query"; import { Link } from "react-router-dom"; @@ -9,7 +10,7 @@ export function RelayCard() { const storage = useStorage(); const { status, data } = useQuery({ - queryKey: ["relays", storage.account.pubkey], + queryKey: ["relays", ark.account.pubkey], queryFn: async () => { const relays = await ark.getUserRelays({}); return relays; diff --git a/apps/desktop/src/routes/settings/components/zapCard.tsx b/apps/desktop/src/routes/settings/components/zapCard.tsx index 134a2e33..e1771d42 100644 --- a/apps/desktop/src/routes/settings/components/zapCard.tsx +++ b/apps/desktop/src/routes/settings/components/zapCard.tsx @@ -1,5 +1,5 @@ -import { useStorage } from "@lume/ark"; import { LoaderIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { compactNumber } from "@lume/utils"; import { useQuery } from "@tanstack/react-query"; import { fetch } from "@tauri-apps/plugin-http"; @@ -7,10 +7,10 @@ import { fetch } from "@tauri-apps/plugin-http"; export function ZapCard() { const storage = useStorage(); const { status, data } = useQuery({ - queryKey: ["user-stats", storage.account.pubkey], + queryKey: ["user-stats", ark.account.pubkey], queryFn: async ({ signal }: { signal: AbortSignal }) => { const res = await fetch( - `https://api.nostr.band/v0/stats/profile/${storage.account.pubkey}`, + `https://api.nostr.band/v0/stats/profile/${ark.account.pubkey}`, { signal, }, @@ -38,8 +38,7 @@ export function ZapCard() {

{compactNumber.format( - data?.stats[storage.account.pubkey]?.zaps_received?.msats / - 1000 || 0, + data?.stats[ark.account.pubkey]?.zaps_received?.msats / 1000 || 0, )}

diff --git a/apps/desktop/src/routes/settings/editProfile.tsx b/apps/desktop/src/routes/settings/editProfile.tsx index b57afd6a..7031681d 100644 --- a/apps/desktop/src/routes/settings/editProfile.tsx +++ b/apps/desktop/src/routes/settings/editProfile.tsx @@ -1,10 +1,11 @@ -import { useArk, useStorage } from "@lume/ark"; +import { useArk } from "@lume/ark"; import { CheckCircleIcon, LoaderIcon, PlusIcon, UnverifiedIcon, } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { NDKKind, NDKUserProfile } from "@nostr-dev-kit/ndk"; import { useQueryClient } from "@tanstack/react-query"; import { message } from "@tauri-apps/plugin-dialog"; @@ -31,7 +32,7 @@ export function EditProfileScreen() { defaultValues: async () => { const res: NDKUserProfile = queryClient.getQueryData([ "user", - storage.account.pubkey, + ark.account.pubkey, ]); if (res.image) { setPicture(res.image); @@ -102,7 +103,7 @@ export function EditProfileScreen() { if (data.nip05) { const verify = ark.validateNIP05({ - pubkey: storage.account.pubkey, + pubkey: ark.account.pubkey, nip05: data.nip05, }); if (verify) { @@ -125,7 +126,7 @@ export function EditProfileScreen() { if (publish) { // invalid cache queryClient.invalidateQueries({ - queryKey: ["user", storage.account.pubkey], + queryKey: ["user", ark.account.pubkey], }); // reset form reset(); diff --git a/apps/desktop/src/routes/settings/general.tsx b/apps/desktop/src/routes/settings/general.tsx index 99a2a227..01f112d0 100644 --- a/apps/desktop/src/routes/settings/general.tsx +++ b/apps/desktop/src/routes/settings/general.tsx @@ -1,5 +1,5 @@ -import { useStorage } from "@lume/ark"; import { DarkIcon, LightIcon, SystemModeIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import * as Switch from "@radix-ui/react-switch"; import { invoke } from "@tauri-apps/api/core"; import { getCurrent } from "@tauri-apps/api/window"; diff --git a/apps/desktop/src/routes/users/components/profile.tsx b/apps/desktop/src/routes/users/components/profile.tsx index fd905990..250db59d 100644 --- a/apps/desktop/src/routes/users/components/profile.tsx +++ b/apps/desktop/src/routes/users/components/profile.tsx @@ -1,4 +1,5 @@ -import { useArk, useProfile, useStorage } from "@lume/ark"; +import { useArk, useProfile } from "@lume/ark"; +import { useStorage } from "@lume/storage"; import { NIP05 } from "@lume/ui"; import { displayNpub } from "@lume/utils"; import * as Avatar from "@radix-ui/react-avatar"; @@ -50,7 +51,7 @@ export function UserProfile({ pubkey }: { pubkey: string }) { }; useEffect(() => { - if (storage.account.contacts.includes(pubkey)) { + if (ark.account.contacts.includes(pubkey)) { setFollowed(true); } }, []); diff --git a/apps/desktop/vite.config.ts b/apps/desktop/vite.config.ts index a48b3938..d0be4dc5 100644 --- a/apps/desktop/vite.config.ts +++ b/apps/desktop/vite.config.ts @@ -1,6 +1,7 @@ import react from "@vitejs/plugin-react-swc"; import million from "million/compiler"; import { defineConfig } from "vite"; +import topLevelAwait from "vite-plugin-top-level-await"; import viteTsconfigPaths from "vite-tsconfig-paths"; export default defineConfig({ @@ -13,6 +14,12 @@ export default defineConfig({ }), react(), viteTsconfigPaths(), + topLevelAwait({ + // The export name of top-level await promise for each chunk module + promiseExportName: "__tla", + // The function to generate import names of top-level await promise in each chunk module + promiseImportName: (i) => `__tla_${i}`, + }), ], envPrefix: ["VITE_", "TAURI_"], build: { diff --git a/packages/ark/src/ark.ts b/packages/ark/src/ark.ts index 66aa26a9..3601f317 100644 --- a/packages/ark/src/ark.ts +++ b/packages/ark/src/ark.ts @@ -1,5 +1,4 @@ -import { LumeStorage } from "@lume/storage"; -import { type NDKEventWithReplies, type NIP05 } from "@lume/types"; +import { Account, type NDKEventWithReplies, type NIP05 } from "@lume/types"; import NDK, { NDKEvent, NDKFilter, @@ -20,18 +19,18 @@ import { NostrFetcher, normalizeRelayUrl } from "nostr-fetch"; import { nip19 } from "nostr-tools"; export class Ark { - #storage: LumeStorage; public ndk: NDK; + public account: Account; constructor({ ndk, - storage, + account, }: { ndk: NDK; - storage: LumeStorage; + account: Account; }) { this.ndk = ndk; - this.#storage = storage; + this.account = account; } public async connectDepot() { @@ -106,8 +105,9 @@ export class Ark { public async getUserProfile(pubkey?: string) { try { + const currentUserPubkey = this.account.pubkey; + // get clean pubkey without any special characters - const currentUserPubkey = this.#storage.account.pubkey; let hexstring = pubkey ? pubkey.replace(/[^a-zA-Z0-9]/g, "").replace("nostr:", "") : currentUserPubkey; @@ -141,8 +141,9 @@ export class Ark { public async getUserContacts(pubkey?: string) { try { + const currentUserPubkey = this.account.pubkey; + // get clean pubkey without any special characters - const currentUserPubkey = this.#storage.account.pubkey; let hexstring = pubkey ? pubkey.replace(/[^a-zA-Z0-9]/g, "").replace("nostr:", "") : currentUserPubkey; @@ -165,8 +166,8 @@ export class Ark { const contacts = [...(await user.follows())].map((user) => user.pubkey); - if (!pubkey || pubkey === this.#storage.account.pubkey) - this.#storage.account.contacts = contacts; + if (!pubkey || pubkey === this.account.pubkey) + this.account.contacts = contacts; return contacts; } catch (e) { @@ -177,7 +178,7 @@ export class Ark { public async getUserRelays({ pubkey }: { pubkey?: string }) { try { const user = this.ndk.getUser({ - pubkey: pubkey ? pubkey : this.#storage.account.pubkey, + pubkey: pubkey ? pubkey : this.account.pubkey, }); return await user.relayList(); } catch (e) { @@ -192,19 +193,19 @@ export class Ark { }); if (publish) { - this.#storage.account.contacts = tags.map((item) => item[1]); + this.account.contacts = tags.map((item) => item[1]); return publish; } } public async createContact({ pubkey }: { pubkey: string }) { - const user = this.ndk.getUser({ pubkey: this.#storage.account.pubkey }); + const user = this.ndk.getUser({ pubkey: this.account.pubkey }); const contacts = await user.follows(); return await user.follow(new NDKUser({ pubkey: pubkey }), contacts); } public async deleteContact({ pubkey }: { pubkey: string }) { - const user = this.ndk.getUser({ pubkey: this.#storage.account.pubkey }); + const user = this.ndk.getUser({ pubkey: this.account.pubkey }); const contacts = await user.follows(); contacts.delete(new NDKUser({ pubkey: pubkey })); @@ -362,7 +363,7 @@ export class Ark { const relayMap = new Map(); const relayEvents = fetcher.fetchLatestEventsPerAuthor( { - authors: this.#storage.account.contacts, + authors: this.account.contacts, relayUrls: connectedRelays, }, { kinds: [NDKKind.RelayList] }, @@ -569,7 +570,7 @@ export class Ark { const event = await this.ndk.fetchEvent({ kinds: [NDKKind.AppRecommendation], "#d": [unknownKind], - authors: this.#storage.account.contacts || [author], + authors: this.account.contacts || [author], }); if (event) return event.tags.filter((item) => item[0] !== "d"); @@ -577,7 +578,7 @@ export class Ark { const altEvent = await this.ndk.fetchEvent({ kinds: [NDKKind.AppHandler], "#k": [unknownKind], - authors: this.#storage.account.contacts || [author], + authors: this.account.contacts || [author], }); if (altEvent) return altEvent.tags.filter((item) => item[0] !== "d"); diff --git a/packages/ark/src/components/column/live.tsx b/packages/ark/src/components/column/live.tsx index 444799d2..ed46ab3f 100644 --- a/packages/ark/src/components/column/live.tsx +++ b/packages/ark/src/components/column/live.tsx @@ -1,7 +1,7 @@ import { ChevronUpIcon } from "@lume/icons"; import { NDKEvent, NDKFilter } from "@nostr-dev-kit/ndk"; import { useEffect, useState } from "react"; -import { useArk } from "../../provider"; +import { useArk } from "../../hooks/useArk"; export function ColumnLiveWidget({ filter, diff --git a/packages/ark/src/components/column/provider.tsx b/packages/ark/src/components/column/provider.tsx index 0743cbc3..49876fbf 100644 --- a/packages/ark/src/components/column/provider.tsx +++ b/packages/ark/src/components/column/provider.tsx @@ -1,3 +1,4 @@ +import { useStorage } from "@lume/storage"; import { IColumn } from "@lume/types"; import { COL_TYPES } from "@lume/utils"; import { @@ -8,7 +9,6 @@ import { useEffect, useState, } from "react"; -import { useStorage } from "../../provider"; type ColumnContext = { columns: IColumn[]; diff --git a/packages/ark/src/components/note/appHandler.tsx b/packages/ark/src/components/note/appHandler.tsx index 540ddb72..f229f063 100644 --- a/packages/ark/src/components/note/appHandler.tsx +++ b/packages/ark/src/components/note/appHandler.tsx @@ -1,6 +1,6 @@ import { NDKAppHandlerEvent } from "@nostr-dev-kit/ndk"; import { useQuery } from "@tanstack/react-query"; -import { useArk } from "../../provider"; +import { useArk } from "../../hooks/useArk"; export function AppHandler({ tag }: { tag: string[] }) { const ark = useArk(); diff --git a/packages/ark/src/components/note/buttons/zap.tsx b/packages/ark/src/components/note/buttons/zap.tsx index c47ac145..b48d8700 100644 --- a/packages/ark/src/components/note/buttons/zap.tsx +++ b/packages/ark/src/components/note/buttons/zap.tsx @@ -1,6 +1,7 @@ import { webln } from "@getalby/sdk"; import { SendPaymentResponse } from "@getalby/sdk/dist/types"; import { CancelIcon, ZapIcon } from "@lume/icons"; +import { useStorage } from "@lume/storage"; import { compactNumber, displayNpub, @@ -13,8 +14,8 @@ import { QRCodeSVG } from "qrcode.react"; import { useEffect, useRef, useState } from "react"; import CurrencyInput from "react-currency-input-field"; import { useNavigate } from "react-router-dom"; +import { useArk } from "../../../hooks/useArk"; import { useProfile } from "../../../hooks/useProfile"; -import { useArk, useStorage } from "../../../provider"; import { useNoteContext } from "../provider"; export function NoteZap() { @@ -87,7 +88,7 @@ export function NoteZap() { useEffect(() => { async function getWalletConnectURL() { const uri: string = await invoke("secure_load", { - key: `${storage.account.pubkey}-nwc`, + key: `${ark.account.pubkey}-nwc`, }); if (uri) setWalletConnectURL(uri); } diff --git a/packages/ark/src/components/note/child.tsx b/packages/ark/src/components/note/child.tsx index cf066af3..d4fa7328 100644 --- a/packages/ark/src/components/note/child.tsx +++ b/packages/ark/src/components/note/child.tsx @@ -22,7 +22,7 @@ export function NoteChild({ "\n", ); - const text = parsedContent; + const text = parsedContent as string; const words = text.split(/( |\n)/); const hashtags = words.filter((word) => word.startsWith("#")); diff --git a/packages/ark/src/components/note/content.tsx b/packages/ark/src/components/note/content.tsx index 92866792..47662cc8 100644 --- a/packages/ark/src/components/note/content.tsx +++ b/packages/ark/src/components/note/content.tsx @@ -1,3 +1,4 @@ +import { useStorage } from "@lume/storage"; import { AUDIOS, IMAGES, @@ -15,7 +16,6 @@ import { nip19 } from "nostr-tools"; import { ReactNode, useMemo, useState } from "react"; import { Link } from "react-router-dom"; import reactStringReplace from "react-string-replace"; -import { useStorage } from "../../provider"; import { Hashtag } from "./mentions/hashtag"; import { MentionNote } from "./mentions/note"; import { MentionUser } from "./mentions/user"; diff --git a/packages/ark/src/components/note/nip89.tsx b/packages/ark/src/components/note/nip89.tsx index 66b4b60a..c747b2e9 100644 --- a/packages/ark/src/components/note/nip89.tsx +++ b/packages/ark/src/components/note/nip89.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import { useArk } from "../../provider"; +import { useArk } from "../../hooks/useArk"; import { AppHandler } from "./appHandler"; import { useNoteContext } from "./provider"; diff --git a/packages/ark/src/components/note/primitives/repost.tsx b/packages/ark/src/components/note/primitives/repost.tsx index 6e8a90d9..446e1494 100644 --- a/packages/ark/src/components/note/primitives/repost.tsx +++ b/packages/ark/src/components/note/primitives/repost.tsx @@ -1,7 +1,7 @@ import { NDKEvent, NostrEvent } from "@nostr-dev-kit/ndk"; import { useQuery } from "@tanstack/react-query"; import { Note } from ".."; -import { useArk } from "../../../provider"; +import { useArk } from "../../../hooks/useArk"; export function RepostNote({ event, diff --git a/packages/ark/src/context.ts b/packages/ark/src/context.ts new file mode 100644 index 00000000..918a4536 --- /dev/null +++ b/packages/ark/src/context.ts @@ -0,0 +1,4 @@ +import { createContext } from "react"; +import { type Ark } from "./ark"; + +export const LumeContext = createContext(undefined); diff --git a/packages/ark/src/hooks/useArk.ts b/packages/ark/src/hooks/useArk.ts new file mode 100644 index 00000000..8d45b8dc --- /dev/null +++ b/packages/ark/src/hooks/useArk.ts @@ -0,0 +1,10 @@ +import { useContext } from "react"; +import { LumeContext } from "../context"; + +export const useArk = () => { + const context = useContext(LumeContext); + if (context === undefined) { + throw new Error("Please import Ark Provider to use useArk() hook"); + } + return context; +}; diff --git a/packages/ark/src/hooks/useEvent.ts b/packages/ark/src/hooks/useEvent.ts index f07cfec9..0d872e1e 100644 --- a/packages/ark/src/hooks/useEvent.ts +++ b/packages/ark/src/hooks/useEvent.ts @@ -1,21 +1,24 @@ -import { useQuery } from '@tanstack/react-query'; -import { useArk } from '../provider'; +import { useQuery } from "@tanstack/react-query"; +import { useArk } from "./useArk"; export function useEvent(id: string) { - const ark = useArk(); - const { status, isLoading, isError, data } = useQuery({ - queryKey: ['event', id], - queryFn: async () => { - const event = await ark.getEventById({ id }); - if (!event) - throw new Error(`Cannot get event with ${id}, will be retry after 10 seconds`); - return event; - }, - refetchOnWindowFocus: false, - refetchOnMount: false, - refetchOnReconnect: false, - retry: 2, - }); + const ark = useArk(); + const { status, isLoading, isError, data } = useQuery({ + queryKey: ["event", id], + queryFn: async () => { + const event = await ark.getEventById({ id }); + if (!event) + throw new Error( + `Cannot get event with ${id}, will be retry after 10 seconds`, + ); + return event; + }, + refetchOnWindowFocus: false, + refetchOnMount: false, + refetchOnReconnect: false, + staleTime: Infinity, + retry: 2, + }); - return { status, isLoading, isError, data }; + return { status, isLoading, isError, data }; } diff --git a/packages/ark/src/hooks/useProfile.ts b/packages/ark/src/hooks/useProfile.ts index 3f79d1dd..30c4f734 100644 --- a/packages/ark/src/hooks/useProfile.ts +++ b/packages/ark/src/hooks/useProfile.ts @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query"; -import { useArk } from "../provider"; +import { useArk } from "./useArk"; export function useProfile(pubkey: string) { const ark = useArk(); @@ -20,6 +20,7 @@ export function useProfile(pubkey: string) { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, + staleTime: Infinity, retry: 2, }); diff --git a/packages/ark/src/hooks/useRelay.ts b/packages/ark/src/hooks/useRelay.ts index 4c38a342..8d29697e 100644 --- a/packages/ark/src/hooks/useRelay.ts +++ b/packages/ark/src/hooks/useRelay.ts @@ -1,6 +1,7 @@ +import { useStorage } from "@lume/storage"; import { NDKKind, NDKRelayUrl, NDKTag } from "@nostr-dev-kit/ndk"; import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { useArk, useStorage } from "../provider"; +import { useArk } from "./useArk"; export function useRelay() { const ark = useArk(); @@ -14,13 +15,13 @@ export function useRelay() { ) => { // Cancel any outgoing refetches await queryClient.cancelQueries({ - queryKey: ["relays", storage.account.pubkey], + queryKey: ["relays", ark.account.pubkey], }); // Snapshot the previous value const prevRelays: NDKTag[] = queryClient.getQueryData([ "relays", - storage.account.pubkey, + ark.account.pubkey, ]); // create new relay list if not exist @@ -42,7 +43,7 @@ export function useRelay() { // Optimistically update to the new value queryClient.setQueryData( - ["relays", storage.account.pubkey], + ["relays", ark.account.pubkey], (prev: NDKTag[]) => [...prev, ["r", relay, purpose ?? ""]], ); @@ -51,7 +52,7 @@ export function useRelay() { }, onSettled: () => { queryClient.invalidateQueries({ - queryKey: ["relays", storage.account.pubkey], + queryKey: ["relays", ark.account.pubkey], }); }, }); @@ -60,13 +61,13 @@ export function useRelay() { mutationFn: async (relay: NDKRelayUrl) => { // Cancel any outgoing refetches await queryClient.cancelQueries({ - queryKey: ["relays", storage.account.pubkey], + queryKey: ["relays", ark.account.pubkey], }); // Snapshot the previous value const prevRelays: NDKTag[] = queryClient.getQueryData([ "relays", - storage.account.pubkey, + ark.account.pubkey, ]); if (!prevRelays) return; @@ -80,14 +81,14 @@ export function useRelay() { }); // Optimistically update to the new value - queryClient.setQueryData(["relays", storage.account.pubkey], prevRelays); + queryClient.setQueryData(["relays", ark.account.pubkey], prevRelays); // Return a context object with the snapshotted value return { prevRelays }; }, onSettled: () => { queryClient.invalidateQueries({ - queryKey: ["relays", storage.account.pubkey], + queryKey: ["relays", ark.account.pubkey], }); }, }); diff --git a/packages/ark/src/index.ts b/packages/ark/src/index.ts index a12fbfd1..22a7efc2 100644 --- a/packages/ark/src/index.ts +++ b/packages/ark/src/index.ts @@ -1,6 +1,8 @@ export * from "./ark"; +export * from "./context"; export * from "./provider"; export * from "./hooks/useEvent"; +export * from "./hooks/useArk"; export * from "./hooks/useProfile"; export * from "./hooks/useRelay"; export * from "./components/column/provider"; diff --git a/packages/ark/src/provider.tsx b/packages/ark/src/provider.tsx index bf790a86..ab897a1f 100644 --- a/packages/ark/src/provider.tsx +++ b/packages/ark/src/provider.tsx @@ -1,7 +1,7 @@ import { LoaderIcon } from "@lume/icons"; import { NDKCacheAdapterTauri } from "@lume/ndk-cache-tauri"; -import { LumeStorage } from "@lume/storage"; -import { QUOTES, delay, sendNativeNotification } from "@lume/utils"; +import { useStorage } from "@lume/storage"; +import { QUOTES, sendNativeNotification } from "@lume/utils"; import NDK, { NDKEvent, NDKKind, @@ -11,44 +11,28 @@ import NDK, { NDKRelayAuthPolicies, } from "@nostr-dev-kit/ndk"; import { fetch } from "@tauri-apps/plugin-http"; -import { locale, platform } from "@tauri-apps/plugin-os"; -import { relaunch } from "@tauri-apps/plugin-process"; -import Database from "@tauri-apps/plugin-sql"; -import { check } from "@tauri-apps/plugin-updater"; import Linkify from "linkify-react"; -import { normalizeRelayUrl, normalizeRelayUrlSet } from "nostr-fetch"; +import { normalizeRelayUrlSet } from "nostr-fetch"; import { PropsWithChildren, useEffect, useState } from "react"; -import { createContext, useContextSelector } from "use-context-selector"; import { Ark } from "./ark"; +import { LumeContext } from "./context"; -type Context = { - storage: LumeStorage; - ark: Ark; -}; - -const LumeContext = createContext({ - storage: undefined, - ark: undefined, -}); - -const LumeProvider = ({ children }: PropsWithChildren) => { - const [context, setContext] = useState(undefined); - const [isNewVersion, setIsNewVersion] = useState(false); +export const LumeProvider = ({ children }: PropsWithChildren) => { + const storage = useStorage(); + const [context, setContext] = useState(undefined); async function initNostrSigner({ - storage, nsecbunker, }: { - storage: LumeStorage; nsecbunker?: boolean; }) { try { - if (!storage.account) return null; + if (!storage.currentUser) return null; // NIP-46 Signer if (nsecbunker) { const localSignerPrivkey = await storage.loadPrivkey( - storage.account.pubkey, + storage.currentUser.pubkey, ); if (!localSignerPrivkey) return null; @@ -64,7 +48,7 @@ const LumeProvider = ({ children }: PropsWithChildren) => { const remoteSigner = new NDKNip46Signer( bunker, - storage.account.pubkey, + storage.currentUser.pubkey, localSigner, ); await remoteSigner.blockUntilReady(); @@ -73,11 +57,8 @@ const LumeProvider = ({ children }: PropsWithChildren) => { } // Privkey Signer - const userPrivkey = await storage.loadPrivkey(storage.account.pubkey); - - if (!userPrivkey) { - return null; - } + const userPrivkey = await storage.loadPrivkey(storage.currentUser.pubkey); + if (!userPrivkey) return null; return new NDKPrivateKeySigner(userPrivkey); } catch (e) { @@ -87,45 +68,23 @@ const LumeProvider = ({ children }: PropsWithChildren) => { } async function init() { - const platformName = await platform(); - const osLocale = await locale(); - const sqliteAdapter = await Database.load("sqlite:lume_v3.db"); - - const storage = new LumeStorage(sqliteAdapter, platformName, osLocale); - await storage.init(); - - // check for new update - if (storage.settings.autoupdate) { - const update = await check(); - // install new version - if (update) { - setIsNewVersion(true); - - await update.downloadAndInstall(); - await relaunch(); - } - } - const explicitRelayUrls = normalizeRelayUrlSet([ "wss://bostr.nokotaro.com/", - "wss://nostr.mutinywallet.com", + "wss://nostr.mutinywallet.com/", ]); - if (storage.settings.depot) { - await storage.launchDepot(); - await delay(2000); - - explicitRelayUrls.push(normalizeRelayUrl("ws://localhost:6090")); - } - // #TODO: user should config outbox relays - const outboxRelayUrls = normalizeRelayUrlSet(["wss://purplepag.es"]); + const outboxRelayUrls = normalizeRelayUrlSet(["wss://purplepag.es/"]); // #TODO: user should config blacklist relays // No need to connect depot tunnel url const blacklistRelayUrls = storage.settings.tunnelUrl.length - ? [storage.settings.tunnelUrl, `${storage.settings.tunnelUrl}/`] - : []; + ? [ + storage.settings.tunnelUrl, + `${storage.settings.tunnelUrl}/`, + "wss://brb.io/", + ] + : ["wss://brb.io/"]; const cacheAdapter = new NDKCacheAdapterTauri(storage); const ndk = new NDK({ @@ -136,7 +95,7 @@ const LumeProvider = ({ children }: PropsWithChildren) => { enableOutboxModel: !storage.settings.lowPower, autoConnectUserRelays: !storage.settings.lowPower, autoFetchUserMutelist: !storage.settings.lowPower, - // clientName: 'Lume', + // clientName: "Lume", // clientNip89: '', }); @@ -145,8 +104,7 @@ const LumeProvider = ({ children }: PropsWithChildren) => { // add signer const signer = await initNostrSigner({ - storage, - nsecbunker: storage.settings.bunker, + nsecbunker: storage.settings.nsecbunker, }); if (signer) ndk.signer = signer; @@ -167,19 +125,19 @@ const LumeProvider = ({ children }: PropsWithChildren) => { }; // update account's metadata - if (storage.account) { - const user = ndk.getUser({ pubkey: storage.account.pubkey }); + if (signer) { + const user = ndk.getUser({ pubkey: storage.currentUser.pubkey }); ndk.activeUser = user; const contacts = await user.follows(); - storage.account.contacts = [...contacts].map((user) => user.pubkey); + storage.currentUser.contacts = [...contacts].map((user) => user.pubkey); // subscribe for new activity const sub = ndk.subscribe( { kinds: [NDKKind.Text, NDKKind.Repost, NDKKind.Zap], - "#p": [storage.account.pubkey], since: Math.floor(Date.now() / 1000), + "#p": [storage.currentUser.pubkey], }, { closeOnEose: false, groupable: false }, ); @@ -212,14 +170,14 @@ const LumeProvider = ({ children }: PropsWithChildren) => { } // ark utils - const ark = new Ark({ storage, ndk }); + const ark = new Ark({ ndk, account: storage.currentUser }); // update context - setContext({ ark, storage }); + setContext(ark); } useEffect(() => { - if (!context && !isNewVersion) init(); + if (!context) init(); }, []); if (!context) { @@ -243,37 +201,13 @@ const LumeProvider = ({ children }: PropsWithChildren) => {
-

- {isNewVersion ? "Found a new version, updating..." : "Starting..."} -

+

Starting

); } return ( - - {children} - + {children} ); }; - -const useArk = () => { - const context = useContextSelector(LumeContext, (state) => state.ark); - if (context === undefined) { - throw new Error("Please import Ark Provider to use useArk() hook"); - } - return context; -}; - -const useStorage = () => { - const context = useContextSelector(LumeContext, (state) => state.storage); - if (context === undefined) { - throw new Error("Please import Ark Provider to use useStorage() hook"); - } - return context; -}; - -export { LumeProvider, useArk, useStorage }; diff --git a/packages/lume-column-antenas/src/home.tsx b/packages/lume-column-antenas/src/home.tsx index 461b42ab..4300ed77 100644 --- a/packages/lume-column-antenas/src/home.tsx +++ b/packages/lume-column-antenas/src/home.tsx @@ -1,4 +1,4 @@ -import { RepostNote, TextNote, useArk, useStorage } from "@lume/ark"; +import { RepostNote, TextNote, useArk } from "@lume/ark"; import { ArrowRightCircleIcon, LoaderIcon } from "@lume/icons"; import { FETCH_LIMIT } from "@lume/utils"; import { NDKEvent, NDKFilter, NDKKind } from "@nostr-dev-kit/ndk"; @@ -11,7 +11,6 @@ export function HomeRoute({ content, }: { colKey: string; content: string }) { const ark = useArk(); - const storage = useStorage(); const ref = useRef(); const cacheKey = `${colKey}-vlist`; @@ -40,7 +39,7 @@ export function HomeRoute({ filter = { kinds: [NDKKind.Text, NDKKind.Repost], "#t": parsed.hashtags.map((item) => item.replace("#", "")), - authors: storage.account.contacts, + authors: ark.account.contacts, }; } else { filter = { diff --git a/packages/lume-column-group/src/components/form.tsx b/packages/lume-column-group/src/components/form.tsx index e3efe6f3..97844b67 100644 --- a/packages/lume-column-group/src/components/form.tsx +++ b/packages/lume-column-group/src/components/form.tsx @@ -1,10 +1,10 @@ -import { useColumnContext, useStorage } from "@lume/ark"; +import { useArk, useColumnContext } from "@lume/ark"; import { CancelIcon, CheckCircleIcon } from "@lume/icons"; import { User } from "@lume/ui"; import { useState } from "react"; export function GroupForm({ id }: { id: number }) { - const storage = useStorage(); + const ark = useArk(); const { updateColumn, removeColumn } = useColumnContext(); const [title, setTitle] = useState(`Group-${id}`); @@ -59,7 +59,7 @@ export function GroupForm({ id }: { id: number }) { {`${users.length} / ∞`}
- {storage.account?.contacts?.map((item: string) => ( + {ark.account?.contacts?.map((item: string) => (