Skip to content

Conversation

jjramirezn
Copy link
Contributor

No description provided.

Copy link

Copy link

vercel bot commented Sep 24, 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 26, 2025 4:30pm

Copy link
Contributor

coderabbitai bot commented Sep 24, 2025

Walkthrough

Ties Manteca withdraw destinationAddress to the destination URL param, centralizes/expands ISO3→ISO2 mappings (adds ARG/BOL/BRA), adds MANTECA account type, updates Add/Withdraw routing to save recent methods and handle MANTECA in bank-account flows, and replaces country-code lookups across UI and withdraw utils to use the new maps.

Changes

Cohort / File(s) Summary
Manteca withdraw page
src/app/(mobile-ui)/withdraw/manteca/page.tsx
Initialize and reset destinationAddress from destination search param via useSearchParams; remove redundant hook so address persists from URL.
Country mapping constants
src/components/AddMoney/consts/index.ts
Introduce/export BRIDGE_ALPHA3_TO_ALPHA2 (renamed), add MANTECA_ALPHA3_TO_ALPHA2 (ARG→AR, BOL→BO, BRA→BR), and export merged ALL_COUNTRIES_ALPHA3_TO_ALPHA2; update enabled bank-transfer sets to use new maps.
Flag / country lookups (UI & utils)
src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx, src/components/AddMoney/components/AddMoneyBankDetails.tsx, src/components/AddMoney/components/DepositMethodList.tsx, src/components/AddWithdraw/DynamicBankAccountForm.tsx, src/components/Claim/Link/views/Confirm.bank-claim.view.tsx, src/components/Common/SavedAccountsView.tsx, src/components/Common/CountryList.tsx, src/utils/withdraw.utils.ts
Replace prior countryCodeMap usage with BRIDGE_ALPHA3_TO_ALPHA2 and/or ALL_COUNTRIES_ALPHA3_TO_ALPHA2 for deriving alpha-2 codes, flag lookups, and withdraw country-code conversions; adjust IBAN-country checks to use BRIDGE_ALPHA3_TO_ALPHA2.
Add/Withdraw routing & recent methods
src/components/AddWithdraw/AddWithdrawRouterView.tsx
Add saveRecentMethod helper and use it when adding methods or selecting countries; include MANTECA in bank-account filtering and saved-account routing; normalize recent-method types and set method in context before navigation for withdraw flows.
Account type enum
src/interfaces/interfaces.ts
Add MANTECA = 'manteca' to AccountType enum.
KYC / profile tweaks
src/components/Kyc/KycStatusDrawer.tsx, src/components/Profile/views/IdentityVerification.view.tsx
Pass additional verification timestamps into KYC components; refactor redirect/KYC success handling and inline some flow logic for identity verification.
Minor imports/flag updates
src/components/Claim/Link/views/Confirm.bank-claim.view.tsx, src/components/AddMoney/components/AddMoneyBankDetails.tsx (also listed above)
Update imports/usages to new country mapping constants for flag derivation; preserve fallback behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Zishan-7
  • kushagrasarathe

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ❓ Inconclusive The pull request description is empty and does not provide any context or summary for the changes introduced, making it difficult for reviewers to understand the scope and intent of these updates. Please add a brief description outlining the key changes, objectives, and any relevant background so that reviewers can quickly grasp the purpose and impact of this pull request.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly identifies the implemented feature of persisting Manteca methods and follows the conventional commit style, providing a concise and specific summary of the primary change in this pull request.
✨ 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/remember-manteca-methods

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e3a0b5 and 0024f54.

📒 Files selected for processing (5)
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx (2 hunks)
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx (2 hunks)
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx (3 hunks)
  • src/components/Common/CountryList.tsx (3 hunks)
  • src/components/Common/SavedAccountsView.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/Common/SavedAccountsView.tsx
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
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.
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".
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".
📚 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/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/Common/CountryList.tsx
📚 Learning: 2025-08-13T18:22:01.941Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#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/components/AddWithdraw/DynamicBankAccountForm.tsx
📚 Learning: 2025-08-14T14:36:18.758Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1094
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:0-0
Timestamp: 2025-08-14T14:36:18.758Z
Learning: Bridge API requires ISO3 country codes (3-letter codes like "USA", "GBR") while flag display components need ISO2 codes (2-letter codes like "US", "GB").

