From 0e326d6bca826a4d9bec7e6e1b159b0a2e7b6b5c Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 13 Mar 2026 22:34:54 -0700 Subject: lazy imports --- src/lib/ark.ts | 17 ++++++++++++----- src/lib/deriveAuthKey.ts | 4 ++-- src/lib/marmot.ts | 4 ++-- src/lib/mls-relay.ts | 4 ++-- src/lib/nip07.ts | 2 +- src/lib/nostr.ts | 32 ++++++++++++++++++-------------- src/lib/parseContent.ts | 2 +- src/lib/seed.ts | 4 ++-- src/lib/walletEntropy.ts | 5 ++++- 9 files changed, 44 insertions(+), 30 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ark.ts b/src/lib/ark.ts index 01c12dae..cb95177d 100644 --- a/src/lib/ark.ts +++ b/src/lib/ark.ts @@ -40,8 +40,11 @@ interface ArkVaultSnapshot { virtualTxs: Record; } -let arkSdkPromise: Promise | undefined; -const loadArkSdk = () => (arkSdkPromise ||= import("@arkade-os/sdk")); +const loadSingleKey = () => import("@arkade-os/sdk/identity/singleKey.js"); +const loadWallet = () => import("@arkade-os/sdk/wallet/wallet.js"); +const loadDelegator = () => import("@arkade-os/sdk/providers/delegator.js"); +const loadVtxoManager = () => import("@arkade-os/sdk/wallet/vtxo-manager.js"); +const loadSwWallet = () => import("@arkade-os/sdk/wallet/serviceWorker/wallet.js"); let walletInstance: any; let walletKey: string | undefined; @@ -55,7 +58,9 @@ export const getWallet = async () => { } if (walletInstance && walletKey === key) return walletInstance; - const { SingleKey, Wallet, RestDelegatorProvider } = await loadArkSdk(); + const [{ SingleKey }, { Wallet }, { RestDelegatorProvider }] = await Promise.all([ + loadSingleKey(), loadWallet(), loadDelegator(), + ]); const identity = SingleKey.fromHex(key); const delegatorProvider = new RestDelegatorProvider(delegatorUrl); @@ -478,7 +483,7 @@ export const refresh = async () => { const wallet = await getWallet(); if (!wallet) return; - const { VtxoManager } = await loadArkSdk(); + const { VtxoManager } = await loadVtxoManager(); const balance = await wallet.getBalance(); const manager = new VtxoManager(wallet); @@ -564,7 +569,9 @@ export const getServiceWorkerWallet = async () => { try { const reg = await navigator.serviceWorker.ready; if (!reg.active) return; - const { ServiceWorkerWallet, SingleKey } = await loadArkSdk(); + const [{ ServiceWorkerWallet }, { SingleKey }] = await Promise.all([ + loadSwWallet(), loadSingleKey(), + ]); swWallet = await ServiceWorkerWallet.create({ serviceWorker: reg.active, arkServerUrl: arkServerUrl!, diff --git a/src/lib/deriveAuthKey.ts b/src/lib/deriveAuthKey.ts index eb498e0a..8f17a7bd 100644 --- a/src/lib/deriveAuthKey.ts +++ b/src/lib/deriveAuthKey.ts @@ -1,6 +1,6 @@ import { scryptAsync } from "@noble/hashes/scrypt.js"; import { bytesToHex } from "@noble/hashes/utils.js"; -import { getPublicKey } from "nostr-tools"; +import { getPublicKey } from "nostr-tools/pure"; export async function deriveAuthKeypair(username: string, password: string) { const salt = `coinos:auth:${username.toLowerCase().replace(/\s/g, "")}`; @@ -10,7 +10,7 @@ export async function deriveAuthKeypair(username: string, password: string) { } export async function deriveWalletEntropy(sk: Uint8Array): Promise { - const { finalizeEvent } = await import("nostr-tools"); + const { finalizeEvent } = await import("nostr-tools/pure"); const event = { kind: 1, created_at: 0, content: "coinos-wallet-key-derivation", tags: [] }; const signed = finalizeEvent(event as any, sk); const sigBytes = new Uint8Array(signed.sig.length / 2); diff --git a/src/lib/marmot.ts b/src/lib/marmot.ts index 16789e61..ba1b02f5 100644 --- a/src/lib/marmot.ts +++ b/src/lib/marmot.ts @@ -13,9 +13,9 @@ import { SimplePool } from "nostr-tools/pool"; import { Relay } from "nostr-tools/relay"; import { MarmotClient, - KeyPackageStore, InviteReader, -} from "@internet-privacy/marmot-ts"; +} from "@internet-privacy/marmot-ts/client"; +import { KeyPackageStore } from "@internet-privacy/marmot-ts/store"; import type { NostrNetworkInterface, PublishResponse, diff --git a/src/lib/mls-relay.ts b/src/lib/mls-relay.ts index be89ef11..77e57bbd 100644 --- a/src/lib/mls-relay.ts +++ b/src/lib/mls-relay.ts @@ -5,11 +5,11 @@ import type { NostrEvent } from "nostr-tools/pure"; import { bytesToHex } from "@noble/hashes/utils.js"; -import { nip19 } from "nostr-tools"; +import * as nip19 from "nostr-tools/nip19"; import { SimplePool } from "nostr-tools/pool"; import { Relay } from "nostr-tools/relay"; import { getMarmotClient, getInviteReader, DM_RELAYS } from "$lib/marmot"; -import { parseMediaImetaTag } from "@internet-privacy/marmot-ts"; +import { parseMediaImetaTag } from "@internet-privacy/marmot-ts/media"; import { BlossomClient } from "nostr-tools/nipb7"; import { ensureSigner } from "$lib/nip07"; import { post } from "$lib/utils"; diff --git a/src/lib/nip07.ts b/src/lib/nip07.ts index dc774186..bb53c2c0 100644 --- a/src/lib/nip07.ts +++ b/src/lib/nip07.ts @@ -12,7 +12,7 @@ const tryNsecFromStorage = async (): Promise => { if (!nsec) return null; try { - const { nip19 } = await import("nostr-tools"); + const nip19 = await import("nostr-tools/nip19"); const { type, data } = nip19.decode(nsec); if (type !== "nsec" || !(data instanceof Uint8Array)) return null; diff --git a/src/lib/nostr.ts b/src/lib/nostr.ts index e91e33f5..558a123d 100644 --- a/src/lib/nostr.ts +++ b/src/lib/nostr.ts @@ -12,12 +12,16 @@ import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js"; import type { EventTemplate } from "nostr-tools"; import { get } from "svelte/store"; -let nostrToolsPromise: Promise | undefined; +let nip04Promise: Promise | undefined; +let nip19Promise: Promise | undefined; +let purePromise: Promise | undefined; let nip44Promise: Promise | undefined; let relayPromise: Promise | undefined; let nip49Promise: Promise | undefined; -const loadNostrTools = () => (nostrToolsPromise ||= import("nostr-tools")); +const loadNip04 = () => (nip04Promise ||= import("nostr-tools/nip04")); +const loadNip19 = () => (nip19Promise ||= import("nostr-tools/nip19")); +const loadPure = () => (purePromise ||= import("nostr-tools/pure")); const loadNip44 = () => (nip44Promise ||= import("nostr-tools/nip44")); const loadRelay = () => (relayPromise ||= import("nostr-tools/relay")); const loadNip49 = () => (nip49Promise ||= import("nostr-tools/nip49")); @@ -34,7 +38,7 @@ type EncryptParams = { export const encrypt = async ({ message, recipient, user }: EncryptParams) => { const sk = await getPrivateKey(user); - const { nip04 } = await loadNostrTools(); + const nip04 = await loadNip04(); return nip04.encrypt(sk, recipient, message); }; @@ -45,7 +49,7 @@ export const decrypt = async ({ event, user }: { event: any; user: any }) => { if (cache[id]) return cache[id]; if (pubkey === user.pubkey) pubkey = event.tags[0][1]; - const { nip04 } = await loadNostrTools(); + const nip04 = await loadNip04(); const message = await nip04.decrypt(await getPrivateKey(user), pubkey, content); cache[id] = Buffer.from(message).toString("utf8"); @@ -62,7 +66,7 @@ export const getPrivateKey = async (user: User): Promise => { if (browser) { k = localStorage.getItem("nsec"); if (k) { - const { nip19 } = await loadNostrTools(); + const nip19 = await loadNip19(); return nip19.decode(k).data as unknown as Uint8Array; } } @@ -76,25 +80,25 @@ export const getPrivateKey = async (user: User): Promise => { throw new Error("nsec not available"); } - const { nip19 } = await loadNostrTools(); + const nip19 = await loadNip19(); localStorage.setItem("nsec", nip19.nsecEncode(k)); return k; }; const decodeNsec = async (nsec: string): Promise => { - const { nip19 } = await loadNostrTools(); + const nip19 = await loadNip19(); const { type, data } = nip19.decode(nsec); if (type === "nsec" && data instanceof Uint8Array) return data; throw new Error("invalid nsec"); }; export const getNsec = async (user: User) => { - const { nip19 } = await loadNostrTools(); + const nip19 = await loadNip19(); return nip19.nsecEncode(await getPrivateKey(user)); }; export const setNsec = async (user: User, nsec: string) => { - const { getPublicKey } = await loadNostrTools(); + const { getPublicKey } = await loadPure(); user.pubkey = getPublicKey(await decodeNsec(nsec)); user.nsec = await encryptNsec(nsec); }; @@ -108,7 +112,7 @@ export const encryptNsec = async (nsec: string) => { export const sign = async (event: any, user?: any) => { if (user?.nsec && !get($signer)?.ready) { const sk = await getPrivateKey(user); - const { getPublicKey } = await loadNostrTools(); + const { getPublicKey } = await loadPure(); $signer.set({ method: "nsec", @@ -156,7 +160,7 @@ const signingMethods: Record Promise> params: [JSON.stringify(event)], }; - const { nip04, finalizeEvent } = await loadNostrTools(); + const [nip04, { finalizeEvent }] = await Promise.all([loadNip04(), loadPure()]); const skBytes = hexToBytes(sk); const content = await nip04.encrypt(skBytes, pk, JSON.stringify(signEvent)); @@ -181,7 +185,7 @@ const signingMethods: Record Promise> try { let response; try { - const { nip04 } = await loadNostrTools(); + const nip04 = await loadNip04(); response = JSON.parse(await nip04.decrypt(hexToBytes(sk), pk, event.content)); } catch { const { getConversationKey, decrypt: nip44decrypt } = await loadNip44(); @@ -199,7 +203,7 @@ const signingMethods: Record Promise> }, async nsec(event: any, { sk }: any) { - const { finalizeEvent } = await loadNostrTools(); + const { finalizeEvent } = await loadPure(); return finalizeEvent(event, hexToBytes(sk)); }, @@ -209,7 +213,7 @@ const signingMethods: Record Promise> async signer(event: any, { pubkey, sig }: any) { event.pubkey = pubkey; - const { getEventHash } = await loadNostrTools(); + const { getEventHash } = await loadPure(); const signedEvent = { ...event, id: getEventHash(event), diff --git a/src/lib/parseContent.ts b/src/lib/parseContent.ts index 13f33b83..bf8895fa 100644 --- a/src/lib/parseContent.ts +++ b/src/lib/parseContent.ts @@ -1,4 +1,4 @@ -import { nip19 } from "nostr-tools"; +import * as nip19 from "nostr-tools/nip19"; export const NEWLINE = "newline"; export const TEXT = "text"; diff --git a/src/lib/seed.ts b/src/lib/seed.ts index 3d58bcb5..43d717e7 100644 --- a/src/lib/seed.ts +++ b/src/lib/seed.ts @@ -7,7 +7,7 @@ export async function deriveNostrKey(entropy: ArrayBuffer) { import("@scure/bip39"), import("@scure/bip39/wordlists/english.js"), import("nostr-tools/nip06"), - import("nostr-tools"), + import("nostr-tools/pure"), ]); const ent = new Uint8Array(entropy).slice(0, 16); @@ -27,7 +27,7 @@ export async function autoUnlockNostr(userPubkey: string) { const { sk, pubkey } = await deriveNostrKey(entropy); if (pubkey !== userPubkey) return; - const { nip19 } = await import("nostr-tools"); + const nip19 = await import("nostr-tools/nip19"); const { bytesToHex } = await import("@noble/hashes/utils.js"); localStorage.setItem("nsec", nip19.nsecEncode(sk)); signer.set({ diff --git a/src/lib/walletEntropy.ts b/src/lib/walletEntropy.ts index 95b3e903..e203ed69 100644 --- a/src/lib/walletEntropy.ts +++ b/src/lib/walletEntropy.ts @@ -24,7 +24,10 @@ export async function tryDeriveFromNsec(): Promise { if (!nsec) return null; try { - const { nip19, finalizeEvent } = await import("nostr-tools"); + const [nip19, { finalizeEvent }] = await Promise.all([ + import("nostr-tools/nip19"), + import("nostr-tools/pure"), + ]); const sk = nip19.decode(nsec).data as Uint8Array; const signed = finalizeEvent({ ...DERIVATION_EVENT } as any, sk); return await hashSignature(signed.sig); -- cgit v1.2.3