Overnight test v3 — PR #24615 CORE FLOW SOLID · USD · FEATURE-FLAGGED

refactor(mobile/staking): adopt money-mover UI on amount screens · github.com/phantom/wallet/pull/24615
Branch lisherwin/staking-money-mover-v2 onto main · head eafbacede2
iPhone 16e simulator (612F8686) · bundle app.phantom.debug
Run started 2026-05-22 21:53:34 UTC
Surfaces
3
Rendering (MM on)
3
Denomination
USD
Flag
enable-money-mover-staking

What this PR does

Replaces the three staking amount pages (native SOL stake, mint PSOL, unstake PSOL) with MoneyMoverProvider + MoneyMoverScreen from @phantom/money-mover-ui — same primitives Kristen uses in SendPage.tsx. User now types USD; useStakeAmountUsdBridge converts to SOL/PSOL via usePrice for submission. New UI sits behind enable-money-mover-staking (user-subject, dev-on / prod-off); legacy implementations are preserved as *Page.legacy.tsx siblings.

Findings

✓ Money-mover UI rendering on all 3 surfaces

Custom keypad (money-mover-key-1..9 .decimal .delete), percentage chips (money-mover-chip-Percentage-…) and pill CTA (money-mover-next) all reachable via GhostEye — same testIDs as Perps/Swap/Send v2.

✓ USD denomination + price conversion working

Native Stake: simulator's SOL balance 0.212199891 → "Balance: • $18.07" via usePrice. Tapping 50% → "$9.03" in USD, which maps to 0.106074621 SOL in the review row. Both sides of the bridge stay in sync.

✓ US/UK disclaimer plumbed

Simulator's locale resolves to non-UK so US text shows in mint review. useShowUKDisclaimer (existing) gates the FCA "high-risk investment" block + Gateway21 approval line for UK users.

Mint "100%" hits insufficient-balance

Tapping the 100% chip on mint uses the full SOL balance, but the staking validation reserves rent + fees, so we get "Insufficient balance" instead of the maximum stake. The Withdraw adapter uses a pre-computed "max sendable" cap; staking should mirror that — wire the existing maxAmount from useMintLiquidStakeAmountProps into the USD-bridge's balance so 100% lands on the safe max. Follow-up.

StakeAmountPage (native SOL stake) DONE

apps/mobile/src/pages/staking/native/StakeAmountPage.moneymover.tsx

Home → Solana → Start Earning → StakeAccountsList → + → Native Staking → Phantom Validator
Empty — "$0", "Balance: • $18.07" (USD), Phantom Validator payment row
Filled (50%) — "$9.03", Review CTA enabled
Review — "Review Stake" title, $9.03 amount, "0.106074621 SOL" in the review row

MintLiquidStakeAmountPage (mint PSOL) PARTIAL

apps/mobile/src/pages/staking/liquid/mint/MintLiquidStakeAmountPage.moneymover.tsx

… → StakingMethodSelection → Liquid Staking
Empty — "Stake SOL" title, "Phantom Staked SOL 6.16% APY" payment with info chevron
100% chip — full balance exceeds rent-protected max, surfaces "Insufficient balance" (see finding)
Mint Filled state with error retained

UnstakeLiquidStakeAmountPage (unstake PSOL) DONE

apps/mobile/src/pages/staking/liquid/unstake/UnstakeLiquidStakeAmountPage.moneymover.tsx

Deep link exp+phantom:///UnstakeLiquidStake
Empty / zero-balance — "$0", "PSOL balance: • $0.00", PSOL payment row, 25/50/100 chips

Feature-flag layout

apps/mobile/src/pages/staking/native/
├── StakeAmountPage.tsx            # entry — re-exports via useFeatureFlag("enable-money-mover-staking")
├── StakeAmountPage.moneymover.tsx # MoneyMoverProvider + adapter + usePrice bridge
└── StakeAmountPage.legacy.tsx     # restored from origin/main (PrimaryAmountInput + KeyboardAmount)

apps/mobile/src/pages/staking/liquid/mint/   (same shape)
apps/mobile/src/pages/staking/liquid/unstake/ (same shape)

packages/feature-flags/src/flags.ts
└── enable-money-mover-staking  defaultValue=false  devDefaultValue=true  subjectAssignment=user