Applied to files:

  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/Common/CountryList.tsx
📚 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 the peanut-ui codebase uses uppercase country codes only, so any functions that look up values in this map should normalize input to uppercase for consistent matching.

Applied to files:

  • src/components/AddWithdraw/DynamicBankAccountForm.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/Common/CountryList.tsx
🧬 Code graph analysis (2)
src/components/AddWithdraw/DynamicBankAccountForm.tsx (1)
src/components/AddMoney/consts/index.ts (2)
  • BRIDGE_ALPHA3_TO_ALPHA2 (2487-2529)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/components/Common/CountryList.tsx (2)
src/components/AddMoney/consts/index.ts (2)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
  • BRIDGE_ALPHA3_TO_ALPHA2 (2487-2529)
src/components/Global/Card/index.tsx (1)
  • getCardPosition (14-19)
🔇 Additional comments (4)
src/components/Common/CountryList.tsx (1)

117-118: Broken flags for Manteca-only countries — use country.iso2 fallback

Several of the new Manteca countries ship only their ISO3 code in the merged map. When the lookup misses, falling back to country.id.toLowerCase() produces an invalid flag CDN URL (e.g. deu.png). Use the provided country.iso2 (already normalized in the dataset) before defaulting to country.id.

-                            const twoLetterCountryCode =
-                                ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.id.toUpperCase()] ?? country.id.toLowerCase()
+                            const iso3 = country.id.toUpperCase()
+                            const twoLetterCountryCode =
+                                ALL_COUNTRIES_ALPHA3_TO_ALPHA2[iso3] ?? country.iso2 ?? iso3

Based on learnings

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

8-8: Updated mapping imports look solid

Pulling in both the Bridge-specific and merged alpha3→alpha2 dictionaries lines up with the shared constants refactor—no issues here.


22-24: Nice job preserving uppercase normalization

Keeping the .toUpperCase() lookup against BRIDGE_ALPHA3_TO_ALPHA2 maintains compatibility with the uppercase ISO3 keys in our map—exactly what we need for IBAN detection. Based on learnings.


268-270: All-countries lookup covers the new Manteca flows

Using the merged ALL_COUNTRIES_ALPHA3_TO_ALPHA2 map ensures we derive the correct ISO2 flag codes for both Bridge and Manteca countries without regressions. Based on learnings.


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.

@coderabbitai coderabbitai bot added the enhancement New feature or request label Sep 24, 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

Caution

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

⚠️ Outside diff range comments (3)
src/components/AddWithdraw/AddWithdrawRouterView.tsx (2)

126-136: Incorrect country detection for withdraw method routing.

isMantecaCountry expects a country identifier (e.g., 'argentina'), but here we pass method.path. For Manteca options the path is /withdraw/manteca?..., so the predicate always returns false. That means we mark Manteca methods as 'bridge', breaking the new context-driven withdraw flow (and saved-account routing) you just added.

Fix by passing the country slug instead of the full path, e.g.:

-            const methodType =
-                method.type === 'crypto' ? 'crypto' : isMantecaCountry(method.path) ? 'manteca' : 'bridge'
+            const methodCountry = method.path?.split('/')[2] ?? method.path
+            const methodType =
+                method.type === 'crypto'
+                    ? 'crypto'
+                    : methodCountry && isMantecaCountry(methodCountry)
+                      ? 'manteca'
+                      : 'bridge'

185-197: MANTECA saved accounts route uses country name instead of slug.

When routing a saved Manteca account you feed country=${account.details.countryName}. Elsewhere (isMantecaCountry, MANTECA_COUNTRIES_CONFIG) we key off slugs (e.g., argentina). Passing the human-readable name (with spaces/uppercase) breaks lookups and drops users on a partially initialized screen.

Derive the slug (you already store countryCode/countryName—if the slug isn’t present, map from ISO2 via countryData). Example fix:

