Skip to content

feat(ramps-controller): add setSelectedProviderForAsset controller method - #9759

Merged
saustrie-consensys merged 7 commits into
mainfrom
saustrie/ramps-controller-set-provider-for-asset
Aug 4, 2026
Merged

feat(ramps-controller): add setSelectedProviderForAsset controller method#9759
saustrie-consensys merged 7 commits into
mainfrom
saustrie/ramps-controller-set-provider-for-asset

Conversation

@saustrie-consensys

@saustrie-consensys saustrie-consensys commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Explanation

Currently, both UB2's BuildQuote (tier-1 silent-switch effect) and MMPay's useEnsureCompatibleProvider hook duplicate the same logic: call providerServesAsset on the selected provider, run providers.find to get a compatible alternative, and call setSelectedProvider. That logic belongs in the controller — it's a state operation, not a UI concern.

This PR adds setSelectedProviderForAsset(assetId, options?) to RampsController. When the currently selected provider does not serve the given CAIP-19 asset, it switches providers.selected to the first provider in providers.data that does, using the already-present providerServesAsset utility in providerAvailability.ts. Returns true if a switch was made, false otherwise. No-op when:

  • providers.data is empty (providers not yet loaded)
  • the currently selected provider already serves the asset
  • no alternative provider serves the asset (leaves current selection unchanged)

Registers as RampsController:setSelectedProviderForAsset via the existing MESSENGER_EXPOSED_METHODS mechanism. Action-types file regenerated via messenger-action-types:generate.

The mobile consumer PR (stacked on the preview build) will simplify useEnsureCompatibleProvider to delegate to this method and remove the duplicated find-and-switch from the UI layer.

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
Changes provider-selection behavior used in buy flows and alters providerServesAsset semantics, which may affect any code that depended on key-only matching.

Overview
Adds setSelectedProviderForAsset(assetId, options?) on RampsController (and RampsController:setSelectedProviderForAsset via messenger) so hosts can silently switch providers.selected to the first entry in providers.data that supports a CAIP-19 asset when the current selection does not. Compatibility uses the fresh provider row in providers.data when it differs from a stale providers.selected copy; it returns whether a switch happened and defaults autoSelected to true when forwarding to setSelectedProvider.

providerServesAsset now treats an asset as supported only when the supportedCryptoCurrencies map value is true, not merely when the key exists (fixes false positives for { assetId: false }).

Reviewed by Cursor Bugbot for commit aadc2e6. Bugbot is set up for automated code reviews on this repo. Configure here.

…thod

Adds setSelectedProviderForAsset(assetId, options?) to RampsController.
When the currently selected provider does not support the given CAIP-19
asset, the method switches providers.selected to the first provider in
providers.data that does, using the existing providerServesAsset utility.
Returns true if a switch was made, false otherwise (no-op when providers
are not loaded, the selected provider already supports the asset, or no
compatible alternative exists).

This moves the "silent provider switch on asset mismatch" logic from
duplicated UI-layer code (BuildQuote tier-1 effect, useEnsureCompatibleProvider)
into the controller, where it can be tested in isolation and called from
any surface without re-implementing providerServesAsset + find.

