From ec304f8bd1ffef69a85b75da033fbccbe6bfc72f Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 5 Feb 2026 09:34:30 -0800 Subject: fix ark payment notifications --- src/routes/(app)/+layout.svelte | 28 +++++++++++++--- src/routes/(app)/account/[id]/+page.svelte | 38 +++++++++++++++++++--- src/routes/(app)/account/ark/+page.svelte | 28 ++++++++++++++++ src/routes/(app)/account/pass/+page.svelte | 28 ++++++++++++++++ src/routes/(app)/invoice/[id]/tip/+page.svelte | 8 ++--- .../[address]/[amount]/[...feeRate]/+page.svelte | 28 ++++++++++++++-- 6 files changed, 141 insertions(+), 17 deletions(-) (limited to 'src/routes') diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index 3a399c3a..c56a487a 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -46,10 +46,30 @@ } }); + // Track last known Ark balance to compute incoming amount + let getLastArkBalance = () => { + return parseInt(localStorage.getItem("lastArkBalance") || "0"); + }; + + let setLastArkBalance = (bal) => { + localStorage.setItem("lastArkBalance", bal.toString()); + }; + let handleArkPayment = async (notification) => { console.log("ARK payment notification:", notification); - let amount = notification.newVtxos.reduce((a, b) => a + b.value, 0); - if (!amount) return; + + // Calculate current total from newVtxos + let currentTotal = notification.newVtxos.reduce((a, b) => a + b.value, 0); + let lastBalance = getLastArkBalance(); + + // Compute delta (incoming amount) + let amount = currentTotal - lastBalance; + + // Update tracked balance + setLastArkBalance(currentTotal); + + // Only process positive incoming amounts + if (amount <= 0) return; if ($fiat && $rateStore && user?.currency) { success(`Received ${f(toFiat(amount, $rateStore), user.currency)}!`); @@ -58,12 +78,12 @@ } try { - let inv = await post(`/invoice`, { + let inv = await post(`/post/invoice`, { invoice: { type: "ark", amount }, user, }); - await post(`/ark/receive`, { + await post(`/post/ark/receive`, { amount, iid: inv.id, }); diff --git a/src/routes/(app)/account/[id]/+page.svelte b/src/routes/(app)/account/[id]/+page.svelte index a8970ca7..db93a04d 100644 --- a/src/routes/(app)/account/[id]/+page.svelte +++ b/src/routes/(app)/account/[id]/+page.svelte @@ -8,6 +8,10 @@ import { t } from "$lib/translations"; import { entropyToMnemonic, mnemonicToSeed } from "@scure/bip39"; import { wordlist } from "@scure/bip39/wordlists/english.js"; + import { + getRememberedWalletPassword, + forgetWalletPassword, + } from "$lib/passwordCache"; let { data } = $props(); let { account, user } = data; @@ -26,12 +30,36 @@ let cancel = $state(() => (passwordPrompt = false)); let toggle = () => (passwordPrompt = !passwordPrompt); + let revealWithCachedPassword = async () => { + const cached = getRememberedWalletPassword(); + if (!cached) return false; + try { + const { decrypt } = await import("nostr-tools/nip49"); + let entropy = await decrypt(seed, cached); + mnemonic = entropyToMnemonic(entropy, wordlist); + password = cached; + return true; + } catch (e) { + forgetWalletPassword(); + return false; + } + }; - let submit = $state(async () => { + let requestMnemonic = async () => { + if (await revealWithCachedPassword()) return; toggle(); - const { decrypt } = await import("nostr-tools/nip49"); - let entropy = await decrypt(seed, password); - mnemonic = entropyToMnemonic(entropy, wordlist); + }; + + let submit = $state(async () => { + passwordPrompt = false; + try { + const { decrypt } = await import("nostr-tools/nip49"); + let entropy = await decrypt(seed, password); + mnemonic = entropyToMnemonic(entropy, wordlist); + } catch (e) { + fail("Invalid password, try again"); + passwordPrompt = true; + } }); let del = async () => { @@ -71,7 +99,7 @@
{$t("accounts.copy")}
{:else if seed} - +
+ + +
+