-                            router.push(
-                                `/withdraw/manteca?country=${account.details.countryName}&destination=${account.identifier}`
-                            )
+                            const country = countryData.find((c) => c.iso2 === account.details.countryCode)
+                            const countrySlug = country?.path ?? account.details.countryCode.toLowerCase()
+                            router.push(
+                                `/withdraw/manteca?country=${countrySlug}&destination=${account.identifier}`
+                            )
src/app/(mobile-ui)/withdraw/manteca/page.tsx (1)

222-236: Destination reset now desynchronizes with updated query params.

resetState() reuses the original paramAddress. If users change the destination (e.g., via Saved Accounts) and retry, the state snaps back to the first value rather than the current URL parameter. Either read the latest searchParams inside resetState or derive from state so the UI stays consistent.

Consider recomputing from useSearchParams() on reset:

-        setDestinationAddress(paramAddress ?? '')
+        const freshDestination = searchParams?.get('destination') ?? ''
+        setDestinationAddress(freshDestination)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8304f63 and 42cb40c.

📒 Files selected for processing (4)
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx (2 hunks)
  • src/components/AddMoney/consts/index.ts (1 hunks)
  • src/components/AddWithdraw/AddWithdrawRouterView.tsx (5 hunks)
  • src/interfaces/interfaces.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-09-18T09:30:42.901Z
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.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/manteca/page.tsx
  • src/components/AddWithdraw/AddWithdrawRouterView.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/app/(mobile-ui)/withdraw/manteca/page.tsx
  • src/components/AddWithdraw/AddWithdrawRouterView.tsx
📚 Learning: 2024-10-22T18:11:36.864Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#469
File: src/app/request/pay/page.tsx:32-49
Timestamp: 2024-10-22T18:11:36.864Z
Learning: In `src/app/request/pay/page.tsx`, the `id` parameter is accessed via `searchParams.id` in the `generateMetadata` function.

Applied to files:

  • src/app/(mobile-ui)/withdraw/manteca/page.tsx
📚 Learning: 2024-10-23T09:38:04.446Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#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)/withdraw/manteca/page.tsx
📚 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/AddMoney/consts/index.ts
🧬 Code graph analysis (1)
src/components/AddWithdraw/AddWithdrawRouterView.tsx (2)
src/components/AddMoney/components/DepositMethodList.tsx (1)
  • DepositMethod (9-17)
src/utils/general.utils.ts (3)
  • RecentMethod (773-781)
  • getUserPreferences (819-831)
  • updateUserPreferences (801-817)
🔇 Additional comments (3)
src/interfaces/interfaces.ts (1)

266-273: New account type looks correct.

Adding AccountType.MANTECA cleanly extends the enum for Manteca-specific flows. No issues spotted.

src/components/AddMoney/consts/index.ts (1)

2488-2532: Confirm downstream handling of new ISO2 codes.

The additional countryCodeMap entries for ARG/BOL/BRA look good, but double-check any consumers that compare the mapped ISO2 codes (e.g., hard-coded allowlists) so they don’t inadvertently exclude the new values being pulled into enabledBankWithdrawCountries/enabledBankDepositCountries.

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

45-48: Guard against missing query params in SSR environments.

useSearchParams() returns null during prerender/SSR. Accessing searchParams.get(...) without a null check throws, breaking the page for initial loads. Wrap in a guard so you only read params when the hook returns a value.

Example:

-    const searchParams = useSearchParams()
-    const paramAddress = searchParams.get('destination')
+    const searchParams = useSearchParams()
+    const paramAddress = searchParams?.get('destination') ?? null

Likely an incorrect or invalid review comment.

Copy link
Contributor

@kushagrasarathe kushagrasarathe left a comment

Choose a reason for hiding this comment

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

approving the pr for fast tracking, but left a concerning comment, lmk when responded

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

Caution

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

⚠️ Outside diff range comments (4)
src/components/AddWithdraw/DynamicBankAccountForm.tsx (1)

68-70: Critical: Mexico check uses ISO2 ("MX") instead of ISO3 ("MEX")

This misclassifies MEX as non-CLABE and can throw "Unsupported country" or render wrong form fields. Fix both occurrences.

Apply this diff:

-        const isMx = country.toUpperCase() === 'MX'
+        const isMx = country.toUpperCase() === 'MEX'

