Skip to content

Prod Release Sprint 124#1551

Merged
kushagrasarathe merged 217 commits intopeanut-walletfrom
peanut-wallet-dev
Jan 7, 2026
Merged

Prod Release Sprint 124#1551
kushagrasarathe merged 217 commits intopeanut-walletfrom
peanut-wallet-dev

Conversation

@Hugo0
Copy link
Contributor

@Hugo0 Hugo0 commented Dec 11, 2025

No description provided.

kushagrasarathe and others added 24 commits December 9, 2025 13:10
[TASK-17159] Add updated points component in withdraw flow
…unts

fix: take account owner name and use it to create external account on bridge
…chore

chore: added home carousel cta item
fix: update copy to be dynamic for install pwa screen wen on brave
@vercel
Copy link

vercel bot commented Dec 11, 2025

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

Project Deployment Review Updated (UTC)
peanut-ui (peanut-wallet-staging) Ready Ready Preview, Comment Jan 7, 2026 0:30am
peanut-wallet Ready Ready Preview, Comment Jan 7, 2026 0:30am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Walkthrough

This PR performs a large-scale refactoring of the codebase, splitting barrel imports across @/utils and @/constants into granular, feature-specific modules; replacing TokenAmountInput with AmountInput and DirectSuccessView with PaymentSuccessView; migrating from useSupportModalContext to useModalsContext; overhauling the icon system to use Material-UI icons; removing web-push notification features; restructuring layouts and metadata; and updating dependencies with new MUI packages while removing legacy packages.

Changes

