chore(runway): cherry-pick fix(predict): prevent token selector from using stale approvals from other flows cp-7.73.0#28699
Merged
chloeYue merged 1 commit intorelease/7.73.0from Apr 13, 2026
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 -->
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. |
chloeYue
approved these changes
Apr 13, 2026
Contributor
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - skip-smart-e2e-selection label found All E2E tests pre-selected. |
|
Contributor
|
@metamaskbot update-mobile-fixture |
Contributor
|
✅ E2E Fixture Validation — Schema is up to date |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



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.