fix(payments): request pot balance validation and navigation issues#1373
fix(payments): request pot balance validation and navigation issues#1373Hugo0 merged 2 commits intopeanut-wallet-devfrom
Conversation
- Always check balance for Peanut wallet payments (including request pots) - Stabilize payment method sorting with useCallback - Fix add-money back button to respect browser history
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. WalkthroughUnconditionally enable Peanut Wallet balance checks (including request-pot initial view), stabilize payment-method availability callbacks, add an onBeforeShow interception to Daimo pay flows, change add-money back navigation to prefer router.back() with a /home fallback, and refine early-return/charge handling in payment initiation. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Possibly related PRs
Suggested labelsenhancement Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
Comment |
|
@coderabbitai review in depth |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 30718 @Hugo0, I'll conduct an in-depth review of this PR. Let me analyze each change carefully. 📊 Overall AssessmentThis PR addresses three critical UX bugs with well-documented fixes. The changes are focused and surgical, but I found several areas that need attention. 🔍 Detailed File-by-File Analysis1. src/components/Payment/PaymentForm/index.tsx
|
| Priority | File | Issue | Recommendation |
|---|---|---|---|
| 🔴 HIGH | add-money/page.tsx | window.history.length unreliable |
Use referrer check or Next.js router state |
| 🔴 HIGH | ActionList.tsx | Race condition in payment method selection | Use functional state update or pass method to modal |
| 🟡 MEDIUM | PaymentForm/index.tsx | Missing null checks in balance validation | Add null/NaN guards before comparison |
| 🟡 MEDIUM | usePaymentInitiator.ts | Complex triple-negative logic | Refactor with explicit variable names |
| 🟢 LOW | ActionList.tsx | State clearing timing in modal | Clear state after async operation completes |
Would you like me to generate code snippets for any of these fixes? Also, should I create follow-up issues for the test coverage gaps?
🏁 Script executed:
#!/bin/bash
# Check if there are existing tests for the modified files
echo "=== Checking for test files ==="
fd -e test.tsx -e test.ts -e spec.tsx -e spec.ts | grep -E "(PaymentForm|ActionList|add-money|usePaymentInitiator)"
echo -e "\n=== Checking for router usage patterns in codebase ==="
rg -n "router\.back\(\)" --type=tsx --type=ts -C2
echo -e "\n=== Checking for window.history usage patterns ==="
rg -n "window\.history" --type=tsx --type=ts -C2
Length of output: 195
🏁 Script executed:
#!/bin/bash
# Check if there are existing tests for the modified files
echo "=== Checking for test files ==="
fd -e test.tsx -e test.ts -e spec.tsx -e spec.ts | grep -E "(PaymentForm|ActionList|add-money|usePaymentInitiator)" || echo "No test files found for modified components"
echo -e "\n=== Checking for router usage patterns in codebase ==="
rg -n "router\.back\(\)" -g "*.tsx" -g "*.ts" -C2 | head -50
echo -e "\n=== Checking for window.history usage patterns ==="
rg -n "window\.history" -g "*.tsx" -g "*.ts" -C2
echo -e "\n=== Checking how other components handle back navigation ==="
rg -n "onBackClick" -g "*.tsx" -g "*.ts" -C2 | head -50
echo -e "\n=== Checking for useCallback usage patterns with sorting/filtering ==="
rg -n "useCallback.*sort|useCallback.*filter" -g "*.tsx" -g "*.ts" -C3 | head -50
Length of output: 13633
🏁 Script executed:
#!/bin/bash
# Check for checkIfInternalNavigation function
echo "=== Finding checkIfInternalNavigation function ==="
rg -n "checkIfInternalNavigation" -g "*.tsx" -g "*.ts" -B5 -A10
echo -e "\n=== Check PaymentForm balance validation patterns ==="
rg -n "peanutWalletBalance" -g "*.tsx" -g "*.ts" -C3 | head -100
echo -e "\n=== Check for similar insufficient balance error handling ==="
rg -n "Insufficient balance" -g "*.tsx" -g "*.ts" -C2
echo -e "\n=== Check how skipChargeCreation is used ==="
rg -n "skipChargeCreation" -g "*.tsx" -g "*.ts" -C3
Length of output: 23815
🔄 Updated Analysis Based on Codebase Patterns
After examining the codebase, I found important context that changes some of my recommendations:
Critical Finding: Inconsistent Navigation Pattern 🔴
Your codebase has a utility function checkIfInternalNavigation() that properly detects internal navigation:
// src/utils/general.utils.ts
export function checkIfInternalNavigation(): boolean {
return !!document.referrer && new URL(document.referrer).origin === window.location.origin
}This is used in Profile and PublicProfile components:
const isInternalReferrer = checkIfInternalNavigation()
if (isInternalReferrer && window.history.length > 1) {
router.back()
} else {
router.push('/home')
}But your PR's add-money/page.tsx is NOT using it! This creates inconsistency and breaks the navigation pattern used elsewhere.
Recommended Fix for add-money/page.tsx:
import { checkIfInternalNavigation } from '@/utils'
const handleBack = () => {
const isInternalReferrer = checkIfInternalNavigation()
if (isInternalReferrer && window.history.length > 1) {
router.back()
} else {
router.push('/home')
}
}This matches the pattern in your Profile components and provides more reliable internal navigation detection.
📊 Updated Priority Recommendations
| Priority | File | Issue | Fix |
|---|---|---|---|
| 🔴 CRITICAL | add-money/page.tsx | Not using checkIfInternalNavigation() |
Use existing utility function for consistency |
| 🟡 MEDIUM | ActionList.tsx | Race condition in payment method selection | Use functional state update |
| 🟡 MEDIUM | PaymentForm/index.tsx | Missing null checks (low risk - codebase pattern) | Add guards for safety |
| 🟢 LOW | usePaymentInitiator.ts | Complex logic but correct per semantics | Consider refactor for clarity later |
✅ Positive Findings:
- Excellent documentation - The markdown file is comprehensive and well-structured
- useCallback fix is correct - Properly stabilizes the function reference with correct dependencies
- Balance check removal is correct - The original guard was indeed wrong
- skipChargeCreation logic is actually correct - It properly distinguishes prepare mode from confirm mode
🔧 Ready-to-Use Fix:
Here's the corrected add-money/page.tsx:
'use client'
import AddWithdrawRouterView from '@/components/AddWithdraw/AddWithdrawRouterView'
import { useOnrampContext } from '@/context/onramp/onrampContext'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'
import { checkIfInternalNavigation } from '@/utils'
export default function AddMoneyPage() {
const router = useRouter()
const { resetOnrampFlow } = useOnrampContext()
useEffect(() => {
resetOnrampFlow()
}, [])
const handleBack = () => {
const isInternalReferrer = checkIfInternalNavigation()
if (isInternalReferrer && window.history.length > 1) {
router.back()
} else {
router.push('/home')
}
}
return (
<AddWithdrawRouterView
flow="add"
pageTitle="Add Money"
mainHeading="Where to add money from?"
onBackClick={handleBack}
/>
)
}🎯 Final Verdict:
The PR correctly fixes the stated issues, but has one consistency issue with the navigation pattern. The balance check fix and sorting stabilization are solid.
Would you like me to:
- Create a follow-up issue for the ActionList race condition?
- Open an issue for adding test coverage?
- Should I prepare a suggestion for the navigation fix?
🧠 Learnings used
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#823
File: src/context/kernelClient.context.tsx:79-86
Timestamp: 2025-04-29T19:36:38.121Z
Learning: When Hugo0 asks to "resolve coderabbit comments", they want to acknowledge the comment without necessarily implementing the suggested changes, as the current implementation might be intentional for their specific use case.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#594
File: src/components/Request/Pay/Views/Initial.view.tsx:188-213
Timestamp: 2024-12-31T15:08:15.640Z
Learning: Always resolve coderabbit comments when reviewing code, since they can contain useful suggestions.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#852
File: src/hooks/useTransactionHistory.ts:177-239
Timestamp: 2025-05-14T21:16:06.369Z
Learning: When reviewing code, pay attention to and resolve CodeRabbit comments as they can contain useful refactoring suggestions and insights.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#942
File: src/components/AddMoney/consts/index.ts:2151-2162
Timestamp: 2025-06-30T10:44:08.048Z
Learning: Hugo0 often agrees with refactoring suggestions but defers implementation due to time constraints, preferring to track improvements as follow-up issues when they're part of larger architectural changes.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/Payment/PaymentForm/index.tsx (1)
372-380: Redirect never triggers because the error flag is never set
handleInitiatePaymentnow pivots onisInsufficientBalanceError, but the balance guard above dispatches'Insufficient balance', whileisInsufficientBalanceErroronly matches"You don't have enough balance.". The new redirect, button label, and enabled state therefore never engage—users see the error yet cannot proceed to Add Money (the button stays disabled), which is a regression in every insufficient-peanut-balance flow. Align the detection with the dispatched copy (or vice versa) so the condition actually flips.- return error?.includes("You don't have enough balance.") + return ( + !!error && + (error.includes("You don't have enough balance.") || error.includes('Insufficient balance')) + )
🧹 Nitpick comments (2)
src/components/Common/ActionListDaimoPayButton.tsx (1)
1-1: Remove unuseduseEffectimport.The
useEffectimport on line 1 is not used anywhere in the file and should be removed:import { useCallback, useState, useRef } from 'react'src/hooks/usePaymentInitiator.ts (1)
2-2: Remove unused imports and variables.Verification confirms these are genuinely unused and can be safely removed:
BALANCE_DECREASEandINITIATE_PAYMENT(line 2) — imported but never referenced in codeuseQueryClientimport (line 30) andqueryClientvariable (line 87) — initialized but never usedRemoving them will reduce unnecessary dependencies and cleanup dead code.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
docs/fixes/request-pot-balance-and-navigation-fixes.md(1 hunks)src/app/(mobile-ui)/add-money/page.tsx(1 hunks)src/components/Common/ActionList.tsx(6 hunks)src/components/Common/ActionListDaimoPayButton.tsx(4 hunks)src/components/Payment/PaymentForm/index.tsx(5 hunks)src/hooks/usePaymentInitiator.ts(5 hunks)
🧰 Additional context used
🧠 Learnings (29)
📓 Common learnings
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1185
File: src/components/Claim/useClaimLink.tsx:14-0
Timestamp: 2025-09-05T07:31:11.396Z
Learning: In the peanut-ui codebase, `window.history.replaceState` is preferred over `router.replace` when immediate/synchronous URL parameter updates are required, as `router.replace` is asynchronous and doesn't guarantee instant URL changes that subsequent code can rely on. This pattern is used consistently across usePaymentInitiator.ts, Confirm.payment.view.tsx, and useClaimLink.tsx.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#1190
File: src/app/(mobile-ui)/qr-pay/page.tsx:156-176
Timestamp: 2025-09-08T03:13:09.111Z
Learning: In the peanut-ui mobile app, the `/qr-pay` route is only accessed through the DirectSendQR component which always includes the qrCode parameter in the URL when redirecting users to the QR pay page.
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1104
File: src/components/Payment/PaymentForm/index.tsx:522-545
Timestamp: 2025-08-22T07:28:32.281Z
Learning: In `src/components/Payment/PaymentForm/index.tsx`, the `handleCompleteDaimoPayment` function is only for updating payment status in the backend after a successful Daimo payment. Payment success/failure is handled by Daimo itself, so try/catch error handling and error display are not needed for backend sync failures - users shouldn't see errors if payment succeeded but database update failed.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#942
File: src/components/AddMoney/consts/index.ts:2151-2162
Timestamp: 2025-06-30T10:44:08.048Z
Learning: Hugo0 often agrees with refactoring suggestions but defers implementation due to time constraints, preferring to track improvements as follow-up issues when they're part of larger architectural changes.
📚 Learning: 2025-09-05T07:31:11.396Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1185
File: src/components/Claim/useClaimLink.tsx:14-0
Timestamp: 2025-09-05T07:31:11.396Z
Learning: In the peanut-ui codebase, `window.history.replaceState` is preferred over `router.replace` when immediate/synchronous URL parameter updates are required, as `router.replace` is asynchronous and doesn't guarantee instant URL changes that subsequent code can rely on. This pattern is used consistently across usePaymentInitiator.ts, Confirm.payment.view.tsx, and useClaimLink.tsx.
Applied to files:
src/app/(mobile-ui)/add-money/page.tsxsrc/hooks/usePaymentInitiator.tssrc/components/Common/ActionList.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-05-22T15:38:48.586Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".
Applied to files:
src/app/(mobile-ui)/add-money/page.tsx
📚 Learning: 2025-09-18T09:30:42.901Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1230
File: src/app/(mobile-ui)/withdraw/page.tsx:92-97
Timestamp: 2025-09-18T09:30:42.901Z
Learning: In src/app/(mobile-ui)/withdraw/page.tsx, the useEffect that calls setShowAllWithdrawMethods(true) when amountFromContext exists is intentionally designed to run only on component mount (empty dependency array), not when amountFromContext changes. This is the correct behavior for the withdraw flow where showing all methods should only happen on initial load when an amount is already present.
Applied to files:
src/app/(mobile-ui)/add-money/page.tsxsrc/components/Common/ActionListDaimoPayButton.tsxsrc/components/Common/ActionList.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.md
📚 Learning: 2025-08-22T07:28:32.281Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1104
File: src/components/Payment/PaymentForm/index.tsx:522-545
Timestamp: 2025-08-22T07:28:32.281Z
Learning: In `src/components/Payment/PaymentForm/index.tsx`, the `handleCompleteDaimoPayment` function is only for updating payment status in the backend after a successful Daimo payment. Payment success/failure is handled by Daimo itself, so try/catch error handling and error display are not needed for backend sync failures - users shouldn't see errors if payment succeeded but database update failed.
Applied to files:
src/app/(mobile-ui)/add-money/page.tsxsrc/components/Common/ActionListDaimoPayButton.tsxsrc/components/Common/ActionList.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-23T09:38:04.446Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:04.446Z
Learning: Within `src/app/request/pay/page.tsx`, extracting the `getBaseUrl` function does not add significant readability, and the host URL construction code is expected to change soon.
Applied to files:
src/app/(mobile-ui)/add-money/page.tsx
📚 Learning: 2024-10-18T01:51:35.247Z
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:141-141
Timestamp: 2024-10-18T01:51:35.247Z
Learning: The `handleConfirm` function in `src/components/Create/Link/Confirm.view.tsx` is separate from the one in `src/components/Offramp/Confirm.view.tsx` and does not need to be renamed when refactoring `handleConfirm` in `src/components/Offramp/Confirm.view.tsx`.
Applied to files:
src/app/(mobile-ui)/add-money/page.tsx
📚 Learning: 2024-10-07T15:25:45.170Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:25:45.170Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(...)` return strings, ensuring that `calculatedFee` consistently returns a string without the need for additional type conversion.
Applied to files:
src/hooks/usePaymentInitiator.tssrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-12-02T17:19:18.532Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/components/Request/Create/Views/Initial.view.tsx:151-156
Timestamp: 2024-12-02T17:19:18.532Z
Learning: In the `InitialView` component at `src/components/Request/Create/Views/Initial.view.tsx`, when setting the default chain and token in the `useEffect` triggered by `isPeanutWallet`, it's acceptable to omit the setters from the dependency array and not include additional error handling for invalid defaults.
Applied to files:
src/hooks/usePaymentInitiator.tssrc/components/Common/ActionList.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-01-16T13:14:40.363Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#631
File: src/components/Create/Create.tsx:108-112
Timestamp: 2025-01-16T13:14:40.363Z
Learning: In the Peanut UI codebase, the `resetTokenContextProvider` function from `tokenSelectorContext` is a stable function reference that doesn't change, so it doesn't need to be included in useEffect dependencies.
Applied to files:
src/hooks/usePaymentInitiator.tssrc/components/Common/ActionListDaimoPayButton.tsx
📚 Learning: 2025-06-18T19:56:55.443Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#919
File: src/components/Withdraw/views/Initial.withdraw.view.tsx:87-87
Timestamp: 2025-06-18T19:56:55.443Z
Learning: In withdraw flows for Peanut Wallet, the PeanutActionDetailsCard should always display "USDC" as the token symbol because it shows the amount being withdrawn from the Peanut Wallet (which holds USDC), regardless of the destination token/chain selected by the user. The TokenSelector is used for choosing the withdrawal destination, not the source display.
Applied to files:
src/hooks/usePaymentInitiator.tssrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-10-02T15:23:01.513Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1266
File: src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx:46-57
Timestamp: 2025-10-02T15:23:01.513Z
Learning: In the withdraw flow at src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, the points calculation query intentionally uses crypto.randomUUID() in the queryKey dependency array to bypass React Query caching, ensuring fresh points estimates on every render. This is the intended behavior.
Applied to files:
src/hooks/usePaymentInitiator.ts
📚 Learning: 2024-10-07T13:42:00.443Z
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.tsx:103-111
Timestamp: 2024-10-07T13:42:00.443Z
Learning: When the token price cannot be fetched in `src/components/Request/Pay/Pay.tsx` within the `PayRequestLink` component, set `tokenPriceData.price` to 0 to ensure the UI remains functional. Since Squid uses their own price engine for x-chain fulfillment transactions, this approach will not affect the transaction computation.
Applied to files:
src/hooks/usePaymentInitiator.tssrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-09-08T03:11:00.114Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#1190
File: src/app/(mobile-ui)/qr-pay/page.tsx:31-41
Timestamp: 2025-09-08T03:11:00.114Z
Learning: In QR payment flows, the `createPayment` API call for payment tracking can be non-awaited when called after successful transaction execution, as it's a non-blocking logging operation and doesn't affect the user's success state.
Applied to files:
src/hooks/usePaymentInitiator.ts
📚 Learning: 2025-08-26T15:25:53.328Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1132
File: src/app/[...recipient]/client.tsx:394-397
Timestamp: 2025-08-26T15:25:53.328Z
Learning: In `src/components/Common/ActionListDaimoPayButton.tsx`, the `handleCompleteDaimoPayment` function should not display error messages to users when DB update fails because the Daimo payment itself has succeeded - showing errors would be confusing since the payment was successful.
Applied to files:
src/components/Common/ActionListDaimoPayButton.tsxsrc/components/Common/ActionList.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.md
📚 Learning: 2025-08-26T17:38:37.055Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1132
File: src/components/Common/ActionList.tsx:153-156
Timestamp: 2025-08-26T17:38:37.055Z
Learning: In ActionList.tsx, when there are circular dependency concerns with ACTION_METHODS being imported by other components, the preferred solution is to move ACTION_METHODS to a separate constants file (like src/constants/actionlist.consts.ts) rather than using prop drilling. This centralizes constants management and creates a cleaner dependency graph.
Applied to files:
src/components/Common/ActionListDaimoPayButton.tsxsrc/components/Common/ActionList.tsx
📚 Learning: 2024-10-07T15:50:29.173Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-07T15:50:29.173Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.
Applied to files:
src/components/Common/ActionListDaimoPayButton.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-29T16:06:38.812Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/useCreateLink.tsx:647-657
Timestamp: 2024-10-29T16:06:38.812Z
Learning: In the React code for `useCreateLink` in `src/components/Create/useCreateLink.tsx`, the `switchNetwork` function used within `useCallback` hooks is stable and does not need to be included in the dependency arrays.
Applied to files:
src/components/Common/ActionListDaimoPayButton.tsx
📚 Learning: 2025-07-05T16:58:25.340Z
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#0
File: :0-0
Timestamp: 2025-07-05T16:58:25.340Z
Learning: Hugo0 successfully refactored sessionStorage usage to React Context in the onramp flow, demonstrating preference for centralized state management over browser storage for component-shared state in React applications.
Applied to files:
src/components/Common/ActionListDaimoPayButton.tsx
📚 Learning: 2025-10-29T11:27:59.248Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1368
File: src/components/Common/ActionList.tsx:109-111
Timestamp: 2025-10-29T11:27:59.248Z
Learning: In `src/components/Common/ActionList.tsx`, the `balance` from `useWallet()` hook is always in USDC (as a formatted string), making it directly comparable to USD amounts without conversion. The comparison `Number(balance) >= amountInUsd` is intentional and correct.
Applied to files:
src/components/Common/ActionList.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#413
File: src/components/Request/Pay/Views/Initial.view.tsx:71-72
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, it's acceptable to use the `!` operator in TypeScript to assert that `selectedTokenData` is not `null` or `undefined`, and potential runtime errors from accessing its properties without checks can be disregarded.
Applied to files:
src/components/Common/ActionList.tsxdocs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-07-24T13:26:10.290Z
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#1014
File: src/components/Claim/Link/Initial.view.tsx:413-413
Timestamp: 2025-07-24T13:26:10.290Z
Learning: In the peanut-ui repository, the change from `${SQUID_API_URL}/route` to `${SQUID_API_URL}/v2/route` in src/components/Claim/Link/Initial.view.tsx was a typo fix, not an API migration, as the codebase was already using Squid API v2.
Applied to files:
docs/fixes/request-pot-balance-and-navigation-fixes.md
📚 Learning: 2024-12-11T10:13:22.806Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#564
File: src/components/Request/Pay/Views/Initial.view.tsx:430-430
Timestamp: 2024-12-11T10:13:22.806Z
Learning: In the React TypeScript file `src/components/Request/Pay/Views/Initial.view.tsx`, when reviewing the `InitialView` component, do not flag potential issues with using non-null assertion `!` on the `slippagePercentage` variable, as handling undefined values in this context is considered out of scope.
Applied to files:
docs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-23T09:38:27.670Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:27.670Z
Learning: In `src/app/request/pay/page.tsx`, if `linkRes` is not OK in the `generateMetadata` function, the desired behavior is to use the standard title and preview image without throwing an error.
Applied to files:
docs/fixes/request-pot-balance-and-navigation-fixes.mdsrc/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-07T15:28:25.280Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:28:25.280Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(estimatedGasCost, 3)` return strings, ensuring consistent return types for `calculatedFee`.
Applied to files:
src/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-07-07T20:22:11.092Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Applied to files:
src/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-09-29T18:34:33.596Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1251
File: src/components/Invites/JoinWaitlistPage.tsx:41-55
Timestamp: 2025-09-29T18:34:33.596Z
Learning: In the JoinWaitlistPage component, after successfully accepting an invite via invitesApi.acceptInvite(), calling fetchUser() is sufficient to update the user state and automatically display the app. No manual navigation to /home or other pages is required since the user is already on the home page and the app will be displayed once user.hasAppAccess is updated.
Applied to files:
src/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.tsx:113-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `PayRequestLink` component (`src/components/Request/Pay/Pay.tsx`), when resolving ENS names, handle errors by displaying an appropriate error message to the user if the ENS cannot be resolved.
Applied to files:
src/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-24T12:39:09.318Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#478
File: src/components/Request/Create/Views/Initial.view.tsx:93-94
Timestamp: 2024-10-24T12:39:09.318Z
Learning: In `src/components/Request/Create/Views/Initial.view.tsx`, the `inputValue` variable passed to `peanut.createRequestLink` is expected to be a string.
Applied to files:
src/components/Payment/PaymentForm/index.tsx
🧬 Code graph analysis (4)
src/app/(mobile-ui)/add-money/page.tsx (1)
src/components/AddWithdraw/AddWithdrawRouterView.tsx (1)
AddWithdrawRouterView(50-330)
src/hooks/usePaymentInitiator.ts (2)
src/utils/general.utils.ts (1)
areEvmAddressesEqual(412-419)src/constants/zerodev.consts.ts (2)
PEANUT_WALLET_TOKEN(20-20)PEANUT_WALLET_CHAIN(18-18)
src/components/Common/ActionList.tsx (2)
src/constants/actionlist.consts.ts (1)
PaymentMethod(5-12)src/hooks/useGeoFilteredPaymentOptions.ts (1)
useGeoFilteredPaymentOptions(30-77)
src/components/Payment/PaymentForm/index.tsx (2)
src/utils/general.utils.ts (1)
areEvmAddressesEqual(412-419)src/constants/zerodev.consts.ts (1)
PEANUT_WALLET_TOKEN(20-20)
🪛 LanguageTool
docs/fixes/request-pot-balance-and-navigation-fixes.md
[style] ~3-~3: Some style guides suggest that commas should set off the year in a month-day-year date.
Context: ...Navigation Fixes Date: October 29, 2025 Issues: Balance check skipped, ba...
(MISSING_COMMA_AFTER_YEAR)
[style] ~181-~181: Consider using a different adverb to strengthen your wording.
Context: ...={() => router.push('/home')} ``` This completely ignores the browser's navigation histor...
(COMPLETELY_ENTIRELY)
🪛 markdownlint-cli2 (0.18.1)
docs/fixes/request-pot-balance-and-navigation-fixes.md
29-29: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Deploy-Preview
🔇 Additional comments (6)
src/app/(mobile-ui)/add-money/page.tsx (1)
16-24: LGTM - Navigation fix with sensible fallback.The new back navigation logic properly respects browser history while providing a fallback for direct navigation scenarios. The
window.history.length > 1check is a reasonable heuristic, though note that in some edge cases (e.g., after a full page reload), this might still redirect to home instead of the expected previous page. This is acceptable given the complexity of tracking navigation state across page reloads.src/components/Common/ActionListDaimoPayButton.tsx (1)
149-166: LGTM - Well-structured interception flow.The
onBeforeShowhook provides a clean extension point for pre-payment checks. The three-phase flow (parent interception → invite modal → payment initiation) is logical and properly handles async operations with early returns.src/hooks/usePaymentInitiator.ts (1)
644-666: LGTM - Guard prevents premature payment execution.The new
shouldReturnAfterChargelogic correctly addresses the bug where fetching an existing charge withoutskipChargeCreation=truewould prematurely execute payment. The condition at lines 656-658 ensures that when a charge already exists and we're not explicitly skipping charge creation (meaning we're in "prepare" mode from the INITIAL view), the function returns early without executing the payment.This aligns with the two-phase flow: charge preparation (no balance mutation) followed by explicit payment execution (balance decrease).
docs/fixes/request-pot-balance-and-navigation-fixes.md (1)
1-295: Excellent documentation practice.This comprehensive documentation file is exemplary. It clearly explains:
- The root causes of each issue
- Why previous approaches were wrong
- The fixes applied with before/after code examples
- Testing checklists
Minor optional improvements flagged by linters:
- Line 3: Consider adding a comma after the year in the date format
- Line 29: The code fence could specify a language identifier
These are purely stylistic and don't diminish the value of this documentation.
src/components/Common/ActionList.tsx (2)
104-114: LGTM - useCallback fixes payment method reshuffling.Wrapping
isMethodUnavailableinuseCallbackwithrequiresVerificationas the dependency stabilizes the function reference. This preventsuseGeoFilteredPaymentOptions'suseMemofrom seeing a dependency change on every render, which was causing the unstableArray.sort()to reshuffle methods.This is the correct fix for the reported reshuffling issue.
120-128: LGTM - Balance check modal integration.The changes properly integrate the new balance check flow:
selectedPaymentMethodstate tracks the user's choice when the balance modal intervenesbypassBalanceModalparameter allows proceeding after modal dismissalonBeforeShowhook inActionListDaimoPayButtonenables pre-payment interceptionThe flow correctly shows the balance modal before initiating payment and allows users to either use their Peanut balance or continue with their original method choice.
Also applies to: 249-264
Fix Request Pot Balance Check & Navigation
Issues Fixed
Changes
✅ No breaking changes