Skip to content

release: dev → main (KYC poll backoff + cleanups)#2340

Merged
Hugo0 merged 17 commits into
mainfrom
dev
Jul 3, 2026
Merged

release: dev → main (KYC poll backoff + cleanups)#2340
Hugo0 merged 17 commits into
mainfrom
dev

Conversation

@Hugo0

@Hugo0 Hugo0 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Merge order: land #2339 (back-merge main→dev) FIRST — then this PR is a clean superset of main.

Release payload (dev-only commits)

  1. fix(kyc): back off verification-progress poll instead of a fixed 5s interval — less API hammering from the KYC progress screen.
  2. test(kyc) eslint cleanup + mascot asset rename (no behavior).

Low-risk release; no service-worker version bump needed (no breaking API changes).

Hugo0 and others added 7 commits July 1, 2026 18:59
…ll-crash

fix(add-money): stop page crash when FX rate fails to load (PEANUT-UI-PS7)
PEANUTMAN_LOGO was the peanut-character illustration mislabeled as a
"logo" — distinct from the app icon (peanut-icon.svg) and the PEANUT
wordmark (PEANUT_LOGO). The name described where it was first used (a
header), not what it depicts.

- Rename export PEANUTMAN_LOGO -> PEANUTMAN and file
  mascot/peanut-logo.svg -> mascot/peanutman.svg; update all call sites,
  the local ASSET_ var, and the mascot alt text ("logo" -> "Peanut mascot").
- Move PEANUT_LOGO_BLACK out of illustrations/ into logos/ (it's the brand
  logo); fix the one subpath import.

No behavior change — same pixels, accurate names. public/peanutman-logo.svg
is retained unchanged as the external email/embed alias.

Co-authored-by: kushagrasarathe <kushagrasarathe@gmail.com>
refactor(assets): name the mascot a mascot, not a logo
…nterval

The verification-progress modal polled initiateSumsubKyc — a mutating
endpoint — every 5s for the whole modal-open as a websocket fallback. For
approved-LATAM users in the self-recovery state each call re-runs a full
provider submission (86 in 20 min for one user, 2026-07-02); even with the
BE cooldown each poll still costs ~3 provider calls + DB writes.

Replace the fixed setInterval with a self-rescheduling setTimeout chain on a
time-escalating schedule (5s for the first minute, then 10s → 20s → 60s) and
stop polling after a ~15 min cap. The backoff is time-based, not error-based:
the poll returns HTTP 200 even when the backend reprocess fails, so an error
count would never escalate. The websocket stays the primary signal and the
modal keeps its existing long-running state after the cap; re-opening restarts
polling fresh.
fix(kyc): back off verification-progress poll instead of a fixed 5s interval
@vercel

vercel Bot commented Jul 2, 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 Jul 3, 2026 3:04am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 70d4fb39-f7d7-48d7-a5c8-ff0eef8bf119

📥 Commits

Reviewing files that changed from the base of the PR and between 357728d and bbd8b6d.

⛔ Files ignored due to path filters (2)
  • src/assets/logos/peanut-logo-dark.svg is excluded by !**/*.svg
  • src/assets/mascot/peanutman.svg is excluded by !**/*.svg
📒 Files selected for processing (30)
  • src/app/(mobile-ui)/notifications/page.tsx
  • src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx
  • src/app/dev/loading-words/page.tsx
  • src/assets/illustrations/index.ts
  • src/assets/logos/index.ts
  • src/assets/mascot/index.ts
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
  • src/components/AddWithdraw/__tests__/AddWithdrawCountriesList.test.tsx
  • src/components/Badges/badge.utils.ts
  • src/components/Card/CardFace.tsx
  • src/components/Card/share-asset/PixelatedCardFace.tsx
  • src/components/Claim/Link/Initial.view.tsx
  • src/components/Claim/Link/SendLinkActionList.tsx
  • src/components/Global/ConfirmInviteModal/index.tsx
  • src/components/Global/CreateAccountButton/index.tsx
  • src/components/Global/NoMoreJailModal/index.tsx
  • src/components/Global/PeanutLoading/CyclingLoading.tsx
  • src/components/Global/PeanutLoading/index.tsx
  • src/components/Global/QRScanner/index.tsx
  • src/components/Home/ActivationCTAs.tsx
  • src/components/Kyc/ProvideEmailStep.tsx
  • src/components/Profile/components/PublicProfile.tsx
  • src/components/TransactionDetails/TransactionCard.tsx
  • src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx
  • src/features/payments/shared/components/SendWithPeanutCta.tsx
  • src/hooks/__tests__/useSumsubKycFlow.test.ts
  • src/hooks/useSumsubKycFlow.ts
  • src/types/capabilities.ts
  • src/utils/capability-gate.test.ts
  • src/utils/capability-gate.ts

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

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 5859.57 → 5872.71 (+13.14)
Findings: +5 net (+32 new, -27 resolved)

