@metamask/ramps-controller 7.0.0 → 7.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [7.1.0]
11
+
12
+ ### Fixed
13
+
14
+ - Fixes quote race condition bug with missing payment method ([#7863](https://github.com/MetaMask/core/pull/7863))
15
+
10
16
  ## [7.0.0]
11
17
 
12
18
  ### Added
@@ -128,7 +134,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
128
134
  - Add `OnRampService` for interacting with the OnRamp API
129
135
  - Add geolocation detection via IP address lookup
130
136
 
131
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@7.0.0...HEAD
137
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@7.1.0...HEAD
138
+ [7.1.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@7.0.0...@metamask/ramps-controller@7.1.0
132
139
  [7.0.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@6.0.0...@metamask/ramps-controller@7.0.0
133
140
  [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@5.1.0...@metamask/ramps-controller@6.0.0
134
141
  [5.1.0]: https://github.com/MetaMask/core/compare/@metamask/ramps-controller@5.0.0...@metamask/ramps-controller@5.1.0
@@ -618,7 +618,6 @@ class RampsController extends base_controller_1.BaseController {
618
618
  state.quotes.selected = null;
619
619
  });
620
620
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_fireAndForget).call(this, this.getPaymentMethods(regionCode, { assetId: token.assetId }).then(() => {
621
- // Restart quote polling after payment methods are fetched
622
621
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_restartPollingIfActive).call(this);
623
622
  return undefined;
624
623
  }));
@@ -877,7 +876,7 @@ class RampsController extends base_controller_1.BaseController {
877
876
  throw new Error('Provider is required. Cannot start quote polling without a selected provider.');
878
877
  }
879
878
  if (!paymentMethod) {
880
- throw new Error('Payment method is required. Cannot start quote polling without a selected payment method.');
879
+ return;
881
880
  }
882
881
  // Stop any existing polling first
883
882
  this.stopQuotePolling();
@@ -1 +1 @@
1
- {"version":3,"file":"RampsController.cjs","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n Country,\n TokensResponse,\n Provider,\n State,\n RampAction,\n PaymentMethod,\n PaymentMethodsResponse,\n QuotesResponse,\n Quote,\n GetQuotesParams,\n RampsToken,\n RampsServiceActions,\n} from './RampsService';\nimport type {\n RampsServiceGetGeolocationAction,\n RampsServiceGetCountriesAction,\n RampsServiceGetTokensAction,\n RampsServiceGetProvidersAction,\n RampsServiceGetPaymentMethodsAction,\n RampsServiceGetQuotesAction,\n} from './RampsService-method-action-types';\nimport type {\n RequestCache as RequestCacheType,\n RequestState,\n ExecuteRequestOptions,\n PendingRequest,\n ResourceType,\n} from './RequestCache';\nimport {\n DEFAULT_REQUEST_CACHE_TTL,\n DEFAULT_REQUEST_CACHE_MAX_SIZE,\n createCacheKey,\n isCacheExpired,\n createLoadingState,\n createSuccessState,\n createErrorState,\n RequestStatus,\n} from './RequestCache';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link RampsController}, used to namespace the\n * controller's actions and events and to namespace the controller's state data\n * when composed with other controllers.\n */\nexport const controllerName = 'RampsController';\n\n/**\n * RampsService action types that RampsController calls via the messenger.\n * Any host (e.g. mobile) that creates a RampsController messenger must delegate\n * these actions from the root messenger so the controller can function.\n */\nexport const RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS: readonly RampsServiceActions['type'][] =\n [\n 'RampsService:getGeolocation',\n 'RampsService:getCountries',\n 'RampsService:getTokens',\n 'RampsService:getProviders',\n 'RampsService:getPaymentMethods',\n 'RampsService:getQuotes',\n ];\n\n/**\n * Default TTL for quotes requests (15 seconds).\n * Quotes are time-sensitive and should have a shorter cache duration.\n */\nconst DEFAULT_QUOTES_TTL = 15000;\n\n// === STATE ===\n\n/**\n * Represents the user's selected region with full country and state objects.\n */\nexport type UserRegion = {\n /**\n * The country object for the selected region.\n */\n country: Country;\n /**\n * The state object if a state was selected, null if only country was selected.\n */\n state: State | null;\n /**\n * The region code string (e.g., \"us-ut\" or \"fr\") used for API calls.\n */\n regionCode: string;\n};\n\n/**\n * Generic type for resource state that bundles data with loading/error states.\n *\n * @template TData - The type of the resource data\n * @template TSelected - The type of the selected item (defaults to null for resources without selection)\n */\nexport type ResourceState<TData, TSelected = null> = {\n /**\n * The resource data.\n */\n data: TData;\n /**\n * The currently selected item, or null if none selected.\n */\n selected: TSelected;\n /**\n * Whether the resource is currently being fetched.\n */\n isLoading: boolean;\n /**\n * Error message if the fetch failed, or null.\n */\n error: string | null;\n};\n\n/**\n * Describes the shape of the state object for {@link RampsController}.\n */\nexport type RampsControllerState = {\n /**\n * The user's region (full country and state objects).\n * Initially set via geolocation fetch, but can be manually changed by the user.\n */\n userRegion: UserRegion | null;\n /**\n * Countries resource state with data, loading, and error.\n * Data contains the list of countries available for ramp actions.\n */\n countries: ResourceState<Country[]>;\n /**\n * Providers resource state with data, selected, loading, and error.\n * Data contains the list of providers available for the current region.\n */\n providers: ResourceState<Provider[], Provider | null>;\n /**\n * Tokens resource state with data, selected, loading, and error.\n * Data contains topTokens and allTokens arrays.\n */\n tokens: ResourceState<TokensResponse | null, RampsToken | null>;\n /**\n * Payment methods resource state with data, selected, loading, and error.\n * Data contains payment methods filtered by region, fiat, asset, and provider.\n */\n paymentMethods: ResourceState<PaymentMethod[], PaymentMethod | null>;\n /**\n * Quotes resource state with data, selected, loading, and error.\n * Data contains quotes from multiple providers for the given parameters.\n * Selected contains the currently selected quote for the user.\n */\n quotes: ResourceState<QuotesResponse | null, Quote | null>;\n /**\n * Cache of request states, keyed by cache key.\n * This stores loading, success, and error states for API requests.\n */\n requests: RequestCacheType;\n};\n\n/**\n * The metadata for each property in {@link RampsControllerState}.\n */\nconst rampsControllerMetadata = {\n userRegion: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n countries: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n providers: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n tokens: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n paymentMethods: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n quotes: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n requests: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n} satisfies StateMetadata<RampsControllerState>;\n\n/**\n * Creates a default resource state object.\n *\n * @template TData - The type of the resource data.\n * @template TSelected - The type of the selected item.\n * @param data - The initial data value.\n * @param selected - The initial selected value.\n * @returns A ResourceState object with default loading and error values.\n */\nfunction createDefaultResourceState<TData, TSelected = null>(\n data: TData,\n selected: TSelected = null as TSelected,\n): ResourceState<TData, TSelected> {\n return {\n data,\n selected,\n isLoading: false,\n error: null,\n };\n}\n\n/**\n * Constructs the default {@link RampsController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link RampsController} state.\n */\nexport function getDefaultRampsControllerState(): RampsControllerState {\n return {\n userRegion: null,\n countries: createDefaultResourceState<Country[]>([]),\n providers: createDefaultResourceState<Provider[], Provider | null>(\n [],\n null,\n ),\n tokens: createDefaultResourceState<\n TokensResponse | null,\n RampsToken | null\n >(null, null),\n paymentMethods: createDefaultResourceState<\n PaymentMethod[],\n PaymentMethod | null\n >([], null),\n quotes: createDefaultResourceState<QuotesResponse | null, Quote | null>(\n null,\n null,\n ),\n requests: {},\n };\n}\n\n/**\n * Resets region-dependent resources (userRegion, providers, tokens, paymentMethods, quotes).\n * Mutates state in place; use from within controller update() for atomic updates.\n *\n * @param state - The state object to mutate.\n * @param options - Options for the reset.\n * @param options.clearUserRegionData - When true, sets userRegion to null (e.g. for full cleanup).\n */\nfunction resetDependentResources(\n state: RampsControllerState,\n options?: { clearUserRegionData?: boolean },\n): void {\n if (options?.clearUserRegionData) {\n state.userRegion = null;\n }\n state.providers.selected = null;\n state.providers.data = [];\n state.providers.isLoading = false;\n state.providers.error = null;\n state.tokens.selected = null;\n state.tokens.data = null;\n state.tokens.isLoading = false;\n state.tokens.error = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.paymentMethods.isLoading = false;\n state.paymentMethods.error = null;\n state.quotes.data = null;\n state.quotes.selected = null;\n state.quotes.isLoading = false;\n state.quotes.error = null;\n}\n\n// === MESSENGER ===\n\n/**\n * Retrieves the state of the {@link RampsController}.\n */\nexport type RampsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Actions that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerActions = RampsControllerGetStateAction;\n\n/**\n * Actions from other messengers that {@link RampsController} calls.\n */\ntype AllowedActions =\n | RampsServiceGetGeolocationAction\n | RampsServiceGetCountriesAction\n | RampsServiceGetTokensAction\n | RampsServiceGetProvidersAction\n | RampsServiceGetPaymentMethodsAction\n | RampsServiceGetQuotesAction;\n\n/**\n * Published when the state of {@link RampsController} changes.\n */\nexport type RampsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Events that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerEvents = RampsControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link RampsController} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link RampsController}.\n */\nexport type RampsControllerMessenger = Messenger<\n typeof controllerName,\n RampsControllerActions | AllowedActions,\n RampsControllerEvents | AllowedEvents\n>;\n\n/**\n * Configuration options for the RampsController.\n */\nexport type RampsControllerOptions = {\n /** The messenger suited for this controller. */\n messenger: RampsControllerMessenger;\n /** The desired state with which to initialize this controller. */\n state?: Partial<RampsControllerState>;\n /** Time to live for cached requests in milliseconds. Defaults to 15 minutes. */\n requestCacheTTL?: number;\n /** Maximum number of entries in the request cache. Defaults to 250. */\n requestCacheMaxSize?: number;\n};\n\n// === HELPER FUNCTIONS ===\n\n/**\n * Finds a country and state from a region code string.\n *\n * @param regionCode - The region code (e.g., \"us-ca\" or \"us\").\n * @param countries - Array of countries to search.\n * @returns UserRegion object with country and state, or null if not found.\n */\nfunction findRegionFromCode(\n regionCode: string,\n countries: Country[],\n): UserRegion | null {\n const normalizedCode = regionCode.toLowerCase().trim();\n const parts = normalizedCode.split('-');\n const countryCode = parts[0];\n const stateCode = parts[1];\n\n const country = countries.find((countryItem) => {\n if (countryItem.isoCode?.toLowerCase() === countryCode) {\n return true;\n }\n if (countryItem.id) {\n const id = countryItem.id.toLowerCase();\n if (id.startsWith('/regions/')) {\n const extractedCode = id.replace('/regions/', '').split('/')[0];\n return extractedCode === countryCode;\n }\n return id === countryCode || id.endsWith(`/${countryCode}`);\n }\n return false;\n });\n\n if (!country) {\n return null;\n }\n\n let state: State | null = null;\n if (stateCode && country.states) {\n state =\n country.states.find((stateItem) => {\n if (stateItem.stateId?.toLowerCase() === stateCode) {\n return true;\n }\n if (stateItem.id) {\n const stateId = stateItem.id.toLowerCase();\n if (\n stateId.includes(`-${stateCode}`) ||\n stateId.endsWith(`/${stateCode}`)\n ) {\n return true;\n }\n }\n return false;\n }) ?? null;\n }\n\n return {\n country,\n state,\n regionCode: normalizedCode,\n };\n}\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * Manages cryptocurrency on/off ramps functionality.\n */\nexport class RampsController extends BaseController<\n typeof controllerName,\n RampsControllerState,\n RampsControllerMessenger\n> {\n /**\n * Default TTL for cached requests.\n */\n readonly #requestCacheTTL: number;\n\n /**\n * Maximum number of entries in the request cache.\n */\n readonly #requestCacheMaxSize: number;\n\n /**\n * Map of pending requests for deduplication.\n * Key is the cache key, value is the pending request with abort controller.\n */\n readonly #pendingRequests: Map<string, PendingRequest> = new Map();\n\n /**\n * Count of in-flight requests per resource type.\n * Used so isLoading is only cleared when the last request for that resource finishes.\n */\n readonly #pendingResourceCount: Map<ResourceType, number> = new Map();\n\n /**\n * Interval ID for automatic quote polling.\n * Set when startQuotePolling() is called, cleared when stopQuotePolling() is called.\n */\n #quotePollingInterval: ReturnType<typeof setInterval> | null = null;\n\n /**\n * Options used for quote polling (walletAddress, amount, redirectUrl).\n * Stored so polling can be restarted when dependencies change.\n */\n #quotePollingOptions: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n } | null = null;\n\n /**\n * Clears the pending resource count map. Used only in tests to exercise the\n * defensive path when get() returns undefined in the finally block.\n *\n * @internal\n */\n clearPendingResourceCountForTest(): void {\n this.#pendingResourceCount.clear();\n }\n\n #clearPendingResourceCountForDependentResources(): void {\n const types: ResourceType[] = [\n 'providers',\n 'tokens',\n 'paymentMethods',\n 'quotes',\n ];\n for (const resourceType of types) {\n this.#pendingResourceCount.delete(resourceType);\n }\n }\n\n /**\n * Constructs a new {@link RampsController}.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this controller.\n * @param args.state - The desired state with which to initialize this\n * controller. Missing properties will be filled in with defaults.\n * @param args.requestCacheTTL - Time to live for cached requests in milliseconds.\n * @param args.requestCacheMaxSize - Maximum number of entries in the request cache.\n */\n constructor({\n messenger,\n state = {},\n requestCacheTTL = DEFAULT_REQUEST_CACHE_TTL,\n requestCacheMaxSize = DEFAULT_REQUEST_CACHE_MAX_SIZE,\n }: RampsControllerOptions) {\n super({\n messenger,\n metadata: rampsControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultRampsControllerState(),\n ...state,\n // Always reset requests cache on initialization (non-persisted)\n requests: {},\n },\n });\n\n this.#requestCacheTTL = requestCacheTTL;\n this.#requestCacheMaxSize = requestCacheMaxSize;\n }\n\n /**\n * Executes a request with caching and deduplication.\n *\n * If a request with the same cache key is already in flight, returns the\n * existing promise. If valid cached data exists, returns it without making\n * a new request.\n *\n * @param cacheKey - Unique identifier for this request.\n * @param fetcher - Function that performs the actual fetch. Receives an AbortSignal.\n * @param options - Options for cache behavior.\n * @returns The result of the request.\n */\n async executeRequest<TResult>(\n cacheKey: string,\n fetcher: (signal: AbortSignal) => Promise<TResult>,\n options?: ExecuteRequestOptions,\n ): Promise<TResult> {\n const ttl = options?.ttl ?? this.#requestCacheTTL;\n\n // Check for existing pending request - join it instead of making a duplicate\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n return pending.promise as Promise<TResult>;\n }\n\n if (!options?.forceRefresh) {\n const cached = this.state.requests[cacheKey];\n if (cached && !isCacheExpired(cached, ttl)) {\n return cached.data as TResult;\n }\n }\n\n // Create abort controller for this request\n const abortController = new AbortController();\n const lastFetchedAt = Date.now();\n const { resourceType } = options ?? {};\n\n // Update state to loading\n this.#updateRequestState(cacheKey, createLoadingState());\n\n // Set resource-level loading state (only on cache miss). Ref-count so concurrent\n // requests for the same resource type (different cache keys) keep isLoading true.\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n this.#pendingResourceCount.set(resourceType, count + 1);\n if (count === 0) {\n this.#setResourceLoading(resourceType, true);\n }\n }\n\n // Create the fetch promise\n const promise = (async (): Promise<TResult> => {\n try {\n const data = await fetcher(abortController.signal);\n\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw new Error('Request was aborted');\n }\n\n this.#updateRequestState(\n cacheKey,\n createSuccessState(data as Json, lastFetchedAt),\n );\n\n if (resourceType) {\n // We need the extra logic because there are two situations where we’re allowed to clear the error:\n // No callback → always clear\n // Callback present → clear only when isResultCurrent() returns true.\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, null);\n }\n }\n\n return data;\n } catch (error) {\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw error;\n }\n\n const errorMessage = (error as Error)?.message ?? 'Unknown error';\n\n this.#updateRequestState(\n cacheKey,\n createErrorState(errorMessage, lastFetchedAt),\n );\n\n if (resourceType) {\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, errorMessage);\n }\n }\n\n throw error;\n } finally {\n // Only delete if this is still our entry (not replaced by a new request)\n const currentPending = this.#pendingRequests.get(cacheKey);\n if (currentPending?.abortController === abortController) {\n this.#pendingRequests.delete(cacheKey);\n }\n\n // Clear resource-level loading state only when no requests for this resource remain\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n const next = Math.max(0, count - 1);\n if (next === 0) {\n this.#pendingResourceCount.delete(resourceType);\n this.#setResourceLoading(resourceType, false);\n } else {\n this.#pendingResourceCount.set(resourceType, next);\n }\n }\n }\n })();\n\n // Store pending request for deduplication\n this.#pendingRequests.set(cacheKey, { promise, abortController });\n\n return promise;\n }\n\n /**\n * Aborts a pending request if one exists.\n *\n * @param cacheKey - The cache key of the request to abort.\n * @returns True if a request was aborted.\n */\n abortRequest(cacheKey: string): boolean {\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n pending.abortController.abort();\n this.#pendingRequests.delete(cacheKey);\n this.#removeRequestState(cacheKey);\n return true;\n }\n return false;\n }\n\n /**\n * Removes a request state from the cache.\n *\n * @param cacheKey - The cache key to remove.\n */\n #removeRequestState(cacheKey: string): void {\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n delete requests[cacheKey];\n });\n }\n\n #cleanupState(): void {\n this.stopQuotePolling();\n this.#clearPendingResourceCountForDependentResources();\n this.update((state) =>\n resetDependentResources(state as unknown as RampsControllerState, {\n clearUserRegionData: true,\n }),\n );\n }\n\n /**\n * Executes a promise without awaiting, swallowing errors.\n * Errors are stored in state via executeRequest.\n *\n * @param promise - The promise to execute.\n */\n #fireAndForget<Result>(promise: Promise<Result>): void {\n promise.catch((_error: unknown) => undefined);\n }\n\n /**\n * Restarts quote polling if it's currently active.\n * Used when dependencies change (token, provider, payment method).\n * Will only restart if all dependencies are still met (startQuotePolling validates this).\n */\n #restartPollingIfActive(): void {\n if (this.#quotePollingInterval !== null && this.#quotePollingOptions) {\n const options = this.#quotePollingOptions;\n this.stopQuotePolling();\n try {\n this.startQuotePolling(options);\n } catch {\n // Dependencies not met yet, polling will need to be manually restarted\n // when dependencies are available\n }\n }\n }\n\n /**\n * Updates a single field (isLoading or error) on a resource state.\n * All resources share the same ResourceState structure, so we use\n * dynamic property access to avoid duplicating switch statements.\n *\n * @param resourceType - The type of resource.\n * @param field - The field to update ('isLoading' or 'error').\n * @param value - The value to set.\n */\n #updateResourceField(\n resourceType: ResourceType,\n field: 'isLoading' | 'error',\n value: boolean | string | null,\n ): void {\n this.update((state) => {\n const resource = state[resourceType];\n if (resource) {\n (resource as Record<string, unknown>)[field] = value;\n }\n });\n }\n\n /**\n * Sets the loading state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param loading - Whether the resource is loading.\n */\n #setResourceLoading(resourceType: ResourceType, loading: boolean): void {\n this.#updateResourceField(resourceType, 'isLoading', loading);\n }\n\n /**\n * Sets the error state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param error - The error message, or null to clear.\n */\n #setResourceError(resourceType: ResourceType, error: string | null): void {\n this.#updateResourceField(resourceType, 'error', error);\n }\n\n /**\n * Gets the state of a specific cached request.\n *\n * @param cacheKey - The cache key to look up.\n * @returns The request state, or undefined if not cached.\n */\n getRequestState(cacheKey: string): RequestState | undefined {\n return this.state.requests[cacheKey];\n }\n\n /**\n * Updates the state for a specific request.\n *\n * @param cacheKey - The cache key.\n * @param requestState - The new state for the request.\n */\n #updateRequestState(cacheKey: string, requestState: RequestState): void {\n const maxSize = this.#requestCacheMaxSize;\n const ttl = this.#requestCacheTTL;\n\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n requests[cacheKey] = requestState;\n\n // Evict expired entries based on TTL\n // Only evict SUCCESS states that have exceeded their TTL\n const keys = Object.keys(requests);\n for (const key of keys) {\n const entry = requests[key];\n if (\n entry &&\n entry.status === RequestStatus.SUCCESS &&\n isCacheExpired(entry, ttl)\n ) {\n delete requests[key];\n }\n }\n\n // Evict oldest entries if cache still exceeds max size\n const remainingKeys = Object.keys(requests);\n if (remainingKeys.length > maxSize) {\n // Sort by timestamp (oldest first)\n const sortedKeys = remainingKeys.sort((a, b) => {\n const aTime = requests[a]?.timestamp ?? 0;\n const bTime = requests[b]?.timestamp ?? 0;\n return aTime - bTime;\n });\n\n // Remove oldest entries until we're under the limit\n const entriesToRemove = remainingKeys.length - maxSize;\n for (let i = 0; i < entriesToRemove; i++) {\n const keyToRemove = sortedKeys[i];\n if (keyToRemove) {\n delete requests[keyToRemove];\n }\n }\n }\n });\n }\n\n /**\n * Sets the user's region manually (without fetching geolocation).\n * This allows users to override the detected region.\n *\n * @param region - The region code to set (e.g., \"US-CA\").\n * @param options - Options for cache behavior.\n * @returns The user region object.\n */\n async setUserRegion(\n region: string,\n options?: ExecuteRequestOptions,\n ): Promise<UserRegion> {\n const normalizedRegion = region.toLowerCase().trim();\n\n try {\n const countriesData = this.state.countries.data;\n if (!countriesData || countriesData.length === 0) {\n this.#cleanupState();\n throw new Error(\n 'No countries found. Cannot set user region without valid country information.',\n );\n }\n\n const userRegion = findRegionFromCode(normalizedRegion, countriesData);\n\n if (!userRegion) {\n this.#cleanupState();\n throw new Error(\n `Region \"${normalizedRegion}\" not found in countries data. Cannot set user region without valid country information.`,\n );\n }\n\n const regionChanged =\n normalizedRegion !== this.state.userRegion?.regionCode;\n\n const needsRefetch =\n regionChanged ||\n !this.state.tokens.data ||\n this.state.providers.data.length === 0;\n\n if (regionChanged) {\n this.#clearPendingResourceCountForDependentResources();\n }\n if (regionChanged) {\n this.stopQuotePolling();\n }\n this.update((state) => {\n if (regionChanged) {\n resetDependentResources(state as unknown as RampsControllerState);\n }\n state.userRegion = userRegion;\n });\n\n if (needsRefetch) {\n const refetchPromises: Promise<unknown>[] = [];\n if (regionChanged || !this.state.tokens.data) {\n refetchPromises.push(\n this.getTokens(userRegion.regionCode, 'buy', options),\n );\n }\n if (regionChanged || this.state.providers.data.length === 0) {\n refetchPromises.push(\n this.getProviders(userRegion.regionCode, options),\n );\n }\n if (refetchPromises.length > 0) {\n this.#fireAndForget(Promise.all(refetchPromises));\n }\n }\n\n return userRegion;\n } catch (error) {\n this.#cleanupState();\n throw error;\n }\n }\n\n /**\n * Sets the user's selected provider by ID, or clears the selection.\n * Looks up the provider from the current providers in state and automatically\n * fetches payment methods for that provider.\n *\n * @param providerId - The provider ID (e.g., \"/providers/moonpay\"), or null to clear.\n * @throws If region is not set, providers are not loaded, or provider is not found.\n */\n setSelectedProvider(providerId: string | null): void {\n if (providerId === null) {\n this.stopQuotePolling();\n this.update((state) => {\n state.providers.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected provider without valid region information.',\n );\n }\n\n const providers = this.state.providers.data;\n if (!providers || providers.length === 0) {\n throw new Error(\n 'Providers not loaded. Cannot set selected provider before providers are fetched.',\n );\n }\n\n const provider = providers.find((prov) => prov.id === providerId);\n if (!provider) {\n throw new Error(\n `Provider with ID \"${providerId}\" not found in available providers.`,\n );\n }\n\n this.update((state) => {\n state.providers.selected = provider;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { provider: provider.id }).then(() => {\n // Restart quote polling after payment methods are fetched\n this.#restartPollingIfActive();\n return undefined;\n }),\n );\n }\n\n /**\n * Initializes the controller by fetching the user's region from geolocation.\n * This should be called once at app startup to set up the initial region.\n *\n * If a userRegion already exists (from persistence or manual selection),\n * this method will skip geolocation fetch and use the existing region.\n *\n * @param options - Options for cache behavior.\n * @returns Promise that resolves when initialization is complete.\n */\n async init(options?: ExecuteRequestOptions): Promise<void> {\n await this.getCountries(options);\n\n let regionCode = this.state.userRegion?.regionCode;\n regionCode ??= await this.messenger.call('RampsService:getGeolocation');\n\n if (!regionCode) {\n throw new Error(\n 'Failed to fetch geolocation. Cannot initialize controller without valid region information.',\n );\n }\n\n await this.setUserRegion(regionCode, options);\n }\n\n hydrateState(options?: ExecuteRequestOptions): void {\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region code is required. Cannot hydrate state without valid region information.',\n );\n }\n\n this.#fireAndForget(this.getTokens(regionCode, 'buy', options));\n this.#fireAndForget(this.getProviders(regionCode, options));\n }\n\n /**\n * Fetches the list of supported countries.\n * The API returns countries with support information for both buy and sell actions.\n * The countries are saved in the controller state once fetched.\n *\n * @param options - Options for cache behavior.\n * @returns An array of countries.\n */\n async getCountries(options?: ExecuteRequestOptions): Promise<Country[]> {\n const cacheKey = createCacheKey('getCountries', []);\n\n const countries = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getCountries');\n },\n { ...options, resourceType: 'countries' },\n );\n\n this.update((state) => {\n state.countries.data = countries;\n });\n\n return countries;\n }\n\n /**\n * Fetches the list of available tokens for a given region and action.\n * The tokens are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param action - The ramp action type ('buy' or 'sell').\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @returns The tokens response containing topTokens and allTokens.\n */\n async getTokens(\n region?: string,\n action: RampAction = 'buy',\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n },\n ): Promise<TokensResponse> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getTokens', [\n normalizedRegion,\n action,\n options?.provider,\n ]);\n\n const tokens = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getTokens',\n normalizedRegion,\n action,\n {\n provider: options?.provider,\n },\n );\n },\n {\n ...options,\n resourceType: 'tokens',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.tokens.data = tokens;\n }\n });\n\n return tokens;\n }\n\n /**\n * Sets the user's selected token by asset ID.\n * Looks up the token from the current tokens in state and automatically\n * fetches payment methods for that token.\n *\n * @param assetId - The asset identifier in CAIP-19 format (e.g., \"eip155:1/erc20:0x...\"), or undefined to clear.\n * @throws If region is not set, tokens are not loaded, or token is not found.\n */\n setSelectedToken(assetId?: string): void {\n if (!assetId) {\n this.stopQuotePolling();\n this.update((state) => {\n state.tokens.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected token without valid region information.',\n );\n }\n\n const tokens = this.state.tokens.data;\n if (!tokens) {\n throw new Error(\n 'Tokens not loaded. Cannot set selected token before tokens are fetched.',\n );\n }\n\n const token =\n tokens.allTokens.find((tok) => tok.assetId === assetId) ??\n tokens.topTokens.find((tok) => tok.assetId === assetId);\n\n if (!token) {\n throw new Error(\n `Token with asset ID \"${assetId}\" not found in available tokens.`,\n );\n }\n\n this.update((state) => {\n state.tokens.selected = token;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { assetId: token.assetId }).then(\n () => {\n // Restart quote polling after payment methods are fetched\n this.#restartPollingIfActive();\n return undefined;\n },\n ),\n );\n }\n\n /**\n * Fetches the list of providers for a given region.\n * The providers are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @param options.crypto - Crypto currency ID(s) to filter by.\n * @param options.fiat - Fiat currency ID(s) to filter by.\n * @param options.payments - Payment method ID(s) to filter by.\n * @returns The providers response containing providers array.\n */\n async getProviders(\n region?: string,\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n crypto?: string | string[];\n fiat?: string | string[];\n payments?: string | string[];\n },\n ): Promise<{ providers: Provider[] }> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getProviders', [\n normalizedRegion,\n options?.provider,\n options?.crypto,\n options?.fiat,\n options?.payments,\n ]);\n\n const { providers } = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getProviders',\n normalizedRegion,\n {\n provider: options?.provider,\n crypto: options?.crypto,\n fiat: options?.fiat,\n payments: options?.payments,\n },\n );\n },\n {\n ...options,\n resourceType: 'providers',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.providers.data = providers;\n }\n });\n\n return { providers };\n }\n\n /**\n * Fetches the list of payment methods for a given context.\n * The payment methods are saved in the controller state once fetched.\n *\n * @param region - User's region code (e.g. \"fr\", \"us-ny\").\n * @param options - Query parameters for filtering payment methods.\n * @param options.fiat - Fiat currency code (e.g., \"usd\"). If not provided, uses the user's region currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.provider - Provider ID path.\n * @returns The payment methods response containing payments array.\n */\n async getPaymentMethods(\n region?: string,\n options?: ExecuteRequestOptions & {\n fiat?: string;\n assetId?: string;\n provider?: string;\n },\n ): Promise<PaymentMethodsResponse> {\n const regionCode = region ?? this.state.userRegion?.regionCode ?? null;\n const fiatToUse =\n options?.fiat ?? this.state.userRegion?.country?.currency ?? null;\n const assetIdToUse =\n options?.assetId ?? this.state.tokens.selected?.assetId ?? '';\n const providerToUse =\n options?.provider ?? this.state.providers.selected?.id ?? '';\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionCode.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getPaymentMethods', [\n normalizedRegion,\n normalizedFiat,\n assetIdToUse,\n providerToUse,\n ]);\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getPaymentMethods', {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: assetIdToUse,\n provider: providerToUse,\n });\n },\n {\n ...options,\n resourceType: 'paymentMethods',\n isResultCurrent: () => {\n const regionMatch =\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion;\n const tokenMatch =\n (this.state.tokens.selected?.assetId ?? '') === assetIdToUse;\n const providerMatch =\n (this.state.providers.selected?.id ?? '') === providerToUse;\n return regionMatch && tokenMatch && providerMatch;\n },\n },\n );\n\n this.update((state) => {\n const currentAssetId = state.tokens.selected?.assetId ?? '';\n const currentProviderId = state.providers.selected?.id ?? '';\n\n const tokenSelectionUnchanged = assetIdToUse === currentAssetId;\n const providerSelectionUnchanged = providerToUse === currentProviderId;\n\n // this is a race condition check to ensure that the selected token and provider in state are the same as the tokens we're requesting for\n // ex: if the user rapidly changes the token or provider, the in-flight payment methods might not be valid\n // so this check will ensure that the payment methods are still valid for the token and provider that were requested\n if (tokenSelectionUnchanged && providerSelectionUnchanged) {\n state.paymentMethods.data = response.payments;\n\n // this will auto-select the first payment method if the selected payment method is not in the new payment methods\n const currentSelectionStillValid = response.payments.some(\n (pm: PaymentMethod) => pm.id === state.paymentMethods.selected?.id,\n );\n if (!currentSelectionStillValid) {\n state.paymentMethods.selected = response.payments[0] ?? null;\n }\n }\n });\n\n return response;\n }\n\n /**\n * Sets the user's selected payment method by ID.\n * Looks up the payment method from the current payment methods in state.\n *\n * @param paymentMethodId - The payment method ID (e.g., \"/payments/debit-credit-card\"), or null to clear.\n * @throws If payment methods are not loaded or payment method is not found.\n */\n setSelectedPaymentMethod(paymentMethodId?: string): void {\n if (!paymentMethodId) {\n this.update((state) => {\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const paymentMethods = this.state.paymentMethods.data;\n if (!paymentMethods || paymentMethods.length === 0) {\n throw new Error(\n 'Payment methods not loaded. Cannot set selected payment method before payment methods are fetched.',\n );\n }\n\n const paymentMethod = paymentMethods.find(\n (pm) => pm.id === paymentMethodId,\n );\n if (!paymentMethod) {\n throw new Error(\n `Payment method with ID \"${paymentMethodId}\" not found in available payment methods.`,\n );\n }\n\n this.update((state) => {\n state.paymentMethods.selected = paymentMethod;\n });\n\n // Restart quote polling if active\n this.#restartPollingIfActive();\n }\n\n /**\n * Fetches quotes from all providers for a given set of parameters.\n * The quotes are saved in the controller state once fetched.\n *\n * @param options - The parameters for fetching quotes.\n * @param options.region - User's region code. If not provided, uses userRegion from state.\n * @param options.fiat - Fiat currency code. If not provided, uses userRegion currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.walletAddress - The destination wallet address.\n * @param options.paymentMethods - Array of payment method IDs. If not provided, uses paymentMethods from state.\n * @param options.provider - Optional provider ID to filter quotes.\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @param options.action - The ramp action type. Defaults to 'buy'.\n * @param options.forceRefresh - Whether to bypass cache.\n * @param options.ttl - Custom TTL for this request.\n * @returns The quotes response containing success, sorted, error, and customActions.\n */\n async getQuotes(options: {\n region?: string;\n fiat?: string;\n assetId: string;\n amount: number;\n walletAddress: string;\n paymentMethods?: string[];\n provider?: string;\n redirectUrl?: string;\n action?: RampAction;\n forceRefresh?: boolean;\n ttl?: number;\n }): Promise<QuotesResponse> {\n const regionToUse = options.region ?? this.state.userRegion?.regionCode;\n const fiatToUse = options.fiat ?? this.state.userRegion?.country?.currency;\n const paymentMethodsToUse =\n options.paymentMethods ??\n this.state.paymentMethods.data.map((pm: PaymentMethod) => pm.id);\n const action = options.action ?? 'buy';\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!paymentMethodsToUse || paymentMethodsToUse.length === 0) {\n throw new Error(\n 'Payment methods are required. Either provide paymentMethods parameter or ensure paymentMethods are set in controller state.',\n );\n }\n\n if (options.amount <= 0 || !Number.isFinite(options.amount)) {\n throw new Error('Amount must be a positive finite number.');\n }\n\n if (!options.assetId || options.assetId.trim() === '') {\n throw new Error('assetId is required.');\n }\n\n if (!options.walletAddress || options.walletAddress.trim() === '') {\n throw new Error('walletAddress is required.');\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const normalizedAssetId = options.assetId.trim();\n const normalizedWalletAddress = options.walletAddress.trim();\n\n const cacheKey = createCacheKey('getQuotes', [\n normalizedRegion,\n normalizedFiat,\n normalizedAssetId,\n options.amount,\n normalizedWalletAddress,\n [...paymentMethodsToUse].sort().join(','),\n options.provider,\n options.redirectUrl,\n action,\n ]);\n\n const params: GetQuotesParams = {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: normalizedAssetId,\n amount: options.amount,\n walletAddress: normalizedWalletAddress,\n paymentMethods: paymentMethodsToUse,\n provider: options.provider,\n redirectUrl: options.redirectUrl,\n action,\n };\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getQuotes', params);\n },\n {\n forceRefresh: options.forceRefresh,\n ttl: options.ttl ?? DEFAULT_QUOTES_TTL,\n resourceType: 'quotes',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.quotes.data = response;\n }\n });\n\n return response;\n }\n\n /**\n * Starts automatic quote polling with a 15-second refresh interval.\n * Fetches quotes immediately and then every 15 seconds.\n * If the response contains exactly one quote, it is auto-selected.\n * If multiple quotes are returned, the existing selection is preserved if still valid.\n *\n * @param options - Parameters for fetching quotes.\n * @param options.walletAddress - The destination wallet address.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @throws If required dependencies (region, token, provider, payment method) are not set.\n */\n startQuotePolling(options: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n }): void {\n // Validate required dependencies\n const regionCode = this.state.userRegion?.regionCode;\n const token = this.state.tokens.selected;\n const provider = this.state.providers.selected;\n const paymentMethod = this.state.paymentMethods.selected;\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot start quote polling without valid region information.',\n );\n }\n\n if (!token) {\n throw new Error(\n 'Token is required. Cannot start quote polling without a selected token.',\n );\n }\n\n if (!provider) {\n throw new Error(\n 'Provider is required. Cannot start quote polling without a selected provider.',\n );\n }\n\n if (!paymentMethod) {\n throw new Error(\n 'Payment method is required. Cannot start quote polling without a selected payment method.',\n );\n }\n\n // Stop any existing polling first\n this.stopQuotePolling();\n\n // Store options for restarts (must be after stop to avoid being cleared)\n this.#quotePollingOptions = options;\n\n // Define the fetch function\n const fetchQuotes = (): void => {\n this.#fireAndForget(\n this.getQuotes({\n assetId: token.assetId,\n amount: options.amount,\n walletAddress: options.walletAddress,\n redirectUrl: options.redirectUrl,\n paymentMethods: [paymentMethod.id],\n provider: provider.id,\n forceRefresh: true,\n }).then((response) => {\n // Auto-select logic: only when exactly one quote is returned\n this.update((state) => {\n if (response.success.length === 1) {\n state.quotes.selected = response.success[0];\n } else {\n // Keep existing selection if still valid, but update with fresh data\n const currentSelection = state.quotes.selected;\n if (currentSelection) {\n const freshQuote = response.success.find(\n (quote) =>\n quote.provider === currentSelection.provider &&\n quote.quote.paymentMethod ===\n currentSelection.quote.paymentMethod,\n );\n // Update with fresh quote data, or clear if no longer valid\n state.quotes.selected = freshQuote ?? null;\n }\n }\n });\n return undefined;\n }),\n );\n };\n\n // Fetch immediately\n fetchQuotes();\n\n // Set up 15-second polling\n this.#quotePollingInterval = setInterval(fetchQuotes, 15000);\n }\n\n /**\n * Stops automatic quote polling.\n * Does not clear quotes data or selection, only stops the interval.\n */\n stopQuotePolling(): void {\n if (this.#quotePollingInterval !== null) {\n clearInterval(this.#quotePollingInterval);\n this.#quotePollingInterval = null;\n }\n this.#quotePollingOptions = null;\n }\n\n /**\n * Manually sets the selected quote.\n *\n * @param quote - The quote to select, or null to clear the selection.\n */\n setSelectedQuote(quote: Quote | null): void {\n this.update((state) => {\n state.quotes.selected = quote;\n });\n }\n\n /**\n * Cleans up controller resources.\n * Stops any active quote polling to prevent memory leaks.\n * Should be called when the controller is no longer needed.\n */\n override destroy(): void {\n this.stopQuotePolling();\n super.destroy();\n }\n\n /**\n * Extracts the widget URL from a quote for redirect providers.\n * Returns the widget URL if available, or null if the quote doesn't have one.\n *\n * @param quote - The quote to extract the widget URL from.\n * @returns The widget URL string, or null if not available.\n */\n getWidgetUrl(quote: Quote): string | null {\n return quote.quote?.widgetUrl ?? null;\n }\n}\n"]}
1
+ {"version":3,"file":"RampsController.cjs","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n Country,\n TokensResponse,\n Provider,\n State,\n RampAction,\n PaymentMethod,\n PaymentMethodsResponse,\n QuotesResponse,\n Quote,\n GetQuotesParams,\n RampsToken,\n RampsServiceActions,\n} from './RampsService';\nimport type {\n RampsServiceGetGeolocationAction,\n RampsServiceGetCountriesAction,\n RampsServiceGetTokensAction,\n RampsServiceGetProvidersAction,\n RampsServiceGetPaymentMethodsAction,\n RampsServiceGetQuotesAction,\n} from './RampsService-method-action-types';\nimport type {\n RequestCache as RequestCacheType,\n RequestState,\n ExecuteRequestOptions,\n PendingRequest,\n ResourceType,\n} from './RequestCache';\nimport {\n DEFAULT_REQUEST_CACHE_TTL,\n DEFAULT_REQUEST_CACHE_MAX_SIZE,\n createCacheKey,\n isCacheExpired,\n createLoadingState,\n createSuccessState,\n createErrorState,\n RequestStatus,\n} from './RequestCache';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link RampsController}, used to namespace the\n * controller's actions and events and to namespace the controller's state data\n * when composed with other controllers.\n */\nexport const controllerName = 'RampsController';\n\n/**\n * RampsService action types that RampsController calls via the messenger.\n * Any host (e.g. mobile) that creates a RampsController messenger must delegate\n * these actions from the root messenger so the controller can function.\n */\nexport const RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS: readonly RampsServiceActions['type'][] =\n [\n 'RampsService:getGeolocation',\n 'RampsService:getCountries',\n 'RampsService:getTokens',\n 'RampsService:getProviders',\n 'RampsService:getPaymentMethods',\n 'RampsService:getQuotes',\n ];\n\n/**\n * Default TTL for quotes requests (15 seconds).\n * Quotes are time-sensitive and should have a shorter cache duration.\n */\nconst DEFAULT_QUOTES_TTL = 15000;\n\n// === STATE ===\n\n/**\n * Represents the user's selected region with full country and state objects.\n */\nexport type UserRegion = {\n /**\n * The country object for the selected region.\n */\n country: Country;\n /**\n * The state object if a state was selected, null if only country was selected.\n */\n state: State | null;\n /**\n * The region code string (e.g., \"us-ut\" or \"fr\") used for API calls.\n */\n regionCode: string;\n};\n\n/**\n * Generic type for resource state that bundles data with loading/error states.\n *\n * @template TData - The type of the resource data\n * @template TSelected - The type of the selected item (defaults to null for resources without selection)\n */\nexport type ResourceState<TData, TSelected = null> = {\n /**\n * The resource data.\n */\n data: TData;\n /**\n * The currently selected item, or null if none selected.\n */\n selected: TSelected;\n /**\n * Whether the resource is currently being fetched.\n */\n isLoading: boolean;\n /**\n * Error message if the fetch failed, or null.\n */\n error: string | null;\n};\n\n/**\n * Describes the shape of the state object for {@link RampsController}.\n */\nexport type RampsControllerState = {\n /**\n * The user's region (full country and state objects).\n * Initially set via geolocation fetch, but can be manually changed by the user.\n */\n userRegion: UserRegion | null;\n /**\n * Countries resource state with data, loading, and error.\n * Data contains the list of countries available for ramp actions.\n */\n countries: ResourceState<Country[]>;\n /**\n * Providers resource state with data, selected, loading, and error.\n * Data contains the list of providers available for the current region.\n */\n providers: ResourceState<Provider[], Provider | null>;\n /**\n * Tokens resource state with data, selected, loading, and error.\n * Data contains topTokens and allTokens arrays.\n */\n tokens: ResourceState<TokensResponse | null, RampsToken | null>;\n /**\n * Payment methods resource state with data, selected, loading, and error.\n * Data contains payment methods filtered by region, fiat, asset, and provider.\n */\n paymentMethods: ResourceState<PaymentMethod[], PaymentMethod | null>;\n /**\n * Quotes resource state with data, selected, loading, and error.\n * Data contains quotes from multiple providers for the given parameters.\n * Selected contains the currently selected quote for the user.\n */\n quotes: ResourceState<QuotesResponse | null, Quote | null>;\n /**\n * Cache of request states, keyed by cache key.\n * This stores loading, success, and error states for API requests.\n */\n requests: RequestCacheType;\n};\n\n/**\n * The metadata for each property in {@link RampsControllerState}.\n */\nconst rampsControllerMetadata = {\n userRegion: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n countries: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n providers: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n tokens: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n paymentMethods: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n quotes: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n requests: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n} satisfies StateMetadata<RampsControllerState>;\n\n/**\n * Creates a default resource state object.\n *\n * @template TData - The type of the resource data.\n * @template TSelected - The type of the selected item.\n * @param data - The initial data value.\n * @param selected - The initial selected value.\n * @returns A ResourceState object with default loading and error values.\n */\nfunction createDefaultResourceState<TData, TSelected = null>(\n data: TData,\n selected: TSelected = null as TSelected,\n): ResourceState<TData, TSelected> {\n return {\n data,\n selected,\n isLoading: false,\n error: null,\n };\n}\n\n/**\n * Constructs the default {@link RampsController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link RampsController} state.\n */\nexport function getDefaultRampsControllerState(): RampsControllerState {\n return {\n userRegion: null,\n countries: createDefaultResourceState<Country[]>([]),\n providers: createDefaultResourceState<Provider[], Provider | null>(\n [],\n null,\n ),\n tokens: createDefaultResourceState<\n TokensResponse | null,\n RampsToken | null\n >(null, null),\n paymentMethods: createDefaultResourceState<\n PaymentMethod[],\n PaymentMethod | null\n >([], null),\n quotes: createDefaultResourceState<QuotesResponse | null, Quote | null>(\n null,\n null,\n ),\n requests: {},\n };\n}\n\n/**\n * Resets region-dependent resources (userRegion, providers, tokens, paymentMethods, quotes).\n * Mutates state in place; use from within controller update() for atomic updates.\n *\n * @param state - The state object to mutate.\n * @param options - Options for the reset.\n * @param options.clearUserRegionData - When true, sets userRegion to null (e.g. for full cleanup).\n */\nfunction resetDependentResources(\n state: RampsControllerState,\n options?: { clearUserRegionData?: boolean },\n): void {\n if (options?.clearUserRegionData) {\n state.userRegion = null;\n }\n state.providers.selected = null;\n state.providers.data = [];\n state.providers.isLoading = false;\n state.providers.error = null;\n state.tokens.selected = null;\n state.tokens.data = null;\n state.tokens.isLoading = false;\n state.tokens.error = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.paymentMethods.isLoading = false;\n state.paymentMethods.error = null;\n state.quotes.data = null;\n state.quotes.selected = null;\n state.quotes.isLoading = false;\n state.quotes.error = null;\n}\n\n// === MESSENGER ===\n\n/**\n * Retrieves the state of the {@link RampsController}.\n */\nexport type RampsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Actions that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerActions = RampsControllerGetStateAction;\n\n/**\n * Actions from other messengers that {@link RampsController} calls.\n */\ntype AllowedActions =\n | RampsServiceGetGeolocationAction\n | RampsServiceGetCountriesAction\n | RampsServiceGetTokensAction\n | RampsServiceGetProvidersAction\n | RampsServiceGetPaymentMethodsAction\n | RampsServiceGetQuotesAction;\n\n/**\n * Published when the state of {@link RampsController} changes.\n */\nexport type RampsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Events that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerEvents = RampsControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link RampsController} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link RampsController}.\n */\nexport type RampsControllerMessenger = Messenger<\n typeof controllerName,\n RampsControllerActions | AllowedActions,\n RampsControllerEvents | AllowedEvents\n>;\n\n/**\n * Configuration options for the RampsController.\n */\nexport type RampsControllerOptions = {\n /** The messenger suited for this controller. */\n messenger: RampsControllerMessenger;\n /** The desired state with which to initialize this controller. */\n state?: Partial<RampsControllerState>;\n /** Time to live for cached requests in milliseconds. Defaults to 15 minutes. */\n requestCacheTTL?: number;\n /** Maximum number of entries in the request cache. Defaults to 250. */\n requestCacheMaxSize?: number;\n};\n\n// === HELPER FUNCTIONS ===\n\n/**\n * Finds a country and state from a region code string.\n *\n * @param regionCode - The region code (e.g., \"us-ca\" or \"us\").\n * @param countries - Array of countries to search.\n * @returns UserRegion object with country and state, or null if not found.\n */\nfunction findRegionFromCode(\n regionCode: string,\n countries: Country[],\n): UserRegion | null {\n const normalizedCode = regionCode.toLowerCase().trim();\n const parts = normalizedCode.split('-');\n const countryCode = parts[0];\n const stateCode = parts[1];\n\n const country = countries.find((countryItem) => {\n if (countryItem.isoCode?.toLowerCase() === countryCode) {\n return true;\n }\n if (countryItem.id) {\n const id = countryItem.id.toLowerCase();\n if (id.startsWith('/regions/')) {\n const extractedCode = id.replace('/regions/', '').split('/')[0];\n return extractedCode === countryCode;\n }\n return id === countryCode || id.endsWith(`/${countryCode}`);\n }\n return false;\n });\n\n if (!country) {\n return null;\n }\n\n let state: State | null = null;\n if (stateCode && country.states) {\n state =\n country.states.find((stateItem) => {\n if (stateItem.stateId?.toLowerCase() === stateCode) {\n return true;\n }\n if (stateItem.id) {\n const stateId = stateItem.id.toLowerCase();\n if (\n stateId.includes(`-${stateCode}`) ||\n stateId.endsWith(`/${stateCode}`)\n ) {\n return true;\n }\n }\n return false;\n }) ?? null;\n }\n\n return {\n country,\n state,\n regionCode: normalizedCode,\n };\n}\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * Manages cryptocurrency on/off ramps functionality.\n */\nexport class RampsController extends BaseController<\n typeof controllerName,\n RampsControllerState,\n RampsControllerMessenger\n> {\n /**\n * Default TTL for cached requests.\n */\n readonly #requestCacheTTL: number;\n\n /**\n * Maximum number of entries in the request cache.\n */\n readonly #requestCacheMaxSize: number;\n\n /**\n * Map of pending requests for deduplication.\n * Key is the cache key, value is the pending request with abort controller.\n */\n readonly #pendingRequests: Map<string, PendingRequest> = new Map();\n\n /**\n * Count of in-flight requests per resource type.\n * Used so isLoading is only cleared when the last request for that resource finishes.\n */\n readonly #pendingResourceCount: Map<ResourceType, number> = new Map();\n\n /**\n * Interval ID for automatic quote polling.\n * Set when startQuotePolling() is called, cleared when stopQuotePolling() is called.\n */\n #quotePollingInterval: ReturnType<typeof setInterval> | null = null;\n\n /**\n * Options used for quote polling (walletAddress, amount, redirectUrl).\n * Stored so polling can be restarted when dependencies change.\n */\n #quotePollingOptions: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n } | null = null;\n\n /**\n * Clears the pending resource count map. Used only in tests to exercise the\n * defensive path when get() returns undefined in the finally block.\n *\n * @internal\n */\n clearPendingResourceCountForTest(): void {\n this.#pendingResourceCount.clear();\n }\n\n #clearPendingResourceCountForDependentResources(): void {\n const types: ResourceType[] = [\n 'providers',\n 'tokens',\n 'paymentMethods',\n 'quotes',\n ];\n for (const resourceType of types) {\n this.#pendingResourceCount.delete(resourceType);\n }\n }\n\n /**\n * Constructs a new {@link RampsController}.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this controller.\n * @param args.state - The desired state with which to initialize this\n * controller. Missing properties will be filled in with defaults.\n * @param args.requestCacheTTL - Time to live for cached requests in milliseconds.\n * @param args.requestCacheMaxSize - Maximum number of entries in the request cache.\n */\n constructor({\n messenger,\n state = {},\n requestCacheTTL = DEFAULT_REQUEST_CACHE_TTL,\n requestCacheMaxSize = DEFAULT_REQUEST_CACHE_MAX_SIZE,\n }: RampsControllerOptions) {\n super({\n messenger,\n metadata: rampsControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultRampsControllerState(),\n ...state,\n // Always reset requests cache on initialization (non-persisted)\n requests: {},\n },\n });\n\n this.#requestCacheTTL = requestCacheTTL;\n this.#requestCacheMaxSize = requestCacheMaxSize;\n }\n\n /**\n * Executes a request with caching and deduplication.\n *\n * If a request with the same cache key is already in flight, returns the\n * existing promise. If valid cached data exists, returns it without making\n * a new request.\n *\n * @param cacheKey - Unique identifier for this request.\n * @param fetcher - Function that performs the actual fetch. Receives an AbortSignal.\n * @param options - Options for cache behavior.\n * @returns The result of the request.\n */\n async executeRequest<TResult>(\n cacheKey: string,\n fetcher: (signal: AbortSignal) => Promise<TResult>,\n options?: ExecuteRequestOptions,\n ): Promise<TResult> {\n const ttl = options?.ttl ?? this.#requestCacheTTL;\n\n // Check for existing pending request - join it instead of making a duplicate\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n return pending.promise as Promise<TResult>;\n }\n\n if (!options?.forceRefresh) {\n const cached = this.state.requests[cacheKey];\n if (cached && !isCacheExpired(cached, ttl)) {\n return cached.data as TResult;\n }\n }\n\n // Create abort controller for this request\n const abortController = new AbortController();\n const lastFetchedAt = Date.now();\n const { resourceType } = options ?? {};\n\n // Update state to loading\n this.#updateRequestState(cacheKey, createLoadingState());\n\n // Set resource-level loading state (only on cache miss). Ref-count so concurrent\n // requests for the same resource type (different cache keys) keep isLoading true.\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n this.#pendingResourceCount.set(resourceType, count + 1);\n if (count === 0) {\n this.#setResourceLoading(resourceType, true);\n }\n }\n\n // Create the fetch promise\n const promise = (async (): Promise<TResult> => {\n try {\n const data = await fetcher(abortController.signal);\n\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw new Error('Request was aborted');\n }\n\n this.#updateRequestState(\n cacheKey,\n createSuccessState(data as Json, lastFetchedAt),\n );\n\n if (resourceType) {\n // We need the extra logic because there are two situations where we’re allowed to clear the error:\n // No callback → always clear\n // Callback present → clear only when isResultCurrent() returns true.\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, null);\n }\n }\n\n return data;\n } catch (error) {\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw error;\n }\n\n const errorMessage = (error as Error)?.message ?? 'Unknown error';\n\n this.#updateRequestState(\n cacheKey,\n createErrorState(errorMessage, lastFetchedAt),\n );\n\n if (resourceType) {\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, errorMessage);\n }\n }\n\n throw error;\n } finally {\n // Only delete if this is still our entry (not replaced by a new request)\n const currentPending = this.#pendingRequests.get(cacheKey);\n if (currentPending?.abortController === abortController) {\n this.#pendingRequests.delete(cacheKey);\n }\n\n // Clear resource-level loading state only when no requests for this resource remain\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n const next = Math.max(0, count - 1);\n if (next === 0) {\n this.#pendingResourceCount.delete(resourceType);\n this.#setResourceLoading(resourceType, false);\n } else {\n this.#pendingResourceCount.set(resourceType, next);\n }\n }\n }\n })();\n\n // Store pending request for deduplication\n this.#pendingRequests.set(cacheKey, { promise, abortController });\n\n return promise;\n }\n\n /**\n * Aborts a pending request if one exists.\n *\n * @param cacheKey - The cache key of the request to abort.\n * @returns True if a request was aborted.\n */\n abortRequest(cacheKey: string): boolean {\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n pending.abortController.abort();\n this.#pendingRequests.delete(cacheKey);\n this.#removeRequestState(cacheKey);\n return true;\n }\n return false;\n }\n\n /**\n * Removes a request state from the cache.\n *\n * @param cacheKey - The cache key to remove.\n */\n #removeRequestState(cacheKey: string): void {\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n delete requests[cacheKey];\n });\n }\n\n #cleanupState(): void {\n this.stopQuotePolling();\n this.#clearPendingResourceCountForDependentResources();\n this.update((state) =>\n resetDependentResources(state as unknown as RampsControllerState, {\n clearUserRegionData: true,\n }),\n );\n }\n\n /**\n * Executes a promise without awaiting, swallowing errors.\n * Errors are stored in state via executeRequest.\n *\n * @param promise - The promise to execute.\n */\n #fireAndForget<Result>(promise: Promise<Result>): void {\n promise.catch((_error: unknown) => undefined);\n }\n\n /**\n * Restarts quote polling if it's currently active.\n * Used when dependencies change (token, provider, payment method).\n * Will only restart if all dependencies are still met (startQuotePolling validates this).\n */\n #restartPollingIfActive(): void {\n if (this.#quotePollingInterval !== null && this.#quotePollingOptions) {\n const options = this.#quotePollingOptions;\n this.stopQuotePolling();\n try {\n this.startQuotePolling(options);\n } catch {\n // Dependencies not met yet, polling will need to be manually restarted\n // when dependencies are available\n }\n }\n }\n\n /**\n * Updates a single field (isLoading or error) on a resource state.\n * All resources share the same ResourceState structure, so we use\n * dynamic property access to avoid duplicating switch statements.\n *\n * @param resourceType - The type of resource.\n * @param field - The field to update ('isLoading' or 'error').\n * @param value - The value to set.\n */\n #updateResourceField(\n resourceType: ResourceType,\n field: 'isLoading' | 'error',\n value: boolean | string | null,\n ): void {\n this.update((state) => {\n const resource = state[resourceType];\n if (resource) {\n (resource as Record<string, unknown>)[field] = value;\n }\n });\n }\n\n /**\n * Sets the loading state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param loading - Whether the resource is loading.\n */\n #setResourceLoading(resourceType: ResourceType, loading: boolean): void {\n this.#updateResourceField(resourceType, 'isLoading', loading);\n }\n\n /**\n * Sets the error state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param error - The error message, or null to clear.\n */\n #setResourceError(resourceType: ResourceType, error: string | null): void {\n this.#updateResourceField(resourceType, 'error', error);\n }\n\n /**\n * Gets the state of a specific cached request.\n *\n * @param cacheKey - The cache key to look up.\n * @returns The request state, or undefined if not cached.\n */\n getRequestState(cacheKey: string): RequestState | undefined {\n return this.state.requests[cacheKey];\n }\n\n /**\n * Updates the state for a specific request.\n *\n * @param cacheKey - The cache key.\n * @param requestState - The new state for the request.\n */\n #updateRequestState(cacheKey: string, requestState: RequestState): void {\n const maxSize = this.#requestCacheMaxSize;\n const ttl = this.#requestCacheTTL;\n\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n requests[cacheKey] = requestState;\n\n // Evict expired entries based on TTL\n // Only evict SUCCESS states that have exceeded their TTL\n const keys = Object.keys(requests);\n for (const key of keys) {\n const entry = requests[key];\n if (\n entry &&\n entry.status === RequestStatus.SUCCESS &&\n isCacheExpired(entry, ttl)\n ) {\n delete requests[key];\n }\n }\n\n // Evict oldest entries if cache still exceeds max size\n const remainingKeys = Object.keys(requests);\n if (remainingKeys.length > maxSize) {\n // Sort by timestamp (oldest first)\n const sortedKeys = remainingKeys.sort((a, b) => {\n const aTime = requests[a]?.timestamp ?? 0;\n const bTime = requests[b]?.timestamp ?? 0;\n return aTime - bTime;\n });\n\n // Remove oldest entries until we're under the limit\n const entriesToRemove = remainingKeys.length - maxSize;\n for (let i = 0; i < entriesToRemove; i++) {\n const keyToRemove = sortedKeys[i];\n if (keyToRemove) {\n delete requests[keyToRemove];\n }\n }\n }\n });\n }\n\n /**\n * Sets the user's region manually (without fetching geolocation).\n * This allows users to override the detected region.\n *\n * @param region - The region code to set (e.g., \"US-CA\").\n * @param options - Options for cache behavior.\n * @returns The user region object.\n */\n async setUserRegion(\n region: string,\n options?: ExecuteRequestOptions,\n ): Promise<UserRegion> {\n const normalizedRegion = region.toLowerCase().trim();\n\n try {\n const countriesData = this.state.countries.data;\n if (!countriesData || countriesData.length === 0) {\n this.#cleanupState();\n throw new Error(\n 'No countries found. Cannot set user region without valid country information.',\n );\n }\n\n const userRegion = findRegionFromCode(normalizedRegion, countriesData);\n\n if (!userRegion) {\n this.#cleanupState();\n throw new Error(\n `Region \"${normalizedRegion}\" not found in countries data. Cannot set user region without valid country information.`,\n );\n }\n\n const regionChanged =\n normalizedRegion !== this.state.userRegion?.regionCode;\n\n const needsRefetch =\n regionChanged ||\n !this.state.tokens.data ||\n this.state.providers.data.length === 0;\n\n if (regionChanged) {\n this.#clearPendingResourceCountForDependentResources();\n }\n if (regionChanged) {\n this.stopQuotePolling();\n }\n this.update((state) => {\n if (regionChanged) {\n resetDependentResources(state as unknown as RampsControllerState);\n }\n state.userRegion = userRegion;\n });\n\n if (needsRefetch) {\n const refetchPromises: Promise<unknown>[] = [];\n if (regionChanged || !this.state.tokens.data) {\n refetchPromises.push(\n this.getTokens(userRegion.regionCode, 'buy', options),\n );\n }\n if (regionChanged || this.state.providers.data.length === 0) {\n refetchPromises.push(\n this.getProviders(userRegion.regionCode, options),\n );\n }\n if (refetchPromises.length > 0) {\n this.#fireAndForget(Promise.all(refetchPromises));\n }\n }\n\n return userRegion;\n } catch (error) {\n this.#cleanupState();\n throw error;\n }\n }\n\n /**\n * Sets the user's selected provider by ID, or clears the selection.\n * Looks up the provider from the current providers in state and automatically\n * fetches payment methods for that provider.\n *\n * @param providerId - The provider ID (e.g., \"/providers/moonpay\"), or null to clear.\n * @throws If region is not set, providers are not loaded, or provider is not found.\n */\n setSelectedProvider(providerId: string | null): void {\n if (providerId === null) {\n this.stopQuotePolling();\n this.update((state) => {\n state.providers.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected provider without valid region information.',\n );\n }\n\n const providers = this.state.providers.data;\n if (!providers || providers.length === 0) {\n throw new Error(\n 'Providers not loaded. Cannot set selected provider before providers are fetched.',\n );\n }\n\n const provider = providers.find((prov) => prov.id === providerId);\n if (!provider) {\n throw new Error(\n `Provider with ID \"${providerId}\" not found in available providers.`,\n );\n }\n\n this.update((state) => {\n state.providers.selected = provider;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { provider: provider.id }).then(() => {\n // Restart quote polling after payment methods are fetched\n this.#restartPollingIfActive();\n return undefined;\n }),\n );\n }\n\n /**\n * Initializes the controller by fetching the user's region from geolocation.\n * This should be called once at app startup to set up the initial region.\n *\n * If a userRegion already exists (from persistence or manual selection),\n * this method will skip geolocation fetch and use the existing region.\n *\n * @param options - Options for cache behavior.\n * @returns Promise that resolves when initialization is complete.\n */\n async init(options?: ExecuteRequestOptions): Promise<void> {\n await this.getCountries(options);\n\n let regionCode = this.state.userRegion?.regionCode;\n regionCode ??= await this.messenger.call('RampsService:getGeolocation');\n\n if (!regionCode) {\n throw new Error(\n 'Failed to fetch geolocation. Cannot initialize controller without valid region information.',\n );\n }\n\n await this.setUserRegion(regionCode, options);\n }\n\n hydrateState(options?: ExecuteRequestOptions): void {\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region code is required. Cannot hydrate state without valid region information.',\n );\n }\n\n this.#fireAndForget(this.getTokens(regionCode, 'buy', options));\n this.#fireAndForget(this.getProviders(regionCode, options));\n }\n\n /**\n * Fetches the list of supported countries.\n * The API returns countries with support information for both buy and sell actions.\n * The countries are saved in the controller state once fetched.\n *\n * @param options - Options for cache behavior.\n * @returns An array of countries.\n */\n async getCountries(options?: ExecuteRequestOptions): Promise<Country[]> {\n const cacheKey = createCacheKey('getCountries', []);\n\n const countries = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getCountries');\n },\n { ...options, resourceType: 'countries' },\n );\n\n this.update((state) => {\n state.countries.data = countries;\n });\n\n return countries;\n }\n\n /**\n * Fetches the list of available tokens for a given region and action.\n * The tokens are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param action - The ramp action type ('buy' or 'sell').\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @returns The tokens response containing topTokens and allTokens.\n */\n async getTokens(\n region?: string,\n action: RampAction = 'buy',\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n },\n ): Promise<TokensResponse> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getTokens', [\n normalizedRegion,\n action,\n options?.provider,\n ]);\n\n const tokens = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getTokens',\n normalizedRegion,\n action,\n {\n provider: options?.provider,\n },\n );\n },\n {\n ...options,\n resourceType: 'tokens',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.tokens.data = tokens;\n }\n });\n\n return tokens;\n }\n\n /**\n * Sets the user's selected token by asset ID.\n * Looks up the token from the current tokens in state and automatically\n * fetches payment methods for that token.\n *\n * @param assetId - The asset identifier in CAIP-19 format (e.g., \"eip155:1/erc20:0x...\"), or undefined to clear.\n * @throws If region is not set, tokens are not loaded, or token is not found.\n */\n setSelectedToken(assetId?: string): void {\n if (!assetId) {\n this.stopQuotePolling();\n this.update((state) => {\n state.tokens.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected token without valid region information.',\n );\n }\n\n const tokens = this.state.tokens.data;\n if (!tokens) {\n throw new Error(\n 'Tokens not loaded. Cannot set selected token before tokens are fetched.',\n );\n }\n\n const token =\n tokens.allTokens.find((tok) => tok.assetId === assetId) ??\n tokens.topTokens.find((tok) => tok.assetId === assetId);\n\n if (!token) {\n throw new Error(\n `Token with asset ID \"${assetId}\" not found in available tokens.`,\n );\n }\n\n this.update((state) => {\n state.tokens.selected = token;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { assetId: token.assetId }).then(\n () => {\n this.#restartPollingIfActive();\n return undefined;\n },\n ),\n );\n }\n\n /**\n * Fetches the list of providers for a given region.\n * The providers are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @param options.crypto - Crypto currency ID(s) to filter by.\n * @param options.fiat - Fiat currency ID(s) to filter by.\n * @param options.payments - Payment method ID(s) to filter by.\n * @returns The providers response containing providers array.\n */\n async getProviders(\n region?: string,\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n crypto?: string | string[];\n fiat?: string | string[];\n payments?: string | string[];\n },\n ): Promise<{ providers: Provider[] }> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getProviders', [\n normalizedRegion,\n options?.provider,\n options?.crypto,\n options?.fiat,\n options?.payments,\n ]);\n\n const { providers } = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getProviders',\n normalizedRegion,\n {\n provider: options?.provider,\n crypto: options?.crypto,\n fiat: options?.fiat,\n payments: options?.payments,\n },\n );\n },\n {\n ...options,\n resourceType: 'providers',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.providers.data = providers;\n }\n });\n\n return { providers };\n }\n\n /**\n * Fetches the list of payment methods for a given context.\n * The payment methods are saved in the controller state once fetched.\n *\n * @param region - User's region code (e.g. \"fr\", \"us-ny\").\n * @param options - Query parameters for filtering payment methods.\n * @param options.fiat - Fiat currency code (e.g., \"usd\"). If not provided, uses the user's region currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.provider - Provider ID path.\n * @returns The payment methods response containing payments array.\n */\n async getPaymentMethods(\n region?: string,\n options?: ExecuteRequestOptions & {\n fiat?: string;\n assetId?: string;\n provider?: string;\n },\n ): Promise<PaymentMethodsResponse> {\n const regionCode = region ?? this.state.userRegion?.regionCode ?? null;\n const fiatToUse =\n options?.fiat ?? this.state.userRegion?.country?.currency ?? null;\n const assetIdToUse =\n options?.assetId ?? this.state.tokens.selected?.assetId ?? '';\n const providerToUse =\n options?.provider ?? this.state.providers.selected?.id ?? '';\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionCode.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getPaymentMethods', [\n normalizedRegion,\n normalizedFiat,\n assetIdToUse,\n providerToUse,\n ]);\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getPaymentMethods', {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: assetIdToUse,\n provider: providerToUse,\n });\n },\n {\n ...options,\n resourceType: 'paymentMethods',\n isResultCurrent: () => {\n const regionMatch =\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion;\n const tokenMatch =\n (this.state.tokens.selected?.assetId ?? '') === assetIdToUse;\n const providerMatch =\n (this.state.providers.selected?.id ?? '') === providerToUse;\n return regionMatch && tokenMatch && providerMatch;\n },\n },\n );\n\n this.update((state) => {\n const currentAssetId = state.tokens.selected?.assetId ?? '';\n const currentProviderId = state.providers.selected?.id ?? '';\n\n const tokenSelectionUnchanged = assetIdToUse === currentAssetId;\n const providerSelectionUnchanged = providerToUse === currentProviderId;\n\n // this is a race condition check to ensure that the selected token and provider in state are the same as the tokens we're requesting for\n // ex: if the user rapidly changes the token or provider, the in-flight payment methods might not be valid\n // so this check will ensure that the payment methods are still valid for the token and provider that were requested\n if (tokenSelectionUnchanged && providerSelectionUnchanged) {\n state.paymentMethods.data = response.payments;\n\n // this will auto-select the first payment method if the selected payment method is not in the new payment methods\n const currentSelectionStillValid = response.payments.some(\n (pm: PaymentMethod) => pm.id === state.paymentMethods.selected?.id,\n );\n if (!currentSelectionStillValid) {\n state.paymentMethods.selected = response.payments[0] ?? null;\n }\n }\n });\n\n return response;\n }\n\n /**\n * Sets the user's selected payment method by ID.\n * Looks up the payment method from the current payment methods in state.\n *\n * @param paymentMethodId - The payment method ID (e.g., \"/payments/debit-credit-card\"), or null to clear.\n * @throws If payment methods are not loaded or payment method is not found.\n */\n setSelectedPaymentMethod(paymentMethodId?: string): void {\n if (!paymentMethodId) {\n this.update((state) => {\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const paymentMethods = this.state.paymentMethods.data;\n if (!paymentMethods || paymentMethods.length === 0) {\n throw new Error(\n 'Payment methods not loaded. Cannot set selected payment method before payment methods are fetched.',\n );\n }\n\n const paymentMethod = paymentMethods.find(\n (pm) => pm.id === paymentMethodId,\n );\n if (!paymentMethod) {\n throw new Error(\n `Payment method with ID \"${paymentMethodId}\" not found in available payment methods.`,\n );\n }\n\n this.update((state) => {\n state.paymentMethods.selected = paymentMethod;\n });\n\n // Restart quote polling if active\n this.#restartPollingIfActive();\n }\n\n /**\n * Fetches quotes from all providers for a given set of parameters.\n * The quotes are saved in the controller state once fetched.\n *\n * @param options - The parameters for fetching quotes.\n * @param options.region - User's region code. If not provided, uses userRegion from state.\n * @param options.fiat - Fiat currency code. If not provided, uses userRegion currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.walletAddress - The destination wallet address.\n * @param options.paymentMethods - Array of payment method IDs. If not provided, uses paymentMethods from state.\n * @param options.provider - Optional provider ID to filter quotes.\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @param options.action - The ramp action type. Defaults to 'buy'.\n * @param options.forceRefresh - Whether to bypass cache.\n * @param options.ttl - Custom TTL for this request.\n * @returns The quotes response containing success, sorted, error, and customActions.\n */\n async getQuotes(options: {\n region?: string;\n fiat?: string;\n assetId: string;\n amount: number;\n walletAddress: string;\n paymentMethods?: string[];\n provider?: string;\n redirectUrl?: string;\n action?: RampAction;\n forceRefresh?: boolean;\n ttl?: number;\n }): Promise<QuotesResponse> {\n const regionToUse = options.region ?? this.state.userRegion?.regionCode;\n const fiatToUse = options.fiat ?? this.state.userRegion?.country?.currency;\n const paymentMethodsToUse =\n options.paymentMethods ??\n this.state.paymentMethods.data.map((pm: PaymentMethod) => pm.id);\n const action = options.action ?? 'buy';\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!paymentMethodsToUse || paymentMethodsToUse.length === 0) {\n throw new Error(\n 'Payment methods are required. Either provide paymentMethods parameter or ensure paymentMethods are set in controller state.',\n );\n }\n\n if (options.amount <= 0 || !Number.isFinite(options.amount)) {\n throw new Error('Amount must be a positive finite number.');\n }\n\n if (!options.assetId || options.assetId.trim() === '') {\n throw new Error('assetId is required.');\n }\n\n if (!options.walletAddress || options.walletAddress.trim() === '') {\n throw new Error('walletAddress is required.');\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const normalizedAssetId = options.assetId.trim();\n const normalizedWalletAddress = options.walletAddress.trim();\n\n const cacheKey = createCacheKey('getQuotes', [\n normalizedRegion,\n normalizedFiat,\n normalizedAssetId,\n options.amount,\n normalizedWalletAddress,\n [...paymentMethodsToUse].sort().join(','),\n options.provider,\n options.redirectUrl,\n action,\n ]);\n\n const params: GetQuotesParams = {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: normalizedAssetId,\n amount: options.amount,\n walletAddress: normalizedWalletAddress,\n paymentMethods: paymentMethodsToUse,\n provider: options.provider,\n redirectUrl: options.redirectUrl,\n action,\n };\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getQuotes', params);\n },\n {\n forceRefresh: options.forceRefresh,\n ttl: options.ttl ?? DEFAULT_QUOTES_TTL,\n resourceType: 'quotes',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.quotes.data = response;\n }\n });\n\n return response;\n }\n\n /**\n * Starts automatic quote polling with a 15-second refresh interval.\n * Fetches quotes immediately and then every 15 seconds.\n * If the response contains exactly one quote, it is auto-selected.\n * If multiple quotes are returned, the existing selection is preserved if still valid.\n *\n * @param options - Parameters for fetching quotes.\n * @param options.walletAddress - The destination wallet address.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @throws If required dependencies (region, token, provider, payment method) are not set.\n */\n startQuotePolling(options: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n }): void {\n // Validate required dependencies\n const regionCode = this.state.userRegion?.regionCode;\n const token = this.state.tokens.selected;\n const provider = this.state.providers.selected;\n const paymentMethod = this.state.paymentMethods.selected;\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot start quote polling without valid region information.',\n );\n }\n\n if (!token) {\n throw new Error(\n 'Token is required. Cannot start quote polling without a selected token.',\n );\n }\n\n if (!provider) {\n throw new Error(\n 'Provider is required. Cannot start quote polling without a selected provider.',\n );\n }\n\n if (!paymentMethod) {\n return;\n }\n\n // Stop any existing polling first\n this.stopQuotePolling();\n\n // Store options for restarts (must be after stop to avoid being cleared)\n this.#quotePollingOptions = options;\n\n // Define the fetch function\n const fetchQuotes = (): void => {\n this.#fireAndForget(\n this.getQuotes({\n assetId: token.assetId,\n amount: options.amount,\n walletAddress: options.walletAddress,\n redirectUrl: options.redirectUrl,\n paymentMethods: [paymentMethod.id],\n provider: provider.id,\n forceRefresh: true,\n }).then((response) => {\n // Auto-select logic: only when exactly one quote is returned\n this.update((state) => {\n if (response.success.length === 1) {\n state.quotes.selected = response.success[0];\n } else {\n // Keep existing selection if still valid, but update with fresh data\n const currentSelection = state.quotes.selected;\n if (currentSelection) {\n const freshQuote = response.success.find(\n (quote) =>\n quote.provider === currentSelection.provider &&\n quote.quote.paymentMethod ===\n currentSelection.quote.paymentMethod,\n );\n // Update with fresh quote data, or clear if no longer valid\n state.quotes.selected = freshQuote ?? null;\n }\n }\n });\n return undefined;\n }),\n );\n };\n\n // Fetch immediately\n fetchQuotes();\n\n // Set up 15-second polling\n this.#quotePollingInterval = setInterval(fetchQuotes, 15000);\n }\n\n /**\n * Stops automatic quote polling.\n * Does not clear quotes data or selection, only stops the interval.\n */\n stopQuotePolling(): void {\n if (this.#quotePollingInterval !== null) {\n clearInterval(this.#quotePollingInterval);\n this.#quotePollingInterval = null;\n }\n this.#quotePollingOptions = null;\n }\n\n /**\n * Manually sets the selected quote.\n *\n * @param quote - The quote to select, or null to clear the selection.\n */\n setSelectedQuote(quote: Quote | null): void {\n this.update((state) => {\n state.quotes.selected = quote;\n });\n }\n\n /**\n * Cleans up controller resources.\n * Stops any active quote polling to prevent memory leaks.\n * Should be called when the controller is no longer needed.\n */\n override destroy(): void {\n this.stopQuotePolling();\n super.destroy();\n }\n\n /**\n * Extracts the widget URL from a quote for redirect providers.\n * Returns the widget URL if available, or null if the quote doesn't have one.\n *\n * @param quote - The quote to extract the widget URL from.\n * @returns The widget URL string, or null if not available.\n */\n getWidgetUrl(quote: Quote): string | null {\n return quote.quote?.widgetUrl ?? null;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"RampsController.d.cts","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RampsController.d.cts","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RampsController.d.mts","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAE3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAGrD,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,QAAQ,EACR,KAAK,EACL,UAAU,EACV,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,KAAK,EAEL,UAAU,EACV,mBAAmB,EACpB,2BAAuB;AACxB,OAAO,KAAK,EACV,gCAAgC,EAChC,8BAA8B,EAC9B,2BAA2B,EAC3B,8BAA8B,EAC9B,mCAAmC,EACnC,2BAA2B,EAC5B,+CAA2C;AAC5C,OAAO,KAAK,EACV,YAAY,IAAI,gBAAgB,EAChC,YAAY,EACZ,qBAAqB,EAGtB,2BAAuB;AAcxB;;;;GAIG;AACH,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,yCAAyC,EAAE,SAAS,mBAAmB,CAAC,MAAM,CAAC,EAQzF,CAAC;AAUJ;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,IAAI;IACnD;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC;IACZ;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,SAAS,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IACpC;;;OAGG;IACH,SAAS,EAAE,aAAa,CAAC,QAAQ,EAAE,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAC;IACtD;;;OAGG;IACH,MAAM,EAAE,aAAa,CAAC,cAAc,GAAG,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC;IAChE;;;OAGG;IACH,cAAc,EAAE,aAAa,CAAC,aAAa,EAAE,EAAE,aAAa,GAAG,IAAI,CAAC,CAAC;IACrE;;;;OAIG;IACH,MAAM,EAAE,aAAa,CAAC,cAAc,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;IAC3D;;;OAGG;IACH,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC;AAuEF;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,IAAI,oBAAoB,CAsBrE;AAqCD;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,wBAAwB,CAClE,OAAO,cAAc,EACrB,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,6BAA6B,CAAC;AAEnE;;GAEG;AACH,KAAK,cAAc,GACf,gCAAgC,GAChC,8BAA8B,GAC9B,2BAA2B,GAC3B,8BAA8B,GAC9B,mCAAmC,GACnC,2BAA2B,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG,0BAA0B,CACtE,OAAO,cAAc,EACrB,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,+BAA+B,CAAC;AAEpE;;GAEG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAC9C,OAAO,cAAc,EACrB,sBAAsB,GAAG,cAAc,EACvC,qBAAqB,GAAG,aAAa,CACtC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,gDAAgD;IAChD,SAAS,EAAE,wBAAwB,CAAC;IACpC,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtC,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAoEF;;GAEG;AACH,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,cAAc,EACrB,oBAAoB,EACpB,wBAAwB,CACzB;;IAuCC;;;;;OAKG;IACH,gCAAgC,IAAI,IAAI;IAgBxC;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,KAAU,EACV,eAA2C,EAC3C,mBAAoD,GACrD,EAAE,sBAAsB;IAiBzB;;;;;;;;;;;OAWG;IACG,cAAc,CAAC,OAAO,EAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,EAClD,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,OAAO,CAAC;IA8GnB;;;;;OAKG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IA0GvC;;;;;OAKG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAyD3D;;;;;;;OAOG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,UAAU,CAAC;IAkEtB;;;;;;;OAOG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAgDpD;;;;;;;;;OASG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,YAAY,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAYnD;;;;;;;OAOG;IACG,YAAY,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAkBvE;;;;;;;;;OASG;IACG,SAAS,CACb,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,GAAE,UAAkB,EAC1B,OAAO,CAAC,EAAE,qBAAqB,GAAG;QAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KAC9B,GACA,OAAO,CAAC,cAAc,CAAC;IAgD1B;;;;;;;OAOG;IACH,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAqDxC;;;;;;;;;;;OAWG;IACG,YAAY,CAChB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,qBAAqB,GAAG;QAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KAC9B,GACA,OAAO,CAAC;QAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;KAAE,CAAC;IAoDrC;;;;;;;;;;OAUG;IACG,iBAAiB,CACrB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,qBAAqB,GAAG;QAChC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GACA,OAAO,CAAC,sBAAsB,CAAC;IAkFlC;;;;;;OAMG;IACH,wBAAwB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI;IAgCxD;;;;;;;;;;;;;;;;;OAiBG;IACG,SAAS,CAAC,OAAO,EAAE;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,UAAU,CAAC;QACpB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,cAAc,CAAC;IA6F3B;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,OAAO,EAAE;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,IAAI;IAgFR;;;OAGG;IACH,gBAAgB,IAAI,IAAI;IAQxB;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAM3C;;;;OAIG;IACM,OAAO,IAAI,IAAI;IAKxB;;;;;;OAMG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI;CAG1C"}
1
+ {"version":3,"file":"RampsController.d.mts","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"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"}
@@ -614,7 +614,6 @@ export class RampsController extends BaseController {
614
614
  state.quotes.selected = null;
615
615
  });
616
616
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_fireAndForget).call(this, this.getPaymentMethods(regionCode, { assetId: token.assetId }).then(() => {
617
- // Restart quote polling after payment methods are fetched
618
617
  __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_restartPollingIfActive).call(this);
619
618
  return undefined;
620
619
  }));