Registers as RampsController:setSelectedProviderForAsset messenger action.
Action-types file regenerated via messenger-action-types:generate.
@saustrie-consensys

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.5-preview-f21e1e0
@metamask-previews/accounts-controller@39.0.6-preview-f21e1e0
@metamask-previews/address-book-controller@7.1.2-preview-f21e1e0
@metamask-previews/ai-controllers@0.8.0-preview-f21e1e0
@metamask-previews/analytics-controller@2.0.0-preview-f21e1e0
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-f21e1e0
@metamask-previews/announcement-controller@8.1.0-preview-f21e1e0
@metamask-previews/app-metadata-controller@2.0.1-preview-f21e1e0
@metamask-previews/approval-controller@9.0.2-preview-f21e1e0
@metamask-previews/assets-controller@13.1.0-preview-f21e1e0
@metamask-previews/assets-controllers@110.1.0-preview-f21e1e0
@metamask-previews/authenticated-user-storage@3.0.1-preview-f21e1e0
@metamask-previews/base-controller@9.1.0-preview-f21e1e0
@metamask-previews/base-data-service@0.1.3-preview-f21e1e0
@metamask-previews/bitcoin-regtest-up@1.0.0-preview-f21e1e0
@metamask-previews/bridge-controller@78.0.3-preview-f21e1e0
@metamask-previews/bridge-status-controller@74.6.1-preview-f21e1e0
@metamask-previews/build-utils@3.0.4-preview-f21e1e0
@metamask-previews/chain-agnostic-permission@1.7.0-preview-f21e1e0
@metamask-previews/chomp-api-service@4.0.0-preview-f21e1e0
@metamask-previews/claims-controller@0.5.3-preview-f21e1e0
@metamask-previews/client-controller@1.0.1-preview-f21e1e0
@metamask-previews/client-utils@1.5.0-preview-f21e1e0
@metamask-previews/compliance-controller@2.1.0-preview-f21e1e0
@metamask-previews/composable-controller@12.0.1-preview-f21e1e0
@metamask-previews/config-registry-controller@2.0.0-preview-f21e1e0
@metamask-previews/connectivity-controller@0.3.0-preview-f21e1e0
@metamask-previews/controller-utils@12.3.0-preview-f21e1e0
@metamask-previews/core-backend@8.1.0-preview-f21e1e0
@metamask-previews/delegation-controller@3.0.2-preview-f21e1e0
@metamask-previews/earn-controller@12.2.3-preview-f21e1e0
@metamask-previews/eip-5792-middleware@3.0.5-preview-f21e1e0
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-f21e1e0
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-f21e1e0
@metamask-previews/ens-controller@19.1.6-preview-f21e1e0
@metamask-previews/eth-block-tracker@15.0.1-preview-f21e1e0
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-f21e1e0
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-f21e1e0
@metamask-previews/foundryup@1.0.1-preview-f21e1e0
@metamask-previews/gas-fee-controller@26.3.1-preview-f21e1e0
@metamask-previews/gator-permissions-controller@5.0.1-preview-f21e1e0
@metamask-previews/geolocation-controller@1.0.0-preview-f21e1e0
@metamask-previews/java-tron-up@1.0.0-preview-f21e1e0
@metamask-previews/json-rpc-engine@10.5.0-preview-f21e1e0
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-f21e1e0
@metamask-previews/keyring-controller@27.1.0-preview-f21e1e0
@metamask-previews/local-node-utils@1.0.0-preview-f21e1e0
@metamask-previews/logging-controller@8.0.2-preview-f21e1e0
@metamask-previews/message-manager@14.1.2-preview-f21e1e0
@metamask-previews/messenger@2.0.0-preview-f21e1e0
@metamask-previews/messenger-cli@0.2.0-preview-f21e1e0
@metamask-previews/money-account-api-data-service@0.4.0-preview-f21e1e0
@metamask-previews/money-account-balance-service@2.4.1-preview-f21e1e0
@metamask-previews/money-account-controller@0.3.3-preview-f21e1e0
@metamask-previews/money-account-upgrade-controller@3.0.1-preview-f21e1e0
@metamask-previews/money-account-utils@1.0.0-preview-f21e1e0
@metamask-previews/multichain-account-service@13.0.0-preview-f21e1e0
@metamask-previews/multichain-api-middleware@4.0.2-preview-f21e1e0
@metamask-previews/multichain-network-controller@3.2.2-preview-f21e1e0
@metamask-previews/multichain-transactions-controller@7.1.1-preview-f21e1e0
@metamask-previews/name-controller@9.1.2-preview-f21e1e0
@metamask-previews/network-connection-banner-controller@0.1.2-preview-f21e1e0
@metamask-previews/network-controller@35.0.0-preview-f21e1e0
@metamask-previews/network-enablement-controller@6.0.2-preview-f21e1e0
@metamask-previews/notification-services-controller@26.0.0-preview-f21e1e0
@metamask-previews/passkey-controller@3.0.0-preview-f21e1e0
@metamask-previews/permission-controller@13.1.1-preview-f21e1e0
@metamask-previews/permission-log-controller@5.1.0-preview-f21e1e0
@metamask-previews/perps-controller@10.0.0-preview-f21e1e0
@metamask-previews/phishing-controller@17.3.1-preview-f21e1e0
@metamask-previews/platform-api-docs@0.0.0-preview-f21e1e0
@metamask-previews/polling-controller@16.0.9-preview-f21e1e0
@metamask-previews/preferences-controller@23.1.0-preview-f21e1e0
@metamask-previews/profile-metrics-controller@4.0.2-preview-f21e1e0
@metamask-previews/profile-sync-controller@28.3.0-preview-f21e1e0
@metamask-previews/ramps-controller@18.0.1-preview-f21e1e0
@metamask-previews/rate-limit-controller@7.0.1-preview-f21e1e0
@metamask-previews/react-data-query@0.2.2-preview-f21e1e0
@metamask-previews/remote-feature-flag-controller@5.0.0-preview-f21e1e0
@metamask-previews/sample-controllers@5.0.4-preview-f21e1e0
@metamask-previews/seedless-onboarding-controller@10.1.0-preview-f21e1e0
@metamask-previews/selected-network-controller@26.1.6-preview-f21e1e0
@metamask-previews/sentinel-api-service@1.0.0-preview-f21e1e0
@metamask-previews/shield-controller@5.1.3-preview-f21e1e0
@metamask-previews/signature-controller@39.2.9-preview-f21e1e0
@metamask-previews/smart-transactions-controller@25.0.2-preview-f21e1e0
@metamask-previews/snap-account-service@2.1.1-preview-f21e1e0
@metamask-previews/social-controllers@2.7.0-preview-f21e1e0
@metamask-previews/solana-test-validator-up@1.0.0-preview-f21e1e0
@metamask-previews/stellar-quickstart-up@0.0.0-preview-f21e1e0
@metamask-previews/storage-service@1.0.2-preview-f21e1e0
@metamask-previews/subscription-controller@6.2.1-preview-f21e1e0
@metamask-previews/transaction-controller@69.4.0-preview-f21e1e0
@metamask-previews/transaction-pay-controller@26.2.0-preview-f21e1e0
@metamask-previews/user-operation-controller@41.2.8-preview-f21e1e0
@metamask-previews/wallet@9.0.0-preview-f21e1e0
@metamask-previews/wallet-cli@0.0.0-preview-f21e1e0