And inside onSubmit:

-                const isUs = country.toUpperCase() === 'USA'
-                const isMx = country.toUpperCase() === 'MX'
+                const isUs = country.toUpperCase() === 'USA'
+                const isMx = country.toUpperCase() === 'MEX'

Also applies to: 163-166

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

76-89: Fix countryInfo lookup for 3-letter codes (e.g., USA) and title-based names

If details.countryCode is a 3-letter code like USA/DEU, the current lookup by id === threeLetterCountryCode will fail since countryData ids are mostly ISO2 or mixed. Prefer resolving to ISO2 first, then fallback to title match.

-                const threeLetterCountryCode = (details.countryCode ?? '').toUpperCase()
-                const twoLetterCountryCode =
-                    ALL_COUNTRIES_ALPHA3_TO_ALPHA2[threeLetterCountryCode] ?? threeLetterCountryCode
+                const threeLetterCountryCode = (details.countryCode ?? '').toUpperCase()
+                const twoLetterCountryCode =
+                    ALL_COUNTRIES_ALPHA3_TO_ALPHA2[threeLetterCountryCode] ?? threeLetterCountryCode
@@
-                let countryInfo
-                if (account.type === AccountType.US) {
-                    countryInfo = ALL_METHODS_DATA.find((c) => c.id === 'US')
-                } else {
-                    countryInfo = details.countryName
-                        ? ALL_METHODS_DATA.find((c) => c.path.toLowerCase() === details.countryName?.toLowerCase())
-                        : ALL_METHODS_DATA.find((c) => c.id === threeLetterCountryCode)
-                }
+                let countryInfo
+                if (account.type === AccountType.US) {
+                    countryInfo = ALL_METHODS_DATA.find((c) => c.id === 'US')
+                } else {
+                    const idForLookup = twoLetterCountryCode && twoLetterCountryCode.length === 2
+                        ? twoLetterCountryCode
+                        : threeLetterCountryCode
+                    countryInfo =
+                        ALL_METHODS_DATA.find((c) => c.id === idForLookup) ??
+                        (details.countryName
+                            ? ALL_METHODS_DATA.find((c) => c.title.toLowerCase() === details.countryName.toLowerCase())
+                            : undefined)
+                }
src/components/AddMoney/consts/index.ts (1)

2601-2613: Bug: SEPA Instant for EUR countries never added

The guard checks countrySpecificWithdrawMethods['Germany'], which is undefined in this file, so SEPA is never pushed. Drop the guard.

