Skip to content

fix(native): OTA beta switch off PostHog, Peanut-only receive, claim settles on CLAIMED - #2955

Closed
innolope-dev wants to merge 3 commits into
devfrom
claude/peanut-connectivity-sentry-ychf0b
Closed

fix(native): OTA beta switch off PostHog, Peanut-only receive, claim settles on CLAIMED#2955
innolope-dev wants to merge 3 commits into
devfrom
claude/peanut-connectivity-sentry-ychf0b

Conversation

@innolope-dev

Copy link
Copy Markdown
Collaborator

Why

Three fixes found while investigating native "trouble reaching Peanut" reports.

  1. OTA beta switch never appeared. The five-tap beta switch was gated on a beta-ota-channel PostHog flag that was never created, so isFeatureEnabled returned false on every prod device — the switch stayed hidden and no device could self-assign to the Capgo staging channel.
  2. Receive screen offered non-Peanut rails. The claim/receive screen showed bank / mercadopago / pix / exchange-wallet options beside the Peanut button.
  3. Claim screen stuck on "Processing". A user got the "claimed" push notification while the screen kept spinning: the backend marks the SendLink CLAIMED and sends the notification before the on-chain claim.txHash projects, but the UI only settled once the poll observed that hash.

What

1. OTA beta switch without the cohort (875d231b)

  • Drop the beta-ota-channel flag gate. Five taps now reveals the switch on any native build.
  • The off switch stays reachable, so a device on staging can always return to the store bundle.
  • Remove the now-dead notEnabled toast and its locale strings.

2. Peanut-only receive screen (ae8b6838)

  • Hide the alternate claim rails so the only receive option is Peanut, for logged-in and guest users.
  • Rail code is kept intact behind a SHOW_ALT_RAILS flag (mirrors the file's SHOW_INVITE_MODAL_FOR_DEVCONNECT pattern) — one-line re-enable. Rail-specific tests are describe.skip'd, not deleted.
  • Guest "Continue with Peanut" button and the devconnect event flow are untouched.

3. Settle the claim screen on CLAIMED (de1aa6f0)

  • Treat status === CLAIMED as terminal success — the same point the backend marks the claim done and notifies — with or without the txHash.
  • The poll reports the hash when present, null when it has yet to project; the success view tracks a claimConfirmed flag instead of gating on the hash. FAILED/CANCELLED and the give-up fallback are unchanged.

Tests

  • useClaimSuccessPolling: updated the CLAIMED-without-hash case to settle instead of poll on; other cadence/failure/ceiling tests unchanged.
  • SuccessClaimLinkView: added a case for CLAIMED-without-hash rendering the success card.
  • BetaUpdatesCard / About.view: dropped the cohort cases.
  • Local gate: prettier clean, changed files typecheck-clean, affected suites pass.

Notes / risks

  • Money surface. Fetch Chain details from SDK #2 removes bank/mercadopago/exchange as claim destinations from this screen (kept reversible behind the flag). hotfix: sdk version update #3 changes when a claim reads as "success" — verified against peanut-api-ts: SendLink.status is set to CLAIMED and processPostClaim (which sends the push) run together, after the claim tx is handled; the failure path writes FAILED via rollbackClaimOnError.
  • The claimed push is sent to the sender; the claimer's screen now settles on the same CLAIMED moment, so both track one signal.
  • Follow-up for backend (not in this PR): processPostClaim awaits the receipt but does not flip FAILED on a revert, so a revert-after-CLAIMED would show success in both the notification and now the UI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Fe2ritzXbCgcxnWLLdJyfg


Generated by Claude Code

The five-tap beta switch was gated on a `beta-ota-channel` PostHog flag
that was never created, so `isFeatureEnabled` returned false on every prod
device and the switch never appeared — the toast said "Beta updates aren't
enabled for this device" and no device could self-assign to the Capgo
`staging` channel.

The tap gesture already keeps the control off customer devices, and Capgo's
own self-assignment setting is the real access boundary, so the cohort added
nothing but a missing setup step. Drop the flag: five taps now reveals the
switch on any native build. The off switch stays reachable, so a device on
staging can always return to the store bundle.

Remove the now-dead notEnabled toast and its locale strings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fe2ritzXbCgcxnWLLdJyfg
The claim/receive screen offered alternate rails (bank, mercadopago, pix,
exchange/wallet) beside the Peanut button. Hide them so the only way to
receive is on Peanut, matching the app-first direction.

The rail code stays intact behind a SHOW_ALT_RAILS flag (mirrors the file's
existing SHOW_INVITE_MODAL_FOR_DEVCONNECT pattern), so it is a one-line
re-enable. The rail-specific tests are skipped for the same reason, not
deleted. The guest "Continue with Peanut" button and the devconnect event
flow are untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fe2ritzXbCgcxnWLLdJyfg
… txHash

The claim success screen stayed on "Processing" until the poll observed the
on-chain claim txHash, but the backend marks the SendLink CLAIMED and sends
the "claimed" notification before that hash projects (and, on native, the
poll GET is often slow to arrive). So a user could get the success push while
the screen kept spinning.

Settle on the same signal that fires the notification: treat CLAIMED as
terminal success, with or without the txHash. The poll reports the hash when
it is already there and null when it has yet to project; the view tracks a
`claimConfirmed` flag instead of gating success on the hash. FAILED/CANCELLED
and the give-up fallback are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fe2ritzXbCgcxnWLLdJyfg
@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
peanut-wallet Ready Ready Preview Sep 3, 2026 5:23pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: bec6a695-35ca-4235-a2b6-1d5143a0ef48

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 7062.75 → 7062.66 (-0.09)
Findings: +1 net (+21 new, -20 resolved)

🆕 New findings (21)

  • critical complexity — src/components/Claim/Link/SendLinkActionList.tsx — CC 69, MI 55.07, SLOC 219
  • high complexity — src/components/Claim/Link/Onchain/Success.view.tsx — CC 38, MI 59.82, SLOC 160
  • medium high-mdd — src/components/Claim/Link/SendLinkActionList.tsx:73 — SendLinkActionList: MDD 105.9 (uses across many lines from declarations)
  • medium high-mdd — src/components/Claim/Link/Onchain/Success.view.tsx:32 — SuccessClaimLinkView: MDD 79.7 (uses across many lines from declarations)
  • medium high-dlt — src/components/Claim/Link/SendLinkActionList.tsx:73 — SendLinkActionList: DLT 49 (calls 49 distinct functions — high context load)
  • medium high-dlt — src/components/Claim/Link/Onchain/Success.view.tsx:32 — SuccessClaimLinkView: DLT 38 (calls 38 distinct functions — high context load)
  • medium high-mdd — src/components/Profile/components/BetaUpdatesCard.tsx:37 — BetaUpdatesCard: MDD 33.0 (uses across many lines from declarations)
  • medium high-mdd — src/components/Profile/views/About.view.tsx:21 — AboutView: MDD 28.6 (uses across many lines from declarations)
  • medium complexity — src/components/Claim/Link/Onchain/useClaimSuccessPolling.ts — CC 22, MI 60.05, SLOC 65
  • medium complexity — src/components/Profile/components/BetaUpdatesCard.tsx — CC 18, MI 56.64, SLOC 88
  • medium method-complexity — src/components/Claim/Link/Onchain/Success.view.tsx:32 — CC 15 SLOC 98
  • medium complexity — src/components/Profile/views/About.view.tsx — CC 13, MI 62.34, SLOC 62
  • low high-mdd — src/components/Claim/Link/Onchain/useClaimSuccessPolling.ts:47 — useClaimSuccessPolling: MDD 17.4 (uses across many lines from declarations)
  • low high-dlt — src/components/Claim/Link/SendLinkActionList.tsx:137 — handleMethodClick: DLT 16 (calls 16 distinct functions — high context load)
  • low high-dlt — src/components/Profile/views/About.view.tsx:21 — AboutView: DLT 16 (calls 16 distinct functions — high context load)
  • low high-mdd — src/components/Claim/Link/SendLinkActionList.tsx:137 — handleMethodClick: MDD 13.1 (uses across many lines from declarations)
  • low high-mdd — src/components/Claim/Link/SendLinkActionList.tsx:356 — MethodCard: MDD 12.3 (uses across many lines from declarations)
  • low high-mdd — src/components/Claim/Link/SendLinkActionList.tsx:286 — : MDD 11.2 (uses across many lines from declarations)
  • low structural-dup — components/Claim/Link/Initial.view.tsx:882 — 6 duplicate lines / 54 tokens with components/Claim/Link/SendLinkActionList.tsx:265
  • low missing-return-type — src/components/Claim/Link/SendLinkActionList.tsx:73 — SendLinkActionList: exported fn missing return type annotation

…and 1 more.

✅ Resolved (20)

  • src/components/Claim/Link/SendLinkActionList.tsx — CC 67, MI 55.15, SLOC 218
  • src/components/Claim/Link/Onchain/Success.view.tsx — CC 36, MI 60.24, SLOC 155
  • src/components/Claim/Link/SendLinkActionList.tsx:67 — SendLinkActionList: MDD 105.1 (uses across many lines from declarations)
  • src/components/Claim/Link/Onchain/Success.view.tsx:32 — SuccessClaimLinkView: MDD 76.4 (uses across many lines from declarations)
  • src/components/Claim/Link/SendLinkActionList.tsx:67 — SendLinkActionList: DLT 49 (calls 49 distinct functions — high context load)
  • src/components/Claim/Link/Onchain/Success.view.tsx:32 — SuccessClaimLinkView: DLT 37 (calls 37 distinct functions — high context load)
  • src/components/Profile/components/BetaUpdatesCard.tsx:41 — BetaUpdatesCard: MDD 36.1 (uses across many lines from declarations)
  • src/components/Profile/views/About.view.tsx:21 — AboutView: MDD 27.8 (uses across many lines from declarations)
  • src/components/Profile/components/BetaUpdatesCard.tsx — CC 24, MI 54.5, SLOC 101
  • src/components/Claim/Link/Onchain/useClaimSuccessPolling.ts — CC 20, MI 60.3, SLOC 65
  • src/components/Profile/views/About.view.tsx — CC 14, MI 61.58, SLOC 66
  • src/components/Claim/Link/Onchain/useClaimSuccessPolling.ts:43 — useClaimSuccessPolling: MDD 17.0 (uses across many lines from declarations)
  • src/components/Profile/views/About.view.tsx:21 — AboutView: DLT 17 (calls 17 distinct functions — high context load)
  • src/components/Claim/Link/SendLinkActionList.tsx:131 — handleMethodClick: DLT 16 (calls 16 distinct functions — high context load)
  • src/components/Claim/Link/SendLinkActionList.tsx:131 — handleMethodClick: MDD 13.1 (uses across many lines from declarations)
  • src/components/Claim/Link/SendLinkActionList.tsx:346 — MethodCard: MDD 12.3 (uses across many lines from declarations)
  • src/components/Claim/Link/SendLinkActionList.tsx:278 — : MDD 11.2 (uses across many lines from declarations)
  • components/Claim/Link/Initial.view.tsx:882 — 6 duplicate lines / 54 tokens with components/Claim/Link/SendLinkActionList.tsx:259
  • src/components/Claim/Link/SendLinkActionList.tsx:67 — SendLinkActionList: exported fn missing return type annotation
  • src/components/Profile/components/BetaUpdatesCard.tsx:41 — BetaUpdatesCard: exported fn missing return type annotation

📈 Painscore deltas (top movers)

File Before After Δ
src/components/Profile/components/BetaUpdatesCard.tsx 8.2 7.5 -0.6

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 5608 ran, 0 failed, 0 skipped, 1.7m

📊 Coverage (unit)

metric %
statements 73.8%
branches 59.0%
functions 67.3%
lines 74.7%
⏱ 10 slowest test cases
time test
🐢 9.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Network failure keeps loading while retries remain, then shows the generic error
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_VOLUME_NEAR_CAP fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › routes the KYC rejection on its wire code, and does not retry it
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_SOURCE_OVER_MONTHLY_CAP fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › User KYC not approved fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_RECENT_REFUND fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_USER_NOT_PROVISIONED fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › a refused idempotency key tells the user to scan again, not to contact support
3.3s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
3.1s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Going offline blames the connection, and reconnecting clears it for the recovered scan
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🖼 Visual diff — no screen moved

62 shots, all identical. baseline 367da93 → head de1aa6f.

job summary

Fixture screenshots, no backend. Advisory — this check never blocks a merge. Posted from the default branch by ds-shots-comment.yml; the report it renders is untrusted data.

@innolope-dev

Copy link
Copy Markdown
Collaborator Author

Superseded by #2956 — same three commits, re-authored locally under my git identity with signed commits (cloud sessions hardcode the author to Claude, which this repo's CLAUDE.md forbids). Tree is byte-identical.

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.

2 participants