Previously providerServesAsset checked only for key presence in
supportedCryptoCurrencies, so a provider with { "asset": false } would
be treated as serving that asset. This aligns the function with the
mobile UI's providerSupportsAsset utility, which has always required
the value to be strictly true.

Without this fix, setSelectedProviderForAsset could select a provider
with a false-valued entry, causing an infinite re-run loop in consumers
that combine a controller-side switch with a UI-side isTokenUnavailable
check (which uses the stricter providerSupportsAsset).
…ProviderForAsset

The existing test passes for the wrong reason: the provider has empty
supportedCryptoCurrencies so providerServesAsset is false regardless,
meaning the p.id !== selectedProvider.id guard in find() never needs to
fire. Add a test that actually exercises the guard: providers.selected
is a stale copy with no assets while providers.data has the same
provider ID with the asset — the guard must skip it to prevent a
spurious self-switch.
…erForAsset

Rename single-letter `p` parameter in providers.find callback (id-length
rule requires at least 2 chars). Drop the `=== true` comparison against
a boolean value in providerAvailability (no-unnecessary-boolean-literal-
compare).
saustrie-consensys added a commit to MetaMask/metamask-mobile that referenced this pull request Aug 3, 2026
Pins @metamask/ramps-controller to the preview build published from
MetaMask/core#9759 (18.0.1-preview-f21e1e0) via a resolutions override.
This makes setSelectedProviderForAsset available at runtime.

With the method present, removes the typeof guard and type cast that were
guarding against the missing symbol. The call is now a direct
Engine.context.RampsController.setSelectedProviderForAsset(...) with no
wrapper.
@saustrie-consensys saustrie-consensys self-assigned this Aug 3, 2026
@saustrie-consensys
saustrie-consensys marked this pull request as ready for review August 3, 2026 14:56
@saustrie-consensys
saustrie-consensys requested review from a team as code owners August 3, 2026 14:57

