Skip to content

feat(predict): add buy with any token flow#27369

Merged
caieu merged 13 commits into
mainfrom
predict/mmpay-predict-core
Mar 13, 2026
Merged

feat(predict): add buy with any token flow#27369
caieu merged 13 commits into
mainfrom
predict/mmpay-predict-core

Conversation

@caieu

@caieu caieu commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

Add PredictBuyWithAnyToken view, components, and hooks for the pay-with-any-token order flow. Includes PredictController, payment token selection, fee summary, order tracking, navigation, active order management, feature flag selectors, and full test coverage.

Description

Adds the "Buy With Any Token" flow to prediction markets, enabling users to place bets using any token in their wallet (not just their predict balance). When a user doesn't have sufficient USDC.e balance on Polygon, this flow handles the deposit + order as a single transaction batch through the confirmations framework.

This is PR 1 of 2 — contains only @MetaMask/predict-owned code. A follow-up PR will add the confirmations integration (registering the new predictDepositAndOrder transaction type, pay-with-modal changes, and navigation support).

What's included

New view — PredictBuyWithAnyToken
Full buy preview screen with amount input, fee summary, action button, and payment token selection. Renders both standalone (predict routes) and within confirmations (as info-root content).

PredictController state extensions

  • activeOrder — tracks order lifecycle (preview → confirming → success/error)
  • selectedPaymentToken — stores the user's chosen payment token

New hooks (13)

Hook Purpose
usePredictActiveOrder Manages active order state in controller
usePredictNavigation Navigation helpers with replace support
usePredictPayWithAnyToken Triggers deposit+order confirmation flow
usePredictPaymentToken Handles payment token selection changes
usePredictBalanceTokenFilter Filters available tokens for predict context
usePredictBuyPreviewActions Orchestrates confirm/back/error handlers
usePredictBuyConditions Derives UI state (canPlaceBet, isBelowMinimum)
usePredictBuyInfo Computes fees, total, toWin from preview
usePredictBuyInputState Manages amount input + focus state
usePredictBuyAvailableBalance Calculates available balance
usePredictBuyBackSwipe Back gesture handler
usePredictOrderTracking Tracks order result (success/error)
usePredictPayWithAnyTokenTracking Tracks deposit confirmation lifecycle

New components (8): PredictBuyActionButton, PredictBuyAmountSection, PredictBuyBottomContent, PredictBuyMinimumError, PredictBuyPreviewHeader, PredictFeeSummary, PredictPayWithRow, PredictPayWithAnyTokenInfo

Feature flag selectors: selectPredictFakOrdersEnabledFlag, selectPredictWithAnyTokenEnabledFlag — gated behind remote predictWithAnyToken flag.

Other changes:

  • Routes updated with new navigation stack entries
  • Analytics helpers for parsing order event properties
  • Transaction constants (chain ID, placeholder address, minimum bet)

Changelog

CHANGELOG entry: null

Related issues

Fixes:

Manual testing steps

Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]

Screenshots/Recordings

Before

After

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

High Risk
Adds a new deposit+order transaction-batching path (payWithAnyTokenConfirmation) and new controller state for active orders/payment-token selection, which affects confirmation routing and transaction submission. Although gated by a remote flag, mistakes could break Predict order placement/deposit flows or create incorrect confirmation behavior.

Overview
Introduces a new Buy With Any Token Predict buy-preview flow, gated by the remote predictWithAnyToken flag, and wires Predict routing to swap BUY_PREVIEW between the legacy screen and the new PredictBuyWithAnyToken view.

Extends PredictController with ephemeral activeOrder and selectedPaymentToken state plus setters, and adds payWithAnyTokenConfirmation() to submit a deposit transaction batch that re-tags predictDeposit txs as predictDepositAndOrder to drive a new confirmation/info experience.

Adds supporting hooks/utilities for navigation (usePredictNavigation), active order and token selection (usePredictActiveOrder, usePredictPaymentToken, usePredictBalanceTokenFilter), order preview initialization (initialPreview), and shared error/toast + analytics helpers; updates buy UI components to reflect the new fee summary/deposit-fee row and improved deposit-in-progress handling. Test coverage is expanded broadly across the new hooks, selectors, navigation, and controller behavior.