-        // 2. add SEPA for EUR countries if not already present from specifics
-        if (country.currency === 'EUR' && countrySpecificWithdrawMethods['Germany']) {
+        // 2. add SEPA for EUR countries if not already present from specifics
+        if (country.currency === 'EUR') {
             // Germany as proxy for SEPA availability
             const sepaExists = withdrawList.some((m) => m.title === 'SEPA Instant')
             if (!sepaExists) {
                 withdrawList.push({
                     id: `${countryCode.toLowerCase()}-sepa-instant-withdraw`,
                     icon: 'bank' as IconName,
                     title: 'SEPA Instant',
                     description: 'EU-wide real-time bank transfers.',
                     isSoon: false,
                 })
             }
         }
src/components/Profile/views/IdentityVerification.view.tsx (1)

122-137: Fix stale closure: include isUserBridgeKycApproved in deps

isVerifiedForCountry uses isUserBridgeKycApproved and user but only depends on user. Add missing deps to avoid incorrect “already verified” badges after status updates.

-        [user]
+        [user, isUserBridgeKycApproved]
🧹 Nitpick comments (9)
src/components/AddWithdraw/DynamicBankAccountForm.tsx (1)

150-161: Harden duplicate-account check to avoid undefined derefs

Calling toLowerCase() on possibly undefined fields can throw when defaults are overridden. Compute a safe identifier per account type.

Apply this diff:

-                const existingAccount = savedAccounts.find(
-                    (account) => account.identifier === (data.accountNumber.toLowerCase() || data.clabe.toLowerCase())
-                )
+                const candidateId = (data.clabe ?? data.accountNumber ?? data.iban ?? '')
+                    .toString()
+                    .trim()
+                    .toLowerCase()
+                const existingAccount = savedAccounts.find((account) => account.identifier?.toLowerCase() === candidateId)
src/components/AddMoney/components/DepositMethodList.tsx (1)

56-60: Normalize once; avoid redundant toLowerCase for flag URL

Minor cleanup: compute lowercase once and use it directly.

Apply this diff:

-                const threeLetterCountryCode = (method.id ?? '').toUpperCase()
-                const twoLetterCountryCode =
-                    ALL_COUNTRIES_ALPHA3_TO_ALPHA2[threeLetterCountryCode] ?? threeLetterCountryCode
-
-                const countryCodeForFlag = twoLetterCountryCode.toLowerCase() ?? ''
+                const threeLetterCountryCode = (method.id ?? '').toUpperCase()
+                const twoLetterCountryCode =
+                    ALL_COUNTRIES_ALPHA3_TO_ALPHA2[threeLetterCountryCode] ?? threeLetterCountryCode
+                const countryCodeForFlag = (twoLetterCountryCode || '').toLowerCase()

And at Image src (Line 79):

-                                    src={`https://flagcdn.com/w160/${countryCodeForFlag.toLowerCase()}.png`}
+                                    src={`https://flagcdn.com/w160/${countryCodeForFlag}.png`}
src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx (1)

184-189: Normalize country code before lookup to ensure correct flag

If details.countryCode comes in lowercase, the lookup will fail and may render a non-ISO2 code to the flag CDN (e.g., "gbr"). Uppercase before lookup, then lowercase for the URL.

Apply this diff:

-    const countryCodeForFlag = () => {
-        if (!bankAccount?.details?.countryCode) return ''
-        const code =
-            ALL_COUNTRIES_ALPHA3_TO_ALPHA2[bankAccount.details.countryCode ?? ''] ?? bankAccount.details.countryCode
-        return code.toLowerCase()
-    }
+    const countryCodeForFlag = () => {
+        const raw = bankAccount?.details?.countryCode ?? ''
+        if (!raw) return ''
+        const alpha3 = raw.toUpperCase()
+        const code = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[alpha3] ?? alpha3
+        return code.toLowerCase()
+    }

Based on learnings

src/components/AddMoney/components/AddMoneyBankDetails.tsx (1)

94-98: Normalize lookup key to uppercase to avoid misses

ALL_COUNTRIES_ALPHA3_TO_ALPHA2 uses uppercase keys. Uppercase countryId before indexing to prevent edge-case misses (e.g., if an id ever comes in lowercase). Based on learnings.

-        const countryId = currentCountryDetails?.id || 'USA'
-        const countryCode = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[countryId] || countryId
+        const countryId = currentCountryDetails?.id || 'USA'
+        const countryCode = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[countryId.toUpperCase()] || countryId
src/components/Common/CountryList.tsx (2)

62-67: Normalize to ISO2 uppercase for stable geo prioritization

Ensure both sides are normalized; otherwise, lowercase or mixed-case inputs can fail to prioritize the user’s country. Based on learnings.

-                const aIsUserCountry =
-                    ALL_COUNTRIES_ALPHA3_TO_ALPHA2[a.id] === userGeoLocationCountryCode ||
-                    a.id === userGeoLocationCountryCode
-                const bIsUserCountry =
-                    ALL_COUNTRIES_ALPHA3_TO_ALPHA2[b.id] === userGeoLocationCountryCode ||
-                    b.id === userGeoLocationCountryCode
+                const geo = userGeoLocationCountryCode?.toUpperCase()
+                const aAlpha2 = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[a.id.toUpperCase()] ?? a.id.toUpperCase()
+                const bAlpha2 = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[b.id.toUpperCase()] ?? b.id.toUpperCase()
+                const aIsUserCountry = !!geo && aAlpha2 === geo
+                const bIsUserCountry = !!geo && bAlpha2 === geo

128-130: Bridge support check: precompute a Set for O(1) lookups (optional)

Slight perf/readability improvement by using a Set rather than includes on a growing array.

src/components/AddMoney/consts/index.ts (1)

2542-2557: Uppercase inputs in enablement checks

Harden isCountryEnabledForBankTransfer against mixed-case inputs by uppercasing before map lookup. Based on learnings.

 const isCountryEnabledForBankTransfer = (countryCode: string, direction: 'withdraw' | 'deposit'): boolean => {
-    // Direct check for 2-letter codes
-    const enabledCountries = direction === 'withdraw' ? enabledBankWithdrawCountries : enabledBankDepositCountries
-    if (enabledCountries.has(countryCode)) {
+    const enabledCountries = direction === 'withdraw' ? enabledBankWithdrawCountries : enabledBankDepositCountries
+    const upper = countryCode.toUpperCase()
+    // Direct check for 2-letter codes
+    if (enabledCountries.has(upper)) {
         return true
     }
 
     // Check if it's a 3-letter code that maps to an enabled 2-letter code
-    const mappedCode = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[countryCode]
+    const mappedCode = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[upper]
     return mappedCode ? enabledCountries.has(mappedCode) : false
 }
src/components/Profile/views/IdentityVerification.view.tsx (2)

98-105: Add handleRedirect to dependencies

handleBack closes over handleRedirect; include it to avoid stale routing behavior.

-    }, [showUserDetailsForm])
+    }, [showUserDetailsForm, handleRedirect])

