Merge Peanut-Wallet into Peanut-Wallet-Dev#1425
Conversation
All these routes are not used and are surface for attack
[TASK-15930] chore: remove unused routes
Update High balance modal copy
[TASK-16676] fix: Request pots redirect
[TASK-16686] Feat/pix modal changes
|
You have run out of free Bugbot PR reviews for this billing cycle. This will reset on December 5. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. WalkthroughRemoves multiple Peanut API route handlers and claim-link client methods, disables the Add Money Prompt and several KYC components/modals, consolidates QR scanner state into a new QrCodeContext, removes "public" history mode and user-search, and applies many UI/text and small prop surface changes across components. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 2 inconclusive)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (51)
Comment |
Signed-off-by: Hugo Montenegro <hugo@peanut.to>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/hooks/useLogin.tsx (1)
30-45: Userouter.push()consistently for all redirects in the post-login flow.The code currently uses
window.location.assign()forredirect_uriand localStorage redirects (lines 36, 40), butrouter.push()for the fallback (line 42). This is inconsistent and unnecessary—getValidRedirectUrl()already guarantees same-origin URLs, so all redirects should userouter.push()to maintain client-side SPA navigation. This aligns with the redirect pattern used throughout the codebase (SetupPasskey.tsx, GuestLoginCta, Landing.tsx, Welcome.tsx, QR page).Replace lines 36 and 40:
window.location.assign(validRedirectUrl)→router.push(validRedirectUrl)src/hooks/useHomeCarouselCTAs.tsx (1)
103-112: Missing dependencies in useCallback.The
generateCarouselCTAscallback is missingsetIsQRScannerOpenandisUserMantecaKycApprovedfrom its dependency array. WhilesetIsQRScannerOpenis stable (from context),isUserMantecaKycApprovedshould be included since it's used in the condition on line 41.Apply this diff:
}, [ showReminderBanner, isPermissionDenied, isUserKycApproved, isUserBridgeKycUnderReview, + isUserMantecaKycApproved, + setIsQRScannerOpen, router, requestPermission, afterPermissionAttempt, snoozeReminderBanner, ])
🧹 Nitpick comments (3)
src/app/api/peanut/get-attachment-info/route.ts (1)
1-5: Remove commented-out code and unused imports.Since this endpoint is being disabled, consider removing the commented-out implementation (lines 11-50) and the now-unused imports (lines 1-5). Version control preserves the implementation if it needs to be restored later, and keeping dead code increases maintenance burden.
Apply this diff to clean up the file:
-import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' -import { getRawParamsFromLink, generateKeysFromString } from '@squirrel-labs/peanut-sdk' // Adjust the import paths according to your project structure -import * as consts from '@/constants' -import { fetchWithSentry } from '@/utils' -export async function POST(request: NextRequest) { +export async function POST() { //TODO: enable if we have attachments again, using /send-link instead of //get-link-details return new NextResponse(null, { status: 405 }) - /* - try { - const { link } = await request.json() - const params = getRawParamsFromLink(link) - const { address: pubKey } = generateKeysFromString(params.password) - - const response = await fetchWithSentry(`${consts.PEANUT_API_URL}/get-link-details`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - pubKey, - apiKey: process.env.PEANUT_API_KEY, - }), - }) - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`) - } - - const data = await response.json() - - return new NextResponse( - JSON.stringify({ - fileUrl: data.linkInfo.file_url, - message: data.linkInfo.text_content, - }), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } - ) - } catch (error) { - console.error('Failed to get attachment:', error) - return new NextResponse('Internal Server Error', { status: 500 }) - } - */ }Also applies to: 11-50
src/app/(mobile-ui)/home/page.tsx (1)
222-223: Add Money Prompt modal temporarily disabled.The modal has been commented out with a TODO indicating it needs proper fixes before re-enabling. The related state management and useEffect logic have been removed to simplify the code. Make sure to track this as a follow-up issue.
Would you like me to help track this or create a follow-up issue for re-enabling the Add Money Prompt modal after fixes?
src/app/(mobile-ui)/qr-pay/page.tsx (1)
436-442: Improved PIX error handling with user-facing message.The change correctly surfaces PIX provider issues to users instead of entering a waiting state. This provides better UX by informing users of external provider problems rather than leaving them in a waiting state.
One minor style note: the condition
EQrType.PIX === qrTypecould be more conventional asqrType === EQrType.PIX(variable on left, constant on right).Consider this diff for consistency with typical condition ordering:
- if (EQrType.PIX === qrType) { + if (qrType === EQrType.PIX) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
src/app/(mobile-ui)/home/page.tsx(2 hunks)src/app/(mobile-ui)/qr-pay/page.tsx(2 hunks)src/app/api/peanut/get-attachment-info/route.ts(2 hunks)src/app/api/peanut/submit-claim-link/confirm/route.ts(0 hunks)src/app/api/peanut/submit-claim-link/init/route.ts(0 hunks)src/app/api/peanut/submit-direct-transfer/route.ts(0 hunks)src/components/Create/useCreateLink.tsx(1 hunks)src/components/Global/BalanceWarningModal/index.tsx(1 hunks)src/components/Global/DirectSendQR/index.tsx(2 hunks)src/components/Global/Icons/qr-code.tsx(1 hunks)src/components/Home/HomeCarouselCTA/CarouselCTA.tsx(3 hunks)src/components/Home/HomeCarouselCTA/index.tsx(1 hunks)src/components/Home/HomeHistory.tsx(5 hunks)src/components/Payment/PaymentForm/index.tsx(1 hunks)src/components/Profile/components/PublicProfile.tsx(1 hunks)src/components/Slider/index.tsx(2 hunks)src/context/QrCodeContext.tsx(1 hunks)src/context/contextProvider.tsx(2 hunks)src/hooks/useHomeCarouselCTAs.tsx(3 hunks)src/hooks/useLogin.tsx(1 hunks)src/hooks/useTransactionHistory.ts(2 hunks)src/hooks/useUserSearch.ts(0 hunks)src/services/users.ts(0 hunks)
💤 Files with no reviewable changes (5)
- src/app/api/peanut/submit-direct-transfer/route.ts
- src/app/api/peanut/submit-claim-link/init/route.ts
- src/hooks/useUserSearch.ts
- src/services/users.ts
- src/app/api/peanut/submit-claim-link/confirm/route.ts
🧰 Additional context used
🧠 Learnings (40)
📓 Common learnings
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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
Repo: peanutprotocol/peanut-ui PR: 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 after scanning MERCADO_PAGO or PIX QR codes.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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 used instead of `router.replace` in URL manipulation functions when immediate/synchronous URL updates are required for subsequent actions to read the updated URL parameters.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 845
File: src/components/Request/link/views/Create.request.link.view.tsx:81-81
Timestamp: 2025-05-13T10:05:24.057Z
Learning: In the peanut-ui project, pages that handle request flows (like Create.request.link.view.tsx) are only accessible to logged-in users who will always have a username, making null checks for user?.user.username unnecessary in these contexts.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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: 2024-10-07T15:25:45.170Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-07T15:28:25.280Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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: 2024-10-08T20:13:42.967Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-08T20:13:42.967Z
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/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-22T18:10:56.955Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 469
File: src/app/request/pay/page.tsx:25-25
Timestamp: 2024-10-22T18:10:56.955Z
Learning: In the `src/app/request/pay/page.tsx` file, the `PreviewType` enum values are strings, so when adding `previewType` to `URLSearchParams`, there's no need to convert them to strings.
Applied to files:
src/components/Payment/PaymentForm/index.tsxsrc/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2025-09-18T09:30:42.901Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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/components/Payment/PaymentForm/index.tsxsrc/app/(mobile-ui)/qr-pay/page.tsxsrc/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-08-26T15:25:53.328Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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/Payment/PaymentForm/index.tsxsrc/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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/Payment/PaymentForm/index.tsx
📚 Learning: 2025-08-22T07:28:32.281Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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/components/Payment/PaymentForm/index.tsxsrc/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2025-06-18T19:56:55.443Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/components/Payment/PaymentForm/index.tsx
📚 Learning: 2024-10-07T13:42:07.299Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 422
File: src/components/Request/Pay/Pay.tsx:113-123
Timestamp: 2024-10-07T13:42:07.299Z
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.tsxsrc/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2024-10-23T09:38:27.670Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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:
src/components/Payment/PaymentForm/index.tsxsrc/app/(mobile-ui)/qr-pay/page.tsxsrc/hooks/useHomeCarouselCTAs.tsxsrc/components/Create/useCreateLink.tsx
📚 Learning: 2025-09-05T07:31:11.396Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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/hooks/useLogin.tsxsrc/components/Create/useCreateLink.tsx
📚 Learning: 2025-07-05T16:58:25.340Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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/hooks/useLogin.tsx
📚 Learning: 2024-10-29T16:06:38.812Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/hooks/useLogin.tsxsrc/components/Create/useCreateLink.tsx
📚 Learning: 2025-09-11T17:46:12.507Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 1200
File: src/app/(mobile-ui)/recover-funds/page.tsx:9-9
Timestamp: 2025-09-11T17:46:12.507Z
Learning: Functions in Next.js that are not marked with "use server" and contain secrets are unsafe to import in client components, as they get bundled into the client JavaScript and can leak environment variables to the browser.
Applied to files:
src/hooks/useLogin.tsx
📚 Learning: 2025-07-24T13:26:10.290Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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:
src/hooks/useLogin.tsxsrc/app/api/peanut/get-attachment-info/route.tssrc/components/Create/useCreateLink.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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 after scanning MERCADO_PAGO or PIX QR codes.
Applied to files:
src/app/(mobile-ui)/qr-pay/page.tsxsrc/components/Global/DirectSendQR/index.tsx
📚 Learning: 2024-11-18T21:36:11.486Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 535
File: src/components/Claim/Claim.tsx:142-146
Timestamp: 2024-11-18T21:36:11.486Z
Learning: In `src/components/Claim/Claim.tsx`, external calls like token price fetching and cross-chain details retrieval are already encapsulated within existing `try...catch` blocks, so additional error handling may be unnecessary.
Applied to files:
src/app/(mobile-ui)/qr-pay/page.tsxsrc/components/Create/useCreateLink.tsx
📚 Learning: 2024-12-11T10:13:22.806Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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:
src/app/(mobile-ui)/qr-pay/page.tsxsrc/app/(mobile-ui)/home/page.tsx
📚 Learning: 2024-10-07T13:42:00.443Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2025-09-08T03:11:00.114Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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.
Applied to files:
src/app/(mobile-ui)/qr-pay/page.tsxsrc/components/Global/DirectSendQR/index.tsx
📚 Learning: 2025-05-13T10:05:24.057Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 845
File: src/components/Request/link/views/Create.request.link.view.tsx:81-81
Timestamp: 2025-05-13T10:05:24.057Z
Learning: In the peanut-ui project, pages that handle request flows (like Create.request.link.view.tsx) are only accessible to logged-in users who will always have a username, making null checks for user?.user.username unnecessary in these contexts.
Applied to files:
src/components/Profile/components/PublicProfile.tsxsrc/components/Create/useCreateLink.tsx
📚 Learning: 2025-04-11T11:33:53.245Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 798
File: src/components/Home/HomeHistory.tsx:138-192
Timestamp: 2025-04-11T11:33:53.245Z
Learning: In the HomeHistory component, infinite scrolling is intentionally not implemented despite the presence of useInfiniteQuery and IntersectionObserver code. The component is designed to only display the first 5 entries with a "View all transactions" link for viewing the complete history.
Applied to files:
src/components/Profile/components/PublicProfile.tsxsrc/components/Home/HomeHistory.tsxsrc/hooks/useTransactionHistory.ts
📚 Learning: 2025-11-04T17:47:06.328Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1396
File: src/app/(mobile-ui)/home/page.tsx:295-304
Timestamp: 2025-11-04T17:47:06.328Z
Learning: In src/app/(mobile-ui)/home/page.tsx, when closing the KycCompletedModal, updateUserById is called without awaiting to provide instant feedback to the user. This fire-and-forget pattern for modal dismissals and UI preference updates is intentional and consistent across the codebase—user experience with instant UI feedback takes priority over waiting for backend sync operations.
Applied to files:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-10-29T11:27:59.248Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/home/page.tsxsrc/components/Global/BalanceWarningModal/index.tsx
📚 Learning: 2024-10-25T11:33:46.776Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 484
File: src/components/Cashout/Components/Initial.view.tsx:273-274
Timestamp: 2024-10-25T11:33:46.776Z
Learning: In the `InitialCashoutView` component (`src/components/Cashout/Components/Initial.view.tsx`), linked bank accounts should not generate error states, and the `ValidatedInput` component will clear any error messages if needed. Therefore, it's unnecessary to manually clear the error state when selecting or clearing linked bank accounts.
Applied to files:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-11-07T11:51:58.861Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1419
File: src/components/Global/BalanceWarningModal/index.tsx:94-94
Timestamp: 2025-11-07T11:51:58.861Z
Learning: In `src/components/Global/BalanceWarningModal/index.tsx`, the casual and congratulatory phrase "You're rich! Congrats on having a high balance." is intentional and by design.
Applied to files:
src/app/(mobile-ui)/home/page.tsxsrc/components/Global/BalanceWarningModal/index.tsx
📚 Learning: 2025-07-07T20:22:11.092Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-05-22T15:38:48.586Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 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)/home/page.tsxsrc/context/contextProvider.tsx
📚 Learning: 2024-10-29T12:20:47.207Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Create/Link/Input.view.tsx:244-248
Timestamp: 2024-10-29T12:20:47.207Z
Learning: In the `TokenAmountInput` component within `src/components/Global/TokenAmountInput/index.tsx`, when `balance` is undefined, the `maxValue` prop should be set to an empty string `''`.
Applied to files:
src/app/(mobile-ui)/home/page.tsxsrc/components/Global/BalanceWarningModal/index.tsx
📚 Learning: 2024-12-02T17:19:18.532Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/home/page.tsxsrc/components/Create/useCreateLink.tsx
📚 Learning: 2025-10-15T06:45:22.055Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1241
File: src/components/ForceIOSPWAInstall/index.tsx:6-51
Timestamp: 2025-10-15T06:45:22.055Z
Learning: In the ForceIOSPWAInstall component (src/components/ForceIOSPWAInstall/index.tsx), the blocking behavior without a skip/dismiss option is intentional by design to force PWA installation on iOS devices.
Applied to files:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-05-15T14:47:26.891Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 857
File: src/hooks/useWebSocket.ts:77-82
Timestamp: 2025-05-15T14:47:26.891Z
Learning: The useWebSocket hook in src/hooks/useWebSocket.ts is designed to provide raw history entries, while the components using it (such as HomeHistory.tsx) are responsible for implementing deduplication logic based on UUID to prevent duplicate entries when combining WebSocket data with other data sources.
Applied to files:
src/components/Home/HomeHistory.tsxsrc/hooks/useTransactionHistory.ts
📚 Learning: 2024-10-18T01:51:35.247Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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/components/Create/useCreateLink.tsx
📚 Learning: 2025-04-30T21:31:27.790Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 827
File: src/components/Claim/Link/Initial.view.tsx:120-126
Timestamp: 2025-04-30T21:31:27.790Z
Learning: The `sendLinksApi.claim` function in the Peanut Protocol UI accepts both username and wallet address as the first parameter.
Applied to files:
src/components/Create/useCreateLink.tsx
📚 Learning: 2025-01-16T13:14:40.363Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/components/Create/useCreateLink.tsxsrc/context/contextProvider.tsx
📚 Learning: 2025-09-15T16:22:58.382Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 1190
File: src/services/manteca.ts:1-1
Timestamp: 2025-09-15T16:22:58.382Z
Learning: In the manteca service, PEANUT_API_KEY should not be imported in a module that's used by client-side components. The getPrices function that requires the API key should be moved to a server-only module to prevent exposing secrets in the client bundle.
Applied to files:
src/components/Create/useCreateLink.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 413
File: src/context/tokenSelector.context.tsx:118-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `TokenContextProvider` component within `src/context/tokenSelector.context.tsx`, in the TypeScript React application, when data changes and before calling `fetchAndSetTokenPrice`, it is necessary to reset `selectedTokenData`, `selectedTokenPrice`, `selectedTokenDecimals`, and `inputDenomination` to discard stale data.
Applied to files:
src/context/contextProvider.tsx
🧬 Code graph analysis (8)
src/components/Home/HomeCarouselCTA/CarouselCTA.tsx (1)
src/components/Global/Icons/Icon.tsx (1)
Icon(209-218)
src/hooks/useLogin.tsx (1)
src/utils/general.utils.ts (2)
clearRedirectUrl(796-800)getValidRedirectUrl(899-915)
src/app/(mobile-ui)/qr-pay/page.tsx (1)
src/components/Global/Icons/Icon.tsx (1)
Icon(209-218)
src/hooks/useHomeCarouselCTAs.tsx (2)
src/hooks/useKycStatus.tsx (1)
useKycStatus(12-36)src/context/QrCodeContext.tsx (1)
useQrCodeContext(17-23)
src/components/Home/HomeHistory.tsx (1)
src/hooks/useTransactionHistory.ts (1)
useTransactionHistory(51-106)
src/context/contextProvider.tsx (2)
src/context/SupportModalContext.tsx (1)
SupportModalProvider(15-37)src/context/QrCodeContext.tsx (1)
QrCodeProvider(12-15)
src/hooks/useTransactionHistory.ts (1)
src/constants/general.consts.ts (1)
PEANUT_API_URL(51-55)
src/components/Global/DirectSendQR/index.tsx (1)
src/context/QrCodeContext.tsx (1)
useQrCodeContext(17-23)
🔇 Additional comments (18)
src/app/api/peanut/get-attachment-info/route.ts (1)
7-10: No active callers found—verification passed. This endpoint was already unused.Codebase search confirms no code references this endpoint. The endpoint was already effectively disabled, so there is no risk of breaking active callers. The disabled state is safe to keep as-is.
Optional: The imports on lines 1-5 (getRawParamsFromLink, generateKeysFromString, consts, fetchWithSentry) are now unused since they're only referenced in the commented code. Consider removing them and the commented block (lines 11-50) for cleaner code.
src/components/Payment/PaymentForm/index.tsx (1)
542-544: LGTM!The button text change from 'Pay' to 'Choose payment method' for the request pot initial view improves user clarity about the next action in this flow.
src/components/Create/useCreateLink.tsx (1)
3-5: LGTM!The removal of
PEANUT_API_URLandfetchWithSentryimports correctly reflects the elimination of the claim-link submission methods (submitClaimLinkInitandsubmitClaimLinkConfirm) from this hook, aligning with the broader PR cleanup of the claim-link flow.src/components/Home/HomeCarouselCTA/index.tsx (1)
35-35: LGTM!The
iconSize={16}prop correctly overrides the default icon size for all carousel CTAs, providing consistent icon sizing across the carousel.src/components/Global/Icons/qr-code.tsx (1)
4-4: LGTM!Adding the props spread (
{...props}) enables better component composition and allows passing accessibility attributes (e.g.,aria-label,role) and other SVG properties to the icon.src/components/Profile/components/PublicProfile.tsx (1)
218-218: LGTM!The removal of the
isPublicprop correctly aligns with the simplifiedHomeHistorycomponent signature that now infers public/private context internally based on the username.src/context/contextProvider.tsx (1)
12-12: LGTM!The
QrCodeProvideris correctly integrated into the context provider tree, enabling shared QR scanner state management across components. The nesting structure is consistent with existing providers.Also applies to: 26-28
src/components/Slider/index.tsx (1)
17-17: LGTM!The addition of the optional
titleprop enables custom slider labels while maintaining backward compatibility with the default "Slide to Proceed" text. The implementation is clean and straightforward.Also applies to: 21-21, 70-70
src/components/Home/HomeCarouselCTA/CarouselCTA.tsx (1)
23-23: LGTM! Clean refactor for configurable icon sizing.The addition of the optional
iconSizeprop with a sensible default (22) maintains backward compatibility while enabling explicit control. The implementation correctly threads the prop through to theIconcomponent.Also applies to: 36-36, 100-100
src/components/Global/DirectSendQR/index.tsx (1)
21-21: LGTM! Successful migration to centralized QR scanner state.The component now consumes QR scanner state from
useQrCodeContextinstead of managing it locally. This centralizes state management and enables other components to control the scanner. The migration is complete and consistent throughout the component.Also applies to: 199-199
src/hooks/useHomeCarouselCTAs.tsx (1)
40-61: LGTM! QR payment CTA integrates well with context.The new QR code payment CTA correctly uses the QR code context to open the scanner and includes proper KYC gating (Bridge or Manteca). The JSX title/description provide good UX messaging, and the explicit
iconSize: 16enables consistent icon sizing.src/context/QrCodeContext.tsx (1)
1-23: LGTM! Well-structured context implementation.The QR code context follows React best practices with:
- Clear type definition for the context value
- Provider component managing state
- Hook with proper error boundary that throws if used outside provider
- Simple, focused API (boolean state + setter)
This centralizes QR scanner state management as intended.
src/components/Global/BalanceWarningModal/index.tsx (2)
92-117: Updated messaging improves clarity and tone.The copy changes:
- Remove "Warning" from header (less alarming)
- Add congratulatory intro (per design learning, casual tone is intentional)
- Clarify non-recoverability of passkeys
- Add platform-specific security links
These changes improve UX by being more informative while maintaining the appropriate tone.
Based on learnings.
121-121: Slider component properly supports the title prop.The SliderProps interface includes
title?: string(line 16 of src/components/Slider/index.tsx), the component destructures and accepts it (line 21), and it's properly rendered with a fallback value (lines 62-64). The code change is correct.src/app/(mobile-ui)/qr-pay/page.tsx (2)
449-449: Correct dependency addition.Adding
qrTypeto the effect dependencies is appropriate since the error handling logic now branches based on the QR type. This ensures the effect re-runs when scanning different QR code types.
845-858: Updated error UI improves visual hierarchy.The error state now uses an alert icon with proper styling (bg-secondary-1) and improved Card structure. This provides better visual feedback to users when QR details cannot be fetched.
src/components/Home/HomeHistory.tsx (2)
37-37: Consistent history behavior after removing public mode.The component now always:
- Uses
mode: 'latest'withlimit: 5- Shows KYC items only when viewing own history
- Displays exactly 5 entries regardless of context
This unified code path simplifies maintenance and removes the public/private distinction in transaction history display.
Also applies to: 168-187, 200-200
27-27: All callers of HomeHistory have been correctly updated to not pass theisPublicprop.Verification found 2 call sites (PublicProfile.tsx and mobile-ui/home/page.tsx), both passing only the
usernameprop. No instances of theisPublicprop were detected. The component signature simplification is complete and properly implemented across the codebase.
| const headers: Record<string, string> = { | ||
| 'Content-Type': 'application/json', | ||
| } | ||
| if (!isPublic) { | ||
| headers['Authorization'] = `Bearer ${Cookies.get('jwt-token')}` | ||
| } | ||
| headers['Authorization'] = `Bearer ${Cookies.get('jwt-token')}` | ||
| const response = await fetchWithSentry(url, { method: 'GET', headers }) | ||
|
|
There was a problem hiding this comment.
Guard Authorization header when JWT is missing.
Cookies.get('jwt-token') returns undefined for logged-out users or expired sessions, so we now send Authorization: Bearer undefined. The backend treats that as an invalid token, producing 401s and breaking history fetches (e.g. PublicProfile). Guard the assignment and skip the header when no token is available.
- const headers: Record<string, string> = {
- 'Content-Type': 'application/json',
- }
- headers['Authorization'] = `Bearer ${Cookies.get('jwt-token')}`
+ const headers: Record<string, string> = {
+ 'Content-Type': 'application/json',
+ }
+ const token = Cookies.get('jwt-token')
+ if (token) {
+ headers['Authorization'] = `Bearer ${token}`
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const headers: Record<string, string> = { | |
| 'Content-Type': 'application/json', | |
| } | |
| if (!isPublic) { | |
| headers['Authorization'] = `Bearer ${Cookies.get('jwt-token')}` | |
| } | |
| headers['Authorization'] = `Bearer ${Cookies.get('jwt-token')}` | |
| const response = await fetchWithSentry(url, { method: 'GET', headers }) | |
| const headers: Record<string, string> = { | |
| 'Content-Type': 'application/json', | |
| } | |
| const token = Cookies.get('jwt-token') | |
| if (token) { | |
| headers['Authorization'] = `Bearer ${token}` | |
| } | |
| const response = await fetchWithSentry(url, { method: 'GET', headers }) |
🤖 Prompt for AI Agents
In src/hooks/useTransactionHistory.ts around lines 67 to 72, the code always
sets Authorization to `Bearer ${Cookies.get('jwt-token')}`, which can be the
string "undefined" when no JWT exists; change it to first read the token into a
variable (e.g. const token = Cookies.get('jwt-token')) and only add
headers['Authorization'] = `Bearer ${token}` when token is truthy, leaving the
header absent for logged-out/expired sessions so we don't send "Bearer
undefined".
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/app/(mobile-ui)/home/page.tsx (1)
227-228: Consider tracking this TODO with an issue.The Add Money Prompt modal is temporarily disabled pending fixes. To ensure this gets re-enabled, consider creating a tracking issue and referencing it in the TODO comment.
Note: The import for
AddMoneyPromptModal(line 22) is now only used in this commented code, which may trigger unused-import warnings. This is acceptable if re-enabling is planned soon.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/app/(mobile-ui)/home/page.tsx(2 hunks)src/components/Global/DirectSendQR/index.tsx(2 hunks)src/components/Home/HomeCarouselCTA/CarouselCTA.tsx(3 hunks)src/components/Home/HomeHistory.tsx(5 hunks)src/components/Payment/PaymentForm/index.tsx(1 hunks)src/context/contextProvider.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/components/Home/HomeCarouselCTA/CarouselCTA.tsx
- src/components/Payment/PaymentForm/index.tsx
- src/context/contextProvider.tsx
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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
Repo: peanutprotocol/peanut-ui PR: 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
Repo: peanutprotocol/peanut-ui PR: 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 after scanning MERCADO_PAGO or PIX QR codes.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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 used instead of `router.replace` in URL manipulation functions when immediate/synchronous URL updates are required for subsequent actions to read the updated URL parameters.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 845
File: src/components/Request/link/views/Create.request.link.view.tsx:81-81
Timestamp: 2025-05-13T10:05:24.057Z
Learning: In the peanut-ui project, pages that handle request flows (like Create.request.link.view.tsx) are only accessible to logged-in users who will always have a username, making null checks for user?.user.username unnecessary in these contexts.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 1190
File: src/services/manteca.ts:1-1
Timestamp: 2025-09-15T16:22:58.382Z
Learning: In the manteca service, PEANUT_API_KEY should not be imported in a module that's used by client-side components. The getPrices function that requires the API key should be moved to a server-only module to prevent exposing secrets in the client bundle.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 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-18T09:30:42.901Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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)/home/page.tsxsrc/components/Home/HomeHistory.tsx
📚 Learning: 2025-11-04T17:47:06.328Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1396
File: src/app/(mobile-ui)/home/page.tsx:295-304
Timestamp: 2025-11-04T17:47:06.328Z
Learning: In src/app/(mobile-ui)/home/page.tsx, when closing the KycCompletedModal, updateUserById is called without awaiting to provide instant feedback to the user. This fire-and-forget pattern for modal dismissals and UI preference updates is intentional and consistent across the codebase—user experience with instant UI feedback takes priority over waiting for backend sync operations.
Applied to files:
src/app/(mobile-ui)/home/page.tsxsrc/components/Home/HomeHistory.tsx
📚 Learning: 2025-11-07T11:51:58.861Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1419
File: src/components/Global/BalanceWarningModal/index.tsx:94-94
Timestamp: 2025-11-07T11:51:58.861Z
Learning: In `src/components/Global/BalanceWarningModal/index.tsx`, the casual and congratulatory phrase "You're rich! Congrats on having a high balance." is intentional and by design.
Applied to files:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-10-29T11:27:59.248Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/home/page.tsx
📚 Learning: 2024-10-25T11:33:46.776Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 484
File: src/components/Cashout/Components/Initial.view.tsx:273-274
Timestamp: 2024-10-25T11:33:46.776Z
Learning: In the `InitialCashoutView` component (`src/components/Cashout/Components/Initial.view.tsx`), linked bank accounts should not generate error states, and the `ValidatedInput` component will clear any error messages if needed. Therefore, it's unnecessary to manually clear the error state when selecting or clearing linked bank accounts.
Applied to files:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-07-07T20:22:11.092Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/home/page.tsx
📚 Learning: 2024-12-11T10:13:22.806Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-05-22T15:38:48.586Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 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)/home/page.tsx
📚 Learning: 2025-08-26T15:25:53.328Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/home/page.tsx
📚 Learning: 2024-12-02T17:19:18.532Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-10-15T06:45:22.055Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1241
File: src/components/ForceIOSPWAInstall/index.tsx:6-51
Timestamp: 2025-10-15T06:45:22.055Z
Learning: In the ForceIOSPWAInstall component (src/components/ForceIOSPWAInstall/index.tsx), the blocking behavior without a skip/dismiss option is intentional by design to force PWA installation on iOS devices.
Applied to files:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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 after scanning MERCADO_PAGO or PIX QR codes.
Applied to files:
src/components/Global/DirectSendQR/index.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 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.
Applied to files:
src/components/Global/DirectSendQR/index.tsx
📚 Learning: 2025-04-11T11:33:53.245Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 798
File: src/components/Home/HomeHistory.tsx:138-192
Timestamp: 2025-04-11T11:33:53.245Z
Learning: In the HomeHistory component, infinite scrolling is intentionally not implemented despite the presence of useInfiniteQuery and IntersectionObserver code. The component is designed to only display the first 5 entries with a "View all transactions" link for viewing the complete history.
Applied to files:
src/components/Home/HomeHistory.tsx
📚 Learning: 2025-05-15T14:47:26.891Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 857
File: src/hooks/useWebSocket.ts:77-82
Timestamp: 2025-05-15T14:47:26.891Z
Learning: The useWebSocket hook in src/hooks/useWebSocket.ts is designed to provide raw history entries, while the components using it (such as HomeHistory.tsx) are responsible for implementing deduplication logic based on UUID to prevent duplicate entries when combining WebSocket data with other data sources.
Applied to files:
src/components/Home/HomeHistory.tsx
🧬 Code graph analysis (2)
src/components/Global/DirectSendQR/index.tsx (1)
src/context/QrCodeContext.tsx (1)
useQrCodeContext(17-23)
src/components/Home/HomeHistory.tsx (1)
src/hooks/useTransactionHistory.ts (1)
useTransactionHistory(51-106)
⏰ 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 (5)
src/app/(mobile-ui)/home/page.tsx (1)
167-167: LGTM! Dependency array correctly updated.The removal of
showAddMoneyPromptModalfrom the dependency array is consistent with the removal of that state variable.src/components/Global/DirectSendQR/index.tsx (1)
21-21: LGTM! Clean refactoring to shared QR scanner state.The migration from local state to context-based state management is well-executed. This architectural improvement enables cross-component control of the QR scanner (e.g., from useHomeCarouselCTAs) while maintaining a single scanner instance across the app. All existing state operations are preserved correctly.
Also applies to: 200-200
src/components/Home/HomeHistory.tsx (3)
28-28: LGTM! Component API simplified.Removing the
isPublicprop simplifies the component API. The public/private distinction is now handled internally through theisViewingOwnHistorylogic.
38-38: LGTM! Consistent refactor removing public mode.The changes to the
useTransactionHistoryhook usage, KYC item inclusion logic, entry limit, and dependency array are all consistent with removing the public/private mode distinction. The component now:
- Uses
mode: 'latest'andlimit: 5consistently- Only includes KYC items when viewing own history
- Correctly updates dependencies
Also applies to: 170-172, 202-202, 212-212
304-333: Verify intended behavior change for pending requests visibility.Removing the
!isPubliccheck means pending requests will now be shown when viewing other users' profiles (specifically, requests the current user sent to them that are still pending). The current code shows noisPublicvariable, confirming this check has been removed.When viewing another user's profile as a logged-in user, the pending requests displayed would be those sent by you to that user with a status of 'NEW'. This could be a useful feature ("you have pending requests with this user"), but the change warrants confirmation.
Please verify this behavior change is intentional and desired.
| const limit = isPublic ? 20 : 5 | ||
| // Only filter when user is requesting for some different user's history | ||
| const filterMutualTxs = !isPublic && username !== user?.user.username | ||
| const filterMutualTxs = username !== user?.user.username |
There was a problem hiding this comment.
Fix the logic for filterMutualTxs.
The current expression evaluates to true when viewing your own profile (when username is undefined), because undefined !== "myusername" returns true. While the hook has protection (filterMutualTxs && username), this misleading value makes the code harder to reason about and could cause bugs if the hook implementation changes.
Apply this diff to fix the logic:
- const filterMutualTxs = username !== user?.user.username
+ const filterMutualTxs = !!username && username !== user?.user.username📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const filterMutualTxs = username !== user?.user.username | |
| const filterMutualTxs = !!username && username !== user?.user.username |
🤖 Prompt for AI Agents
In src/components/Home/HomeHistory.tsx around line 32, the current
filterMutualTxs expression incorrectly evaluates true when username is
undefined; change it to explicitly require username to be present and different
from the logged-in user's username (i.e., check that username is truthy AND
username !== user?.user.username), and coerce the result to a boolean so the
variable cannot be misleading if the hook changes.
sync.