Skip to content

Conversation

Zishan-7
Copy link
Contributor

No description provided.

Copy link

Add KYC to Links flow

Copy link

vercel bot commented Sep 18, 2025

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

Project Deployment Preview Comments Updated (UTC)
peanut-wallet Ready Ready Preview Comment Sep 19, 2025 2:15pm

Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

Walkthrough

Adds Manteca/MercadoPago regional payment and KYC flows, parameterizes currency and flag/logo handling, extends claim/request routing and context APIs, adjusts ActionList geolocation/auth gating, and refactors qr-pay Card/modal footer UI.

Changes

Cohort / File(s) Change summary
QR Pay UI & modal footer
src/app/(mobile-ui)/qr-pay/page.tsx
Swapped Card import to @/components/Global/Card, restructured error Card markup/styles, and replaced ActionModal footer with PeanutDoesntStoreAnyPersonalInformation.
Client routing / ActionList gating
src/app/[...recipient]/client.tsx
Reworked showActionList conditional grouping affecting direct_pay visibility and aligned flag rename showExternalWalletFulfilMethodsshowExternalWalletFulfillMethods.
Manteca KYC flow & currency param
src/components/Claim/Link/MantecaFlowManager.tsx, src/components/Payment/Views/MantecaFulfillment.view.tsx, src/components/Claim/Link/views/MantecaReviewStep.tsx, src/hooks/useCurrency.ts, src/components/Kyc/InitiateMantecaKYCModal.tsx (usage)
Added KYC modal state/auto-open when not approved, Argentina fallback country data, fetchUser on KYC success, dynamic currency propagation (MantecaReviewStep now takes currency), and useCurrency initial isLoading true.
Country selection & routing to Manteca/MercadoPago
src/components/Common/CountryList.tsx, src/components/Common/CountryListRouter.tsx
Include Manteca-supported countries in claim/request checks; route selected countries to MercadoPago/Manteca flows; surface new setters (setClaimToMercadoPago, setFlowStep, setFulfillUsingManteca).
ActionList geolocation & auth gating
src/components/Common/ActionList.tsx, src/constants/actionlist.consts.ts
Add Pix payment method, geolocation-filtered methods (PIX for BR, Mercado Pago for non-BR), Loading while geo resolves, and auth-based gating that sets regionalMethodType or emits regional URL steps.
Claim initial & URL step updates
src/components/Claim/Link/Initial.view.tsx, src/components/Claim/useClaimLink.tsx
Add setClaimToMercadoPago usage, support new URL steps (regional-claim, regional-req-fulfill), and broaden effect gating to trigger claim/regional flows earlier.
Contexts: claim & fulfillment
src/context/ClaimBankFlowContext.tsx, src/context/RequestFulfillmentFlowContext.tsx, src/components/Payment/PaymentForm/index.tsx
Add regionalMethodType + setRegionalMethodType to both contexts; rename fulfill/fulfil fields to Fulfill spelling; expose setFulfillUsingManteca; PaymentForm reads step=regional-req-fulfill to toggle Manteca fulfillment.
PeanutActionDetailsCard & UI tweaks
src/components/Global/PeanutActionDetailsCard/index.tsx, src/components/Kyc/CountryRegionRow.tsx
Treat REGIONAL_METHOD_CLAIM like bank flows for icon/logo display, render flag/logo when countryCodeForFlag OR logo present, suppress bank overlay for regional claims, and update CountryFlagAndName import path.
Manteca details copy
src/components/Claim/Link/views/MantecaDetailsStep.view.tsx
Heading changed from "Enter Mercado Pago account details" to "Enter account details".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • jjramirezn
  • kushagrasarathe

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% 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, so there is no high-level intent or summary in the PR body. This is inconclusive because reviewers cannot rely on a PR description to quickly understand scope, rationale, and consumer impact even though the raw summary shows many KYC/Manteca-related changes across files and public APIs. A short description is needed to clarify objectives and risk for reviewers. Ask the author to add a brief PR description that states the intent and top-level changes, explicitly lists the most important public API/signature changes (e.g., new/renamed context setters, added KYC modal/country props, currency prop on MantecaReviewStep), and includes any required migration or QA steps and a link to the task/ticket for reviewer context. This will make review and release notes much easier.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title "[TASK-14805] Feat/kyc integration links" is concise and explicitly references the primary change (KYC integration and link/flow updates), which matches the raw summary showing extensive KYC/Manteca flow additions, modal integrations, and related hook/context changes. It is readable, focused, and helps a teammate scanning history understand the main purpose of the PR. The title avoids noise and is sufficiently specific for this changeset.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/kyc-integration-links

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/(mobile-ui)/qr-pay/page.tsx (1)

379-383: Guard Next/Image against null src and fix alt text

methodIcon can be null (default branch), which will break <Image>. Also, alt text is always “Mercado Pago” even for PIX.

-                        <div className="flex items-center justify-center rounded-full bg-white">
-                            <Image src={methodIcon} alt="Mercado Pago" width={50} height={50} />
-                        </div>
+                        <div className="flex items-center justify-center rounded-full bg-white">
+                            {methodIcon ? (
+                                <Image
+                                    src={methodIcon}
+                                    alt={paymentLock?.type === 'PIX' ? 'PIX' : 'Mercado Pago'}
+                                    width={50}
+                                    height={50}
+                                />
+                            ) : (
+                                <div className="flex h-[50px] w-[50px] items-center justify-center rounded-full bg-grey-4">
+                                    <Icon name="wallet-outline" />
+                                </div>
+                            )}
+                        </div>
🧹 Nitpick comments (7)
src/components/Kyc/CountryRegionRow.tsx (1)