🆕 New findings (32)

  • critical complexity — src/components/AddWithdraw/AddWithdrawCountriesList.tsx — CC 123, MI 56.93, SLOC 350
  • critical complexity — src/hooks/useSumsubKycFlow.ts — CC 84, MI 52.91, SLOC 379
  • critical complexity — src/utils/capability-gate.ts — CC 68, MI 63.85, SLOC 182
  • high hotspot — src/components/AddWithdraw/AddWithdrawCountriesList.tsx — 42 commits, +702/-480 lines since 6 months ago
  • high complexity — src/components/Home/ActivationCTAs.tsx — CC 42, MI 59.11, SLOC 160
  • high hotspot — src/hooks/useSumsubKycFlow.ts — 42 commits, +650/-90 lines since 6 months ago
  • high hotspot — src/components/Badges/badge.utils.ts — 34 commits, +332/-108 lines since 6 months ago
  • medium high-mdd — src/hooks/useSumsubKycFlow.ts:51 — useSumsubKycFlow: MDD 176.0 (uses across many lines from declarations)
  • medium high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:45 — AddWithdrawCountriesList: MDD 143.4 (uses across many lines from declarations)
  • medium high-dlt — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:45 — AddWithdrawCountriesList: DLT 61 (calls 61 distinct functions — high context load)
  • medium high-mdd — src/components/Home/ActivationCTAs.tsx:77 — ActivationCTAs: MDD 45.8 (uses across many lines from declarations)
  • medium high-dlt — src/hooks/useSumsubKycFlow.ts:51 — useSumsubKycFlow: DLT 41 (calls 41 distinct functions — high context load)
  • medium high-mdd — src/hooks/useSumsubKycFlow.ts:200 — : MDD 36.7 (uses across many lines from declarations)
  • medium high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:452 — : MDD 28.5 (uses across many lines from declarations)
  • medium high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:443 — renderPaymentMethods: MDD 27.3 (uses across many lines from declarations)
  • medium hotspot — src/components/TransactionDetails/TransactionCard.tsx — 27 commits, +192/-140 lines since 6 months ago
  • medium method-complexity — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:45 — CC 21 SLOC 118
  • medium method-complexity — src/hooks/useSumsubKycFlow.ts:200 — CC 21 SLOC 91
  • medium method-complexity — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:166 — CC 16 SLOC 56
  • medium complexity — src/components/Kyc/ProvideEmailStep.tsx — CC 11, MI 56.46, SLOC 58

…and 12 more.

✅ Resolved (27)

  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx — CC 119, MI 56.62, SLOC 336
  • src/hooks/useSumsubKycFlow.ts — CC 79, MI 52.54, SLOC 349
  • src/utils/capability-gate.ts — CC 62, MI 64.19, SLOC 167
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx — 40 commits, +688/-480 lines since 6 months ago
  • src/hooks/useSumsubKycFlow.ts — 40 commits, +583/-76 lines since 6 months ago
  • src/components/Home/ActivationCTAs.tsx — CC 34, MI 57.96, SLOC 130
  • src/components/Badges/badge.utils.ts — 33 commits, +330/-106 lines since 6 months ago
  • src/hooks/useSumsubKycFlow.ts:21 — useSumsubKycFlow: MDD 169.6 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:44 — AddWithdrawCountriesList: MDD 140.0 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:44 — AddWithdrawCountriesList: DLT 60 (calls 60 distinct functions — high context load)
  • src/components/Home/ActivationCTAs.tsx:76 — ActivationCTAs: MDD 40.9 (uses across many lines from declarations)
  • src/hooks/useSumsubKycFlow.ts:21 — useSumsubKycFlow: DLT 37 (calls 37 distinct functions — high context load)
  • src/hooks/useSumsubKycFlow.ts:147 — : MDD 36.7 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:438 — : MDD 28.5 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:429 — renderPaymentMethods: MDD 27.3 (uses across many lines from declarations)
  • src/components/TransactionDetails/TransactionCard.tsx — 26 commits, +190/-138 lines since 6 months ago
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:44 — CC 21 SLOC 114
  • src/hooks/useSumsubKycFlow.ts:147 — CC 21 SLOC 91
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:162 — CC 15 SLOC 53
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:135 — small useEffect that only sets state from deps

