@metamask/ramps-controller 8.0.0 → 8.1.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/dist/RampsController.cjs +618 -116
  3. package/dist/RampsController.cjs.map +1 -1
  4. package/dist/RampsController.d.cts +261 -12
  5. package/dist/RampsController.d.cts.map +1 -1
  6. package/dist/RampsController.d.mts +261 -12
  7. package/dist/RampsController.d.mts.map +1 -1
  8. package/dist/RampsController.mjs +618 -116
  9. package/dist/RampsController.mjs.map +1 -1
  10. package/dist/RampsService.cjs.map +1 -1
  11. package/dist/RampsService.d.cts +4 -0
  12. package/dist/RampsService.d.cts.map +1 -1
  13. package/dist/RampsService.d.mts +4 -0
  14. package/dist/RampsService.d.mts.map +1 -1
  15. package/dist/RampsService.mjs.map +1 -1
  16. package/dist/RequestCache.cjs.map +1 -1
  17. package/dist/RequestCache.d.cts +2 -0
  18. package/dist/RequestCache.d.cts.map +1 -1
  19. package/dist/RequestCache.d.mts +2 -0
  20. package/dist/RequestCache.d.mts.map +1 -1
  21. package/dist/RequestCache.mjs.map +1 -1
  22. package/dist/TransakService-method-action-types.cjs +7 -0
  23. package/dist/TransakService-method-action-types.cjs.map +1 -0
  24. package/dist/TransakService-method-action-types.d.cts +106 -0
  25. package/dist/TransakService-method-action-types.d.cts.map +1 -0
  26. package/dist/TransakService-method-action-types.d.mts +106 -0
  27. package/dist/TransakService-method-action-types.d.mts.map +1 -0
  28. package/dist/TransakService-method-action-types.mjs +6 -0
  29. package/dist/TransakService-method-action-types.mjs.map +1 -0
  30. package/dist/TransakService.cjs +588 -0
  31. package/dist/TransakService.cjs.map +1 -0
  32. package/dist/TransakService.d.cts +329 -0
  33. package/dist/TransakService.d.cts.map +1 -0
  34. package/dist/TransakService.d.mts +329 -0
  35. package/dist/TransakService.d.mts.map +1 -0
  36. package/dist/TransakService.mjs +582 -0
  37. package/dist/TransakService.mjs.map +1 -0
  38. package/dist/index.cjs +6 -1
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +4 -1
  41. package/dist/index.d.cts.map +1 -1
  42. package/dist/index.d.mts +4 -1
  43. package/dist/index.d.mts.map +1 -1
  44. package/dist/index.mjs +1 -0
  45. package/dist/index.mjs.map +1 -1
  46. package/package.json +1 -1
@@ -10,7 +10,7 @@ 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_quotePollingInterval, _RampsController_quotePollingOptions, _RampsController_clearPendingResourceCountForDependentResources, _RampsController_removeRequestState, _RampsController_cleanupState, _RampsController_fireAndForget, _RampsController_restartPollingIfActive, _RampsController_updateResourceField, _RampsController_setResourceLoading, _RampsController_setResourceError, _RampsController_updateRequestState;
13
+ var _RampsController_instances, _RampsController_requestCacheTTL, _RampsController_requestCacheMaxSize, _RampsController_pendingRequests, _RampsController_pendingResourceCount, _RampsController_quotePollingInterval, _RampsController_quotePollingOptions, _RampsController_clearPendingResourceCountForDependentResources, _RampsController_abortDependentRequests, _RampsController_mutateRequests, _RampsController_removeRequestState, _RampsController_cleanupState, _RampsController_fireAndForget, _RampsController_restartPollingIfActive, _RampsController_requireRegion, _RampsController_isRegionCurrent, _RampsController_isTokenCurrent, _RampsController_isProviderCurrent, _RampsController_updateResourceField, _RampsController_setResourceLoading, _RampsController_setResourceError, _RampsController_updateRequestState, _RampsController_syncWidgetUrl, _RampsController_syncTransakAuthOnError;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.RampsController = exports.getDefaultRampsControllerState = exports.RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS = exports.controllerName = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
@@ -35,6 +35,30 @@ exports.RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS = [
35
35
  'RampsService:getPaymentMethods',
36
36
  'RampsService:getQuotes',
37
37
  'RampsService:getBuyWidgetUrl',
38
+ 'TransakService:setApiKey',
39
+ 'TransakService:setAccessToken',
40
+ 'TransakService:clearAccessToken',
41
+ 'TransakService:sendUserOtp',
42
+ 'TransakService:verifyUserOtp',
43
+ 'TransakService:logout',
44
+ 'TransakService:getUserDetails',
45
+ 'TransakService:getBuyQuote',
46
+ 'TransakService:getKycRequirement',
47
+ 'TransakService:getAdditionalRequirements',
48
+ 'TransakService:createOrder',
49
+ 'TransakService:getOrder',
50
+ 'TransakService:getUserLimits',
51
+ 'TransakService:requestOtt',
52
+ 'TransakService:generatePaymentWidgetUrl',
53
+ 'TransakService:submitPurposeOfUsageForm',
54
+ 'TransakService:patchUser',
55
+ 'TransakService:submitSsnDetails',
56
+ 'TransakService:confirmPayment',
57
+ 'TransakService:getTranslation',
58
+ 'TransakService:getIdProofStatus',
59
+ 'TransakService:cancelOrder',
60
+ 'TransakService:cancelAllActiveOrders',
61
+ 'TransakService:getActiveOrders',
38
62
  ];
