@metamask-previews/ramps-controller 15.1.0-preview-34f2bcbf7 → 15.1.0-preview-aa4ef4666
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/RampsController.cjs +39 -80
- package/dist/RampsController.cjs.map +1 -1
- package/dist/RampsController.d.cts +11 -5
- package/dist/RampsController.d.cts.map +1 -1
- package/dist/RampsController.d.mts +11 -5
- package/dist/RampsController.d.mts.map +1 -1
- package/dist/RampsController.mjs +39 -80
- package/dist/RampsController.mjs.map +1 -1
- package/dist/errorNormalization.cjs +84 -0
- package/dist/errorNormalization.cjs.map +1 -0
- package/dist/errorNormalization.d.cts +56 -0
- package/dist/errorNormalization.d.cts.map +1 -0
- package/dist/errorNormalization.d.mts +56 -0
- package/dist/errorNormalization.d.mts.map +1 -0
- package/dist/errorNormalization.mjs +78 -0
- package/dist/errorNormalization.mjs.map +1 -0
- package/dist/index.cjs +19 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +7 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -0
- package/dist/index.mjs.map +1 -1
- package/dist/providerAvailability.cjs +139 -0
- package/dist/providerAvailability.cjs.map +1 -0
- package/dist/providerAvailability.d.cts +120 -0
- package/dist/providerAvailability.d.cts.map +1 -0
- package/dist/providerAvailability.d.mts +120 -0
- package/dist/providerAvailability.d.mts.map +1 -0
- package/dist/providerAvailability.mjs +131 -0
- package/dist/providerAvailability.mjs.map +1 -0
- package/dist/quoteClassification.cjs +44 -0
- package/dist/quoteClassification.cjs.map +1 -0
- package/dist/quoteClassification.d.cts +33 -0
- package/dist/quoteClassification.d.cts.map +1 -0
- package/dist/quoteClassification.d.mts +33 -0
- package/dist/quoteClassification.d.mts.map +1 -0
- package/dist/quoteClassification.mjs +38 -0
- package/dist/quoteClassification.mjs.map +1 -0
- package/dist/quoteSelection.cjs +154 -0
- package/dist/quoteSelection.cjs.map +1 -0
- package/dist/quoteSelection.d.cts +93 -0
- package/dist/quoteSelection.d.cts.map +1 -0
- package/dist/quoteSelection.d.mts +93 -0
- package/dist/quoteSelection.d.mts.map +1 -0
- package/dist/quoteSelection.mjs +148 -0
- package/dist/quoteSelection.mjs.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add a pure `resolveFiatDepositRoute` helper (and `FiatDepositRoute` type) that picks the on-ramp asset a region should buy for a fiat deposit: the preferred target asset (e.g. mUSD) when a provider serves it, otherwise the first convertible fallback asset (e.g. native ETH) with a serving provider, or `undefined` when none is purchasable. It reuses `regionHasProviderForAsset` so it obeys the same scope semantics (an aggregator-only fallback is unreachable under scope `off`), enabling the "buy ETH, convert to mUSD" deposit route in regions without a direct mUSD provider ([#9428](https://github.com/MetaMask/core/pull/9428))
|
|
13
|
+
- Add pure quote-selection helpers `getSmartSelectedQuote` and `fitsProviderLimits`, the amount validator `validateBuyAmount`, and a `BuyAmountValidation` type so headless-buy consumers can share the controller's provider-agnostic quote ranking (`preferredProviderIds` then reliability then price then first surviving candidate), scope-aware in-app filtering, and per-provider fiat-limit enforcement instead of re-deriving them ([#9414](https://github.com/MetaMask/core/pull/9414))
|
|
14
|
+
- Add pure provider-availability helpers `providerServesAsset`, `getProvidersServingAsset`, `regionHasProviderForAsset`, and `isFiatDepositAvailable` so headless-buy consumers can share the controller's case-insensitive CAIP-19 asset matching and scope-aware region/availability gating instead of re-deriving it, keeping the two from disagreeing ([#9409](https://github.com/MetaMask/core/pull/9409))
|
|
15
|
+
- Add pure quote-classification helpers `isExternalBrowserQuote`, `isCustomActionQuote`, and `isInAppOnlyQuote` so consumers can share the controller's in-app-vs-external browser-mode classification without owning host redirect/deeplink concerns ([#9409](https://github.com/MetaMask/core/pull/9409))
|
|
16
|
+
- Add pure error-normalization helpers `getErrorMessage`, `extractExplicitTypedError`, and `normalizeToTypedError` (with a `TypedError<Code>` type) so consumers can share error-shape extraction while keeping their own error-code taxonomy ([#9409](https://github.com/MetaMask/core/pull/9409))
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- `RampsController.getQuotes` now derives its provider-widening decision from the `getProviderScope` scope (`off` stays native-only; `in-app`/`all` widen) rather than the `restrictToKnownOrNativeProviders` flag, and picks the widened auto-selected quote via the shared `getSmartSelectedQuote`, feeding in the user's completed-order provider preference so a returning user's previously-used provider is preferred over the reliability/price winner ([#9414](https://github.com/MetaMask/core/pull/9414))
|
|
21
|
+
- `RampsController` now derives its internal region provider-asset matching and quote in-app/custom-action/external filtering from the shared `providerAvailability` and `quoteClassification` helpers, so the exposed helpers stay behaviourally identical to the controller's own selection ([#9409](https://github.com/MetaMask/core/pull/9409))
|
|
22
|
+
|
|
23
|
+
### Deprecated
|
|
24
|
+
|
|
25
|
+
- **`RampsController.getQuotes`'s `restrictToKnownOrNativeProviders` option is deprecated** in favor of provider-class scope (`getProviderScope`): `off` keeps native-only auto-selection and `in-app`/`all` widen, so the flag is redundant. It is still honored for one release (like `autoSelectProvider`, it routes a no-`providers` request through the gated path) and will be removed in a later major ([#9414](https://github.com/MetaMask/core/pull/9414))
|
|
26
|
+
|
|
10
27
|
## [15.1.0]
|
|
11
28
|
|
|
12
29
|
### Added
|
package/dist/RampsController.cjs
CHANGED
|
@@ -15,6 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.RampsController = exports.getInternalOrderCode = exports.normalizeProviderCode = exports.getDefaultRampsControllerState = exports.RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS = exports.controllerName = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
17
17
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
18
|
+
const providerAvailability_1 = require("./providerAvailability.cjs");
|
|
19
|
+
const quoteSelection_1 = require("./quoteSelection.cjs");
|
|
18
20
|
const rampsErrorCodes_1 = require("./rampsErrorCodes.cjs");
|
|
19
21
|
const RampsService_1 = require("./RampsService.cjs");
|
|
20
22
|
const RequestCache_1 = require("./RequestCache.cjs");
|
|
@@ -991,11 +993,17 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
991
993
|
* during auto-selection, in priority order (e.g. derived by the caller
|
|
992
994
|
* from completed-order history). Only used when `autoSelectProvider` is
|
|
993
995
|
* true and `providers` is omitted.
|
|
994
|
-
* @param options.restrictToKnownOrNativeProviders -
|
|
995
|
-
*
|
|
996
|
-
*
|
|
997
|
-
*
|
|
998
|
-
*
|
|
996
|
+
* @param options.restrictToKnownOrNativeProviders - **Deprecated** (still
|
|
997
|
+
* honored for one release). Headless-buy v0 gating: when true,
|
|
998
|
+
* auto-selection resolves only a native provider, and an explicitly passed
|
|
999
|
+
* `providers` list is filtered to those supporting the region and asset; if
|
|
1000
|
+
* nothing qualifies, `getQuotes` returns an empty response instead of
|
|
1001
|
+
* quoting other providers. Provider-class scope (`getProviderScope`) is now
|
|
1002
|
+
* the gate (`off` stays native-only; `in-app`/`all` widen), so this flag is
|
|
1003
|
+
* redundant and will be removed in a later major. Like `autoSelectProvider`,
|
|
1004
|
+
* it still routes a no-`providers` request through the gated path so
|
|
1005
|
+
* existing callers keep working; new callers should rely on the scope
|
|
1006
|
+
* instead of passing this flag.
|
|
999
1007
|
* @param options.redirectUrl - Optional redirect URL after order completion.
|
|
1000
1008
|
* @param options.action - The ramp action type. Defaults to 'buy'.
|
|
1001
1009
|
* @param options.forceRefresh - Whether to bypass cache.
|
|
@@ -1016,17 +1024,24 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
1016
1024
|
if (normalizedAssetIdForValidation === '') {
|
|
1017
1025
|
throw new Error('assetId is required.');
|
|
1018
1026
|
}
|
|
1019
|
-
//
|
|
1020
|
-
// auto-selection
|
|
1021
|
-
//
|
|
1022
|
-
//
|
|
1027
|
+
// Provider-class scope is the gate (P2.M8): `off` keeps native-only
|
|
1028
|
+
// auto-selection (the kill switch); `in-app`/`all` widen the auto-selection
|
|
1029
|
+
// path to every supporting provider and pick the best quote from the
|
|
1030
|
+
// results (in-app vs external is only knowable per-quote via
|
|
1031
|
+
// `buyWidget.browser`). Only the auto-select path that MM Pay's
|
|
1023
1032
|
// `getRampsQuote` uses is affected; explicit-`providers` callers and the
|
|
1024
1033
|
// plain all-provider path are untouched.
|
|
1025
1034
|
const providerScope = __classPrivateFieldGet(this, _RampsController_getProviderScope, "f").call(this);
|
|
1026
|
-
const
|
|
1027
|
-
|
|
1035
|
+
const scopeWidens = providerScope !== 'off';
|
|
1036
|
+
// The auto-select entry path. `restrictToKnownOrNativeProviders` is
|
|
1037
|
+
// `@deprecated` (P2.M8) but still honored here: like `autoSelectProvider`,
|
|
1038
|
+
// it routes a no-explicit-`providers` request through the resolved/gated
|
|
1039
|
+
// path, so existing callers (TPC `getRampsQuote`) are unaffected until the
|
|
1040
|
+
// option is removed in a later major.
|
|
1041
|
+
const usesAutoSelectPath = !options.providers &&
|
|
1028
1042
|
(options.autoSelectProvider === true ||
|
|
1029
1043
|
options.restrictToKnownOrNativeProviders === true);
|
|
1044
|
+
const widenToInAppProviders = scopeWidens && usesAutoSelectPath;
|
|
1030
1045
|
let providersToUse;
|
|
1031
1046
|
let inAppProviderCatalog = this.state.providers.data;
|
|
1032
1047
|
if (options.providers) {
|
|
@@ -1083,7 +1098,8 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
1083
1098
|
// `restrictToKnownOrNativeProviders`), and an empty supporting set must not
|
|
1084
1099
|
// fall through to unfiltered quotes from providers that do not support the
|
|
1085
1100
|
// asset.
|
|
1086
|
-
if ((
|
|
1101
|
+
if ((widenToInAppProviders ||
|
|
1102
|
+
options.restrictToKnownOrNativeProviders === true) &&
|
|
1087
1103
|
providersToUse.length === 0) {
|
|
1088
1104
|
return { success: [], sorted: [], error: [], customActions: [] };
|
|
1089
1105
|
}
|
|
@@ -1898,62 +1914,13 @@ _RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheM
|
|
|
1898
1914
|
state.userRegion = userRegion;
|
|
1899
1915
|
});
|
|
1900
1916
|
}, _RampsController_pickInAppQuote = function _RampsController_pickInAppQuote(response, { scope, amount, fiat, providers, }) {
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
const limit = provider?.limits?.fiat?.[fiat]?.[quote.quote.paymentMethod];
|
|
1909
|
-
if (!limit) {
|
|
1910
|
-
// No published limits for this provider/payment method: treat as
|
|
1911
|
-
// eligible and let the provider enforce limits at checkout.
|
|
1912
|
-
return true;
|
|
1913
|
-
}
|
|
1914
|
-
return amount >= limit.minAmount && amount <= limit.maxAmount;
|
|
1915
|
-
};
|
|
1916
|
-
const isEligible = (quote) => {
|
|
1917
|
-
// `all` (Phase 2) skips the in-app-only exclusions; both scopes still
|
|
1918
|
-
// enforce provider limits up front.
|
|
1919
|
-
if (scope !== 'all') {
|
|
1920
|
-
const providerCode = normalizeProviderCode(quote.provider);
|
|
1921
|
-
if (customActionProviderCodes.has(providerCode)) {
|
|
1922
|
-
return false;
|
|
1923
|
-
}
|
|
1924
|
-
// Defensive: the wire may carry an inline `isCustomAction` flag that is
|
|
1925
|
-
// absent from the published `Quote` type.
|
|
1926
|
-
if (quote.quote.isCustomAction === true) {
|
|
1927
|
-
return false;
|
|
1928
|
-
}
|
|
1929
|
-
if (quote.quote.buyWidget?.browser === 'IN_APP_OS_BROWSER') {
|
|
1930
|
-
return false;
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
return fitsProviderLimits(quote);
|
|
1934
|
-
};
|
|
1935
|
-
const candidates = response.success.filter(isEligible);
|
|
1936
|
-
if (candidates.length === 0) {
|
|
1937
|
-
return undefined;
|
|
1938
|
-
}
|
|
1939
|
-
const candidateByCode = new Map(candidates.map((quote) => [normalizeProviderCode(quote.provider), quote]));
|
|
1940
|
-
const pickBySortOrder = (sortBy) => {
|
|
1941
|
-
const order = response.sorted.find((entry) => entry.sortBy === sortBy)?.ids;
|
|
1942
|
-
if (!order) {
|
|
1943
|
-
return undefined;
|
|
1944
|
-
}
|
|
1945
|
-
for (const providerId of order) {
|
|
1946
|
-
const match = candidateByCode.get(normalizeProviderCode(providerId));
|
|
1947
|
-
if (match) {
|
|
1948
|
-
return match;
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
return undefined;
|
|
1952
|
-
};
|
|
1953
|
-
// Reliability first, then price, then the first surviving candidate.
|
|
1954
|
-
return (pickBySortOrder('reliability') ??
|
|
1955
|
-
pickBySortOrder('price') ??
|
|
1956
|
-
candidates[0]);
|
|
1917
|
+
return (0, quoteSelection_1.getSmartSelectedQuote)(response, {
|
|
1918
|
+
scope,
|
|
1919
|
+
amount,
|
|
1920
|
+
fiat,
|
|
1921
|
+
providers,
|
|
1922
|
+
preferredProviderIds: __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_getPreferredProviderIdsFromOrders).call(this),
|
|
1923
|
+
});
|
|
1957
1924
|
}, _RampsController_getSupportingProvidersForRegion =
|
|
1958
1925
|
/**
|
|
1959
1926
|
* Returns the region's providers that support the given asset, plus the full
|
|
@@ -1977,18 +1944,10 @@ async function _RampsController_getSupportingProvidersForRegion({ assetId, regio
|
|
|
1977
1944
|
else {
|
|
1978
1945
|
({ providers } = await this.getProviders(normalizedRegion));
|
|
1979
1946
|
}
|
|
1980
|
-
//
|
|
1981
|
-
//
|
|
1982
|
-
//
|
|
1983
|
-
|
|
1984
|
-
const normalizedAssetId = assetId.toLowerCase();
|
|
1985
|
-
const supporting = providers.filter((provider) => {
|
|
1986
|
-
const map = provider?.supportedCryptoCurrencies;
|
|
1987
|
-
if (!map) {
|
|
1988
|
-
return false;
|
|
1989
|
-
}
|
|
1990
|
-
return Object.keys(map).some((key) => key.toLowerCase() === normalizedAssetId);
|
|
1991
|
-
});
|
|
1947
|
+
// Case-insensitive CAIP-19 matching is shared with headless-buy consumers
|
|
1948
|
+
// via `getProvidersServingAsset`, so the controller and the UI region gate
|
|
1949
|
+
// cannot disagree about which providers serve the asset.
|
|
1950
|
+
const supporting = (0, providerAvailability_1.getProvidersServingAsset)(providers, assetId);
|
|
1992
1951
|
return { supporting, all: providers };
|
|
1993
1952
|
}, _RampsController_filterProviderIdsBySupport =
|
|
1994
1953
|
/**
|