chore(runway): cherry-pick fix(predict): prevent token selector from using stale approvals from other flows cp-7.73.0#28699
Conversation
…using stale approvals from other flows cp-7.73.0 (#28685) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> A user reported that the "Pay with" token selector on `PredictBuyWithAnyToken`wasn't allowing to select a different token. A transaction is needed to that work and the current logic could pick up pending approvals from unrelated flows (bridge, swap, send, etc.), allowing them to select tokens from the wrong transaction context. **Root cause:** `initPayWithAnyToken()` calls `addTransactionBatch()` directly without first rejecting existing pending approvals — unlike the standalone `predictDeposit` flow which goes through `useConfirmNavigation` and rejects all unapproved transactions before creating its own. When stale approvals existed, `useApprovalRequest()` returned the first (wrong) approval, and `PredictPayWithRow` enabled token selection based on a generic `transactionMeta` truthiness check. **Fix (defense-in-depth):** 1. **`usePredictBuyActions`** — added `rejectPendingTransactions()` in the `transitionEnd` handler before `initPayWithAnyToken()`, mirroring the cleanup pattern from `useConfirmNavigation`. 2. **`PredictPayWithRow`** — replaced the generic `transactionMeta` truthiness check with `hasTransactionType(transactionMeta, [TransactionType.predictDepositAndOrder])`, so the selector only enables for the correct transaction type. This branch also includes prior commits that handle no-quotes blocking alerts in the buy flow and disable the pay-with selector until transaction metadata is ready. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Predict buy-with-any-token token selector isolation Scenario: token selector stays disabled when a non-predict approval is pending Given user has an unconfirmed swap or bridge transaction pending And user navigates to a Predict market buy screen When the buy screen finishes loading Then the "Pay with" row does not show an arrow icon And tapping the "Pay with" row does not open the token selection modal Scenario: token selector enables after deposit-and-order batch is created Given user has no pending transactions And user navigates to a Predict market buy screen When the buy screen finishes loading and initPayWithAnyToken completes Then the "Pay with" row shows the arrow icon And tapping the "Pay with" row opens the token selection modal Scenario: stale approvals are rejected on buy screen entry Given user has an unconfirmed transaction from another flow And user navigates to a Predict market buy screen When the screen transition completes Then the stale unconfirmed transaction is rejected And a new deposit-and-order batch is created as the only pending approval ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches transaction/approval handling in the Predict buy flow by programmatically rejecting unapproved transactions and tightening when the pay-with selector is enabled; regressions could affect in-flight approvals or block token selection. > > **Overview** > Prevents the `PredictBuyWithAnyToken` pay-with token selector from latching onto stale approvals from other flows. > > On screen entry, `usePredictBuyActions` now rejects all `unapproved` transactions before calling `initPayWithAnyToken`, and `PredictPayWithRow` only enables navigation/UI affordances when the current `transactionMeta` is a `TransactionType.predictDepositAndOrder` (otherwise it disables press, hides the arrow, and removes the muted background). The buy flow also propagates *blocking* pay alerts (insufficient balance / no quotes) via `usePredictBuyInfo` into `usePredictBuyConditions` and `usePredictBuyError` to disable placing bets and surface the correct blocking message, with updated tests. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 69b5397. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
|
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. |
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
Tag selection rationale:
No other feature areas are impacted - changes are fully contained within the Predict UI components and their hooks. Performance Test Selection: |
|
|
✅ E2E Fixture Validation — Schema is up to date |



Description
A user reported that the "Pay with" token selector on
PredictBuyWithAnyTokenwasn't allowing to select a different token. Atransaction is needed to that work and the current logic could pick up
pending approvals from unrelated flows (bridge, swap, send, etc.),
allowing them to select tokens from the wrong transaction context.
Root cause:
initPayWithAnyToken()callsaddTransactionBatch()directly without first rejecting existing pending approvals — unlike the
standalone
predictDepositflow which goes throughuseConfirmNavigationand rejects all unapproved transactions beforecreating its own. When stale approvals existed,
useApprovalRequest()returned the first (wrong) approval, and
PredictPayWithRowenabledtoken selection based on a generic
transactionMetatruthiness check.Fix (defense-in-depth):
usePredictBuyActions— addedrejectPendingTransactions()inthe
transitionEndhandler beforeinitPayWithAnyToken(), mirroringthe cleanup pattern from
useConfirmNavigation.PredictPayWithRow— replaced the generictransactionMetatruthiness check with
hasTransactionType(transactionMeta, [TransactionType.predictDepositAndOrder]), so the selector only enablesfor the correct transaction type.
This branch also includes prior commits that handle no-quotes blocking
alerts in the buy flow and disable the pay-with selector until
transaction metadata is ready.
Changelog
CHANGELOG entry: null
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
N/A
After
N/A
Pre-merge author checklist
Docs and MetaMask Mobile
Coding
Standards.
if applicable
guidelines).
Not required for external contributors.
Pre-merge reviewer checklist
app, test code being changed).
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
Note
Medium Risk
Touches transaction/approval handling in the Predict buy flow by
programmatically rejecting unapproved transactions and tightening when
the pay-with selector is enabled; regressions could affect in-flight
approvals or block token selection.
Overview
Prevents the
PredictBuyWithAnyTokenpay-with token selector fromlatching onto stale approvals from other flows.
On screen entry,
usePredictBuyActionsnow rejects allunapprovedtransactions before calling
initPayWithAnyToken, andPredictPayWithRowonly enables navigation/UI affordances when thecurrent
transactionMetais aTransactionType.predictDepositAndOrder(otherwise it disables press, hides the arrow, and removes the muted
background). The buy flow also propagates blocking pay alerts
(insufficient balance / no quotes) via
usePredictBuyInfointousePredictBuyConditionsandusePredictBuyErrorto disable placingbets and surface the correct blocking message, with updated tests.
Reviewed by Cursor Bugbot for commit
69b5397. Bugbot is set up for automated
code reviews on this repo. Configure
here.