Skip to content

merge: sync main hotfixes into dev#1963

Merged
Hugo0 merged 24 commits into
devfrom
sync/main-to-dev-resolved
May 10, 2026
Merged

merge: sync main hotfixes into dev#1963
Hugo0 merged 24 commits into
devfrom
sync/main-to-dev-resolved

Conversation

@kushagrasarathe

Copy link
Copy Markdown
Contributor

Summary

Changes synced from main:

Conflict resolutions:

File Resolution
tests.yml Combined both: main's push trigger + dev's workflow_dispatch + permissions
qr-pay/page.tsx Take main — useQrKycGate(paymentProcessor) needed for rail-specific gating
AddWithdrawCountriesList.tsx Keep dev — has native routing (query param support for Capacitor)
analytics.consts.ts Keep both events (QR_NOTIFY_ME_CLICKED + QR_DECODING_ERROR_SHOWN)
useBridgeTransferReadiness.test.ts Take main — proper as const typing instead of as any

Test plan

  • CI passes (typecheck + tests + prettier)
  • Verify qr-pay Pix decoding error shows correct rail-specific copy
  • Verify bridge transfers show $0.00 fee (no 50bps deduction)
  • Close chore: sync dev with main #1953 after this merges

kushagrasarathe and others added 23 commits May 6, 2026 23:12
…andling

the bridge KYC state handling in transfer flows (withdraw, deposit, claim, qr-pay)
had multiple issues: wrong priority order, missing ToS checks, redirects instead of
inline flows, and broken rejection handling.

changes:
- new `useBridgeTransferReadiness` hook: unified pre-transfer gate with correct
  priority (hard rejection → tos → fixable rejection → enrollment → ready)
- `useBridgeTosStatus`: expanded to check `tos_acceptance`/`tos_v2_acceptance` in
  rail `additionalRequirements` metadata, not just `REQUIRES_INFORMATION` status
- `InitiateKycModal`: added `blocked` variant (contact support CTA), `error` prop
  for failed self-heal attempts
- withdraw/bank, add-money/bank, AddWithdrawCountriesList: replaced fragmented
  `needsBridgeEnrollment` + `guardWithTos` + `bridgeRejection` checks with unified gate
- BankFlowManager (claim flow): added ToS guard + rejection handling for non-guest paths
- qr-pay: replaced redirect-based KYC (`router.push('/profile/identity-verification')`)
  with inline sumsub SDK initiation (`handleInitiateKyc('LATAM')`)
- BridgeTosStep: show confirmation modal before iframe, prevent modal flash during
  confirmation with `isConfirming` state
- KycProviderRejection, ActivationCTAs, RegionsVerification: replaced broken
  `$crisp.push` calls with `setIsSupportModalOpen`
- useSumsubKycFlow: fixed race condition where `fetchCurrentStatus` closes SDK wrapper
  on first attempt by guarding with `showWrapperRef`
- useProviderRejectionStatus: permanent rejections now show generic support message
  instead of misleading "upload a clearer photo"
- DynamicBankAccountForm: `__silent__` sentinel to prevent form navigation when gate blocks
- close kyc modal via `sumsubFlow.showWrapper` effect instead of in `onVerify` callback
…ata cast, gate fallthrough

- BridgeTosStep: wrap confirmBridgeTosAndAwaitRails in try/catch to prevent
  isConfirming getting stuck on error
- useBridgeTosStatus: use Array.isArray guard for additionalRequirements metadata
- all gate checks: always return when gate is not ready, even if guardWithTos
  returns false (defensive)
…lt, dedup variant mapping

- useSumsubKycFlow: save/restore prevStatusRef on crossRegion failure to prevent
  suppressing subsequent legitimate APPROVED transitions
- DynamicBankAccountForm: replace __silent__ magic string with typed { silent: true }
- useBridgeTransferReadiness: extract getKycModalVariant() and getGateProviderMessage()
  helpers to deduplicate gate→modal mapping across 4 files
- BankFlowManager: only close kyc modal if sdk opened (check showWrapper), preserving
  error visibility on failure
…minate SDK auto-close race

the fetchCurrentStatus effect could still race with handleInitiateKyc in rare
cases — initiatingRef resets in the finally block before React batches the
showWrapper state update. adding userInitiatedRef as a guard permanently
disables the background fetch after any user-initiated flow, since the SDK
and websocket handle status updates from that point.
Users paying with a Pix QR were told to ask the merchant for a Mercado
Pago QR, which is wrong and confusing. Branch the message on qrType so
Pix scans get Pix-specific guidance.

Also capture qr_decoding_error_shown so we can measure how often this
fallback fires and which rails are most affected.
Per CodeRabbit review on #1948: ARGENTINA_QR3 was hitting the default
branch and getting told to ask the merchant for a Mercado Pago QR —
QR3 and Mercado Pago are distinct Argentine standards, so the copy
was actively misleading.

Now branches PIX, ARGENTINA_QR3, and the MP default explicitly.
In Argentina, Mercado Pago is the dominant rail and a workable fallback
when a QR3 code fails to decode — so suggesting "ask for a Mercado Pago
QR" is the most useful guidance for QR3 users too. Only Pix needs the
rail-specific copy because Brazil has no equivalent fallback.

Reverts the previous QR3-specific message; adds a comment explaining
the regional reasoning so future readers don't trip on the same point
CodeRabbit raised.
…hine

fix: bridge KYC state machine — unified gate, inline ToS, rejection handling
Signed-off-by: Juan José Ramírez <70615692+jjramirezn@users.noreply.github.com>
…rror-message

[TASK-19529] fix(qr-pay): Pix-specific copy on QR decoding error + capture event
Sister change to peanut-api-ts hotfix/bridge-developer-fee-zero. With
the backend no longer attaching developer_fee_percent on Bridge
transfers, the UI's "amount you will receive" math must stop deducting
the same 50bps locally — otherwise we under-quote.

Setting BRIDGE_DEVELOPER_FEE_RATE to 0 turns applyBridgeCrossCurrencyFee
and reverseBridgeCrossCurrencyFee into identity functions, which
matches what Bridge actually delivers. The hardcoded "Fee: $ 0.00"
PaymentInfoRows in withdraw/bank-claim flows now become truthful.

Tests are reparameterized against the constant so they stay correct
when the FX-spread followup re-enables a margin.
…fee-zero