Written by Cursor Bugbot for commit 7f6706f. This will update automatically on new commits. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-predict Predict team label Mar 11, 2026
@caieu caieu force-pushed the predict/mmpay-predict-core branch 2 times, most recently from 1d347db to 045750d Compare March 11, 2026 16:45
@caieu caieu marked this pull request as ready for review March 12, 2026 10:22
@caieu caieu requested a review from a team as a code owner March 12, 2026 10:22
Comment thread app/components/UI/Predict/hooks/usePredictOrderPreview.ts Outdated
Comment thread app/components/UI/Predict/hooks/usePredictPayWithAnyToken.ts
isShowingToWinSkeleton,
}: PredictBuyAmountSectionProps) => {
const tw = useTailwind();
const pulseAnim = useRef(new Animated.Value(1)).current;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not Reanimated?

import type { PredictMarket, PredictOutcomeToken } from '../types';
import type { PredictEntryPoint } from '../types/navigation';

export function parseAnalyticsProperties(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe rename to parsePredictBuyAnalyticsProperties

caieu added 11 commits March 12, 2026 16:32
Add PredictBuyWithAnyToken view, components, and hooks for the
pay-with-any-token order flow. Includes PredictController,
payment token selection, fee summary, order tracking, navigation,
active order management, feature flag selectors, and full test coverage.
@caieu caieu force-pushed the predict/mmpay-predict-core branch from e3de0fe to 28ae0b0 Compare March 12, 2026 19:32
matallui
matallui previously approved these changes Mar 12, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

return {
success: true,
response: { batchId: PREDICTION_ERROR_TRANSACTION_BATCH_ID },
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

User denial returns success instead of indicating cancellation

High Severity

When a user denies the transaction signature in payWithAnyTokenConfirmation, the catch block returns { success: true, response: { batchId: PREDICTION_ERROR_TRANSACTION_BATCH_ID } }. Returning success: true for a user cancellation is misleading — callers treating the result as a successful submission will proceed with order tracking and UI updates for a transaction that never happened. The batchId is set to 'NA', which downstream code may try to track or poll.

Fix in Cursor Fix in Web

marketType:
market?.outcomes?.length === 1
? PredictEventValues.MARKET_TYPE.BINARY
: PredictEventValues.MARKET_TYPE.MULTI_OUTCOME,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Market type detection incorrect for binary markets

Medium Severity

The marketType detection uses market?.outcomes?.length === 1 to determine a BINARY market, but binary markets typically have 2 outcomes (Yes/No). A market with exactly 1 outcome is unusual, while a market with 2 outcomes is the standard binary case. Markets with 3+ outcomes are multi-outcome. When market is undefined, the expression evaluates to undefined === 1 which is false, so it defaults to MULTI_OUTCOME — also potentially wrong for the undefined case.

Fix in Cursor Fix in Web

}
},
[payWithAnyTokenConfirmation, handleDepositError, navigateToConfirmation],
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

triggerPayWithAnyToken ignores its params argument entirely

Medium Severity

The triggerPayWithAnyToken callback's parameter list is commented out (//(params: PredictPayWithAnyTokenParams) => {) and replaced with () => {. Callers pass { market, outcome, outcomeToken } arguments but they are silently ignored. The route params (market, outcome, outcomeToken, preview) in the commented-out navigateToConfirmation block are also never passed. While marked with a TODO, this means the confirmation screen receives no context about which market/outcome the user is betting on.

Fix in Cursor Fix in Web

preview,
placeOrder,
depositAmount: total - depositFee,
setIsConfirming,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

depositAmount calculation may subtract wrong fee component

Medium Severity

The depositAmount is computed as total - depositFee and passed to both usePredictBuyActions (line 158) and PredictPayWithAnyTokenInfo (line 327). If depositFee is undefined (which is possible since usePredictBuyInfo may return it as optional), then total - undefined evaluates to NaN, which would propagate as NaN through the deposit flow and potentially cause incorrect transaction amounts or UI display issues.

Additional Locations (1)
Fix in Cursor Fix in Web

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePredictions, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePredict
  • Risk Level: high
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR heavily modifies the Predict (Polymarket) feature across UI components, hooks, selectors, analytics, and introduces changes to the Engine-level predict-controller (app/core/Engine/controllers/predict-controller). This directly impacts the full prediction lifecycle (open position, preview, deposit, claim, balance sync) which is covered by SmokePredictions.

Because Predictions is embedded within the Trending tab and affects shared wallet activity/history display, SmokeWalletPlatform must also run.

Prediction flows involve on-chain transactions (opening positions, deposits, claims), so SmokeConfirmations is required to validate the confirmation UI and transaction handling integration.

No other domains (accounts, networks, snaps, perps, ramps, multi-chain API) were modified.

Given the Engine controller changes and broad UI/hook refactors, this is high risk within the Predictions vertical and requires full validation of that flow and its wallet integrations.

Performance Test Selection:
Extensive changes to Predict views, hooks (order preview, balance filtering, payment token logic), and controller logic may impact market list loading, deposit flow responsiveness, and balance updates. Running @PerformancePredict ensures no regressions in prediction market loading and transaction-related performance.

View GitHub Actions results

@github-actions

Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
16 value mismatches detected (expected — fixture represents an existing user).
View details

@sonarqubecloud

Copy link
Copy Markdown

@caieu caieu enabled auto-merge March 12, 2026 23:57
@caieu caieu added this pull request to the merge queue Mar 13, 2026
Merged via the queue into main with commit 4d0ffbe Mar 13, 2026
176 of 179 checks passed
@caieu caieu deleted the predict/mmpay-predict-core branch March 13, 2026 00:21
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 13, 2026
@metamaskbot metamaskbot added the release-7.71.0 Issue or pull request that will be included in release 7.71.0 label Mar 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.71.0 Issue or pull request that will be included in release 7.71.0 size-XL team-predict Predict team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants