…mp API requests (MetaMask#9983)
## Explanation
The on-ramp API is adding server-side feature flags (LaunchDarkly) that
are gated per client product and client version — e.g. "enable feature X
for MetaMask Mobile >= 8.10.0". To evaluate those gates, the API needs
to know which client is calling.
This PR adds optional `clientProduct` and `clientVersion` constructor
options to `RampsService` and `TransakService`. When the host supplies
them, every on-ramp API fetch carries two query params:
- `clientProduct` (e.g. `metamask-mobile`)
- `clientVersion` (the app SemVer, not the ramps-controller package
version)
Identity travels **in the URL, not in headers**, because the on-ramp CDN
caches responses keyed by URL. If gating identity lived in headers, two
clients in different flag cohorts would share the same cache entry and
one cohort's response could be served to the other. Query params make
the cache key and the flag decision agree by construction.
Both fields are optional. Hosts that don't pass them send no identity
params, and the API fails closed (feature off) — so this is fully
backwards compatible.
Also exported for hosts and tests: the `RampsClientIdentity` type, the
`addRampsClientIdentityParams` helper, and the
`RAMPS_CLIENT_PRODUCT_PARAM` / `RAMPS_CLIENT_VERSION_PARAM` constants.
The `controller` query param is intentionally left as the
ramps-controller package version; the new params carry the app identity
instead of overloading it.
## References
Related to the on-ramp API version-gated feature flag rollout (Unified
Buy 2.0 catalog gating / fiat soft-default) —
[TRAM-3828](https://consensyssoftware.atlassian.net/browse/TRAM-3828).
- API: consensys-vertical-apps/va-mmcx-onramp-api#1141
- Mobile: MetaMask/metamask-mobile#35359
- Extension: MetaMask/metamask-extension#45823
## Changelog
Updated `packages/ramps-controller/CHANGELOG.md` (Unreleased → Added).
## Checklist
- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc) for new or updated code as
appropriate
- [x] I've communicated my changes to consumers by updating changelogs
for packages I've changed
- [x] No breaking changes introduced
Made with [Cursor](https://cursor.com)
## Demo
<div>
<a href="https://www.loom.com/share/9f913895e9bb4ccd95a3a79138566f4c">
<p>Introducing Launchdarkly flags for Ramps Backend - Watch Video</p>
</a>
<a href="https://www.loom.com/share/9f913895e9bb4ccd95a3a79138566f4c">
<img style="max-width:300px;"
src="https://cdn.loom.com/sessions/thumbnails/9f913895e9bb4ccd95a3a79138566f4c-36a975aecd13f632-full-play.gif#t=0.1">
</a>
</div>
[TRAM-3828]:
https://consensyssoftware.atlassian.net/browse/TRAM-3828?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Description
Wires the extension's client identity (
clientProduct: 'metamask-extension',clientVersionfromprocess.env.METAMASK_VERSION) intoRampsService. The ramps-controller sends these asclientProduct/clientVersionquery params so CDN cache keys vary per client, letting the on-ramp API evaluate version-gated LaunchDarkly flags — first consumer:ramps-v2-fiat-soft-default(TRAM-3828).This also bumps
@metamask/ramps-controllerfrom^15.0.0to^20.2.0(MetaMask/core#9983 in Release/1216.0.0), adapting to the intervening breaking changes:normalizeProviderCodeinuseRampsBuildQuoteaddPrecreatedOrderrequires a non-emptychainId; the extension param types now require it (no production caller passes params yet)getProviderScope/getDefaultRedirectUrlunused; the messenger spreadsRAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS)Pinned to
@metamask/ramps-controller@^20.2.0(released).Changelog
CHANGELOG entry: null
Related issues
Fixes: TRAM-3828
Manual testing steps
clientProduct=metamask-extension&clientVersion=<x.y.z>query params (no client-identity headers)Screenshots/Recordings
N/A — no UI change.
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Large dependency jump on ramps buy/checkout paths and new required
chainIdfor precreated orders; client identity on all ramps API calls affects backend flag rollout behavior.Overview
Wires extension client identity into
RampsServiceviaclientProduct: 'metamask-extension'andclientVersionfromMETAMASK_VERSION, so on-ramp API requests can carry version-gated LaunchDarkly behavior through query params (not headers).Upgrades
@metamask/ramps-controllerfrom^15.0.0to^20.2.0and adapts to breaking changes: buy-quote checkout uses provider IDs as-is (dropsnormalizeProviderCode), andchainIdis required onaddRampsPrecreatedOrder/ hook types. E2E fixtures and metrics snapshots drop the removedRampsController.countriespersisted state.Reviewed by Cursor Bugbot for commit 81a8033. Bugbot is set up for automated code reviews on this repo. Configure here.
Demo
Introducing Launchdarkly flags for Ramps Backend - Watch Video