Skip to content

feat: removes provider and token persistence in ramps controller#8307

Merged
georgeweiler merged 2 commits into
mainfrom
provider-persist
Mar 25, 2026
Merged

feat: removes provider and token persistence in ramps controller#8307
georgeweiler merged 2 commits into
mainfrom
provider-persist

Conversation

@georgeweiler

@georgeweiler georgeweiler commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Explanation

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Medium risk because it changes controller state persistence/hydration behavior, which could affect startup UX and any consumers expecting providers/tokens to survive across sessions.

Overview
Stops persisting RampsController providers and tokens state (metadata persist: false) so these resources are refetched instead of being restored from disk.

Updates RampsController tests and snapshots to no longer expect persisted providers/tokens, and adjusts init/region-change test cases to assert refetching/reset behavior. Adds a changelog entry describing the persistence change.

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

@georgeweiler georgeweiler requested review from a team as code owners March 25, 2026 21:12
Update changelog to reflect changes in provider state persistence and API handling.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 1 potential issue.

Fix All in Cursor

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

},
providers: {
persist: true,
persist: false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Persisted providerAutoSelected inconsistent with non-persisted providers.selected

Low Severity

providerAutoSelected still has persist: true while providers (including providers.selected) now has persist: false. After a session restart, providerAutoSelected may remain true from the previous session while providers.selected resets to null. Since resetDependentResources (which clears providerAutoSelected) is only called when the region changes, not when the same region is restored after restart, this stale flag persists until setSelectedProvider is explicitly called again. The flag and the selection it describes are now out of sync across restarts.

Additional Locations (1)
Fix in Cursor Fix in Web

@georgeweiler georgeweiler added this pull request to the merge queue Mar 25, 2026
Merged via the queue into main with commit 765739b Mar 25, 2026
326 checks passed
@georgeweiler georgeweiler deleted the provider-persist branch March 25, 2026 21:40
github-merge-queue Bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request Mar 27, 2026
…t by token support (#27958)

<!--
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**

Fixed a bug where selecting a provider for some token (e.g. MUSD on
Linea) would instantly show "No payment methods are available" because
the provider's cached `supportedCryptoCurrencies` map was stale and
didn't include the token.

**Root cause:** The providers data (`supportedCryptoCurrencies`) was
persisted across sessions and only refreshed on region change or fresh
install. For tokens added to the backend after the user's last provider
cache update, the map wouldn't include the token, causing the payment
methods query to be disabled and the "Token Not Available" modal to show
— even though the API supports it.

**Evidence from reporter's state logs (v7.71.0 build 4173):**
- MUSD Linea
(`eip155:59144/erc20:0xaca92e438df0b2401ff60da7e4337b687a2435da`) was
`NOT IN MAP` for all 11 providers
- Fresh `/providers` endpoint already includes MUSD Linea for Transak
and Mercuryo
- Providers data was served from stale Redux persist cache

**Fix:**
1. `queries/providers.ts` + `useRampsProviders`: added a react-query
wrapper for `getProviders` with `staleTime: 15min` and `refetchOnMount:
true`. Providers (including `supportedCryptoCurrencies`) are refreshed
when data is stale (>15min) and a component using `useRampsProviders`
mounts (e.g. after password unlock or entering the buy flow). On app
restart, react-query cache is empty so the first mount always fetches
fresh data. The query calls `getProviders(regionCode, { forceRefresh:
true })` to bypass the controller's internal cache.
2. `ProviderSelectionModal`: skip quotes fetch when
`selectedPaymentMethod` is null (prevents API error "Payment methods are
required"), and set `showQuotes=false` so no "No providers available"
error is shown
3. `ProviderSelection`: when quotes are not available, fall back to
separating providers by `supportedCryptoCurrencies` — supported tokens
on top, others under "Other options"

**Companion fix in core:** George's `feat: removes provider and token
persistence in ramps controller`
([#8307](MetaMask/core#8307)) sets `persist:
false` for providers and tokens so stale data won't survive across app
restarts. The react-query refresh complements this by also catching
stale data within long-running sessions.

## **Changelog**

CHANGELOG entry: Fixed payment methods and provider availability for
newly added tokens by refreshing providers via react-query (15min TTL)
on mount and separating the provider list by token support

## **Related issues**

Fixes:
[TRAM-3383](https://consensyssoftware.atlassian.net/browse/TRAM-3383)

## **Manual testing steps**

```gherkin
Feature: Payment methods load for tokens missing from supportedCryptoCurrencies

  Scenario: providers are refreshed when stale on mount
    Given the app has provider data older than 15 minutes
    When the user enters the buy flow or unlocks the app (component mounts)
    Then providers data should be refetched from the API via react-query
    And supportedCryptoCurrencies should be up to date

  Scenario: providers are always fresh after app restart
    Given the user restarts the app (react-query cache is empty)
    When the user enters the password and the app loads
    Then providers data should be fetched fresh from the API
    And supportedCryptoCurrencies should include newly added tokens

  Scenario: user opens change provider when no payment method is selected
    Given user is on the Buy screen with a provider that does not support the selected token
    And no payment method is selected (selectedPaymentMethod is null)

    When user taps "Change provider"
    Then the provider list should show supported providers at the top
    And unsupported providers should appear under "Other options" separator
    And no "No providers available" error should be shown
```

## **Screenshots/Recordings**

### **Before**



https://github.com/user-attachments/assets/0b4ea4fc-9a59-4fe6-a706-da95ec60c3af


### **After**

Payment methods query fires and returns results from the API.



https://github.com/user-attachments/assets/c3081ec5-63d8-460a-996e-3e8dabc90b7c



https://github.com/user-attachments/assets/0ebb7fdc-1d5f-40ce-82c8-4fa7f47ef90f



## **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**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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.







<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Medium risk due to new react-query-driven provider refetching and
conditional quote fetching logic that can change network request
patterns and provider ordering in the buy flow.
> 
> **Overview**
> Prevents stale `supportedCryptoCurrencies` from breaking buy flows by
adding a react-query `providers` query (15min `staleTime`,
`refetchOnMount`, `forceRefresh`) and wiring it into `useRampsProviders`
(triggered when `regionCode` is available).
> 
> Tightens “token unavailable” and provider selection behavior:
`BuildQuote` now treats missing entries in `supportedCryptoCurrencies`
as unsupported, `ProviderSelectionModal` skips quote fetching and
disables quote UI when `selectedPaymentMethod` is `null`, and
`ProviderSelection` groups providers into supported vs unsupported (with
an “Other options” separator) when quotes aren’t shown/available.
> 
> Adds/updates unit tests for the new query options, provider grouping,
quote-fetch gating, and the token-unavailable edge case.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
707342f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Pedro Pablo Aste Kompen <wachunei@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants