-
Notifications
You must be signed in to change notification settings - Fork 13
[TASK-14805] Feat/kyc integration links #1229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TASK-14805] Feat/kyc integration links #1229
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds 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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
There was a problem hiding this 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 benull
(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 nameWhen a
logo
is provided, thealt
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 conditionThe 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 dataSame Argentina constant exists in other files. Extract to a shared constants file.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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
totrue
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 handlenull
.ClaimBankFlowContext declares
flowStep: ClaimBankFlowStep | null
(initialnull
) andresetFlow
/ other callers usesetFlowStep(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. ForREGIONAL_METHOD_CLAIM
, the card won’t prefix ARS/BRL. Is that intentional?
170-172
: No action required — flagcdn.com already allowed via images.remotePatternsnext.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 flowCancelling closes the modal and navigates back. Looks correct.
123-124
: Lowercasing country code is safe hereUsing optional chaining before
toLowerCase()
avoids runtime errors. LGTM.src/components/Payment/Views/MantecaFulfillment.view.tsx (1)
36-37
: KYC-gated query enablement looks correctQuery is disabled until
chargeDetails?.uuid
exists and KYC is approved. Good.
There was a problem hiding this 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 changesgeolocatedMethods 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 stringPass 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 RegionalMethodTypeAvoid 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 usersHard-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/removeParamStepAdd 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 failsIf 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 nameUse 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 viewsThis 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
📒 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 plumbingSetting 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 countryCodeForFlagThis 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.replaceremoveParamStep (and addParamStep) in src/components/Claim/useClaimLink.tsx call window.history.replaceState — no change required.
There was a problem hiding this 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
There was a problem hiding this 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 provideruseRequestFulfillmentFlow 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 typedCasting 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
📒 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
No description provided.