@metamask/ramps-controller 10.2.0 → 12.0.0
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 +19 -1
- package/dist/RampsController.cjs +110 -28
- package/dist/RampsController.cjs.map +1 -1
- package/dist/RampsController.d.cts +29 -11
- package/dist/RampsController.d.cts.map +1 -1
- package/dist/RampsController.d.mts +29 -11
- package/dist/RampsController.d.mts.map +1 -1
- package/dist/RampsController.mjs +108 -27
- package/dist/RampsController.mjs.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [12.0.0]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **BREAKING:** Update state hydration to make `init()` idempotent and remove `hydrateState()` ([#8157](https://github.com/MetaMask/core/pull/8157))
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
- Remove `hydrateState()` — use `init()` as the single entry point for controller hydration
|
|
19
|
+
|
|
20
|
+
## [11.0.0]
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **BREAKING:** Replace `getWidgetUrl` with `getBuyWidgetData` (returns `BuyWidget | null`); add `addPrecreatedOrder` for custom-action ramp flows (e.g., PayPal, Robinhood, Coinbase) ([#8100](https://github.com/MetaMask/core/pull/8100))
|
|
25
|
+
|
|
10
26
|
## [10.2.0]
|
|
11
27
|
|
|
12
28
|
### Fixed
|
|
@@ -198,7 +214,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
198
214
|
- Add `OnRampService` for interacting with the OnRamp API
|
|
199
215
|
- Add geolocation detection via IP address lookup
|
|
200
216
|
|
|
201
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@
|
|
217
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@12.0.0...HEAD
|
|
218
|
+
[12.0.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@11.0.0...@metamask/ramps-controller@12.0.0
|
|
219
|
+
[11.0.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@10.2.0...@metamask/ramps-controller@11.0.0
|
|
202
220
|
[10.2.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@10.1.0...@metamask/ramps-controller@10.2.0
|
|
203
221
|
[10.1.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@10.0.0...@metamask/ramps-controller@10.1.0
|
|
204
222
|
[10.0.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@9.0.0...@metamask/ramps-controller@10.0.0
|
package/dist/RampsController.cjs
CHANGED
|
@@ -10,9 +10,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
11
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
12
|
};
|
|
13
|
-
var _RampsController_instances, _RampsController_requestCacheTTL, _RampsController_requestCacheMaxSize, _RampsController_pendingRequests, _RampsController_pendingResourceCount, _RampsController_orderPollingMeta, _RampsController_orderPollingTimer, _RampsController_isPolling, _RampsController_clearPendingResourceCountForDependentResources, _RampsController_abortDependentRequests, _RampsController_registerActionHandlers, _RampsController_mutateRequests, _RampsController_removeRequestState, _RampsController_cleanupState, _RampsController_fireAndForget, _RampsController_requireRegion, _RampsController_isRegionCurrent, _RampsController_isTokenCurrent, _RampsController_isProviderCurrent, _RampsController_updateResourceField, _RampsController_setResourceLoading, _RampsController_setResourceError, _RampsController_updateRequestState, _RampsController_refreshOrder, _RampsController_pollPendingOrders, _RampsController_syncTransakAuthOnError;
|
|
13
|
+
var _RampsController_instances, _RampsController_requestCacheTTL, _RampsController_requestCacheMaxSize, _RampsController_pendingRequests, _RampsController_pendingResourceCount, _RampsController_orderPollingMeta, _RampsController_orderPollingTimer, _RampsController_isPolling, _RampsController_initPromise, _RampsController_clearPendingResourceCountForDependentResources, _RampsController_abortDependentRequests, _RampsController_registerActionHandlers, _RampsController_mutateRequests, _RampsController_removeRequestState, _RampsController_cleanupState, _RampsController_fireAndForget, _RampsController_requireRegion, _RampsController_isRegionCurrent, _RampsController_isTokenCurrent, _RampsController_isProviderCurrent, _RampsController_updateResourceField, _RampsController_setResourceLoading, _RampsController_setResourceError, _RampsController_updateRequestState, _RampsController_runInit, _RampsController_refreshOrder, _RampsController_pollPendingOrders, _RampsController_syncTransakAuthOnError;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.RampsController = exports.getDefaultRampsControllerState = exports.RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS = exports.controllerName = void 0;
|
|
15
|
+
exports.RampsController = 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 RampsService_1 = require("./RampsService.cjs");
|
|
18
18
|
const RequestCache_1 = require("./RequestCache.cjs");
|
|
@@ -250,6 +250,10 @@ function findRegionFromCode(regionCode, countries) {
|
|
|
250
250
|
regionCode: normalizedCode,
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
|
+
function normalizeProviderCode(providerCode) {
|
|
254
|
+
return providerCode.replace(/^\/providers\//u, '');
|
|
255
|
+
}
|
|
256
|
+
exports.normalizeProviderCode = normalizeProviderCode;
|
|
253
257
|
// === ORDER POLLING CONSTANTS ===
|
|
254
258
|
const TERMINAL_ORDER_STATUSES = new Set([
|
|
255
259
|
RampsService_1.RampsOrderStatus.Completed,
|
|
@@ -323,6 +327,7 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
323
327
|
_RampsController_orderPollingMeta.set(this, new Map());
|
|
324
328
|
_RampsController_orderPollingTimer.set(this, null);
|
|
325
329
|
_RampsController_isPolling.set(this, false);
|
|
330
|
+
_RampsController_initPromise.set(this, null);
|
|
326
331
|
__classPrivateFieldSet(this, _RampsController_requestCacheTTL, requestCacheTTL, "f");
|
|
327
332
|
__classPrivateFieldSet(this, _RampsController_requestCacheMaxSize, requestCacheMaxSize, "f");
|
|
328
333
|
__classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_registerActionHandlers).call(this);
|
|
@@ -565,25 +570,28 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
565
570
|
* Initializes the controller by fetching the user's region from geolocation.
|
|
566
571
|
* This should be called once at app startup to set up the initial region.
|
|
567
572
|
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
573
|
+
* Idempotent: subsequent calls return the same promise unless forceRefresh is set.
|
|
574
|
+
* Skips getCountries when countries are already loaded; skips geolocation when
|
|
575
|
+
* userRegion already exists.
|
|
570
576
|
*
|
|
571
|
-
* @param options - Options for cache behavior.
|
|
577
|
+
* @param options - Options for cache behavior. forceRefresh bypasses idempotency and re-runs the full flow.
|
|
572
578
|
* @returns Promise that resolves when initialization is complete.
|
|
573
579
|
*/
|
|
574
580
|
async init(options) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
regionCode ?? (regionCode = await this.messenger.call('RampsService:getGeolocation'));
|
|
578
|
-
if (!regionCode) {
|
|
579
|
-
throw new Error('Failed to fetch geolocation. Cannot initialize controller without valid region information.');
|
|
581
|
+
if (!options?.forceRefresh && __classPrivateFieldGet(this, _RampsController_initPromise, "f") !== null) {
|
|
582
|
+
return __classPrivateFieldGet(this, _RampsController_initPromise, "f");
|
|
580
583
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
const
|
|
585
|
-
|
|
586
|
-
|
|
584
|
+
if (options?.forceRefresh) {
|
|
585
|
+
__classPrivateFieldSet(this, _RampsController_initPromise, null, "f");
|
|
586
|
+
}
|
|
587
|
+
const initPromise = __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_runInit).call(this, options).then(() => undefined, (error) => {
|
|
588
|
+
if (__classPrivateFieldGet(this, _RampsController_initPromise, "f") === initPromise) {
|
|
589
|
+
__classPrivateFieldSet(this, _RampsController_initPromise, null, "f");
|
|
590
|
+
}
|
|
591
|
+
throw error;
|
|
592
|
+
});
|
|
593
|
+
__classPrivateFieldSet(this, _RampsController_initPromise, initPromise, "f");
|
|
594
|
+
return initPromise;
|
|
587
595
|
}
|
|
588
596
|
/**
|
|
589
597
|
* Fetches the list of supported countries.
|
|
@@ -945,25 +953,74 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
945
953
|
super.destroy();
|
|
946
954
|
}
|
|
947
955
|
/**
|
|
948
|
-
* Fetches the widget
|
|
956
|
+
* Fetches the widget data from a quote for redirect providers.
|
|
949
957
|
* Makes a request to the buyURL endpoint via the RampsService to get the
|
|
950
|
-
* actual provider widget URL.
|
|
958
|
+
* actual provider widget URL and optional order ID for polling.
|
|
951
959
|
*
|
|
952
960
|
* @param quote - The quote to fetch the widget URL from.
|
|
953
|
-
* @returns Promise resolving to the
|
|
961
|
+
* @returns Promise resolving to the full BuyWidget (url, browser, orderId), or null if not available (missing buyURL or empty url in response).
|
|
962
|
+
* @throws Rethrows errors from the RampsService (e.g. HttpError, network failures) so clients can react to fetch failures.
|
|
954
963
|
*/
|
|
955
|
-
async
|
|
964
|
+
async getBuyWidgetData(quote) {
|
|
956
965
|
const buyUrl = quote.quote?.buyURL;
|
|
957
966
|
if (!buyUrl) {
|
|
958
967
|
return null;
|
|
959
968
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
return buyWidget.url ?? null;
|
|
963
|
-
}
|
|
964
|
-
catch {
|
|
969
|
+
const buyWidget = await this.messenger.call('RampsService:getBuyWidgetUrl', buyUrl);
|
|
970
|
+
if (!buyWidget?.url) {
|
|
965
971
|
return null;
|
|
966
972
|
}
|
|
973
|
+
return buyWidget;
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* Registers an order ID for polling until the order is created or resolved.
|
|
977
|
+
* Adds a minimal stub order to controller state; the existing order polling
|
|
978
|
+
* will fetch the full order when the provider has created it.
|
|
979
|
+
*
|
|
980
|
+
* @param params - Object containing order identifiers and wallet info.
|
|
981
|
+
* @param params.orderId - Full order ID (e.g. "/providers/paypal/orders/abc123") or order code.
|
|
982
|
+
* @param params.providerCode - Provider code (e.g. "paypal", "transak"), with or without /providers/ prefix.
|
|
983
|
+
* @param params.walletAddress - Wallet address for the order.
|
|
984
|
+
* @param params.chainId - Optional chain ID for the order.
|
|
985
|
+
*/
|
|
986
|
+
addPrecreatedOrder(params) {
|
|
987
|
+
const { orderId, providerCode, walletAddress, chainId } = params;
|
|
988
|
+
const orderCode = orderId.includes('/orders/')
|
|
989
|
+
? orderId.split('/orders/')[1]
|
|
990
|
+
: orderId;
|
|
991
|
+
if (!orderCode?.trim()) {
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
const normalizedProviderCode = normalizeProviderCode(providerCode);
|
|
995
|
+
const stubOrder = {
|
|
996
|
+
providerOrderId: orderCode,
|
|
997
|
+
provider: {
|
|
998
|
+
id: `/providers/${normalizedProviderCode}`,
|
|
999
|
+
name: '',
|
|
1000
|
+
environmentType: '',
|
|
1001
|
+
description: '',
|
|
1002
|
+
hqAddress: '',
|
|
1003
|
+
links: [],
|
|
1004
|
+
logos: { light: '', dark: '', height: 0, width: 0 },
|
|
1005
|
+
},
|
|
1006
|
+
walletAddress,
|
|
1007
|
+
status: RampsService_1.RampsOrderStatus.Precreated,
|
|
1008
|
+
orderType: 'buy',
|
|
1009
|
+
createdAt: Date.now(),
|
|
1010
|
+
isOnlyLink: false,
|
|
1011
|
+
success: false,
|
|
1012
|
+
cryptoAmount: 0,
|
|
1013
|
+
fiatAmount: 0,
|
|
1014
|
+
providerOrderLink: '',
|
|
1015
|
+
totalFeesFiat: 0,
|
|
1016
|
+
txHash: '',
|
|
1017
|
+
network: chainId ? { chainId, name: '' } : { chainId: '', name: '' },
|
|
1018
|
+
canBeUpdated: true,
|
|
1019
|
+
idHasExpired: false,
|
|
1020
|
+
excludeFromPurchases: false,
|
|
1021
|
+
timeDescriptionPending: '',
|
|
1022
|
+
};
|
|
1023
|
+
this.addOrder(stubOrder);
|
|
967
1024
|
}
|
|
968
1025
|
/**
|
|
969
1026
|
* Fetches an order from the unified V2 API endpoint.
|
|
@@ -978,10 +1035,17 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
978
1035
|
const order = await this.messenger.call('RampsService:getOrder', providerCode, orderCode, wallet);
|
|
979
1036
|
this.update((state) => {
|
|
980
1037
|
const idx = state.orders.findIndex((existing) => existing.providerOrderId === orderCode);
|
|
981
|
-
if (idx
|
|
1038
|
+
if (idx === -1) {
|
|
1039
|
+
state.orders.push({
|
|
1040
|
+
...order,
|
|
1041
|
+
providerOrderId: orderCode,
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
else {
|
|
982
1045
|
state.orders[idx] = {
|
|
983
1046
|
...state.orders[idx],
|
|
984
1047
|
...order,
|
|
1048
|
+
providerOrderId: orderCode,
|
|
985
1049
|
};
|
|
986
1050
|
}
|
|
987
1051
|
});
|
|
@@ -1397,7 +1461,7 @@ class RampsController extends base_controller_1.BaseController {
|
|
|
1397
1461
|
}
|
|
1398
1462
|
}
|
|
1399
1463
|
exports.RampsController = RampsController;
|
|
1400
|
-
_RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheMaxSize = new WeakMap(), _RampsController_pendingRequests = new WeakMap(), _RampsController_pendingResourceCount = new WeakMap(), _RampsController_orderPollingMeta = new WeakMap(), _RampsController_orderPollingTimer = new WeakMap(), _RampsController_isPolling = new WeakMap(), _RampsController_instances = new WeakSet(), _RampsController_clearPendingResourceCountForDependentResources = function _RampsController_clearPendingResourceCountForDependentResources() {
|
|
1464
|
+
_RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheMaxSize = new WeakMap(), _RampsController_pendingRequests = new WeakMap(), _RampsController_pendingResourceCount = new WeakMap(), _RampsController_orderPollingMeta = new WeakMap(), _RampsController_orderPollingTimer = new WeakMap(), _RampsController_isPolling = new WeakMap(), _RampsController_initPromise = new WeakMap(), _RampsController_instances = new WeakSet(), _RampsController_clearPendingResourceCountForDependentResources = function _RampsController_clearPendingResourceCountForDependentResources() {
|
|
1401
1465
|
for (const resourceType of DEPENDENT_RESOURCE_KEYS) {
|
|
1402
1466
|
__classPrivateFieldGet(this, _RampsController_pendingResourceCount, "f").delete(resourceType);
|
|
1403
1467
|
}
|
|
@@ -1484,6 +1548,24 @@ _RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheM
|
|
|
1484
1548
|
}
|
|
1485
1549
|
}
|
|
1486
1550
|
});
|
|
1551
|
+
}, _RampsController_runInit = async function _RampsController_runInit(options) {
|
|
1552
|
+
const forceRefresh = options?.forceRefresh === true;
|
|
1553
|
+
const hasCountries = this.state.countries.data.length > 0;
|
|
1554
|
+
if (forceRefresh || !hasCountries) {
|
|
1555
|
+
await this.getCountries(options);
|
|
1556
|
+
}
|
|
1557
|
+
let regionCode;
|
|
1558
|
+
if (forceRefresh) {
|
|
1559
|
+
regionCode = await this.messenger.call('RampsService:getGeolocation');
|
|
1560
|
+
}
|
|
1561
|
+
else {
|
|
1562
|
+
regionCode = this.state.userRegion?.regionCode;
|
|
1563
|
+
regionCode ?? (regionCode = await this.messenger.call('RampsService:getGeolocation'));
|
|
1564
|
+
}
|
|
1565
|
+
if (!regionCode) {
|
|
1566
|
+
throw new Error('Failed to fetch geolocation. Cannot initialize controller without valid region information.');
|
|
1567
|
+
}
|
|
1568
|
+
await this.setUserRegion(regionCode, options);
|
|
1487
1569
|
}, _RampsController_refreshOrder =
|
|
1488
1570
|
/**
|
|
1489
1571
|
* Refreshes a single order via the V2 API and updates it in state.
|
|
@@ -1496,7 +1578,7 @@ async function _RampsController_refreshOrder(order) {
|
|
|
1496
1578
|
if (!providerCode || !order.providerOrderId || !order.walletAddress) {
|
|
1497
1579
|
return;
|
|
1498
1580
|
}
|
|
1499
|
-
const providerCodeSegment = providerCode
|
|
1581
|
+
const providerCodeSegment = normalizeProviderCode(providerCode);
|
|
1500
1582
|
const previousStatus = order.status;
|
|
1501
1583
|
try {
|
|
1502
1584
|
const updatedOrder = await this.getOrder(providerCodeSegment, order.providerOrderId, order.walletAddress);
|