39
63
  /**
40
64
  * Default TTL for quotes requests (15 seconds).
@@ -81,12 +105,24 @@ const rampsControllerMetadata = {
81
105
  includeInStateLogs: false,
82
106
  usedInUi: true,
83
107
  },
108
+ widgetUrl: {
109
+ persist: false,
110
+ includeInDebugSnapshot: true,
111
+ includeInStateLogs: false,
112
+ usedInUi: true,
113
+ },
84
114
  requests: {
85
115
  persist: false,
86
116
  includeInDebugSnapshot: true,
87
117
  includeInStateLogs: false,
88
118
  usedInUi: true,
89
119
  },
120
+ nativeProviders: {
121
+ persist: false,
122
+ includeInDebugSnapshot: true,
123
+ includeInStateLogs: false,
124
+ usedInUi: true,
125
+ },
90
126
  };
91
127
  /**
92
128
  * Creates a default resource state object.
@@ -121,10 +157,47 @@ function getDefaultRampsControllerState() {
121
157
  tokens: createDefaultResourceState(null, null),
122
158
  paymentMethods: createDefaultResourceState([], null),
123
159
  quotes: createDefaultResourceState(null, null),
160
+ widgetUrl: createDefaultResourceState(null),
124
161
  requests: {},
162
+ nativeProviders: {
163
+ transak: {
164
+ isAuthenticated: false,
165
+ userDetails: createDefaultResourceState(null),
166
+ buyQuote: createDefaultResourceState(null),
167
+ kycRequirement: createDefaultResourceState(null),
168
+ },
169
+ },
125
170
  };
126
171
  }
127
172
  exports.getDefaultRampsControllerState = getDefaultRampsControllerState;
173
+ const DEPENDENT_RESOURCE_KEYS = [
174
+ 'providers',
175
+ 'tokens',
176
+ 'paymentMethods',
177
+ 'quotes',
178
+ ];
179
+ const DEPENDENT_RESOURCE_KEYS_SET = new Set(DEPENDENT_RESOURCE_KEYS);
180
+ function resetResource(state, resourceType, defaultResource) {
181
+ const def = defaultResource ?? getDefaultRampsControllerState()[resourceType];
182
+ const resource = state[resourceType];
183
+ resource.data = def.data;
184
+ resource.selected = def.selected;
185
+ resource.isLoading = def.isLoading;
186
+ resource.error = def.error;
187
+ }
188
+ /**
189
+ * Resets the widgetUrl resource to its default state.
190
+ * Mutates state in place; use from within controller update() for atomic updates.
191
+ *
192
+ * @param state - The state object to mutate.
193
+ */
194
+ function resetWidgetUrl(state) {
195
+ const def = getDefaultRampsControllerState().widgetUrl;
196
+ state.widgetUrl.data = def.data;
197
+ state.widgetUrl.selected = def.selected;
198
+ state.widgetUrl.isLoading = def.isLoading;
199
+ state.widgetUrl.error = def.error;
200
+ }
128
201
  /**
129
202
  * Resets region-dependent resources (userRegion, providers, tokens, paymentMethods, quotes).
130
203
  * Mutates state in place; use from within controller update() for atomic updates.
@@ -137,22 +210,11 @@ function resetDependentResources(state, options) {
137
210
  if (options?.clearUserRegionData) {
138
211
  state.userRegion = null;
139
212
  }
140
- state.providers.selected = null;
141
- state.providers.data = [];
142
- state.providers.isLoading = false;
143
- state.providers.error = null;
144
- state.tokens.selected = null;
145
- state.tokens.data = null;
146
- state.tokens.isLoading = false;
147
- state.tokens.error = null;
148
- state.paymentMethods.data = [];
149
- state.paymentMethods.selected = null;
150
- state.paymentMethods.isLoading = false;
151
- state.paymentMethods.error = null;
152
- state.quotes.data = null;
153
- state.quotes.selected = null;
154
- state.quotes.isLoading = false;
155
- state.quotes.error = null;
213
+ const defaultState = getDefaultRampsControllerState();
214
+ for (const key of DEPENDENT_RESOURCE_KEYS) {
215
+ resetResource(state, key, defaultState[key]);
216
+ }
217
+ resetWidgetUrl(state);
156
218
  }
157
219
  // === HELPER FUNCTIONS ===
158
220
  /**
@@ -276,31 +338,49 @@ class RampsController extends base_controller_1.BaseController {
276
338
  __classPrivateFieldSet(this, _RampsController_requestCacheMaxSize, requestCacheMaxSize, "f");
277
339
  }
278
340
  /**
279
- * Executes a request with caching and deduplication.
341
+ * Executes a request with caching, deduplication, and at most one in-flight
342
+ * request per resource type.
280
343
  *
281
- * If a request with the same cache key is already in flight, returns the
282
- * existing promise. If valid cached data exists, returns it without making
283
- * a new request.
344
+ * 1. **Same cache key in flight** – If a request with this cache key is
345
+ * already pending, returns that promise (deduplication; no second request).
284
346
  *
285
- * @param cacheKey - Unique identifier for this request.
286
- * @param fetcher - Function that performs the actual fetch. Receives an AbortSignal.
287
- * @param options - Options for cache behavior.
288
- * @returns The result of the request.
347
+ * 2. **Cache hit** – If valid, non-expired data exists in state.requests for
348
+ * this key and forceRefresh is not set, returns that data without fetching.
349
+ *
350
+ * 3. **New request** Creates an AbortController and fires the fetcher.
351
+ * If options.resourceType is set, tags the pending request with that
352
+ * resource type (so #abortDependentRequests can cancel it on region
353
+ * change or cleanup) and ref-counts resource-level loading state.
354
+ * On success or error, updates request state and resource error;
355
+ * in finally, clears resource loading only if this request was not
356
+ * aborted.
357
+ *
358
+ * @param cacheKey - Unique identifier for this request (e.g. from createCacheKey).
359
+ * @param fetcher - Async function that performs the fetch. Receives an AbortSignal
360
+ * that is aborted when this request is superseded by another for the same resource.
361
+ * @param options - Optional forceRefresh, ttl, and resourceType for loading/error state.
362
+ * @returns The result of the request (from cache, joined promise, or fetcher).
289
363
  */
290
364
  async executeRequest(cacheKey, fetcher, options) {
365
+ // Get TTL for verifying cache expiration
291
366
  const ttl = options?.ttl ?? __classPrivateFieldGet(this, _RampsController_requestCacheTTL, "f");
292
- // Check for existing pending request - join it instead of making a duplicate
367
+ // DEDUPLICATION:
368
+ // Check if a request is already in flight for this cache key
369
+ // If so, return the original promise for that request
293
370
  const pending = __classPrivateFieldGet(this, _RampsController_pendingRequests, "f").get(cacheKey);
294
371
  if (pending) {
295
372
  return pending.promise;
296
373
  }
374
+ // CACHE HIT:
375
+ // If cache is not expired, return the cached data
297
376
  if (!options?.forceRefresh) {
298
377
  const cached = this.state.requests[cacheKey];
299
378
  if (cached && !(0, RequestCache_1.isCacheExpired)(cached, ttl)) {
300
379
  return cached.data;
301
380
  }
302
381
  }
303
- // Create abort controller for this request
382
+ // Create a new abort controller for this request
383
+ // Record the time the request was started
304
384
  const abortController = new AbortController();
305
385
  const lastFetchedAt = Date.now();
306
386
  const { resourceType } = options ?? {};
@@ -319,15 +399,11 @@ class RampsController extends base_controller_1.BaseController {
319
399
  const promise = (async () => {
320
400
  try {
321
401
  const data = await fetcher(abortController.signal);
322
- // Don't update state if aborted
323
402
  if (abortController.signal.aborted) {
324
403
  throw new Error('Request was aborted');
325
404
  }
326
405
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_updateRequestState).call(this, cacheKey, (0, RequestCache_1.createSuccessState)(data, lastFetchedAt));
327
406
  if (resourceType) {
328
- // We need the extra logic because there are two situations where we’re allowed to clear the error:
329
- // No callback → always clear
330
- // Callback present → clear only when isResultCurrent() returns true.
331
407
  const isCurrent = !options?.isResultCurrent || options.isResultCurrent();
332
408
  if (isCurrent) {
333
409
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_setResourceError).call(this, resourceType, null);
@@ -336,7 +412,6 @@ class RampsController extends base_controller_1.BaseController {
336
412
  return data;
337
413
  }
338
414
  catch (error) {
339
- // Don't update state if aborted
340
415
  if (abortController.signal.aborted) {
341
416
  throw error;
342
417
  }
@@ -351,13 +426,12 @@ class RampsController extends base_controller_1.BaseController {
351
426
  throw error;
352
427
  }
353
428
  finally {
354
- // Only delete if this is still our entry (not replaced by a new request)
355
- const currentPending = __classPrivateFieldGet(this, _RampsController_pendingRequests, "f").get(cacheKey);
356
- if (currentPending?.abortController === abortController) {
429
+ if (__classPrivateFieldGet(this, _RampsController_pendingRequests, "f").get(cacheKey)?.abortController ===
430
+ abortController) {
357
431
  __classPrivateFieldGet(this, _RampsController_pendingRequests, "f").delete(cacheKey);
358
432
  }
359
433
  // Clear resource-level loading state only when no requests for this resource remain
360
- if (resourceType) {
434
+ if (resourceType && !abortController.signal.aborted) {
361
435
  const count = __classPrivateFieldGet(this, _RampsController_pendingResourceCount, "f").get(resourceType) ?? 0;
362
436
  const next = Math.max(0, count - 1);
363
437
  if (next === 0) {
@@ -370,8 +444,11 @@ class RampsController extends base_controller_1.BaseController {
370
444
  }
371
445
  }
372
446
  })();
373
- // Store pending request for deduplication
374
- __classPrivateFieldGet(this, _RampsController_pendingRequests, "f").set(cacheKey, { promise, abortController });
447
+ __classPrivateFieldGet(this, _RampsController_pendingRequests, "f").set(cacheKey, {
448
+ promise,
449
+ abortController,
450
+ resourceType,
451
+ });
375
452
  return promise;
376
453
  }
377
454
  /**
@@ -425,9 +502,8 @@ class RampsController extends base_controller_1.BaseController {
425
502
  !this.state.tokens.data ||
426
503
  this.state.providers.data.length === 0;
427
504
  if (regionChanged) {
505
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_abortDependentRequests).call(this);
428
506
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_clearPendingResourceCountForDependentResources).call(this);
429
- }
430
- if (regionChanged) {
431
507
  this.stopQuotePolling();
432
508
  }
433
509
  this.update((state) => {
@@ -468,15 +544,11 @@ class RampsController extends base_controller_1.BaseController {
468
544
  this.stopQuotePolling();
469
545
  this.update((state) => {
470
546
  state.providers.selected = null;
471
- state.paymentMethods.data = [];
472
- state.paymentMethods.selected = null;
547
+ resetResource(state, 'paymentMethods');
473
548
  });
474
549
  return;
475
550
  }
476
- const regionCode = this.state.userRegion?.regionCode;
477
- if (!regionCode) {
478
- throw new Error('Region is required. Cannot set selected provider without valid region information.');
479
- }
551
+ const regionCode = __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
480
552
  const providers = this.state.providers.data;
481
553
  if (!providers || providers.length === 0) {
482
554
  throw new Error('Providers not loaded. Cannot set selected provider before providers are fetched.');
@@ -487,9 +559,9 @@ class RampsController extends base_controller_1.BaseController {
487
559
  }
488
560
  this.update((state) => {
489
561
  state.providers.selected = provider;
490
- state.paymentMethods.data = [];
491
- state.paymentMethods.selected = null;
562
+ resetResource(state, 'paymentMethods');
492
563
  state.quotes.selected = null;
564
+ resetWidgetUrl(state);
493
565
  });
494
566
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_fireAndForget).call(this, this.getPaymentMethods(regionCode, { provider: provider.id }).then(() => {
495
567
  // Restart quote polling after payment methods are fetched
@@ -517,10 +589,7 @@ class RampsController extends base_controller_1.BaseController {
517
589
  await this.setUserRegion(regionCode, options);
518
590
  }
519
591
  hydrateState(options) {
520
- const regionCode = this.state.userRegion?.regionCode;
521
- if (!regionCode) {
522
- throw new Error('Region code is required. Cannot hydrate state without valid region information.');
523
- }
592
+ const regionCode = __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
524
593
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_fireAndForget).call(this, this.getTokens(regionCode, 'buy', options));
525
594
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_fireAndForget).call(this, this.getProviders(regionCode, options));
526
595
  }
@@ -538,7 +607,7 @@ class RampsController extends base_controller_1.BaseController {
538
607
  return this.messenger.call('RampsService:getCountries');
539
608
  }, { ...options, resourceType: 'countries' });
540
609
  this.update((state) => {
541
- state.countries.data = countries;
610
+ state.countries.data = Array.isArray(countries) ? [...countries] : [];
542
611
  });
543
612
  return countries;
544
613
  }
@@ -553,10 +622,7 @@ class RampsController extends base_controller_1.BaseController {
553
622
  * @returns The tokens response containing topTokens and allTokens.
554
623
  */
555
624
  async getTokens(region, action = 'buy', options) {
556
- const regionToUse = region ?? this.state.userRegion?.regionCode;
557
- if (!regionToUse) {
558
- throw new Error('Region is required. Either provide a region parameter or ensure userRegion is set in controller state.');
559
- }
625
+ const regionToUse = region ?? __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
560
626
  const normalizedRegion = regionToUse.toLowerCase().trim();
561
627
  const cacheKey = (0, RequestCache_1.createCacheKey)('getTokens', [
562
628
  normalizedRegion,
@@ -570,8 +636,7 @@ class RampsController extends base_controller_1.BaseController {
570
636
  }, {
571
637
  ...options,
572
638
  resourceType: 'tokens',
573
- isResultCurrent: () => this.state.userRegion?.regionCode === undefined ||
574
- this.state.userRegion?.regionCode === normalizedRegion,
639
+ isResultCurrent: () => __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_isRegionCurrent).call(this, normalizedRegion),
575
640
  });
576
641
  this.update((state) => {
577
642
  const userRegionCode = state.userRegion?.regionCode;
@@ -594,15 +659,11 @@ class RampsController extends base_controller_1.BaseController {
594
659
  this.stopQuotePolling();
595
660
  this.update((state) => {
596
661
  state.tokens.selected = null;
597
- state.paymentMethods.data = [];
598
- state.paymentMethods.selected = null;
662
+ resetResource(state, 'paymentMethods');
599
663
  });
600
664
  return;
601
665
  }
602
- const regionCode = this.state.userRegion?.regionCode;
603
- if (!regionCode) {
604
- throw new Error('Region is required. Cannot set selected token without valid region information.');
605
- }
666
+ const regionCode = __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
606
667
  const tokens = this.state.tokens.data;
607
668
  if (!tokens) {
608
669
  throw new Error('Tokens not loaded. Cannot set selected token before tokens are fetched.');
@@ -614,9 +675,9 @@ class RampsController extends base_controller_1.BaseController {
614
675
  }
615
676
  this.update((state) => {
616
677
  state.tokens.selected = token;
617
- state.paymentMethods.data = [];
618
- state.paymentMethods.selected = null;
678
+ resetResource(state, 'paymentMethods');
619
679
  state.quotes.selected = null;
680
+ resetWidgetUrl(state);
620
681
  });
621
682
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_fireAndForget).call(this, this.getPaymentMethods(regionCode, { assetId: token.assetId }).then(() => {
622
683
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_restartPollingIfActive).call(this);
@@ -636,10 +697,7 @@ class RampsController extends base_controller_1.BaseController {
636
697
  * @returns The providers response containing providers array.
637
698
  */
638
699
  async getProviders(region, options) {
639
- const regionToUse = region ?? this.state.userRegion?.regionCode;
640
- if (!regionToUse) {
641
- throw new Error('Region is required. Either provide a region parameter or ensure userRegion is set in controller state.');
642
- }
700
+ const regionToUse = region ?? __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
643
701
  const normalizedRegion = regionToUse.toLowerCase().trim();
644
702
  const cacheKey = (0, RequestCache_1.createCacheKey)('getProviders', [
645
703
  normalizedRegion,
@@ -658,8 +716,7 @@ class RampsController extends base_controller_1.BaseController {
658
716
  }, {
659
717
  ...options,
660
718
  resourceType: 'providers',
661
- isResultCurrent: () => this.state.userRegion?.regionCode === undefined ||
662
- this.state.userRegion?.regionCode === normalizedRegion,
719
+ isResultCurrent: () => __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_isRegionCurrent).call(this, normalizedRegion),
663
720
  });
664
721
  this.update((state) => {
665
722
  const userRegionCode = state.userRegion?.regionCode;
@@ -681,13 +738,10 @@ class RampsController extends base_controller_1.BaseController {
681
738
  * @returns The payment methods response containing payments array.
682
739
  */
683
740
  async getPaymentMethods(region, options) {
684
- const regionCode = region ?? this.state.userRegion?.regionCode ?? null;
741
+ const regionCode = region ?? __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
685
742
  const fiatToUse = options?.fiat ?? this.state.userRegion?.country?.currency ?? null;
686
743
  const assetIdToUse = options?.assetId ?? this.state.tokens.selected?.assetId ?? '';
687
744
  const providerToUse = options?.provider ?? this.state.providers.selected?.id ?? '';
688
- if (!regionCode) {
689
- throw new Error('Region is required. Either provide a region parameter or ensure userRegion is set in controller state.');
690
- }
691
745
  if (!fiatToUse) {
692
746
  throw new Error('Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.');
693
747
  }
@@ -710,10 +764,9 @@ class RampsController extends base_controller_1.BaseController {
710
764
  ...options,
711
765
  resourceType: 'paymentMethods',
712
766
  isResultCurrent: () => {
713
- const regionMatch = this.state.userRegion?.regionCode === undefined ||
714
- this.state.userRegion?.regionCode === normalizedRegion;
715
- const tokenMatch = (this.state.tokens.selected?.assetId ?? '') === assetIdToUse;
716
- const providerMatch = (this.state.providers.selected?.id ?? '') === providerToUse;
767
+ const regionMatch = __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_isRegionCurrent).call(this, normalizedRegion);
768
+ const tokenMatch = __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_isTokenCurrent).call(this, assetIdToUse);
769
+ const providerMatch = __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_isProviderCurrent).call(this, providerToUse);
717
770
  return regionMatch && tokenMatch && providerMatch;
718
771
  },
719
772
  });
@@ -783,7 +836,7 @@ class RampsController extends base_controller_1.BaseController {
783
836
  * @returns The quotes response containing success, sorted, error, and customActions.
784
837
  */
785
838
  async getQuotes(options) {
786
- const regionToUse = options.region ?? this.state.userRegion?.regionCode;
839
+ const regionToUse = options.region ?? __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
787
840
  const fiatToUse = options.fiat ?? this.state.userRegion?.country?.currency;
788
841
  const paymentMethodsToUse = options.paymentMethods ??
789
842
  this.state.paymentMethods.data.map((pm) => pm.id);
@@ -791,9 +844,6 @@ class RampsController extends base_controller_1.BaseController {
791
844
  this.state.providers.data.map((provider) => provider.id);
792
845
  const action = options.action ?? 'buy';
793
846
  const assetIdToUse = options.assetId ?? this.state.tokens.selected?.assetId;
794
- if (!regionToUse) {
795
- throw new Error('Region is required. Either provide a region parameter or ensure userRegion is set in controller state.');
796
- }
797
847
  if (!fiatToUse) {
798
848
  throw new Error('Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.');
799
849
  }
@@ -844,8 +894,7 @@ class RampsController extends base_controller_1.BaseController {
844
894
  forceRefresh: options.forceRefresh,
845
895
  ttl: options.ttl ?? DEFAULT_QUOTES_TTL,
846
896
  resourceType: 'quotes',
847
- isResultCurrent: () => this.state.userRegion?.regionCode === undefined ||
848
- this.state.userRegion?.regionCode === normalizedRegion,
897
+ isResultCurrent: () => __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_isRegionCurrent).call(this, normalizedRegion),
849
898
  });
850
899
  this.update((state) => {
851
900
  const userRegionCode = state.userRegion?.regionCode;
@@ -861,21 +910,20 @@ class RampsController extends base_controller_1.BaseController {
861
910
  * If the response contains exactly one quote, it is auto-selected.
862
911
  * If multiple quotes are returned, the existing selection is preserved if still valid.
863
912
  *
913
+ * Returns early (no-op) if the selected payment method is not yet set,
914
+ * allowing callers to invoke this before payment-method selection is finalized.
915
+ *
864
916
  * @param options - Parameters for fetching quotes.
865
917
  * @param options.walletAddress - The destination wallet address.
866
918
  * @param options.amount - The amount (in fiat for buy, crypto for sell).
867
919
  * @param options.redirectUrl - Optional redirect URL after order completion.
868
- * @throws If required dependencies (region, token, provider, payment method) are not set.
920
+ * @throws If required dependencies (region, token, provider) are not set.
869
921
  */
870
922
  startQuotePolling(options) {
871
- // Validate required dependencies
872
- const regionCode = this.state.userRegion?.regionCode;
923
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_requireRegion).call(this);
873
924
  const token = this.state.tokens.selected;
874
925
  const provider = this.state.providers.selected;
875
926
  const paymentMethod = this.state.paymentMethods.selected;
876
- if (!regionCode) {
877
- throw new Error('Region is required. Cannot start quote polling without valid region information.');
878
- }
879
927
  if (!token) {
880
928
  throw new Error('Token is required. Cannot start quote polling without a selected token.');
881
929
  }
@@ -900,10 +948,12 @@ class RampsController extends base_controller_1.BaseController {
900
948
  providers: [provider.id],
901
949
  forceRefresh: true,
902
950
  }).then((response) => {
951
+ let newSelectedQuote = null;
903
952
  // Auto-select logic: only when exactly one quote is returned
904
953
  this.update((state) => {
905
954
  if (response.success.length === 1) {
906
- state.quotes.selected = response.success[0];
955
+ newSelectedQuote = response.success[0];
956
+ state.quotes.selected = newSelectedQuote;
907
957
  }
908
958
  else {
909
959
  // Keep existing selection if still valid, but update with fresh data
@@ -912,11 +962,12 @@ class RampsController extends base_controller_1.BaseController {
912
962
  const freshQuote = response.success.find((quote) => quote.provider === currentSelection.provider &&
913
963
  quote.quote.paymentMethod ===
914
964
  currentSelection.quote.paymentMethod);
915
- // Update with fresh quote data, or clear if no longer valid
916
- state.quotes.selected = freshQuote ?? null;
965
+ newSelectedQuote = freshQuote ?? null;
966
+ state.quotes.selected = newSelectedQuote;
917
967
  }
918
968
  }
919
969
  });
970
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncWidgetUrl).call(this, newSelectedQuote);
920
971
  return undefined;
921
972
  }));
922
973
  };
@@ -938,6 +989,7 @@ class RampsController extends base_controller_1.BaseController {
938
989
  }
939
990
  /**
940
991
  * Manually sets the selected quote.
992
+ * Automatically triggers a widget URL fetch for the new quote.
941
993
  *
942
994
  * @param quote - The quote to select, or null to clear the selection.
943
995
  */
@@ -945,6 +997,7 @@ class RampsController extends base_controller_1.BaseController {
945
997
  this.update((state) => {
946
998
  state.quotes.selected = quote;
947
999
  });
1000
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncWidgetUrl).call(this, quote);
948
1001
  }
949
1002
  /**
950
1003
  * Cleans up controller resources.
@@ -962,6 +1015,8 @@ class RampsController extends base_controller_1.BaseController {
962
1015
  *
963
1016
  * @param quote - The quote to fetch the widget URL from.
964
1017
  * @returns Promise resolving to the widget URL string, or null if not available.
1018
+ * @deprecated Read `state.widgetUrl` instead. The widget URL is now automatically
1019
+ * fetched and stored in state whenever the selected quote changes.
965
1020
  */
966
1021
  async getWidgetUrl(quote) {
967
1022
  const buyUrl = quote.quote?.buyURL;
@@ -972,34 +1027,433 @@ class RampsController extends base_controller_1.BaseController {
972
1027
  const buyWidget = await this.messenger.call('RampsService:getBuyWidgetUrl', buyUrl);
973
1028
  return buyWidget.url ?? null;
974
1029
  }
975
- catch (error) {
976
- console.error('Error fetching widget URL:', error);
1030
+ catch {
977
1031
  return null;
978
1032
  }
979
1033
  }
1034
+ /**
1035
+ * Sets the Transak API key used for all Transak API requests.
1036
+ *
1037
+ * @param apiKey - The Transak API key.
1038
+ */
1039
+ transakSetApiKey(apiKey) {
1040
+ this.messenger.call('TransakService:setApiKey', apiKey);
1041
+ }
1042
+ /**
1043
+ * Sets the Transak access token and marks the user as authenticated.
1044
+ *
1045
+ * @param token - The access token received from Transak auth.
1046
+ */
1047
+ transakSetAccessToken(token) {
1048
+ this.messenger.call('TransakService:setAccessToken', token);
1049
+ this.transakSetAuthenticated(true);
1050
+ }
1051
+ /**
1052
+ * Clears the Transak access token and marks the user as unauthenticated.
1053
+ */
1054
+ transakClearAccessToken() {
1055
+ this.messenger.call('TransakService:clearAccessToken');
1056
+ this.transakSetAuthenticated(false);
1057
+ }
1058
+ /**
1059
+ * Updates the Transak authentication flag in controller state.
1060
+ *
1061
+ * @param isAuthenticated - Whether the user is authenticated with Transak.
1062
+ */
1063
+ transakSetAuthenticated(isAuthenticated) {
1064
+ this.update((state) => {
1065
+ state.nativeProviders.transak.isAuthenticated = isAuthenticated;
1066
+ });
1067
+ }
1068
+ /**
1069
+ * Resets all Transak state back to defaults (unauthenticated, no data).
1070
+ */
1071
+ transakResetState() {
1072
+ this.messenger.call('TransakService:clearAccessToken');
1073
+ this.update((state) => {
1074
+ state.nativeProviders.transak =
1075
+ getDefaultRampsControllerState().nativeProviders.transak;
1076
+ });
1077
+ }
1078
+ /**
1079
+ * Sends a one-time password to the user's email for Transak authentication.
1080
+ *
1081
+ * @param email - The user's email address.
1082
+ * @returns The OTP response containing a state token for verification.
1083
+ */
1084
+ async transakSendUserOtp(email) {
1085
+ return this.messenger.call('TransakService:sendUserOtp', email);
1086
+ }
1087
+ /**
1088
+ * Verifies a one-time password and authenticates the user with Transak.
1089
+ * Updates the controller's authentication state on success.
1090
+ *
1091
+ * @param email - The user's email address.
1092
+ * @param verificationCode - The OTP code entered by the user.
1093
+ * @param stateToken - The state token from the sendUserOtp response.
1094
+ * @returns The access token for subsequent authenticated requests.
1095
+ */
1096
+ async transakVerifyUserOtp(email, verificationCode, stateToken) {
1097
+ const token = await this.messenger.call('TransakService:verifyUserOtp', email, verificationCode, stateToken);
1098
+ this.transakSetAuthenticated(true);
1099
+ return token;
1100
+ }
1101
+ /**
1102
+ * Logs the user out of Transak. Clears authentication state and user details
1103
+ * regardless of whether the API call succeeds or fails.
1104
+ *
1105
+ * @returns A message indicating the logout result.
1106
+ */
1107
+ async transakLogout() {
1108
+ try {
1109
+ const result = await this.messenger.call('TransakService:logout');
1110
+ return result;
1111
+ }
1112
+ finally {
1113
+ this.transakClearAccessToken();
1114
+ this.update((state) => {
1115
+ state.nativeProviders.transak.userDetails.data = null;
1116
+ });
1117
+ }
1118
+ }
1119
+ /**
1120
+ * Fetches the authenticated user's details from Transak.
1121
+ * Updates the userDetails resource state with loading/success/error states.
1122
+ *
1123
+ * @returns The user's profile and KYC details.
1124
+ */
1125
+ async transakGetUserDetails() {
1126
+ this.update((state) => {
1127
+ state.nativeProviders.transak.userDetails.isLoading = true;
1128
+ state.nativeProviders.transak.userDetails.error = null;
1129
+ });
1130
+ try {
1131
+ const details = await this.messenger.call('TransakService:getUserDetails');
1132
+ this.update((state) => {
1133
+ state.nativeProviders.transak.userDetails.data = details;
1134
+ state.nativeProviders.transak.userDetails.isLoading = false;
1135
+ });
1136
+ return details;
1137
+ }
1138
+ catch (error) {
1139
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1140
+ const errorMessage = error?.message ?? 'Unknown error';
1141
+ this.update((state) => {
1142
+ state.nativeProviders.transak.userDetails.isLoading = false;
1143
+ state.nativeProviders.transak.userDetails.error = errorMessage;
1144
+ });
1145
+ throw error;
1146
+ }
1147
+ }
1148
+ /**
1149
+ * Fetches a buy quote from Transak for the given parameters.
1150
+ * Updates the buyQuote resource state with loading/success/error states.
1151
+ *
1152
+ * @param fiatCurrency - The fiat currency code (e.g., "USD").
1153
+ * @param cryptoCurrency - The cryptocurrency identifier.
1154
+ * @param network - The blockchain network identifier.
1155
+ * @param paymentMethod - The payment method identifier.
1156
+ * @param fiatAmount - The fiat amount as a string.
1157
+ * @returns The buy quote with pricing and fee details.
1158
+ */
1159
+ async transakGetBuyQuote(fiatCurrency, cryptoCurrency, network, paymentMethod, fiatAmount) {
1160
+ this.update((state) => {
1161
+ state.nativeProviders.transak.buyQuote.isLoading = true;
1162
+ state.nativeProviders.transak.buyQuote.error = null;
1163
+ });
1164
+ try {
1165
+ const quote = await this.messenger.call('TransakService:getBuyQuote', fiatCurrency, cryptoCurrency, network, paymentMethod, fiatAmount);
1166
+ this.update((state) => {
1167
+ state.nativeProviders.transak.buyQuote.data = quote;
1168
+ state.nativeProviders.transak.buyQuote.isLoading = false;
1169
+ });
1170
+ return quote;
1171
+ }
1172
+ catch (error) {
1173
+ const errorMessage = error?.message ?? 'Unknown error';
1174
+ this.update((state) => {
1175
+ state.nativeProviders.transak.buyQuote.isLoading = false;
1176
+ state.nativeProviders.transak.buyQuote.error = errorMessage;
1177
+ });
1178
+ throw error;
1179
+ }
1180
+ }
1181
+ /**
1182
+ * Fetches the KYC requirement for a given quote.
1183
+ * Updates the kycRequirement resource state with loading/success/error states.
1184
+ *
1185
+ * @param quoteId - The quote ID to check KYC requirements for.
1186
+ * @returns The KYC requirement status and whether the user can place an order.
1187
+ */
1188
+ async transakGetKycRequirement(quoteId) {
1189
+ this.update((state) => {
1190
+ state.nativeProviders.transak.kycRequirement.isLoading = true;
1191
+ state.nativeProviders.transak.kycRequirement.error = null;
1192
+ });
1193
+ try {
1194
+ const requirement = await this.messenger.call('TransakService:getKycRequirement', quoteId);
1195
+ this.update((state) => {
1196
+ state.nativeProviders.transak.kycRequirement.data = requirement;
1197
+ state.nativeProviders.transak.kycRequirement.isLoading = false;
1198
+ });
1199
+ return requirement;
1200
+ }
1201
+ catch (error) {
1202
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1203
+ const errorMessage = error?.message ?? 'Unknown error';
1204
+ this.update((state) => {
1205
+ state.nativeProviders.transak.kycRequirement.isLoading = false;
1206
+ state.nativeProviders.transak.kycRequirement.error = errorMessage;
1207
+ });
1208
+ throw error;
1209
+ }
1210
+ }
1211
+ /**
1212
+ * Fetches additional KYC requirements (e.g., ID proof, address proof) for a quote.
1213
+ *
1214
+ * @param quoteId - The quote ID to check additional requirements for.
1215
+ * @returns The list of additional forms required.
1216
+ */
1217
+ async transakGetAdditionalRequirements(quoteId) {
1218
+ try {
1219
+ return await this.messenger.call('TransakService:getAdditionalRequirements', quoteId);
1220
+ }
1221
+ catch (error) {
1222
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1223
+ throw error;
1224
+ }
1225
+ }
1226
+ /**
1227
+ * Creates a new order on Transak. If an existing order conflicts (HTTP 409),
1228
+ * active orders are cancelled and the creation is retried.
1229
+ *
1230
+ * @param quoteId - The quote ID to create an order from.
1231
+ * @param walletAddress - The destination wallet address.
1232
+ * @param paymentMethodId - The payment method to use.
1233
+ * @returns The created deposit order.
1234
+ */
1235
+ async transakCreateOrder(quoteId, walletAddress, paymentMethodId) {
1236
+ try {
1237
+ return await this.messenger.call('TransakService:createOrder', quoteId, walletAddress, paymentMethodId);
1238
+ }
1239
+ catch (error) {
1240
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1241
+ throw error;
1242
+ }
1243
+ }
1244
+ /**
1245
+ * Fetches an existing order from Transak by order ID.
1246
+ *
1247
+ * @param orderId - The order ID (deposit format or raw Transak format).
1248
+ * @param wallet - The wallet address associated with the order.
1249
+ * @param paymentDetails - Optional payment details to attach to the order.
1250
+ * @returns The deposit order details.
1251
+ */
1252
+ async transakGetOrder(orderId, wallet, paymentDetails) {
1253
+ return this.messenger.call('TransakService:getOrder', orderId, wallet, paymentDetails);
1254
+ }
1255
+ /**
1256
+ * Fetches the user's spending limits for a given currency and payment method.
1257
+ *
1258
+ * @param fiatCurrency - The fiat currency code.
1259
+ * @param paymentMethod - The payment method identifier.
1260
+ * @param kycType - The KYC level type.
1261
+ * @returns The user's limits, spending, and remaining amounts.
1262
+ */
1263
+ async transakGetUserLimits(fiatCurrency, paymentMethod, kycType) {
1264
+ try {
1265
+ return await this.messenger.call('TransakService:getUserLimits', fiatCurrency, paymentMethod, kycType);
1266
+ }
1267
+ catch (error) {
1268
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1269
+ throw error;
1270
+ }
1271
+ }
1272
+ /**
1273
+ * Requests a one-time token (OTT) for the Transak payment widget.
1274
+ *
1275
+ * @returns The OTT response containing the token.
1276
+ */
1277
+ async transakRequestOtt() {
1278
+ try {
1279
+ return await this.messenger.call('TransakService:requestOtt');
1280
+ }
1281
+ catch (error) {
1282
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1283
+ throw error;
1284
+ }
1285
+ }
1286
+ /**
1287
+ * Generates a URL for the Transak payment widget with pre-filled parameters.
1288
+ *
1289
+ * @param ottToken - The one-time token for widget authentication.
1290
+ * @param quote - The buy quote to pre-fill in the widget.
1291
+ * @param walletAddress - The destination wallet address.
1292
+ * @param extraParams - Optional additional URL parameters.
1293
+ * @returns The fully constructed widget URL string.
1294
+ */
1295
+ transakGeneratePaymentWidgetUrl(ottToken, quote, walletAddress, extraParams) {
1296
+ return this.messenger.call('TransakService:generatePaymentWidgetUrl', ottToken, quote, walletAddress, extraParams);
1297
+ }
1298
+ /**
1299
+ * Submits the user's purpose of usage form for KYC compliance.
1300
+ *
1301
+ * @param purpose - Array of purpose strings selected by the user.
1302
+ * @returns A promise that resolves when the form is submitted.
1303
+ */
1304
+ async transakSubmitPurposeOfUsageForm(purpose) {
1305
+ try {
1306
+ return await this.messenger.call('TransakService:submitPurposeOfUsageForm', purpose);
1307
+ }
1308
+ catch (error) {
1309
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1310
+ throw error;
1311
+ }
1312
+ }
1313
+ /**
1314
+ * Updates the user's personal or address details on Transak.
1315
+ *
1316
+ * @param data - The user data fields to update.
1317
+ * @returns The API response data.
1318
+ */
1319
+ async transakPatchUser(data) {
1320
+ try {
1321
+ return await this.messenger.call('TransakService:patchUser', data);
1322
+ }
1323
+ catch (error) {
1324
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1325
+ throw error;
1326
+ }
1327
+ }
1328
+ /**
1329
+ * Submits the user's SSN for identity verification.
1330
+ *
1331
+ * @param ssn - The Social Security Number.
1332
+ * @param quoteId - The quote ID associated with the order requiring SSN.
1333
+ * @returns The API response data.
1334
+ */
1335
+ async transakSubmitSsnDetails(ssn, quoteId) {
1336
+ try {
1337
+ return await this.messenger.call('TransakService:submitSsnDetails', ssn, quoteId);
1338
+ }
1339
+ catch (error) {
1340
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1341
+ throw error;
1342
+ }
1343
+ }
1344
+ /**
1345
+ * Confirms payment for an order after the user has completed payment.
1346
+ *
1347
+ * @param orderId - The order ID to confirm payment for.
1348
+ * @param paymentMethodId - The payment method used.
1349
+ * @returns Whether the payment confirmation was successful.
1350
+ */
1351
+ async transakConfirmPayment(orderId, paymentMethodId) {
1352
+ try {
1353
+ return await this.messenger.call('TransakService:confirmPayment', orderId, paymentMethodId);
1354
+ }
1355
+ catch (error) {
1356
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1357
+ throw error;
1358
+ }
1359
+ }
1360
+ /**
1361
+ * Translates generic ramps identifiers to Transak-specific identifiers.
1362
+ *
1363
+ * @param request - The translation request with optional identifiers to translate.
1364
+ * @returns The translated Transak-specific identifiers.
1365
+ */
1366
+ async transakGetTranslation(request) {
1367
+ return this.messenger.call('TransakService:getTranslation', request);
1368
+ }
1369
+ /**
1370
+ * Checks the status of an ID proof submission for KYC.
1371
+ *
1372
+ * @param workFlowRunId - The workflow run ID to check status for.
1373
+ * @returns The current ID proof status.
1374
+ */
1375
+ async transakGetIdProofStatus(workFlowRunId) {
1376
+ try {
1377
+ return await this.messenger.call('TransakService:getIdProofStatus', workFlowRunId);
1378
+ }
1379
+ catch (error) {
1380
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1381
+ throw error;
1382
+ }
1383
+ }
1384
+ /**
1385
+ * Cancels a specific Transak order.
1386
+ *
1387
+ * @param depositOrderId - The deposit order ID to cancel.
1388
+ * @returns A promise that resolves when the order is cancelled.
1389
+ */
1390
+ async transakCancelOrder(depositOrderId) {
1391
+ try {
1392
+ return await this.messenger.call('TransakService:cancelOrder', depositOrderId);
1393
+ }
1394
+ catch (error) {
1395
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1396
+ throw error;
1397
+ }
1398
+ }
1399
+ /**
1400
+ * Cancels all active Transak orders. Individual cancellation failures
1401
+ * are collected and returned rather than thrown.
1402
+ *
1403
+ * @returns An array of errors from any failed cancellations (empty if all succeeded).
1404
+ */
1405
+ async transakCancelAllActiveOrders() {
1406
+ try {
1407
+ return await this.messenger.call('TransakService:cancelAllActiveOrders');
1408
+ }
1409
+ catch (error) {
1410
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1411
+ throw error;
1412
+ }
1413
+ }
1414
+ /**
1415
+ * Fetches all active Transak orders for the authenticated user.
1416
+ *
1417
+ * @returns The list of active orders.
1418
+ */
1419
+ async transakGetActiveOrders() {
1420
+ try {
1421
+ return await this.messenger.call('TransakService:getActiveOrders');
1422
+ }
1423
+ catch (error) {
1424
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_syncTransakAuthOnError).call(this, error);
1425
+ throw error;
1426
+ }
1427
+ }
980
1428
  }
981
1429
  exports.RampsController = RampsController;
982
1430
  _RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheMaxSize = new WeakMap(), _RampsController_pendingRequests = new WeakMap(), _RampsController_pendingResourceCount = new WeakMap(), _RampsController_quotePollingInterval = new WeakMap(), _RampsController_quotePollingOptions = new WeakMap(), _RampsController_instances = new WeakSet(), _RampsController_clearPendingResourceCountForDependentResources = function _RampsController_clearPendingResourceCountForDependentResources() {
983
- const types = [
984
- 'providers',
985
- 'tokens',
986
- 'paymentMethods',
987
- 'quotes',
988
- ];
989
- for (const resourceType of types) {
1431
+ for (const resourceType of DEPENDENT_RESOURCE_KEYS) {
990
1432
  __classPrivateFieldGet(this, _RampsController_pendingResourceCount, "f").delete(resourceType);
991
1433
  }
992
- }, _RampsController_removeRequestState = function _RampsController_removeRequestState(cacheKey) {
1434
+ }, _RampsController_abortDependentRequests = function _RampsController_abortDependentRequests() {
1435
+ for (const [cacheKey, pending] of __classPrivateFieldGet(this, _RampsController_pendingRequests, "f").entries()) {
1436
+ if (pending.resourceType &&
1437
+ DEPENDENT_RESOURCE_KEYS_SET.has(pending.resourceType)) {
1438
+ pending.abortController.abort();
1439
+ __classPrivateFieldGet(this, _RampsController_pendingRequests, "f").delete(cacheKey);
1440
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_removeRequestState).call(this, cacheKey);
1441
+ }
1442
+ }
1443
+ }, _RampsController_mutateRequests = function _RampsController_mutateRequests(fn) {
993
1444
  this.update((state) => {
994
1445
  const requests = state.requests;
1446
+ fn(requests);
1447
+ });
1448
+ }, _RampsController_removeRequestState = function _RampsController_removeRequestState(cacheKey) {
1449
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_mutateRequests).call(this, (requests) => {
995
1450
  delete requests[cacheKey];
996
1451
  });
997
1452
  }, _RampsController_cleanupState = function _RampsController_cleanupState() {
998
1453
  this.stopQuotePolling();
1454
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_abortDependentRequests).call(this);
999
1455
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_clearPendingResourceCountForDependentResources).call(this);
1000
- this.update((state) => resetDependentResources(state, {
1001
- clearUserRegionData: true,
1002
- }));
1456
+ this.update((state) => resetDependentResources(state, { clearUserRegionData: true }));
1003
1457
  }, _RampsController_fireAndForget = function _RampsController_fireAndForget(promise) {
1004
1458
  promise.catch((_error) => undefined);
1005
1459
  }, _RampsController_restartPollingIfActive = function _RampsController_restartPollingIfActive() {
@@ -1014,6 +1468,21 @@ _RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheM
1014
1468
  // when dependencies are available
1015
1469
  }
1016
1470
  }
1471
+ }, _RampsController_requireRegion = function _RampsController_requireRegion() {
1472
+ const regionCode = this.state.userRegion?.regionCode;
1473
+ if (!regionCode) {
1474
+ throw new Error('Region is required. Cannot proceed without valid region information.');
1475
+ }
1476
+ return regionCode;
1477
+ }, _RampsController_isRegionCurrent = function _RampsController_isRegionCurrent(normalizedRegion) {
1478
+ const current = this.state.userRegion?.regionCode;
1479
+ return current === undefined || current === normalizedRegion;
1480
+ }, _RampsController_isTokenCurrent = function _RampsController_isTokenCurrent(normalizedAssetId) {
1481
+ const current = this.state.tokens.selected?.assetId ?? '';
1482
+ return current === normalizedAssetId;
1483
+ }, _RampsController_isProviderCurrent = function _RampsController_isProviderCurrent(normalizedProviderId) {
1484
+ const current = this.state.providers.selected?.id ?? '';
1485
+ return current === normalizedProviderId;
1017
1486
  }, _RampsController_updateResourceField = function _RampsController_updateResourceField(resourceType, field, value) {
1018
1487
  this.update((state) => {
1019
1488
  const resource = state[resourceType];
@@ -1028,11 +1497,8 @@ _RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheM
1028
1497
  }, _RampsController_updateRequestState = function _RampsController_updateRequestState(cacheKey, requestState) {
1029
1498
  const maxSize = __classPrivateFieldGet(this, _RampsController_requestCacheMaxSize, "f");
1030
1499
  const ttl = __classPrivateFieldGet(this, _RampsController_requestCacheTTL, "f");
1031
- this.update((state) => {
1032
- const requests = state.requests;
1500
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_mutateRequests).call(this, (requests) => {
1033
1501
  requests[cacheKey] = requestState;
1034
- // Evict expired entries based on TTL
1035
- // Only evict SUCCESS states that have exceeded their TTL
1036
1502
  const keys = Object.keys(requests);
1037
1503
  for (const key of keys) {
1038
1504
  const entry = requests[key];
@@ -1041,16 +1507,13 @@ _RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheM
1041
1507
  delete requests[key];
1042
1508
  }
1043
1509
  }
1044
- // Evict oldest entries if cache still exceeds max size
1045
1510
  const remainingKeys = Object.keys(requests);
1046
1511
  if (remainingKeys.length > maxSize) {
1047
- // Sort by timestamp (oldest first)
1048
1512
  const sortedKeys = remainingKeys.sort((a, b) => {
1049
1513
  const aTime = requests[a]?.timestamp ?? 0;
1050
1514
  const bTime = requests[b]?.timestamp ?? 0;
1051
1515
  return aTime - bTime;
1052
1516
  });
1053
- // Remove oldest entries until we're under the limit
1054
1517
  const entriesToRemove = remainingKeys.length - maxSize;
1055
1518
  for (let i = 0; i < entriesToRemove; i++) {
1056
1519
  const keyToRemove = sortedKeys[i];
@@ -1060,5 +1523,44 @@ _RampsController_requestCacheTTL = new WeakMap(), _RampsController_requestCacheM
1060
1523
  }
1061
1524
  }
1062
1525
  });
1526
+ }, _RampsController_syncWidgetUrl = function _RampsController_syncWidgetUrl(quote) {
1527
+ const buyUrl = quote?.quote?.buyURL;
1528
+ if (!buyUrl) {
1529
+ this.update((state) => {
1530
+ resetWidgetUrl(state);
1531
+ });
1532
+ return;
1533
+ }
1534
+ if (this.state.widgetUrl.data === null) {
1535
+ this.update((state) => {
1536
+ state.widgetUrl.isLoading = true;
1537
+ state.widgetUrl.error = null;
1538
+ });
1539
+ }
1540
+ __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_fireAndForget).call(this, this.messenger
1541
+ .call('RampsService:getBuyWidgetUrl', buyUrl)
1542
+ .then((buyWidget) => {
1543
+ this.update((state) => {
1544
+ state.widgetUrl.data = buyWidget;
1545
+ state.widgetUrl.isLoading = false;
1546
+ state.widgetUrl.error = null;
1547
+ });
1548
+ return undefined;
1549
+ })
1550
+ .catch((error) => {
1551
+ this.update((state) => {
1552
+ state.widgetUrl.isLoading = false;
1553
+ state.widgetUrl.error =
1554
+ error instanceof Error
1555
+ ? error.message
1556
+ : 'Failed to fetch widget URL';
1557
+ });
1558
+ }));
1559
+ }, _RampsController_syncTransakAuthOnError = function _RampsController_syncTransakAuthOnError(error) {
1560
+ if (error instanceof Error &&
1561
+ 'httpStatus' in error &&
1562
+ error.httpStatus === 401) {
1563
+ this.transakSetAuthenticated(false);
1564
+ }
1063
1565
  };
1064
1566
  //# sourceMappingURL=RampsController.cjs.map