diff options
| author | Adam Soltys <[email protected]> | 2026-02-11 17:09:39 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-02-11 17:09:39 -0800 |
| commit | 3aa9ce1b5985397d7f568887ec6f881df13c1034 (patch) | |
| tree | 2c459692dc5315e92924de6be9f0999a835e0f54 /src | |
| parent | 8a4b0087cbfe8b43d9b43d19af6d991a646ef3d7 (diff) | |
| download | coinos-ui-3aa9ce1b5985397d7f568887ec6f881df13c1034.tar.gz coinos-ui-3aa9ce1b5985397d7f568887ec6f881df13c1034.zip | |
fix ts errors
Diffstat (limited to 'src')
60 files changed, 513 insertions, 485 deletions
diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 00000000..3673ad85 --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,26 @@ +/// <reference types="@sveltejs/kit" /> + +declare const grecaptcha: { + ready(callback: () => void): void; + execute(siteKey: string, options: { action: string }): Promise<string>; +}; + +declare class NDEFReader { + constructor(); + scan(): Promise<void>; + write(data: any): Promise<void>; + addEventListener(type: string, listener: (event: any) => void): void; + removeEventListener(type: string, listener: (event: any) => void): void; +} + +interface Window { + nostr?: { + getPublicKey(): Promise<string>; + signEvent(event: any): Promise<any>; + nip04?: { + encrypt(pubkey: string, plaintext: string): Promise<string>; + decrypt(pubkey: string, ciphertext: string): Promise<string>; + }; + }; + maplibregl?: any; +} diff --git a/src/components/Account.svelte b/src/components/Account.svelte index 0eaf6dfb..d05addbe 100644 --- a/src/components/Account.svelte +++ b/src/components/Account.svelte @@ -13,7 +13,7 @@ forgetWalletPassword, } from "$lib/passwordCache"; - let { user, rate, account } = $props(); + let { user, rate, account }: any = $props(); let { name, seed, @@ -27,8 +27,8 @@ let arkBalance = $state(0); let arkLoading = $state(false); let passwordPrompt = $state(false); - let password = $state(); - let pendingUrl = $state(); + let password: string | undefined = $state(); + let pendingUrl: string | undefined = $state(); let cancel = $state(() => { passwordPrompt = false; pendingUrl = undefined; @@ -41,7 +41,7 @@ const { decrypt } = await import("nostr-tools/nip49"); if (seed) { // Legacy: per-account seed is raw hex key - $arkkey = hex.encode(decrypt(seed, cached)); + $arkkey = hex.encode(decrypt(seed, cached) as Uint8Array); } else if (user.seed) { // Master seed: derive m/86'/0'/0'/0/0 const [ @@ -58,7 +58,7 @@ let s = await mnemonicToSeed(mnemonic, cached); let master = HDKey.fromMasterSeed(s, versions); let arkChild = master.derive("m/86'/0'/0'/0/0"); - $arkkey = bytesToHex(arkChild.privateKey); + $arkkey = bytesToHex(arkChild.privateKey!); } else { return false; } @@ -76,9 +76,9 @@ if (isArk) { pendingUrl = url; if ($arkkey) { - goto(pendingUrl); + goto(pendingUrl!); } else if (await tryUnlockArk()) { - goto(pendingUrl); + goto(pendingUrl!); } else { passwordPrompt = true; } @@ -91,7 +91,7 @@ let submitPassword = async () => { const { decrypt } = await import("nostr-tools/nip49"); if (seed) { - $arkkey = hex.encode(decrypt(seed, password)); + $arkkey = hex.encode(decrypt(seed, password!) as Uint8Array); } else if (user.seed) { const [ { HDKey }, @@ -102,12 +102,12 @@ import("@scure/bip39"), import("@scure/bip39/wordlists/english.js"), ]); - let entropy = await decrypt(user.seed, password); + let entropy = await decrypt(user.seed, password!); let mnemonic = entropyToMnemonic(entropy, wordlist); - let s = await mnemonicToSeed(mnemonic, password); + let s = await mnemonicToSeed(mnemonic, password!); let master = HDKey.fromMasterSeed(s, versions); let arkChild = master.derive("m/86'/0'/0'/0/0"); - $arkkey = bytesToHex(arkChild.privateKey); + $arkkey = bytesToHex(arkChild.privateKey!); } passwordPrompt = false; if (pendingUrl) { diff --git a/src/components/Amount.svelte b/src/components/Amount.svelte index 4c7c487a..2587520a 100644 --- a/src/components/Amount.svelte +++ b/src/components/Amount.svelte @@ -2,14 +2,14 @@ import { copy, s, f, toFiat } from "$lib/utils"; import { fiat } from "$lib/store"; const { - align, + align = "", amount, - locale, - tip, + locale = undefined, + tip = undefined, rate, currency, locked = false, - } = $props(); + }: any = $props(); const icon = $derived(locked ? "ph:lock-fill" : "ph:lightning-fill"); const canShowFiat = $derived($fiat && rate && currency); diff --git a/src/components/AmountField.svelte b/src/components/AmountField.svelte index 36e7d4a6..21c36631 100644 --- a/src/components/AmountField.svelte +++ b/src/components/AmountField.svelte @@ -6,12 +6,15 @@ let { amount = $bindable(), none = $t("accounts.none"), - desc, + desc = "", currency, rate, - label, - name, - } = $props(); + label = "", + name = "", + locale = undefined, + submit = undefined, + element = undefined, + }: any = $props(); let setting = $state(); let set = () => { diff --git a/src/components/AppForm.svelte b/src/components/AppForm.svelte index ec33390a..026e4aba 100644 --- a/src/components/AppForm.svelte +++ b/src/components/AppForm.svelte @@ -42,7 +42,7 @@ let lud16 = $derived(`${user.username}@${$page.url.host}`); - let el = $state(); + let el: HTMLFormElement | undefined = $state(); let submit = async (e) => { e.preventDefault(); let body = new FormData(el); @@ -65,7 +65,7 @@ try { await post(`/post/apps/delete`, { pubkey }); goto("/settings/nostr"); - } catch (e) { + } catch (e: any) { fail(e.message); } }; diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte index 0ab48706..f45f4d0c 100644 --- a/src/components/AppHeader.svelte +++ b/src/components/AppHeader.svelte @@ -8,12 +8,12 @@ let { user, subject = $bindable() } = $props(); - let w = $state(); + let w: number | undefined = $state(); $effect(() => (subject = subject || user)); let bg = $derived( - $banner?.id && $banner.id === subject?.id - ? `url(${$banner.src})` + ($banner as any)?.id && ($banner as any).id === subject?.id + ? `url(${($banner as any).src})` : subject?.banner ? subject.banner.includes(":") ? `url(${subject.banner})` @@ -71,10 +71,10 @@ > <nav class="flex justify-end items-center space-x-4 p-5"> {#if user} - {#each links as { href, icon, flip, label }} + {#each links as { href, icon, label }} <a {href} data-sveltekit-preload-code="eager" aria-label={label}> <button class="btn-menu {opacity(href)}" aria-label={label}> - <iconify-icon noobserver {icon} width={w > 640 ? 32 : 24} {flip} + <iconify-icon noobserver {icon} width={(w ?? 0) > 640 ? 32 : 24} ></iconify-icon> </button> </a> diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte index 438008b8..ca35fb35 100644 --- a/src/components/Avatar.svelte +++ b/src/components/Avatar.svelte @@ -6,9 +6,10 @@ user: any; size?: number; disabled?: boolean; + class?: string; } - let { user, size = 32, disabled = false }: Props = $props(); + let { user, size = 32, disabled = false, class: className = "" }: Props = $props(); let s = $derived(size.toString()); let link = $derived( @@ -22,7 +23,7 @@ let fallback = $derived( `${base}/punks/` + punk(user?.pubkey || user?.id || "aa"), ); - let tmp = $derived($avatar?.id && $avatar.id === user?.id && $avatar.src); + let tmp = $derived(($avatar as any)?.id && ($avatar as any).id === user?.id && ($avatar as any).src); let src = $derived(tmp || profile || fallback); </script> diff --git a/src/components/Balance.svelte b/src/components/Balance.svelte index 5d1bfd7b..b05d9ac5 100644 --- a/src/components/Balance.svelte +++ b/src/components/Balance.svelte @@ -17,7 +17,7 @@ </script> {#if show && user.haspin && $pin?.length !== 6} - <Pin cancel={() => (show = false)} /> + <Pin cancel={() => { show = false; return ""; }} /> {/if} <div> diff --git a/src/components/Event.svelte b/src/components/Event.svelte index 8faba04d..3ecf00fc 100644 --- a/src/components/Event.svelte +++ b/src/components/Event.svelte @@ -9,7 +9,7 @@ import { page } from "$app/stores"; let amount = 21; - let { event, minimal, last = true, user } = $props(); + let { event, minimal = false, last = true, user = undefined }: any = $props(); let { author, parts, zaps, names, created_at, pubkey } = $derived(event); let { id } = event; @@ -25,7 +25,7 @@ event: await sign(request), }); await post("/post/payments", { amount, payreq }); - } catch (e) { + } catch (e: any) { console.log(e); fail(e.message); } diff --git a/src/components/InvoiceData.svelte b/src/components/InvoiceData.svelte index 3be12215..51f7b396 100644 --- a/src/components/InvoiceData.svelte +++ b/src/components/InvoiceData.svelte @@ -14,8 +14,9 @@ locale, tip, rate, + align = "", t, - } = $props(); + }: any = $props(); let loaded = $state(false); let { memo } = $derived(invoice); diff --git a/src/components/ItemForm.svelte b/src/components/ItemForm.svelte index 77437c1f..d087e2bf 100644 --- a/src/components/ItemForm.svelte +++ b/src/components/ItemForm.svelte @@ -8,21 +8,21 @@ import Spinner from "$comp/Spinner.svelte"; let { item = $bindable(), user } = $props(); - let fileInput = $state(), formElement = $state(), file, submitting = $state(), progress; - let select = () => fileInput.click(); - let src = $state(); + let fileInput: HTMLInputElement | undefined = $state(), formElement: HTMLFormElement | undefined = $state(), file: File, submitting = $state(), progress: any; + let select = () => fileInput!.click(); + let src: string | undefined = $state(); - let tooLarge = {}; - let handleFile = async ({ target }, type) => { + let tooLarge: Record<string, boolean> = {}; + let handleFile = async ({ target }: { target: EventTarget | null }, type: string) => { tooLarge[type] = false; - file = target.files[0]; + file = (target as HTMLInputElement).files![0]; if (!file) return; if (file.size > 10000000) return (tooLarge[type] = true); var reader = new FileReader(); reader.onload = async (e) => { - src = e.target.result; + src = (e.target as FileReader).result as string; }; reader.readAsDataURL(file); @@ -31,11 +31,11 @@ async function handleSubmit() { try { submitting = true; - let data = new FormData(formElement); + let data = new FormData(formElement!); if (src) { try { - let { hash } = JSON.parse(await upload(file, "item", progress)); + let { hash } = JSON.parse(await upload(file, "item", progress) as string); data.set("image", hash); @@ -48,7 +48,7 @@ } } - const response = await fetch(formElement.action, { + const response = await fetch(formElement!.action, { method: "POST", body: data, }); diff --git a/src/components/LandingHeader.svelte b/src/components/LandingHeader.svelte index 603795ab..1a2af208 100644 --- a/src/components/LandingHeader.svelte +++ b/src/components/LandingHeader.svelte @@ -7,7 +7,7 @@ import DarkToggle from "$comp/DarkToggle.svelte"; import LocaleSelector from "$comp/LocaleSelector.svelte"; - let { howItWorks, faq, about, user } = $props(); + let { howItWorks = undefined, faq = undefined, about = undefined, user = undefined }: any = $props(); let showMobileMenu = $state(false); let header = $state(); diff --git a/src/components/Lnurlw.svelte b/src/components/Lnurlw.svelte index 784e8468..ac79b101 100644 --- a/src/components/Lnurlw.svelte +++ b/src/components/Lnurlw.svelte @@ -1,7 +1,7 @@ <script lang="ts"> import { tick } from "svelte"; import handler from "$lib/handler"; - import { sats, f, s } from "$lib/utils"; + import { sats, f, s, focus } from "$lib/utils"; import { t } from "$lib/translations"; import { enhance } from "$app/forms"; import Numpad from "$comp/Numpad.svelte"; @@ -23,8 +23,8 @@ let amount = $state(Math.round(minWithdrawable / 1000)); let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2))); - let submit = $state(); - let submitting = $state(); + let submit: HTMLButtonElement | undefined = $state(); + let submitting: boolean = $state(false); let toggle = () => (submitting = !submitting); let setMax = async (e) => { @@ -70,7 +70,6 @@ use:enhance={handler(toggle)} action="?/withdraw" method="POST" - onsubmit={submit} class="space-y-5" > <input name="amount" value={amount} type="hidden" /> diff --git a/src/components/LocaleSelector.svelte b/src/components/LocaleSelector.svelte index e6fbdec8..6511eccd 100644 --- a/src/components/LocaleSelector.svelte +++ b/src/components/LocaleSelector.svelte @@ -2,7 +2,7 @@ import { run } from "svelte/legacy"; import { t, locale, locales } from "$lib/translations"; - let { style } = $props(); + let { style = "" }: any = $props(); let l = $state($locale); const handleChange = ({ currentTarget }) => { diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte index 3abdfcc4..26f32ee8 100644 --- a/src/components/LocationsMap.svelte +++ b/src/components/LocationsMap.svelte @@ -5,15 +5,15 @@ import { back } from "$lib/utils"; let { locations } = $props(); - let map; - let mapContainer = $state(), - mapWrapper = $state(); - let markers = []; - let search = $state(); - let clearSearch = (e) => (search = ""); + let map: any; + let mapContainer: any = $state(), + mapWrapper: any = $state(); + let markers: any[] = []; + let search: string = $state(""); + let clearSearch = (e: any) => (search = ""); let currentIndex = -1; - let timeout = $state(); + let timeout: any = $state(); let full = () => { if (!document.fullscreenElement) { @@ -32,17 +32,18 @@ map.resize(); } else { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.mozCancelFullScreen) { + let doc = document as any; + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else if (doc.mozCancelFullScreen) { /* Firefox */ - document.mozCancelFullScreen(); - } else if (document.webkitExitFullscreen) { + doc.mozCancelFullScreen(); + } else if (doc.webkitExitFullscreen) { /* Chrome, Safari and Opera */ - document.webkitExitFullscreen(); - } else if (document.msExitFullscreen) { + doc.webkitExitFullscreen(); + } else if (doc.msExitFullscreen) { /* IE/Edge */ - document.msExitFullscreen(); + doc.msExitFullscreen(); } } }; @@ -58,7 +59,7 @@ }; let selected = $state(); - function select(m) { + function select(m: any) { selected = m; stopFlying(); currentIndex = inview.indexOf(m); @@ -114,11 +115,11 @@ timeout = setTimeout(startFlying, 4000); } - function debounce(func, delay) { - let timeout; + function debounce(func: any, delay: any) { + let timeout: any; let immediate = true; - return function (...args) { + return function (this: any, ...args: any[]) { const context = this; if (immediate) { @@ -137,7 +138,8 @@ function stopFlying() { updateLabelVisibility(); if (!timeout) return; - timeout = clearTimeout(timeout); + clearTimeout(timeout); + timeout = undefined; if (currentPopup) { currentPopup.remove(); @@ -147,7 +149,7 @@ map.off("moveend"); } - let inview = $state([]); + let inview: any[] = $state([]); let updateLabelVisibility = debounce(() => { inview = []; @@ -167,20 +169,20 @@ inview = inview.sort((a, b) => a.tags.name.localeCompare(b.tags.name)); }, 200); - let locationMarkers = {}; - let popups = {}; + let locationMarkers: any = {}; + let popups: any = {}; let counter = 0; - let maplibrePromise; + let maplibrePromise: any; const loadMaplibre = async () => { - if (window.maplibregl) return window.maplibregl; + if ((window as any).maplibregl) return (window as any).maplibregl; if (maplibrePromise) return maplibrePromise; maplibrePromise = new Promise((resolve, reject) => { const existing = document.querySelector("script[data-maplibre]"); if (existing) { - if (window.maplibregl) return resolve(window.maplibregl); - existing.addEventListener("load", () => resolve(window.maplibregl)); + if ((window as any).maplibregl) return resolve((window as any).maplibregl); + existing.addEventListener("load", () => resolve((window as any).maplibregl)); existing.addEventListener("error", reject); return; } @@ -197,7 +199,7 @@ script.async = true; script.defer = true; script.dataset.maplibre = "true"; - script.onload = () => resolve(window.maplibregl); + script.onload = () => resolve((window as any).maplibregl); script.onerror = reject; document.head.appendChild(script); }); diff --git a/src/components/Nostr.svelte b/src/components/Nostr.svelte index 8718d4eb..e7fd0e58 100644 --- a/src/components/Nostr.svelte +++ b/src/components/Nostr.svelte @@ -10,11 +10,11 @@ import { nostrConnectRelay } from "$lib/nostr"; import Success from "$comp/Success.svelte"; - let { id } = $props(); + let { id = undefined }: any = $props(); let extensionAvailable = $derived(browser && window.nostr); let cancel = () => { - eventToSign.set(); + eventToSign.set(undefined); showNsec = false; connectUrl = undefined; $signer = "cancel"; @@ -29,7 +29,7 @@ let hadSigner = $state(!!$signer); - let connectUrl = $state(); + let connectUrl: string | undefined = $state(); let nostrConnect = async () => { const { Relay } = await import("nostr-tools/relay"); const { nip04, generateSecretKey, getPublicKey } = await import( @@ -76,7 +76,7 @@ }); }; - let nsec = $state(); + let nsec: string = $state(""); let showNsec = $state(); let toggleNsec = () => { $signer = { @@ -86,7 +86,7 @@ let nsecSign = async () => { const { nip19, getPublicKey } = await import("nostr-tools"); - let sk; + let sk: Uint8Array; if (nsec.startsWith("nsec")) sk = nip19.decode(nsec).data as Uint8Array; else sk = hexToBytes(nsec); @@ -108,13 +108,13 @@ const signerSigned = async () => { await new Promise((r) => setTimeout(r, 100)); let sig = await navigator.clipboard.readText(); - $signer.params.sig = sig; - $signer.ready = true; + ($signer as any).params.sig = sig; + ($signer as any).ready = true; $signer = $signer; }; let signUrl = $derived( - `nostrsigner:${encodeURIComponent(JSON.stringify($eventToSign))}?compressionType=none&returnType=signature&type=sign_event&appName=Coinos`, + `nostrsigner:${encodeURIComponent(JSON.stringify($eventToSign))}?compressionType=none&returnType=signature&type=sign_event&appName=Coinos` as string, ); </script> @@ -127,7 +127,7 @@ > <h1 class="text-center text-2xl font-semibold">Nostr sign</h1> - {#if $eventToSign.sig && !hadSigner} + {#if ($eventToSign as any).sig && !hadSigner} <Success /> {:else} {#if connectUrl} @@ -150,7 +150,7 @@ ></iconify-icon> {$t("payments.openLink")}</a > - <button class="btn" onclick={() => copy(connectUrl)}> + <button class="btn" onclick={() => copy(connectUrl!)}> <iconify-icon noobserver icon="ph:copy-bold" width="32" ></iconify-icon> {$t("payments.copy")}</button diff --git a/src/components/Numpad.svelte b/src/components/Numpad.svelte index 664010e1..6a9f3c6e 100644 --- a/src/components/Numpad.svelte +++ b/src/components/Numpad.svelte @@ -10,11 +10,11 @@ amount = $bindable(), currency = "USD", fiat = $bindable(), - element, + element = $bindable(), rate = $bindable(), - locale, - submit = undefined, - amountFiat = 0, + locale = undefined, + submit = $bindable(undefined), + amountFiat = $bindable(0), } = $props(); // ---- Local state ---- @@ -26,7 +26,7 @@ let symbol = $state(""); let position = $state("before"); - function getCurrencyInfo(locale = "en-US", currency) { + function getCurrencyInfo(locale: any = "en-US", currency: string) { const l = typeof locale === "function" ? locale() : locale || "en-US"; const region = l.length >= 2 ? l.slice(-2) : ""; const currencyDisplay = @@ -39,7 +39,7 @@ maximumFractionDigits: 2, }); const parts = formatter.formatToParts(123456.78); - const { value: decimal } = parts.find((p) => p.type === "decimal"); + const { value: decimal } = parts.find((p) => p.type === "decimal")!; const currencyPart = parts.find((p) => p.type === "currency"); const sym = currencyPart ? currencyPart.value : ""; const firstNumberIndex = parts.findIndex((p) => p.type === "integer"); @@ -77,14 +77,14 @@ if (fiat) { const numericFiat = parseFloat((fiatDigits || "0").replace(/\D/g, "")) / 100; - amountFiat = isFinite(numericFiat) ? numericFiat.toFixed(2) : "0.00"; + amountFiat = isFinite(numericFiat) ? numericFiat.toFixed(2) : "0.00" as any; amount = numericFiat ? Math.round((numericFiat * sats) / rate) : 0; } else { // integer-only sats, already normalized const a = parseInt((html || "0").replace(/[^\d]/g, "")) || 0; amount = a || 0; const fval = amount ? (amount * rate) / sats : 0; - amountFiat = fval ? fval.toFixed(2) : "0.00"; + amountFiat = fval ? fval.toFixed(2) : "0.00" as any; } }; @@ -149,17 +149,17 @@ if (!node) return; const range = document.createRange(); const sel = getSelection(); - const L = node.length ?? node.textContent?.length ?? 0; + const L = (node as any).length ?? node.textContent?.length ?? 0; range.setStart(node, L); range.setEnd(node, L); - sel.removeAllRanges(); - sel.addRange(range); + sel?.removeAllRanges(); + sel?.addRange(range); }); } prevHtml = html.toString(); }; - const handleInput = (value) => { + const handleInput = (value: string) => { if (fiat) { if (value === arrow) { fiatDigits = fiatDigits.length > 1 ? fiatDigits.slice(0, -1) : "0"; @@ -187,12 +187,12 @@ input(null, true); }; - const select = (e) => { + const select = (e: any) => { const range = document.createRange(); range.selectNodeContents(e.target); const sel = getSelection(); - sel.removeAllRanges(); - sel.addRange(range); + sel?.removeAllRanges(); + sel?.addRange(range); }; const blur = () => { @@ -211,7 +211,7 @@ element && (element.innerHTML = html); } else { // going -> fiat - const cents = Math.round((parseFloat(amountFiat || "0") || 0) * 100); + const cents = Math.round((parseFloat(String(amountFiat) || "0") || 0) * 100); fiatDigits = Math.max(0, cents).toString(); fiat = true; html = formatFiatFromDigits(fiatDigits, decimalChar); @@ -226,11 +226,11 @@ if (!node) return; const range = document.createRange(); const sel = getSelection(); - const L = node.length ?? node.textContent?.length ?? 0; + const L = (node as any).length ?? node.textContent?.length ?? 0; range.setStart(node, L); range.setEnd(node, L); - sel.removeAllRanges(); - sel.addRange(range); + sel?.removeAllRanges(); + sel?.addRange(range); }); $fiatStore = fiat; @@ -255,7 +255,7 @@ onMount(() => { fiat = $fiatStore; if (fiat) { - const cents = Math.round((parseFloat(amountFiat || "0") || 0) * 100); + const cents = Math.round((parseFloat(String(amountFiat) || "0") || 0) * 100); fiatDigits = Math.max(0, cents).toString(); html = formatFiatFromDigits(fiatDigits, decimalChar); // keep html in sync on mount } else { diff --git a/src/components/Password.svelte b/src/components/Password.svelte index cc91d554..02d65948 100644 --- a/src/components/Password.svelte +++ b/src/components/Password.svelte @@ -6,7 +6,7 @@ import { password as pw, passwordPrompt } from "$lib/store"; let { user } = $props(); - let password = $state(); + let password: string | undefined = $state(); let cancel = () => ($passwordPrompt = false); diff --git a/src/components/Payments.svelte b/src/components/Payments.svelte index 4d6f1da1..ff3f0d19 100644 --- a/src/components/Payments.svelte +++ b/src/components/Payments.svelte @@ -6,7 +6,7 @@ import { t } from "$lib/translations"; import locales from "$lib/locales"; import { fiat } from "$lib/store"; - const { fund, locale, user, payments } = $props(); + const { fund = undefined, locale, user, payments }: any = $props(); const language = $derived(user?.language || "en"); </script> diff --git a/src/components/Qr.svelte b/src/components/Qr.svelte index 6a34ee7c..37b1708c 100644 --- a/src/components/Qr.svelte +++ b/src/components/Qr.svelte @@ -1,7 +1,7 @@ <script lang="ts"> import { onMount } from "svelte"; import { browser } from "$app/environment"; - let { icon, text } = $props(); + let { icon = "", text }: any = $props(); let qr = $state(); let screenfull; diff --git a/src/components/SetAmount.svelte b/src/components/SetAmount.svelte index a28f207a..8a1573bd 100644 --- a/src/components/SetAmount.svelte +++ b/src/components/SetAmount.svelte @@ -14,8 +14,9 @@ setAmount, newAmount = $bindable(0), toggleAmount, + element = undefined, t, - } = $props(); + }: any = $props(); </script> {#if settingAmount} diff --git a/src/components/SetType.svelte b/src/components/SetType.svelte index ffc4cca8..4734cb07 100644 --- a/src/components/SetType.svelte +++ b/src/components/SetType.svelte @@ -11,8 +11,9 @@ setAmount, setType, toggleType, + activeOnly = false, t, - } = $props(); + }: any = $props(); </script> diff --git a/src/components/Success.svelte b/src/components/Success.svelte index 20557f9f..6a0e8eae 100644 --- a/src/components/Success.svelte +++ b/src/components/Success.svelte @@ -2,9 +2,9 @@ import { browser } from "$app/environment"; import { scale } from "svelte/transition"; import Amount from "$comp/Amount.svelte"; - const { amount, tip, rate, currency, locale, title } = $props(); + const { amount, tip = undefined, rate, currency, locale, title = "" }: any = $props(); - let ConfettiComp = $state(null); + let ConfettiComp: any = $state(null); let loaded = $state(false); $effect(() => { if (browser) @@ -13,10 +13,12 @@ }); }); - $effect(async () => { + $effect(() => { if (!browser || !loaded || ConfettiComp) return; - const mod = await import("svelte-confetti"); - ConfettiComp = mod.Confetti; + (async () => { + const mod = await import("svelte-confetti"); + ConfettiComp = mod.Confetti; + })(); }); </script> diff --git a/src/components/WalletPass.svelte b/src/components/WalletPass.svelte index e7a3c7f9..f6d611d0 100644 --- a/src/components/WalletPass.svelte +++ b/src/components/WalletPass.svelte @@ -9,7 +9,7 @@ rememberWalletPassword, forgetWalletPassword, } from "$lib/passwordCache"; - let { cancel, password = $bindable(), submit } = $props(); + let { cancel = $bindable(), password = $bindable(), submit } = $props(); let revealPassword = $state(); let rememberForMs = $state(defaultRememberForMs); @@ -75,7 +75,7 @@ id="rememberFor" class="w-full" value={rememberForMs} - onchange={(e) => (rememberForMs = Number(e.target.value))} + onchange={(e) => (rememberForMs = Number((e.target as HTMLSelectElement).value))} > {#each rememberForOptions as option} <option value={option.ms}>{option.label}</option> diff --git a/src/lib/locales.ts b/src/lib/locales.ts index 68a28abd..282eac22 100644 --- a/src/lib/locales.ts +++ b/src/lib/locales.ts @@ -1,22 +1,22 @@ -import de from "date-fns/locale/de"; -import el from "date-fns/locale/el"; -import en from "date-fns/locale/en-US"; -import es from "date-fns/locale/es"; -import fa from "date-fns/locale/fa-IR"; -import fr from "date-fns/locale/fr"; -import ja from "date-fns/locale/ja"; -import pt from "date-fns/locale/pt"; -import ru from "date-fns/locale/ru"; -import zh from "date-fns/locale/zh-CN"; -import ar from "date-fns/locale/ar-SA"; -import hi from "date-fns/locale/hi"; -import bn from "date-fns/locale/bn"; -import tr from "date-fns/locale/tr"; -import ko from "date-fns/locale/ko"; -import it from "date-fns/locale/it"; -import nl from "date-fns/locale/nl"; -import th from "date-fns/locale/th"; -import pl from "date-fns/locale/pl"; +import { de } from "date-fns/locale/de"; +import { el } from "date-fns/locale/el"; +import { enUS as en } from "date-fns/locale/en-US"; +import { es } from "date-fns/locale/es"; +import { faIR as fa } from "date-fns/locale/fa-IR"; +import { fr } from "date-fns/locale/fr"; +import { ja } from "date-fns/locale/ja"; +import { pt } from "date-fns/locale/pt"; +import { ru } from "date-fns/locale/ru"; +import { zhCN as zh } from "date-fns/locale/zh-CN"; +import { arSA as ar } from "date-fns/locale/ar-SA"; +import { hi } from "date-fns/locale/hi"; +import { bn } from "date-fns/locale/bn"; +import { tr } from "date-fns/locale/tr"; +import { ko } from "date-fns/locale/ko"; +import { it } from "date-fns/locale/it"; +import { nl } from "date-fns/locale/nl"; +import { th } from "date-fns/locale/th"; +import { pl } from "date-fns/locale/pl"; export default { de, diff --git a/src/lib/nip07.ts b/src/lib/nip07.ts index 4c2048e2..85f68377 100644 --- a/src/lib/nip07.ts +++ b/src/lib/nip07.ts @@ -1,27 +1,26 @@ import { bytesToHex } from '@noble/hashes/utils.js'; import { finalizeEvent } from 'nostr-tools/pure'; -import { unwrapEvent } from 'nostr-tools/nip17'; import { getPrivateKey } from '$lib/nostr'; import * as libnip44 from '$lib/nip44'; import { u } from '$lib/nip44'; // Signs an event using NIP-07 if available, otherwise getPrivateKey() -export const signEvent = async (event: object, user: object): object => { - if (await window.nostr.getPublicKey() === user.pubkey) { - return window.nostr.signEvent(event); +export const signEvent = async (event: any, user: any): Promise<any> => { + if (await (window as any).nostr.getPublicKey() === user.pubkey) { + return (window as any).nostr.signEvent(event); } else { - const sk = await getPrivateKey(); + const sk = await getPrivateKey(user); return finalizeEvent(event, sk); } } // Encrypts an event in NIP-44 using NIP-07 if available, otherwise getPrivateKey() -export const encrypt = async (json: object, user: object, receiverPK: string): string => { - if (await window.nostr.getPublicKey() === user.pubkey) { - return window.nostr.nip44.encrypt( +export const encrypt = async (json: any, user: any, receiverPK: string): Promise<string> => { + if (await (window as any).nostr.getPublicKey() === user.pubkey) { + return (window as any).nostr.nip44.encrypt( receiverPK, JSON.stringify(json)); } else { - const senderSK = await getPrivateKey(); + const senderSK = await getPrivateKey(user); const senderSKString = bytesToHex(senderSK); const ckey = u.getConversationKey(senderSKString, receiverPK); return libnip44.encrypt(JSON.stringify(json), ckey); @@ -29,12 +28,12 @@ export const encrypt = async (json: object, user: object, receiverPK: string): s } // Decrypts an event in NIP-44 using NIP-07 if available, otherwise getPrivateKey() -export const decrypt = async (encrypted: string, user: object, receiverPK: string): object => { - if (await window.nostr.getPublicKey() === user.pubkey) { - return JSON.parse(await window.nostr.nip44.decrypt( +export const decrypt = async (encrypted: string, user: any, receiverPK: string): Promise<any> => { + if (await (window as any).nostr.getPublicKey() === user.pubkey) { + return JSON.parse(await (window as any).nostr.nip44.decrypt( receiverPK, encrypted)); } else { - const senderSK = await getPrivateKey(); + const senderSK = await getPrivateKey(user); 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 d7ce181d..b039ebf8 100644 --- a/src/lib/nip17.ts +++ b/src/lib/nip17.ts @@ -25,9 +25,9 @@ const DM_FETCH_LIMIT = 256; // Returns the sk as Uint8Array, or null if using NIP-07 extension. const ensureSigner = async (userPubkey: string): Promise<Uint8Array | null> => { // Check if NIP-07 extension is available and matches user - if (window.nostr) { + if ((window as any).nostr) { try { - const extPubkey = await window.nostr.getPublicKey(); + const extPubkey = await (window as any).nostr.getPublicKey(); if (extPubkey === userPubkey) { return null; // Use NIP-07 } @@ -37,7 +37,7 @@ const ensureSigner = async (userPubkey: string): Promise<Uint8Array | null> => { } // Check if signer already has a valid sk (64 hex chars = 32 bytes) - const currentSigner = get(signer); + const currentSigner: any = get(signer); if (currentSigner?.ready && currentSigner?.params?.sk && currentSigner.params.sk.length === 64) { return hexToBytes(currentSigner.params.sk); } @@ -54,7 +54,7 @@ const ensureSigner = async (userPubkey: string): Promise<Uint8Array | null> => { // Wait for signer to be ready const signerValue = await new Promise<any>((resolve, reject) => { let unsubscribe: () => void; - unsubscribe = signer.subscribe((v) => { + unsubscribe = signer.subscribe((v: any) => { if (v === 'cancel') { setTimeout(() => unsubscribe?.()); eventToSign.set(null); @@ -87,7 +87,7 @@ const ensureSigner = async (userPubkey: string): Promise<Uint8Array | null> => { // If expiryDays is specified, the message will expire in that many days, // plus a random amount from 0 to 2 for security. // (expiration time = random creation time + expiryDays + 2 days) -export const createNIP17MessageSK = (text: string, senderSK: Uint8Array, receiverPK: string, wrapPK: string = null, expiryDays: number = null) => { +export const createNIP17MessageSK = (text: string, senderSK: Uint8Array, receiverPK: string, wrapPK: string | null = null, expiryDays: number | null = null) => { const rumour = createRumour(text, getPublicKey(senderSK), receiverPK); const sealed = sealRumourSK(rumour, senderSK, wrapPK || receiverPK, expiryDays); return giftWrap(sealed, wrapPK || receiverPK, expiryDays); @@ -100,14 +100,14 @@ export const createNIP17MessageSK = (text: string, senderSK: Uint8Array, receive // If expiryDays is specified, the message will expire in that many days, // plus a random amount from 0 to 2 for security. // (expiration time = random creation time + expiryDays + 2 days) -export const createNIP17MessageNIP07 = async (text: string, senderPK: string, receiverPK: string, wrapPK: string = null, expiryDays: number = null) => { +export const createNIP17MessageNIP07 = async (text: string, senderPK: string, receiverPK: string, wrapPK: string | null = null, expiryDays: number | null = null) => { const rumour = createRumour(text, senderPK, receiverPK); const sealed = await sealRumourNip07(rumour, wrapPK || receiverPK, expiryDays); return giftWrap(sealed, wrapPK || receiverPK, expiryDays); } const createRumour = (text: string, senderPK: string, receiverPK: string) => { - const rumour = { + const rumour: any = { kind: 14, // rumour created_at: Math.floor(Date.now() / 1000), tags: [["p", receiverPK]], @@ -118,13 +118,13 @@ const createRumour = (text: string, senderPK: string, receiverPK: string) => { return rumour; } -const sealRumourSK = (rumour: object, senderSK: Uint8Array, receiverPK: string, expiryDays: number = null) => { +const sealRumourSK = (rumour: any, senderSK: Uint8Array, receiverPK: string, expiryDays: number | null = null) => { const senderSKString = bytesToHex(senderSK); const conversationKey = u.getConversationKey(senderSKString, receiverPK); const encryptedRumour = encrypt(JSON.stringify(rumour), conversationKey); const created = randomTimestamp(); - const sealEvent = { + const sealEvent: any = { kind: 13, // seal created_at: created, tags: [], @@ -139,12 +139,12 @@ const sealRumourSK = (rumour: object, senderSK: Uint8Array, receiverPK: string, return finalizeEvent(sealEvent, senderSK); } -const sealRumourNip07 = async (rumour: object, receiverPK: string, expiryDays: number = null) => { - const encryptedRumour = await window.nostr.nip44.encrypt( +const sealRumourNip07 = async (rumour: any, receiverPK: string, expiryDays: number | null = null) => { + const encryptedRumour = await (window as any).nostr.nip44.encrypt( receiverPK, JSON.stringify(rumour)); const created = randomTimestamp(); - const sealEvent = { + const sealEvent: any = { kind: 13, // seal created_at: created, tags: [], @@ -155,17 +155,16 @@ const sealRumourNip07 = async (rumour: object, receiverPK: string, expiryDays: n sealEvent.tags.push(["expiration", expiration.toString()]); } - return window.nostr.signEvent(sealEvent); + return (window as any).nostr.signEvent(sealEvent); } -const giftWrap = (event: object, receiverPK: string, expiryDays: number = null) => { +const giftWrap = (event: any, receiverPK: string, expiryDays: number | null = null) => { const secretKey = generateSecretKey(); - const SKString = bytesToHex(secretKey); - const conversationKey = u.getConversationKey(secretKey, receiverPK); + const conversationKey = u.getConversationKey(bytesToHex(secretKey), receiverPK); const encryptedEvent = encrypt(JSON.stringify(event), conversationKey); const created = randomTimestamp(); - const giftWrapEvent = { + const giftWrapEvent: any = { kind: 1059, // gift wrap created_at: created, tags: [["p", receiverPK]], @@ -180,18 +179,18 @@ const giftWrap = (event: object, receiverPK: string, expiryDays: number = null) return finalizeEvent(giftWrapEvent, secretKey); } -const decryptNIP17MessageNIP07 = async (wrapped: object): object => { - const sealedText = await window.nostr.nip44.decrypt( +const decryptNIP17MessageNIP07 = async (wrapped: any): Promise<any> => { + const sealedText = await (window as any).nostr.nip44.decrypt( wrapped.pubkey, wrapped.content); const sealed = JSON.parse(sealedText); - const rumourText = await window.nostr.nip44.decrypt( + const rumourText = await (window as any).nostr.nip44.decrypt( sealed.pubkey, sealed.content); return JSON.parse(rumourText); } // Decrypts the provided message, addressed to the user. // If NIP-07 is available, it uses that, otherwise it triggers the signer modal. -export const decrypt = async (wrapped: object, user: object): object => { +export const decrypt = async (wrapped: any, user: any): Promise<any> => { const sk = await ensureSigner(user.pubkey); if (sk === null) { @@ -204,15 +203,15 @@ export const decrypt = async (wrapped: object, user: object): object => { // Returns the rumours of the messages the provided user has sent or received. // If the events have an expiration timestamp, // that timestamp is added to its rumour object as the property `expiration`. -export const getMessageRumours = async (user: object): object[] => { +export const getMessageRumours = async (user: any): Promise<any[]> => { const preferredRelays = await getPreferredRelays(user.pubkey); // Always include default relays to catch messages that might be there - const relays = [...new Set([...preferredRelays, ...DM_RELAYS_LIST])]; + const relays = Array.from(new Set([...preferredRelays, ...DM_RELAYS_LIST])); const wrapped = await pool.querySync( relays, { kinds: [1059], "#p": [user.pubkey], limit: DM_FETCH_LIMIT } ); - let rumours = []; + let rumours: any[] = []; // intentionally decrypting sequentially to avoid having a bunch of popups for (const event of wrapped) { if (expired(event)) { @@ -221,7 +220,7 @@ export const getMessageRumours = async (user: object): object[] => { } try { - const rumour = await decrypt(event, user); + const rumour: any = await decrypt(event, user); const expires = expiration(event); if (expires) { @@ -239,7 +238,7 @@ export const getMessageRumours = async (user: object): object[] => { // Returns the preferred relays of the user with the provided pubkey, // according to their kind-10050 event. -export const getPreferredRelays = async (pubkey: string): string[] => { +export const getPreferredRelays = async (pubkey: string): Promise<string[]> => { if (relayListCache.has(pubkey)) return relayListCache.get(pubkey); @@ -247,7 +246,7 @@ export const getPreferredRelays = async (pubkey: string): string[] => { DM_RELAYS_LIST, { kinds: [10050], limit: 1, authors: [pubkey] } ); - let relays = []; + let relays: string[] = []; for (const event of events) { for (const tag of event.tags) { if (tag.length >= 2 && tag[0] == "relay") { @@ -266,21 +265,21 @@ export const getPreferredRelays = async (pubkey: string): string[] => { } // Publish to a single relay with NIP-42 auth support -const publishWithAuth = async (relayUrl: string, event: object, sk: Uint8Array | null): Promise<string> => { +const publishWithAuth = async (relayUrl: string, event: any, sk: Uint8Array | null): Promise<string> => { const relay = await Relay.connect(relayUrl); - const signAuthEvent = async (authEvent: object) => { + const signAuthEvent = async (authEvent: any) => { if (sk) { return finalizeEvent(authEvent, sk); - } else if (window.nostr) { - return await window.nostr.signEvent(authEvent); + } else if ((window as any).nostr) { + return await (window as any).nostr.signEvent(authEvent); } throw new Error('No signing method for auth'); }; try { return await relay.publish(event); - } catch (e) { + } catch (e: any) { // Check if it's an auth error if (e?.message?.includes('auth-required')) { // Authenticate and retry @@ -294,7 +293,7 @@ const publishWithAuth = async (relayUrl: string, event: object, sk: Uint8Array | // Store the current sk for use in publish let currentSk: Uint8Array | null = null; -const publishToPreferred = async (event: object, pubkey: string, expiryEnabled: boolean): Promise<string> => { +const publishToPreferred = async (event: any, pubkey: string, expiryEnabled: boolean): Promise<string> => { let preferredRelays = await getPreferredRelays(pubkey); if (expiryEnabled) { preferredRelays = await relaysSupporting(preferredRelays, [40]); @@ -305,7 +304,7 @@ const publishToPreferred = async (event: object, pubkey: string, expiryEnabled: const promises = preferredRelays.map(url => publishWithAuth(url, event, currentSk)); try { - return await Promise.any(promises); + return await (Promise as any).any(promises); } catch (e) { const results = await Promise.allSettled(promises); console.error('All relay publishes failed:', results); @@ -315,7 +314,7 @@ const publishToPreferred = async (event: object, pubkey: string, expiryEnabled: // Sends a NIP-17 message from `user` to `recipient`. // If expiryDays is set, messages will expire after that many days. -export const send = async (message: string, user: object, recipient: object, expiryDays?: number) => { +export const send = async (message: string, user: any, recipient: any, expiryDays?: number) => { let event1, event2; const sk = await ensureSigner(user.pubkey); diff --git a/src/lib/nip51.ts b/src/lib/nip51.ts index b1b0b613..0210bf8b 100644 --- a/src/lib/nip51.ts +++ b/src/lib/nip51.ts @@ -1,5 +1,4 @@ import { SimplePool } from 'nostr-tools/pool'; -import { verifyEvent } from 'nostr-tools/pure'; import { signEvent, encrypt, decrypt } from '$lib/nip07'; const pool = new SimplePool(); @@ -7,7 +6,7 @@ import { PUBLIC_DM_RELAYS } from '$env/static/public'; const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(','); // Mute the provided pubkey, as the provided user. -export const mute = async (user: object, pubkey: string, hide: bool) => { +export const mute = async (user: any, pubkey: string, hide: boolean) => { let { shown, hidden } = await getMuteLists(user); if (hide) { hidden.push(["p", pubkey]); @@ -17,19 +16,19 @@ export const mute = async (user: object, pubkey: string, hide: bool) => { await publishMuteList(user, shown, hidden); } -const tagMatches = (tag: string[], pubkey: string): bool => +const tagMatches = (tag: string[], pubkey: string): boolean => tag.length >= 2 && tag[0] === "p" && tag[1] === pubkey; // Unmute the provided pubkey, as the provided user. -export const unmute = async (user: object, pubkey: string) => { +export const unmute = async (user: any, pubkey: string) => { let { shown, hidden } = await getMuteLists(user); - shown = shown.filter(tag => !tagMatches(tag, pubkey)); - hidden = hidden.filter(tag => !tagMatches(tag, pubkey)); + shown = shown.filter((tag: string[]) => !tagMatches(tag, pubkey)); + hidden = hidden.filter((tag: string[]) => !tagMatches(tag, pubkey)); await publishMuteList(user, shown, hidden); } // Returns a set of the provided user's muted accounts. -export const mutedAccounts = async (user: object): Set<string> => { +export const mutedAccounts = async (user: any): Promise<Set<string>> => { const { shown, hidden } = await getMuteLists(user); let muted = new Set<string>(); for (const tag of shown) { @@ -45,7 +44,7 @@ export const mutedAccounts = async (user: object): Set<string> => { return muted; } -const getMuteLists = async (user: object): object => { +const getMuteLists = async (user: any): Promise<any> => { const listEvents = await pool.querySync( DM_RELAYS_LIST, { kinds: [10000], "authors": [user.pubkey], limit: 1 } ); @@ -60,7 +59,7 @@ const getMuteLists = async (user: object): object => { }; } -const publishMuteList = async (user: object, shown: string[], hidden: string[]) => { +const publishMuteList = async (user: any, shown: string[], hidden: string[]) => { const event = await signEvent({ kind: 10000, created_at: Math.floor(Date.now() / 1000), diff --git a/src/lib/nostr.ts b/src/lib/nostr.ts index 99efb697..dd283987 100644 --- a/src/lib/nostr.ts +++ b/src/lib/nostr.ts @@ -9,15 +9,7 @@ import { } from "$lib/store"; import { post, wait } from "$lib/utils"; import { bytesToHex } from "@noble/hashes/utils.js"; -import { - type EventTemplate, - finalizeEvent, - getEventHash, - getPublicKey, - nip04, - nip19, -} from "nostr-tools"; -import { Relay } from "nostr-tools/relay"; +import type { EventTemplate } from "nostr-tools"; import { get } from "svelte/store"; let nostrToolsPromise: @@ -49,7 +41,7 @@ export const encrypt = async ({ message, recipient, user }: EncryptParams) => { return nip04.encrypt(sk, recipient, message); }; -export const decrypt = async ({ event, user }) => { +export const decrypt = async ({ event, user }: { event: any; user: any }) => { const cache = get(decrypted); try { let { content, pubkey, id } = event; @@ -120,7 +112,7 @@ export const encryptNsec = async (nsec: string) => { return nip49encrypt(d, await getPassword()); }; -export const sign = async (event, user) => { +export const sign = async (event: any, user?: any) => { if (user?.nsec && !get($signer)?.ready) { const sk = await getPrivateKey(user); const { getPublicKey } = await loadNostrTools(); @@ -162,8 +154,8 @@ const getPassword = async (): Promise<string> => { export const nostrConnectRelay = "wss://relay.nsec.app"; -const signingMethods = { - async connect(event, { sk, pk, pubkey }) { +const signingMethods: Record<string, (event: any, params: any) => Promise<any>> = { + async connect(event: any, { sk, pk, pubkey }: any) { const id = crypto.randomUUID(); const signEvent = { id, @@ -214,16 +206,16 @@ const signingMethods = { }); }, - async nsec(event, { sk }) { + async nsec(event: any, { sk }: any) { const { finalizeEvent } = await loadNostrTools(); return finalizeEvent(event, sk); }, - async extension(event) { - return window.nostr.signEvent(event); + async extension(event: any) { + return window.nostr!.signEvent(event); }, - async signer(event, { pubkey, sig }) { + async signer(event: any, { pubkey, sig }: any) { event.pubkey = pubkey; const { getEventHash } = await loadNostrTools(); const signedEvent = { @@ -236,8 +228,8 @@ const signingMethods = { }; // Returns all the keys mentioned in the provided event's 'p' tags. -export const pTagKeys = (event: object): string[] => { - let keys = []; +export const pTagKeys = (event: any): string[] => { + let keys: string[] = []; for (const tag of event.tags) { if (tag[0] === "p") { keys.push(tag[1]); diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte index 5734c71f..8331c98e 100644 --- a/src/routes/(app)/[username]/(profile)/+layout.svelte +++ b/src/routes/(app)/[username]/(profile)/+layout.svelte @@ -29,7 +29,7 @@ try { await post(`/reset`, { username: n, password }); success("Password reset"); - } catch (e) { + } catch (e: any) { fail(e.message); } }; diff --git a/src/routes/(app)/[username]/receive/+page.svelte b/src/routes/(app)/[username]/receive/+page.svelte index 009422a5..6921d443 100644 --- a/src/routes/(app)/[username]/receive/+page.svelte +++ b/src/routes/(app)/[username]/receive/+page.svelte @@ -26,7 +26,7 @@ import { goto, invalidate } from "$app/navigation"; import { page } from "$app/stores"; - let { data } = $props(); + let { data }: any = $props(); let showOptions; @@ -40,7 +40,7 @@ let qr; let aid = $derived(subject.id); - let invoice = $derived({ + let invoice: any = $derived({ aid, type: types.lightning, items: [], @@ -65,7 +65,7 @@ else url += "?options=true"; goto(url, { invalidateAll: true, noScroll: true }); - } catch (e) { + } catch (e: any) { fail(e.message); } }; @@ -158,7 +158,6 @@ {invoice} {copy} {link} - {type} {showQr} {txt} t={$t} diff --git a/src/routes/(app)/account/[id]/+page.svelte b/src/routes/(app)/account/[id]/+page.svelte index ad977e7a..4a23a211 100644 --- a/src/routes/(app)/account/[id]/+page.svelte +++ b/src/routes/(app)/account/[id]/+page.svelte @@ -40,7 +40,7 @@ mnemonic = entropyToMnemonic(entropy, wordlist); password = cached; return true; - } catch (e) { + } catch (e: any) { forgetWalletPassword(); return false; } @@ -57,7 +57,7 @@ const { decrypt } = await import("nostr-tools/nip49"); let entropy = await decrypt(seed, password); mnemonic = entropyToMnemonic(entropy, wordlist); - } catch (e) { + } catch (e: any) { fail("Invalid password, try again"); passwordPrompt = true; } @@ -67,7 +67,7 @@ try { await post("/api/account/delete", { id }); goto(`/${user.username}`); - } catch (e) { + } catch (e: any) { fail(e.message); } }; diff --git a/src/routes/(app)/account/ark/+page.svelte b/src/routes/(app)/account/ark/+page.svelte index 32dbfe13..0c4d8783 100644 --- a/src/routes/(app)/account/ark/+page.svelte +++ b/src/routes/(app)/account/ark/+page.svelte @@ -66,12 +66,12 @@ let seed = await mnemonicToSeed(mnemonic, pw); let master = HDKey.fromMasterSeed(seed, versions); let arkChild = master.derive("m/86'/0'/0'/0/0"); - let arkHex = bytesToHex(arkChild.privateKey); + let arkHex = bytesToHex(arkChild.privateKey!); const identity = SingleKey.fromHex(arkHex); const wallet = await Wallet.create({ identity, arkServerUrl }); arkAddress = await wallet.getAddress(); confirmed = true; - } catch (e) { + } catch (e: any) { console.log("master seed derivation failed", e); fail("Invalid password"); } @@ -117,7 +117,7 @@ forgetWalletPassword(); } goto(`/${user.username}`); - } catch (e) { + } catch (e: any) { console.log(e); fail(e.message); } @@ -150,7 +150,7 @@ forgetWalletPassword(); } goto(`/${user.username}`); - } catch (e) { + } catch (e: any) { console.log(e); fail(e.message); } @@ -220,7 +220,7 @@ id="rememberFor" class="w-full" value={rememberForMs} - onchange={(e) => (rememberForMs = Number(e.target.value))} + onchange={(e) => (rememberForMs = Number((e.target as HTMLSelectElement).value))} > {#each rememberForOptions as option} <option value={option.ms}>{option.label}</option> @@ -371,7 +371,7 @@ id="rememberFor" class="w-full" value={rememberForMs} - onchange={(e) => (rememberForMs = Number(e.target.value))} + onchange={(e) => (rememberForMs = Number((e.target as HTMLSelectElement).value))} > {#each rememberForOptions as option} <option value={option.ms}>{option.label}</option> diff --git a/src/routes/(app)/account/pass/+page.svelte b/src/routes/(app)/account/pass/+page.svelte index a64d95ee..4e9573d4 100644 --- a/src/routes/(app)/account/pass/+page.svelte +++ b/src/routes/(app)/account/pass/+page.svelte @@ -21,13 +21,13 @@ forgetWalletPassword, } from "$lib/passwordCache"; - let { data } = $props(); + let { data }: any = $props(); let { user } = data; - let submitting = $state(); + let submitting = $state(false); - let confirm = $state(), - password = $state(), + let confirm: string = $state(""), + password: string = $state(""), revealPassword = $state(), revealConfirm = $state(); let rememberForMs = $state(defaultRememberForMs); @@ -47,7 +47,7 @@ try { const { encrypt } = await import("nostr-tools/nip49"); let seed = await encrypt( - mnemonicToEntropy($mnemonic, wordlist), + mnemonicToEntropy($mnemonic as string, wordlist), password, ); @@ -55,7 +55,7 @@ await post("/post/user", { seed }); let master = HDKey.fromMasterSeed( - await mnemonicToSeed($mnemonic, password), + await mnemonicToSeed($mnemonic as string, password), versions, ); @@ -78,7 +78,7 @@ } $mnemonic = ""; goto(`/${user.username}`); - } catch (e) { + } catch (e: any) { console.log(e); fail(e.message); } @@ -188,7 +188,7 @@ id="rememberFor" class="w-full" value={rememberForMs} - onchange={(e) => (rememberForMs = Number(e.target.value))} + onchange={(e) => (rememberForMs = Number((e.target as HTMLSelectElement).value))} > {#each rememberForOptions as option} <option value={option.ms}>{option.label}</option> diff --git a/src/routes/(app)/dm/+page.svelte b/src/routes/(app)/dm/+page.svelte index 7b864f89..95cb208e 100644 --- a/src/routes/(app)/dm/+page.svelte +++ b/src/routes/(app)/dm/+page.svelte @@ -23,7 +23,7 @@ } /// chat selection - const usernameFromPubkey = async (pubkey: string): string => { + const usernameFromPubkey = async (pubkey: string): Promise<string | null> => { const response = await fetch(`/api/users/${pubkey}`); if (response.ok) { const userInfo = await response.json(); @@ -35,7 +35,7 @@ const userInfo = async (pubkey: string) => { if (pubkey.slice(0, 4) === "npub") { - return userInfo(decode(pubkey).data); + return userInfo(decode(pubkey).data as string); } const nostrUserInfo = await getNostrUserInfo(pubkey) || {}; @@ -48,11 +48,11 @@ nip05Valid: valid, pubkey }; } - const name = (userInfo: object): string => { + const name = (userInfo: any): string => { return userInfo.coinosUsername || userInfo.nostrName || $t("dm.anonymous"); } - const id = (userInfo: object): string => { + const id = (userInfo: any): string => { if (userInfo.nip05 && userInfo.nip05.slice(0, 2) == "_@") { return userInfo.nip05.slice(2); } @@ -60,11 +60,11 @@ return userInfo.nip05 || (npubEncode(userInfo.pubkey).slice(0, 16) + "..."); } - const idValid = (userInfo: object): string => { + const idValid = (userInfo: any): boolean => { return !userInfo.nip05 || userInfo.nip05Valid; } - const rumourInvolves = (rumour: object, pubkey: string) => { + const rumourInvolves = (rumour: any, pubkey: string) => { if (rumour.pubkey === pubkey) { return true; } else { @@ -77,7 +77,7 @@ } } - const mostRecentCommunication = (rumours: object[], pubkey: string) => { + const mostRecentCommunication = (rumours: any[], pubkey: string) => { let mostRecentTime = null; for (const rumour of rumours.filter((r) => rumourInvolves(r, pubkey))) { if (!mostRecentTime || rumour.created_at > mostRecentTime) { @@ -87,9 +87,9 @@ return mostRecentTime; } - const updateSendersRecipients = async (rumours: object[]) => { - const senders = new Set<object>(); - const recipients = new Set<object>(); + const updateSendersRecipients = async (rumours: any[]) => { + const senders = new Set<any>(); + const recipients = new Set<any>(); for (const rumour of rumours) { if (rumour.pubkey !== user.pubkey) { senders.add(await userInfo(rumour.pubkey)); @@ -102,7 +102,7 @@ messageSenders = Array.from(senders); messageRecipients = Array.from(recipients); - const chatMap = new Map<string, object>(); + const chatMap = new Map<string, any>(); for (const sender of senders) { chatMap.set(sender.pubkey, sender); } @@ -110,31 +110,31 @@ chatMap.set(recipient.pubkey, recipient); } chats = Array.from(chatMap.values()); - chats.sort((a, b) => mostRecentCommunication(rumours, b.pubkey) - mostRecentCommunication(rumours, a.pubkey)); + chats.sort((a, b) => (mostRecentCommunication(rumours, b.pubkey) ?? 0) - (mostRecentCommunication(rumours, a.pubkey) ?? 0)); }; - let messageSenders = $state([]); - let messageRecipients = $state([]); - let chats = $state([]); + let messageSenders: any[] = $state([]); + let messageRecipients: any[] = $state([]); + let chats: any[] = $state([]); getMessageRumours(user).then(updateSendersRecipients); - let selectedChat = $state(null); + let selectedChat: any = $state(null); let creatingNewChat = $state(false); let searchQuery = $state(""); /// individual chat let text = $state(""); - let allRumours = $state([]); - let messageRumours = $state([]); - let dates = $state([]); + let allRumours: any[] = $state([]); + let messageRumours: any = $state([]); + let dates: any[] = $state([]); let relayWarningShown = $state(false); let expiryEnabled = $state(false); let expiryDays = $state(7); let canSend = $state(false); let canSendExpiring = $state(false); - let nostrUserInfo = $state({}); + let nostrUserInfo: any = $state({}); - const includesPubkey = (chats: object[], pubkey: string) => { + const includesPubkey = (chats: any[], pubkey: string) => { for (const c of chats) { if (c.pubkey === pubkey) { return true; @@ -143,7 +143,7 @@ return false; } - const selectChat = (c: object) => { + const selectChat = (c: any) => { selectedChat = c; if (!includesPubkey(chats, c.pubkey)) { chats.unshift(c); @@ -184,23 +184,23 @@ onMount(() => { const urlParams = new URLSearchParams(window.location.search); if (urlParams.get('username')) { - selectChatUsername(urlParams.get('username')); + selectChatUsername(urlParams.get('username')!); } else if (urlParams.get('nip05')) { - selectChatNip05(urlParams.get('nip05')); + selectChatNip05(urlParams.get('nip05')!); } else if (urlParams.get('pubkey')) { - selectChatPubkey(urlParams.get('pubkey')); + selectChatPubkey(urlParams.get('pubkey')!); } }); - const appendMultimap = (map: Map, key: string, value: object) => { + const appendMultimap = (map: Map<any, any>, key: any, value: any) => { if (map.has(key)) { - map.get(key).push(value); + map.get(key)!.push(value); } else { map.set(key, [value]); } } - const dateMap = (events: object[]): Map<number, object> => { + const dateMap = (events: any[]): Map<any, any> => { let eventsMap = new Map(); for (const event of events) { const created = Math.floor(event.created_at / 86400); @@ -249,7 +249,7 @@ } const sendMessage = async (message: string) => { - const expiry = expiryEnabled ? expiryDays : null; + const expiry = expiryEnabled ? expiryDays : undefined; await libnip17.send(message, user, selectedChat, expiry); updateEvents(); } diff --git a/src/routes/(app)/firehose/+page.svelte b/src/routes/(app)/firehose/+page.svelte index 6b2338c2..2fdaa4d0 100644 --- a/src/routes/(app)/firehose/+page.svelte +++ b/src/routes/(app)/firehose/+page.svelte @@ -4,7 +4,7 @@ import { onMount } from "svelte"; import { ignore } from "$lib/store"; - let events = $state([]); + let events: any[] = $state([]); let paused = $state(); let pause = (e) => { e.preventDefault(); @@ -21,7 +21,7 @@ const { Relay } = await import("nostr-tools/relay"); const relay = await Relay.connect("wss://relay.primal.net"); const subscription = relay.subscribe([{ kinds: [1], limit: 20 }], { - async onevent(event) { + async onevent(event: any) { if (paused) return; const { parts, names } = await post("/post/parseEvent", { event }); event.author = await get(`/api/users/${event.pubkey}`); diff --git a/src/routes/(app)/fund/[id]/+page.svelte b/src/routes/(app)/fund/[id]/+page.svelte index 5f8d848f..c3fa7ce1 100644 --- a/src/routes/(app)/fund/[id]/+page.svelte +++ b/src/routes/(app)/fund/[id]/+page.svelte @@ -12,7 +12,7 @@ import { bech32 } from "@scure/base"; const encoder = new TextEncoder(); - let { data } = $props(); + let { data }: any = $props(); let { amount, payments, managers, rate, user } = data; let { id } = $page.params; @@ -21,7 +21,7 @@ let currency = user ? user.currency : "CAD"; let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2))); - $effect(() => ($loginRedirect = $page.url.pathname)); + $effect(() => { $loginRedirect = $page.url.pathname; }); let show = $state(); let toggle = () => (show = !show); diff --git a/src/routes/(app)/fund/[id]/access/+page.svelte b/src/routes/(app)/fund/[id]/access/+page.svelte index 9a7a85cb..24ded54e 100644 --- a/src/routes/(app)/fund/[id]/access/+page.svelte +++ b/src/routes/(app)/fund/[id]/access/+page.svelte @@ -15,7 +15,7 @@ m = await post(`/post/fund/${id}/managers/delete`, { id: user.id, }); - } catch (e) { + } catch (e: any) { fail(e.message); } }; diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte index beffa264..bf62a062 100644 --- a/src/routes/(app)/invoice/[id]/+page.svelte +++ b/src/routes/(app)/invoice/[id]/+page.svelte @@ -28,7 +28,7 @@ import { t } from "$lib/translations"; import { goto, invalidate } from "$app/navigation"; - let { data } = $props(); + let { data }: any = $props(); let showOptions; @@ -91,7 +91,7 @@ else url += "?options=true"; goto(url, { invalidateAll: true, noScroll: true }); - } catch (e) { + } catch (e: any) { fail(e.message); } }; @@ -185,7 +185,6 @@ {invoice} {copy} {link} - {type} {txt} t={$t} bind:showQr={$showQr} diff --git a/src/routes/(app)/invoice/[id]/tip/+page.svelte b/src/routes/(app)/invoice/[id]/tip/+page.svelte index c9f38837..4d3af188 100644 --- a/src/routes/(app)/invoice/[id]/tip/+page.svelte +++ b/src/routes/(app)/invoice/[id]/tip/+page.svelte @@ -10,10 +10,10 @@ const tipAmounts = ["No", "10%", "15%", "20%"]; let showCustomAmount = $state(); - let customInput = $state(); - let customTipAmount = $state(); + let customInput: HTMLInputElement = $state() as any; + let customTipAmount: number = $state(0); - let apply = async (e) => { + let apply = async (e: Event) => { e.preventDefault(); if (customTipAmount > 0) { @@ -25,24 +25,24 @@ let active = (amount) => !customTipAmount && Math.round(tipPercent) === parseInt(amount.slice(0, 2)); - const handleCustomTipAmount = (e) => { - customTipAmount = e.target.value; + const handleCustomTipAmount = (e: Event) => { + customTipAmount = Number((e.target as HTMLInputElement).value); tipPercent = (customTipAmount / amountFiat) * 100; tip = Math.round((amount / 100) * tipPercent); }; let timeout; - const handleSlide = (e) => { - customTipAmount = ""; + const handleSlide = (e: Event) => { + customTipAmount = 0; if (customInput) { customInput.value = ""; } - tipPercent = e.target.value; + tipPercent = Number((e.target as HTMLInputElement).value); tip = Math.round((amount / 100) * tipPercent); }; let submitting = $state(); - const handleTipButtonClick = async (v) => { + const handleTipButtonClick = async (v: string) => { submitting = true; if (v === "No") { tipPercent = 0; @@ -56,9 +56,9 @@ submit.click(); }; - let submit = $state(); + let submit: HTMLButtonElement = $state() as any; - let { data } = $props(); + let { data }: any = $props(); let { invoice, id, user } = $state(data); let { aid, @@ -87,7 +87,7 @@ }); let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2))); - let tipAmount = $derived(((tip * rate) / sats).toFixed(2)); + let tipAmount = $derived(parseFloat(((tip * rate) / sats).toFixed(2))); let invoiceAmountFiatFormatted = $derived(f(amountFiat, currency)); </script> @@ -147,14 +147,14 @@ use:focus type="button" class="btn" - class:active={active(amount, tipPercent)} + class:active={active(amount)} onclick={() => handleTipButtonClick(amount)}>{amount}</button > {:else} <button type="button" class="btn" - class:active={active(amount, tipPercent)} + class:active={active(amount)} onclick={() => handleTipButtonClick(amount)}>{amount}</button > {/if} diff --git a/src/routes/(app)/messages/+page.svelte b/src/routes/(app)/messages/+page.svelte index 606af893..2de56e0b 100644 --- a/src/routes/(app)/messages/+page.svelte +++ b/src/routes/(app)/messages/+page.svelte @@ -9,24 +9,24 @@ let { data } = $props(); - let { messages, notes, invoices, sent, received, subject, user } = + let { messages, notes, invoices, sent, received, subject, user }: any = $state(data); - let refresh = (d) => + let refresh = (d: any) => ({ messages, notes, invoices, sent, received, subject, user } = d); let keys = new Set(); - let latest = $state([]); - let ready; + let latest: any[] = $state([]); + let ready: any; - e.subscribe(async (event) => { + e.subscribe(async (event: any) => { if (!(browser && event && ready)) return; if ( event.recipient?.id === user.id && - !~latest.findIndex((m) => m.id === event.id) + !~latest.findIndex((m: any) => m.id === event.id) ) { event.content = await decrypt({ event, user }); - let i = latest.findIndex((m) => m.pubkey === event.pubkey); + let i = latest.findIndex((m: any) => m.pubkey === event.pubkey); let popped; if (~i) popped = latest.splice(i, 1); else popped = latest.pop(); @@ -36,7 +36,7 @@ } }); - let initialize = async (p) => { + let initialize = async (p: any) => { let i = 0; ready = false; if (!(browser && user)) return; @@ -80,7 +80,7 @@ <a href={`/messages/${u.username}`}> <div class="flex hover:bg-gray-100 p-4 rounded-2xl"> <div class="my-auto"> - <Avatar user={u} size={"20"} disabled={true} /> + <Avatar user={u} size={20} disabled={true} /> </div> <div class="my-auto truncate"> <div class="my-auto ml-1 text-lg font-bold">{u.username}</div> diff --git a/src/routes/(app)/messages/[recipient]/+page.svelte b/src/routes/(app)/messages/[recipient]/+page.svelte index c8d522f0..f399ab25 100644 --- a/src/routes/(app)/messages/[recipient]/+page.svelte +++ b/src/routes/(app)/messages/[recipient]/+page.svelte @@ -15,12 +15,12 @@ let { data } = $props(); function fadeScale( - node, - { delay = 0, duration = 200, easing = (x) => x, baseScale = 0 }, + node: any, + { delay = 0, duration = 200, easing = (x: number) => x, baseScale = 0 }, ) { const o = +getComputedStyle(node).opacity; const m = getComputedStyle(node).transform.match(/scale\(([0-9.]+)\)/); - const s = m ? m[1] : 1; + const s: any = m ? m[1] : 1; const is = 1 - baseScale; return { @@ -35,10 +35,10 @@ }; } - let { messages, recipient, user } = $state(data); - let input, pane = $state(); + let { messages, recipient, user }: any = $state(data); + let input: any, pane: any = $state(); - let initialize = async (p) => { + let initialize = async (p: any) => { await Promise.all( messages.map( async (event) => (event.message = await decrypt({ event, user })), @@ -49,8 +49,8 @@ tick().then(() => pane && (pane.scrollTop = pane.scrollHeight)); }; - e.subscribe(async (event) => { - let found = ~messages.findIndex((m) => m.id === event?.id); + e.subscribe(async (event: any) => { + let found = ~messages.findIndex((m: any) => m.id === event?.id); if (event?.recipient.id === user.id && !found) { event.message = await decrypt({ event, user }); messages.push(event); @@ -59,11 +59,11 @@ } }); - let sent, submitting, message = $state(); + let sent: any, submitting: any, message: any = $state(); let submit = async () => { submitting = true; - let event = { + let event: any = { pubkey: user.pubkey, created_at: Math.floor(Date.now() / 1000), kind: 4, @@ -93,8 +93,8 @@ await send(event); sent = true; - } catch (e) { - console.log(e); + } catch (err: any) { + console.log(err); fail("Failed to send message"); } @@ -102,7 +102,7 @@ submitting = false; }; - let keydown = (e) => { + let keydown = (e: any) => { if (e.key === "Enter") { e.preventDefault(); submit(); @@ -149,7 +149,7 @@ {message} </div> <div class="mt-auto"> - <Avatar user={author} size={"12"} /> + <Avatar user={author} size={12} /> </div> </div> <div class="text-sm text-gray-400 mb-6" class:text-right={ours}> diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte index e368f2ad..436a7ab6 100644 --- a/src/routes/(app)/payment/[id]/+page.svelte +++ b/src/routes/(app)/payment/[id]/+page.svelte @@ -66,7 +66,7 @@ let bump = async () => { try { await post(`/payment/${id}/bump`, { id }); - } catch (e) { + } catch (e: any) { fail(e.message); } }; diff --git a/src/routes/(app)/pos/+page.svelte b/src/routes/(app)/pos/+page.svelte index 967ddd09..6806fec3 100644 --- a/src/routes/(app)/pos/+page.svelte +++ b/src/routes/(app)/pos/+page.svelte @@ -3,7 +3,7 @@ import { hex } from "@scure/base"; // Convert Uint8Array → JS "binary string" in safe chunks - function bs(uint8Array) { + function bs(uint8Array: Uint8Array) { let binaryString = ""; const chunkSize = 0x8000; for (let i = 0; i < uint8Array.length; i += chunkSize) { @@ -13,7 +13,7 @@ return binaryString; } - let { data, form } = $props(); + let { data, form }: any = $props(); let { token } = $state(data); // --- Defaults --- @@ -23,12 +23,12 @@ const WORK_BAUD = 921600; // fast flashing // --- Shared state --- - let esploader = $state(); - let chip, transport; + let esploader: any = $state(); + let chip: any, transport: any; let connected = $state(false); let portInfo = $state(""); - let ESPLoader; - let Transport; + let ESPLoader: any; + let Transport: any; // --- Existing config path (generated server-side to hex in form.bytes) --- let bytes = $derived(form ? hex.decode(form.bytes) : undefined); @@ -37,8 +37,8 @@ let configDone = $state(false); // --- New firmware flashing path --- - let fwFile = $state(null); - let fwBytes = $state(); // Uint8Array + let fwFile: any = $state(null); + let fwBytes: Uint8Array | undefined = $state(); // Uint8Array let fwAddress = $state(FW_ADDRESS_DEFAULT); let fwEraseAll = $state(false); let fwProgress = $state(0); @@ -53,7 +53,7 @@ if (!ESPLoader || !Transport) { ({ ESPLoader, Transport } = await import("esptool-js")); } - const device = await navigator.serial.requestPort({}); + const device = await (navigator as any).serial.requestPort({}); transport = new Transport(device, true); esploader = new ESPLoader({ transport, @@ -90,10 +90,10 @@ configDone = true; }; - function onPickFw(e) { + function onPickFw(e: Event) { fwError = ""; fwDone = false; - const f = e.target.files?.[0]; + const f = (e.target as HTMLInputElement).files?.[0]; fwFile = f || null; if (!fwFile) { fwBytes = undefined; @@ -101,7 +101,7 @@ } const reader = new FileReader(); reader.onload = () => { - const buf = new Uint8Array(reader.result); + const buf = new Uint8Array(reader.result as ArrayBuffer); fwBytes = buf; }; reader.onerror = () => { @@ -138,7 +138,7 @@ }); fwDone = true; - } catch (e) { + } catch (e: any) { console.error(e); fwError = e?.message || "Flash failed."; } @@ -178,7 +178,7 @@ id="littlefs-address" class="input" bind:value={littlefsAddress} - onchange={(e) => (littlefsAddress = Number(e.target.value))} + onchange={(e) => (littlefsAddress = Number((e.target as HTMLInputElement).value))} /> <div class="mt-3"> <button class="btn" onclick={flashConfig}>Flash config</button> @@ -214,7 +214,7 @@ id="firmware-address" class="input" bind:value={fwAddress} - onchange={(e) => (fwAddress = Number(e.target.value))} + onchange={(e) => (fwAddress = Number((e.target as HTMLInputElement).value))} /> <label class="flex items-center gap-2 mt-2"> diff --git a/src/routes/(app)/send/[...text]/+page.svelte b/src/routes/(app)/send/[...text]/+page.svelte index 25a77a1e..34acb4b0 100644 --- a/src/routes/(app)/send/[...text]/+page.svelte +++ b/src/routes/(app)/send/[...text]/+page.svelte @@ -21,10 +21,10 @@ all = await get("/contacts"); }; - let el = $state(), + let el: any = $state(), text = $state(), pasted = $state(), - w = $state(); + w: number | undefined = $state(); let keypress = (e) => e.key === "Enter" ? e.preventDefault() || el.click() : (pasted = false); diff --git a/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.svelte b/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.svelte index ea1e9f71..f5bc3bc6 100644 --- a/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.svelte +++ b/src/routes/(app)/send/ark/[address]/[amount]/[...feeRate]/+page.svelte @@ -32,7 +32,7 @@ }); goto(`/sent/${p.id}`, { invalidateAll: true }); - } catch (e) { + } catch (e: any) { submitting = false; error = e.message || "Failed to send"; } diff --git a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte index faa6c919..ecdb3b08 100644 --- a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte +++ b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte @@ -22,11 +22,11 @@ import Amount from "$comp/Amount.svelte"; - let { data, form } = $props(); + let { data, form }: any = $props(); let { encode, decode } = hexUtil; let passwordPrompt = $state(); - let password = $state(); + let password: any = $state(); let cancel = $state(() => (passwordPrompt = false)); let signed = $state(); let loading = $state(false); @@ -39,7 +39,7 @@ password = cached; await signTx(); return true; - } catch (e) { + } catch (e: any) { forgetWalletPassword(); return false; } @@ -69,7 +69,7 @@ user: data.user, }); goto(`/sent/${p.id}`, { invalidateAll: true }); - } catch (e) { + } catch (e: any) { loading = false; error = e.message || "Failed to send"; } @@ -102,15 +102,15 @@ import("@scure/bip39"), import("@scure/bip39/wordlists/english.js"), ]); - let entropy = await decrypt(account.seed || data.user.seed, password); + let entropy = await decrypt(account.seed || data.user.seed, password as string); let mnemonic = entropyToMnemonic(entropy, wordlist); - let seed = await mnemonicToSeed(mnemonic, password); - let master = HDKey.fromMasterSeed(seed, network); + let seed = await mnemonicToSeed(mnemonic, password as string); + let master = HDKey.fromMasterSeed(seed, network as any); let child = master.derive(`m/84'/0'/${account.accountIndex ?? 0}'`); let raw = decode(hex); let isPSBT = raw[0] === 0x70 && raw[1] === 0x73 && raw[2] === 0x62 && raw[3] === 0x74; - let tx = isPSBT ? Transaction.fromPSBT(raw) : Transaction.fromRaw(raw); + let tx: any = isPSBT ? Transaction.fromPSBT(raw) : Transaction.fromRaw(raw); for (let [i, input] of tx.inputs.entries()) { let { witnessUtxo, path } = inputs[i]; @@ -120,14 +120,14 @@ tx.updateInput(i, { witnessUtxo }); } let key = child.derive(path); - tx.signIdx(key.privateKey, i); + tx.signIdx(key.privateKey!, i); } tx.finalize(); hex = tx.hex; signed = true; await tick(); - submit.click(); + (submit as any).click(); }; let toggle = () => (submitting = !submitting); @@ -145,7 +145,7 @@ inputs, } = $derived(data); - let { feeRate } = $state(data); + let { feeRate }: any = $state(data); $effect(() => { if (fees) { @@ -162,8 +162,8 @@ let { balance, currency } = data.user; let submitting = $state(), - submit = $state(), - showSettings; + submit: any = $state(), + showSettings = $state(); let feeNames = { fastestFee: $t("payments.fastest"), @@ -247,7 +247,7 @@ </div> {#if passwordPrompt} - <WalletPass bind:password bind:cancel submit={signTx} /> + <WalletPass bind:password {cancel} submit={signTx} /> {/if} <style> diff --git a/src/routes/(app)/send/invoice/[id]/+page.svelte b/src/routes/(app)/send/invoice/[id]/+page.svelte index 2a2d72e2..f3f2f618 100644 --- a/src/routes/(app)/send/invoice/[id]/+page.svelte +++ b/src/routes/(app)/send/invoice/[id]/+page.svelte @@ -23,7 +23,7 @@ focus, loc, } from "$lib/utils"; - let { data, form } = $props(); + let { data, form }: any = $props(); let { trusted, balance, invoice, user } = $state(data); let { address, hash, payreq, user: recipient, tip } = $state(data.invoice); @@ -33,8 +33,8 @@ let rate = $derived(invoice.rate * (data.rate / data.invoiceRate)); - let a = $state(), - af = $state(), + let a: any = $state(), + af: any = $state(), fiat = $state(untrack(() => !amount)); let amountFiat = $state((untrack(() => amount) * untrack(() => rate)) / sats); @@ -63,7 +63,7 @@ }); }; - let toggleTrust = async (e) => { + let toggleTrust = async (e: Event) => { e.preventDefault(); e.stopPropagation(); @@ -100,7 +100,7 @@ // } // }); - let setMax = (e) => { + let setMax = (e: Event) => { e.preventDefault(); fiat = false; amount = balance; @@ -126,7 +126,7 @@ </h1> <div class="flex p-1 gap-2 justify-center"> - <Avatar user={recipient} size={"20"} /> + <Avatar user={recipient} size={20} /> <p class="text-4xl break-words my-auto"> {recipient.username} </p> diff --git a/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.server.ts b/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.server.ts index fef0a359..7a5514e8 100644 --- a/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.server.ts +++ b/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.server.ts @@ -4,7 +4,7 @@ import { fail, redirect } from "@sveltejs/kit"; export async function load({ cookies, params, parent }) { const { user } = await parent(); - let data = { ...params }; + let data: any = { ...params }; const rates = await getRates(); if (!params.payreq.startsWith("lno")) { data = { ...data, ...(await post("/parse", params, auth(cookies))) }; diff --git a/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte b/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte index 66ac240d..526038fa 100644 --- a/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte +++ b/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte @@ -11,15 +11,15 @@ import { fiat, rate, pin } from "$lib/store"; import { sendArkViaForward } from "$lib/ark"; - let { data, form } = $props(); + let { data, form }: any = $props(); let { alias, memo, payreq, ourfee, user } = $derived({ ...data, ...form }); let a = $state(); let { currency, locked } = $derived(user); let locale = $derived(loc(user)); - $effect(() => ($rate ||= data.rate)); - $effect(() => form && (loading = false)); + $effect(() => { $rate ||= data.rate; }); + $effect(() => { if (form) loading = false; }); let showMax = $state(); let error = $state(""); @@ -27,12 +27,13 @@ let loading = $state(); let next = $state(); + let show = $state(false); let toggle = () => (show = !show); let amount = $derived(form?.amount || data.amount); let maxfee = $state( Math.max(5, Math.round(untrack(() => amount) * 0.02 || 0)), ); - $effect(() => (maxfee = Math.max(5, Math.round(amount * 0.02) || 0))); + $effect(() => { maxfee = Math.max(5, Math.round(amount * 0.02) || 0); }); let handler = ({ cancel }) => { loading = true; @@ -51,7 +52,7 @@ user, }); goto(`/sent/${p.id}`, { invalidateAll: true }); - } catch (e) { + } catch (e: any) { loading = false; error = e.message || "Failed to send"; } @@ -71,7 +72,7 @@ }); goto(`/send/bitcoin/${inv.hash}/${amount}`); - } catch (e) { + } catch (e: any) { loading = false; error = e.message || "Failed to send"; } @@ -115,7 +116,7 @@ <div class="my-auto"> {#if $fiat} <h2 class="text-xl"> - {f(toFiat(ourfee, $rate), currency)} + {f(toFiat(ourfee as number, $rate as number), currency)} </h2> {:else} <h3 class="text-secondary">⚡️{s(ourfee)}</h3> @@ -191,6 +192,7 @@ {locale} bind:rate={$rate} submit={next} + element={undefined} /> <button type="submit" class="btn" bind:this={next} >{$t("payments.next")}</button diff --git a/src/routes/(app)/send/zap/[id]/[...amount]/+page.svelte b/src/routes/(app)/send/zap/[id]/[...amount]/+page.svelte index 0af4e6ac..78b4d64f 100644 --- a/src/routes/(app)/send/zap/[id]/[...amount]/+page.svelte +++ b/src/routes/(app)/send/zap/[id]/[...amount]/+page.svelte @@ -12,7 +12,7 @@ import { sign, send } from "$lib/nostr"; import { rate, pin } from "$lib/store"; - let { data, form } = $props(); + let { data, form }: any = $props(); let { id, request, user } = $derived({ ...data, ...form }); let a = $state(data.amount); @@ -20,19 +20,21 @@ let locale = $derived(loc(user)); let event = $state(); - $effect(() => ($rate ||= data.rate)); - $effect(async () => { + $effect(() => { $rate ||= data.rate; }); + $effect(() => { if (form || request) { - try { - loading = false; - event = await sign(request); - let { pr: payreq } = await post("/post/zap", { event }); - await post("/post/payments", { amount, payreq, pin: $pin }); - goto(`/e/${id}`); - } catch (e) { - console.log(e); - fail(e.message); - } + (async () => { + try { + loading = false; + event = await sign(request); + let { pr: payreq } = await post("/post/zap", { event }); + await post("/post/payments", { amount, payreq, pin: $pin }); + goto(`/e/${id}`); + } catch (e: any) { + console.log(e); + fail(e.message); + } + })(); } }); @@ -42,6 +44,7 @@ let submit = () => (loading = true); let next = $state(); + let show = $state(false); let toggle = () => (show = !show); let amount = $derived(form?.amount || data.amount); let maxfee = $state(Math.max(5, Math.round(untrack(() => amount) * 0.005))); @@ -63,6 +66,7 @@ {locale} bind:rate={$rate} submit={next} + element={undefined} /> <button type="submit" class="btn" bind:this={next} >{$t("payments.next")}</button diff --git a/src/routes/(app)/settings/+layout.svelte b/src/routes/(app)/settings/+layout.svelte index 02e2fe62..a8792333 100644 --- a/src/routes/(app)/settings/+layout.svelte +++ b/src/routes/(app)/settings/+layout.svelte @@ -17,9 +17,9 @@ import { SimplePool } from 'nostr-tools/pool'; import { finalizeEvent } from 'nostr-tools/pure'; - let { children, data, form } = $props(); + let { children, data, form }: any = $props(); - let formElement = $state(); + let formElement: HTMLFormElement | undefined = $state(); let { token, cookies, subscriptions } = $derived(data); let { tab } = $derived(data); @@ -48,7 +48,7 @@ import { PUBLIC_DM_RELAYS } from '$env/static/public'; const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(','); const updateRelaysIfAvailable = async () => { - const relayEntry = document.getElementById('dmRelays'); + const relayEntry = document.getElementById('dmRelays') as HTMLTextAreaElement | null; if (!relayEntry || relayEntry.value.length === 0) return; const newRelays = relayEntry.value.split(/[ \r\n\t]+/) @@ -65,8 +65,8 @@ content: "" }; let signed; - if (await window.nostr.getPublicKey() === user.pubkey) { - signed = await window.nostr.signEvent(event); + if (await window.nostr!.getPublicKey() === user.pubkey) { + signed = await window.nostr!.signEvent(event); } else { const sk = await getPrivateKey(user); signed = finalizeEvent(event, sk); @@ -78,23 +78,23 @@ try { new URL(url); return true; - } catch (err) { + } catch (err: any) { return false; } } - async function handleSubmit(e) { + async function handleSubmit(e: any) { updateRelaysIfAvailable(); e.preventDefault(); try { submitting = true; - let body = new FormData(formElement); + let body = new FormData(formElement!); form = { user: await fd({ formData() { return body; }, - }), + } as any), }; await tick(); @@ -122,14 +122,14 @@ if ($avatar) { try { let { hash } = JSON.parse( - await upload($avatar.file, $avatar.type, $avatar.progress, token), + await upload(($avatar as any).file, ($avatar as any).type, ($avatar as any).progress) as string, ); let url = `${$page.url.origin}/api/public/${hash}.webp`; body.set("picture", url); await fetch(url, { cache: "reload", mode: "no-cors" }); - } catch (e) { + } catch (e: any) { console.log("problem upsubmitting avatar", e); } } @@ -137,13 +137,13 @@ if ($banner) { try { let { hash } = JSON.parse( - await upload($banner.file, $banner.type, $banner.progress, token), + await upload(($banner as any).file, ($banner as any).type, ($banner as any).progress) as string, ); let url = `${$page.url.origin}/api/public/${hash}.webp`; body.set("banner", url); await fetch(url, { cache: "reload", mode: "no-cors" }); - } catch (e) { + } catch (e: any) { console.log("problem uploading banner", e); } } @@ -171,7 +171,7 @@ try { event = await sign(event, user); send(event); - } catch (e) { + } catch (e: any) { warning("Nostr profile not updated"); } } @@ -179,8 +179,8 @@ let email = body.get("email"); if (email && email !== prev.email) { try { - cookies.get = function (n) { - return this.find((c) => c.name === n).value; + (cookies as any).get = function (n: string) { + return (this as any).find((c: any) => c.name === n)?.value; }; user.verified = false; @@ -188,13 +188,13 @@ await post("/email", { email }); warning($t("user.settings.verifying"), false); - } catch (e) { + } catch (e: any) { fail(e.message); console.log(e); } } - const response = await fetch(formElement.action, { + const response = await fetch(formElement!.action, { method: "POST", body, }); @@ -203,11 +203,11 @@ if (result.type === "success") { await invalidateAll(); - if (body.get("password")) $password = body.get("password"); + if (body.get("password")) $password = body.get("password") as string; } applyAction(result); - } catch (e) { + } catch (e: any) { console.log(e); fail("Something went wrong"); } diff --git a/src/routes/(app)/settings/account/+page.svelte b/src/routes/(app)/settings/account/+page.svelte index 1aa46ff6..a3cc24fd 100644 --- a/src/routes/(app)/settings/account/+page.svelte +++ b/src/routes/(app)/settings/account/+page.svelte @@ -19,7 +19,8 @@ let rate = $derived(() => rates[currency]); let fiats = Object.keys(rates).sort((a, b) => a.localeCompare(b)); - let keypress = (e) => e.key === "Enter" && (e.preventDefault() || el.click()); + let el: any; + let keypress = (e: any) => e.key === "Enter" && (e.preventDefault() || el.click()); let editingReserve = $state(), editingThreshold = $state(), @@ -44,19 +45,19 @@ if (!user.threshold) user.threshold = 1000000; if (!user.reserve) user.reserve = 100000; - let reserveEl = $state(), - thresholdEl = $state(); + let reserveEl: any = $state(), + thresholdEl: any = $state(); let push = $state(), - pm, - subscription; + pm: any, + subscription: any; onMount(async () => { if (!browser) return; pm = navigator?.serviceWorker && - (await navigator.serviceWorker.getRegistration()).pushManager; + (await navigator.serviceWorker.getRegistration())?.pushManager; permission = await pm.permissionState({ userVisibleOnly: true, @@ -308,7 +309,7 @@ </h1> <Numpad bind:amount={user.reserve} - bind:currency + {currency} bind:rate bind:submit={doneReserve} bind:element={reserveEl} diff --git a/src/routes/(app)/settings/nostr/+page.svelte b/src/routes/(app)/settings/nostr/+page.svelte index f1d06c66..ae074d30 100644 --- a/src/routes/(app)/settings/nostr/+page.svelte +++ b/src/routes/(app)/settings/nostr/+page.svelte @@ -12,13 +12,14 @@ let { data } = $props(); let { apps, challenge, user } = $derived(data); let npub = $state(untrack(() => user.npub)); - let extensionAvailable = $derived(browser && window.nostr); + let extensionAvailable = $derived(browser && (window as any).nostr); let { locale } = $derived(user); import { SimplePool } from 'nostr-tools/pool'; let newNsec = $state(), - nsec = $state(), + nsec: any = $state(), + nwc: string = $state(""), pin = $state(""), revealNsec = $state(), revealNwc = $state(); @@ -36,17 +37,17 @@ let getPubkey = async () => { $signer = { method: "extension", ready: true }; extension = true; - npub = await window.nostr.getPublicKey(); + npub = await window.nostr!.getPublicKey(); await tick(); - $save.click(); + ($save as any).click(); }; import { PUBLIC_DM_RELAYS } from '$env/static/public'; const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(','); const pool = new SimplePool(); getPreferredRelays(user.pubkey).then(relays => { - const relayEntry = document.getElementById('dmRelays'); - relayEntry.value = relays.join("\n"); + const relayEntry = document.getElementById('dmRelays') as HTMLTextAreaElement | null; + if (relayEntry) relayEntry.value = relays.join("\n"); }); </script> @@ -77,8 +78,8 @@ class="text-yellow-300" ></iconify-icon> {#if $fiat && $rate} - {f((app.spent * $rate) / sats, user.currency, locale)} / - {f((app.max_amount * $rate) / sats, user.currency, locale)} + {f((app.spent * ($rate as number)) / sats, user.currency, locale)} / + {f((app.max_amount * ($rate as number)) / sats, user.currency, locale)} {:else} {s(app.spent, locale)} / {s(app.max_amount, locale)} @@ -116,7 +117,6 @@ href={`/qr/${encodeURIComponent(app.nwc)}`} class:btn-disabled={!app.secret} title={$t("user.receive.showQR")} - disabled={!app.secret} > <iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon> </a> diff --git a/src/routes/(app)/settings/profile/+page.svelte b/src/routes/(app)/settings/profile/+page.svelte index d4a54a9f..e7a60677 100644 --- a/src/routes/(app)/settings/profile/+page.svelte +++ b/src/routes/(app)/settings/profile/+page.svelte @@ -15,11 +15,11 @@ let username = $state(); let avatarFile, - avatarInput = $state(), + avatarInput: any = $state(), bannerFile, password = $state(), revealPassword = $state(), - bannerInput = $state(); + bannerInput: any = $state(); let selectAvatar = () => avatarInput.click(); let selectBanner = () => bannerInput.click(); @@ -31,7 +31,7 @@ let tooLarge = $state({}); - let handleFile = async ({ target }, type) => { + let handleFile = async ({ target }: any, type: string) => { tooLarge[type] = false; let file = target.files[0]; if (!file) return; @@ -45,11 +45,11 @@ } var reader = new FileReader(); - reader.onload = async (e) => { + reader.onload = async (e: any) => { if (type === "picture") { - $avatar.src = e.target.result; + ($avatar as any).src = e.target.result; } else if (type === "banner") { - $bannerStore.src = e.target.result; + ($bannerStore as any).src = e.target.result; } }; @@ -109,9 +109,9 @@ tabindex="0" > <img - src={$avatar?.src || picture} + src={($avatar as any)?.src || picture} class="absolute w-full h-full object-cover object-center visible overflow-hidden" - alt={username} + alt={username as any} /> </div> {:else} @@ -158,7 +158,7 @@ aria-label="Select banner" > <img - src={$bannerStore ? $bannerStore.src : banner} + src={$bannerStore ? ($bannerStore as any).src : banner} class="w-full object-cover object-center visible overflow-hidden h-48 mb-4 hover:opacity-80" alt="Banner" /> @@ -196,7 +196,6 @@ >{$t("user.settings.about")}</label > <textarea - type="text" name="about" bind:value={about} placeholder={$t("user.settings.aboutPlaceholder")} diff --git a/src/routes/(app)/settings/security/+page.svelte b/src/routes/(app)/settings/security/+page.svelte index 8c9f0105..7ce68d11 100644 --- a/src/routes/(app)/settings/security/+page.svelte +++ b/src/routes/(app)/settings/security/+page.svelte @@ -6,6 +6,7 @@ import Qr from "$comp/Qr.svelte"; import { copy, post, success, fail } from "$lib/utils"; import { save, pin as current } from "$lib/store"; + import { getNsec } from "$lib/nostr"; import { invalidate } from "$app/navigation"; import { page } from "$app/stores"; @@ -19,11 +20,11 @@ importing = $state(), newNsec = $state(), nsec = $state(), - otp = $state(), - pin = $state(""), + otp: any = $state(), + pin: any = $state(""), revealSeed, revealNsec = $state(), - token = $state(""), + token: any = $state(""), setting2fa = $state(), settingPin = $state(), verify = $state(""); @@ -51,13 +52,13 @@ } }; - let checkPin = async () => { + let checkPin = async (_?: any) => { try { - if (pin.length > 5 && pin === verify) { + if (pin && pin.length > 5 && pin === verify) { $current = pin; pin = ""; verify = ""; - $save.click(); + ($save as any).click(); settingPin = false; verifying = false; } else { @@ -85,7 +86,7 @@ try { disablingPin = true; await tick(); - $save.click(); + ($save as any).click(); } catch (e) { console.log(e); fail("Failed to disable pin"); @@ -109,7 +110,7 @@ let startDisabling2fa = () => (disabling2fa = true); let startConfirming2fa = () => (confirming2fa = true); - let cancel = () => { + let cancel: any = () => { pin = null; token = null; verifying = false; @@ -119,9 +120,9 @@ disabling2fa = false; }; - let enable2fa = async (twoFa) => { + let enable2fa = async (twoFa?: any) => { try { - if (setting2fa && token.length === 6) { + if (setting2fa && token && token.length === 6) { await post("/enable2fa", { token }); success("2FA enabled"); user.twofa = 1; @@ -133,9 +134,9 @@ } }; - let disable2fa = async () => { + let disable2fa = async (_?: any) => { try { - if (disabling2fa && token.length === 6) { + if (disabling2fa && token && token.length === 6) { await post("/disable2fa", { token }); success("2FA disabled"); delete user.twofa; @@ -148,9 +149,9 @@ }; let verifying = $derived(pin?.length > 5); - $effect(() => verify && checkPin(pin)); - $effect(() => setting2fa && enable2fa(token)); - $effect(() => disabling2fa && disable2fa(token)); + $effect(() => { if (verify) checkPin(pin as any); }); + $effect(() => { if (setting2fa) enable2fa(token as any); }); + $effect(() => { if (disabling2fa) disable2fa(token as any); }); </script> <input type="hidden" name="newpin" value={disablingPin ? "delete" : pin} /> @@ -195,7 +196,7 @@ {#if setting2fa} <a href={otp.uri}> - <Qr text={otp.uri} /> + <Qr text={otp.uri} icon="" /> </a> <div class="text-center my-4"> @@ -226,7 +227,6 @@ bind:value={token} title="Enter 2FA Code" {cancel} - persist={false} notify={false} /> {/if} diff --git a/src/routes/(static)/bounties/+page.svelte b/src/routes/(static)/bounties/+page.svelte index 6e8fb12b..3cc269dc 100644 --- a/src/routes/(static)/bounties/+page.svelte +++ b/src/routes/(static)/bounties/+page.svelte @@ -3,7 +3,7 @@ import { s } from "$lib/utils"; import Amount from "$comp/Amount.svelte"; - let { data } = $props(); + let { data }: any = $props(); let { users } = data; let bounties = [ diff --git a/src/routes/(static)/login/+page.svelte b/src/routes/(static)/login/+page.svelte index 30592625..2f67b48e 100644 --- a/src/routes/(static)/login/+page.svelte +++ b/src/routes/(static)/login/+page.svelte @@ -18,7 +18,7 @@ import { sha256 } from "@noble/hashes/sha2.js"; import { bytesToHex } from "@noble/hashes/utils.js"; - let { data, form } = $props(); + let { data, form }: any = $props(); onMount(() => { if (browser) { @@ -50,16 +50,16 @@ } }); - let cancel = () => (need2fa = false); + let cancel: any = () => { need2fa = false; }; - let username = $state(), - email, - btn = $state(); + let username: string | undefined = $state(), + email: any, + btn: HTMLButtonElement = $state() as any; - $effect(() => form && ({ username, password: $password } = form)); + $effect(() => { if (form) ({ username, password: $password } = form); }); let need2fa = $derived(form?.message === "2fa"); $effect(() => { - if (need2fa && form.token === token) token = ""; + if (need2fa && form?.token === token) token = ""; }); let revealPassword = $state(false); @@ -76,17 +76,17 @@ }); }); - const enhanceLogin = async ({ formData, cancel }) => { + const enhanceLogin = async ({ formData, cancel }: any) => { try { const recaptcha = await getRecaptchaToken(); - formData.set("recaptcha", recaptcha); - } catch (err) { + formData.set("recaptcha", recaptcha as string); + } catch (err: any) { fail(err.message || "captcha failed"); cancel(); return; } - return async ({ result }) => { + return async ({ result }: any) => { if (result.type === "success") { await invalidateAll(); } @@ -124,11 +124,11 @@ try { const recaptcha = await getRecaptchaToken(); - formData.append("loginRedirect", redirect); - formData.append("token", token); + formData.append("loginRedirect", (redirect ?? "") as string); + formData.append("token", token ?? ""); formData.append("event", JSON.stringify(signedEvent)); formData.append("challenge", challenge); - formData.append("recaptcha", recaptcha); + formData.append("recaptcha", recaptcha as string); let response = await fetch("/login?/nostr", { method: "POST", @@ -138,7 +138,7 @@ const result = deserialize(await response.text()); applyAction(result); - } catch (e) { + } catch (e: any) { fail(e.message); } }; @@ -147,7 +147,7 @@ if (!browser) return; const nodeBadge = document.querySelector(".grecaptcha-badge"); if (nodeBadge) { - document.body.removeChild(nodeBadge.parentNode); + document.body.removeChild(nodeBadge.parentNode!); } const scriptSelector = diff --git a/src/routes/(static)/register/+page.svelte b/src/routes/(static)/register/+page.svelte index 38e8cbb0..29aac7df 100644 --- a/src/routes/(static)/register/+page.svelte +++ b/src/routes/(static)/register/+page.svelte @@ -26,7 +26,7 @@ } from "unique-names-generator"; import { sign } from "$lib/nostr"; - let { form, data } = $props(); + let { form, data }: any = $props(); let { challenge } = $derived(data); let recaptchaSiteKey = PUBLIC_RECAPTCHA_SITE_KEY; let isTor = browser && location.hostname.endsWith(".onion"); @@ -51,7 +51,7 @@ } }); - let username = $state(); + let username: string | undefined = $state(); let { index } = $state(data); let revealPassword = $state(false); @@ -65,7 +65,7 @@ } }; - let refresh = async (e) => { + let refresh = async (e: any) => { e.preventDefault(); cleared = false; @@ -92,17 +92,17 @@ } }); - let token = $state(), - formElement; - let code = []; - let redirect; + let token: string = $state(""), + formElement: any; + let code: any[] = []; + let redirect: any; - let cancel = () => (need2fa = false); + let cancel: any = () => { need2fa = false; }; - let email, - btn = $state(); + let email: any, + btn: HTMLButtonElement = $state() as any; - let loading = $state(); + let loading = $state(false); const getRecaptchaToken = () => new Promise((resolve, reject) => { if (isTor) return resolve(""); @@ -115,14 +115,14 @@ }); }); - async function handleSubmit(e) { + async function handleSubmit(e: SubmitEvent) { e.preventDefault(); loading = true; - let data = new FormData(this); - let user = Object.fromEntries(data); - user.username = user.username.replace(/\s*/g, ""); + let data = new FormData(e.target as HTMLFormElement); + let user: Record<string, any> = Object.fromEntries(data); + user.username = (user.username as string).replace(/\s*/g, ""); for (let k in user) { data.set(k, user[k]); @@ -130,8 +130,8 @@ try { const recaptcha = await getRecaptchaToken(); - data.set("recaptcha", recaptcha); - } catch (err) { + data.set("recaptcha", recaptcha as string); + } catch (err: any) { fail(err.message || "captcha failed"); loading = false; return; @@ -141,7 +141,7 @@ if ($avatar) { try { let { hash } = JSON.parse( - await upload($avatar.file, $avatar.type, $avatar.progress, token), + await upload(($avatar as any).file, ($avatar as any).type, ($avatar as any).progress) as string, ); let url = `${$page.url.origin}/api/public/${hash}.webp`; @@ -170,37 +170,37 @@ loading = false; } - let avatarInput = $state(); + let avatarInput: HTMLInputElement = $state() as any; let decr = () => (index = index <= 0 ? 63 : index - 1); let incr = () => (index = index >= 63 ? 0 : index + 1); let selectAvatar = () => avatarInput.click(); let progress; - let handleFile = async ({ target }) => { + let handleFile = async ({ target }: { target: HTMLInputElement }) => { let type = "picture"; - let file = target.files[0]; + let file = target.files![0]; if (!file) return; - if (file.size > 10000000) form.error = "File too large"; + if (file.size > 10000000) form!.error = "File too large"; $avatar = { file, type, progress }; var reader = new FileReader(); - reader.onload = async (e) => { + reader.onload = async (e: any) => { src = e.target.result; }; reader.readAsDataURL(file); }; - let need2fa = $derived(form?.message === "2fa"); - let src = $derived(`/api/public/${punks[index]}.webp`); + let need2fa: any = $derived(form?.message === "2fa"); + let src: string = $derived(`/api/public/${punks[index]}.webp`); $effect(() => { - if (need2fa && form.token === token) token = ""; + if (need2fa && form?.token === token) token = ""; }); $effect(() => { - token && token?.length === 6 && tick().then(() => btn.click()); + token && token.length === 6 && tick().then(() => btn.click()); }); let nostrLogin = async () => { @@ -221,11 +221,11 @@ try { const recaptcha = await getRecaptchaToken(); - formData.append("loginRedirect", redirect); - formData.append("token", token); + formData.append("loginRedirect", redirect ?? ""); + formData.append("token", token ?? ""); formData.append("event", JSON.stringify(signedEvent)); formData.append("challenge", challenge); - formData.append("recaptcha", recaptcha); + formData.append("recaptcha", recaptcha as string); let response = await fetch("/login?/nostr", { method: "POST", @@ -239,7 +239,7 @@ } applyAction(result); - } catch (e) { + } catch (e: any) { fail(e.message); } }; @@ -248,7 +248,7 @@ if (!browser) return; const nodeBadge = document.querySelector(".grecaptcha-badge"); if (nodeBadge) { - document.body.removeChild(nodeBadge.parentNode); + document.body.removeChild(nodeBadge.parentNode!); } const scriptSelector = @@ -274,7 +274,7 @@ type="file" class="hidden!" bind:this={avatarInput} - onchange={(e) => handleFile(e, "picture")} + onchange={(e: any) => handleFile(e)} /> <div class="relative"> diff --git a/src/routes/(static)/support/+page.svelte b/src/routes/(static)/support/+page.svelte index 7a2b05a5..c82a6cf9 100644 --- a/src/routes/(static)/support/+page.svelte +++ b/src/routes/(static)/support/+page.svelte @@ -27,7 +27,7 @@ } }); - let submit = (e) => { + let submit = (e: any) => { e.preventDefault(); if (isTor) { post("/post/email", { @@ -58,7 +58,7 @@ if (!browser) return; const nodeBadge = document.querySelector(".grecaptcha-badge"); if (nodeBadge) { - document.body.removeChild(nodeBadge.parentNode); + document.body.removeChild(nodeBadge.parentNode!); } const scriptSelector = @@ -119,7 +119,6 @@ > <textarea rows={5} - type="text" name="message" bind:value={message} required |
