feat: delegate AuthenticationController:getBearerToken in RampsServic…#30319
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. |
85bcd83 to
2f27466
Compare
|
2f27466 to
c654920
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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 9341546. Configure here.
This reverts commit 9341546.
MetaMask#8843) ## Explanation `RampsService.getBuyWidgetUrl` previously issued unauthenticated requests to the ramps API (`/providers/<provider>/buy-widget`). The upstream API is being gated behind authentication, so without a bearer token the call will start to fail and break the Buy flow for every consumer (mobile, extension). This PR makes `getBuyWidgetUrl` authenticated by sourcing a bearer token from `AuthenticationController` via the messenger and attaching it as an `Authorization: Bearer <token>` header on the outgoing request. **How it works:** - A new private method `RampsService.#getRequestHeaders` calls the messenger action `AuthenticationController:getBearerToken` and returns the `Authorization` header. It is awaited once per `getBuyWidgetUrl` invocation (verified by a new test) before the request is dispatched through the existing `#policy.execute` wrapper, so token retrieval happens outside the retry/circuit-breaker loop. If the token call rejects (e.g. wallet is locked, user signed out), the rejection propagates and no HTTP call is made — also covered by a new test. - `RampsServiceMessenger`'s `AllowedActions` is widened from `never` to `AuthenticationController.AuthenticationControllerGetBearerTokenAction`. This is a **breaking change** to the messenger contract: consumers must delegate the `AuthenticationController:getBearerToken` action into the ramps messenger before calling `getBuyWidgetUrl`. - The scope of the auth requirement is deliberately narrow — only `getBuyWidgetUrl` is authenticated in this PR. Other endpoints (e.g. `getGeolocation`) remain unauthenticated and explicitly do not request a bearer token; this is locked in by tests that assert `getBearerToken` is not called and that no `Authorization` header is sent for those endpoints. **Dependency added:** `@metamask/profile-sync-controller@^28.1.0` is added as a runtime dependency solely for its `AuthenticationController` type export (the `AuthenticationControllerGetBearerTokenAction` action type). It is not instantiated by `ramps-controller`; the implementing controller lives in the consuming app and is wired up via the messenger. **Demo:** https://github.com/user-attachments/assets/87d4d146-1ce4-4582-a27a-4e60760fae7b **Test updates:** - Existing happy-path tests for `getBuyWidgetUrl` now assert the `Authorization: Bearer mock-bearer-token` header is present on the nock interceptor. - New tests cover: bearer token is fetched exactly once per call; rejection from `getBearerToken` short-circuits before any HTTP request; and the scope assertion that `getGeolocation` remains unauthenticated. - The `getRootMessenger`/`getService` test helpers now delegate the `AuthenticationController:getBearerToken` action and expose a `mockGetBearerToken` jest mock so individual tests can override the resolution behavior. ## References - Fixes [TRAM-3502](https://consensyssoftware.atlassian.net/browse/TRAM-3502) - Consumer adoption (mobile): MetaMask/metamask-mobile#30319 ## 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 [TRAM-3502]: https://consensyssoftware.atlassian.net/browse/TRAM-3502?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk due to a **breaking** messenger contract change requiring consumers to delegate `AuthenticationController:getBearerToken`, and because it changes how `getBuyWidgetUrl` performs network requests by adding auth headers and failing early when tokens are unavailable. > > **Overview** > `RampsService.getBuyWidgetUrl` now authenticates buy-widget requests by retrieving a bearer token via the messenger action `AuthenticationController:getBearerToken` and sending `Authorization: Bearer <token>` on the HTTP call. > > This widens `RampsServiceMessenger` allowed actions (a **breaking change** for consumers that must delegate/register the new action), adds `@metamask/profile-sync-controller` as a runtime dependency for the action type, updates TS project references, and extends tests to assert auth header behavior, token fetch call counts, and that unrelated endpoints (e.g. `getGeolocation`) remain unauthenticated. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bdad742. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Darius Costolas <10818970+meltingice1337@users.noreply.github.com>
## Explanation Release 993.0.0 — two packages: - **`@metamask/ramps-controller`** `13.3.1` → **`14.0.0`** (major) - **`@metamask/transaction-pay-controller`** `22.6.1` → **`22.6.2`** (patch) `ramps-controller@14.0.0` ships MetaMask#8843, which authenticates `getBuyWidgetUrl` by requiring `AuthenticationController:getBearerToken` on its messenger. That's a breaking messenger-contract change, so major. `transaction-pay-controller@22.6.2` is a no-code-change patch that bumps its dep range on `ramps-controller` from `^13.3.1` to `^14.0.0`. Included to keep the dependency graph current and avoid duplicate `ramps-controller` copies in consumer node_modules. Its code doesn't touch any of the breaking surface. ## References - Feature PR: MetaMask#8843 - Mobile adoption (draft): MetaMask/metamask-mobile#30319 ## 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** > Moderate risk because this release includes a **breaking** `@metamask/ramps-controller` messenger-contract change requiring consumers to delegate `AuthenticationController:getBearerToken` before calling `getBuyWidgetUrl`. The rest is version/changelog/dependency range updates with minimal runtime impact. > > **Overview** > Bumps the monorepo release version to `993.0.0` and publishes `@metamask/ramps-controller` `14.0.0` (major) and `@metamask/transaction-pay-controller` `22.6.2` (patch). > > `ramps-controller@14.0.0` documents a **breaking** change requiring `RampsServiceMessenger` consumers to delegate `AuthenticationController:getBearerToken`, and adds bearer-token authentication for `getBuyWidgetUrl` plus a new runtime dependency on `@metamask/profile-sync-controller`. > > `transaction-pay-controller@22.6.2` is a dependency-only update to consume `@metamask/ramps-controller@^14.0.0`, with corresponding `yarn.lock` updates. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b8f2fe6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Darius Costolas <10818970+meltingice1337@users.noreply.github.com>
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: Performance Test Selection: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #30319 +/- ##
==========================================
+ Coverage 82.66% 82.70% +0.03%
==========================================
Files 5551 5561 +10
Lines 142775 143083 +308
Branches 32957 33051 +94
==========================================
+ Hits 118026 118336 +310
+ Misses 16890 16863 -27
- Partials 7859 7884 +25 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Skipping e2e because of this |