71-96: Complete dependency list for handleUserDetailsSubmit

Include fetchUser and handleInitiateKyc in deps to avoid stale references if hook rebinds them.

-        [user]
+        [user, fetchUser, handleInitiateKyc]
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42cb40c and 2e3a0b5.

📒 Files selected for processing (11)
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx (2 hunks)
  • src/components/AddMoney/components/AddMoneyBankDetails.tsx (2 hunks)
  • src/components/AddMoney/components/DepositMethodList.tsx (2 hunks)
  • src/components/AddMoney/consts/index.ts (3 hunks)
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx (3 hunks)
  • src/components/Claim/Link/views/Confirm.bank-claim.view.tsx (2 hunks)
  • src/components/Common/CountryList.tsx (3 hunks)
  • src/components/Common/SavedAccountsView.tsx (2 hunks)
  • src/components/Kyc/KycStatusDrawer.tsx (2 hunks)
  • src/components/Profile/views/IdentityVerification.view.tsx (5 hunks)
  • src/utils/withdraw.utils.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (9)
📚 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/Common/CountryList.tsx
  • src/components/AddMoney/components/DepositMethodList.tsx
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/utils/withdraw.utils.ts
  • src/components/Common/SavedAccountsView.tsx
  • src/components/Claim/Link/views/Confirm.bank-claim.view.tsx
  • src/components/AddMoney/consts/index.ts
  • src/components/Profile/views/IdentityVerification.view.tsx
📚 Learning: 2025-08-14T14:36:18.758Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1094
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:0-0
Timestamp: 2025-08-14T14:36:18.758Z
Learning: Bridge API requires ISO3 country codes (3-letter codes like "USA", "GBR") while flag display components need ISO2 codes (2-letter codes like "US", "GB").

Applied to files:

  • src/components/Common/CountryList.tsx
  • src/components/AddMoney/components/DepositMethodList.tsx
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/components/Common/SavedAccountsView.tsx
  • src/components/AddMoney/consts/index.ts
📚 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/Common/CountryList.tsx
  • src/components/AddMoney/components/DepositMethodList.tsx
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/utils/withdraw.utils.ts
  • src/components/Common/SavedAccountsView.tsx
  • src/components/Claim/Link/views/Confirm.bank-claim.view.tsx
📚 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 the peanut-ui codebase uses uppercase country codes only, so any functions that look up values in this map should normalize input to uppercase for consistent matching.

Applied to files:

  • src/components/AddMoney/components/DepositMethodList.tsx
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx
  • src/components/AddMoney/components/AddMoneyBankDetails.tsx
  • src/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/utils/withdraw.utils.ts
  • src/components/Common/SavedAccountsView.tsx
📚 Learning: 2025-09-18T09:30:42.901Z
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.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
📚 Learning: 2025-08-13T18:22:01.941Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#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/components/AddWithdraw/DynamicBankAccountForm.tsx
  • src/utils/withdraw.utils.ts
  • src/components/Common/SavedAccountsView.tsx