@@ -873,7 +872,7 @@ export class RampsController extends BaseController {
873
872
  throw new Error('Provider is required. Cannot start quote polling without a selected provider.');
874
873
  }
875
874
  if (!paymentMethod) {
876
- throw new Error('Payment method is required. Cannot start quote polling without a selected payment method.');
875
+ return;
877
876
  }
878
877
  // Stop any existing polling first
879
878
  this.stopQuotePolling();
@@ -1 +1 @@
1
- {"version":3,"file":"RampsController.mjs","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n Country,\n TokensResponse,\n Provider,\n State,\n RampAction,\n PaymentMethod,\n PaymentMethodsResponse,\n QuotesResponse,\n Quote,\n GetQuotesParams,\n RampsToken,\n RampsServiceActions,\n} from './RampsService';\nimport type {\n RampsServiceGetGeolocationAction,\n RampsServiceGetCountriesAction,\n RampsServiceGetTokensAction,\n RampsServiceGetProvidersAction,\n RampsServiceGetPaymentMethodsAction,\n RampsServiceGetQuotesAction,\n} from './RampsService-method-action-types';\nimport type {\n RequestCache as RequestCacheType,\n RequestState,\n ExecuteRequestOptions,\n PendingRequest,\n ResourceType,\n} from './RequestCache';\nimport {\n DEFAULT_REQUEST_CACHE_TTL,\n DEFAULT_REQUEST_CACHE_MAX_SIZE,\n createCacheKey,\n isCacheExpired,\n createLoadingState,\n createSuccessState,\n createErrorState,\n RequestStatus,\n} from './RequestCache';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link RampsController}, used to namespace the\n * controller's actions and events and to namespace the controller's state data\n * when composed with other controllers.\n */\nexport const controllerName = 'RampsController';\n\n/**\n * RampsService action types that RampsController calls via the messenger.\n * Any host (e.g. mobile) that creates a RampsController messenger must delegate\n * these actions from the root messenger so the controller can function.\n */\nexport const RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS: readonly RampsServiceActions['type'][] =\n [\n 'RampsService:getGeolocation',\n 'RampsService:getCountries',\n 'RampsService:getTokens',\n 'RampsService:getProviders',\n 'RampsService:getPaymentMethods',\n 'RampsService:getQuotes',\n ];\n\n/**\n * Default TTL for quotes requests (15 seconds).\n * Quotes are time-sensitive and should have a shorter cache duration.\n */\nconst DEFAULT_QUOTES_TTL = 15000;\n\n// === STATE ===\n\n/**\n * Represents the user's selected region with full country and state objects.\n */\nexport type UserRegion = {\n /**\n * The country object for the selected region.\n */\n country: Country;\n /**\n * The state object if a state was selected, null if only country was selected.\n */\n state: State | null;\n /**\n * The region code string (e.g., \"us-ut\" or \"fr\") used for API calls.\n */\n regionCode: string;\n};\n\n/**\n * Generic type for resource state that bundles data with loading/error states.\n *\n * @template TData - The type of the resource data\n * @template TSelected - The type of the selected item (defaults to null for resources without selection)\n */\nexport type ResourceState<TData, TSelected = null> = {\n /**\n * The resource data.\n */\n data: TData;\n /**\n * The currently selected item, or null if none selected.\n */\n selected: TSelected;\n /**\n * Whether the resource is currently being fetched.\n */\n isLoading: boolean;\n /**\n * Error message if the fetch failed, or null.\n */\n error: string | null;\n};\n\n/**\n * Describes the shape of the state object for {@link RampsController}.\n */\nexport type RampsControllerState = {\n /**\n * The user's region (full country and state objects).\n * Initially set via geolocation fetch, but can be manually changed by the user.\n */\n userRegion: UserRegion | null;\n /**\n * Countries resource state with data, loading, and error.\n * Data contains the list of countries available for ramp actions.\n */\n countries: ResourceState<Country[]>;\n /**\n * Providers resource state with data, selected, loading, and error.\n * Data contains the list of providers available for the current region.\n */\n providers: ResourceState<Provider[], Provider | null>;\n /**\n * Tokens resource state with data, selected, loading, and error.\n * Data contains topTokens and allTokens arrays.\n */\n tokens: ResourceState<TokensResponse | null, RampsToken | null>;\n /**\n * Payment methods resource state with data, selected, loading, and error.\n * Data contains payment methods filtered by region, fiat, asset, and provider.\n */\n paymentMethods: ResourceState<PaymentMethod[], PaymentMethod | null>;\n /**\n * Quotes resource state with data, selected, loading, and error.\n * Data contains quotes from multiple providers for the given parameters.\n * Selected contains the currently selected quote for the user.\n */\n quotes: ResourceState<QuotesResponse | null, Quote | null>;\n /**\n * Cache of request states, keyed by cache key.\n * This stores loading, success, and error states for API requests.\n */\n requests: RequestCacheType;\n};\n\n/**\n * The metadata for each property in {@link RampsControllerState}.\n */\nconst rampsControllerMetadata = {\n userRegion: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n countries: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n providers: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n tokens: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n paymentMethods: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n quotes: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n requests: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n} satisfies StateMetadata<RampsControllerState>;\n\n/**\n * Creates a default resource state object.\n *\n * @template TData - The type of the resource data.\n * @template TSelected - The type of the selected item.\n * @param data - The initial data value.\n * @param selected - The initial selected value.\n * @returns A ResourceState object with default loading and error values.\n */\nfunction createDefaultResourceState<TData, TSelected = null>(\n data: TData,\n selected: TSelected = null as TSelected,\n): ResourceState<TData, TSelected> {\n return {\n data,\n selected,\n isLoading: false,\n error: null,\n };\n}\n\n/**\n * Constructs the default {@link RampsController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link RampsController} state.\n */\nexport function getDefaultRampsControllerState(): RampsControllerState {\n return {\n userRegion: null,\n countries: createDefaultResourceState<Country[]>([]),\n providers: createDefaultResourceState<Provider[], Provider | null>(\n [],\n null,\n ),\n tokens: createDefaultResourceState<\n TokensResponse | null,\n RampsToken | null\n >(null, null),\n paymentMethods: createDefaultResourceState<\n PaymentMethod[],\n PaymentMethod | null\n >([], null),\n quotes: createDefaultResourceState<QuotesResponse | null, Quote | null>(\n null,\n null,\n ),\n requests: {},\n };\n}\n\n/**\n * Resets region-dependent resources (userRegion, providers, tokens, paymentMethods, quotes).\n * Mutates state in place; use from within controller update() for atomic updates.\n *\n * @param state - The state object to mutate.\n * @param options - Options for the reset.\n * @param options.clearUserRegionData - When true, sets userRegion to null (e.g. for full cleanup).\n */\nfunction resetDependentResources(\n state: RampsControllerState,\n options?: { clearUserRegionData?: boolean },\n): void {\n if (options?.clearUserRegionData) {\n state.userRegion = null;\n }\n state.providers.selected = null;\n state.providers.data = [];\n state.providers.isLoading = false;\n state.providers.error = null;\n state.tokens.selected = null;\n state.tokens.data = null;\n state.tokens.isLoading = false;\n state.tokens.error = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.paymentMethods.isLoading = false;\n state.paymentMethods.error = null;\n state.quotes.data = null;\n state.quotes.selected = null;\n state.quotes.isLoading = false;\n state.quotes.error = null;\n}\n\n// === MESSENGER ===\n\n/**\n * Retrieves the state of the {@link RampsController}.\n */\nexport type RampsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Actions that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerActions = RampsControllerGetStateAction;\n\n/**\n * Actions from other messengers that {@link RampsController} calls.\n */\ntype AllowedActions =\n | RampsServiceGetGeolocationAction\n | RampsServiceGetCountriesAction\n | RampsServiceGetTokensAction\n | RampsServiceGetProvidersAction\n | RampsServiceGetPaymentMethodsAction\n | RampsServiceGetQuotesAction;\n\n/**\n * Published when the state of {@link RampsController} changes.\n */\nexport type RampsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Events that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerEvents = RampsControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link RampsController} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link RampsController}.\n */\nexport type RampsControllerMessenger = Messenger<\n typeof controllerName,\n RampsControllerActions | AllowedActions,\n RampsControllerEvents | AllowedEvents\n>;\n\n/**\n * Configuration options for the RampsController.\n */\nexport type RampsControllerOptions = {\n /** The messenger suited for this controller. */\n messenger: RampsControllerMessenger;\n /** The desired state with which to initialize this controller. */\n state?: Partial<RampsControllerState>;\n /** Time to live for cached requests in milliseconds. Defaults to 15 minutes. */\n requestCacheTTL?: number;\n /** Maximum number of entries in the request cache. Defaults to 250. */\n requestCacheMaxSize?: number;\n};\n\n// === HELPER FUNCTIONS ===\n\n/**\n * Finds a country and state from a region code string.\n *\n * @param regionCode - The region code (e.g., \"us-ca\" or \"us\").\n * @param countries - Array of countries to search.\n * @returns UserRegion object with country and state, or null if not found.\n */\nfunction findRegionFromCode(\n regionCode: string,\n countries: Country[],\n): UserRegion | null {\n const normalizedCode = regionCode.toLowerCase().trim();\n const parts = normalizedCode.split('-');\n const countryCode = parts[0];\n const stateCode = parts[1];\n\n const country = countries.find((countryItem) => {\n if (countryItem.isoCode?.toLowerCase() === countryCode) {\n return true;\n }\n if (countryItem.id) {\n const id = countryItem.id.toLowerCase();\n if (id.startsWith('/regions/')) {\n const extractedCode = id.replace('/regions/', '').split('/')[0];\n return extractedCode === countryCode;\n }\n return id === countryCode || id.endsWith(`/${countryCode}`);\n }\n return false;\n });\n\n if (!country) {\n return null;\n }\n\n let state: State | null = null;\n if (stateCode && country.states) {\n state =\n country.states.find((stateItem) => {\n if (stateItem.stateId?.toLowerCase() === stateCode) {\n return true;\n }\n if (stateItem.id) {\n const stateId = stateItem.id.toLowerCase();\n if (\n stateId.includes(`-${stateCode}`) ||\n stateId.endsWith(`/${stateCode}`)\n ) {\n return true;\n }\n }\n return false;\n }) ?? null;\n }\n\n return {\n country,\n state,\n regionCode: normalizedCode,\n };\n}\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * Manages cryptocurrency on/off ramps functionality.\n */\nexport class RampsController extends BaseController<\n typeof controllerName,\n RampsControllerState,\n RampsControllerMessenger\n> {\n /**\n * Default TTL for cached requests.\n */\n readonly #requestCacheTTL: number;\n\n /**\n * Maximum number of entries in the request cache.\n */\n readonly #requestCacheMaxSize: number;\n\n /**\n * Map of pending requests for deduplication.\n * Key is the cache key, value is the pending request with abort controller.\n */\n readonly #pendingRequests: Map<string, PendingRequest> = new Map();\n\n /**\n * Count of in-flight requests per resource type.\n * Used so isLoading is only cleared when the last request for that resource finishes.\n */\n readonly #pendingResourceCount: Map<ResourceType, number> = new Map();\n\n /**\n * Interval ID for automatic quote polling.\n * Set when startQuotePolling() is called, cleared when stopQuotePolling() is called.\n */\n #quotePollingInterval: ReturnType<typeof setInterval> | null = null;\n\n /**\n * Options used for quote polling (walletAddress, amount, redirectUrl).\n * Stored so polling can be restarted when dependencies change.\n */\n #quotePollingOptions: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n } | null = null;\n\n /**\n * Clears the pending resource count map. Used only in tests to exercise the\n * defensive path when get() returns undefined in the finally block.\n *\n * @internal\n */\n clearPendingResourceCountForTest(): void {\n this.#pendingResourceCount.clear();\n }\n\n #clearPendingResourceCountForDependentResources(): void {\n const types: ResourceType[] = [\n 'providers',\n 'tokens',\n 'paymentMethods',\n 'quotes',\n ];\n for (const resourceType of types) {\n this.#pendingResourceCount.delete(resourceType);\n }\n }\n\n /**\n * Constructs a new {@link RampsController}.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this controller.\n * @param args.state - The desired state with which to initialize this\n * controller. Missing properties will be filled in with defaults.\n * @param args.requestCacheTTL - Time to live for cached requests in milliseconds.\n * @param args.requestCacheMaxSize - Maximum number of entries in the request cache.\n */\n constructor({\n messenger,\n state = {},\n requestCacheTTL = DEFAULT_REQUEST_CACHE_TTL,\n requestCacheMaxSize = DEFAULT_REQUEST_CACHE_MAX_SIZE,\n }: RampsControllerOptions) {\n super({\n messenger,\n metadata: rampsControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultRampsControllerState(),\n ...state,\n // Always reset requests cache on initialization (non-persisted)\n requests: {},\n },\n });\n\n this.#requestCacheTTL = requestCacheTTL;\n this.#requestCacheMaxSize = requestCacheMaxSize;\n }\n\n /**\n * Executes a request with caching and deduplication.\n *\n * If a request with the same cache key is already in flight, returns the\n * existing promise. If valid cached data exists, returns it without making\n * a new request.\n *\n * @param cacheKey - Unique identifier for this request.\n * @param fetcher - Function that performs the actual fetch. Receives an AbortSignal.\n * @param options - Options for cache behavior.\n * @returns The result of the request.\n */\n async executeRequest<TResult>(\n cacheKey: string,\n fetcher: (signal: AbortSignal) => Promise<TResult>,\n options?: ExecuteRequestOptions,\n ): Promise<TResult> {\n const ttl = options?.ttl ?? this.#requestCacheTTL;\n\n // Check for existing pending request - join it instead of making a duplicate\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n return pending.promise as Promise<TResult>;\n }\n\n if (!options?.forceRefresh) {\n const cached = this.state.requests[cacheKey];\n if (cached && !isCacheExpired(cached, ttl)) {\n return cached.data as TResult;\n }\n }\n\n // Create abort controller for this request\n const abortController = new AbortController();\n const lastFetchedAt = Date.now();\n const { resourceType } = options ?? {};\n\n // Update state to loading\n this.#updateRequestState(cacheKey, createLoadingState());\n\n // Set resource-level loading state (only on cache miss). Ref-count so concurrent\n // requests for the same resource type (different cache keys) keep isLoading true.\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n this.#pendingResourceCount.set(resourceType, count + 1);\n if (count === 0) {\n this.#setResourceLoading(resourceType, true);\n }\n }\n\n // Create the fetch promise\n const promise = (async (): Promise<TResult> => {\n try {\n const data = await fetcher(abortController.signal);\n\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw new Error('Request was aborted');\n }\n\n this.#updateRequestState(\n cacheKey,\n createSuccessState(data as Json, lastFetchedAt),\n );\n\n if (resourceType) {\n // We need the extra logic because there are two situations where we’re allowed to clear the error:\n // No callback → always clear\n // Callback present → clear only when isResultCurrent() returns true.\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, null);\n }\n }\n\n return data;\n } catch (error) {\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw error;\n }\n\n const errorMessage = (error as Error)?.message ?? 'Unknown error';\n\n this.#updateRequestState(\n cacheKey,\n createErrorState(errorMessage, lastFetchedAt),\n );\n\n if (resourceType) {\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, errorMessage);\n }\n }\n\n throw error;\n } finally {\n // Only delete if this is still our entry (not replaced by a new request)\n const currentPending = this.#pendingRequests.get(cacheKey);\n if (currentPending?.abortController === abortController) {\n this.#pendingRequests.delete(cacheKey);\n }\n\n // Clear resource-level loading state only when no requests for this resource remain\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n const next = Math.max(0, count - 1);\n if (next === 0) {\n this.#pendingResourceCount.delete(resourceType);\n this.#setResourceLoading(resourceType, false);\n } else {\n this.#pendingResourceCount.set(resourceType, next);\n }\n }\n }\n })();\n\n // Store pending request for deduplication\n this.#pendingRequests.set(cacheKey, { promise, abortController });\n\n return promise;\n }\n\n /**\n * Aborts a pending request if one exists.\n *\n * @param cacheKey - The cache key of the request to abort.\n * @returns True if a request was aborted.\n */\n abortRequest(cacheKey: string): boolean {\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n pending.abortController.abort();\n this.#pendingRequests.delete(cacheKey);\n this.#removeRequestState(cacheKey);\n return true;\n }\n return false;\n }\n\n /**\n * Removes a request state from the cache.\n *\n * @param cacheKey - The cache key to remove.\n */\n #removeRequestState(cacheKey: string): void {\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n delete requests[cacheKey];\n });\n }\n\n #cleanupState(): void {\n this.stopQuotePolling();\n this.#clearPendingResourceCountForDependentResources();\n this.update((state) =>\n resetDependentResources(state as unknown as RampsControllerState, {\n clearUserRegionData: true,\n }),\n );\n }\n\n /**\n * Executes a promise without awaiting, swallowing errors.\n * Errors are stored in state via executeRequest.\n *\n * @param promise - The promise to execute.\n */\n #fireAndForget<Result>(promise: Promise<Result>): void {\n promise.catch((_error: unknown) => undefined);\n }\n\n /**\n * Restarts quote polling if it's currently active.\n * Used when dependencies change (token, provider, payment method).\n * Will only restart if all dependencies are still met (startQuotePolling validates this).\n */\n #restartPollingIfActive(): void {\n if (this.#quotePollingInterval !== null && this.#quotePollingOptions) {\n const options = this.#quotePollingOptions;\n this.stopQuotePolling();\n try {\n this.startQuotePolling(options);\n } catch {\n // Dependencies not met yet, polling will need to be manually restarted\n // when dependencies are available\n }\n }\n }\n\n /**\n * Updates a single field (isLoading or error) on a resource state.\n * All resources share the same ResourceState structure, so we use\n * dynamic property access to avoid duplicating switch statements.\n *\n * @param resourceType - The type of resource.\n * @param field - The field to update ('isLoading' or 'error').\n * @param value - The value to set.\n */\n #updateResourceField(\n resourceType: ResourceType,\n field: 'isLoading' | 'error',\n value: boolean | string | null,\n ): void {\n this.update((state) => {\n const resource = state[resourceType];\n if (resource) {\n (resource as Record<string, unknown>)[field] = value;\n }\n });\n }\n\n /**\n * Sets the loading state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param loading - Whether the resource is loading.\n */\n #setResourceLoading(resourceType: ResourceType, loading: boolean): void {\n this.#updateResourceField(resourceType, 'isLoading', loading);\n }\n\n /**\n * Sets the error state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param error - The error message, or null to clear.\n */\n #setResourceError(resourceType: ResourceType, error: string | null): void {\n this.#updateResourceField(resourceType, 'error', error);\n }\n\n /**\n * Gets the state of a specific cached request.\n *\n * @param cacheKey - The cache key to look up.\n * @returns The request state, or undefined if not cached.\n */\n getRequestState(cacheKey: string): RequestState | undefined {\n return this.state.requests[cacheKey];\n }\n\n /**\n * Updates the state for a specific request.\n *\n * @param cacheKey - The cache key.\n * @param requestState - The new state for the request.\n */\n #updateRequestState(cacheKey: string, requestState: RequestState): void {\n const maxSize = this.#requestCacheMaxSize;\n const ttl = this.#requestCacheTTL;\n\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n requests[cacheKey] = requestState;\n\n // Evict expired entries based on TTL\n // Only evict SUCCESS states that have exceeded their TTL\n const keys = Object.keys(requests);\n for (const key of keys) {\n const entry = requests[key];\n if (\n entry &&\n entry.status === RequestStatus.SUCCESS &&\n isCacheExpired(entry, ttl)\n ) {\n delete requests[key];\n }\n }\n\n // Evict oldest entries if cache still exceeds max size\n const remainingKeys = Object.keys(requests);\n if (remainingKeys.length > maxSize) {\n // Sort by timestamp (oldest first)\n const sortedKeys = remainingKeys.sort((a, b) => {\n const aTime = requests[a]?.timestamp ?? 0;\n const bTime = requests[b]?.timestamp ?? 0;\n return aTime - bTime;\n });\n\n // Remove oldest entries until we're under the limit\n const entriesToRemove = remainingKeys.length - maxSize;\n for (let i = 0; i < entriesToRemove; i++) {\n const keyToRemove = sortedKeys[i];\n if (keyToRemove) {\n delete requests[keyToRemove];\n }\n }\n }\n });\n }\n\n /**\n * Sets the user's region manually (without fetching geolocation).\n * This allows users to override the detected region.\n *\n * @param region - The region code to set (e.g., \"US-CA\").\n * @param options - Options for cache behavior.\n * @returns The user region object.\n */\n async setUserRegion(\n region: string,\n options?: ExecuteRequestOptions,\n ): Promise<UserRegion> {\n const normalizedRegion = region.toLowerCase().trim();\n\n try {\n const countriesData = this.state.countries.data;\n if (!countriesData || countriesData.length === 0) {\n this.#cleanupState();\n throw new Error(\n 'No countries found. Cannot set user region without valid country information.',\n );\n }\n\n const userRegion = findRegionFromCode(normalizedRegion, countriesData);\n\n if (!userRegion) {\n this.#cleanupState();\n throw new Error(\n `Region \"${normalizedRegion}\" not found in countries data. Cannot set user region without valid country information.`,\n );\n }\n\n const regionChanged =\n normalizedRegion !== this.state.userRegion?.regionCode;\n\n const needsRefetch =\n regionChanged ||\n !this.state.tokens.data ||\n this.state.providers.data.length === 0;\n\n if (regionChanged) {\n this.#clearPendingResourceCountForDependentResources();\n }\n if (regionChanged) {\n this.stopQuotePolling();\n }\n this.update((state) => {\n if (regionChanged) {\n resetDependentResources(state as unknown as RampsControllerState);\n }\n state.userRegion = userRegion;\n });\n\n if (needsRefetch) {\n const refetchPromises: Promise<unknown>[] = [];\n if (regionChanged || !this.state.tokens.data) {\n refetchPromises.push(\n this.getTokens(userRegion.regionCode, 'buy', options),\n );\n }\n if (regionChanged || this.state.providers.data.length === 0) {\n refetchPromises.push(\n this.getProviders(userRegion.regionCode, options),\n );\n }\n if (refetchPromises.length > 0) {\n this.#fireAndForget(Promise.all(refetchPromises));\n }\n }\n\n return userRegion;\n } catch (error) {\n this.#cleanupState();\n throw error;\n }\n }\n\n /**\n * Sets the user's selected provider by ID, or clears the selection.\n * Looks up the provider from the current providers in state and automatically\n * fetches payment methods for that provider.\n *\n * @param providerId - The provider ID (e.g., \"/providers/moonpay\"), or null to clear.\n * @throws If region is not set, providers are not loaded, or provider is not found.\n */\n setSelectedProvider(providerId: string | null): void {\n if (providerId === null) {\n this.stopQuotePolling();\n this.update((state) => {\n state.providers.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected provider without valid region information.',\n );\n }\n\n const providers = this.state.providers.data;\n if (!providers || providers.length === 0) {\n throw new Error(\n 'Providers not loaded. Cannot set selected provider before providers are fetched.',\n );\n }\n\n const provider = providers.find((prov) => prov.id === providerId);\n if (!provider) {\n throw new Error(\n `Provider with ID \"${providerId}\" not found in available providers.`,\n );\n }\n\n this.update((state) => {\n state.providers.selected = provider;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { provider: provider.id }).then(() => {\n // Restart quote polling after payment methods are fetched\n this.#restartPollingIfActive();\n return undefined;\n }),\n );\n }\n\n /**\n * Initializes the controller by fetching the user's region from geolocation.\n * This should be called once at app startup to set up the initial region.\n *\n * If a userRegion already exists (from persistence or manual selection),\n * this method will skip geolocation fetch and use the existing region.\n *\n * @param options - Options for cache behavior.\n * @returns Promise that resolves when initialization is complete.\n */\n async init(options?: ExecuteRequestOptions): Promise<void> {\n await this.getCountries(options);\n\n let regionCode = this.state.userRegion?.regionCode;\n regionCode ??= await this.messenger.call('RampsService:getGeolocation');\n\n if (!regionCode) {\n throw new Error(\n 'Failed to fetch geolocation. Cannot initialize controller without valid region information.',\n );\n }\n\n await this.setUserRegion(regionCode, options);\n }\n\n hydrateState(options?: ExecuteRequestOptions): void {\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region code is required. Cannot hydrate state without valid region information.',\n );\n }\n\n this.#fireAndForget(this.getTokens(regionCode, 'buy', options));\n this.#fireAndForget(this.getProviders(regionCode, options));\n }\n\n /**\n * Fetches the list of supported countries.\n * The API returns countries with support information for both buy and sell actions.\n * The countries are saved in the controller state once fetched.\n *\n * @param options - Options for cache behavior.\n * @returns An array of countries.\n */\n async getCountries(options?: ExecuteRequestOptions): Promise<Country[]> {\n const cacheKey = createCacheKey('getCountries', []);\n\n const countries = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getCountries');\n },\n { ...options, resourceType: 'countries' },\n );\n\n this.update((state) => {\n state.countries.data = countries;\n });\n\n return countries;\n }\n\n /**\n * Fetches the list of available tokens for a given region and action.\n * The tokens are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param action - The ramp action type ('buy' or 'sell').\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @returns The tokens response containing topTokens and allTokens.\n */\n async getTokens(\n region?: string,\n action: RampAction = 'buy',\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n },\n ): Promise<TokensResponse> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getTokens', [\n normalizedRegion,\n action,\n options?.provider,\n ]);\n\n const tokens = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getTokens',\n normalizedRegion,\n action,\n {\n provider: options?.provider,\n },\n );\n },\n {\n ...options,\n resourceType: 'tokens',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.tokens.data = tokens;\n }\n });\n\n return tokens;\n }\n\n /**\n * Sets the user's selected token by asset ID.\n * Looks up the token from the current tokens in state and automatically\n * fetches payment methods for that token.\n *\n * @param assetId - The asset identifier in CAIP-19 format (e.g., \"eip155:1/erc20:0x...\"), or undefined to clear.\n * @throws If region is not set, tokens are not loaded, or token is not found.\n */\n setSelectedToken(assetId?: string): void {\n if (!assetId) {\n this.stopQuotePolling();\n this.update((state) => {\n state.tokens.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected token without valid region information.',\n );\n }\n\n const tokens = this.state.tokens.data;\n if (!tokens) {\n throw new Error(\n 'Tokens not loaded. Cannot set selected token before tokens are fetched.',\n );\n }\n\n const token =\n tokens.allTokens.find((tok) => tok.assetId === assetId) ??\n tokens.topTokens.find((tok) => tok.assetId === assetId);\n\n if (!token) {\n throw new Error(\n `Token with asset ID \"${assetId}\" not found in available tokens.`,\n );\n }\n\n this.update((state) => {\n state.tokens.selected = token;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { assetId: token.assetId }).then(\n () => {\n // Restart quote polling after payment methods are fetched\n this.#restartPollingIfActive();\n return undefined;\n },\n ),\n );\n }\n\n /**\n * Fetches the list of providers for a given region.\n * The providers are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @param options.crypto - Crypto currency ID(s) to filter by.\n * @param options.fiat - Fiat currency ID(s) to filter by.\n * @param options.payments - Payment method ID(s) to filter by.\n * @returns The providers response containing providers array.\n */\n async getProviders(\n region?: string,\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n crypto?: string | string[];\n fiat?: string | string[];\n payments?: string | string[];\n },\n ): Promise<{ providers: Provider[] }> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getProviders', [\n normalizedRegion,\n options?.provider,\n options?.crypto,\n options?.fiat,\n options?.payments,\n ]);\n\n const { providers } = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getProviders',\n normalizedRegion,\n {\n provider: options?.provider,\n crypto: options?.crypto,\n fiat: options?.fiat,\n payments: options?.payments,\n },\n );\n },\n {\n ...options,\n resourceType: 'providers',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.providers.data = providers;\n }\n });\n\n return { providers };\n }\n\n /**\n * Fetches the list of payment methods for a given context.\n * The payment methods are saved in the controller state once fetched.\n *\n * @param region - User's region code (e.g. \"fr\", \"us-ny\").\n * @param options - Query parameters for filtering payment methods.\n * @param options.fiat - Fiat currency code (e.g., \"usd\"). If not provided, uses the user's region currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.provider - Provider ID path.\n * @returns The payment methods response containing payments array.\n */\n async getPaymentMethods(\n region?: string,\n options?: ExecuteRequestOptions & {\n fiat?: string;\n assetId?: string;\n provider?: string;\n },\n ): Promise<PaymentMethodsResponse> {\n const regionCode = region ?? this.state.userRegion?.regionCode ?? null;\n const fiatToUse =\n options?.fiat ?? this.state.userRegion?.country?.currency ?? null;\n const assetIdToUse =\n options?.assetId ?? this.state.tokens.selected?.assetId ?? '';\n const providerToUse =\n options?.provider ?? this.state.providers.selected?.id ?? '';\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionCode.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getPaymentMethods', [\n normalizedRegion,\n normalizedFiat,\n assetIdToUse,\n providerToUse,\n ]);\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getPaymentMethods', {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: assetIdToUse,\n provider: providerToUse,\n });\n },\n {\n ...options,\n resourceType: 'paymentMethods',\n isResultCurrent: () => {\n const regionMatch =\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion;\n const tokenMatch =\n (this.state.tokens.selected?.assetId ?? '') === assetIdToUse;\n const providerMatch =\n (this.state.providers.selected?.id ?? '') === providerToUse;\n return regionMatch && tokenMatch && providerMatch;\n },\n },\n );\n\n this.update((state) => {\n const currentAssetId = state.tokens.selected?.assetId ?? '';\n const currentProviderId = state.providers.selected?.id ?? '';\n\n const tokenSelectionUnchanged = assetIdToUse === currentAssetId;\n const providerSelectionUnchanged = providerToUse === currentProviderId;\n\n // this is a race condition check to ensure that the selected token and provider in state are the same as the tokens we're requesting for\n // ex: if the user rapidly changes the token or provider, the in-flight payment methods might not be valid\n // so this check will ensure that the payment methods are still valid for the token and provider that were requested\n if (tokenSelectionUnchanged && providerSelectionUnchanged) {\n state.paymentMethods.data = response.payments;\n\n // this will auto-select the first payment method if the selected payment method is not in the new payment methods\n const currentSelectionStillValid = response.payments.some(\n (pm: PaymentMethod) => pm.id === state.paymentMethods.selected?.id,\n );\n if (!currentSelectionStillValid) {\n state.paymentMethods.selected = response.payments[0] ?? null;\n }\n }\n });\n\n return response;\n }\n\n /**\n * Sets the user's selected payment method by ID.\n * Looks up the payment method from the current payment methods in state.\n *\n * @param paymentMethodId - The payment method ID (e.g., \"/payments/debit-credit-card\"), or null to clear.\n * @throws If payment methods are not loaded or payment method is not found.\n */\n setSelectedPaymentMethod(paymentMethodId?: string): void {\n if (!paymentMethodId) {\n this.update((state) => {\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const paymentMethods = this.state.paymentMethods.data;\n if (!paymentMethods || paymentMethods.length === 0) {\n throw new Error(\n 'Payment methods not loaded. Cannot set selected payment method before payment methods are fetched.',\n );\n }\n\n const paymentMethod = paymentMethods.find(\n (pm) => pm.id === paymentMethodId,\n );\n if (!paymentMethod) {\n throw new Error(\n `Payment method with ID \"${paymentMethodId}\" not found in available payment methods.`,\n );\n }\n\n this.update((state) => {\n state.paymentMethods.selected = paymentMethod;\n });\n\n // Restart quote polling if active\n this.#restartPollingIfActive();\n }\n\n /**\n * Fetches quotes from all providers for a given set of parameters.\n * The quotes are saved in the controller state once fetched.\n *\n * @param options - The parameters for fetching quotes.\n * @param options.region - User's region code. If not provided, uses userRegion from state.\n * @param options.fiat - Fiat currency code. If not provided, uses userRegion currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.walletAddress - The destination wallet address.\n * @param options.paymentMethods - Array of payment method IDs. If not provided, uses paymentMethods from state.\n * @param options.provider - Optional provider ID to filter quotes.\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @param options.action - The ramp action type. Defaults to 'buy'.\n * @param options.forceRefresh - Whether to bypass cache.\n * @param options.ttl - Custom TTL for this request.\n * @returns The quotes response containing success, sorted, error, and customActions.\n */\n async getQuotes(options: {\n region?: string;\n fiat?: string;\n assetId: string;\n amount: number;\n walletAddress: string;\n paymentMethods?: string[];\n provider?: string;\n redirectUrl?: string;\n action?: RampAction;\n forceRefresh?: boolean;\n ttl?: number;\n }): Promise<QuotesResponse> {\n const regionToUse = options.region ?? this.state.userRegion?.regionCode;\n const fiatToUse = options.fiat ?? this.state.userRegion?.country?.currency;\n const paymentMethodsToUse =\n options.paymentMethods ??\n this.state.paymentMethods.data.map((pm: PaymentMethod) => pm.id);\n const action = options.action ?? 'buy';\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!paymentMethodsToUse || paymentMethodsToUse.length === 0) {\n throw new Error(\n 'Payment methods are required. Either provide paymentMethods parameter or ensure paymentMethods are set in controller state.',\n );\n }\n\n if (options.amount <= 0 || !Number.isFinite(options.amount)) {\n throw new Error('Amount must be a positive finite number.');\n }\n\n if (!options.assetId || options.assetId.trim() === '') {\n throw new Error('assetId is required.');\n }\n\n if (!options.walletAddress || options.walletAddress.trim() === '') {\n throw new Error('walletAddress is required.');\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const normalizedAssetId = options.assetId.trim();\n const normalizedWalletAddress = options.walletAddress.trim();\n\n const cacheKey = createCacheKey('getQuotes', [\n normalizedRegion,\n normalizedFiat,\n normalizedAssetId,\n options.amount,\n normalizedWalletAddress,\n [...paymentMethodsToUse].sort().join(','),\n options.provider,\n options.redirectUrl,\n action,\n ]);\n\n const params: GetQuotesParams = {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: normalizedAssetId,\n amount: options.amount,\n walletAddress: normalizedWalletAddress,\n paymentMethods: paymentMethodsToUse,\n provider: options.provider,\n redirectUrl: options.redirectUrl,\n action,\n };\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getQuotes', params);\n },\n {\n forceRefresh: options.forceRefresh,\n ttl: options.ttl ?? DEFAULT_QUOTES_TTL,\n resourceType: 'quotes',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.quotes.data = response;\n }\n });\n\n return response;\n }\n\n /**\n * Starts automatic quote polling with a 15-second refresh interval.\n * Fetches quotes immediately and then every 15 seconds.\n * If the response contains exactly one quote, it is auto-selected.\n * If multiple quotes are returned, the existing selection is preserved if still valid.\n *\n * @param options - Parameters for fetching quotes.\n * @param options.walletAddress - The destination wallet address.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @throws If required dependencies (region, token, provider, payment method) are not set.\n */\n startQuotePolling(options: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n }): void {\n // Validate required dependencies\n const regionCode = this.state.userRegion?.regionCode;\n const token = this.state.tokens.selected;\n const provider = this.state.providers.selected;\n const paymentMethod = this.state.paymentMethods.selected;\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot start quote polling without valid region information.',\n );\n }\n\n if (!token) {\n throw new Error(\n 'Token is required. Cannot start quote polling without a selected token.',\n );\n }\n\n if (!provider) {\n throw new Error(\n 'Provider is required. Cannot start quote polling without a selected provider.',\n );\n }\n\n if (!paymentMethod) {\n throw new Error(\n 'Payment method is required. Cannot start quote polling without a selected payment method.',\n );\n }\n\n // Stop any existing polling first\n this.stopQuotePolling();\n\n // Store options for restarts (must be after stop to avoid being cleared)\n this.#quotePollingOptions = options;\n\n // Define the fetch function\n const fetchQuotes = (): void => {\n this.#fireAndForget(\n this.getQuotes({\n assetId: token.assetId,\n amount: options.amount,\n walletAddress: options.walletAddress,\n redirectUrl: options.redirectUrl,\n paymentMethods: [paymentMethod.id],\n provider: provider.id,\n forceRefresh: true,\n }).then((response) => {\n // Auto-select logic: only when exactly one quote is returned\n this.update((state) => {\n if (response.success.length === 1) {\n state.quotes.selected = response.success[0];\n } else {\n // Keep existing selection if still valid, but update with fresh data\n const currentSelection = state.quotes.selected;\n if (currentSelection) {\n const freshQuote = response.success.find(\n (quote) =>\n quote.provider === currentSelection.provider &&\n quote.quote.paymentMethod ===\n currentSelection.quote.paymentMethod,\n );\n // Update with fresh quote data, or clear if no longer valid\n state.quotes.selected = freshQuote ?? null;\n }\n }\n });\n return undefined;\n }),\n );\n };\n\n // Fetch immediately\n fetchQuotes();\n\n // Set up 15-second polling\n this.#quotePollingInterval = setInterval(fetchQuotes, 15000);\n }\n\n /**\n * Stops automatic quote polling.\n * Does not clear quotes data or selection, only stops the interval.\n */\n stopQuotePolling(): void {\n if (this.#quotePollingInterval !== null) {\n clearInterval(this.#quotePollingInterval);\n this.#quotePollingInterval = null;\n }\n this.#quotePollingOptions = null;\n }\n\n /**\n * Manually sets the selected quote.\n *\n * @param quote - The quote to select, or null to clear the selection.\n */\n setSelectedQuote(quote: Quote | null): void {\n this.update((state) => {\n state.quotes.selected = quote;\n });\n }\n\n /**\n * Cleans up controller resources.\n * Stops any active quote polling to prevent memory leaks.\n * Should be called when the controller is no longer needed.\n */\n override destroy(): void {\n this.stopQuotePolling();\n super.destroy();\n }\n\n /**\n * Extracts the widget URL from a quote for redirect providers.\n * Returns the widget URL if available, or null if the quote doesn't have one.\n *\n * @param quote - The quote to extract the widget URL from.\n * @returns The widget URL string, or null if not available.\n */\n getWidgetUrl(quote: Quote): string | null {\n return quote.quote?.widgetUrl ?? null;\n }\n}\n"]}
1
+ {"version":3,"file":"RampsController.mjs","sourceRoot":"","sources":["../src/RampsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n Country,\n TokensResponse,\n Provider,\n State,\n RampAction,\n PaymentMethod,\n PaymentMethodsResponse,\n QuotesResponse,\n Quote,\n GetQuotesParams,\n RampsToken,\n RampsServiceActions,\n} from './RampsService';\nimport type {\n RampsServiceGetGeolocationAction,\n RampsServiceGetCountriesAction,\n RampsServiceGetTokensAction,\n RampsServiceGetProvidersAction,\n RampsServiceGetPaymentMethodsAction,\n RampsServiceGetQuotesAction,\n} from './RampsService-method-action-types';\nimport type {\n RequestCache as RequestCacheType,\n RequestState,\n ExecuteRequestOptions,\n PendingRequest,\n ResourceType,\n} from './RequestCache';\nimport {\n DEFAULT_REQUEST_CACHE_TTL,\n DEFAULT_REQUEST_CACHE_MAX_SIZE,\n createCacheKey,\n isCacheExpired,\n createLoadingState,\n createSuccessState,\n createErrorState,\n RequestStatus,\n} from './RequestCache';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link RampsController}, used to namespace the\n * controller's actions and events and to namespace the controller's state data\n * when composed with other controllers.\n */\nexport const controllerName = 'RampsController';\n\n/**\n * RampsService action types that RampsController calls via the messenger.\n * Any host (e.g. mobile) that creates a RampsController messenger must delegate\n * these actions from the root messenger so the controller can function.\n */\nexport const RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS: readonly RampsServiceActions['type'][] =\n [\n 'RampsService:getGeolocation',\n 'RampsService:getCountries',\n 'RampsService:getTokens',\n 'RampsService:getProviders',\n 'RampsService:getPaymentMethods',\n 'RampsService:getQuotes',\n ];\n\n/**\n * Default TTL for quotes requests (15 seconds).\n * Quotes are time-sensitive and should have a shorter cache duration.\n */\nconst DEFAULT_QUOTES_TTL = 15000;\n\n// === STATE ===\n\n/**\n * Represents the user's selected region with full country and state objects.\n */\nexport type UserRegion = {\n /**\n * The country object for the selected region.\n */\n country: Country;\n /**\n * The state object if a state was selected, null if only country was selected.\n */\n state: State | null;\n /**\n * The region code string (e.g., \"us-ut\" or \"fr\") used for API calls.\n */\n regionCode: string;\n};\n\n/**\n * Generic type for resource state that bundles data with loading/error states.\n *\n * @template TData - The type of the resource data\n * @template TSelected - The type of the selected item (defaults to null for resources without selection)\n */\nexport type ResourceState<TData, TSelected = null> = {\n /**\n * The resource data.\n */\n data: TData;\n /**\n * The currently selected item, or null if none selected.\n */\n selected: TSelected;\n /**\n * Whether the resource is currently being fetched.\n */\n isLoading: boolean;\n /**\n * Error message if the fetch failed, or null.\n */\n error: string | null;\n};\n\n/**\n * Describes the shape of the state object for {@link RampsController}.\n */\nexport type RampsControllerState = {\n /**\n * The user's region (full country and state objects).\n * Initially set via geolocation fetch, but can be manually changed by the user.\n */\n userRegion: UserRegion | null;\n /**\n * Countries resource state with data, loading, and error.\n * Data contains the list of countries available for ramp actions.\n */\n countries: ResourceState<Country[]>;\n /**\n * Providers resource state with data, selected, loading, and error.\n * Data contains the list of providers available for the current region.\n */\n providers: ResourceState<Provider[], Provider | null>;\n /**\n * Tokens resource state with data, selected, loading, and error.\n * Data contains topTokens and allTokens arrays.\n */\n tokens: ResourceState<TokensResponse | null, RampsToken | null>;\n /**\n * Payment methods resource state with data, selected, loading, and error.\n * Data contains payment methods filtered by region, fiat, asset, and provider.\n */\n paymentMethods: ResourceState<PaymentMethod[], PaymentMethod | null>;\n /**\n * Quotes resource state with data, selected, loading, and error.\n * Data contains quotes from multiple providers for the given parameters.\n * Selected contains the currently selected quote for the user.\n */\n quotes: ResourceState<QuotesResponse | null, Quote | null>;\n /**\n * Cache of request states, keyed by cache key.\n * This stores loading, success, and error states for API requests.\n */\n requests: RequestCacheType;\n};\n\n/**\n * The metadata for each property in {@link RampsControllerState}.\n */\nconst rampsControllerMetadata = {\n userRegion: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n countries: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n providers: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n tokens: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n paymentMethods: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n quotes: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n requests: {\n persist: false,\n includeInDebugSnapshot: true,\n includeInStateLogs: false,\n usedInUi: true,\n },\n} satisfies StateMetadata<RampsControllerState>;\n\n/**\n * Creates a default resource state object.\n *\n * @template TData - The type of the resource data.\n * @template TSelected - The type of the selected item.\n * @param data - The initial data value.\n * @param selected - The initial selected value.\n * @returns A ResourceState object with default loading and error values.\n */\nfunction createDefaultResourceState<TData, TSelected = null>(\n data: TData,\n selected: TSelected = null as TSelected,\n): ResourceState<TData, TSelected> {\n return {\n data,\n selected,\n isLoading: false,\n error: null,\n };\n}\n\n/**\n * Constructs the default {@link RampsController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link RampsController} state.\n */\nexport function getDefaultRampsControllerState(): RampsControllerState {\n return {\n userRegion: null,\n countries: createDefaultResourceState<Country[]>([]),\n providers: createDefaultResourceState<Provider[], Provider | null>(\n [],\n null,\n ),\n tokens: createDefaultResourceState<\n TokensResponse | null,\n RampsToken | null\n >(null, null),\n paymentMethods: createDefaultResourceState<\n PaymentMethod[],\n PaymentMethod | null\n >([], null),\n quotes: createDefaultResourceState<QuotesResponse | null, Quote | null>(\n null,\n null,\n ),\n requests: {},\n };\n}\n\n/**\n * Resets region-dependent resources (userRegion, providers, tokens, paymentMethods, quotes).\n * Mutates state in place; use from within controller update() for atomic updates.\n *\n * @param state - The state object to mutate.\n * @param options - Options for the reset.\n * @param options.clearUserRegionData - When true, sets userRegion to null (e.g. for full cleanup).\n */\nfunction resetDependentResources(\n state: RampsControllerState,\n options?: { clearUserRegionData?: boolean },\n): void {\n if (options?.clearUserRegionData) {\n state.userRegion = null;\n }\n state.providers.selected = null;\n state.providers.data = [];\n state.providers.isLoading = false;\n state.providers.error = null;\n state.tokens.selected = null;\n state.tokens.data = null;\n state.tokens.isLoading = false;\n state.tokens.error = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.paymentMethods.isLoading = false;\n state.paymentMethods.error = null;\n state.quotes.data = null;\n state.quotes.selected = null;\n state.quotes.isLoading = false;\n state.quotes.error = null;\n}\n\n// === MESSENGER ===\n\n/**\n * Retrieves the state of the {@link RampsController}.\n */\nexport type RampsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Actions that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerActions = RampsControllerGetStateAction;\n\n/**\n * Actions from other messengers that {@link RampsController} calls.\n */\ntype AllowedActions =\n | RampsServiceGetGeolocationAction\n | RampsServiceGetCountriesAction\n | RampsServiceGetTokensAction\n | RampsServiceGetProvidersAction\n | RampsServiceGetPaymentMethodsAction\n | RampsServiceGetQuotesAction;\n\n/**\n * Published when the state of {@link RampsController} changes.\n */\nexport type RampsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n RampsControllerState\n>;\n\n/**\n * Events that {@link RampsControllerMessenger} exposes to other consumers.\n */\nexport type RampsControllerEvents = RampsControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link RampsController} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link RampsController}.\n */\nexport type RampsControllerMessenger = Messenger<\n typeof controllerName,\n RampsControllerActions | AllowedActions,\n RampsControllerEvents | AllowedEvents\n>;\n\n/**\n * Configuration options for the RampsController.\n */\nexport type RampsControllerOptions = {\n /** The messenger suited for this controller. */\n messenger: RampsControllerMessenger;\n /** The desired state with which to initialize this controller. */\n state?: Partial<RampsControllerState>;\n /** Time to live for cached requests in milliseconds. Defaults to 15 minutes. */\n requestCacheTTL?: number;\n /** Maximum number of entries in the request cache. Defaults to 250. */\n requestCacheMaxSize?: number;\n};\n\n// === HELPER FUNCTIONS ===\n\n/**\n * Finds a country and state from a region code string.\n *\n * @param regionCode - The region code (e.g., \"us-ca\" or \"us\").\n * @param countries - Array of countries to search.\n * @returns UserRegion object with country and state, or null if not found.\n */\nfunction findRegionFromCode(\n regionCode: string,\n countries: Country[],\n): UserRegion | null {\n const normalizedCode = regionCode.toLowerCase().trim();\n const parts = normalizedCode.split('-');\n const countryCode = parts[0];\n const stateCode = parts[1];\n\n const country = countries.find((countryItem) => {\n if (countryItem.isoCode?.toLowerCase() === countryCode) {\n return true;\n }\n if (countryItem.id) {\n const id = countryItem.id.toLowerCase();\n if (id.startsWith('/regions/')) {\n const extractedCode = id.replace('/regions/', '').split('/')[0];\n return extractedCode === countryCode;\n }\n return id === countryCode || id.endsWith(`/${countryCode}`);\n }\n return false;\n });\n\n if (!country) {\n return null;\n }\n\n let state: State | null = null;\n if (stateCode && country.states) {\n state =\n country.states.find((stateItem) => {\n if (stateItem.stateId?.toLowerCase() === stateCode) {\n return true;\n }\n if (stateItem.id) {\n const stateId = stateItem.id.toLowerCase();\n if (\n stateId.includes(`-${stateCode}`) ||\n stateId.endsWith(`/${stateCode}`)\n ) {\n return true;\n }\n }\n return false;\n }) ?? null;\n }\n\n return {\n country,\n state,\n regionCode: normalizedCode,\n };\n}\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * Manages cryptocurrency on/off ramps functionality.\n */\nexport class RampsController extends BaseController<\n typeof controllerName,\n RampsControllerState,\n RampsControllerMessenger\n> {\n /**\n * Default TTL for cached requests.\n */\n readonly #requestCacheTTL: number;\n\n /**\n * Maximum number of entries in the request cache.\n */\n readonly #requestCacheMaxSize: number;\n\n /**\n * Map of pending requests for deduplication.\n * Key is the cache key, value is the pending request with abort controller.\n */\n readonly #pendingRequests: Map<string, PendingRequest> = new Map();\n\n /**\n * Count of in-flight requests per resource type.\n * Used so isLoading is only cleared when the last request for that resource finishes.\n */\n readonly #pendingResourceCount: Map<ResourceType, number> = new Map();\n\n /**\n * Interval ID for automatic quote polling.\n * Set when startQuotePolling() is called, cleared when stopQuotePolling() is called.\n */\n #quotePollingInterval: ReturnType<typeof setInterval> | null = null;\n\n /**\n * Options used for quote polling (walletAddress, amount, redirectUrl).\n * Stored so polling can be restarted when dependencies change.\n */\n #quotePollingOptions: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n } | null = null;\n\n /**\n * Clears the pending resource count map. Used only in tests to exercise the\n * defensive path when get() returns undefined in the finally block.\n *\n * @internal\n */\n clearPendingResourceCountForTest(): void {\n this.#pendingResourceCount.clear();\n }\n\n #clearPendingResourceCountForDependentResources(): void {\n const types: ResourceType[] = [\n 'providers',\n 'tokens',\n 'paymentMethods',\n 'quotes',\n ];\n for (const resourceType of types) {\n this.#pendingResourceCount.delete(resourceType);\n }\n }\n\n /**\n * Constructs a new {@link RampsController}.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this controller.\n * @param args.state - The desired state with which to initialize this\n * controller. Missing properties will be filled in with defaults.\n * @param args.requestCacheTTL - Time to live for cached requests in milliseconds.\n * @param args.requestCacheMaxSize - Maximum number of entries in the request cache.\n */\n constructor({\n messenger,\n state = {},\n requestCacheTTL = DEFAULT_REQUEST_CACHE_TTL,\n requestCacheMaxSize = DEFAULT_REQUEST_CACHE_MAX_SIZE,\n }: RampsControllerOptions) {\n super({\n messenger,\n metadata: rampsControllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultRampsControllerState(),\n ...state,\n // Always reset requests cache on initialization (non-persisted)\n requests: {},\n },\n });\n\n this.#requestCacheTTL = requestCacheTTL;\n this.#requestCacheMaxSize = requestCacheMaxSize;\n }\n\n /**\n * Executes a request with caching and deduplication.\n *\n * If a request with the same cache key is already in flight, returns the\n * existing promise. If valid cached data exists, returns it without making\n * a new request.\n *\n * @param cacheKey - Unique identifier for this request.\n * @param fetcher - Function that performs the actual fetch. Receives an AbortSignal.\n * @param options - Options for cache behavior.\n * @returns The result of the request.\n */\n async executeRequest<TResult>(\n cacheKey: string,\n fetcher: (signal: AbortSignal) => Promise<TResult>,\n options?: ExecuteRequestOptions,\n ): Promise<TResult> {\n const ttl = options?.ttl ?? this.#requestCacheTTL;\n\n // Check for existing pending request - join it instead of making a duplicate\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n return pending.promise as Promise<TResult>;\n }\n\n if (!options?.forceRefresh) {\n const cached = this.state.requests[cacheKey];\n if (cached && !isCacheExpired(cached, ttl)) {\n return cached.data as TResult;\n }\n }\n\n // Create abort controller for this request\n const abortController = new AbortController();\n const lastFetchedAt = Date.now();\n const { resourceType } = options ?? {};\n\n // Update state to loading\n this.#updateRequestState(cacheKey, createLoadingState());\n\n // Set resource-level loading state (only on cache miss). Ref-count so concurrent\n // requests for the same resource type (different cache keys) keep isLoading true.\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n this.#pendingResourceCount.set(resourceType, count + 1);\n if (count === 0) {\n this.#setResourceLoading(resourceType, true);\n }\n }\n\n // Create the fetch promise\n const promise = (async (): Promise<TResult> => {\n try {\n const data = await fetcher(abortController.signal);\n\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw new Error('Request was aborted');\n }\n\n this.#updateRequestState(\n cacheKey,\n createSuccessState(data as Json, lastFetchedAt),\n );\n\n if (resourceType) {\n // We need the extra logic because there are two situations where we’re allowed to clear the error:\n // No callback → always clear\n // Callback present → clear only when isResultCurrent() returns true.\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, null);\n }\n }\n\n return data;\n } catch (error) {\n // Don't update state if aborted\n if (abortController.signal.aborted) {\n throw error;\n }\n\n const errorMessage = (error as Error)?.message ?? 'Unknown error';\n\n this.#updateRequestState(\n cacheKey,\n createErrorState(errorMessage, lastFetchedAt),\n );\n\n if (resourceType) {\n const isCurrent =\n !options?.isResultCurrent || options.isResultCurrent();\n if (isCurrent) {\n this.#setResourceError(resourceType, errorMessage);\n }\n }\n\n throw error;\n } finally {\n // Only delete if this is still our entry (not replaced by a new request)\n const currentPending = this.#pendingRequests.get(cacheKey);\n if (currentPending?.abortController === abortController) {\n this.#pendingRequests.delete(cacheKey);\n }\n\n // Clear resource-level loading state only when no requests for this resource remain\n if (resourceType) {\n const count = this.#pendingResourceCount.get(resourceType) ?? 0;\n const next = Math.max(0, count - 1);\n if (next === 0) {\n this.#pendingResourceCount.delete(resourceType);\n this.#setResourceLoading(resourceType, false);\n } else {\n this.#pendingResourceCount.set(resourceType, next);\n }\n }\n }\n })();\n\n // Store pending request for deduplication\n this.#pendingRequests.set(cacheKey, { promise, abortController });\n\n return promise;\n }\n\n /**\n * Aborts a pending request if one exists.\n *\n * @param cacheKey - The cache key of the request to abort.\n * @returns True if a request was aborted.\n */\n abortRequest(cacheKey: string): boolean {\n const pending = this.#pendingRequests.get(cacheKey);\n if (pending) {\n pending.abortController.abort();\n this.#pendingRequests.delete(cacheKey);\n this.#removeRequestState(cacheKey);\n return true;\n }\n return false;\n }\n\n /**\n * Removes a request state from the cache.\n *\n * @param cacheKey - The cache key to remove.\n */\n #removeRequestState(cacheKey: string): void {\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n delete requests[cacheKey];\n });\n }\n\n #cleanupState(): void {\n this.stopQuotePolling();\n this.#clearPendingResourceCountForDependentResources();\n this.update((state) =>\n resetDependentResources(state as unknown as RampsControllerState, {\n clearUserRegionData: true,\n }),\n );\n }\n\n /**\n * Executes a promise without awaiting, swallowing errors.\n * Errors are stored in state via executeRequest.\n *\n * @param promise - The promise to execute.\n */\n #fireAndForget<Result>(promise: Promise<Result>): void {\n promise.catch((_error: unknown) => undefined);\n }\n\n /**\n * Restarts quote polling if it's currently active.\n * Used when dependencies change (token, provider, payment method).\n * Will only restart if all dependencies are still met (startQuotePolling validates this).\n */\n #restartPollingIfActive(): void {\n if (this.#quotePollingInterval !== null && this.#quotePollingOptions) {\n const options = this.#quotePollingOptions;\n this.stopQuotePolling();\n try {\n this.startQuotePolling(options);\n } catch {\n // Dependencies not met yet, polling will need to be manually restarted\n // when dependencies are available\n }\n }\n }\n\n /**\n * Updates a single field (isLoading or error) on a resource state.\n * All resources share the same ResourceState structure, so we use\n * dynamic property access to avoid duplicating switch statements.\n *\n * @param resourceType - The type of resource.\n * @param field - The field to update ('isLoading' or 'error').\n * @param value - The value to set.\n */\n #updateResourceField(\n resourceType: ResourceType,\n field: 'isLoading' | 'error',\n value: boolean | string | null,\n ): void {\n this.update((state) => {\n const resource = state[resourceType];\n if (resource) {\n (resource as Record<string, unknown>)[field] = value;\n }\n });\n }\n\n /**\n * Sets the loading state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param loading - Whether the resource is loading.\n */\n #setResourceLoading(resourceType: ResourceType, loading: boolean): void {\n this.#updateResourceField(resourceType, 'isLoading', loading);\n }\n\n /**\n * Sets the error state for a resource type.\n *\n * @param resourceType - The type of resource.\n * @param error - The error message, or null to clear.\n */\n #setResourceError(resourceType: ResourceType, error: string | null): void {\n this.#updateResourceField(resourceType, 'error', error);\n }\n\n /**\n * Gets the state of a specific cached request.\n *\n * @param cacheKey - The cache key to look up.\n * @returns The request state, or undefined if not cached.\n */\n getRequestState(cacheKey: string): RequestState | undefined {\n return this.state.requests[cacheKey];\n }\n\n /**\n * Updates the state for a specific request.\n *\n * @param cacheKey - The cache key.\n * @param requestState - The new state for the request.\n */\n #updateRequestState(cacheKey: string, requestState: RequestState): void {\n const maxSize = this.#requestCacheMaxSize;\n const ttl = this.#requestCacheTTL;\n\n this.update((state) => {\n const requests = state.requests as unknown as Record<\n string,\n RequestState | undefined\n >;\n requests[cacheKey] = requestState;\n\n // Evict expired entries based on TTL\n // Only evict SUCCESS states that have exceeded their TTL\n const keys = Object.keys(requests);\n for (const key of keys) {\n const entry = requests[key];\n if (\n entry &&\n entry.status === RequestStatus.SUCCESS &&\n isCacheExpired(entry, ttl)\n ) {\n delete requests[key];\n }\n }\n\n // Evict oldest entries if cache still exceeds max size\n const remainingKeys = Object.keys(requests);\n if (remainingKeys.length > maxSize) {\n // Sort by timestamp (oldest first)\n const sortedKeys = remainingKeys.sort((a, b) => {\n const aTime = requests[a]?.timestamp ?? 0;\n const bTime = requests[b]?.timestamp ?? 0;\n return aTime - bTime;\n });\n\n // Remove oldest entries until we're under the limit\n const entriesToRemove = remainingKeys.length - maxSize;\n for (let i = 0; i < entriesToRemove; i++) {\n const keyToRemove = sortedKeys[i];\n if (keyToRemove) {\n delete requests[keyToRemove];\n }\n }\n }\n });\n }\n\n /**\n * Sets the user's region manually (without fetching geolocation).\n * This allows users to override the detected region.\n *\n * @param region - The region code to set (e.g., \"US-CA\").\n * @param options - Options for cache behavior.\n * @returns The user region object.\n */\n async setUserRegion(\n region: string,\n options?: ExecuteRequestOptions,\n ): Promise<UserRegion> {\n const normalizedRegion = region.toLowerCase().trim();\n\n try {\n const countriesData = this.state.countries.data;\n if (!countriesData || countriesData.length === 0) {\n this.#cleanupState();\n throw new Error(\n 'No countries found. Cannot set user region without valid country information.',\n );\n }\n\n const userRegion = findRegionFromCode(normalizedRegion, countriesData);\n\n if (!userRegion) {\n this.#cleanupState();\n throw new Error(\n `Region \"${normalizedRegion}\" not found in countries data. Cannot set user region without valid country information.`,\n );\n }\n\n const regionChanged =\n normalizedRegion !== this.state.userRegion?.regionCode;\n\n const needsRefetch =\n regionChanged ||\n !this.state.tokens.data ||\n this.state.providers.data.length === 0;\n\n if (regionChanged) {\n this.#clearPendingResourceCountForDependentResources();\n }\n if (regionChanged) {\n this.stopQuotePolling();\n }\n this.update((state) => {\n if (regionChanged) {\n resetDependentResources(state as unknown as RampsControllerState);\n }\n state.userRegion = userRegion;\n });\n\n if (needsRefetch) {\n const refetchPromises: Promise<unknown>[] = [];\n if (regionChanged || !this.state.tokens.data) {\n refetchPromises.push(\n this.getTokens(userRegion.regionCode, 'buy', options),\n );\n }\n if (regionChanged || this.state.providers.data.length === 0) {\n refetchPromises.push(\n this.getProviders(userRegion.regionCode, options),\n );\n }\n if (refetchPromises.length > 0) {\n this.#fireAndForget(Promise.all(refetchPromises));\n }\n }\n\n return userRegion;\n } catch (error) {\n this.#cleanupState();\n throw error;\n }\n }\n\n /**\n * Sets the user's selected provider by ID, or clears the selection.\n * Looks up the provider from the current providers in state and automatically\n * fetches payment methods for that provider.\n *\n * @param providerId - The provider ID (e.g., \"/providers/moonpay\"), or null to clear.\n * @throws If region is not set, providers are not loaded, or provider is not found.\n */\n setSelectedProvider(providerId: string | null): void {\n if (providerId === null) {\n this.stopQuotePolling();\n this.update((state) => {\n state.providers.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected provider without valid region information.',\n );\n }\n\n const providers = this.state.providers.data;\n if (!providers || providers.length === 0) {\n throw new Error(\n 'Providers not loaded. Cannot set selected provider before providers are fetched.',\n );\n }\n\n const provider = providers.find((prov) => prov.id === providerId);\n if (!provider) {\n throw new Error(\n `Provider with ID \"${providerId}\" not found in available providers.`,\n );\n }\n\n this.update((state) => {\n state.providers.selected = provider;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { provider: provider.id }).then(() => {\n // Restart quote polling after payment methods are fetched\n this.#restartPollingIfActive();\n return undefined;\n }),\n );\n }\n\n /**\n * Initializes the controller by fetching the user's region from geolocation.\n * This should be called once at app startup to set up the initial region.\n *\n * If a userRegion already exists (from persistence or manual selection),\n * this method will skip geolocation fetch and use the existing region.\n *\n * @param options - Options for cache behavior.\n * @returns Promise that resolves when initialization is complete.\n */\n async init(options?: ExecuteRequestOptions): Promise<void> {\n await this.getCountries(options);\n\n let regionCode = this.state.userRegion?.regionCode;\n regionCode ??= await this.messenger.call('RampsService:getGeolocation');\n\n if (!regionCode) {\n throw new Error(\n 'Failed to fetch geolocation. Cannot initialize controller without valid region information.',\n );\n }\n\n await this.setUserRegion(regionCode, options);\n }\n\n hydrateState(options?: ExecuteRequestOptions): void {\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region code is required. Cannot hydrate state without valid region information.',\n );\n }\n\n this.#fireAndForget(this.getTokens(regionCode, 'buy', options));\n this.#fireAndForget(this.getProviders(regionCode, options));\n }\n\n /**\n * Fetches the list of supported countries.\n * The API returns countries with support information for both buy and sell actions.\n * The countries are saved in the controller state once fetched.\n *\n * @param options - Options for cache behavior.\n * @returns An array of countries.\n */\n async getCountries(options?: ExecuteRequestOptions): Promise<Country[]> {\n const cacheKey = createCacheKey('getCountries', []);\n\n const countries = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getCountries');\n },\n { ...options, resourceType: 'countries' },\n );\n\n this.update((state) => {\n state.countries.data = countries;\n });\n\n return countries;\n }\n\n /**\n * Fetches the list of available tokens for a given region and action.\n * The tokens are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param action - The ramp action type ('buy' or 'sell').\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @returns The tokens response containing topTokens and allTokens.\n */\n async getTokens(\n region?: string,\n action: RampAction = 'buy',\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n },\n ): Promise<TokensResponse> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getTokens', [\n normalizedRegion,\n action,\n options?.provider,\n ]);\n\n const tokens = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getTokens',\n normalizedRegion,\n action,\n {\n provider: options?.provider,\n },\n );\n },\n {\n ...options,\n resourceType: 'tokens',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.tokens.data = tokens;\n }\n });\n\n return tokens;\n }\n\n /**\n * Sets the user's selected token by asset ID.\n * Looks up the token from the current tokens in state and automatically\n * fetches payment methods for that token.\n *\n * @param assetId - The asset identifier in CAIP-19 format (e.g., \"eip155:1/erc20:0x...\"), or undefined to clear.\n * @throws If region is not set, tokens are not loaded, or token is not found.\n */\n setSelectedToken(assetId?: string): void {\n if (!assetId) {\n this.stopQuotePolling();\n this.update((state) => {\n state.tokens.selected = null;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const regionCode = this.state.userRegion?.regionCode;\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot set selected token without valid region information.',\n );\n }\n\n const tokens = this.state.tokens.data;\n if (!tokens) {\n throw new Error(\n 'Tokens not loaded. Cannot set selected token before tokens are fetched.',\n );\n }\n\n const token =\n tokens.allTokens.find((tok) => tok.assetId === assetId) ??\n tokens.topTokens.find((tok) => tok.assetId === assetId);\n\n if (!token) {\n throw new Error(\n `Token with asset ID \"${assetId}\" not found in available tokens.`,\n );\n }\n\n this.update((state) => {\n state.tokens.selected = token;\n state.paymentMethods.data = [];\n state.paymentMethods.selected = null;\n state.quotes.selected = null;\n });\n\n this.#fireAndForget(\n this.getPaymentMethods(regionCode, { assetId: token.assetId }).then(\n () => {\n this.#restartPollingIfActive();\n return undefined;\n },\n ),\n );\n }\n\n /**\n * Fetches the list of providers for a given region.\n * The providers are saved in the controller state once fetched.\n *\n * @param region - The region code (e.g., \"us\", \"fr\", \"us-ny\"). If not provided, uses the user's region from controller state.\n * @param options - Options for cache behavior and query filters.\n * @param options.provider - Provider ID(s) to filter by.\n * @param options.crypto - Crypto currency ID(s) to filter by.\n * @param options.fiat - Fiat currency ID(s) to filter by.\n * @param options.payments - Payment method ID(s) to filter by.\n * @returns The providers response containing providers array.\n */\n async getProviders(\n region?: string,\n options?: ExecuteRequestOptions & {\n provider?: string | string[];\n crypto?: string | string[];\n fiat?: string | string[];\n payments?: string | string[];\n },\n ): Promise<{ providers: Provider[] }> {\n const regionToUse = region ?? this.state.userRegion?.regionCode;\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getProviders', [\n normalizedRegion,\n options?.provider,\n options?.crypto,\n options?.fiat,\n options?.payments,\n ]);\n\n const { providers } = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call(\n 'RampsService:getProviders',\n normalizedRegion,\n {\n provider: options?.provider,\n crypto: options?.crypto,\n fiat: options?.fiat,\n payments: options?.payments,\n },\n );\n },\n {\n ...options,\n resourceType: 'providers',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.providers.data = providers;\n }\n });\n\n return { providers };\n }\n\n /**\n * Fetches the list of payment methods for a given context.\n * The payment methods are saved in the controller state once fetched.\n *\n * @param region - User's region code (e.g. \"fr\", \"us-ny\").\n * @param options - Query parameters for filtering payment methods.\n * @param options.fiat - Fiat currency code (e.g., \"usd\"). If not provided, uses the user's region currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.provider - Provider ID path.\n * @returns The payment methods response containing payments array.\n */\n async getPaymentMethods(\n region?: string,\n options?: ExecuteRequestOptions & {\n fiat?: string;\n assetId?: string;\n provider?: string;\n },\n ): Promise<PaymentMethodsResponse> {\n const regionCode = region ?? this.state.userRegion?.regionCode ?? null;\n const fiatToUse =\n options?.fiat ?? this.state.userRegion?.country?.currency ?? null;\n const assetIdToUse =\n options?.assetId ?? this.state.tokens.selected?.assetId ?? '';\n const providerToUse =\n options?.provider ?? this.state.providers.selected?.id ?? '';\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n const normalizedRegion = regionCode.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const cacheKey = createCacheKey('getPaymentMethods', [\n normalizedRegion,\n normalizedFiat,\n assetIdToUse,\n providerToUse,\n ]);\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getPaymentMethods', {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: assetIdToUse,\n provider: providerToUse,\n });\n },\n {\n ...options,\n resourceType: 'paymentMethods',\n isResultCurrent: () => {\n const regionMatch =\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion;\n const tokenMatch =\n (this.state.tokens.selected?.assetId ?? '') === assetIdToUse;\n const providerMatch =\n (this.state.providers.selected?.id ?? '') === providerToUse;\n return regionMatch && tokenMatch && providerMatch;\n },\n },\n );\n\n this.update((state) => {\n const currentAssetId = state.tokens.selected?.assetId ?? '';\n const currentProviderId = state.providers.selected?.id ?? '';\n\n const tokenSelectionUnchanged = assetIdToUse === currentAssetId;\n const providerSelectionUnchanged = providerToUse === currentProviderId;\n\n // this is a race condition check to ensure that the selected token and provider in state are the same as the tokens we're requesting for\n // ex: if the user rapidly changes the token or provider, the in-flight payment methods might not be valid\n // so this check will ensure that the payment methods are still valid for the token and provider that were requested\n if (tokenSelectionUnchanged && providerSelectionUnchanged) {\n state.paymentMethods.data = response.payments;\n\n // this will auto-select the first payment method if the selected payment method is not in the new payment methods\n const currentSelectionStillValid = response.payments.some(\n (pm: PaymentMethod) => pm.id === state.paymentMethods.selected?.id,\n );\n if (!currentSelectionStillValid) {\n state.paymentMethods.selected = response.payments[0] ?? null;\n }\n }\n });\n\n return response;\n }\n\n /**\n * Sets the user's selected payment method by ID.\n * Looks up the payment method from the current payment methods in state.\n *\n * @param paymentMethodId - The payment method ID (e.g., \"/payments/debit-credit-card\"), or null to clear.\n * @throws If payment methods are not loaded or payment method is not found.\n */\n setSelectedPaymentMethod(paymentMethodId?: string): void {\n if (!paymentMethodId) {\n this.update((state) => {\n state.paymentMethods.selected = null;\n });\n return;\n }\n\n const paymentMethods = this.state.paymentMethods.data;\n if (!paymentMethods || paymentMethods.length === 0) {\n throw new Error(\n 'Payment methods not loaded. Cannot set selected payment method before payment methods are fetched.',\n );\n }\n\n const paymentMethod = paymentMethods.find(\n (pm) => pm.id === paymentMethodId,\n );\n if (!paymentMethod) {\n throw new Error(\n `Payment method with ID \"${paymentMethodId}\" not found in available payment methods.`,\n );\n }\n\n this.update((state) => {\n state.paymentMethods.selected = paymentMethod;\n });\n\n // Restart quote polling if active\n this.#restartPollingIfActive();\n }\n\n /**\n * Fetches quotes from all providers for a given set of parameters.\n * The quotes are saved in the controller state once fetched.\n *\n * @param options - The parameters for fetching quotes.\n * @param options.region - User's region code. If not provided, uses userRegion from state.\n * @param options.fiat - Fiat currency code. If not provided, uses userRegion currency.\n * @param options.assetId - CAIP-19 cryptocurrency identifier.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.walletAddress - The destination wallet address.\n * @param options.paymentMethods - Array of payment method IDs. If not provided, uses paymentMethods from state.\n * @param options.provider - Optional provider ID to filter quotes.\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @param options.action - The ramp action type. Defaults to 'buy'.\n * @param options.forceRefresh - Whether to bypass cache.\n * @param options.ttl - Custom TTL for this request.\n * @returns The quotes response containing success, sorted, error, and customActions.\n */\n async getQuotes(options: {\n region?: string;\n fiat?: string;\n assetId: string;\n amount: number;\n walletAddress: string;\n paymentMethods?: string[];\n provider?: string;\n redirectUrl?: string;\n action?: RampAction;\n forceRefresh?: boolean;\n ttl?: number;\n }): Promise<QuotesResponse> {\n const regionToUse = options.region ?? this.state.userRegion?.regionCode;\n const fiatToUse = options.fiat ?? this.state.userRegion?.country?.currency;\n const paymentMethodsToUse =\n options.paymentMethods ??\n this.state.paymentMethods.data.map((pm: PaymentMethod) => pm.id);\n const action = options.action ?? 'buy';\n\n if (!regionToUse) {\n throw new Error(\n 'Region is required. Either provide a region parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!fiatToUse) {\n throw new Error(\n 'Fiat currency is required. Either provide a fiat parameter or ensure userRegion is set in controller state.',\n );\n }\n\n if (!paymentMethodsToUse || paymentMethodsToUse.length === 0) {\n throw new Error(\n 'Payment methods are required. Either provide paymentMethods parameter or ensure paymentMethods are set in controller state.',\n );\n }\n\n if (options.amount <= 0 || !Number.isFinite(options.amount)) {\n throw new Error('Amount must be a positive finite number.');\n }\n\n if (!options.assetId || options.assetId.trim() === '') {\n throw new Error('assetId is required.');\n }\n\n if (!options.walletAddress || options.walletAddress.trim() === '') {\n throw new Error('walletAddress is required.');\n }\n\n const normalizedRegion = regionToUse.toLowerCase().trim();\n const normalizedFiat = fiatToUse.toLowerCase().trim();\n const normalizedAssetId = options.assetId.trim();\n const normalizedWalletAddress = options.walletAddress.trim();\n\n const cacheKey = createCacheKey('getQuotes', [\n normalizedRegion,\n normalizedFiat,\n normalizedAssetId,\n options.amount,\n normalizedWalletAddress,\n [...paymentMethodsToUse].sort().join(','),\n options.provider,\n options.redirectUrl,\n action,\n ]);\n\n const params: GetQuotesParams = {\n region: normalizedRegion,\n fiat: normalizedFiat,\n assetId: normalizedAssetId,\n amount: options.amount,\n walletAddress: normalizedWalletAddress,\n paymentMethods: paymentMethodsToUse,\n provider: options.provider,\n redirectUrl: options.redirectUrl,\n action,\n };\n\n const response = await this.executeRequest(\n cacheKey,\n async () => {\n return this.messenger.call('RampsService:getQuotes', params);\n },\n {\n forceRefresh: options.forceRefresh,\n ttl: options.ttl ?? DEFAULT_QUOTES_TTL,\n resourceType: 'quotes',\n isResultCurrent: () =>\n this.state.userRegion?.regionCode === undefined ||\n this.state.userRegion?.regionCode === normalizedRegion,\n },\n );\n\n this.update((state) => {\n const userRegionCode = state.userRegion?.regionCode;\n\n if (userRegionCode === undefined || userRegionCode === normalizedRegion) {\n state.quotes.data = response;\n }\n });\n\n return response;\n }\n\n /**\n * Starts automatic quote polling with a 15-second refresh interval.\n * Fetches quotes immediately and then every 15 seconds.\n * If the response contains exactly one quote, it is auto-selected.\n * If multiple quotes are returned, the existing selection is preserved if still valid.\n *\n * @param options - Parameters for fetching quotes.\n * @param options.walletAddress - The destination wallet address.\n * @param options.amount - The amount (in fiat for buy, crypto for sell).\n * @param options.redirectUrl - Optional redirect URL after order completion.\n * @throws If required dependencies (region, token, provider, payment method) are not set.\n */\n startQuotePolling(options: {\n walletAddress: string;\n amount: number;\n redirectUrl?: string;\n }): void {\n // Validate required dependencies\n const regionCode = this.state.userRegion?.regionCode;\n const token = this.state.tokens.selected;\n const provider = this.state.providers.selected;\n const paymentMethod = this.state.paymentMethods.selected;\n\n if (!regionCode) {\n throw new Error(\n 'Region is required. Cannot start quote polling without valid region information.',\n );\n }\n\n if (!token) {\n throw new Error(\n 'Token is required. Cannot start quote polling without a selected token.',\n );\n }\n\n if (!provider) {\n throw new Error(\n 'Provider is required. Cannot start quote polling without a selected provider.',\n );\n }\n\n if (!paymentMethod) {\n return;\n }\n\n // Stop any existing polling first\n this.stopQuotePolling();\n\n // Store options for restarts (must be after stop to avoid being cleared)\n this.#quotePollingOptions = options;\n\n // Define the fetch function\n const fetchQuotes = (): void => {\n this.#fireAndForget(\n this.getQuotes({\n assetId: token.assetId,\n amount: options.amount,\n walletAddress: options.walletAddress,\n redirectUrl: options.redirectUrl,\n paymentMethods: [paymentMethod.id],\n provider: provider.id,\n forceRefresh: true,\n }).then((response) => {\n // Auto-select logic: only when exactly one quote is returned\n this.update((state) => {\n if (response.success.length === 1) {\n state.quotes.selected = response.success[0];\n } else {\n // Keep existing selection if still valid, but update with fresh data\n const currentSelection = state.quotes.selected;\n if (currentSelection) {\n const freshQuote = response.success.find(\n (quote) =>\n quote.provider === currentSelection.provider &&\n quote.quote.paymentMethod ===\n currentSelection.quote.paymentMethod,\n );\n // Update with fresh quote data, or clear if no longer valid\n state.quotes.selected = freshQuote ?? null;\n }\n }\n });\n return undefined;\n }),\n );\n };\n\n // Fetch immediately\n fetchQuotes();\n\n // Set up 15-second polling\n this.#quotePollingInterval = setInterval(fetchQuotes, 15000);\n }\n\n /**\n * Stops automatic quote polling.\n * Does not clear quotes data or selection, only stops the interval.\n */\n stopQuotePolling(): void {\n if (this.#quotePollingInterval !== null) {\n clearInterval(this.#quotePollingInterval);\n this.#quotePollingInterval = null;\n }\n this.#quotePollingOptions = null;\n }\n\n /**\n * Manually sets the selected quote.\n *\n * @param quote - The quote to select, or null to clear the selection.\n */\n setSelectedQuote(quote: Quote | null): void {\n this.update((state) => {\n state.quotes.selected = quote;\n });\n }\n\n /**\n * Cleans up controller resources.\n * Stops any active quote polling to prevent memory leaks.\n * Should be called when the controller is no longer needed.\n */\n override destroy(): void {\n this.stopQuotePolling();\n super.destroy();\n }\n\n /**\n * Extracts the widget URL from a quote for redirect providers.\n * Returns the widget URL if available, or null if the quote doesn't have one.\n *\n * @param quote - The quote to extract the widget URL from.\n * @returns The widget URL string, or null if not available.\n */\n getWidgetUrl(quote: Quote): string | null {\n return quote.quote?.widgetUrl ?? null;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/ramps-controller",
3
- "version": "7.0.0",
3
+ "version": "7.1.0",
4
4
  "description": "A controller for managing cryptocurrency on/off ramps functionality",
5
5
  "keywords": [
6
6
  "MetaMask",