From db59579a2efa8416f78c855faa7d7e62048447e5 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 24 Feb 2026 13:01:02 -0800 Subject: lint --- src/lib/ark.ts | 22 +++---- src/lib/crypto.ts | 15 +---- src/lib/nip07.ts | 164 ++++++++++++++++++++++++----------------------- src/lib/nip17.ts | 45 ++++++++++--- src/lib/nip44.ts | 4 +- src/lib/walletEntropy.ts | 3 +- 6 files changed, 135 insertions(+), 118 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ark.ts b/src/lib/ark.ts index a3939a40..82d1ccce 100644 --- a/src/lib/ark.ts +++ b/src/lib/ark.ts @@ -104,7 +104,11 @@ export const syncTransactions = async (aid: string) => { if (arkSending) return; const p = _syncTransactions(aid); syncPromise = p; - try { return await p; } finally { if (syncPromise === p) syncPromise = null; } + try { + return await p; + } finally { + if (syncPromise === p) syncPromise = null; + } }; export const vtxoKey = (v: { txid: string; vout: number }) => `${v.txid}:${v.vout}`; @@ -131,9 +135,7 @@ let syncPromise: Promise | null = null; const withTimeout = (promise: Promise, ms: number, label: string) => Promise.race([ promise, - new Promise((_, reject) => - setTimeout(() => reject(new Error(`${label} timed out`)), ms), - ), + new Promise((_, reject) => setTimeout(() => reject(new Error(`${label} timed out`)), ms)), ]); export const sendArk = async (address: string, amount: number) => { @@ -158,21 +160,13 @@ export const sendArk = async (address: string, amount: number) => { } let txid; try { - txid = await withTimeout( - wallet.sendBitcoin({ address, amount }), - 45_000, - "Ark send", - ); + txid = await withTimeout(wallet.sendBitcoin({ address, amount }), 45_000, "Ark send"); } catch (e: any) { if (e?.message?.includes("VTXO_ALREADY_REGISTERED")) { await wallet.settle(); const vtxos = await wallet.getVtxos({ spendableOnly: false }); if (vtxos?.length) addProcessedVtxos(vtxos.map(vtxoKey)); - txid = await withTimeout( - wallet.sendBitcoin({ address, amount }), - 45_000, - "Ark send retry", - ); + txid = await withTimeout(wallet.sendBitcoin({ address, amount }), 45_000, "Ark send retry"); } else { throw e; } diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts index d941d894..80a6364a 100644 --- a/src/lib/crypto.ts +++ b/src/lib/crypto.ts @@ -2,17 +2,11 @@ export function isPrfEncrypted(value: string): boolean { return value.startsWith("{"); } -async function importPrfKey( - prfKey: ArrayBuffer, - usages: KeyUsage[], -): Promise { +async function importPrfKey(prfKey: ArrayBuffer, usages: KeyUsage[]): Promise { return crypto.subtle.importKey("raw", prfKey, "AES-GCM", false, usages); } -export async function prfEncrypt( - prfKey: ArrayBuffer, - plaintext: Uint8Array, -): Promise { +export async function prfEncrypt(prfKey: ArrayBuffer, plaintext: Uint8Array): Promise { const key = await importPrfKey(prfKey, ["encrypt"]); const iv = crypto.getRandomValues(new Uint8Array(12)); const ciphertext = new Uint8Array( @@ -29,10 +23,7 @@ export async function prfEncrypt( }); } -export async function prfDecrypt( - prfKey: ArrayBuffer, - encrypted: string, -): Promise { +export async function prfDecrypt(prfKey: ArrayBuffer, encrypted: string): Promise { const { iv, ct } = JSON.parse(encrypted); const key = await importPrfKey(prfKey, ["decrypt"]); const ivBytes = fromBase64Url(iv); diff --git a/src/lib/nip07.ts b/src/lib/nip07.ts index a0af0861..093e2ead 100644 --- a/src/lib/nip07.ts +++ b/src/lib/nip07.ts @@ -1,102 +1,108 @@ -import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; -import { finalizeEvent } from 'nostr-tools/pure'; -import * as libnip44 from '$lib/nip44'; -import { u } from '$lib/nip44'; +import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; +import { finalizeEvent } from "nostr-tools/pure"; +import * as libnip44 from "$lib/nip44"; +import { u } from "$lib/nip44"; -import { eventToSign, signer } from '$lib/store'; -import { get } from 'svelte/store'; +import { eventToSign, signer } from "$lib/store"; +import { get } from "svelte/store"; // Ensures we have access to a secret key, triggering the signer modal if needed. // Returns the sk as Uint8Array, or null if using NIP-07 extension. export const ensureSigner = async (userPubkey: string): Promise => { - // Check if NIP-07 extension is available and matches user - if (window.nostr) { - try { - const extPubkey = await window.nostr.getPublicKey(); - if (extPubkey === userPubkey) { - return null; // Use NIP-07 - } - } catch (e) { - // Extension didn't work, fall through to signer - } + // Check if NIP-07 extension is available and matches user + if (window.nostr) { + try { + const extPubkey = await window.nostr.getPublicKey(); + if (extPubkey === userPubkey) { + return null; // Use NIP-07 + } + } catch (e) { + // Extension didn't work, fall through to signer } + } - // Check if signer already has a valid sk (64 hex chars = 32 bytes) - const currentSigner = get(signer); - if (currentSigner?.ready && currentSigner?.params?.sk && currentSigner.params.sk.length === 64) { - return hexToBytes(currentSigner.params.sk); - } + // Check if signer already has a valid sk (64 hex chars = 32 bytes) + const currentSigner = get(signer); + if (currentSigner?.ready && currentSigner?.params?.sk && currentSigner.params.sk.length === 64) { + return hexToBytes(currentSigner.params.sk); + } - // Clear invalid signer state before triggering modal - if (currentSigner?.ready && (!currentSigner?.params?.sk || currentSigner.params.sk.length !== 64)) { - signer.set(undefined); - } + // Clear invalid signer state before triggering modal + if ( + currentSigner?.ready && + (!currentSigner?.params?.sk || currentSigner.params.sk.length !== 64) + ) { + signer.set(undefined); + } - // Trigger the signer modal with a dummy event - const dummyEvent = { kind: 14, content: 'DM encryption', tags: [], created_at: Math.floor(Date.now() / 1000) }; - eventToSign.set(dummyEvent); + // Trigger the signer modal with a dummy event + const dummyEvent = { + kind: 14, + content: "DM encryption", + tags: [], + created_at: Math.floor(Date.now() / 1000), + }; + eventToSign.set(dummyEvent); - // Wait for signer to be ready - const signerValue = await new Promise((resolve, reject) => { - let unsubscribe: () => void; - unsubscribe = signer.subscribe((v) => { - if (v === 'cancel') { - setTimeout(() => unsubscribe?.()); - eventToSign.set(null); - reject(new Error('cancelled')); - } - if (v?.ready) { - setTimeout(() => unsubscribe?.()); - eventToSign.set(null); - resolve(v); - } - }); + // Wait for signer to be ready + const signerValue = await new Promise((resolve, reject) => { + let unsubscribe: () => void; + unsubscribe = signer.subscribe((v) => { + if (v === "cancel") { + setTimeout(() => unsubscribe?.()); + eventToSign.set(null); + reject(new Error("cancelled")); + } + if (v?.ready) { + setTimeout(() => unsubscribe?.()); + eventToSign.set(null); + resolve(v); + } }); + }); - if (signerValue?.params?.sk) { - return hexToBytes(signerValue.params.sk); - } + if (signerValue?.params?.sk) { + return hexToBytes(signerValue.params.sk); + } - // If extension method was selected - if (signerValue?.method === 'extension') { - return null; // Use NIP-07 - } + // If extension method was selected + if (signerValue?.method === "extension") { + return null; // Use NIP-07 + } - throw new Error('No signing method available'); -} + throw new Error("No signing method available"); +}; // Signs an event using NIP-07 if available, otherwise getPrivateKey() export const signEvent = async (event: any, user: any): Promise => { - const sk = await ensureSigner(user.pubkey); - if (sk === null) { - return (window as any).nostr.signEvent(event); - } else { - return finalizeEvent(event, sk); - } -} + const sk = await ensureSigner(user.pubkey); + if (sk === null) { + return (window as any).nostr.signEvent(event); + } else { + return finalizeEvent(event, sk); + } +}; // Encrypts an event in NIP-44 using NIP-07 if available, otherwise getPrivateKey() export const encrypt = async (json: any, user: any, receiverPK: string): Promise => { - const senderSK = await ensureSigner(user.pubkey); - if (senderSK === null) { - return (window as any).nostr.nip44.encrypt( - receiverPK, JSON.stringify(json)); - } else { - const senderSKString = bytesToHex(senderSK); - const ckey = u.getConversationKey(senderSKString, receiverPK); - return libnip44.encrypt(JSON.stringify(json), ckey); - } -} + const senderSK = await ensureSigner(user.pubkey); + if (senderSK === null) { + return (window as any).nostr.nip44.encrypt(receiverPK, JSON.stringify(json)); + } else { + const senderSKString = bytesToHex(senderSK); + const ckey = u.getConversationKey(senderSKString, receiverPK); + return libnip44.encrypt(JSON.stringify(json), ckey); + } +}; // Decrypts an event in NIP-44 using NIP-07 if available, otherwise getPrivateKey() export const decrypt = async (encrypted: string, user: any, receiverPK: string): Promise => { - const senderSK = await ensureSigner(user.pubkey); - if (senderSK === null) { - return JSON.parse(await (window as any).nostr.nip44.decrypt( - receiverPK, encrypted)); - } else { - const senderSKString = bytesToHex(senderSK); - const ckey = u.getConversationKey(senderSKString, receiverPK); - return JSON.parse(libnip44.decrypt(encrypted, ckey)); - } -} + const senderSK = await ensureSigner(user.pubkey); + if (senderSK === null) { + return JSON.parse(await (window as any).nostr.nip44.decrypt(receiverPK, encrypted)); + } else { + const senderSKString = bytesToHex(senderSK); + const ckey = u.getConversationKey(senderSKString, receiverPK); + return JSON.parse(libnip44.decrypt(encrypted, ckey)); + } +}; diff --git a/src/lib/nip17.ts b/src/lib/nip17.ts index 0398c426..97191a18 100644 --- a/src/lib/nip17.ts +++ b/src/lib/nip17.ts @@ -5,18 +5,18 @@ import { SimplePool } from "nostr-tools/pool"; import { Relay } from "nostr-tools/relay"; import { unwrapEvent } from "nostr-tools/nip17"; -import { ensureSigner } from '$lib/nip07'; -import { relaysSupporting } from '$lib/nip11'; -import { expired, expiration } from '$lib/nip40'; -import { encrypt, u } from '$lib/nip44'; +import { ensureSigner } from "$lib/nip07"; +import { relaysSupporting } from "$lib/nip11"; +import { expired, expiration } from "$lib/nip40"; +import { encrypt, u } from "$lib/nip44"; const TWO_DAYS = 2 * 24 * 60 * 60; const randomTimestamp = () => Math.floor(Date.now() / 1000 - Math.random() * TWO_DAYS); const pool = new SimplePool(); let relayListCache = new Map(); -import { PUBLIC_DM_RELAYS } from '$env/static/public'; -const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(','); +import { PUBLIC_DM_RELAYS } from "$env/static/public"; +const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(","); const DM_FETCH_LIMIT = 65536; // Create a NIP-17 message using a provided sender secret key. @@ -283,7 +283,14 @@ const publishToPreferred = async ( } }; -const createAndPublishMessageEvent = async (sk: Uint8Array | null, message: string, userPK: string, recipientPK: string, eventFor: string, expiryDays?: number) => { +const createAndPublishMessageEvent = async ( + sk: Uint8Array | null, + message: string, + userPK: string, + recipientPK: string, + eventFor: string, + expiryDays?: number, +) => { let event; if (sk === null) { event = await createNIP17MessageNIP07(message, userPK, recipientPK, eventFor, expiryDays); @@ -303,12 +310,30 @@ export const send = async (message: string, user: any, recipient: any, expiryDay if (user.pubkey === recipient.pubkey) { return createAndPublishMessageEvent( - sk, message, user.pubkey, recipient.pubkey, user.pubkey, expiryDays); + sk, + message, + user.pubkey, + recipient.pubkey, + user.pubkey, + expiryDays, + ); } else { const p1 = createAndPublishMessageEvent( - sk, message, user.pubkey, recipient.pubkey, recipient.pubkey, expiryDays); + sk, + message, + user.pubkey, + recipient.pubkey, + recipient.pubkey, + expiryDays, + ); const p2 = createAndPublishMessageEvent( - sk, message, user.pubkey, recipient.pubkey, user.pubkey, expiryDays); + sk, + message, + user.pubkey, + recipient.pubkey, + user.pubkey, + expiryDays, + ); return Promise.all([p1, p2]); } }; diff --git a/src/lib/nip44.ts b/src/lib/nip44.ts index 6025a54f..19384b9b 100644 --- a/src/lib/nip44.ts +++ b/src/lib/nip44.ts @@ -24,7 +24,9 @@ export const u = { }, getConversationKey(privkeyA: string, pubkeyB: string): Uint8Array { - const sharedX = secp256k1.getSharedSecret(hexToBytes(privkeyA), hexToBytes("02" + pubkeyB)).subarray(1, 33); + const sharedX = secp256k1 + .getSharedSecret(hexToBytes(privkeyA), hexToBytes("02" + pubkeyB)) + .subarray(1, 33); return hkdf_extract(sha256, sharedX, utf8ToBytes("nip44-v2")); }, diff --git a/src/lib/walletEntropy.ts b/src/lib/walletEntropy.ts index f022a2cc..25bd49b8 100644 --- a/src/lib/walletEntropy.ts +++ b/src/lib/walletEntropy.ts @@ -10,8 +10,7 @@ const DERIVATION_EVENT = { async function hashSignature(sig: string): Promise { const sigBytes = new Uint8Array(sig.length / 2); - for (let i = 0; i < sig.length; i += 2) - sigBytes[i / 2] = parseInt(sig.slice(i, i + 2), 16); + for (let i = 0; i < sig.length; i += 2) sigBytes[i / 2] = parseInt(sig.slice(i, i + 2), 16); return crypto.subtle.digest("SHA-256", sigBytes); } -- cgit v1.2.3