📚 Learning: 2025-09-03T12:23:31.845Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1173
File: src/components/Common/SavedAccountsView.tsx:86-87
Timestamp: 2025-09-03T12:23:31.845Z
Learning: In the CountryData interface from src/components/AddMoney/consts, the path field is required (not optional) for all country entries.

Applied to files:

  • src/components/Common/SavedAccountsView.tsx
📚 Learning: 2025-09-03T12:23:31.845Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1173
File: src/components/Common/SavedAccountsView.tsx:86-87
Timestamp: 2025-09-03T12:23:31.845Z
Learning: In the ALL_METHODS_DATA structure from src/components/AddMoney/consts, the path field is required (not optional) for all country entries.

Applied to files:

  • src/components/Common/SavedAccountsView.tsx
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#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/Profile/views/IdentityVerification.view.tsx
🧬 Code graph analysis (9)
src/components/Common/CountryList.tsx (2)
src/components/AddMoney/consts/index.ts (2)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
  • BRIDGE_ALPHA3_TO_ALPHA2 (2487-2529)
src/components/Global/Card/index.tsx (1)
  • getCardPosition (14-19)
src/components/AddMoney/components/DepositMethodList.tsx (1)
src/components/AddMoney/consts/index.ts (1)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx (1)
src/components/AddMoney/consts/index.ts (1)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/components/AddMoney/components/AddMoneyBankDetails.tsx (1)
src/components/AddMoney/consts/index.ts (1)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/components/AddWithdraw/DynamicBankAccountForm.tsx (1)
src/components/AddMoney/consts/index.ts (2)
  • BRIDGE_ALPHA3_TO_ALPHA2 (2487-2529)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/utils/withdraw.utils.ts (1)
src/components/AddMoney/consts/index.ts (1)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/components/Common/SavedAccountsView.tsx (1)
src/components/AddMoney/consts/index.ts (1)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/components/Claim/Link/views/Confirm.bank-claim.view.tsx (1)
src/components/AddMoney/consts/index.ts (1)
  • ALL_COUNTRIES_ALPHA3_TO_ALPHA2 (2537-2540)
src/components/Profile/views/IdentityVerification.view.tsx (8)
src/hooks/useKycStatus.tsx (1)
  • useKycStatus (12-26)
src/context/authContext.tsx (1)
  • useAuth (182-188)
src/utils/general.utils.ts (2)
  • getRedirectUrl (1201-1203)
  • clearRedirectUrl (1205-1209)
src/hooks/useBridgeKycFlow.ts (1)
  • useBridgeKycFlow (30-180)
src/components/AddMoney/UserDetailsForm.tsx (2)
  • UserDetailsFormData (7-10)
  • UserDetailsForm (19-110)
src/app/actions/users.ts (1)
  • updateUserById (12-35)
src/components/AddMoney/consts/index.ts (2)
  • BRIDGE_ALPHA3_TO_ALPHA2 (2487-2529)
  • MantecaSupportedExchanges (8-19)
src/components/Common/CountryList.tsx (1)
  • CountryList (40-199)
🔇 Additional comments (17)
src/components/Kyc/KycStatusDrawer.tsx (2)

123-126: Good call using verification timestamps for processing state.

Wiring verification?.createdAt through here lets the Manteca flow display an accurate “started” value while still falling back to the stored Bridge timestamp. Nicely handles both providers.


139-145: Accurate failure timestamp source.

Using verification?.updatedAt ensures we surface the latest rejection time coming from Manteca while keeping the Bridge fallback intact. Looks great.

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

8-8: LGTM: using unified country maps

Importing BRIDGE_ALPHA3_TO_ALPHA2 and ALL_COUNTRIES_ALPHA3_TO_ALPHA2 aligns this component with the new centralized mappings.


22-24: LGTM: IBAN-country check uses the right map

Uppercasing input and checking BRIDGE_ALPHA3_TO_ALPHA2 is appropriate here.


159-160: Verify: route segment uses the expected slug, not ISO3

Pushing to /withdraw/${country}/bank assumes country is the URL segment. If country here is ISO3 (e.g., "DEU"), this may mismatch routes expecting a slug/title.

