Skip to content

fix: Phantom in-app browser race condition + CheckoutMode improvements#55

Merged
akbarsaputrait merged 5 commits into
masterfrom
fix/phantom-inapp-browser-race-condition
Jul 22, 2026
Merged

fix: Phantom in-app browser race condition + CheckoutMode improvements#55
akbarsaputrait merged 5 commits into
masterfrom
fix/phantom-inapp-browser-race-condition

Conversation

@akbarsaputrait

Copy link
Copy Markdown
Member

Summary

Fixes wallet auto-connect race condition in Phantom in-app browser and adds CheckoutMode quality-of-life features.

Changes

1. Fix: Phantom in-app browser race condition (RozoPayModal/index.tsx)

  • Solana auto-connects via wallet-standard while force EVM connect fires async, causing premature navigation to SELECT_TOKEN before EVM settles
  • Added didForceEvmConnectRef guard: blocks auto-navigate until forced EVM connect resolves
  • Added 10s safety timeout to prevent user being stuck on SELECT_METHOD if EVM connect never resolves (e.g. user rejection)
  • Result: Phantom in-app browser now correctly shows SELECT_METHOD with both chain tiles when both wallets connect

2. feat: ?paymentId query param (CheckoutMode.tsx)

  • Reads ?paymentId=XXX from URL, sets paymentId, cleans URL via replaceState
  • Auto-opens RozoPay modal after short mount delay

3. feat: Wallet deeplink logos (CheckoutMode.tsx)

  • Shows MetaMask, Phantom, Trust, Coinbase, OKX wallet icons below payment ID
  • Each icon links to the wallet's deeplink with the checkout URL (/checkout?paymentId=XXX)
  • Uses @web3icons/react branded icons

4. Version bump

  • @rozoai/intent-pay: 0.1.38-beta.30.1.38-beta.4

In Phantom's in-app browser, Solana auto-connects via wallet-standard
while force EVM connect fires simultaneously. The auto-navigate effect
was running before EVM connected, causing premature navigation to
SELECT_TOKEN (Solana-only view) before both chains settled.

Added a guard: if force EVM connect is pending and EVM isn't connected yet,
return early to wait. Added a 10s safety timeout to clear the flag if
EVM never connects (user rejection fallback).
When URL contains ?paymentId=xxx, the component:
- Reads payment ID from URL on mount
- Sets it as the payment ID
- Auto-opens the PayModal
- Cleans up URL to prevent re-triggering on refresh

Also bumps version to 0.1.38-beta.4
@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
intent-example Ready Ready Preview, Comment Jul 20, 2026 3:27pm

Request Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ec72f600f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/connectkit/src/components/RozoPayModal/index.tsx Outdated
Comment thread examples/nextjs-app/components/CheckoutMode.tsx Outdated

@shawnmuggle shawnmuggle left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approved — no P0/P1.

Core fix is correct: the didForceEvmConnect && !isEthConnected guard plus the ethStatus/isSolanaConnecting settling checks properly block the premature jump to SELECT_TOKEN in the Phantom in-app browser, and the 10s safety timeout prevents a stuck SELECT_METHOD on user rejection. The useRef→useState migration is the right call so dependent effects re-trigger.

Non-blocking notes:

  • didForceEvmConnect is intentionally omitted from the force-connect effect's deps (only added to the auto-navigate effect) to avoid clearing the 10s timer early — correct but subtle; a one-line comment would help future readers.
  • showRef.current = show is assigned during render; works, mildly against React guidance, fine for an example app.
  • Wallet deeplinks are hardcoded for the demo — fine.

@akbarsaputrait
akbarsaputrait merged commit 9ccbcfe into master Jul 22, 2026
4 of 5 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.

2 participants