@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 2 potential issues.

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.

Reviewed by Cursor Bugbot for commit 88ad973. Configure here.

Comment thread packages/ramps-controller/src/RampsController.ts
…data

setSelectedProviderForAsset checked asset compatibility against the
providers.selected snapshot, which can be stale once a newer providers
list lands in providers.data. When the fresh entry for the current
provider did serve the asset and another provider served it too, the
method switched away and returned true.

Look the current provider up in providers.data by id, falling back to
providers.selected when it is absent, and keep the self-switch guard on
the replacement lookup. Add a regression test for the case where a
second compatible provider is available.

Also export RampsControllerSetSelectedProviderForAssetAction from the
package index alongside its sibling method action types, and apply oxfmt
formatting to the test file.
@saustrie-consensys
saustrie-consensys added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit 5333d83 Aug 4, 2026
50 checks passed
@saustrie-consensys
saustrie-consensys deleted the saustrie/ramps-controller-set-provider-for-asset branch August 4, 2026 02:49
@saustrie-consensys saustrie-consensys mentioned this pull request Aug 4, 2026
4 tasks
saustrie-consensys added a commit to MetaMask/metamask-mobile that referenced this pull request Aug 4, 2026
Pins @metamask/ramps-controller to the preview build published from
MetaMask/core#9759 (18.0.1-preview-f21e1e0) via a resolutions override.
This makes setSelectedProviderForAsset available at runtime.

With the method present, removes the typeof guard and type cast that were
guarding against the missing symbol. The call is now a direct
Engine.context.RampsController.setSelectedProviderForAsset(...) with no
wrapper.
pull Bot pushed a commit to Reality2byte/core that referenced this pull request Aug 4, 2026
## Explanation

Automated release bump created with `yarn create-release-branch` for:

- `@metamask/ramps-controller` `18.0.1` to `19.0.0` (major). Unreleased
includes breaking changes from MetaMask#9752 (remove `getDefaultRedirectUrl`
from `RampsControllerOptions`; require
`RampsService:getDefaultRedirectCallbackUrl` delegation) plus the new
`setSelectedProviderForAsset` API and `providerServesAsset` fix from
MetaMask#9759.
- `@metamask/transaction-pay-controller` `26.2.0` to `26.2.1` (patch).
Included as a direct dependent of the major bump so its
`@metamask/ramps-controller` range moves to `^19.0.0`. Also publishes
the pending `@metamask/network-controller` bump.

SemVer: major is required because of the MetaMask#9752 BREAKING entries in
Unreleased; a minor would be wrong even though MetaMask#9759 alone would have
been a minor.

## References

- Related to MetaMask#9759 (`setSelectedProviderForAsset` and
`providerServesAsset` fix)
- Related to MetaMask#9752 (Headless Buy default redirect URL sourced from
`RampsService`; breaking for hosts)
- Consumer mobile adoption for MetaMask#9759: MetaMask/metamask-mobile#34195
- Breaking-change consumer note from MetaMask#9752: hosts must drop
`getDefaultRedirectUrl` and delegate
`RampsService:getDefaultRedirectCallbackUrl` (or spread
`RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS`)

## 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
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [x] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Low direct code risk in this diff, but shipping ramps-controller
19.0.0 forces consumer migrations (messenger delegation, dropped
`getDefaultRedirectUrl`) and can break MM Pay fiat quoting if hosts are
not updated.
> 
> **Overview**
> This is an **automated release cut** (no application code in the
diff): it finalizes versions and changelogs so npm consumers pick up
ramps work that landed in earlier PRs.
> 
> **`@metamask/ramps-controller` `19.0.0` (major)** moves Unreleased
notes into `[19.0.0]`. Hosts upgrading get **breaking** Headless Buy
redirect wiring: `getDefaultRedirectUrl` is removed from
`RampsControllerOptions`, widened `getQuotes` paths must delegate
**`RampsService:getDefaultRedirectCallbackUrl`**, and defaults come from
**`RampsService` / `getDefaultRedirectCallbackUrl(environment)`**. The
release also documents **`setSelectedProviderForAsset`** plus a
**`providerServesAsset`** fix (map values must be `true`).
> 
> **`@metamask/transaction-pay-controller` `26.2.1` (patch)** bumps
**`@metamask/ramps-controller`** to `^19.0.0` as a direct dependent and
records a pending **`@metamask/network-controller`** `^35.0.1` bump. The
root monorepo version becomes **`1172.0.0`**; **`yarn.lock`** is updated
accordingly.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
277ec22. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
pull Bot pushed a commit to firas9941/metamask-mobile that referenced this pull request Aug 6, 2026
MetaMask#34195)

<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
-->

## **Description**

<!-- mms-check: type=text required=true -->

Rewires the provider-compatibility switch so the logic lives in
`RampsController` (via `setSelectedProviderForAsset`, from
MetaMask/core#9759) rather than being duplicated in the UI layer.

**Background.** When a user selects Coinbase (or any non-native
aggregator) in UB2 and then opens MMPay,
`RampsController.providers.selected` still points to the aggregator.
MMPay's `useHasNativeFiatProvider` checks `selectedProvider?.type ===
'native'` and returns false, causing `useAutomaticTransactionPayToken`
to dead-end before selecting a payment method. The "Pay with..." section
skeleton spins indefinitely.

**This PR.** The switch logic moves to the controller.
`RampsController.setSelectedProviderForAsset(assetId)`:
- Finds the first provider in `state.providers.data` that serves
`assetId`.
- Calls `setSelectedProvider` internally with `autoSelected: true`.
- Returns `true` if a switch happened, `false` otherwise.

Changes:
- `useRampsProviders.ts` / `useRampsController.ts` - expose
`setSelectedProviderForAsset` from `Engine.context.RampsController`.
- `useEnsureCompatibleProvider.ts` - single `useEffect` calling
`setSelectedProviderForAsset`.
- `BuildQuote.tsx` Effect 2 - uses controller method instead of inline
find-and-switch.
- `money-account-deposit-info.tsx` - calls `useEnsureCompatibleProvider`
so MMPay switches away from an incompatible aggregator.
- Bumps `@metamask/ramps-controller` to stable `^19.0.0` (no preview
resolution).
- Includes the TRAM-3757 redirect-URL consumer wiring so `19.0.0` works
before/alongside MetaMask#34207 landing on main.

Merge after MetaMask#34207.

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

CHANGELOG entry: null

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Refs: https://consensyssoftware.atlassian.net/browse/TRAM-3635
Refs: MetaMask/core#9759
Refs: MetaMask#34207

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: MMPay provider compatibility after UB2 aggregator selection

  Scenario: user opens MMPay after selecting Coinbase in UB2
    Given the user has selected Coinbase as the provider in UB2
    When the user opens MMPay Add funds
    Then the Pay with section resolves to a payment method row
    And the skeleton does not spin indefinitely
```

Device testing tracked in TRAM-3635.

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

N/A - logic-only change; visual behavior is the fix itself (no more
infinite skeleton).

### **Before**

MetaMask#33977

### **After**


https://consensys.slack.com/archives/C030G4739T3/p1785749933438429?thread_ts=1785357615.968319&cid=C030G4739T3

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

- [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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches fiat deposit provider selection and auto-pay timing in
confirmations; wrong switching could hide payment methods or pick the
wrong ramp provider.
> 
> **Overview**
> Wires **`RampsController.setSelectedProviderForAsset`** through
`useRampsProviders` / `useRampsController` so UI stops duplicating “pick
a provider for this asset” logic.
> 
> **`useEnsureCompatibleProvider`** runs on MMPay add-funds
(`MoneyAccountDepositInfo`): it calls the controller first, and when
`moneyHeadlessAllProviders` is off it can still **auto-select a native**
provider if an aggregator already lists the asset (fixes stuck “Pay
with…” after UB2 left Coinbase selected).
> 
> **`BuildQuote`** token-unavailable handling now tries
`setSelectedProviderForAsset` before falling back to another supporting
provider or the token-not-available modal; it waits until providers are
loaded.
> 
> **`useAutomaticTransactionPayToken`** no longer latches early on the
fiat path when fiat isn’t ready yet, so a later provider switch can
complete auto-selection.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
efad05d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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