hotfix(bridge): zero-out cross-currency dev fee to match backend
ci: fix auto-bump PR base + add pull_request trigger to Tests
brings in:
- fix(bridge): zero-out cross-currency dev fee (#1957)
- fix(qr-pay): Pix-specific decoding error copy (#1948)
- ci: push trigger + pull_request for API-created PRs (#1956)
- ci: target dev for content submodule bumps

conflicts resolved:
- tests.yml: combined both triggers (push + pull_request + workflow_dispatch + permissions)
- qr-pay: take main's useQrKycGate(paymentProcessor) signature
- AddWithdrawCountriesList: keep dev's native routing (query param support)
- analytics.consts: keep both QR_NOTIFY_ME_CLICKED and QR_DECODING_ERROR_SHOWN
- useBridgeTransferReadiness.test: take main's stricter typing (no `as any`)
@vercel

vercel Bot commented May 10, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment May 10, 2026 10:23am

Request Review

@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR makes QR-pay KYC gating processor-aware and adds QR-type-specific decoding-error copy with a new analytics event; sets the bridge developer fee rate to 0 and updates tests to compute expected outcomes from the shared constant; and expands CI test triggers and sets update-content PR base to dev.

Changes

QR Pay Error Messaging and Analytics

Layer / File(s) Summary
Analytics Event Definition
src/constants/analytics.consts.ts
New QR_DECODING_ERROR_SHOWN event constant added to ANALYTICS_EVENTS, extending the AnalyticsEvent union type.
KYC Hook Signature & Logic
src/hooks/useQrKycGate.ts
useQrKycGate now accepts optional `paymentProcessor?: 'MANTECA'
QR Pay Page - KYC Gate and Error Handling
src/app/(mobile-ui)/qr-pay/page.tsx
KYC gate initialization now passes paymentProcessor; payment-lock decoding errors show PIX-specific "ask merchant to regenerate" or Mercado Pago fallback copy and emit QR_DECODING_ERROR_SHOWN with qr_type.

Bridge Developer Fee Rate and Test Updates

Layer / File(s) Summary
Bridge Fee Rate Configuration
src/constants/payment.consts.ts
BRIDGE_DEVELOPER_FEE_RATE changed from 0.005 to 0 with expanded inline documentation describing current 0% behavior and future FX-spread re-enablement.
Bridge Utils Test - Helper Setup
src/utils/__tests__/bridge.utils.test.ts
Imports BRIDGE_DEVELOPER_FEE_RATE and introduces NET_OF_100 helper to compute expected post-fee results dynamically.
Bridge Utils Test - Fee Application
src/utils/__tests__/bridge.utils.test.ts
Cross-currency fee application tests updated to assert results ≈ NET_OF_100 instead of hardcoded 99.5; case-insensitivity and zero/negative amount tests updated.
Bridge Utils Test - Reverse Fee and Extended Coverage
src/utils/__tests__/bridge.utils.test.ts
Reverse-fee tests use NET_OF_100 as input and update assertions accordingly.
Bridge Transfer Readiness Test - Type Improvements
src/hooks/__tests__/useBridgeTransferReadiness.test.ts
Tightened test typing by importing ProviderRejectionState, concretely typing defaultRejection, updating setup default cast, and removing stray as any casts.

CI Workflow Configuration

Layer / File(s) Summary
Workflow Configuration Updates
.github/workflows/tests.yml, .github/workflows/update-content.yml
tests.yml adds push trigger for all branches and reformats pull_request branch list; update-content.yml gh pr create now targets dev via --base dev.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'merge: sync main hotfixes into dev' accurately describes the primary change—syncing multiple hotfixes from main into the dev branch.
Description check ✅ Passed The description comprehensively explains the sync purpose, lists the four specific hotfixes synced from main, documents all conflict resolutions, and includes a test plan with verification steps.
Linked Issues check ✅ Passed The PR meets all key coding objectives from #1953: syncs bridge fee zeroing, QR-pay Pix-specific copy with analytics event, CI workflow triggers, and proper typings in tests.
Out of Scope Changes check ✅ Passed All changes are scoped to the four synced hotfixes and conflict resolutions. No out-of-scope modifications beyond the documented sync objectives were introduced.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@github-actions

github-actions Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 5748.41 → 5728.23 (-20.18)
Findings: 0 net (+25 new, -25 resolved)

🆕 New findings (25)

  • critical complexity — src/app/(mobile-ui)/qr-pay/page.tsx — CC 261, MI 54.04, SLOC 843
  • high hotspot — src/app/(mobile-ui)/qr-pay/page.tsx — 95 commits, +1218/-1199 lines since 6 months ago
  • high hotspot — src/app/(mobile-ui)/withdraw/manteca/page.tsx — 51 commits, +566/-338 lines since 6 months ago
  • high hotspot — src/app/(mobile-ui)/add-money/[country]/bank/page.tsx — 43 commits, +492/-422 lines since 6 months ago
  • high complexity — src/hooks/useQrKycGate.ts — CC 35, MI 61.15, SLOC 89
  • high hotspot — src/hooks/useSumsubKycFlow.ts — 30 commits, +440/-67 lines since 6 months ago
  • high complexity — src/constants/analytics.consts.ts — CC 1, MI 36.6, SLOC 127
  • medium react-long-component — src/app/(mobile-ui)/qr-pay/page.tsx:72 — QRPayPage is 1308 lines — split it
  • medium high-mdd — src/app/(mobile-ui)/qr-pay/page.tsx:72 — QRPayPage: MDD 316.8 (uses across many lines from declarations)
  • medium high-mdd — src/app/(mobile-ui)/qr-pay/page.tsx:437 — : MDD 33.2 (uses across many lines from declarations)
  • medium high-mdd — src/hooks/useQrKycGate.ts:30 — useQrKycGate: MDD 28.6 (uses across many lines from declarations)
  • medium hotspot — src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx — 28 commits, +276/-118 lines since 6 months ago
  • medium hotspot — src/components/AddWithdraw/AddWithdrawCountriesList.tsx — 26 commits, +358/-261 lines since 6 months ago
  • medium high-mdd — src/hooks/useQrKycGate.ts:35 — : MDD 21.8 (uses across many lines from declarations)
  • medium method-complexity — src/app/(mobile-ui)/qr-pay/page.tsx:437 — CC 20 SLOC 109
  • medium hotspot — src/app/actions/sumsub.ts — 20 commits, +142/-66 lines since 6 months ago
  • medium method-complexity — src/hooks/useQrKycGate.ts:35 — CC 17 SLOC 56
  • medium complexity — src/constants/payment.consts.ts — CC 2, MI 64.31, SLOC 19
  • medium react-effect-derives-state — src/app/(mobile-ui)/qr-pay/page.tsx:795 — small useEffect that only sets state from deps
  • low high-dlt — src/app/(mobile-ui)/qr-pay/page.tsx:437 — : DLT 17 (calls 17 distinct functions — high context load)

…and 5 more.

✅ Resolved (25)

  • src/app/(mobile-ui)/qr-pay/page.tsx — CC 260, MI 54.07, SLOC 841
  • src/app/(mobile-ui)/qr-pay/page.tsx — 90 commits, +1175/-1161 lines since 6 months ago
  • src/app/(mobile-ui)/withdraw/manteca/page.tsx — 46 commits, +522/-302 lines since 6 months ago
  • src/app/(mobile-ui)/add-money/[country]/bank/page.tsx — 38 commits, +439/-373 lines since 6 months ago
  • src/hooks/useQrKycGate.ts — CC 36, MI 61.12, SLOC 89
  • src/constants/analytics.consts.ts — CC 1, MI 36.69, SLOC 126
  • src/app/(mobile-ui)/qr-pay/page.tsx:72 — QRPayPage is 1302 lines — split it
  • src/app/(mobile-ui)/qr-pay/page.tsx:72 — QRPayPage: MDD 315.4 (uses across many lines from declarations)
  • src/app/(mobile-ui)/qr-pay/page.tsx:431 — : MDD 33.2 (uses across many lines from declarations)
  • src/hooks/useSumsubKycFlow.ts — 27 commits, +429/-65 lines since 6 months ago
  • src/hooks/useQrKycGate.ts:29 — useQrKycGate: MDD 25.8 (uses across many lines from declarations)
  • src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx — 24 commits, +221/-88 lines since 6 months ago
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx — 22 commits, +287/-219 lines since 6 months ago
  • src/hooks/useQrKycGate.ts:34 — : MDD 21.4 (uses across many lines from declarations)
  • src/app/(mobile-ui)/qr-pay/page.tsx:431 — CC 20 SLOC 109
  • src/app/sw.ts — 20 commits, +874/-836 lines since 6 months ago
  • src/hooks/useQrKycGate.ts:34 — CC 18 SLOC 56
  • src/constants/payment.consts.ts — CC 2, MI 64.37, SLOC 19
  • src/app/(mobile-ui)/qr-pay/page.tsx:789 — small useEffect that only sets state from deps
  • src/app/(mobile-ui)/qr-pay/page.tsx:431 — : DLT 17 (calls 17 distinct functions — high context load)

…and 5 more.

📈 Painscore deltas (top movers)

File Before After Δ
src/components/Claim/Link/views/BankFlowManager.view.tsx 15.2 15.8 +0.5

@github-actions

github-actions Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 940 ran, 0 failed, 0 skipped, 14.7s

📊 Coverage (unit)

metric %
statements 44.9%
branches 23.9%
functions 24.1%
lines 44.6%
⏱ 10 slowest test cases
time test
0.3s src/app/actions/__tests__/api-headers-extended.test.ts › should not include apiKey in updateUserById body
0.3s src/app/actions/__tests__/api-headers.test.ts › should include Content-Type in updateUserById
0.2s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid 9-digit US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle too long for US account
0.1s src/components/Request/__tests__/request-states.test.tsx › API failure shows error message and toast
0.1s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Perk claimed shows shake class + go home button
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle invalid ETH address (too short)
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid ETH address
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid US account with spaces 2
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid Italian IBAN
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
.github/workflows/update-content.yml (1)

45-69: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align commit parent with the PR base branch (dev).

The workflow uses the default branch (main) as the parent commit but hardcodes --base dev. If main and dev have diverged, unrelated commits from main will be included in the PR.

Suggested fix
               run: |
+                  BASE_BRANCH="dev"
                   BRANCH="auto/update-content-$(date -u +%Y%m%d-%H%M%S)"
                   SUBMODULE_SHA=$(git -C src/content rev-parse HEAD)
-                  PARENT=$(git rev-parse HEAD)
+                  PARENT=$(gh api repos/${{ github.repository }}/git/ref/refs/heads/$BASE_BRANCH --jq '.object.sha')
                   BASE_TREE=$(gh api repos/${{ github.repository }}/git/commits/$PARENT --jq '.tree.sha')
@@
                   gh pr create \
                     --head "$BRANCH" \
-                    --base dev \
+                    --base "$BASE_BRANCH" \
                     --title "Update content submodule" \
                     --body "Auto-generated: updates content submodule to latest peanut-content main."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/update-content.yml around lines 45 - 69, The workflow is
creating the commit with PARENT set to the default branch instead of the PR base
(dev), causing unrelated commits to be included; update the logic that computes
PARENT so it resolves the commit SHA of the target PR base (dev) and use that
SHA for BASE_TREE and as the parents[] when creating the commit (affecting the
variables PARENT, BASE_TREE, TREE, COMMIT_SHA, and BRANCH), e.g. fetch the ref
for the dev branch via the GitHub API and assign that SHA to PARENT before
creating the tree/commit/branch and opening the PR with --head "$BRANCH" --base
dev.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/`(mobile-ui)/qr-pay/page.tsx:
- Line 112: The call site passes paymentProcessor into useQrKycGate but the hook
signature (useQrKycGate) currently accepts no parameters; either remove the
argument from the call (change useQrKycGate(paymentProcessor) to useQrKycGate())
to match the existing export, or modify the hook definition (export function
useQrKycGate(paymentProcessor: PaymentProcessorType): QrKycGateResult) and
update its implementation to consume the paymentProcessor parameter where needed
(adjust types and any internal references inside useQrKycGate accordingly).

---

Outside diff comments:
In @.github/workflows/update-content.yml:
- Around line 45-69: The workflow is creating the commit with PARENT set to the
default branch instead of the PR base (dev), causing unrelated commits to be
included; update the logic that computes PARENT so it resolves the commit SHA of
the target PR base (dev) and use that SHA for BASE_TREE and as the parents[]
when creating the commit (affecting the variables PARENT, BASE_TREE, TREE,
COMMIT_SHA, and BRANCH), e.g. fetch the ref for the dev branch via the GitHub
API and assign that SHA to PARENT before creating the tree/commit/branch and
opening the PR with --head "$BRANCH" --base dev.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 079e99d8-515a-4b17-a06e-ad1c7dec036e

📥 Commits

Reviewing files that changed from the base of the PR and between ab1f5c2 and 881833c.

📒 Files selected for processing (7)
  • .github/workflows/tests.yml
  • .github/workflows/update-content.yml
  • src/app/(mobile-ui)/qr-pay/page.tsx
  • src/constants/analytics.consts.ts
  • src/constants/payment.consts.ts
  • src/hooks/__tests__/useBridgeTransferReadiness.test.ts
  • src/utils/__tests__/bridge.utils.test.ts

Comment thread src/app/(mobile-ui)/qr-pay/page.tsx
- useQrKycGate: restore paymentProcessor param (regressed by cherry-pick),
  remove SimpleFi references (removed from dev), keep user?.rails dep
- useBridgeTransferReadiness.test: use ProviderRejectionState type instead
  of `as const` to allow state comparisons in mock setup

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
src/hooks/useQrKycGate.ts (1)

30-127: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use paymentProcessor to actually scope Manteca-only gating

Line 30 introduces paymentProcessor, but it is never used in the decision tree. As written, Lines 66-115 still enforce Manteca rejection/KYC paths for every rail, so non-Manteca QR flows can be incorrectly blocked by Manteca history.

Suggested fix
 export function useQrKycGate(paymentProcessor?: 'MANTECA' | null): QrKycGateResult {
     const { user, isFetchingUser, fetchUser } = useAuth()
+    const isMantecaProcessor = paymentProcessor === 'MANTECA'
@@
         if (hasSumsubApproved) {
-            // check if manteca has rejected rails (qr payments use manteca)
-            const rejectedMantecaRails = (user?.rails ?? []).filter(
-                (r) => r.rail.provider.code === 'MANTECA' && r.status === 'REJECTED'
-            )
-            if (rejectedMantecaRails.length > 0) {
-                const railMeta = (rejectedMantecaRails[0].metadata ?? {}) as Record<string, unknown>
-                const mantecaKyc = currentUser.kycVerifications
-                    ?.filter((v) => v.provider === 'MANTECA')
-                    .sort((a, b) => new Date(b.updatedAt ?? 0).getTime() - new Date(a.updatedAt ?? 0).getTime())[0]
-                const kycMeta = (mantecaKyc?.metadata ?? {}) as Record<string, unknown>
-                const isFixable =
-                    railMeta.selfHealable === true &&
-                    mantecaKyc?.rejectType !== 'PROVIDER_FINAL' &&
-                    ((kycMeta.selfHealAttempt as number) || 0) < MAX_SELF_HEAL_ATTEMPTS
-                setKycGateState(
-                    isFixable ? QrKycState.PROVIDER_REJECTION_FIXABLE : QrKycState.PROVIDER_REJECTION_BLOCKED
-                )
-                return
+            if (isMantecaProcessor) {
+                const rejectedMantecaRails = (user?.rails ?? []).filter(
+                    (r) => r.rail.provider.code === 'MANTECA' && r.status === 'REJECTED'
+                )
+                if (rejectedMantecaRails.length > 0) {
+                    const railMeta = (rejectedMantecaRails[0].metadata ?? {}) as Record<string, unknown>
+                    const mantecaKyc = currentUser.kycVerifications
+                        ?.filter((v) => v.provider === 'MANTECA')
+                        .sort((a, b) => new Date(b.updatedAt ?? 0).getTime() - new Date(a.updatedAt ?? 0).getTime())[0]
+                    const kycMeta = (mantecaKyc?.metadata ?? {}) as Record<string, unknown>
+                    const isFixable =
+                        railMeta.selfHealable === true &&
+                        mantecaKyc?.rejectType !== 'PROVIDER_FINAL' &&
+                        ((kycMeta.selfHealAttempt as number) || 0) < MAX_SELF_HEAL_ATTEMPTS
+                    setKycGateState(
+                        isFixable ? QrKycState.PROVIDER_REJECTION_FIXABLE : QrKycState.PROVIDER_REJECTION_BLOCKED
+                    )
+                    return
+                }
             }
             setKycGateState(QrKycState.PROCEED_TO_PAY)
             return
         }
 
-        const mantecaKycs = currentUser.kycVerifications?.filter((v) => v.provider === 'MANTECA') ?? []
+        const mantecaKycs = isMantecaProcessor
+            ? currentUser.kycVerifications?.filter((v) => v.provider === 'MANTECA') ?? []
+            : []
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/useQrKycGate.ts` around lines 30 - 127, The code never uses the
paymentProcessor param so MANTECA-specific checks are applied to all flows;
update useQrKycGate.determineKycGateState to only run Manteca-specific logic
when paymentProcessor === 'MANTECA'. Concretely, wrap the rejectedMantecaRails
check and the mantecaKyc/mantecaKycs branches (references: rejectedMantecaRails,
mantecaKyc, mantecaKycs, MantecaKycStatus) in a guard such as if
(paymentProcessor === 'MANTECA') { ... } and otherwise skip to the non-Manteca
paths (e.g., treat sumsub-approved or bridge KYC as allowing PROCEED_TO_PAY
without consulting Manteca rails). Ensure the dependency array still includes
paymentProcessor.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/hooks/useQrKycGate.ts`:
- Around line 30-127: The code never uses the paymentProcessor param so
MANTECA-specific checks are applied to all flows; update
useQrKycGate.determineKycGateState to only run Manteca-specific logic when
paymentProcessor === 'MANTECA'. Concretely, wrap the rejectedMantecaRails check
and the mantecaKyc/mantecaKycs branches (references: rejectedMantecaRails,
mantecaKyc, mantecaKycs, MantecaKycStatus) in a guard such as if
(paymentProcessor === 'MANTECA') { ... } and otherwise skip to the non-Manteca
paths (e.g., treat sumsub-approved or bridge KYC as allowing PROCEED_TO_PAY
without consulting Manteca rails). Ensure the dependency array still includes
paymentProcessor.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3f9208fd-1941-41b0-bbbe-2e454b92986f

📥 Commits

Reviewing files that changed from the base of the PR and between 881833c and e1afb44.

📒 Files selected for processing (2)
  • src/hooks/__tests__/useBridgeTransferReadiness.test.ts
  • src/hooks/useQrKycGate.ts
✅ Files skipped from review due to trivial changes (1)
  • src/hooks/tests/useBridgeTransferReadiness.test.ts

@Hugo0 Hugo0 merged commit c1a5358 into dev May 10, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants