From 523ed462ae82383e1c2cca172a49dce05d619c96 Mon Sep 17 00:00:00 2001 From: martinshub-tech Date: Mon, 31 Aug 2026 08:45:39 +0100 Subject: [PATCH] fix: drop retry for read-only simulations to prevent slow UX on 404s --- lib/queryClient.ts | 2 ++ lib/soroban.ts | 63 +++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/lib/queryClient.ts b/lib/queryClient.ts index 080db99..c8c3fb9 100644 --- a/lib/queryClient.ts +++ b/lib/queryClient.ts @@ -1,5 +1,6 @@ import { QueryClient } from '@tanstack/react-query'; import { queryKeys } from './query-keys'; +import toast from 'react-hot-toast'; export function makeQueryClient(): QueryClient { return new QueryClient({ @@ -47,5 +48,6 @@ export async function refreshStreamData(): Promise { ]); } catch (error) { console.warn('Failed to refresh stream data after a transaction.', error); + toast.error('Failed to refresh data. Please refresh the page manually.'); } } diff --git a/lib/soroban.ts b/lib/soroban.ts index 07fac9c..d88edb6 100644 --- a/lib/soroban.ts +++ b/lib/soroban.ts @@ -549,45 +549,40 @@ export async function simulateReadOnly( validateTimeout(timeoutMs); if (signal?.aborted) throw new OperationAbortedError(); - return withRetry(async () => { - const account = await withTimeout( - getServer().getAccount(source), - timeoutMs, - 'simulateReadOnly/getAccount', - signal, - ); - const fee = await getInclusionFee(timeoutMs, signal); - const contract = new Contract(contractId); - const tx = new TransactionBuilder(account, { - fee, - networkPassphrase: getNetworkPassphrase(), - }) - .addOperation(contract.call(method, ...args)) - .setTimeout(60) - .build(); + const account = await withTimeout( + getServer().getAccount(source), + timeoutMs, + 'simulateReadOnly/getAccount', + signal, + ); + const fee = await getInclusionFee(timeoutMs, signal); + const contract = new Contract(contractId); + const tx = new TransactionBuilder(account, { + fee, + networkPassphrase: getNetworkPassphrase(), + }) + .addOperation(contract.call(method, ...args)) + .setTimeout(60) + .build(); - if (signal?.aborted) throw new OperationAbortedError(); + if (signal?.aborted) throw new OperationAbortedError(); - const result = await withTimeout( - getServer().simulateTransaction(tx), - timeoutMs, - 'simulateTransaction', - signal, - ); + const result = await withTimeout( + getServer().simulateTransaction(tx), + timeoutMs, + 'simulateTransaction', + signal, + ); - if (signal?.aborted) throw new OperationAbortedError(); + if (signal?.aborted) throw new OperationAbortedError(); - if (SorobanRpc.Api.isSimulationError(result)) { - throw new Error(`Simulation error: ${result.error}`); - } - const retval = result.result?.retval; - if (!retval) throw new Error('No result returned from simulation'); + if (SorobanRpc.Api.isSimulationError(result)) { + throw new Error(`Simulation error: ${result.error}`); + } + const retval = result.result?.retval; + if (!retval) throw new Error('No result returned from simulation'); - return xdr.ScVal.fromXDR(retval.toXDR()); - }, { - context: `simulateReadOnly(${method})`, - signal, - }); + return xdr.ScVal.fromXDR(retval.toXDR()); } // ── Helpers ───────────────────────────────────────────────────────────────────