9-18: Normalize countryCode to uppercase before rendering (aligns with upstream maps).

Per retrieved learnings, countryCodeMap expects UPPERCASE 3-letter keys. Normalize here to avoid lookup/flag mismatches and default isBridge to a boolean.

-export const CountryRegionRow = ({ countryCode, isBridge }: CountryRegionRowProps) => {
-    if (!isBridge && !countryCode) {
+export const CountryRegionRow = ({ countryCode, isBridge = false }: CountryRegionRowProps) => {
+    const normalizedCode = (countryCode ?? '').trim().toUpperCase()
+    if (!isBridge && !normalizedCode) {
         return null
     }
 
     return (
         <PaymentInfoRow
             label="Country/Region"
-            value={<CountryFlagAndName countryCode={countryCode ?? ''} isBridgeRegion={isBridge} />}
+            value={<CountryFlagAndName countryCode={normalizedCode} isBridgeRegion={isBridge} />}
         />
     )
 }

Note: Using retrieved learning about uppercase normalization from previous PR context.

src/components/Global/PeanutActionDetailsCard/index.tsx (2)

171-179: Fix alt text for logos and guard against undefined flag name

When a logo is provided, the alt still reads as a flag and may render "undefined flag". Use a context-appropriate alt.

Apply:

-        const imgSrc = logo ? logo : `https://flagcdn.com/w320/${countryCodeForFlag}.png`
+        const imgSrc = logo ? logo : `https://flagcdn.com/w320/${countryCodeForFlag}.png`
+        const altText = logo ? 'Payment method' : `${(countryCodeForFlag ?? '').toUpperCase()} flag`
...
-                        <Image
-                            src={imgSrc}
-                            alt={`${countryCodeForFlag} flag`}
+                        <Image
+                            src={imgSrc}
+                            alt={altText}
                             width={160}
                             height={160}
                             className="h-12 w-12 rounded-full object-cover"
                         />

168-169: Deduplicate the bank/brand icon condition

The same composite condition appears twice. Extract to a single boolean to avoid drift.

-    const isRegionalMethodClaim = transactionType === 'REGIONAL_METHOD_CLAIM'
+    const isRegionalMethodClaim = transactionType === 'REGIONAL_METHOD_CLAIM'
+    const showBankBranding =
+        isWithdrawBankAccount || isAddBankAccount || isClaimLinkBankAccount || isRegionalMethodClaim
...
-        if (isWithdrawBankAccount || isAddBankAccount || isClaimLinkBankAccount || isRegionalMethodClaim)
+        if (showBankBranding)
...
-                    (isWithdrawBankAccount || isAddBankAccount || isClaimLinkBankAccount || isRegionalMethodClaim) ? (
+                    showBankBranding ? (

Also applies to: 172-172, 198-199

src/components/Claim/Link/MantecaFlowManager.tsx (1)

31-39: Avoid duplicating Argentina fallback data

argentinaCountryData is redefined here and elsewhere. Centralize this in a shared constants module to prevent drift.

src/app/(mobile-ui)/qr-pay/page.tsx (2)

172-178: Remove stray no-op statement

finalPaymentLock on its own line is a leftover no-op.

-        if (finalPaymentLock.code === '') {
-            finalPaymentLock
+        if (finalPaymentLock.code === '') {
             setErrorMessage('Could not fetch qr payment details')
             setIsSuccess(false)
             setLoadingState('Idle')
             return
         }

35-36: Consider centralizing the hard cap

MAX_QR_PAYMENT_AMOUNT = '200' is a business limit; move to shared config to keep web and backend aligned.

src/components/Payment/Views/MantecaFulfillment.view.tsx (1)

39-47: Avoid duplicating Argentina fallback data

Same Argentina constant exists in other files. Extract to a shared constants file.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e952b5 and d6ea557.

📒 Files selected for processing (10)
  • src/app/(mobile-ui)/qr-pay/page.tsx (3 hunks)
  • src/app/[...recipient]/client.tsx (1 hunks)
  • src/components/Claim/Link/MantecaFlowManager.tsx (4 hunks)
  • src/components/Claim/Link/views/MantecaReviewStep.tsx (3 hunks)
  • src/components/Common/CountryList.tsx (1 hunks)
  • src/components/Common/CountryListRouter.tsx (2 hunks)
  • src/components/Global/PeanutActionDetailsCard/index.tsx (3 hunks)
  • src/components/Kyc/CountryRegionRow.tsx (1 hunks)
  • src/components/Payment/Views/MantecaFulfillment.view.tsx (4 hunks)
  • src/hooks/useCurrency.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-08-14T14:42:54.411Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#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/Kyc/CountryRegionRow.tsx
  • src/components/Common/CountryListRouter.tsx
📚 Learning: 2025-06-18T19:56:55.443Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#919
File: src/components/Withdraw/views/Initial.withdraw.view.tsx:87-87
Timestamp: 2025-06-18T19:56:55.443Z
Learning: In withdraw flows for Peanut Wallet, the PeanutActionDetailsCard should always display "USDC" as the token symbol because it shows the amount being withdrawn from the Peanut Wallet (which holds USDC), regardless of the destination token/chain selected by the user. The TokenSelector is used for choosing the withdrawal destination, not the source display.

Applied to files:

  • src/components/Global/PeanutActionDetailsCard/index.tsx
📚 Learning: 2025-05-22T15:38:48.586Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".

Applied to files:

  • src/components/Global/PeanutActionDetailsCard/index.tsx
  • src/components/Common/CountryListRouter.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#1190
File: src/app/(mobile-ui)/qr-pay/page.tsx:156-176
Timestamp: 2025-09-08T03:13:09.111Z
Learning: In the peanut-ui mobile app, the `/qr-pay` route is only accessed through the DirectSendQR component which always includes the qrCode parameter in the URL when redirecting users to the QR pay page.

Applied to files:

  • src/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2025-09-08T03:13:09.111Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#1190
File: src/app/(mobile-ui)/qr-pay/page.tsx:156-176
Timestamp: 2025-09-08T03:13:09.111Z
Learning: In the peanut-ui mobile app, the `/qr-pay` route is only accessed through the DirectSendQR component which always includes the qrCode parameter in the URL when redirecting users to the QR pay page after scanning MERCADO_PAGO or PIX QR codes.

Applied to files:

  • src/app/(mobile-ui)/qr-pay/page.tsx
📚 Learning: 2025-08-26T15:25:53.328Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1132
File: src/app/[...recipient]/client.tsx:394-397
Timestamp: 2025-08-26T15:25:53.328Z
Learning: In `src/components/Common/ActionListDaimoPayButton.tsx`, the `handleCompleteDaimoPayment` function should not display error messages to users when DB update fails because the Daimo payment itself has succeeded - showing errors would be confusing since the payment was successful.

Applied to files:

  • src/app/[...recipient]/client.tsx
🧬 Code graph analysis (6)
src/components/Claim/Link/views/MantecaReviewStep.tsx (1)
src/hooks/useCurrency.ts (1)
  • useCurrency (21-65)
src/components/Payment/Views/MantecaFulfillment.view.tsx (7)
src/context/RequestFulfillmentFlowContext.tsx (1)
  • useRequestFulfillmentFlow (109-115)
src/redux/hooks.ts (1)
  • usePaymentStore (12-12)
src/hooks/useKycStatus.tsx (1)
  • useKycStatus (12-26)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/services/manteca.ts (1)
  • mantecaApi (95-232)
src/components/AddMoney/consts/index.ts (1)
  • CountryData (153-162)
src/components/Kyc/InitiateMantecaKYCModal.tsx (1)
  • InitiateMantecaKYCModal (23-70)
src/components/Global/PeanutActionDetailsCard/index.tsx (1)
src/components/Global/Icons/Icon.tsx (1)
  • Icon (196-205)
src/app/(mobile-ui)/qr-pay/page.tsx (1)
src/components/Kyc/KycVerificationInProgressModal.tsx (1)
  • PeanutDoesntStoreAnyPersonalInformation (52-59)
src/components/Claim/Link/MantecaFlowManager.tsx (5)
src/context/ClaimBankFlowContext.tsx (1)
  • useClaimBankFlow (143-149)
src/components/AddMoney/consts/index.ts (1)
  • CountryData (153-162)
src/hooks/useKycStatus.tsx (1)
  • useKycStatus (12-26)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/components/Kyc/InitiateMantecaKYCModal.tsx (1)
  • InitiateMantecaKYCModal (23-70)
src/components/Common/CountryListRouter.tsx (3)
src/context/ClaimBankFlowContext.tsx (1)
  • useClaimBankFlow (143-149)
src/context/RequestFulfillmentFlowContext.tsx (1)
  • useRequestFulfillmentFlow (109-115)
src/components/AddMoney/consts/index.ts (2)
  • CountryData (153-162)
  • MantecaSupportedExchanges (8-19)
🔇 Additional comments (19)
src/components/Kyc/CountryRegionRow.tsx (1)

2-2: Approve: case-sensitive import verified.
Found single canonical file src/components/Kyc/CountryFlagAndName.tsx exporting CountryFlagAndName; no other filename variants or mismatched exports detected.

src/hooks/useCurrency.ts (1)

25-25: Initial loading state change looks good.

The change from false to true for the initial loading state is appropriate. This prevents UI flickers when the hook is first invoked with a currency code, as the loading state will correctly reflect that data is being fetched.

src/components/Common/CountryList.tsx (2)

136-138: Country support logic correctly updated for Manteca integration.

The expansion of isSupported to include both bridge and Manteca-supported countries aligns well with the PR's objective of integrating Manteca/MercadoPago flows.


123-125: Resolved — MantecaSupportedExchanges is exported.
Export found at src/components/AddMoney/consts/index.ts:8; no action required.

src/components/Common/CountryListRouter.tsx (4)

73-76: Flow control logic for Manteca countries looks correct.

The conditional routing to Manteca fulfillment when the country is supported makes sense. The logic properly hides the bank flow manager and enables Manteca fulfillment.


44-49: Verified — context hooks present; no action required.
Both setClaimToMercadoPago and setFlowStep are defined and exposed in src/context/ClaimBankFlowContext.tsx; resolving.


50-56: setFulfillUsingManteca is present in RequestFulfillmentFlowContext — no action required.
Declared and exposed by the provider in src/context/RequestFulfillmentFlowContext.tsx (lines 36, 52, 63, 86).


66-71: No change needed — flowStep is intentionally nullable and consumers handle null.

ClaimBankFlowContext declares flowStep: ClaimBankFlowStep | null (initial null) and resetFlow / other callers use setFlowStep(null) as the intended initial/default state. See src/context/ClaimBankFlowContext.tsx and the call in src/components/Common/CountryListRouter.tsx.

src/components/Claim/Link/views/MantecaReviewStep.tsx (4)

17-17: Currency prop addition is well implemented.

The component now accepts a dynamic currency prop instead of hardcoding 'ARS', making it more flexible for different country integrations.

Also applies to: 25-25


29-29: Good use of the updated useCurrency hook.

The component correctly passes the dynamic currency to the useCurrency hook.


65-65: Currency correctly passed to withdraw API.

The dynamic currency is properly included in the withdrawal API payload.


41-41: Verify currency format consistency.

File: src/components/Claim/Link/views/MantecaReviewStep.tsx — line ~41

            value: `1 USD = ${price?.buy} ${currency}`,

Confirm whether this is for "Manteca" (not "Mantas") and whether UI/UX requires the currency code here or a localized symbol/format; attach the design/doc or state the desired format so we can update accordingly.

src/app/[...recipient]/client.tsx (2)

396-398: Simplified condition logic looks cleaner.

The refactored condition with grouped logic is more readable. The change maintains the same behavior while improving code clarity.


397-398: Resolved — fulfillUsingManteca is initialized and exposed in RequestFulfillmentFlowContext
Initialized with useState(false); the value and setter are included in the provider value and the memo dependency array (src/context/RequestFulfillmentFlowContext.tsx — init at line 52; provider value ~82–86; memo deps include it at line 98).

src/components/Global/PeanutActionDetailsCard/index.tsx (2)

221-241: Confirm currency symbol behavior for regional claims

currencySymbol is shown for ADD_MONEY/*_BANK_ACCOUNT flows only. For REGIONAL_METHOD_CLAIM, the card won’t prefix ARS/BRL. Is that intentional?


170-172: No action required — flagcdn.com already allowed via images.remotePatterns

next.config.js defines images.remotePatterns with hostname: '*' for both http and https, so flagcdn.com is permitted in production.

src/components/Claim/Link/MantecaFlowManager.tsx (2)

53-57: Good KYC cancel flow

Cancelling closes the modal and navigates back. Looks correct.


123-124: Lowercasing country code is safe here

Using optional chaining before toLowerCase() avoids runtime errors. LGTM.

src/components/Payment/Views/MantecaFulfillment.view.tsx (1)

36-37: KYC-gated query enablement looks correct

Query is disabled until chargeDetails?.uuid exists and KYC is approved. Good.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/Claim/useClaimLink.tsx (1)

99-106: Use Next router replace instead of window.history.replaceState to ensure searchParams-driven effects re-run.

Direct replaceState may not trigger Next’s searchParams updates, so downstream effects that watch useSearchParams (e.g., in PaymentForm) might not fire. Prefer router.replace to produce a client navigation update.

Apply this diff here:

-    const addParamStep = (step: 'bank' | 'claim' | 'regional-claim' | 'regional-req-fulfill') => {
+    const addParamStep = (step: 'bank' | 'claim' | 'regional-claim' | 'regional-req-fulfill') => {
         const params = new URLSearchParams(searchParams)
         params.set('step', step)

         const hash = window.location.hash
         const newUrl = `${pathname}?${params.toString()}${hash}`
-        window.history.replaceState(null, '', newUrl)
+        router.replace(newUrl)
     }

And outside this hunk, initialize the router:

// add import
import { usePathname, useSearchParams, useRouter } from 'next/navigation'

// inside hook body
const router = useRouter()

Optional: centralize step values in a shared type/const to avoid string drift across files.

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

168-177: sortedActionMethods not recomputing when geolocatedMethods changes

geolocatedMethods is omitted from deps, so list may stay stale after geo resolves.

-    const sortedActionMethods = useMemo(() => {
-        return [...geolocatedMethods].sort((a, b) => {
+    const sortedActionMethods = useMemo(() => {
+        return [...geolocatedMethods].sort((a, b) => {
             const aIsUnavailable = a.soon || (a.id === 'bank' && requiresVerification)
             const bIsUnavailable = b.soon || (b.id === 'bank' && requiresVerification)
             if (aIsUnavailable === bIsUnavailable) {
                 return 0
             }
             return aIsUnavailable ? 1 : -1
         })
-    }, [requiresVerification])
+    }, [requiresVerification, geolocatedMethods])
♻️ Duplicate comments (1)
src/components/Payment/Views/MantecaFulfillment.view.tsx (1)

50-55: Type mismatch: logo expects StaticImageData; avoid passing flag URL string

Pass flags via countryCodeForFlag and keep logo to static assets only. This also aligns with previous review guidance.

-    const actionCardLogo = selectedCountry?.id
-        ? `https://flagcdn.com/w320/${selectedCountry?.id.toLowerCase()}.png`
-        : regionalMethodType === 'mercadopago'
-          ? MERCADO_PAGO
-          : PIX
+    const actionCardLogo =
+        selectedCountry?.id ? undefined : regionalMethodType === 'mercadopago' ? MERCADO_PAGO : PIX
...
-                    logo={actionCardLogo}
-                    countryCodeForFlag={selectedCountry?.id.toLowerCase()}
+                    logo={actionCardLogo}
+                    countryCodeForFlag={selectedCountry?.id?.toLowerCase()}

Also applies to: 100-102

🧹 Nitpick comments (9)
src/components/Claim/Link/views/MantecaDetailsStep.view.tsx (1)

26-36: Copy tweak is fine; consider aligning placeholder with regional method.

Heading is now generic, but the placeholder still references Mercado Pago ("CVU or Alias"). If this view will be reused for Pix later, make the label/placeholder conditional to avoid UX mismatch.

src/components/Claim/useClaimLink.tsx (1)

108-114: Mirror refactor for removal: use router.replace to keep Next state in sync.

-    const removeParamStep = () => {
+    const removeParamStep = () => {
         const params = new URLSearchParams(searchParams)
         params.delete('step')
         const queryString = params.toString()
-        const newUrl = `${pathname}${queryString ? `?${queryString}` : ''}${window.location.hash}`
-        window.history.replaceState(null, '', newUrl)
+        const newUrl = `${pathname}${queryString ? `?${queryString}` : ''}${window.location.hash}`
+        router.replace(newUrl)
     }
src/context/ClaimBankFlowContext.tsx (1)

47-49: Deduplicate the regional method union into a shared alias.

The string union appears in multiple places; extract it once to avoid drift and ease future additions (e.g., SPEI/UPI).

+type RegionalMethodType = 'mercadopago' | 'pix'
 
 interface ClaimBankFlowContextType {
@@
-    regionalMethodType: 'mercadopago' | 'pix'
-    setRegionalMethodType: (regionalMethodType: 'mercadopago' | 'pix') => void
+    regionalMethodType: RegionalMethodType
+    setRegionalMethodType: (regionalMethodType: RegionalMethodType) => void
 }
@@
-const [regionalMethodType, setRegionalMethodType] = useState<'mercadopago' | 'pix'>('mercadopago')
+const [regionalMethodType, setRegionalMethodType] = useState<RegionalMethodType>('mercadopago')
@@
-setRegionalMethodType('mercadopago')
+setRegionalMethodType('mercadopago')
@@
- regionalMethodType,
- setRegionalMethodType,
+ regionalMethodType,
+ setRegionalMethodType,

Optional: default regionalMethodType could be derived from selectedCountry/geolocation when available.

Also applies to: 68-69, 85-86, 119-121, 139-140

src/context/RequestFulfillmentFlowContext.tsx (2)

37-38: Define and reuse a shared RegionalMethodType

Avoid repeating the string union in multiple places. Create a single exported alias and use it here and in ClaimBankFlowContext to prevent drift.

+export type RegionalMethodType = 'mercadopago' | 'pix'
 ...
-    regionalMethodType: 'mercadopago' | 'pix'
-    setRegionalMethodType: (regionalMethodType: 'mercadopago' | 'pix') => void
+    regionalMethodType: RegionalMethodType
+    setRegionalMethodType: (regionalMethodType: RegionalMethodType) => void
 ...
-    const [regionalMethodType, setRegionalMethodType] = useState<'mercadopago' | 'pix'>('mercadopago')
+    const [regionalMethodType, setRegionalMethodType] = useState<RegionalMethodType>('mercadopago')

Also applies to: 55-55


55-55: Reset default may be wrong for BR users

Hard-resetting to 'mercadopago' can misalign with a BR user’s expected 'pix'. Consider persisting the last selection or deriving a geo default.

Example (persist last choice):

-const [regionalMethodType, setRegionalMethodType] = useState<RegionalMethodType>('mercadopago')
+const [regionalMethodType, setRegionalMethodType] = useState<RegionalMethodType>(() => {
+  if (typeof window === 'undefined') return 'mercadopago'
+  return (localStorage.getItem('regionalMethodType') as RegionalMethodType) || 'mercadopago'
+})
 ...
- setRegionalMethodType('mercadopago')
+ // optional: preserve last selection instead of hard reset
+ // setRegionalMethodType((localStorage.getItem('regionalMethodType') as RegionalMethodType) || 'mercadopago')

And persist on change where you call setRegionalMethodType.

Also applies to: 67-67

src/components/Claim/Link/Initial.view.tsx (1)

634-645: Effect missing deps; potential stale closure on handleClaimLink/removeParamStep

Add missing dependencies to avoid stale references and ensure single-run correctness after URL updates.

-    useEffect(() => {
+    useEffect(() => {
         const stepFromURL = searchParams.get('step')
         if (user && claimLinkData.status !== 'CLAIMED') {
             removeParamStep()
             if (stepFromURL === 'claim' && isPeanutWallet) {
                 handleClaimLink(false, true)
             } else if (stepFromURL === 'regional-claim') {
                 setClaimToMercadoPago(true)
             }
         }
-    }, [user, searchParams, isPeanutWallet])
+    }, [user, isPeanutWallet, searchParams, claimLinkData.status, removeParamStep, handleClaimLink, setClaimToMercadoPago])
src/components/Common/ActionList.tsx (1)

144-155: Geo error fallback: don’t hide regional methods when geo fails

If the geo call errors or returns null, default to showing all methods; otherwise BR/Non‑BR filtering applies.

-import { useGeoLocaion } from '@/hooks/useGeoLocaion'
+import { useGeoLocaion } from '@/hooks/useGeoLocaion'
 ...
-    const { countryCode: userGeoLocationCountryCode, isLoading: isGeoLoading } = useGeoLocaion()
+    const { countryCode: userGeoLocationCountryCode, isLoading: isGeoLoading, error: geoError } = useGeoLocaion()
 ...
-    const geolocatedMethods = useMemo(() => {
-        // show pix in brazil and mercado pago in other countries
-        return ACTION_METHODS.filter((method) => {
+    const geolocatedMethods = useMemo(() => {
+        // If geo unavailable/failed, show all methods
+        if (!userGeoLocationCountryCode || geoError) return ACTION_METHODS
+        // show pix in Brazil and mercado pago elsewhere
+        return ACTION_METHODS.filter((method) => {
             if (userGeoLocationCountryCode === 'BR' && method.id === 'mercadopago') {
                 return false
             }
             if (userGeoLocationCountryCode !== 'BR' && method.id === 'pix') {
                 return false
             }
             return true
         })
-    }, [userGeoLocationCountryCode])
+    }, [userGeoLocationCountryCode, geoError])

Also applies to: 27-29

src/components/Claim/Link/MantecaFlowManager.tsx (2)

118-125: User-facing text: capitalize provider name

Use human-friendly names in the header.

-                    recipientName={isSuccess ? 'You’ll receive' : 'Receive in ' + regionalMethodType}
+                    recipientName={
+                        isSuccess
+                            ? 'You’ll receive'
+                            : `Receive in ${regionalMethodType === 'mercadopago' ? 'Mercado Pago' : 'Pix'}`
+                      }

31-39: Duplicate Argentina fallback object across views

This AR fallback appears here and in MantecaFulfillment; extract to a shared const (e.g., AddMoney/consts) to avoid drift.

Example:

-const argentinaCountryData = { ... } as CountryData
+import { ARGENTINA_COUNTRY } from '@/components/AddMoney/consts'
 ...
- country={selectedCountry || argentinaCountryData}
+ country={selectedCountry || ARGENTINA_COUNTRY}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6ea557 and 3aa4a8d.

📒 Files selected for processing (10)
  • src/components/Claim/Link/Initial.view.tsx (2 hunks)
  • src/components/Claim/Link/MantecaFlowManager.tsx (4 hunks)
  • src/components/Claim/Link/views/MantecaDetailsStep.view.tsx (1 hunks)
  • src/components/Claim/useClaimLink.tsx (1 hunks)
  • src/components/Common/ActionList.tsx (8 hunks)
  • src/components/Payment/PaymentForm/index.tsx (2 hunks)
  • src/components/Payment/Views/MantecaFulfillment.view.tsx (4 hunks)
  • src/constants/actionlist.consts.ts (2 hunks)
  • src/context/ClaimBankFlowContext.tsx (5 hunks)
  • src/context/RequestFulfillmentFlowContext.tsx (5 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-09-05T07:31:11.396Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1185
File: src/components/Claim/useClaimLink.tsx:14-0
Timestamp: 2025-09-05T07:31:11.396Z
Learning: In the peanut-ui codebase, `window.history.replaceState` is preferred over `router.replace` when immediate/synchronous URL parameter updates are required, as `router.replace` is asynchronous and doesn't guarantee instant URL changes that subsequent code can rely on. This pattern is used consistently across usePaymentInitiator.ts, Confirm.payment.view.tsx, and useClaimLink.tsx.

Applied to files:

  • src/components/Claim/Link/Initial.view.tsx
📚 Learning: 2025-08-26T17:38:37.055Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1132
File: src/components/Common/ActionList.tsx:153-156
Timestamp: 2025-08-26T17:38:37.055Z
Learning: In ActionList.tsx, when there are circular dependency concerns with ACTION_METHODS being imported by other components, the preferred solution is to move ACTION_METHODS to a separate constants file (like src/constants/actionlist.consts.ts) rather than using prop drilling. This centralizes constants management and creates a cleaner dependency graph.

Applied to files:

  • src/components/Common/ActionList.tsx
📚 Learning: 2025-09-18T09:30:42.881Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1230
File: src/app/(mobile-ui)/withdraw/page.tsx:92-97
Timestamp: 2025-09-18T09:30:42.881Z
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/Common/ActionList.tsx
📚 Learning: 2025-08-15T08:05:05.417Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1098
File: src/components/LandingPage/noFees.tsx:243-248
Timestamp: 2025-08-15T08:05:05.417Z
Learning: In the peanut-ui project, when displaying country flags from external CDNs like flagcdn.com, the preference is to show country-specific images without fallback handling. The team prioritizes showing accurate country flags over having generic fallback images.

Applied to files:

  • src/components/Payment/Views/MantecaFulfillment.view.tsx
📚 Learning: 2025-07-24T13:26:10.290Z
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#1014
File: src/components/Claim/Link/Initial.view.tsx:413-413
Timestamp: 2025-07-24T13:26:10.290Z
Learning: In the peanut-ui repository, the change from `${SQUID_API_URL}/route` to `${SQUID_API_URL}/v2/route` in src/components/Claim/Link/Initial.view.tsx was a typo fix, not an API migration, as the codebase was already using Squid API v2.

Applied to files:

  • src/components/Claim/useClaimLink.tsx
🧬 Code graph analysis (4)
src/components/Claim/Link/MantecaFlowManager.tsx (5)
src/context/ClaimBankFlowContext.tsx (1)
  • useClaimBankFlow (150-156)
src/components/AddMoney/consts/index.ts (1)
  • CountryData (153-162)
src/hooks/useKycStatus.tsx (1)
  • useKycStatus (12-26)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/components/Kyc/InitiateMantecaKYCModal.tsx (1)
  • InitiateMantecaKYCModal (23-70)
src/components/Payment/PaymentForm/index.tsx (1)
src/context/RequestFulfillmentFlowContext.tsx (1)
  • useRequestFulfillmentFlow (116-122)
src/components/Common/ActionList.tsx (4)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/hooks/useGeoLocaion.ts (1)
  • useGeoLocaion (8-34)
src/constants/actionlist.consts.ts (1)
  • ACTION_METHODS (13-46)
src/app/[...recipient]/loading.tsx (1)
  • Loading (3-5)
src/components/Payment/Views/MantecaFulfillment.view.tsx (7)
src/context/RequestFulfillmentFlowContext.tsx (1)
  • useRequestFulfillmentFlow (116-122)
src/redux/hooks.ts (1)
  • usePaymentStore (12-12)
src/hooks/useKycStatus.tsx (1)
  • useKycStatus (12-26)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/services/manteca.ts (1)
  • mantecaApi (95-232)
src/components/AddMoney/consts/index.ts (1)
  • CountryData (153-162)
src/components/Kyc/InitiateMantecaKYCModal.tsx (1)
  • InitiateMantecaKYCModal (23-70)
🔇 Additional comments (6)
src/components/Payment/PaymentForm/index.tsx (2)

84-90: LGTM on exposing Manteca toggles from context.


655-657: Render guard is correct; ensure upstream resets are in place.

Once fulfillUsingManteca flips true, this early return hides the rest of the form. With the unset fix above, navigation away will restore default flows.

src/constants/actionlist.consts.ts (1)

1-1: PIX export found; confirm re-export and ID alignment

  • Confirmed: src/assets/payment-apps/index.ts exports PIX (export { default as PIX } from './pix.svg').
  • Verify that '@/assets' re-exports PIX (so import { PIX } from '@/assets' resolves) and that the runtime ID used in unions/switches matches the expected value (e.g., 'pix' vs 'PIX').
src/components/Common/ActionList.tsx (1)

97-106: Good gating for regional methods and state plumbing

Setting regionalMethodType before toggling the flow is correct for both claim and request paths.

Also applies to: 127-136, 53-54, 68-69

src/components/Claim/Link/MantecaFlowManager.tsx (1)

46-48: Nice: avoids passing flag URLs as logo and uses countryCodeForFlag

This matches the card API and prevents TS/type issues.

Also applies to: 123-125

src/components/Claim/Link/Initial.view.tsx (1)

634-638: Confirmed: removeParamStep uses window.history.replaceState, not router.replace

removeParamStep (and addParamStep) in src/components/Claim/useClaimLink.tsx call window.history.replaceState — no change required.

Copy link
Contributor

@jjramirezn jjramirezn left a comment

Choose a reason for hiding this comment

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

Please resolve comments before merging

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/Common/ActionList.tsx (1)

168-177: Bug: sortedActionMethods does not update when geolocation resolves.

The memo sorts geolocatedMethods but doesn’t depend on it, so the list can be stale after isGeoLoading flips to false.

Apply this diff:

-    const sortedActionMethods = useMemo(() => {
-        return [...geolocatedMethods].sort((a, b) => {
+    const sortedActionMethods = useMemo(() => {
+        return [...geolocatedMethods].sort((a, b) => {
             const aIsUnavailable = a.soon || (a.id === 'bank' && requiresVerification)
             const bIsUnavailable = b.soon || (b.id === 'bank' && requiresVerification)

             if (aIsUnavailable === bIsUnavailable) {
                 return 0
             }
             return aIsUnavailable ? 1 : -1
         })
-    }, [requiresVerification])
+    }, [requiresVerification, geolocatedMethods])
🧹 Nitpick comments (7)
src/components/Request/views/ExternalWalletFulfilMethods.tsx (2)

26-26: Guard: ensure this view is always under the Request Fulfil(l)ment provider

useRequestFulfillmentFlow throws if no provider; confirm routing never mounts this outside the provider. Also, naming is inconsistent across the codebase (Fulfil vs Fulfill/Fulfillment). Consider standardizing to one spelling to avoid import mistakes and search friction.


38-38: Avoid unsafe type assertion; make methods.id strongly typed

Casting method.id to ExternalWalletFulfilMethod hides drift. Type the methods array so id is already the correct union, then drop the cast.

Apply this local change:

-                            setExternalWalletFulfillMethod(method.id as ExternalWalletFulfilMethod)
+                            setExternalWalletFulfillMethod(method.id)

And adjust the methods declaration to enforce id typing (no behavioral change):

// Replace the current `methods: PaymentMethod[]` with:
const methods = [
  {
    id: 'exchange',
    title: 'Exchange',
    description: 'Lemon, Binance, Ripio and more',
    icons: [RIPIO_LOGO, BINANCE_LOGO, LEMON_LOGO],
    soon: false,
  },
  {
    id: 'wallet',
    title: 'Crypto Wallet',
    description: 'Metamask, Trustwallet and more',
    icons: [RAINBOW_LOGO, TRUST_WALLET_SMALL_LOGO, METAMASK_LOGO],
    soon: false,
  },
] as const satisfies ReadonlyArray<PaymentMethod & { id: ExternalWalletFulfilMethod }>

This keeps PaymentMethod shape while narrowing id to 'exchange' | 'wallet'.

src/components/Payment/PaymentForm/index.tsx (1)

554-561: Add setter to deps to satisfy exhaustive-deps and avoid stale closure.

Include setFulfillUsingManteca in the dependency array.

-    }, [user, searchParams])
+    }, [user, searchParams, setFulfillUsingManteca])
src/components/Common/ActionList.tsx (2)

27-30: Rename hook to useGeoLocation for consistency and future grepability.

Typo in hook/file name (“useGeoLocaion”). Recommend renaming export and file to useGeoLocation and updating imports.


98-106: Unify regional flow toggles; avoid MercadoPago‑specific flag for PIX.

You set setRegionalMethodType('pix'|'mercadopago') but still toggle setClaimToMercadoPago(true) for both. This is confusing and risks method‑specific branching elsewhere.

Consider a neutral flag (e.g., setClaimToRegional(true)) or branch on method.id when setting the legacy toggle.

Also applies to: 128-136

src/context/RequestFulfillmentFlowContext.tsx (2)

8-8: Rename type alias to match “Fulfill” convention.

Keep types consistent with public fields.

-export type ExternalWalletFulfilMethod = 'exchange' | 'wallet'
+export type ExternalWalletFulfillMethod = 'exchange' | 'wallet'

Follow through by updating usages in this file and imports in consumers.


116-121: Minor: align error message/provider name spelling.

Function uses “Fulfillment” while message mentions “Fulfilment”. Consider unifying spelling repo‑wide for clarity.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 651ab67 and 1c55ac6.

📒 Files selected for processing (6)
  • src/app/[...recipient]/client.tsx (3 hunks)
  • src/components/Common/ActionList.tsx (7 hunks)
  • src/components/Payment/PaymentForm/index.tsx (3 hunks)
  • src/components/Request/views/ExternalWalletFulfilManager.tsx (2 hunks)
  • src/components/Request/views/ExternalWalletFulfilMethods.tsx (2 hunks)
  • src/context/RequestFulfillmentFlowContext.tsx (4 hunks)
🔥 Files not summarized due to errors (1)
  • src/components/Request/views/ExternalWalletFulfilMethods.tsx: Error: Server error: no LLM provider could handle the message
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#1190
File: src/app/(mobile-ui)/qr-pay/page.tsx:156-176
Timestamp: 2025-09-08T03:13:09.111Z
Learning: In the peanut-ui mobile app, the `/qr-pay` route is only accessed through the DirectSendQR component which always includes the qrCode parameter in the URL when redirecting users to the QR pay page after scanning MERCADO_PAGO or PIX QR codes.
📚 Learning: 2025-09-18T09:30:42.881Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1230
File: src/app/(mobile-ui)/withdraw/page.tsx:92-97
Timestamp: 2025-09-18T09:30:42.881Z
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/[...recipient]/client.tsx
  • src/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-08-26T17:38:37.055Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1132
File: src/components/Common/ActionList.tsx:153-156
Timestamp: 2025-08-26T17:38:37.055Z
Learning: In ActionList.tsx, when there are circular dependency concerns with ACTION_METHODS being imported by other components, the preferred solution is to move ACTION_METHODS to a separate constants file (like src/constants/actionlist.consts.ts) rather than using prop drilling. This centralizes constants management and creates a cleaner dependency graph.

Applied to files:

  • src/components/Common/ActionList.tsx
📚 Learning: 2025-09-05T07:31:11.396Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1185
File: src/components/Claim/useClaimLink.tsx:14-0
Timestamp: 2025-09-05T07:31:11.396Z
Learning: In the peanut-ui codebase, `window.history.replaceState` is preferred over `router.replace` when immediate/synchronous URL parameter updates are required, as `router.replace` is asynchronous and doesn't guarantee instant URL changes that subsequent code can rely on. This pattern is used consistently across usePaymentInitiator.ts, Confirm.payment.view.tsx, and useClaimLink.tsx.

Applied to files:

  • src/components/Payment/PaymentForm/index.tsx
🧬 Code graph analysis (4)
src/components/Request/views/ExternalWalletFulfilManager.tsx (3)
src/context/RequestFulfillmentFlowContext.tsx (1)
  • useRequestFulfillmentFlow (116-122)
src/redux/hooks.ts (1)
  • usePaymentStore (12-12)
src/components/Request/views/ExternalWalletFulfilMethods.tsx (1)
  • ExternalWalletFulfilMethods (25-45)
src/components/Request/views/ExternalWalletFulfilMethods.tsx (1)
src/context/RequestFulfillmentFlowContext.tsx (2)
  • useRequestFulfillmentFlow (116-122)
  • ExternalWalletFulfilMethod (8-8)
src/components/Common/ActionList.tsx (4)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/hooks/useGeoLocaion.ts (1)
  • useGeoLocaion (8-34)
src/constants/actionlist.consts.ts (1)
  • ACTION_METHODS (13-46)
src/app/[...recipient]/loading.tsx (1)
  • Loading (3-5)
src/components/Payment/PaymentForm/index.tsx (1)
src/context/RequestFulfillmentFlowContext.tsx (1)
  • useRequestFulfillmentFlow (116-122)
🔇 Additional comments (11)
src/app/[...recipient]/client.tsx (2)

67-73: Rename alignment looks good.

Using showExternalWalletFulfillMethods consistently matches the updated context API.


435-437: External wallet path render guard is correct.

Renders ExternalWalletFulfilManager only when showExternalWalletFulfillMethods is true.

src/components/Payment/PaymentForm/index.tsx (2)

84-90: Context API rename consumption looks correct.

Destructuring matches provider exports, including setFulfillUsingManteca.


645-649: Back action for external-wallet flow is correct.

Resets method state and returns to the selection list.

src/components/Common/ActionList.tsx (2)

144-156: Geo filtering logic OK; confirm fallback when geolocation fails.

When countryCode is null, PIX is hidden globally and Mercado Pago is shown. If that’s intentional, ignore; otherwise, default to showing both when geo is unknown.


179-185: Loading state handling for geolocation is correct.

Prevents flicker by gating on isGeoLoading.

src/components/Request/views/ExternalWalletFulfilManager.tsx (3)

12-16: Rename adoption LGTM.

All context fields now use “Fulfill” spelling and align with provider.


49-60: Back flow resets are correct.

Clearing method then showing list avoids stale state when switching paths.


62-64: Method list toggle works as expected.

Guarding and onBack wiring look correct.

src/context/RequestFulfillmentFlowContext.tsx (2)

19-25: Public API changes LGTM.

showExternalWalletFulfillMethods/externalWalletFulfillMethod and regionalMethodType additions are coherent.

Also applies to: 37-39


44-46: State wiring and resetFlow updates look correct.

Initial values and resets (including regionalMethodType) are sane.

Also applies to: 55-55, 57-69

@Zishan-7 Zishan-7 merged commit 830e2cf into feat/manteca-integration Sep 19, 2025
4 checks passed
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.

2 participants