If needed, change to selectedCountry:

-                    router.push(`/withdraw/${country}/bank`)
+                    router.push(`/withdraw/${selectedCountry}/bank`)

Based on learnings


275-277: LGTM: flag code derived from unified map

Mapping alpha3→alpha2 and lowercasing for the flag CDN is correct.

src/components/AddMoney/components/DepositMethodList.tsx (1)

7-7: LGTM: migrated to ALL_COUNTRIES_ALPHA3_TO_ALPHA2

Consistent with the repo-wide change.

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

4-4: LGTM: migrated to unified country map

Import switch is consistent with other modules.

src/utils/withdraw.utils.ts (1)

1-1: LGTM: use unified maps alongside countryData

Keeps all country lookups consistent.

src/components/Claim/Link/views/Confirm.bank-claim.view.tsx (2)

4-4: LGTM: centralized country map import

Consistent with the broader PR direction.


52-54: LGTM: robust flag code derivation

Uppercasing input then mapping to ISO2 with fallback matches the shared pattern.

src/components/AddMoney/components/AddMoneyBankDetails.tsx (1)

12-12: LGTM: unified mapping import

Switching to ALL_COUNTRIES_ALPHA3_TO_ALPHA2 aligns with the new central map.

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

2-2: LGTM: import swap to unified mapping

Using ALL_COUNTRIES_ALPHA3_TO_ALPHA2 keeps flag lookups consistent across sources.

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

2-8: LGTM: constants alignment

Using BRIDGE_ALPHA3_TO_ALPHA2 and ALL_COUNTRIES_ALPHA3_TO_ALPHA2 is consistent with the new mapping split.

src/components/AddMoney/consts/index.ts (2)

2487-2529: LGTM: bridge mapping extracted and renamed

Renaming to BRIDGE_ALPHA3_TO_ALPHA2 clarifies scope and keeps keys uppercase for ISO3→ISO2.


2531-2540: LGTM: separate Manteca map and merged ALL map

Splitting MANTECA_ALPHA3_TO_ALPHA2 from BRIDGE resolves earlier concern about mixing non-bridge countries, while ALL covers UI flag needs. Addresses prior review concern.

src/components/Profile/views/IdentityVerification.view.tsx (1)

56-61: LGTM: onKycSuccess fetch + redirect

Fetching user before redirect avoids stale UI after approval.

Comment on lines 121 to 123
const twoLetterCountryCode =
countryCodeMap[country.id.toUpperCase()] ?? country.id.toLowerCase()
ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.id.toUpperCase()] ?? country.id.toLowerCase()
const position = getCardPosition(index, filteredCountries.length)
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Use iso2 as fallback for flags instead of id.toLowerCase()

If a country.id is a 3-letter code not present in the map, falling back to id.toLowerCase() yields an invalid flag code (e.g., deu). Prefer the iso2 field.

-                            const twoLetterCountryCode =
-                                ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.id.toUpperCase()] ?? country.id.toLowerCase()
+                            const twoLetterCountryCode =
+                                ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.id.toUpperCase()] ??
+                                country.iso2 ??
+                                country.id
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const twoLetterCountryCode =
countryCodeMap[country.id.toUpperCase()] ?? country.id.toLowerCase()
ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.id.toUpperCase()] ?? country.id.toLowerCase()
const position = getCardPosition(index, filteredCountries.length)
const twoLetterCountryCode =
ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.id.toUpperCase()] ??
country.iso2 ??
country.id
const position = getCardPosition(index, filteredCountries.length)
🤖 Prompt for AI Agents
In src/components/Common/CountryList.tsx around lines 121 to 123, the code falls
back to country.id.toLowerCase() when the 3-letter code lookup fails, which
produces invalid flag codes; replace that fallback with the country's iso2 value
(e.g., country.iso2?.toLowerCase()) and ensure a safe default if iso2 is missing
(such as an empty string or a placeholder), so the flag code resolution becomes:
try the alpha3→alpha2 map first, then country.iso2 lowercased, otherwise the
safe default.

@jjramirezn jjramirezn merged commit adc48f5 into feat/manteca-integration Sep 26, 2025
2 of 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