…and 7 more.

📈 Painscore deltas (top movers)

File Before After Δ
src/components/Kyc/ProvideEmailStep.tsx 0.0 8.4 +8.4
src/utils/capability-gate.ts 7.5 8.1 +0.5
src/components/Home/ActivationCTAs.tsx 9.4 9.9 +0.5

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 1678 ran, 0 failed, 0 skipped, 25.0s

📊 Coverage (unit)

metric %
statements 55.0%
branches 38.1%
functions 42.9%
lines 55.0%
⏱ 10 slowest test cases
time test
4.1s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
0.4s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › every sticker stays within canvas at any count
0.3s src/app/actions/__tests__/api-headers.test.ts › should include Content-Type in updateUserById
0.2s src/app/actions/__tests__/api-headers-extended.test.ts › should not include apiKey in updateUserById body
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 too long for US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid UK IBAN with spaces
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle maximum length (17 digits) US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid US account with spaces
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid ETH address with surrounding spaces
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

…6-07-02

chore: back-merge main → dev (2026-07-02 hotfix wave)
…ce, never hard-stops

The 15-min KYC_POLL_CAP_MS stopped the fallback poll entirely, so a websocket
event missed during a long manual review (laptop sleep, mobile background,
network switch) left the user on 'Almost there' forever with onKycSuccess
never firing. The poll now settles at the 60s floor and keeps going for the
whole modal-open lifetime; the backend self-recovery cooldown bounds the
per-call cost, so it's nothing like the fixed-5s battering ram the schedule
replaced. Regression tests: keeps polling past 15 min (bounded ~10 calls in
the following 10 min, not zero, not a flood) and a late APPROVED still fires
onKycSuccess.
Hugo0 and others added 5 commits July 2, 2026 18:05
Companion to peanut-api-ts#1119. Users whose email was never captured used
to dead-end on 'message support' (their only fix was a ticket); the BE now
emits a provide-email NextAction for those rails, and this renders it: an
email form (ActionModal, BridgeTosStep shell) wired into the two places the
block surfaces — the home activation CTA and the bank add/withdraw gate.
Saving posts update-user (first-time email set is allowed while KYC-locked)
and the BE flips the rails to PENDING and resubmits automatically.
…tract, shadowing, copy

getKycModalVariant maps provide-email to 'blocked' so unwired gate consumers
keep the contact-support floor instead of a bogus re-verify CTA; the gate and
ActivationCTAs both detect via the provide-email action kind (one contract,
no reason-code divergence) and prefer an email-blocked rail over an earlier
terminal one; the home CTA copy now says 'Add your email / Add email' instead
of promising support and opening a form; the sheet resets on reopen and
guards a not-yet-loaded userId.
feat(kyc): provide-email sheet for the no-email verification dead-end
fix(kyc): verification poll never hard-stops — no user strand (post-merge /code-review)
…6-07-03-ui

chore: back-merge main → dev (offramp migration deposit + invite fixes)
Hugo0 and others added 2 commits July 2, 2026 19:16
…sistently (final /code-review)

Final pre-prod review of the #2342 provide-email surfaces found two consumer
sites diverging from the canonical deriveGate order (email-blocked > fixable):

- ActivationCTAs: the copy memo ranked hasFixableRejection above isEmailBlocked
  while the button onClick ranked isEmailBlocked first — so with both rail
  states the card said 'Upload document' but opened the email sheet, and hid
  the document path. Reordered the memo (+ primaryRejectionMessage) to
  email-blocked → fixable → terminal, matching onClick and deriveGate.
- AddWithdrawCountriesList.handleFormSubmit: missing the provide-email branch
  that checkBridgeGate has, so a rail flipping to email-blocked between
  form-open and submit opened the contact-support KYC modal instead of the
  email sheet — the exact self-serve→support-ticket regression #2342 fixes.
  Added the branch; regression test pins provide-email → sheet, not modal.

Follow-up (not blocking): ActivationCTAs re-implements gate ordering inline;
it should consume deriveGate directly so consumers can't drift again.

Full suite 1675 green; typecheck clean.
…onsistency

fix(kyc): route email-blocked gates to the self-serve email sheet consistently (final /code-review)
@Hugo0 Hugo0 merged commit adb82bb into main Jul 3, 2026
20 of 24 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