diff --git a/src/app/(mobile-ui)/history/page.tsx b/src/app/(mobile-ui)/history/page.tsx index 903b560c8..4c0e4242f 100644 --- a/src/app/(mobile-ui)/history/page.tsx +++ b/src/app/(mobile-ui)/history/page.tsx @@ -65,7 +65,6 @@ const HistoryPage = () => { // Fallback: Use raw entry with proper amount formatting let fallbackAmount = newEntry.amount.toString() - // For DEPOSIT entries, amount is in wei and needs formatting if (newEntry.type === 'DEPOSIT' && newEntry.extraData?.blockNumber) { try { fallbackAmount = formatUnits(BigInt(newEntry.amount), PEANUT_WALLET_TOKEN_DECIMALS) diff --git a/src/components/Claim/Link/Initial.view.tsx b/src/components/Claim/Link/Initial.view.tsx index 17a6f5ef4..0f81be943 100644 --- a/src/components/Claim/Link/Initial.view.tsx +++ b/src/components/Claim/Link/Initial.view.tsx @@ -542,6 +542,7 @@ export const InitialClaimLinkView = (props: IClaimScreenProps) => { console.error('Error fetching route:', error) if (!toToken && !toChain) { setSelectedRoute(undefined) + setHasFetchedRoute(true) // Mark as fetched to show error and allow retry } setErrorState({ showError: true, @@ -685,7 +686,7 @@ export const InitialClaimLinkView = (props: IClaimScreenProps) => { ) } - if (selectedRoute || (isXChain && hasFetchedRoute)) { + if (selectedRoute) { return 'Review' } @@ -693,6 +694,10 @@ export const InitialClaimLinkView = (props: IClaimScreenProps) => { return 'Receiving' } + if (isXChain && hasFetchedRoute && !selectedRoute) { + return 'Retry' + } + return 'Receive now' } @@ -708,9 +713,11 @@ export const InitialClaimLinkView = (props: IClaimScreenProps) => { } else if (recipientType === 'iban' || recipientType === 'us') { handleIbanRecipient() } else if (!isPeanutChain) { - if (selectedRoute || (isXChain && hasFetchedRoute)) { + if (selectedRoute) { + // Only proceed if we have a valid route onNext() } else if (isXChain) { + // No route yet or route fetch failed - trigger refetch setRefetchXchainRoute(true) } } else { diff --git a/src/components/Payment/PaymentForm/index.tsx b/src/components/Payment/PaymentForm/index.tsx index deaf38a98..61e87a50f 100644 --- a/src/components/Payment/PaymentForm/index.tsx +++ b/src/components/Payment/PaymentForm/index.tsx @@ -185,8 +185,9 @@ export const PaymentForm = ({ }, [dispatch, recipient]) useEffect(() => { - // Skip balance check if on CONFIRM or STATUS view (balance has been optimistically updated) - if (currentView === 'CONFIRM' || currentView === 'STATUS') { + // Skip balance check if on CONFIRM or STATUS view, or if transaction is being processed + // (balance has been optimistically updated in these states) + if (currentView === 'CONFIRM' || currentView === 'STATUS' || isProcessing) { return } @@ -274,6 +275,7 @@ export const PaymentForm = ({ isExternalWalletConnected, isExternalWalletFlow, currentView, + isProcessing, ]) // fetch token price diff --git a/src/services/sendLinks.ts b/src/services/sendLinks.ts index b45faf00c..78c3df69e 100644 --- a/src/services/sendLinks.ts +++ b/src/services/sendLinks.ts @@ -119,9 +119,12 @@ export const sendLinksApi = { get: async (link: string): Promise => { const params = getParamsFromLink(link) const pubKey = generateKeysFromString(params.password).address - const url = `${PEANUT_API_URL}/send-links/${pubKey}?c=${params.chainId}&v=${params.contractVersion}&i=${params.depositIdx}` + // Add timestamp to prevent caching of 404s during DB replication lag + const cacheBuster = Date.now() + const url = `${PEANUT_API_URL}/send-links/${pubKey}?c=${params.chainId}&v=${params.contractVersion}&i=${params.depositIdx}&_=${cacheBuster}` const response = await fetchWithSentry(url, { method: 'GET', + cache: 'no-store', // Prevent browser from caching responses }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) diff --git a/src/utils/history.utils.ts b/src/utils/history.utils.ts index 09accb163..ab9cc593d 100644 --- a/src/utils/history.utils.ts +++ b/src/utils/history.utils.ts @@ -255,7 +255,10 @@ export async function completeHistoryEntry(entry: HistoryEntry): Promise