Skip to content

feat: delegate AuthenticationController:getBearerToken in RampsServic…#30319

Merged
amitabh94 merged 8 commits into
mainfrom
feat/TRAM-3502
Jun 1, 2026
Merged

feat: delegate AuthenticationController:getBearerToken in RampsServic…#30319
amitabh94 merged 8 commits into
mainfrom
feat/TRAM-3502

Conversation

@meltingice1337

@meltingice1337 meltingice1337 commented May 18, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adopts the breaking messenger contract introduced in @metamask/ramps-controller for TRAM-3502, which moves the Buy widget API call from unauthenticated to authenticated using a bearer token sourced from AuthenticationController.

Why: The Buy widget endpoint on the ramps API has been gated behind authentication. Without sending an Authorization: Bearer <token> header on getBuyWidgetUrl, mobile users will be unable to launch the Transak buy flow.

What changed in core (the dependency):

  • RampsService.getBuyWidgetUrl now fetches a bearer token via AuthenticationController:getBearerToken and sends it as an Authorization header.
  • RampsServiceMessenger's AllowedActions was widened from never to include AuthenticationController:getBearerToken — i.e. consumers (this app) must delegate that action into the ramps messenger or the call will throw.
  • See the core PR for the full contract change: <link-to-core-PR>.

What this PR does in mobile:

  1. Bumps @metamask/ramps-controller to 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.0 once published).
  2. Delegates AuthenticationController:getBearerToken into the RampsServiceMessenger at the point where the messenger is constructed in the engine/controller-init layer.
  3. Surfaces the new failure modes (wallet locked / user signed out / token fetch failure) to the Buy entry points so the user gets a usable error rather than an unhandled rejection.

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

Feature: Buy widget authentication

  Scenario: Signed-in user opens the Buy widget
    Given the user is signed in and the wallet is unlocked
    And the user has selected a token that supports Transak
    When the user taps "Buy" and proceeds to the Transak provider
    Then the Buy widget URL loads successfully
    And the upstream request to the ramps API includes an "Authorization: Bearer <token>" header
    And Transak opens in the in-app browser as before

  Scenario: Wallet-locked user attempts to open the Buy widget
    Given the wallet is locked
    When the user taps "Buy" and proceeds to the Transak provider
    Then the user sees a clear error state (not a silent failure or crash)
    And no unauthenticated request is sent to the ramps API

  Scenario: Signed-out user attempts to open the Buy widget
    Given the user is signed out of profile sync / authentication
    When the user taps "Buy" and proceeds to the Transak provider
    Then the user sees a clear error state
    And no unauthenticated request is sent to the ramps API

  Scenario: Bearer token call fails transiently
    Given the AuthenticationController fails to mint a bearer token
    When the user taps "Buy" and proceeds to the Transak provider
    Then the failure is surfaced as a user-facing error
    And retrying after the underlying auth issue is resolved succeeds

How to verify the Authorization header on-device:

  • Point a debugging proxy (Charles / mitmproxy) at the device.
  • Trigger the Buy flow and inspect the request to https://on-ramp.api.cx.metamask.io/providers/<provider>/buy-widget.
  • Confirm an Authorization: Bearer <jwt> header is present.

Screenshots/Recordings

Before

After

auth_demo.mp4

Pre-merge author checklist

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 to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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.

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-controller to ^14.0.0 so the Buy widget can call the ramps API with an authenticated bearer token (required by the new controller contract).

When getRampsServiceMessenger builds the child messenger, it now delegates AuthenticationController:getBearerToken from the root messenger into RampsServiceMessenger, so RampsService can 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.

@github-actions

Copy link
Copy Markdown
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.

@github-actions github-actions Bot added the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 18, 2026
@metamaskbotv2 metamaskbotv2 Bot added the team-money-movement issues related to Money Movement features label May 18, 2026
@sonarqubecloud

Copy link
Copy Markdown

Comment thread ios/MetaMask.xcodeproj/project.pbxproj Outdated
@meltingice1337 meltingice1337 marked this pull request as ready for review May 19, 2026 14:21
@meltingice1337 meltingice1337 requested a review from a team as a code owner May 19, 2026 14:21

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

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.

Reviewed by Cursor Bugbot for commit 9341546. Configure here.

Comment thread android/app/build.gradle Outdated
@meltingice1337 meltingice1337 removed the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 19, 2026
Comment thread ios/MetaMask.xcodeproj/project.pbxproj Outdated
pull Bot pushed a commit to Reality2byte/core that referenced this pull request May 20, 2026
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>
@meltingice1337 meltingice1337 mentioned this pull request May 20, 2026
4 tasks
pull Bot pushed a commit to Reality2byte/core that referenced this pull request May 20, 2026
## 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>
@github-actions github-actions Bot added the risk:high AI analysis: high risk label Jun 1, 2026
@amitabh94 amitabh94 enabled auto-merge June 1, 2026 17:19
@amitabh94 amitabh94 removed the risk:high AI analysis: high risk label Jun 1, 2026
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeAccounts, SmokeConfirmations, SmokeIdentity, SmokeNetworkAbstractions, SmokeNetworkExpansion, SmokeSwap, SmokeStake, SmokeWalletPlatform, SmokeMoney, SmokePerps, SmokeMultiChainAPI, SmokePredictions, SmokeSeedlessOnboarding, SmokeBrowser, SmokeSnaps
  • Selected Performance tags: @PerformanceAccountList, @PerformanceOnboarding, @PerformanceLogin, @PerformanceSwaps, @PerformanceLaunch, @PerformanceAssetLoading, @PerformancePredict, @PerformancePreps
  • Risk Level: high
  • AI Confidence: 100%
click to see 🤖 AI reasoning details

E2E Test Selection:
Hard rule (controller-version-update): @MetaMask controller package version updated in package.json: @metamask/ramps-controller. Running all tests.

Performance Test Selection:
Hard rule (controller-version-update): @MetaMask controller package version updated in package.json: @metamask/ramps-controller. Running all tests.

View GitHub Actions results

@github-actions github-actions Bot added the risk:high AI analysis: high risk label Jun 1, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.70%. Comparing base (13349a0) to head (2fc01cf).
⚠️ Report is 18 commits behind head on main.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@amitabh94 amitabh94 added the skip-e2e skip E2E test jobs label Jun 1, 2026
@amitabh94

Copy link
Copy Markdown
Contributor

Skipping e2e because of this
https://consensys.slack.com/archives/C02U025CVU4/p1780342035328929

@amitabh94 amitabh94 added this pull request to the merge queue Jun 1, 2026
Merged via the queue into main with commit 044726b Jun 1, 2026
157 of 159 checks passed
@amitabh94 amitabh94 deleted the feat/TRAM-3502 branch June 1, 2026 23:16
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 1, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.81.0 Issue or pull request that will be included in release 7.81.0 label Jun 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.81.0 Issue or pull request that will be included in release 7.81.0 risk:high AI analysis: high risk size-S skip-e2e skip E2E test jobs team-money-movement issues related to Money Movement features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants