Fix - stabilize wallet auto-connect → token selection with readiness gate#44
Fix - stabilize wallet auto-connect → token selection with readiness gate#44akbarsaputrait wants to merge 11 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 833a9294d4
ℹ️ 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".
| if (!anyWalletConnected) { | ||
| gateState = "pass"; // gate inert — caller renders tiles as before | ||
| } else if (walletSettling || orderPending) { |
There was a problem hiding this comment.
Wait while wallets are still reconnecting
In the reconnect/autoConnect window (ethStatus is connecting/reconnecting or isSolanaConnecting is true), wagmi/Solana can still report connected=false, so this branch returns pass before walletSettling is considered. Since SelectMethod only hides the tiles for waiting, wallet in-app browsers still show the method tiles during the exact settling window this gate is intended to cover; check walletSettling before the no-wallet pass branch, or include settling in waiting.
Useful? React with 👍 / 👎.
shawnmuggle
left a comment
There was a problem hiding this comment.
LGTM — no P0/P1 blockers. Two-pass review (local deep review + codex second opinion).
Scope note: the PR body describes only the useAutoConnectGate readiness gate, but this PR also adds the WaitingDepositAddress Pusher→polling 60s payin fallback (new usePayinPolling hook). Worth adding to the description for future auditability.
Verified OK: payin fallback run-once guard / double-unsubscribe idempotency / polling cleanup are all correct — no leak, no duplicate polling; order === error routes to ERROR (not treated as ready); solana/stellarPaymentEligible dropping the order gate is semantically safe (SELECT_TOKEN has its own loading state).
P2 (non-blocking, follow-up):
useAutoConnectGate— during the wallet reconnect window (connecting/reconnectingbutconnectedstill false),anyWalletConnectedis false →gateState="pass"→ SelectMethod briefly shows tiles instead of the spinner. Not a regression (original code flashed tiles here too; this PR improved the "connected-but-order-pending" window). Could hoistwalletSettlingabove theanyWalletConnectedcheck to close it fully.orderReadygates onpaymentState !== idle/errorrather than the stricterpay.order != null; a theoretical "non-idle but order undefined" state would navigate. Practically unreachable and SELECT_TOKEN only shows loading, doesn't crash.
Problem
In wallet in-app browsers (Phantom, Base App, MetaMask mobile), opening the pay modal with a wallet already connected was flaky — flashed or got stuck on
SELECT_METHODinstead of auto-navigating toSELECT_TOKEN, forcing users to "refresh a few times."Root cause: the modal's auto-navigate effect raced three async signals (wagmi reconnect, Solana autoConnect, async
createPreviewOrder()). The EVM branch gated only on connection (stable); the Solana/Stellar branches also requiredpay.order != null(flaky). An errored preview order could also pass!= nulland reach a broken token screen.Fix
A narrow readiness gate on the auto-connect path. It blocks navigation on two cheap, critical signals — wallet settled + order resolved (from FSM state, not
!= null) — while balances keep loading progressively inSELECT_TOKEN.useAutoConnectGate— composes wallet-connection status + FSM state intogateState: "pass" | "waiting" | "ready" | "error"."waiting", routes to the Error page on"error"(new safety), navigates on"ready", leaves tiles on"pass"(no wallet).SelectMethod— shows the existing spinner while"waiting"(no tile flash).idle, non-errorFSM state → coversunhydrated(publicsetPayIdresume path) andpayout_completed; unknown states degrade to tiles, never hang.The tiles keep their existing
showSolana/StellarPaymentMethodorder gate (tapping a tile starts a payment, so it still needs an order); only the auto-navigate path uses the order-independent eligibility.