Description
This PR adopts the breaking messenger contract introduced in
@metamask/ramps-controllerfor TRAM-3502, which moves the Buy widget API call from unauthenticated to authenticated using a bearer token sourced fromAuthenticationController.Why: The Buy widget endpoint on the ramps API has been gated behind authentication. Without sending an
Authorization: Bearer <token>header ongetBuyWidgetUrl, mobile users will be unable to launch the Transak buy flow.What changed in core (the dependency):
RampsService.getBuyWidgetUrlnow fetches a bearer token viaAuthenticationController:getBearerTokenand sends it as anAuthorizationheader.RampsServiceMessenger'sAllowedActionswas widened fromneverto includeAuthenticationController:getBearerToken— i.e. consumers (this app) must delegate that action into the ramps messenger or the call will throw.<link-to-core-PR>.What this PR does in mobile:
@metamask/ramps-controllerto the new major version (currently consuming the preview build@metamask-previews/ramps-controller@<preview-version>while the core PR is in review; will switch to^14.0.0once published).AuthenticationController:getBearerTokeninto theRampsServiceMessengerat the point where the messenger is constructed in the engine/controller-init layer.Changelog
CHANGELOG entry: null
Related issues
Fixes: TRAM-3502
Depends on (core):
<link-to-core-PR>— must be merged and released to NPM before this PR can leave draft.Manual testing steps
How to verify the Authorization header on-device:
https://on-ramp.api.cx.metamask.io/providers/<provider>/buy-widget.Authorization: Bearer <jwt>header is present.Screenshots/Recordings
Before
After
auth_demo.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
Wires bearer-token access into the Buy/ramps path; mis-delegation would break Transak buy, but changes are localized to messenger setup and a dependency bump.
Overview
Upgrades
@metamask/ramps-controllerto ^14.0.0 so the Buy widget can call the ramps API with an authenticated bearer token (required by the new controller contract).When
getRampsServiceMessengerbuilds the child messenger, it now delegatesAuthenticationController:getBearerTokenfrom the root messenger intoRampsServiceMessenger, soRampsServicecan mint tokens without the call failing at runtime. A unit test asserts that delegated call returns the token from the registered handler.Reviewed by Cursor Bugbot for commit c7e989f. Bugbot is set up for automated code reviews on this repo. Configure here.