Cohort / File(s) Summary
Import path refactoring (utils & constants)
src/utils/*, src/constants/*, src/app/**/*, src/components/**/*, src/app/actions/*, src/app/api/**/*
Widespread splitting of barrel imports from @/utils and @/constants into granular modules (@/utils/general.utils, @/utils/sentry.utils, @/utils/sdkErrorHandler.utils, @/utils/ens.utils, @/utils/bridge-accounts.utils, @/constants/general.consts, @/constants/zerodev.consts, @/constants/manteca.consts, @/constants/query.consts). Affects 60+ files with consistent pattern changes.
Component replacement: TokenAmountInput → AmountInput
src/app/(mobile-ui)/withdraw/page.tsx, src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, src/app/(mobile-ui)/withdraw/manteca/page.tsx, src/app/(mobile-ui)/add-money/[country]/bank/page.tsx, src/app/(mobile-ui)/add-money/page.tsx, src/app/(mobile-ui)/qr-pay/page.tsx, src/components/AddMoney/components/InputAmountStep.tsx, src/components/Global/TokenAmountInput/index.tsx (removed)
Replaces TokenAmountInput with new AmountInput component; updates props from tokenValue/setTokenValue to initialAmount/setPrimaryAmount/setSecondaryAmount with primaryDenomination/secondaryDenomination objects. Removes comma-based parsing (uses direct numeric parsing). Affects withdraw/add-money flows.
Button import path consolidation
src/components/0_Bruddle/index.ts, src/components/**/*, src/app/**/*
Moves Button import from barrel @/components/0_Bruddle to direct path @/components/0_Bruddle/Button. Removes Button, Card, BaseSelect from barrel exports (index.ts). Affects 30+ components.
Success view replacement: DirectSuccessView → PaymentSuccessView
src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, src/app/(mobile-ui)/add-money/crypto/direct/page.tsx, src/app/(mobile-ui)/add-money/crypto/page.tsx, src/app/(mobile-ui)/withdraw/crypto/page.tsx
Replaces DirectSuccessView with PaymentSuccessView component in success state rendering across multiple payment flows.
Context migration: useSupportModalContext → useModalsContext
src/components/**/*, src/app/**/*
Replaces useSupportModalContext with useModalsContext from @/context/ModalsContext across 15+ components (modals, drawers, headers, navigation, chat). Affects modal state management and support CTA visibility.
Icon system overhaul
src/components/Global/Icon/index.tsx (removed), src/components/Global/Icons/Icon.tsx, src/components/Global/Icons/*.tsx (60+ icon files deleted and rebuilt)
Removes custom Icon component and 60+ individual SVG icon files (e.g., alert.tsx, check.tsx, arrow-up.tsx, etc.). Introduces Icon component backed by Material-UI icons via @mui/icons-material. Updates icon name mappings; adds new icons (camera-flip, plus-circle, alert-filled, etc.); removes others (exchange-arrows).
Web-push feature removal
src/app/actions.ts (removed), scripts/generate.mjs, package.json, src/components/Global/IOSInstallPWAModal/index.tsx (removed)
Removes push notification subscription/sending functions, VAPID key generation, and PWA install modal. Removes web-push dependency and related types.
Withdraw/add-money flow refactoring
src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, src/app/(mobile-ui)/withdraw/manteca/page.tsx, src/app/(mobile-ui)/add-money/[country]/bank/page.tsx, src/app/(mobile-ui)/add-money/crypto/page.tsx, src/components/AddMoney/components/MantecaAddMoney.tsx, src/components/AddWithdraw/*
Removes non-EUR SEPA redirect logic and gating (eliminates useNonEurSepaRedirect, isNonEuroSepaCountry checks). Updates amount parsing (no comma stripping). Introduces isSavedAccount flag for Manteca flows. Refactors bank details form to use single accountOwnerName field instead of separate first/last names. Adds autoStartKyc prop to KYC modal. Replaces TokenAmountInput with AmountInput.
QR-pay flow simplification
src/app/(mobile-ui)/qr-pay/page.tsx
Removes pending transactions handling (usePendingTransactions), simplifies retry logic (fixed 3000ms delay), consolidates effect dependencies, changes loading button text to fixed "Loading...". Makes QrPayPageLoading non-exported.
Layout & metadata restructuring
src/app/layout.tsx, src/app/ClientProviders.tsx (new), src/app/metadata.ts
Extracts multi-provider wrapper into new ClientProviders component; converts root layout to use it. Replaces generated metadata with explicit export const metadata: Metadata including metadataBase, icons, openGraph, twitter fields. Moves metadata logic from separate file into layout.
Payment/claim flow refactoring
src/app/[...recipient]/client.tsx, src/components/Claim/Link/SendLinkActionList.tsx (new), src/components/Common/CountryListRouter.tsx, src/components/Common/ActionList.tsx (removed)
Simplifies PaymentPage routing via early returns for payment request/charge IDs; removes flow prop. Introduces SendLinkActionList for claim method selection (bank, Mercadopago, Pix, external wallet). Removes ActionList component. Simplifies CountryListRouter to only accept required claimLinkData (removes optional flow, requestLinkData props).
Rhino deposit integration
src/components/AddMoney/views/RhinoDeposit.view.tsx (new), src/components/AddMoney/components/ChainChip.tsx (new), src/app/(mobile-ui)/add-money/crypto/page.tsx
Introduces RhinoDepositView component for crypto deposit workflow (chain type tabs, polling for deposit address status, QR display). Adds ChainChip component for network/token display with logos. Refactors crypto add-money flow from multi-step UI to simplified Rhino-based flow.
Package.json & configuration updates
package.json, next.config.js
Adds @mui/icons-material, @mui/material, @emotion/react, @radix-ui/react-tabs. Removes @calcom/embed-react, Chakra UI packages, web-push, uuid, react-csv, react-ga4, yup, lottie-react. Adds dev:clean script. Expands experimental.optimizePackageImports with new package entries. Removes serverExternalPackages: [].
Component removals
src/components/Global/{FeeDescription, ConfirmDetails, ChainSelector, TokenAmountInput, RewardsModal, StatusViewWrapper, PaymentsFooter, PeanutSponsored, RecipientInput, Search, Sorting, TablePagination, TextEdit, Timeline, ToggleTheme, ImageEdit, InfoRow, ImageEdit, IOSInstallPWAModal}/index.tsx, src/components/AddMoney/components/{CryptoMethodDrawer, CryptoSourceListCard}.tsx, src/components/AddMoney/views/NetworkSelection.view.tsx, src/components/Common/ActionList.tsx, src/components/Common/ActionListDaimoPayButton.tsx
Removes 20+ UI components/modals related to deprecated flows, rewards, theme toggling, generic form inputs, and tables.
New components & features
src/components/Global/AmountInput/index.tsx (new), src/components/Global/InvitesGraph/index.tsx (enhanced), src/components/Common/ContactsListSkeleton.tsx (new), src/app/(mobile-ui)/profile/backup/page.tsx (new), src/components/Claim/Link/SendLinkActionList.tsx (new)
Introduces AmountInput with dual-denomination, slider support, and auto-focus on WEB. Enhances InvitesGraph with drag detection and improved force-directed layout. Adds ContactsListSkeleton loading placeholder. New backup page with FAQ modals. New SendLinkActionList for claim method selection.
Utility & helper refactoring
src/app/actions/clients.ts, src/components/Global/CopyToClipboard/index.tsx, src/components/Global/GeneralRecipientInput/index.tsx, src/components/AddMoney/components/InputAmountStep.tsx, src/components/Global/Modal/index.tsx, src/components/Global/Select/index.tsx, src/components/Global/Badges/StatusBadge.tsx, src/components/Global/StatusPill/index.tsx
Centralizes PUBLIC_CLIENTS_BY_CHAIN map in clients.ts with environment-driven recovery chain support. Converts CopyToClipboard to forwardRef with imperative copy() handle. Refactors GeneralRecipientInput recipient validation. Updates Modal (removes showPrev/onPrev). Changes icon names (cancel vs close, chevron-down vs arrow-bottom). Adds refunded status to badge/pill components.
Minor UI & text updates
src/components/Global/PeanutActionCard/index.tsx, .gitignore, .cursorrules, knip.json, src/app/(mobile-ui)/layout.tsx
Updates subtitle in PeanutActionCard ("Perfect to DM friends!"). Fixes .gitignore newline. Adds import rules and performance guidelines to .cursorrules. Removes config files from knip.json entry. Adjusts pull-to-refresh logic and padding in mobile layout.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • Implements the same large-scale barrel import splitting as #1556, refactoring symbols from @/utils and @/constants into granular modules across the entire codebase.
  • Shares the same component replacements and payment flow refactors with #1572 (TokenAmountInput→AmountInput, DirectSuccessView→PaymentSuccessView, removal of DevConnect intent handling).
  • Overlaps with #1579 on icon system overhaul, moving from custom Icon implementation to Material-UI icons and updating icon name mappings.

Suggested reviewers

  • jjramirezn
🚥 Pre-merge checks | ❌ 3
❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.05% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to understand the intent, rationale, or scope of changes beyond examining the raw diff. Add a detailed description explaining the purpose of the changes, key modifications, breaking changes if any, and testing performed.
Title check ❓ Inconclusive The title 'Prod Release Sprint 124' is vague and generic, using non-descriptive terms like 'Prod Release' and 'Sprint 124' without conveying the primary changes in this large, multi-system changeset. Consider using a more specific title that highlights the main change, such as 'Refactor imports and replace component architecture (AmountInput, PaymentSuccessView, Icons migration to Material-UI)' or a specific technical objective. Avoid generic sprint references.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch peanut-wallet-dev

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

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: 0

🧹 Nitpick comments (5)
src/components/Setup/components/SetupWrapper.tsx (1)

281-292: Consider adding type safety for the cloned props.

The cloneElement approach works but lacks type checking for the injected props. If InstallPWA's prop interface changes, this won't catch mismatches at compile time.

Consider using a render prop pattern or explicit prop passing for better type safety:

-{Children.map(children, (child) => {
-    if ((child as ReactElement).type === InstallPWA) {
-        return cloneElement(child as ReactElement, {
-            deferredPrompt,
-            canInstall,
-            deviceType,
-            screenId,
-            setShowBraveSuccessMessage,
-        })
-    }
-    return child
-})}
+{Children.map(children, (child) => {
+    if ((child as ReactElement<React.ComponentProps<typeof InstallPWA>>).type === InstallPWA) {
+        return cloneElement(child as ReactElement<React.ComponentProps<typeof InstallPWA>>, {
+            deferredPrompt,
+            canInstall,
+            deviceType,
+            screenId,
+            setShowBraveSuccessMessage,
+        })
+    }
+    return child
+})}
src/app/(mobile-ui)/withdraw/manteca/page.tsx (1)

47-48: Unused import: STAR_STRAIGHT_ICON

The STAR_STRAIGHT_ICON import appears to be unused after the refactor to use PointsCard. The inline points display that previously used this icon has been replaced.

 import { usePointsCalculation } from '@/hooks/usePointsCalculation'
-import STAR_STRAIGHT_ICON from '@/assets/icons/starStraight.svg'
 import PointsCard from '@/components/Common/PointsCard'
src/components/AddWithdraw/DynamicBankAccountForm.tsx (3)

29-45: Clarify long‑term plan for multiple name fields on IBankAccountDetails

You now have name, firstName, lastName, and accountOwnerName on IBankAccountDetails. The comments later in the file state that firstName/lastName are only for backwards compatibility and not used in the UI, and accountOwnerName is the canonical input.

To reduce future confusion for consumers of this type, consider either:

  • Marking name and/or firstName/lastName as clearly legacy/deprecated in a doc comment, or
  • Planning a follow‑up refactor where accountOwnerName becomes the only public input, and first/last are derived only at the payload boundary.

This doesn’t block the current change but will help keep the type surface understandable as the codebase evolves.


175-191: Harden and de‑duplicate accountOwnerName → first/last split logic

The splitting logic is straightforward and matches the validation rules (first token as firstName, the rest as lastName, with a legacy fallback to data.firstName/data.lastName). A couple of small robustness/maintainability tweaks would help:

  1. Guard on the trimmed value, not just truthiness

Right now, a string of only spaces enters the first branch:

if (data.accountOwnerName) {
  const nameParts = data.accountOwnerName.trim().split(/\s+/)
  firstName = nameParts[0] || ''
  lastName = nameParts.slice(1).join(' ') || ''
}

Even though the UI validator should prevent this, you could make the split logic safer (and friendlier to programmatic callers) by basing the condition on the trimmed value and falling back if it’s empty or has fewer than two parts:

- if (data.accountOwnerName) {
-   const nameParts = data.accountOwnerName.trim().split(/\s+/)
-   firstName = nameParts[0] || ''
-   lastName = nameParts.slice(1).join(' ') || ''
- } else {
-   firstName = data.firstName || ''
-   lastName = data.lastName || ''
- }
+ const trimmedOwnerName = (data.accountOwnerName ?? '').trim()
+ if (trimmedOwnerName.length > 0) {
+   const nameParts = trimmedOwnerName.split(/\s+/)
+   if (nameParts.length >= 2) {
+     firstName = nameParts[0]
+     lastName = nameParts.slice(1).join(' ')
+   } else {
+     // fallback if only a single token somehow sneaks through
+     firstName = data.firstName || nameParts[0] || ''
+     lastName = data.lastName || ''
+   }
+ } else {
+   firstName = data.firstName || ''
+   lastName = data.lastName || ''
+ }
  1. Consider extracting into a small helper

Since the exact same firstName/lastName pair is used in the payload (accountOwnerName.firstName/lastName), the rawData passed to onSuccess, and the persisted Redux form data, extracting this into a helper (e.g. deriveAccountOwnerNames(data: IBankAccountDetails)) would:

  • Avoid future drift if the splitting rules change.
  • Make this part of onSubmit easier to read.

These adjustments are non‑blocking but would make the behavior more defensive and maintainable.

Also applies to: 226-227, 238-239


357-387: DRY up duplicated account owner name validation rules

The accountOwnerName field’s validation (required + “at least two space‑separated parts”) is repeated three times: guest claim flow, logged‑in claim without fullName, and withdraw flow. The logic and error messages are identical.

To keep things consistent and easier to tweak later, consider extracting the rules into a shared constant/function:

+ const accountOwnerNameRules = {
+   required: 'Account owner name is required',
+   validate: (value: string) => {
+     const trimmed = value.trim()
+     const parts = trimmed.split(/\s+/)
+     if (parts.length < 2) {
+       return 'Please enter both first and last name'
+     }
+     return true
+   },
+ }
...
- {renderInput('accountOwnerName', 'Account Owner Name', {
-   required: 'Account owner name is required',
-   validate: (value: string) => {
-     const trimmed = value.trim()
-     const parts = trimmed.split(/\s+/)
-     if (parts.length < 2) {
-       return 'Please enter both first and last name'
-     }
-     return true
-   },
- })}
+ {renderInput('accountOwnerName', 'Account Owner Name', accountOwnerNameRules)}

Same reference can be reused in all three places, reducing the chance of small copy‑paste differences in future edits.

Also applies to: 396-409

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cc8fb7f and 94b7f8d.

📒 Files selected for processing (10)
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx (1 hunks)
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx (2 hunks)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx (3 hunks)
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx (8 hunks)
  • src/components/Claim/Link/views/BankFlowManager.view.tsx (1 hunks)
  • src/components/Setup/Views/InstallPWA.tsx (5 hunks)
  • src/components/Setup/components/SetupWrapper.tsx (4 hunks)
  • src/hooks/useBravePWAInstallState.ts (1 hunks)
  • src/hooks/useGetBrowserType.ts (1 hunks)
  • src/hooks/useHomeCarouselCTAs.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (20)
📓 Common learnings
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/noFees.tsx:282-285
Timestamp: 2025-08-14T12:46:10.706Z
Learning: In the peanutprotocol/peanut-ui project, loading states are implemented only after they have been properly designed by the design team to ensure consistency across the application.
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-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/components/Claim/Link/views/BankFlowManager.view.tsx
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
📚 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/Claim/Link/views/BankFlowManager.view.tsx
📚 Learning: 2025-11-06T08:19:05.201Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1407
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:459-475
Timestamp: 2025-11-06T08:19:05.201Z
Learning: In src/components/AddWithdraw/DynamicBankAccountForm.tsx, the street address field has a 35-character maximum length limit because the backend provider enforces this constraint, applicable to both US and Mexican addresses.

Applied to files:

  • src/components/Claim/Link/views/BankFlowManager.view.tsx
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.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)/withdraw/[country]/bank/page.tsx
  • src/hooks/useHomeCarouselCTAs.tsx
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.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/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/hooks/useHomeCarouselCTAs.tsx
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
📚 Learning: 2025-08-14T14:42:54.411Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/utils/withdraw.utils.ts:181-191
Timestamp: 2025-08-14T14:42:54.411Z
Learning: The countryCodeMap in src/components/AddMoney/consts/index.ts uses uppercase 3-letter country codes as keys (like 'AUT', 'BEL', 'CZE') that map to 2-letter country codes, requiring input normalization to uppercase for proper lookups.

Applied to files:

  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/hooks/useHomeCarouselCTAs.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
📚 Learning: 2025-08-13T18:22:01.941Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:0-0
Timestamp: 2025-08-13T18:22:01.941Z
Learning: In the DynamicBankAccountForm component, the countryName parameter from useParams will always resemble a country title, not a URL slug.

Applied to files:

  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
📚 Learning: 2025-10-02T15:23:01.513Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1266
File: src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx:46-57
Timestamp: 2025-10-02T15:23:01.513Z
Learning: In the withdraw flow at src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, the points calculation query intentionally uses crypto.randomUUID() in the queryKey dependency array to bypass React Query caching, ensuring fresh points estimates on every render. This is the intended behavior.

Applied to files:

  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/hooks/useHomeCarouselCTAs.tsx
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.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)/withdraw/[country]/bank/page.tsx
  • src/hooks/useHomeCarouselCTAs.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
📚 Learning: 2025-08-11T10:35:02.715Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1078
File: src/hooks/useKycFlow.ts:129-141
Timestamp: 2025-08-11T10:35:02.715Z
Learning: In the KYC flow implementation in `src/hooks/useKycFlow.ts`, when Terms of Service (ToS) is accepted, there will always be a KYC link available in the `apiResponse`. The system ensures this invariant, so defensive checks for missing KYC links after ToS acceptance are unnecessary.

Applied to files:

  • src/hooks/useHomeCarouselCTAs.tsx
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1112
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:336-343
Timestamp: 2025-08-20T09:08:19.266Z
Learning: In the KYC flow implementation, `setJustCompletedKyc` must be called after `await fetchUser()` in the `handleKycSuccess` callback. Setting `justCompletedKyc` before fetching the user would cause a re-fetching loop because `handleKycSuccess` is set in a useEffect inside the KYC hook, which would cause the UI flow to get stuck in one view.

Applied to files:

  • src/hooks/useHomeCarouselCTAs.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
📚 Learning: 2025-10-08T17:13:13.155Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1299
File: src/app/(mobile-ui)/points/page.tsx:41-51
Timestamp: 2025-10-08T17:13:13.155Z
Learning: In `src/app/(mobile-ui)/points/page.tsx`, the icon name "invite-heart" is intentionally used (not "inviter-heart") when displaying who invited the current user, as this is a deliberate design choice despite semantic differences with UserHeader usage.

Applied to files:

  • src/app/(mobile-ui)/withdraw/manteca/page.tsx
📚 Learning: 2025-09-16T17:27:39.840Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1201
File: src/components/Payment/Views/MantecaFulfillment.view.tsx:56-56
Timestamp: 2025-09-16T17:27:39.840Z
Learning: In the TRequestResponse interface (src/services/services.types.ts), recipientAccount is a required field, not optional. When requestDetails is not null, recipientAccount and its nested user.username properties are guaranteed to exist. Only requestDetails itself can be null (typed as TRequestResponse | null).

Applied to files:

  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/AddWithdraw/AddWithdrawCountriesList.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/AddWithdraw/DynamicBankAccountForm.tsx
📚 Learning: 2025-06-22T16:10:53.167Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 915
File: src/hooks/useKycFlow.ts:96-124
Timestamp: 2025-06-22T16:10:53.167Z
Learning: The `initiateKyc` function in `src/app/actions/users.ts` already includes comprehensive error handling with try-catch blocks and returns structured responses with either `{ data }` or `{ error }` fields, so additional try-catch blocks around its usage are not needed.

Applied to files:

  • src/components/AddWithdraw/AddWithdrawCountriesList.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/components/Setup/components/SetupWrapper.tsx
  • src/components/Setup/Views/InstallPWA.tsx
📚 Learning: 2025-08-19T09:08:16.945Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1107
File: src/components/LandingPage/hero.tsx:160-160
Timestamp: 2025-08-19T09:08:16.945Z
Learning: In the Hero component at src/components/LandingPage/hero.tsx, the team prefers to keep the main heading as h2 (not h1) and does not want a heading prop parameter - the heading content should remain hardcoded in the component.

Applied to files:

  • src/components/Setup/components/SetupWrapper.tsx
📚 Learning: 2025-08-07T12:53:50.946Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1072
File: src/app/(setup)/setup/page.tsx:173-175
Timestamp: 2025-08-07T12:53:50.946Z
Learning: In the peanut-ui setup flow at `src/app/(setup)/setup/page.tsx`, when handling unsupported scenarios, both device not supported and browser not supported cases should show the same "Unsupported browser" message using the `UnsupportedBrowserModal` component, rather than having distinct messaging for each scenario.

Applied to files:

  • src/components/Setup/Views/InstallPWA.tsx
📚 Learning: 2025-08-12T17:44:04.268Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/dropLink.tsx:35-42
Timestamp: 2025-08-12T17:44:04.268Z
Learning: In the Peanut UI project, opening the `/setup` route in a new tab from landing page CTAs is intentional design behavior to keep users on the marketing page while they start the setup process.

Applied to files:

  • src/components/Setup/Views/InstallPWA.tsx
🧬 Code graph analysis (6)
src/hooks/useBravePWAInstallState.ts (1)
src/hooks/useGetBrowserType.ts (1)
  • useGetBrowserType (19-85)
src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx (1)
src/components/Payment/PaymentInfoRow.tsx (1)
  • PaymentInfoRow (18-88)
src/hooks/useHomeCarouselCTAs.tsx (1)
src/hooks/useGeoLocation.ts (1)
  • useGeoLocation (17-71)
src/components/AddWithdraw/DynamicBankAccountForm.tsx (1)
scripts/compare-rates.mjs (2)
  • value (24-24)
  • trimmed (20-20)
src/components/Setup/components/SetupWrapper.tsx (1)
src/hooks/useBravePWAInstallState.ts (1)
  • useBravePWAInstallState (17-67)
src/components/Setup/Views/InstallPWA.tsx (2)
src/components/Setup/Setup.types.ts (2)
  • BeforeInstallPromptEvent (57-64)
  • ScreenId (1-14)
src/hooks/useBravePWAInstallState.ts (1)
  • useBravePWAInstallState (17-67)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (19)
src/hooks/useGetBrowserType.ts (1)

56-59: LGTM! Correct ordering for Brave detection.

Moving Brave detection before Chrome is necessary since Brave's user agent includes "chrome". The optional chaining on isBrave?.() and explicit === true check provide good defensive handling.

src/hooks/useBravePWAInstallState.ts (1)

17-67: Well-structured hook with proper cleanup.

The implementation correctly:

  • Uses cancellation pattern for async safety
  • Cleans up event listener on unmount
  • Gracefully handles missing getInstalledRelatedApps API
  • Combines multiple signals (standalone mode, related apps, browser type)
src/components/Setup/components/SetupWrapper.tsx (1)

212-223: Clean integration of Brave-specific messaging.

The conditional heading logic is clear and the state management is straightforward. The shouldShowBraveInstalledHeaderOnly flag appropriately gates the success message to Brave users on PWA install screens.

src/components/Setup/Views/InstallPWA.tsx (4)

38-38: Good refactor to centralized hook.

Replacing the inline Brave detection with useBravePWAInstallState consolidates browser detection logic and ensures consistency across components.


159-163: Confirm intended UX: Brave users see only the header after installation.

When Brave PWA is installed but not in standalone mode, AndroidPWASpecificInstallFlow returns null. Combined with SetupWrapper showing "Success! Please open the Peanut app from your home screen...", this provides the guidance. Just ensure this is the intended flow where users see only text with no action button.


72-74: Adding push to dependencies is technically correct.

While Next.js router's push function is stable, including it satisfies the exhaustive-deps rule. No functional change expected.


95-110: Remove this review comment — the component does not use conflicting sources of PWA state.

InstallPWA imports only isBrave from useBravePWAInstallState (line 38), not isPWAInstalled. The component's local isPWAInstalled state (line 37) is independent and is the only source used within this component. The local state intentionally includes the 10-second installComplete delay (lines 76–82), and the effect at lines 95–110 correctly uses only this local state alongside isBrave. No divergence between two sources exists.

Likely an incorrect or invalid review comment.

src/app/(mobile-ui)/withdraw/manteca/page.tsx (1)

372-374: Good refactor: Consolidated points display into reusable component.

The replacement of the inline points display with PointsCard improves consistency across the codebase. The pointsDivRef is correctly passed for confetti origin positioning.

src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx (1)

292-295: Good change: Clearer label and consistent data source.

The label change from "Full name" to "Account Owner" is more accurate for this context. The fallback chain accountOwnerName -> fullName -> 'N/A' properly handles cases where the new field isn't yet populated on older accounts.

src/hooks/useHomeCarouselCTAs.tsx (5)

45-45: Verify handling when geolocation is loading or fails.

useGeoLocation returns countryCode which can be null during loading or on error. The isLatamUser check at line 97 correctly handles this (null !== 'AR' && null !== 'BR'), so the LATAM CTA won't show during loading, which is appropriate behavior.


95-98: Good DRY refactor for KYC and LATAM checks.

Consolidating hasKycApproval avoids repeating the OR condition. The isLatamUser derivation is clear and correctly uses the 2-letter ISO country codes that useGeoLocation returns.


153-177: New LATAM Cashback CTA looks good.

The CTA is appropriately gated to Argentina and Brazil users. The copy is clear about the 20% cashback benefit and the invite mechanism. Navigation to /points is correct for the rewards/referral page.


206-206: Consistent use of hasKycApproval variable.

The KYC prompt condition now correctly uses the consolidated hasKycApproval variable, maintaining consistency with the QR payment CTA logic.


242-242: Dependency array correctly updated.

Adding userCountryCode ensures the carousel CTAs regenerate when the user's country is determined, which is necessary for the LATAM CTA to appear correctly.

src/components/AddWithdraw/AddWithdrawCountriesList.tsx (3)

15-15: Import cleanup: updateUserById removed.

The removal of updateUserById from imports aligns with the AI summary indicating that the branch updating user profile (fullName and email) has been removed. This simplifies the flow by relying on form-collected accountOwnerName.


94-96: Simplified happy path validation.

Removing the fullName check is correct since accountOwnerName is now always collected from the form (via DynamicBankAccountForm). The comment clearly documents this design decision.


119-126: Fallback account details correctly construct accountOwnerName for display.

The code safely constructs accountOwnerName from payload.accountOwnerName.firstName and payload.accountOwnerName.lastName. Form validation upstream in DynamicBankAccountForm ensures both properties are always strings (with empty string defaults), so the template literal correctly composes the display name for the confirmation page even when the account isn't immediately found in refreshed user data.

src/components/Claim/Link/views/BankFlowManager.view.tsx (1)

431-434: The split firstName and lastName derived from user.fullName are not actually used in the saved accounts flow. While a single-word name would result in an empty lastName string, this doesn't impact functionality since receiverFullName is set directly to userForOfframp.fullName (the unsplit full name), and the split values are neither displayed in the confirmation view nor sent to any API. If these fields are intended for future use, consider whether the empty string for single-word names is acceptable or if additional validation/trimming is needed.

src/components/AddWithdraw/DynamicBankAccountForm.tsx (1)

91-107: Prefill behavior for account owner name and email looks consistent with flows

The new defaultAccountOwnerName and useForm defaults correctly distinguish flows:

  • Claim flow: pre‑fills accountOwnerName and email from user.user.fullName / user.user.email when present.
  • Withdraw flow: leaves accountOwnerName empty by design and avoids pre‑filling email, relying instead on the stored user email (only rendering the email field when there is no user email).

Because initialData and persistedFormData are spread after the defaults, existing saved data will still override these values, preserving backwards compatibility. This looks good as‑is.

Fix/manteca loading state, Duplicate manteca KYC modal, copy change
@coderabbitai coderabbitai bot added the enhancement New feature or request label Dec 11, 2025
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)/qr-pay/page.tsx (1)

1556-1576: Send button loading label change looks good; consider centralizing copy

The conditional now cleanly differentiates between WebSocket wait ('Processing Payment...') and generic loading ('Loading...'), which is fine and keeps UX clear. If you find more places using similar strings, you might eventually want to centralize these labels (or tie them to loadingState) to avoid copy drift, but that’s purely optional.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 94b7f8d and 8236fdd.

📒 Files selected for processing (3)
  • src/app/(mobile-ui)/qr-pay/page.tsx (1 hunks)
  • src/components/Global/PeanutActionCard/index.tsx (1 hunks)
  • src/components/Kyc/InitiateMantecaKYCModal.tsx (4 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/noFees.tsx:282-285
Timestamp: 2025-08-14T12:46:10.706Z
Learning: In the peanutprotocol/peanut-ui project, loading states are implemented only after they have been properly designed by the design team to ensure consistency across the application.
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-10-08T17:13:13.155Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1299
File: src/app/(mobile-ui)/points/page.tsx:41-51
Timestamp: 2025-10-08T17:13:13.155Z
Learning: In `src/app/(mobile-ui)/points/page.tsx`, the icon name "invite-heart" is intentionally used (not "inviter-heart") when displaying who invited the current user, as this is a deliberate design choice despite semantic differences with UserHeader usage.

Applied to files:

  • src/components/Global/PeanutActionCard/index.tsx
📚 Learning: 2025-07-24T10:57:15.315Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1000
File: src/components/og/ProfileCardOG.tsx:0-0
Timestamp: 2025-07-24T10:57:15.315Z
Learning: In `src/components/og/ProfileCardOG.tsx`, the scribble image should have an empty alt attribute (alt="") to prevent layout issues if the image fails to load. Since it's a decorative element positioned absolutely over the username text, showing alt text would interfere with the layout and username display.

Applied to files:

  • src/components/Global/PeanutActionCard/index.tsx
📚 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/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/app/(mobile-ui)/qr-pay/page.tsx
  • src/components/Kyc/InitiateMantecaKYCModal.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
📚 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)/qr-pay/page.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/app/(mobile-ui)/qr-pay/page.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/app/(mobile-ui)/qr-pay/page.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/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/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2024-10-23T09:38:04.446Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:04.446Z
Learning: Within `src/app/request/pay/page.tsx`, extracting the `getBaseUrl` function does not add significant readability, and the host URL construction code is expected to change soon.

Applied to files:

  • src/app/(mobile-ui)/qr-pay/page.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/components/Kyc/InitiateMantecaKYCModal.tsx
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1112
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:336-343
Timestamp: 2025-08-20T09:08:19.266Z
Learning: In the KYC flow implementation, `setJustCompletedKyc` must be called after `await fetchUser()` in the `handleKycSuccess` callback. Setting `justCompletedKyc` before fetching the user would cause a re-fetching loop because `handleKycSuccess` is set in a useEffect inside the KYC hook, which would cause the UI flow to get stuck in one view.

Applied to files:

  • src/components/Kyc/InitiateMantecaKYCModal.tsx
🔇 Additional comments (4)
src/components/Global/PeanutActionCard/index.tsx (1)

27-27: Copy change looks good

Text update is localized to the subtitle and doesn’t affect layout or behavior. Safe to ship as-is.

src/components/Kyc/InitiateMantecaKYCModal.tsx (3)

22-22: LGTM!

The autoStartKyc prop is properly typed and integrated into the component.

Also applies to: 35-35


64-69: LGTM!

The dynamic title and description logic provides appropriate feedback during the auto-start flow while preserving flexibility for custom messaging.


118-118: LGTM!

The auto-start logic correctly triggers for users who haven't completed KYC approval, streamlining the verification flow for new users while preserving manual control for users requiring regional re-verification.

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: 0

🧹 Nitpick comments (1)
src/components/Global/WalletNavigation/index.tsx (1)

109-109: Consider adding fill="currentColor" to Support icon for consistency.

The Home icon (Line 87) uses fill="currentColor" to inherit color for the active state styling, but the Support icon does not. Adding this attribute would ensure consistent color behavior across both mobile navigation items.

🔎 Proposed fix for visual consistency
-                <NavIcon name="peanut-support" size={20} />
+                <NavIcon name="peanut-support" size={20} fill="currentColor" />
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3f9431 and 1bf34b0.

📒 Files selected for processing (1)
  • src/components/Global/WalletNavigation/index.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/noFees.tsx:282-285
Timestamp: 2025-08-14T12:46:10.706Z
Learning: In the peanutprotocol/peanut-ui project, loading states are implemented only after they have been properly designed by the design team to ensure consistency across the application.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.
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.
🧬 Code graph analysis (1)
src/components/Global/WalletNavigation/index.tsx (1)
src/context/ModalsContext.tsx (1)
  • useModalsContext (81-87)
⏰ 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 (3)
src/components/Global/WalletNavigation/index.tsx (3)

23-29: LGTM! Icon sizing reflects a unified design scheme.

The updated icon sizes create logical groupings (14 for directional actions and info, 15 for transaction actions), improving visual consistency across the desktop navigation.


87-88: LGTM! Home icon and label spacing updated consistently.

The larger icon (26 vs 20) combined with fill="currentColor" ensures proper color inheritance for the active state, and removing mt-1 from the label maintains proper visual alignment with the increased icon size.


6-6: No issues identified. The useModalsContext hook correctly provides the setIsSupportModalOpen method. The ModalsContext interface (line 16) and provider value (line 59) both include setIsSupportModalOpen, and the usage at line 72 in WalletNavigation is valid.

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: 0

♻️ Duplicate comments (2)
src/app/(mobile-ui)/add-money/crypto/page.tsx (1)

20-26: Include peanutWalletAddress in the query key to prevent stale cache.

The queryFn uses peanutWalletAddress to create the deposit address, but it's missing from the queryKey. If the wallet address changes (e.g., account switch), React Query will serve stale cached data created for a different wallet address.

🔎 Proposed fix
     const { data: depositAddressData, isLoading } = useQuery({
-        queryKey: ['rhino-deposit-address', user?.user.userId, chainType],
+        queryKey: ['rhino-deposit-address', user?.user.userId, peanutWalletAddress, chainType],
         queryFn: () =>
             rhinoApi.createDepositAddress(peanutWalletAddress as string, chainType, user?.user.userId as string),
         enabled: !!user && !!peanutWalletAddress,
         staleTime: 1000 * 60 * 60 * 24, // 24 hours
     })
src/components/Global/Icons/Icon.tsx (1)

168-168: Refine the Tailwind color class detection regex.

The regex /text-/ will match any className containing "text-" anywhere (e.g., "context-menu", "latest-version", "subtext-container"), not just Tailwind color classes. This could cause incorrect color handling where Tailwind classes are detected when they shouldn't be.

🔎 Proposed fix to make the regex more specific
-    const hasTextColorClass = className && /text-/.test(className)
+    const hasTextColorClass = className && /(?:^|\s)text-\w+/.test(className)

This ensures the pattern matches "text-" only at word boundaries (start of string or after whitespace), preventing false positives.

🧹 Nitpick comments (4)
src/components/Global/CopyToClipboard/index.tsx (1)

68-68: Simplify redundant fill logic.

Since fill has a default value of 'black' (line 20), the ternary fill ? fill : 'white' will never use the 'white' fallback. This is either dead code or indicates a misunderstanding of the default parameter behavior.

🔎 Proposed fix
-                fill={fill ? fill : 'white'}
+                fill={fill}
src/components/Global/TokenAndNetworkConfirmationModal/index.tsx (1)

41-48: Calculate remaining EVM chain count dynamically.

The hardcoded .slice(0, 6) and '+4 EVM' text assume exactly 10 EVM chains total. If RHINO_SUPPORTED_EVM_CHAINS grows or shrinks, this display becomes incorrect.

🔎 Proposed fix
-                            {RHINO_SUPPORTED_EVM_CHAINS.slice(0, 6).map((chain) => (
+                            {RHINO_SUPPORTED_EVM_CHAINS.slice(0, Math.min(6, RHINO_SUPPORTED_EVM_CHAINS.length)).map((chain) => (
                                 <ChainChip key={chain.name} chainName={chain.name} chainSymbol={chain.logoUrl} />
                             ))}
-                            <ChainChip
-                                chainName={'+4 EVM'}
-                                logo="plus"
-                                logoClassName="bg-black rounded-full text-white"
-                            />
+                            {RHINO_SUPPORTED_EVM_CHAINS.length > 6 && (
+                                <ChainChip
+                                    chainName={`+${RHINO_SUPPORTED_EVM_CHAINS.length - 6} EVM`}
+                                    logo="plus"
+                                    logoClassName="bg-black rounded-full text-white"
+                                />
+                            )}
src/components/Global/AddressLink/index.tsx (2)

17-17: Simplify by removing redundant crypto address check.

The printableAddress function already checks isCryptoAddress internally and returns the address unchanged if it's not a crypto address. The ternary here is redundant.

🔎 Proposed simplification
-        isCryptoAddress(address) ? printableAddress(address) : address
+        printableAddress(address)

38-38: Simplify by removing redundant crypto address check.

Same as line 17—printableAddress already handles non-crypto addresses internally, making this ternary unnecessary.

🔎 Proposed simplification
-            setDisplayAddress(isCryptoAddress(address) ? printableAddress(address) : address)
+            setDisplayAddress(printableAddress(address))
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 466e78a and 755dcee.

📒 Files selected for processing (7)
  • src/app/(mobile-ui)/add-money/crypto/page.tsx
  • src/components/AddMoney/components/ChainChip.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/Global/AddressLink/index.tsx
  • src/components/Global/CopyToClipboard/index.tsx
  • src/components/Global/Icons/Icon.tsx
  • src/components/Global/TokenAndNetworkConfirmationModal/index.tsx
🧰 Additional context used
🧠 Learnings (32)
📓 Common learnings
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/noFees.tsx:282-285
Timestamp: 2025-08-14T12:46:10.706Z
Learning: In the peanutprotocol/peanut-ui project, loading states are implemented only after they have been properly designed by the design team to ensure consistency across the application.
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 669
File: src/lib/validation/recipient.ts:21-56
Timestamp: 2025-02-17T14:07:49.883Z
Learning: In the peanut-ui repository, wrapping switch case blocks in braces to comply with linter rules and avoid variable leakage is considered a non-blocking style improvement.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2026-01-02T13:14:32.635Z
Learning: In the peanut-ui codebase, the add-money flows (bank and Manteca) use nuqs library for URL-based state management (step, amount, currency via useQueryStates), while RequestFulfillmentFlowContext still uses enum-based context state. This creates intentional partial migration where URL state is used for user-facing flows that benefit from deep linking and bookmarking.
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-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/components/Global/CopyToClipboard/index.tsx
  • src/app/(mobile-ui)/add-money/crypto/page.tsx
  • src/components/Global/AddressLink/index.tsx
📚 Learning: 2025-10-02T15:23:01.513Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1266
File: src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx:46-57
Timestamp: 2025-10-02T15:23:01.513Z
Learning: In the withdraw flow at src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, the points calculation query intentionally uses crypto.randomUUID() in the queryKey dependency array to bypass React Query caching, ensuring fresh points estimates on every render. This is the intended behavior.

Applied to files:

  • src/app/(mobile-ui)/add-money/crypto/page.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.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/app/(mobile-ui)/add-money/crypto/page.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.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)/add-money/crypto/page.tsx
📚 Learning: 2026-01-02T13:14:32.635Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2026-01-02T13:14:32.635Z
Learning: In the peanut-ui codebase, the add-money flows (bank and Manteca) use nuqs library for URL-based state management (step, amount, currency via useQueryStates), while RequestFulfillmentFlowContext still uses enum-based context state. This creates intentional partial migration where URL state is used for user-facing flows that benefit from deep linking and bookmarking.

Applied to files:

  • src/app/(mobile-ui)/add-money/crypto/page.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/app/(mobile-ui)/add-money/crypto/page.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.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/app/(mobile-ui)/add-money/crypto/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)/add-money/crypto/page.tsx
  • src/components/AddMoney/components/ChainChip.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/Global/TokenAndNetworkConfirmationModal/index.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 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.

Applied to files:

  • src/app/(mobile-ui)/add-money/crypto/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)/add-money/crypto/page.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.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/app/(mobile-ui)/add-money/crypto/page.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/Global/TokenAndNetworkConfirmationModal/index.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/app/(mobile-ui)/add-money/crypto/page.tsx
📚 Learning: 2025-11-13T18:17:06.391Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2025-11-13T18:17:06.391Z
Learning: In peanutprotocol/peanut-ui, the Service Worker cannot cache POST requests (including blockchain RPC calls like balanceOf) because the browser Cache Storage API only accepts GET requests as cache keys per the W3C spec. Alternative solutions documented in sw.ts include server-side proxy (POST→GET conversion) or custom IndexedDB caching. Current approach uses TanStack Query in-memory cache (30s staleTime) for balance queries.

Applied to files:

  • src/app/(mobile-ui)/add-money/crypto/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)/add-money/crypto/page.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/components/AddMoney/components/ChainChip.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/Global/TokenAndNetworkConfirmationModal/index.tsx
📚 Learning: 2025-08-14T14:42:54.411Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/utils/withdraw.utils.ts:181-191
Timestamp: 2025-08-14T14:42:54.411Z
Learning: The countryCodeMap in src/components/AddMoney/consts/index.ts uses uppercase 3-letter country codes as keys (like 'AUT', 'BEL', 'CZE') that map to 2-letter country codes, requiring input normalization to uppercase for proper lookups.

Applied to files:

  • src/components/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.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/components/AddMoney/views/RhinoDeposit.view.tsx
📚 Learning: 2025-06-22T16:10:53.167Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 915
File: src/hooks/useKycFlow.ts:96-124
Timestamp: 2025-06-22T16:10:53.167Z
Learning: The `initiateKyc` function in `src/app/actions/users.ts` already includes comprehensive error handling with try-catch blocks and returns structured responses with either `{ data }` or `{ error }` fields, so additional try-catch blocks around its usage are not needed.

Applied to files:

  • src/components/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/Global/AddressLink/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/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.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/Global/AddressLink/index.tsx
📚 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/Global/AddressLink/index.tsx
📚 Learning: 2024-10-08T20:28:39.527Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 431
File: src/components/Create/Link/Success.view.tsx:89-89
Timestamp: 2024-10-08T20:28:39.527Z
Learning: `utils.printableAddress` is implemented in the codebase.

Applied to files:

  • src/components/Global/AddressLink/index.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/components/Global/TokenAndNetworkConfirmationModal/index.tsx
📚 Learning: 2024-10-07T15:50:29.173Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-07T15:50:29.173Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.

Applied to files:

  • src/components/Global/TokenAndNetworkConfirmationModal/index.tsx
📚 Learning: 2024-10-29T12:19:41.968Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.

Applied to files:

  • src/components/Global/TokenAndNetworkConfirmationModal/index.tsx
📚 Learning: 2024-10-11T01:14:15.489Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 424
File: src/components/Global/TokenSelector/TokenSelector.tsx:197-211
Timestamp: 2024-10-11T01:14:15.489Z
Learning: In `src/components/Global/TokenSelector/TokenSelector.tsx`, when the calculation within functions like `byChainAndText` is not computationally expensive, it's acceptable to avoid using `useCallback` for memoization.

Applied to files:

  • src/components/Global/TokenAndNetworkConfirmationModal/index.tsx
📚 Learning: 2025-08-07T12:53:50.946Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1072
File: src/app/(setup)/setup/page.tsx:173-175
Timestamp: 2025-08-07T12:53:50.946Z
Learning: In the peanut-ui setup flow at `src/app/(setup)/setup/page.tsx`, when handling unsupported scenarios, both device not supported and browser not supported cases should show the same "Unsupported browser" message using the `UnsupportedBrowserModal` component, rather than having distinct messaging for each scenario.

Applied to files:

  • src/components/Global/TokenAndNetworkConfirmationModal/index.tsx
📚 Learning: 2025-10-08T17:13:13.155Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1299
File: src/app/(mobile-ui)/points/page.tsx:41-51
Timestamp: 2025-10-08T17:13:13.155Z
Learning: In `src/app/(mobile-ui)/points/page.tsx`, the icon name "invite-heart" is intentionally used (not "inviter-heart") when displaying who invited the current user, as this is a deliberate design choice despite semantic differences with UserHeader usage.

Applied to files:

  • src/components/Global/Icons/Icon.tsx
🧬 Code graph analysis (7)
src/components/Global/CopyToClipboard/index.tsx (2)
src/components/0_Bruddle/Button.tsx (1)
  • Button (80-283)
src/components/Global/Icons/Icon.tsx (1)
  • Icon (286-295)
src/app/(mobile-ui)/add-money/crypto/page.tsx (4)
src/context/authContext.tsx (1)
  • useAuth (247-253)
src/hooks/wallet/useWallet.ts (1)
  • useWallet (16-122)
src/services/services.types.ts (1)
  • RhinoChainType (475-475)
src/services/rhino.ts (1)
  • rhinoApi (5-89)
src/components/AddMoney/components/ChainChip.tsx (2)
src/components/Global/Icons/Icon.tsx (2)
  • IconName (74-146)
  • Icon (286-295)
src/components/0_Bruddle/Card.tsx (1)
  • Card (72-72)
src/components/AddMoney/views/RhinoDeposit.view.tsx (6)
src/services/services.types.ts (2)
  • RhinoChainType (475-475)
  • CreateDepositAddressResponse (476-481)
src/components/Global/CopyToClipboard/index.tsx (1)
  • CopyToClipboardRef (6-8)
src/services/rhino.ts (1)
  • rhinoApi (5-89)
src/hooks/useAutoTruncatedAddress.ts (1)
  • useAutoTruncatedAddress (102-199)
src/utils/general.utils.ts (2)
  • isCryptoAddress (89-91)
  • printableAddress (93-96)
src/constants/rhino.consts.ts (3)
  • RHINO_SUPPORTED_TOKENS (56-59)
  • SUPPORTED_EVM_CHAINS (26-37)
  • CHAIN_LOGOS (2-15)
src/components/Global/AddressLink/index.tsx (2)
src/utils/general.utils.ts (2)
  • isCryptoAddress (89-91)
  • printableAddress (93-96)
src/utils/__mocks__/justaname.ts (1)
  • usePrimaryName (6-10)
src/components/Global/TokenAndNetworkConfirmationModal/index.tsx (1)
src/constants/rhino.consts.ts (3)
  • RHINO_SUPPORTED_OTHER_CHAINS (51-53)
  • RHINO_SUPPORTED_EVM_CHAINS (47-49)
  • RHINO_SUPPORTED_TOKENS (56-59)
src/components/Global/Icons/Icon.tsx (2)
src/components/Global/Icons/bulb.tsx (1)
  • BulbIcon (3-11)
src/components/Global/Icons/invite-heart.tsx (1)
  • InviteHeartIcon (3-32)
⏰ 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/components/AddMoney/components/ChainChip.tsx (1)

12-20: LGTM!

Clean implementation with clear props and rendering logic. The component appropriately handles both image-based and icon-based logos via conditional rendering.

src/components/AddMoney/views/RhinoDeposit.view.tsx (3)

164-190: LGTM!

The tabbed network selector is well-implemented using Radix UI with proper ARIA labels and clear visual states. The three network types (EVM, Solana, Tron) are appropriately handled.


202-217: LGTM!

The QR code display and copy-to-clipboard integration is well-executed. Good use of the imperative copyRef.current?.copy() API and the useAutoTruncatedAddress hook for responsive address display.


227-239: Clarify TRON USDT support limitation in the Rhino API.

The code excludes USDT from TRON deposits, leaving only USDC as the supported token. Since TRC-20 USDT is widely used on TRON, this limitation warrants documentation. Verify whether:

  • The Rhino API genuinely does not support USDT deposits on TRON (backend constraint)
  • Or if this is outdated logic that should be updated

Add a comment explaining the constraint if it's intentional, or remove the filter if USDT should be supported.

src/app/(mobile-ui)/add-money/crypto/page.tsx (1)

28-31: LGTM!

The success callback is properly memoized with useCallback, and the dependencies are correct. The flow to show the success view with the deposited amount is clean.

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: 6

🤖 Fix all issues with AI Agents
In @src/components/Global/AmountInput/index.tsx:
- Around line 162-171: formattedAmount from formatTokenAmount may include commas
(e.g., "1,234.56"), so converting it directly with Number(...) in the block that
sets display and exact values causes NaN; update the logic around
formattedAmount (the variables selectedAmountStr, formattedAmount and the call
to setExactValue using DECIMAL_SCALE) to strip commas (e.g., remove all ','
characters) or otherwise normalize the string to a plain numeric literal before
converting to Number/parseFloat, then call setDisplayValue(formattedAmount) and
setExactValue(Number(cleanedString) * 10 ** DECIMAL_SCALE).
- Around line 75-80: The useEffect that syncs initialAmount checks displayValue
but only lists [initialAmount] in its dependency array, causing a stale
comparison; update the effect by removing the displayValue check from the
if-condition so it reads if (initialAmount && initialAmount !==
lastOutputSecondaryRef.current) { setDisplayValue(initialAmount);
setExactValue(Number(initialAmount) * 10 ** DECIMAL_SCALE); } thereby keeping
the dependency array as [initialAmount] and relying on lastOutputSecondaryRef to
prevent feedback loops; ensure you reference the existing identifiers useEffect,
initialAmount, lastOutputSecondaryRef, setDisplayValue, setExactValue, and
DECIMAL_SCALE when making the change.
- Around line 178-186: The useEffect handling defaultSliderSuggestedAmount sets
display and exact values using formatTokenAmount but converts the
comma-formatted string to Number directly, causing NaN; update the effect (the
useEffect that reads defaultSliderSuggestedAmount) to strip commas from the
formattedAmount before converting: call formattedAmount.replace(/,/g, '') (or a
small helper like stripCommas) prior to Number(...) when computing
setExactValue(Number(...) * 10 ** DECIMAL_SCALE), and ensure setDisplayValue
still receives the original formatted (with commas) string.
- Around line 216-225: The onChange handler for AmountInput uses
formatTokenAmount (which may insert commas) but then calls Number(value) when
setting exact cents via setExactValue, causing NaN for commaed values; update
the handler (the onChange arrow function setting displayValue and calling
setExactValue) to remove thousands separators from the string before converting
to Number (e.g., strip commas or non-numeric characters except the decimal
point) and then multiply by 10 ** DECIMAL_SCALE so setExactValue receives a
valid numeric value.
- Around line 141-175: The onSliderValueChange useCallback closes over
displaySymbol and denominations (used when calling formatTokenAmount) but they
are not listed in its dependency array, which can lead to stale values; update
the dependency array for onSliderValueChange to include displaySymbol and
denominations (and also include formatTokenAmount and DECIMAL_SCALE if they are
not guaranteed stable) so the callback rebinds when those values change.
- Around line 122-139: The useEffect updates setPrimaryAmount and
setSecondaryAmount but does not list those callback props in its dependency
array; add setPrimaryAmount and setSecondaryAmount to the effect dependencies
(alongside displayValue, alternativeDisplayValue, displaySymbol,
secondaryDenomination) so React’s exhaustive-deps rule is satisfied and the
effect will re-run if those callbacks change; you do not need to add
lastOutputSecondaryRef since refs are stable.
🧹 Nitpick comments (2)
src/components/Global/AmountInput/index.tsx (2)

104-109: Consider adding denominations to useMemo dependencies.

The exchangeRate calculation uses the denominations object (Line 106-107) but it's not included in the dependency array. While denominations is derived from props and will change when those props change, including it ensures React can properly track all dependencies.

🔎 Proposed fix
 const exchangeRate = useMemo(() => {
     if (!secondaryDenomination) return 1
     const alternativePrice = denominations[alternativeDisplaySymbol]?.price
     const mainPrice = denominations[displaySymbol]?.price
     return alternativePrice / mainPrice
-}, [displaySymbol, alternativeDisplaySymbol, secondaryDenomination])
+}, [displaySymbol, alternativeDisplaySymbol, secondaryDenomination, denominations])

116-120: Consider adding denominations to useMemo dependencies.

The calculation uses denominations[alternativeDisplaySymbol]?.decimals (Line 119) but denominations is not in the dependency array.

🔎 Proposed fix
 const alternativeDisplayValue = useMemo(() => {
     if (!secondaryDenomination || !alternativeValue) return '0.00'
     const scaledDownValue = alternativeValue / 10 ** DECIMAL_SCALE
     return formatTokenAmount(scaledDownValue, denominations[alternativeDisplaySymbol]?.decimals) ?? '0.00'
-}, [alternativeValue, alternativeDisplaySymbol, secondaryDenomination])
+}, [alternativeValue, alternativeDisplaySymbol, secondaryDenomination, denominations])
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 764a697 and b27f31a.

📒 Files selected for processing (1)
  • src/components/Global/AmountInput/index.tsx
🧰 Additional context used
🧠 Learnings (20)
📓 Common learnings
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/noFees.tsx:282-285
Timestamp: 2025-08-14T12:46:10.706Z
Learning: In the peanutprotocol/peanut-ui project, loading states are implemented only after they have been properly designed by the design team to ensure consistency across the application.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2026-01-02T13:14:32.635Z
Learning: In the peanut-ui codebase, the add-money flows (bank and Manteca) use nuqs library for URL-based state management (step, amount, currency via useQueryStates), while RequestFulfillmentFlowContext still uses enum-based context state. This creates intentional partial migration where URL state is used for user-facing flows that benefit from deep linking and bookmarking.
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.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.
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-10-24T13:44:39.473Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1332
File: src/components/Global/TokenAmountInput/index.tsx:141-150
Timestamp: 2025-10-24T13:44:39.473Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), the slider feature (controlled by `showSlider` prop) is only shown for USD input mode. When the slider is used with `maxAmount`, the `selectedAmount` is computed in USD and `isInputUsd` is always `true`, so the conversion in `onChange` handles it correctly.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2024-10-29T12:19:41.968Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2025-08-22T07:25:59.304Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.

Applied to files:

  • src/components/Global/AmountInput/index.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/components/Global/AmountInput/index.tsx
📚 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/Global/AmountInput/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/Global/AmountInput/index.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/components/Global/AmountInput/index.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/components/Global/AmountInput/index.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/components/Global/AmountInput/index.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/Global/AmountInput/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/components/Global/AmountInput/index.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/Global/AmountInput/index.tsx
📚 Learning: 2024-10-11T01:14:15.489Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 424
File: src/components/Global/TokenSelector/TokenSelector.tsx:197-211
Timestamp: 2024-10-11T01:14:15.489Z
Learning: In `src/components/Global/TokenSelector/TokenSelector.tsx`, when the calculation within functions like `byChainAndText` is not computationally expensive, it's acceptable to avoid using `useCallback` for memoization.

Applied to files:

  • src/components/Global/AmountInput/index.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/components/Global/AmountInput/index.tsx
📚 Learning: 2024-10-24T12:40:15.006Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 478
File: src/components/Request/Create/Views/Initial.view.tsx:48-128
Timestamp: 2024-10-24T12:40:15.006Z
Learning: When `handleOnNext` is deliberately refactored to avoid dependencies that change, it's acceptable to have an empty dependency array in `useCallback`.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2025-05-19T19:40:43.138Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 868
File: src/components/Payment/PaymentForm/index.tsx:284-293
Timestamp: 2025-05-19T19:40:43.138Z
Learning: When converting between USD and token amounts, always check if the token price (divisor) is valid and non-zero before performing the division to prevent Infinity, NaN, or errors. Implementing validation like `if (!tokenPrice || isNaN(tokenPrice) || tokenPrice === 0)` before division operations is crucial for handling cases where price data might be unavailable.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2024-12-02T17:21:45.515Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 551
File: src/context/walletContext/walletContext.tsx:87-88
Timestamp: 2024-12-02T17:21:45.515Z
Learning: When converting `totalBalance` (in USD) to a `BigInt` balance in `src/context/walletContext/walletContext.tsx`, multiplying by `1e6` is intentional to maintain compatibility with USDC's 6 decimal places. The application displays only 2 decimal places, so this level of precision is sufficient.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2025-08-14T14:42:54.411Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/utils/withdraw.utils.ts:181-191
Timestamp: 2025-08-14T14:42:54.411Z
Learning: The countryCodeMap in src/components/AddMoney/consts/index.ts uses uppercase 3-letter country codes as keys (like 'AUT', 'BEL', 'CZE') that map to 2-letter country codes, requiring input normalization to uppercase for proper lookups.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2024-11-26T12:06:11.603Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 545
File: src/components/Global/GeneralRecipientInput/index.tsx:118-126
Timestamp: 2024-11-26T12:06:11.603Z
Learning: For bank account input fields, use `autocomplete="bank-account-number"` when the recipient type is `'us'` or `'iban'`.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
⏰ 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 (1)
src/components/Global/AmountInput/index.tsx (1)

93-97: Add missing dependency to useEffect.

The setCurrentDenomination callback should be included in the dependency array to satisfy React's exhaustive-deps rule and ensure the effect captures the latest reference.

🔎 Proposed fix
 useEffect(() => {
     if (setCurrentDenomination) {
         setCurrentDenomination(displaySymbol)
     }
-}, [displaySymbol])
+}, [displaySymbol, setCurrentDenomination])
⛔ Skipped due to learnings
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.
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.
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.
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.
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.
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 478
File: src/components/Dashboard/useDashboard.tsx:134-134
Timestamp: 2024-10-24T12:36:40.508Z
Learning: In the file `src/components/Dashboard/useDashboard.tsx`, memoization of the `getTokenSymbol` function is not necessary because it is lightweight and does not involve complex computations or network calls.
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.

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: 3

🤖 Fix all issues with AI Agents
In @src/components/Global/AmountInput/index.tsx:
- Around line 64-66: The initialization uses Number(initialAmount) which breaks
for comma-formatted strings like "1,234.56"; before converting initialAmount to
a numeric exactValue, strip commas (e.g., const cleaned = (initialAmount ||
'').replace(/,/g, '')) and then parse Number(cleaned) or fallback to 0, e.g.
setExactValue(Number(cleaned || '0') * 10 ** DECIMAL_SCALE); keep displayValue
initialized to the original initialAmount (so the UI still shows commas) and
update any other logic that parses initialAmount (e.g., in TokenAmountInput
consumers) to use the same cleaned value.
- Around line 77-82: The sync useEffect handling initialAmount fails to strip
thousand-separators, so Number(initialAmount) can yield NaN; update the effect
that reads initialAmount (the useEffect referencing initialAmount, displayValue,
isEditingRef) to sanitize initialAmount by removing commas (e.g., replaceAll or
regex) before converting to Number, then call setDisplayValue with the raw
initialAmount and setExactValue(Number(sanitized) * 10 ** DECIMAL_SCALE) to
match the behavior used elsewhere (same fix as around line 66).
- Line 73: hasValue is computed using Number(displayValue) which returns NaN for
values containing commas (e.g., "1,234.56"), so update the computation to strip
commas before converting: compute hasValue from
Number(displayValue.replace(/,/g, '')) or use parseFloat on the comma-stripped
string and coerce to Boolean; ensure the same comma-stripping approach is used
wherever displayValue is parsed (including places that set
defaultSliderSuggestedAmount or compute rawAlternativeValue) so the conditional
gating rawAlternativeValue behaves correctly.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b27f31a and 1457b2a.

📒 Files selected for processing (1)
  • src/components/Global/AmountInput/index.tsx
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/noFees.tsx:282-285
Timestamp: 2025-08-14T12:46:10.706Z
Learning: In the peanutprotocol/peanut-ui project, loading states are implemented only after they have been properly designed by the design team to ensure consistency across the application.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2026-01-02T13:14:32.635Z
Learning: In the peanut-ui codebase, the add-money flows (bank and Manteca) use nuqs library for URL-based state management (step, amount, currency via useQueryStates), while RequestFulfillmentFlowContext still uses enum-based context state. This creates intentional partial migration where URL state is used for user-facing flows that benefit from deep linking and bookmarking.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.
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.
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-10-24T13:44:39.473Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1332
File: src/components/Global/TokenAmountInput/index.tsx:141-150
Timestamp: 2025-10-24T13:44:39.473Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), the slider feature (controlled by `showSlider` prop) is only shown for USD input mode. When the slider is used with `maxAmount`, the `selectedAmount` is computed in USD and `isInputUsd` is always `true`, so the conversion in `onChange` handles it correctly.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2024-10-29T12:19:41.968Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.

Applied to files:

  • src/components/Global/AmountInput/index.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/components/Global/AmountInput/index.tsx
📚 Learning: 2025-08-22T07:25:59.304Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 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/Global/AmountInput/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/Global/AmountInput/index.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/components/Global/AmountInput/index.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/components/Global/AmountInput/index.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/components/Global/AmountInput/index.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/Global/AmountInput/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/components/Global/AmountInput/index.tsx
📚 Learning: 2024-10-11T01:14:15.489Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 424
File: src/components/Global/TokenSelector/TokenSelector.tsx:197-211
Timestamp: 2024-10-11T01:14:15.489Z
Learning: In `src/components/Global/TokenSelector/TokenSelector.tsx`, when the calculation within functions like `byChainAndText` is not computationally expensive, it's acceptable to avoid using `useCallback` for memoization.

Applied to files:

  • src/components/Global/AmountInput/index.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/components/Global/AmountInput/index.tsx
📚 Learning: 2025-08-14T14:42:54.411Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/utils/withdraw.utils.ts:181-191
Timestamp: 2025-08-14T14:42:54.411Z
Learning: The countryCodeMap in src/components/AddMoney/consts/index.ts uses uppercase 3-letter country codes as keys (like 'AUT', 'BEL', 'CZE') that map to 2-letter country codes, requiring input normalization to uppercase for proper lookups.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2024-11-26T12:06:11.603Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 545
File: src/components/Global/GeneralRecipientInput/index.tsx:118-126
Timestamp: 2024-11-26T12:06:11.603Z
Learning: For bank account input fields, use `autocomplete="bank-account-number"` when the recipient type is `'us'` or `'iban'`.

Applied to files:

  • src/components/Global/AmountInput/index.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/Global/AmountInput/index.tsx
📚 Learning: 2025-05-19T19:40:43.138Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 868
File: src/components/Payment/PaymentForm/index.tsx:284-293
Timestamp: 2025-05-19T19:40:43.138Z
Learning: When converting between USD and token amounts, always check if the token price (divisor) is valid and non-zero before performing the division to prevent Infinity, NaN, or errors. Implementing validation like `if (!tokenPrice || isNaN(tokenPrice) || tokenPrice === 0)` before division operations is crucial for handling cases where price data might be unavailable.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
📚 Learning: 2024-12-02T17:21:45.515Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 551
File: src/context/walletContext/walletContext.tsx:87-88
Timestamp: 2024-12-02T17:21:45.515Z
Learning: When converting `totalBalance` (in USD) to a `BigInt` balance in `src/context/walletContext/walletContext.tsx`, multiplying by `1e6` is intentional to maintain compatibility with USDC's 6 decimal places. The application displays only 2 decimal places, so this level of precision is sufficient.

Applied to files:

  • src/components/Global/AmountInput/index.tsx
🧬 Code graph analysis (1)
src/components/Global/AmountInput/index.tsx (2)
src/hooks/useGetDeviceType.ts (1)
  • useDeviceType (37-42)
src/utils/general.utils.ts (1)
  • formatTokenAmount (375-421)
⏰ 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 (2)
src/components/Global/AmountInput/index.tsx (2)

140-175: The slider snapping logic is well-designed.

The magnetic snap point at 33.33% with tolerance and completion threshold provides good UX for equal splits. The logic correctly:

  • Snaps only at the 33.33% magnetic point (with 0.5% tolerance)
  • Only snaps when amountCollected > 0 exists
  • Requires the snap amount to nearly complete the pot (98% threshold)
  • Fills exactly to remainingAmount when conditions are met

This prevents accidental over-filling while making equal splits intuitive.


268-294: Currency toggle implementation is correct.

The toggle logic properly handles:

  • Resetting isEditingRef to allow sync with converted value
  • Empty input case (just swaps symbol)
  • Strips commas from alternativeDisplayValue before setting displayValue (line 283)
  • Uses pre-scaled alternativeValue directly for exactValue (line 282)

The exchange icon and positioning provide clear affordance for the swap action.

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: 2

🤖 Fix all issues with AI agents
In @src/components/AddMoney/views/RhinoDeposit.view.tsx:
- Line 47: Rename the misspelled state and its setter: change
isUpdatingDepositAddresStatus to isUpdatingDepositAddressStatus and
setisUpdatingDepositAddresStatus to setIsUpdatingDepositAddressStatus; update
the useState declaration and replace all usages of the old identifiers
(including any props, effects, handlers, or conditional checks) to the new
camelCase names to keep consistency across the component (e.g., in functions,
JSX, and calls that toggle or read this state).

In @src/components/Global/InfoCard/index.tsx:
- Line 30: The success variant definition for the InfoCard (the "success" key
that currently sets 'border-success-1 bg-success-6 text-success-7') fails WCAG
AA contrast; update the text color to a darker success token (e.g., replace
text-success-7 with a darker token such as text-success-8 or another shade that
yields at least 4.5:1 against bg-success-6) and re-run a contrast checker to
confirm the new combination meets 4.5:1 for normal text.
🧹 Nitpick comments (2)
src/components/Common/ContactsListSkeleton.tsx (2)

16-22: Use isDisabled prop instead of empty onClick handler.

The skeleton cards use an empty onClick={() => {}} handler. Since ActionListCard supports an isDisabled prop, consider using it to prevent interaction more explicitly.

♻️ Proposed refactor
                    return (
                        <ActionListCard
                            key={index}
                            title={<div className="h-4 w-32 animate-pulse rounded bg-gray-200" />}
                            position={position}
-                           onClick={() => {}}
+                           onClick={() => {}}
+                           isDisabled={true}
                            leftIcon={<div className="h-8 w-8 animate-pulse rounded-full bg-gray-200" />}
                        />
                    )

9-27: Add accessibility attributes for loading state.

The skeleton lacks ARIA attributes to announce the loading state to screen readers. Consider adding aria-busy="true" and an aria-label or visually-hidden text to improve accessibility.

♻️ Proposed refactor
    return (
-       <div className="space-y-2">
+       <div className="space-y-2" aria-busy="true" aria-label="Loading contacts">
            <h2 className="text-base font-bold">Your contacts</h2>
            <div className="flex-1 space-y-0 overflow-y-auto">
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1457b2a and 10f106f.

📒 Files selected for processing (4)
  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
  • src/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/Common/ContactsListSkeleton.tsx
  • src/components/Global/InfoCard/index.tsx
🧰 Additional context used
🧠 Learnings (26)
📓 Common learnings
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:279-279
Timestamp: 2025-08-14T08:02:26.705Z
Learning: For hotfixes in the peanut-ui codebase, prefer generic error messages over specific validation error details until the copy can be reviewed with the team, even when the validation functions return detailed error messages.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1089
File: src/components/LandingPage/noFees.tsx:282-285
Timestamp: 2025-08-14T12:46:10.706Z
Learning: In the peanutprotocol/peanut-ui project, loading states are implemented only after they have been properly designed by the design team to ensure consistency across the application.
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.
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.
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`.
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-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/components/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.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/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
📚 Learning: 2025-08-14T14:42:54.411Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1094
File: src/utils/withdraw.utils.ts:181-191
Timestamp: 2025-08-14T14:42:54.411Z
Learning: The countryCodeMap in src/components/AddMoney/consts/index.ts uses uppercase 3-letter country codes as keys (like 'AUT', 'BEL', 'CZE') that map to 2-letter country codes, requiring input normalization to uppercase for proper lookups.

Applied to files:

  • src/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.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/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.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/components/AddMoney/views/RhinoDeposit.view.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.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/components/AddMoney/views/RhinoDeposit.view.tsx
📚 Learning: 2025-06-22T16:10:53.167Z
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 915
File: src/hooks/useKycFlow.ts:96-124
Timestamp: 2025-06-22T16:10:53.167Z
Learning: The `initiateKyc` function in `src/app/actions/users.ts` already includes comprehensive error handling with try-catch blocks and returns structured responses with either `{ data }` or `{ error }` fields, so additional try-catch blocks around its usage are not needed.

Applied to files:

  • src/components/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.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/AddMoney/views/RhinoDeposit.view.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/components/AddMoney/views/RhinoDeposit.view.tsx
📚 Learning: 2025-11-06T08:19:05.201Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1407
File: src/components/AddWithdraw/DynamicBankAccountForm.tsx:459-475
Timestamp: 2025-11-06T08:19:05.201Z
Learning: In src/components/AddWithdraw/DynamicBankAccountForm.tsx, the street address field has a 35-character maximum length limit because the backend provider enforces this constraint, applicable to both US and Mexican addresses.

Applied to files:

  • src/components/AddMoney/components/AddMoneyBankDetails.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/components/AddMoney/components/AddMoneyBankDetails.tsx
📚 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/AddMoney/components/AddMoneyBankDetails.tsx
📚 Learning: 2026-01-02T13:14:32.635Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2026-01-02T13:14:32.635Z
Learning: In the peanut-ui codebase, the add-money flows (bank and Manteca) use nuqs library for URL-based state management (step, amount, currency via useQueryStates), while RequestFulfillmentFlowContext still uses enum-based context state. This creates intentional partial migration where URL state is used for user-facing flows that benefit from deep linking and bookmarking.

Applied to files:

  • src/components/AddMoney/components/AddMoneyBankDetails.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/AddMoney/components/AddMoneyBankDetails.tsx
📚 Learning: 2024-10-29T12:19:41.968Z
Learnt from: jjramirezn
Repo: peanutprotocol/peanut-ui PR: 495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.

Applied to files:

  • src/components/AddMoney/components/AddMoneyBankDetails.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/components/AddMoney/components/AddMoneyBankDetails.tsx
📚 Learning: 2025-08-22T07:25:59.304Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1104
File: src/components/Payment/PaymentForm/index.tsx:596-600
Timestamp: 2025-08-22T07:25:59.304Z
Learning: The `TokenAmountInput` component in `src/components/Global/TokenAmountInput/` always returns decimal strings (e.g., "1,234.56"), not base units. When passing these values to external APIs like Daimo's `toUnits` prop, simply stripping commas with `.replace(/,/g, '')` is sufficient.

Applied to files:

  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
📚 Learning: 2024-10-08T20:13:42.967Z
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 420
File: src/components/Offramp/Offramp.consts.ts:27-28
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Offramp/Offramp.consts.ts`, the `MIN_CASHOUT_LIMIT` is set to $10 because smaller amounts are impractical due to approximately $1 fee per cashout.

Applied to files:

  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
📚 Learning: 2025-10-24T13:44:39.473Z
Learnt from: Zishan-7
Repo: peanutprotocol/peanut-ui PR: 1332
File: src/components/Global/TokenAmountInput/index.tsx:141-150
Timestamp: 2025-10-24T13:44:39.473Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), the slider feature (controlled by `showSlider` prop) is only shown for USD input mode. When the slider is used with `maxAmount`, the `selectedAmount` is computed in USD and `isInputUsd` is always `true`, so the conversion in `onChange` handles it correctly.

Applied to files:

  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
📚 Learning: 2025-11-07T11:51:58.900Z
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.900Z
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/components/AddMoney/components/AddMoneyBankDetails.tsx
🧬 Code graph analysis (2)
src/components/Common/ContactsListSkeleton.tsx (2)
src/components/Global/Card/index.tsx (1)
  • getCardPosition (15-20)
src/components/ActionListCard/index.tsx (1)
  • ActionListCard (23-78)
src/components/AddMoney/components/AddMoneyBankDetails.tsx (1)
src/components/Payment/PaymentInfoRow.tsx (1)
  • PaymentInfoRow (18-89)
⏰ 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 (16)
src/components/AddMoney/components/AddMoneyBankDetails.tsx (5)

15-18: LGTM!

Import path updates align with the broader refactoring to use granular, feature-specific module imports.


76-79: LGTM!

Amount source correctly updated to use depositInstructions.amount from the request fulfillment context, consistent with the removal of usePaymentStore and chargeDetails.


224-234: Verify that 10-character truncation is sufficient for bank deposit references.

The deposit reference is truncated to 10 characters for both display and copy operations. If banks require the full reference to correctly identify and route transfers, copying only the first 10 characters could cause deposit failures or misattribution.

Ensure this truncation aligns with the backend's reference generation and bank requirements.


248-255: LGTM!

Account Holder Name is correctly rendered conditionally at the top of the bank details block, following the same pattern as other detail rows and consistent with the generateBankDetails function logic for Euro/Mexico flows.


214-217: LGTM!

The iconSize="4" update creates visual consistency with the PaymentInfoRow component, which also uses iconSize=4 for its copy functionality.

src/components/Common/ContactsListSkeleton.tsx (1)

2-3: Import paths are correct and resolve properly to their respective modules.

src/components/Global/InfoCard/index.tsx (5)

7-7: LGTM!

The addition of the 'success' variant and customContent prop are properly typed and integrate cleanly with the component's API.

Also applies to: 22-22


39-39: Verify the icon size reduction aligns with design specifications.

The default iconSize changed from 16 to 14 pixels, affecting all instances that don't explicitly override it. Confirm this visual change is intentional and review existing usages to ensure consistency with the design system.

Based on learnings, visual changes should be validated with the design team before release.


51-51: LGTM!

The parameter correctly matches the interface definition.


54-54: LGTM!

Including customContent in the hasContent check correctly prevents the fallback message when custom content is provided.


104-105: LGTM!

The custom content is correctly rendered within the content area. The explicit conditional check is clear and works as expected.

src/components/AddMoney/views/RhinoDeposit.view.tsx (5)

52-83: LGTM!

The polling setup with initial delay, status fetching via TanStack Query, and status mapping logic are well-implemented. The 15-second initial delay before polling starts is reasonable to avoid unnecessary API calls, and the conditional refetch interval properly stops polling once the deposit is completed.


108-112: Verify onSuccess is not called multiple times.

The effect includes onSuccess in the dependency array. If the parent component doesn't memoize this callback, it will re-create it on every render, causing the effect to re-run. Since you're checking if depositAddressStatus === 'completed', a non-memoized callback could trigger onSuccess multiple times while in the completed state.

Consider either:

  1. Ensuring the parent memoizes onSuccess with useCallback
  2. Adding a ref-based guard to ensure onSuccess is called only once per completion
  3. Removing onSuccess from deps and using useEffectEvent if available in your React version
Example guard pattern
+const hasCalledSuccess = useRef(false)
+
 useEffect(() => {
-    if (depositAddressStatus === 'completed' && depositAddressStatusData?.amount) {
+    if (depositAddressStatus === 'completed' && depositAddressStatusData?.amount && !hasCalledSuccess.current) {
+        hasCalledSuccess.current = true
         onSuccess(depositAddressStatusData?.amount)
     }
-}, [depositAddressStatusData, depositAddressStatus, onSuccess])
+}, [depositAddressStatusData, depositAddressStatus])

114-147: LGTM!

The error state UI provides clear, user-friendly messaging explaining the market movement issue and reassuring users that their funds are being returned. The "Try Again" flow is intuitive.


149-281: LGTM!

The main UI is well-structured with:

  • Proper loading states and conditional rendering
  • Clear network type selector with Radix Tabs
  • QR code with truncated address display and copy functionality
  • Correct token filtering (USDC excluded for TRON at lines 227-232)
  • Helpful deposit limit information
  • Conditional EVM networks card for better UX

The component provides a smooth deposit flow with appropriate visual feedback.


85-96: Add error handling for the status reset call.

The rhinoApi.resetDepositAddressStatus call can throw an error, but failures are currently swallowed. This leaves users without feedback when clicking "Try Again" fails.

Likely an incorrect or invalid review comment.

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