Skip to content

chore: back-merge main → dev (20260616) — withdraw + send dead-button hotfixes (#2224, #2225)#2228

Merged
Hugo0 merged 7 commits into
devfrom
chore/backmerge-main-to-dev-20260616
Jun 16, 2026
Merged

chore: back-merge main → dev (20260616) — withdraw + send dead-button hotfixes (#2224, #2225)#2228
Hugo0 merged 7 commits into
devfrom
chore/backmerge-main-to-dev-20260616

Conversation

@Hugo0

@Hugo0 Hugo0 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Back-merges the prod hotfixes merged to main into dev so the next dev→main release doesn't conflict.

Carries:

Clean merge (0 conflicts) — both changed files were identical on dev and main. No dev-side architecture to graft.

Hugo0 and others added 7 commits June 15, 2026 14:54
handleAmountContinue threw 'Failed to get country from bank account' inside
the onClick when getCountryFromAccount returned undefined. A synchronous throw
in a click handler aborts the router transition with zero UI feedback — the
button just goes dead ('press Continue, nothing happens'). Surfaced as a
customer report + Sentry incomplete-app-router-transaction (6 users/14d).

Three changes make the handler correct-by-construction:
- Route Manteca (AR/BR) accounts by method type BEFORE the generic saved-bank
  branch. Manteca accounts also set selectedBankAccount, so they previously
  fell into that branch and either mis-routed to the Bridge bank page or threw.
- Replace the throw with setError + console.error so an unresolved country is a
  recoverable, visible error, not a dead button.
- Add a terminal else that sets an error, so no selected-method shape can ever
  leave the handler having done nothing.

The real country-resolution fix is the API counterpart (Manteca flat metadata
shape); this is the defense-in-depth that guarantees the symptom can't recur.

Adds the first tests for the no-country path and Manteca routing — the harness
previously mocked getCountryFromAccount to always succeed, so this path was
entirely uncovered.
…t-clean

Avoid adding a no-require-imports eslint error: drive the bridge.utils mock
through a hoisted mock fn (matching the file's mockUseWallet idiom) instead of
require()-ing the mocked module inside the test.
CodeRabbit nit: the component destructures spendableBalance; the harness default
mocked the wrong key (balance), leaving maxDecimalAmount=0 for existing tests.
PaymentMethodActionList renders an 'Exchange or Wallet' card (soon:false, so
enabled) whose tap only does anything when the caller passes onPayWithExternalWallet.
The semantic-request flow passes it; the direct-send flow (SendInputView, non-
logged-in users) does NOT — and direct-send has no external-wallet path at all
(only Input/Status/Success views). So a guest who entered an amount and tapped
the card got nothing: a dead button (audit HIGH finding, same class as the
withdraw Continue throw).

Fix at the component level so it's correct-by-construction for every caller:
only render the exchange-or-wallet card when an onPayWithExternalWallet handler
is provided. No caller can surface a card it can't honor. Semantic-request is
unchanged (still passes the handler). Adds the component's first tests.
…-no-throw

fix(withdraw): Continue button can never silently die (no-throw + correct Manteca routing)
…let-dead-card

fix(send): hide 'Exchange or Wallet' dead-button card in direct-send flow
@vercel

vercel Bot commented Jun 16, 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 Jun 16, 2026 2:11am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The withdraw page's handleAmountContinue gains an explicit Manteca routing branch, replaces a thrown exception with a user-visible setError when bank-account country resolution fails, and adds a catch-all fallback. PaymentMethodActionList filters out the exchange-or-wallet option when no onPayWithExternalWallet callback is provided. Both changes are covered by new regression tests.

Changes

Withdraw Continue-button routing fixes

Layer / File(s) Summary
handleAmountContinue routing branches and fallback
src/app/(mobile-ui)/withdraw/page.tsx
Adds a manteca branch that routes to /withdraw/manteca with method+country params before the saved-bank-account branch; replaces a thrown exception with console.error+setError when bank-account country is unresolved; adds a catch-all fallback that logs and shows a generic setup error.
Test infrastructure and GROUP 6 regression tests
src/app/(mobile-ui)/withdraw/__tests__/withdraw-states.test.tsx
Replaces the static getCountryFromAccount mock with a controllable mockGetCountryFromAccount, fixes the wallet mock shape to spendableBalance, adds a beforeEach reset guard, and introduces GROUP 6 tests verifying the no-throw setError path and Manteca navigation.

PaymentMethodActionList exchange-or-wallet visibility fix

Layer / File(s) Summary
visibleMethods filtering and tests
src/features/payments/shared/components/PaymentMethodActionList.tsx, src/features/payments/shared/components/__tests__/PaymentMethodActionList.test.tsx
Derives visibleMethods that excludes exchange-or-wallet when onPayWithExternalWallet is absent and maps the render over it; test suite asserts the card is hidden without the handler and rendered+clickable with it.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • peanutprotocol/peanut-ui#2224: Implements the same no-throw/setError behavior and Manteca routing precedence in the withdraw Continue handler that this PR directly builds upon.
  • peanutprotocol/peanut-ui#2222: Introduces /withdraw/manteca/page.tsx that consumes the method/country query params this PR now emits from the Continue handler.
  • peanutprotocol/peanut-ui#2056: Refactors Manteca supported-country validation in /withdraw/manteca, directly related to the country=argentina routing added here.

Suggested reviewers

  • jjramirezn
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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 accurately describes the PR as a back-merge of two hotfixes (#2224 and #2225) for withdraw and send features, which aligns with the file changes and PR objectives.
Description check ✅ Passed The description clearly relates to the changeset, explaining it's a back-merge of hotfixes with specific issue references and a summary of fixes applied across the withdraw and send features.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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

@github-actions

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 5796.9 → 5797.23 (+0.33)
Findings: 0 net (+10 new, -10 resolved)

🆕 New findings (10)

  • critical complexity — src/app/(mobile-ui)/withdraw/page.tsx — CC 119, MI 53.93, SLOC 336
  • medium react-long-component — src/app/(mobile-ui)/withdraw/page.tsx:28 — WithdrawPage is 432 lines — split it
  • medium high-mdd — src/app/(mobile-ui)/withdraw/page.tsx:28 — WithdrawPage: MDD 100.1 (uses across many lines from declarations)
  • medium high-dlt — src/app/(mobile-ui)/withdraw/page.tsx:28 — WithdrawPage: DLT 46 (calls 46 distinct functions — high context load)
  • medium structural-dup — src/features/payments/flows/contribute-pot/components/RequestPotActionList.tsx:177 — 24 duplicate lines / 140 tokens with src/features/payments/shared/components/PaymentMethodActionList.tsx:104
  • medium high-mdd — src/features/payments/shared/components/PaymentMethodActionList.tsx:40 — PaymentMethodActionList: MDD 23.5 (uses across many lines from declarations)
  • medium complexity — src/features/payments/shared/components/PaymentMethodActionList.tsx — CC 23, MI 65.28, SLOC 52
  • medium method-complexity — src/app/(mobile-ui)/withdraw/page.tsx:257 — CC 17 SLOC 55
  • low high-mdd — src/app/(mobile-ui)/withdraw/page.tsx:257 — handleAmountContinue: MDD 17.3 (uses across many lines from declarations)
  • low high-mdd — src/features/payments/shared/components/PaymentMethodActionList.tsx:99 — : MDD 11.9 (uses across many lines from declarations)

✅ Resolved (10)

  • src/app/(mobile-ui)/withdraw/page.tsx — CC 119, MI 54.34, SLOC 322
  • src/app/(mobile-ui)/withdraw/page.tsx:28 — WithdrawPage is 404 lines — split it
  • src/app/(mobile-ui)/withdraw/page.tsx:28 — WithdrawPage: MDD 93.4 (uses across many lines from declarations)
  • src/app/(mobile-ui)/withdraw/page.tsx:28 — WithdrawPage: DLT 45 (calls 45 distinct functions — high context load)
  • src/features/payments/flows/contribute-pot/components/RequestPotActionList.tsx:177 — 24 duplicate lines / 140 tokens with src/features/payments/shared/components/PaymentMethodActionList.tsx:95
  • src/features/payments/shared/components/PaymentMethodActionList.tsx — CC 21, MI 64.84, SLOC 48
  • src/features/payments/shared/components/PaymentMethodActionList.tsx:40 — PaymentMethodActionList: MDD 20.0 (uses across many lines from declarations)
  • src/app/(mobile-ui)/withdraw/page.tsx:257 — CC 17 SLOC 41
  • src/features/payments/shared/components/PaymentMethodActionList.tsx:90 — : MDD 11.9 (uses across many lines from declarations)
  • src/app/(mobile-ui)/withdraw/page.tsx:257 — handleAmountContinue: MDD 10.3 (uses across many lines from declarations)

@github-actions

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 1447 ran, 0 failed, 0 skipped, 19.9s

📊 Coverage (unit)

metric %
statements 52.2%
branches 34.5%
functions 39.2%
lines 52.1%
⏱ 10 slowest test cases
time test
0.3s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › every stamp stays within canvas at any count
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/Request/__tests__/request-states.test.tsx › API failure shows error message and toast
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle maximum length (17 digits) US account
0.1s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Manteca PIX form ready shows merchant card + amount input + pay button
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid ETH address in lowercase
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle too long for US account
0.1s 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 minimum length (6 digits) US account
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@Hugo0 Hugo0 merged commit c5a5b9d into dev Jun 16, 2026
25 of 32 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.

1 participant