Uh oh!
There was an error while loading. Please reload this page.
chore(ramp): adopt core-owned Headless Buy default redirect URL - #34207
Conversation
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. |
2202951 to
29ba630Compare29ba630 to
ad3f01bComparePR template — items to address before "Ready for review"Warnings — informational, address before merging:
See docs/readme/ready-for-review.md for the full Definition of Ready for Review. |
1 similar comment
PR template — items to address before "Ready for review"Warnings — informational, address before merging:
See docs/readme/ready-for-review.md for the full Definition of Ready for Review. |
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. |
… URL from RampsService (MetaMask#9752) ## Explanation On the widened Headless Buy all-providers path, MetaMask Pay's quote request omits `redirectUrl`. The quotes API only embeds a `buyURL`/`buyWidget` when a `redirectUrl` is present, so `RampsController.getQuotes` must supply a default there. Until now that default came from a `getDefaultRedirectUrl` callback injected by the mobile client, which review flagged as an unusual controller-init pattern for a value core can derive itself. This PR moves ownership into core without giving `RampsController` a second copy of the environment: - Adds the exported pure `getDefaultRedirectCallbackUrl(environment)` helper as the canonical environment-to-callback map (`on-ramp-content` for production/staging, `on-ramp.dev-api` for development, `localhost:3000` for local). - Adds `RampsService.getDefaultRedirectCallbackUrl()` and the matching messenger action, which returns that URL for the environment the service was already constructed with. `baseUrlOverride` deliberately does not apply: in production and staging the callback lives on `on-ramp-content`, not the API/`on-ramp-cache` host that `baseUrlOverride` replaces; using the API override here would break client completion matching. `RampsEnvironment.Local` yields a localhost callback pinned to port 3000. - Removes `getDefaultRedirectUrl` from `RampsControllerOptions`. On the widened path, when the caller omits `redirectUrl`, the controller calls `RampsService:getDefaultRedirectCallbackUrl`. Explicit caller `redirectUrl` still wins; the native-only (flag-off) path still injects nothing. If a host upgrades without delegating the new action, the entire `RampsController:getQuotes` call rejects (including MM Pay fiat quoting), rather than returning aggregator quotes without a widget URL. That is intentional and covered by a unit test. ### Breaking change 1. Delegate `RampsService:getDefaultRedirectCallbackUrl` to the `RampsController` messenger (prefer spreading `RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS` instead of extending a hand-written list), and drop any `getDefaultRedirectUrl` constructor argument. 2. Reimplement mobile `getRampCallbackBaseUrl()` as `getDefaultRedirectCallbackUrl(getRampsEnvironment())` in the same upgrade so quote defaults and Checkout completion detection share one environment source. Builds that set `RAMPS_ENVIRONMENT` differently from `METAMASK_ENVIRONMENT` (notably some `exp` / `e2e-bs` flavors) can otherwise mismatch. ## References - Fixes TRAM-3757 - Follow-up from MetaMask/metamask-mobile#32682 (review thread MetaMask/metamask-mobile#32682 (comment)) - Related: TRAM-3698 (the original missing buy-widget URL gap) - Consumer draft: MetaMask/metamask-mobile#34207 ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] 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** > Breaking messenger and constructor contract for Headless Buy / MM Pay quoting; mis-delegation fails the whole `getQuotes` call, and env mismatch between service and UI callback detection could break checkout completion. > > **Overview** > **Breaking:** Widened Headless Buy quotes no longer use an injected `getDefaultRedirectUrl` on `RampsController`. When `moneyHeadlessAllProviders` is on and the caller omits `redirectUrl`, the controller calls **`RampsService:getDefaultRedirectCallbackUrl`** and forwards that URL into `getQuotes` so aggregator quotes get a `buyURL`/`buyWidget`. Explicit `redirectUrl` still wins; the native-only path does not call the service. > > Adds **`getDefaultRedirectCallbackUrl(environment)`** (canonical env → `/regions/fake-callback` map, ignoring `baseUrlOverride`) plus **`RampsService.getDefaultRedirectCallbackUrl()`** and the messenger action/type, exported from the package. Hosts must delegate the new action (listed in **`RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS`**) or **`getQuotes` rejects**; mobile should align UI callback matching with the same helper and environment source. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3b3ff32. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Bump @metamask/ramps-controller to the TRAM-3757 preview, drop the client getDefaultRedirectUrl injection, spread RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS for messenger delegation, and make getRampCallbackBaseUrl a thin wrapper around getDefaultRedirectCallbackUrl(getRampsEnvironment()) so UB2 quote, Continue, Checkout, and the controller default share one environment source.
Replace the preview pin with the stable ^19.0.0 release now that redirect-URL support is published on npm.
ad3f01b to
e6fe057Comparesaustrie-consensys
commented
Aug 4, 2026
Triggered an RC installable build for this PR via Build Mobile App ( Workflow run: https://github.com/MetaMask/metamask-mobile/actions/runs/30916339056 When the run finishes:
|
saustrie-consensys
commented
Aug 4, 2026
Correction: two identical Use this run (already past prepare, building both platforms): Inputs: Artifacts when green:
|
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: Performance Test Selection: |
Uh oh!
There was an error while loading. Please reload this page.



Description
Adopts the TRAM-3757 core change from MetaMask/core#9752 so Headless Buy and UB2 share one finish-line (fake-callback) URL derivation.
@metamask/ramps-controllerto the stable published^19.0.0release.getDefaultRedirectUrlinjection fromramps-controller-init.ts. Core now supplies the widened-path default throughRampsService:getDefaultRedirectCallbackUrl.RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONSin the controller messenger so the new action cannot be forgotten on future upgrades.getRampCallbackBaseUrl()asgetDefaultRedirectCallbackUrl(getRampsEnvironment()), deleting the duplicated host table. BuildQuote, Continue rewrite, Checkout completion matching, and the controller default now all use the same environment source (RAMPS_ENVIRONMENT, thenMETAMASK_ENVIRONMENT).Changelog
CHANGELOG entry: null
Related issues
Fixes: TRAM-3757
Refs: MetaMask/core#9752
Manual testing steps
N/A - unit-covered wiring and package bump only. Covered by unit tests for
getRampCallbackBaseUrl(parity withgetDefaultRedirectCallbackUrl(getRampsEnvironment()), includingRAMPS_ENVIRONMENToverride),ramps-controller-init, and messenger construction.Screenshots/Recordings
N/A - no user-visible UI change; wiring/package bump only.
Before
N/A
After
N/A, simply proving that UB2 still works.
ScreenRecording_08-04-2026.07-47-37_1.MP4
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Note
Medium Risk
Changes ramp buy/checkout redirect URL resolution for headless and UB2 flows; behavior should match prior mapping but depends on core v19 and messenger delegation being correct.
Overview
Bumps
@metamask/ramps-controllerto ^19.0.0 (TRAM-3757 / core#9752) so the widened Headless Buy quote path gets its default redirect from core instead of the mobile client.getRampCallbackBaseUrl()no longer maintains a local host switch onMETAMASK_ENVIRONMENT; it delegates togetDefaultRedirectCallbackUrl(getRampsEnvironment()), aligning UB2 BuildQuote, checkout completion, and Continue rewrite with the same env source (RAMPS_ENVIRONMENT, thenMETAMASK_ENVIRONMENT).ramps-controller-initdrops thegetDefaultRedirectUrlinjection intoRampsController.The ramps controller messenger now spreads
RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONSinstead of a hand-maintained action list, soRampsService:getDefaultRedirectCallbackUrlstays delegated on upgrades. Tests assert parity with core andRAMPS_ENVIRONMENToverride behavior.Reviewed by Cursor Bugbot for commit 721b70e. Bugbot is set up for automated code reviews on this repo. Configure here.