Skip to content

Merge Peanut-Wallet into Peanut-Wallet-Dev#1425

Merged
Hugo0 merged 14 commits intopeanut-wallet-devfrom
peanut-wallet
Nov 8, 2025
Merged

Merge Peanut-Wallet into Peanut-Wallet-Dev#1425
Hugo0 merged 14 commits intopeanut-wallet-devfrom
peanut-wallet

Conversation

@Hugo0
Copy link
Contributor

@Hugo0 Hugo0 commented Nov 8, 2025

sync.

@cursor
Copy link

cursor bot commented Nov 8, 2025

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.

@vercel
Copy link

vercel bot commented Nov 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
peanut-wallet Canceled Canceled Nov 8, 2025 5:04pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Removes 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

Cohort / File(s) Summary
Peanut API routes (deleted/disabled)
src/app/api/peanut/get-attachment-info/route.ts, src/app/api/peanut/submit-claim-link/init/route.ts, src/app/api/peanut/submit-claim-link/confirm/route.ts, src/app/api/peanut/submit-direct-transfer/route.ts
Disabled get-attachment-info (returns 405; original logic commented) and removed claim-link init/confirm and direct-transfer routes, eliminating server-side Peanut claim/transfer flows.
Home / Add Money / KYC UI
src/app/(mobile-ui)/home/page.tsx, src/components/Home/KycCompletedModal/index.tsx, src/components/IdentityVerification/StartVerificationModal.tsx, src/hooks/useIdentityVerification.tsx, src/components/Profile/views/RegionsPage.view.tsx, src/components/Profile/views/RegionsVerification.view.tsx, src/app/(mobile-ui)/profile/identity-verification/*
Removed Add Money Prompt modal state/effects and KYC-related components/layouts/hooks (multiple verification pages, modals, and hook implementations) and adjusted Home rendering accordingly.
QR scanner context & usage
src/context/QrCodeContext.tsx, src/context/contextProvider.tsx, src/components/Global/DirectSendQR/index.tsx, src/hooks/useHomeCarouselCTAs.tsx, src/app/(mobile-ui)/qr-pay/page.tsx
Added QrCodeContext provider and hook; migrated DirectSendQR and Home carousel CTAs to use shared QR scanner state; qr-pay adjusted PIX error handling and effect deps; UI for initiation errors restyled.
Claim-link client removal
src/components/Create/useCreateLink.tsx
Removed submitClaimLinkInit and submitClaimLinkConfirm methods and related Peanut API client logic from the hook.
User search removal & user service
src/hooks/useUserSearch.ts, src/services/users.ts
Deleted useUserSearch hook and removed usersApi.search() method, eliminating client-side user search API usage.
Transaction history / HomeHistory
src/hooks/useTransactionHistory.ts, src/components/Home/HomeHistory.tsx, src/components/Profile/components/PublicProfile.tsx
Removed 'public' mode from useTransactionHistory (types/overloads updated), unified endpoint/auth behavior; HomeHistory signature simplified (removed isPublic) and now uses latest mode/limit 5.
Haptics removal & related props
many files (examples: src/components/0_Bruddle/Button.tsx, src/components/Home/HomeCarouselCTA/CarouselCTA.tsx, src/components/Payment/PaymentForm/index.tsx, src/app/[...recipient]/client.tsx, src/app/(mobile-ui)/withdraw/crypto/page.tsx, src/components/TransactionDetails/TransactionCard.tsx, src/components/Claim/*, src/components/Global/WalletNavigation/index.tsx)
Removed use-haptic dependency and triggerHaptic calls across multiple components; removed related props (e.g., disableHaptics) and simplified click handlers.
UI component prop surface changes
src/components/Slider/index.tsx, src/components/Home/HomeCarouselCTA/CarouselCTA.tsx, src/components/Home/HomeCarouselCTA/index.tsx, src/components/Global/BalanceWarningModal/index.tsx, src/components/Global/Icons/qr-code.tsx, src/components/Global/Icons/Icon.tsx, src/components/Global/Icons/globe-lock.tsx, src/components/0_Bruddle/BaseInput.tsx, src/components/0_Bruddle/BaseSelect.tsx, src/components/Global/TokenAmountInput/index.tsx
Added title?: string to SliderProps; added iconSize?: number to CarouselCTA and passed iconSize={16} at use sites; BalanceWarningModal copy/layout updated; QR icon spreads props; removed GlobeLockIcon and its mapping; removed BaseSelect component and rightContent from BaseInput; TokenAmountInput removed URL param sync and simplified conversion onChange.
Identity / country utilities and components removed/changed
src/utils/identityVerification.tsx, src/components/AddMoney/consts/index.ts, src/constants/stateCodes.consts.ts, src/components/Profile/components/IdentityVerificationCountryList.tsx, src/components/Profile/components/CountryListSection.tsx, src/components/Profile/views/IdentityVerification.view.tsx
Removed getCountriesForRegion and state code constants; adjusted country-related types/fields and removed several profile country-list components; IdentityVerification.view refactored to inline logic (no signature change).
Mocks, tests and config
src/utils/__mocks__/simplewebauthn-browser.ts, package.json, tailwind.config.js
Deleted WebAuthn mock module; removed dependencies (@radix-ui/react-accordion, @radix-ui/react-select, use-haptic) and a jest moduleNameMapper entry in package.json; removed accordion keyframes/animations from Tailwind config.
Various API / UI small edits
assorted components and files (e.g., src/components/Global/UnsupportedBrowserModal/index.tsx, src/components/Global/DirectSendQR/*, src/components/Global/Icons/qr-code.tsx, src/assets/icons/index.ts)
Miscellaneous adjustments: passkey support provider removed and UnsupportedBrowserModal updated to use hook directly; some icon exports removed from assets barrel; SVG prop spreading added to qr-code icon.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

  • Pay extra attention to:
    • All client-side callers of removed Peanut API routes and hook methods (ensure no lingering references or unhandled flows).
    • useTransactionHistory signature/type changes and all call sites (HomeHistory, other consumers).
    • Deletions of identity verification hooks/components: ensure no remaining imports and that profile/verification flows still compile and behave.
    • QrCodeProvider placement in app context tree and any race conditions when opening scanner.
    • Global removal of use-haptic: verify UX expectations where tactile feedback was relied upon.
    • Removal of BaseSelect and stateCodes: forms that used those types/exports may need replacements.

Possibly related PRs

Suggested reviewers

  • jjramirezn

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title describes a branch merge operation but lacks specificity about what changes are being merged and does not clearly convey the primary changes in the changeset. Consider providing a more descriptive title that summarizes the main functional changes (e.g., 'Remove Peanut API endpoints and update QR/payment flows' or 'Refactor modals and history visibility logic').
Description check ❓ Inconclusive The description 'sync.' is extremely vague and generic, providing no meaningful information about the changeset contents. Expand the description to include details about what is being synchronized and summarize key changes (e.g., removed API routes, refactored components, context updates).

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc3ac14 and ea9a23d.

⛔ Files ignored due to path filters (5)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/assets/icons/europe-globe.svg is excluded by !**/*.svg
  • src/assets/icons/latam-globe.svg is excluded by !**/*.svg
  • src/assets/icons/north-america-globe.svg is excluded by !**/*.svg
  • src/assets/icons/rest-of-world-globe.svg is excluded by !**/*.svg
📒 Files selected for processing (51)
  • package.json (0 hunks)
  • src/app/(mobile-ui)/home/page.tsx (3 hunks)
  • src/app/(mobile-ui)/profile/identity-verification/[region]/[country]/page.tsx (0 hunks)
  • src/app/(mobile-ui)/profile/identity-verification/[region]/page.tsx (0 hunks)
  • src/app/(mobile-ui)/profile/identity-verification/layout.tsx (0 hunks)
  • src/app/(mobile-ui)/profile/identity-verification/page.tsx (1 hunks)
  • src/app/(mobile-ui)/withdraw/crypto/page.tsx (0 hunks)
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx (2 hunks)
  • src/app/[...recipient]/client.tsx (0 hunks)
  • src/assets/icons/index.ts (0 hunks)
  • src/components/0_Bruddle/BaseInput.tsx (1 hunks)
  • src/components/0_Bruddle/BaseSelect.tsx (0 hunks)
  • src/components/0_Bruddle/Button.tsx (0 hunks)
  • src/components/0_Bruddle/index.ts (0 hunks)
  • src/components/ActionListCard/index.tsx (1 hunks)
  • src/components/AddMoney/consts/index.ts (0 hunks)
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx (3 hunks)
  • src/components/Claim/Claim.tsx (1 hunks)
  • src/components/Claim/Link/Onchain/Confirm.view.tsx (1 hunks)
  • src/components/Claim/Link/Onchain/Success.view.tsx (2 hunks)
  • src/components/Common/CountryList.tsx (2 hunks)
  • src/components/Global/DirectSendQR/index.tsx (2 hunks)
  • src/components/Global/Icons/Icon.tsx (0 hunks)
  • src/components/Global/Icons/globe-lock.tsx (0 hunks)
  • src/components/Global/TokenAmountInput/index.tsx (1 hunks)
  • src/components/Global/UnsupportedBrowserModal/index.tsx (3 hunks)
  • src/components/Global/WalletNavigation/index.tsx (1 hunks)
  • src/components/Home/HomeCarouselCTA/CarouselCTA.tsx (3 hunks)
  • src/components/Home/HomeHistory.tsx (6 hunks)
  • src/components/Home/KycCompletedModal/index.tsx (0 hunks)
  • src/components/IdentityVerification/StartVerificationModal.tsx (0 hunks)
  • src/components/Invites/InvitesPage.tsx (0 hunks)
  • src/components/Payment/PaymentForm/index.tsx (1 hunks)
  • src/components/Payment/Views/Confirm.payment.view.tsx (0 hunks)
  • src/components/Payment/Views/Status.payment.view.tsx (2 hunks)
  • src/components/Profile/components/CountryListSection.tsx (0 hunks)
  • src/components/Profile/components/IdentityVerificationCountryList.tsx (0 hunks)
  • src/components/Profile/index.tsx (3 hunks)
  • src/components/Profile/views/IdentityVerification.view.tsx (4 hunks)
  • src/components/Profile/views/RegionsPage.view.tsx (0 hunks)
  • src/components/Profile/views/RegionsVerification.view.tsx (0 hunks)
  • src/components/TransactionDetails/TransactionCard.tsx (0 hunks)
  • src/constants/index.ts (0 hunks)
  • src/constants/stateCodes.consts.ts (0 hunks)
  • src/context/contextProvider.tsx (2 hunks)
  • src/context/passkeySupportContext.tsx (0 hunks)
  • src/hooks/useIdentityVerification.tsx (0 hunks)
  • src/interfaces/interfaces.ts (0 hunks)
  • src/utils/__mocks__/simplewebauthn-browser.ts (0 hunks)
  • src/utils/identityVerification.tsx (0 hunks)
  • tailwind.config.js (0 hunks)

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai bot added the enhancement New feature or request label Nov 8, 2025
Signed-off-by: Hugo Montenegro <hugo@peanut.to>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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: Use router.push() consistently for all redirects in the post-login flow.

The code currently uses window.location.assign() for redirect_uri and localStorage redirects (lines 36, 40), but router.push() for the fallback (line 42). This is inconsistent and unnecessary—getValidRedirectUrl() already guarantees same-origin URLs, so all redirects should use router.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 generateCarouselCTAs callback is missing setIsQRScannerOpen and isUserMantecaKycApproved from its dependency array. While setIsQRScannerOpen is stable (from context), isUserMantecaKycApproved should 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 === qrType could be more conventional as qrType === 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

📥 Commits

Reviewing files that changed from the base of the PR and between c64475c and 6c8ac2b.

📒 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.tsx
  • src/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.tsx
  • src/app/(mobile-ui)/qr-pay/page.tsx
  • 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/components/Payment/PaymentForm/index.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/app/(mobile-ui)/qr-pay/page.tsx
  • src/hooks/useHomeCarouselCTAs.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/app/api/peanut/get-attachment-info/route.ts
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/components/Home/HomeHistory.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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_URL and fetchWithSentry imports correctly reflects the elimination of the claim-link submission methods (submitClaimLinkInit and submitClaimLinkConfirm) 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 isPublic prop correctly aligns with the simplified HomeHistory component signature that now infers public/private context internally based on the username.

src/context/contextProvider.tsx (1)

12-12: LGTM!

The QrCodeProvider is 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 title prop 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 iconSize prop with a sensible default (22) maintains backward compatibility while enabling explicit control. The implementation correctly threads the prop through to the Icon component.

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 useQrCodeContext instead 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: 16 enables 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:

  1. Remove "Warning" from header (less alarming)
  2. Add congratulatory intro (per design learning, casual tone is intentional)
  3. Clarify non-recoverability of passkeys
  4. 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 qrType to 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:

  1. Uses mode: 'latest' with limit: 5
  2. Shows KYC items only when viewing own history
  3. 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 the isPublic prop.

Verification found 2 call sites (PublicProfile.tsx and mobile-ui/home/page.tsx), both passing only the username prop. No instances of the isPublic prop were detected. The component signature simplification is complete and properly implemented across the codebase.

Comment on lines 67 to 72
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 })

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

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.

Suggested change
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".

This reverts commit bc3ac14, reversing
changes made to 6c8ac2b.
@vercel vercel bot temporarily deployed to Production – peanut-wallet November 8, 2025 17:04 Inactive
@Hugo0 Hugo0 merged commit 40d5d81 into peanut-wallet-dev Nov 8, 2025
3 of 4 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6c8ac2b and bc3ac14.

📒 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.tsx
  • src/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.tsx
  • src/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 showAddMoneyPromptModal from 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 isPublic prop simplifies the component API. The public/private distinction is now handled internally through the isViewingOwnHistory logic.


38-38: LGTM! Consistent refactor removing public mode.

The changes to the useTransactionHistory hook 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' and limit: 5 consistently
  • 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 !isPublic check 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 no isPublic variable, 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants