From 80d5549db025afe62f30814713d9c28641668295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josip=20Boj=C4=8Di=C4=87?= Date: Mon, 30 Mar 2026 16:15:41 +0200 Subject: [PATCH] Temporarily remove spark balance workaround --- app/features/accounts/account-hooks.ts | 54 ++++++----- app/features/shared/spark.ts | 126 +++---------------------- 2 files changed, 45 insertions(+), 135 deletions(-) diff --git a/app/features/accounts/account-hooks.ts b/app/features/accounts/account-hooks.ts index af518d28..06bf4602 100644 --- a/app/features/accounts/account-hooks.ts +++ b/app/features/accounts/account-hooks.ts @@ -54,44 +54,50 @@ export class AccountsCache { // This is used for a Spark bug workaround in useTrackAndUpdateSparkAccountBalances hook. // Once the bug is resolved we can change this function to simply update the account balance if changed. // TODO: Update when Spark bug is fixed and workaround is removed. - updateSparkAccountIfBalanceOrWalletChanged(account: SparkAccount) { + updateSparkAccountBalance({ + accountId, + availableBalance, + ownedBalance, + }: { + accountId: string; + availableBalance: Money; + ownedBalance: Money; + }) { this.queryClient.setQueryData([AccountsCache.Key], (curr: Account[]) => curr.map((x) => { - if (x.id !== account.id || x.type !== 'spark') return x; + if (x.id !== accountId || x.type !== 'spark') return x; - const versionOk = account.version >= x.version; - const balanceChanged = this.hasDifferentBalanceOrWallet(x, account); - const willUpdate = versionOk && balanceChanged; + const balanceChanged = this.hasDifferentBalance(x, { + availableBalance, + ownedBalance, + }); sparkDebugLog('Cache update check', { - accountId: account.id, - cachedVersion: String(x.version), - incomingVersion: String(account.version), - versionOk: String(versionOk), - balanceChanged: String(balanceChanged), - willUpdate: String(willUpdate), + accountId, + willUpdate: balanceChanged, + newAvailableBalance: availableBalance.toString(), + newOwnedBalance: ownedBalance.toString(), }); - return willUpdate ? account : x; + return balanceChanged ? { ...x, availableBalance, ownedBalance } : x; }), ); } - private hasDifferentBalanceOrWallet( - accountOne: SparkAccount, - accountTwo: SparkAccount, + private hasDifferentBalance( + account: SparkAccount, + balance: { + availableBalance: Money; + ownedBalance: Money; + }, ) { - const oneOwned = accountOne.ownedBalance ?? Money.zero(accountOne.currency); - const twoOwned = accountTwo.ownedBalance ?? Money.zero(accountTwo.currency); - const oneAvailable = - accountOne.availableBalance ?? Money.zero(accountOne.currency); - const twoAvailable = - accountTwo.availableBalance ?? Money.zero(accountTwo.currency); + const accountOwned = account.ownedBalance ?? Money.zero(account.currency); + const accountAvailable = + account.availableBalance ?? Money.zero(account.currency); return ( - !oneOwned.equals(twoOwned) || - !oneAvailable.equals(twoAvailable) || - accountOne.wallet !== accountTwo.wallet + !accountOwned.equals(balance.ownedBalance) || + !accountAvailable.equals(balance.availableBalance) ); } diff --git a/app/features/shared/spark.ts b/app/features/shared/spark.ts index 4e42402e..19efd175 100644 --- a/app/features/shared/spark.ts +++ b/app/features/shared/spark.ts @@ -7,9 +7,7 @@ import { type QueryClient, queryOptions, useQueries, - useQueryClient, } from '@tanstack/react-query'; -import { useEffect, useRef } from 'react'; import { type Currency, Money } from '~/lib/money'; import { measureOperation } from '~/lib/performance'; import { computeSHA256 } from '~/lib/sha256'; @@ -108,27 +106,6 @@ export function sparkBalanceQueryKey(accountId: string) { export function useTrackAndUpdateSparkAccountBalances() { const { data: sparkAccounts } = useAccounts({ type: 'spark' }); const accountCache = useAccountsCache(); - const queryClient = useQueryClient(); - - // Needed for workaround below. - // TODO: Remove when workaround is removed. - const verifiedZeroBalanceAccounts = useRef(new Set()); - - useEffect(() => { - const clear = () => verifiedZeroBalanceAccounts.current.clear(); - - const onVisibilityChange = () => { - if (document.visibilityState === 'visible') clear(); - }; - - document.addEventListener('visibilitychange', onVisibilityChange); - window.addEventListener('online', clear); - return () => { - document.removeEventListener('visibilitychange', onVisibilityChange); - window.removeEventListener('online', clear); - }; - }, []); - // end workaround useQueries({ queries: sparkAccounts.map((account) => ({ @@ -155,108 +132,35 @@ export function useTrackAndUpdateSparkAccountBalances() { { accountId: account.id }, ); - sparkDebugLog('Balance fetched from Spark SDK', { - accountId: account.id, - owned: String(satsBalance.owned), - available: String(satsBalance.available), - }); - - // WORKAROUND: Spark SDK sometimes returns 0 for balance incorrectly. - // The bug seems to be resolved after the wallet is reinitialized. - // Reinitialize the wallet and re-check balance. - // TODO: Remove when Spark fixes the bug. - let effectiveOwnedBalance = satsBalance.owned; - let effectiveAvailableBalance = satsBalance.available; - let effectiveWallet = account.wallet; - if (Number(satsBalance.owned) === 0) { - if (!verifiedZeroBalanceAccounts.current.has(account.id)) { - try { - const { - ownedBalance: freshOwnedBalance, - availableBalance: freshAvailableBalance, - wallet: newWallet, - } = await measureOperation( - 'SparkWallet.balanceRecovery', - async () => { - console.warn( - '[Spark] Balance returned 0, reinitializing wallet', - { - accountId: account.id, - network: account.network, - }, - ); - - const mnemonic = await queryClient.fetchQuery( - sparkMnemonicQueryOptions(), - ); - const newWallet = await queryClient.fetchQuery({ - ...sparkWalletQueryOptions({ - network: account.network, - mnemonic, - }), - staleTime: 0, // Forces a refetch - }); - - const { satsBalance: freshSatsBalance } = - await newWallet.getBalance(); - return { - ownedBalance: freshSatsBalance.owned, - availableBalance: freshSatsBalance.available, - wallet: newWallet, - }; - }, - { accountId: account.id }, - ); - - effectiveOwnedBalance = freshOwnedBalance; - effectiveAvailableBalance = freshAvailableBalance; - effectiveWallet = newWallet; - - if (Number(freshOwnedBalance) === 0) { - verifiedZeroBalanceAccounts.current.add(account.id); - } - } catch (error) { - console.error('Failed to reinitialize Spark wallet', { - cause: error, - accountId: account.id, - }); - return satsBalance.owned; - } - } - } else { - verifiedZeroBalanceAccounts.current.delete(account.id); - } - // END WORKAROUND - const newOwnedBalance = new Money({ - amount: Number(effectiveOwnedBalance), + amount: Number(satsBalance.owned), currency: account.currency as Currency, unit: getDefaultUnit(account.currency), }); const newAvailableBalance = new Money({ - amount: Number(effectiveAvailableBalance), + amount: Number(satsBalance.available), currency: account.currency as Currency, unit: getDefaultUnit(account.currency), }); - sparkDebugLog('Updating accounts cache', { + sparkDebugLog( + 'Balance fetched from Spark SDK. Will update accounts cache', + { + accountId: account.id, + prevOwned: account.ownedBalance?.toString() ?? 'null', + newOwned: newOwnedBalance.toString(), + prevAvailable: account.availableBalance?.toString() ?? 'null', + newAvailable: newAvailableBalance.toString(), + accountVersion: String(account.version), + }, + ); + accountCache.updateSparkAccountBalance({ accountId: account.id, - prevOwned: account.ownedBalance?.toString() ?? 'null', - newOwned: newOwnedBalance.toString(), - prevAvailable: account.availableBalance?.toString() ?? 'null', - newAvailable: newAvailableBalance.toString(), - walletChanged: String(effectiveWallet !== account.wallet), - accountVersion: String(account.version), - }); - - accountCache.updateSparkAccountIfBalanceOrWalletChanged({ - ...account, - wallet: effectiveWallet, ownedBalance: newOwnedBalance, availableBalance: newAvailableBalance, }); - return effectiveOwnedBalance; + return satsBalance.owned; }, staleTime: Number.POSITIVE_INFINITY, gcTime: Number.POSITIVE_INFINITY,