@metamask-previews/core-backend 9.0.0-preview-5bb6dba48 → 9.0.0-preview-d8fceeabc

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
@@ -9,11 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Added
11
11
 
12
+ - Add `authTokenTimeout` to `ApiPlatformClientOptions` and export `DEFAULT_AUTH_TOKEN_TIMEOUT` ([#10104](https://github.com/MetaMask/core/pull/10104))
13
+ - Requests wait at most this long (default 500ms) for `getBearerToken`. If the token is not ready, the request is sent unauthenticated while the in-flight `fetchQuery` continues so later requests can attach the token. Set `authTokenTimeout` to `0` to wait indefinitely.
14
+ - Bearer-token `fetchQuery` uses `staleTime: 0` so concurrent requests are de-duplicated without a second JWT cache; token lifetime stays with AuthenticationController.
12
15
  - Add `bypassServerCache` option to `FetchOptions` ([#10068](https://github.com/MetaMask/core/pull/10068))
13
16
  - When true, the v5/v6 multi-account balances requests skip the client-side query cache (stale time defaults to 0) and append a random `bypassServerCache` query param so the Accounts API's server-side cache (keyed on the full URL) misses. Intended for hard refreshes only, e.g. right after a transaction confirms.
14
17
 
15
18
  ### Changed
16
19
 
20
+ - Bearer-token `fetchQuery` no longer uses a 5-minute `STALE_TIMES.AUTH_TOKEN`; `STALE_TIMES.AUTH_TOKEN` is removed ([#10104](https://github.com/MetaMask/core/pull/10104))
17
21
  - Bump `@metamask/remote-feature-flag-controller` from `^6.0.0` to `^6.1.0` ([#9980](https://github.com/MetaMask/core/pull/9980))
18
22
  - Bump `@metamask/utils` from `^11.11.0` to `^11.12.0` ([#10076](https://github.com/MetaMask/core/pull/10076))
19
23
  - Bump `@metamask/account-tree-controller` from `^8.0.0` to `^8.1.0` ([#10088](https://github.com/MetaMask/core/pull/10088))
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
13
13
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
14
14
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
15
15
  };
16
- var _BaseApiClient_queryClientInstance;
16
+ var _BaseApiClient_instances, _BaseApiClient_queryClientInstance, _BaseApiClient_fetchBearerToken;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.HttpError = exports.GC_TIMES = exports.STALE_TIMES = exports.API_URLS = exports.BaseApiClient = exports.authQueryKeys = void 0;
19
19
  const query_core_1 = require("@tanstack/query-core");
@@ -53,10 +53,13 @@ class BaseApiClient {
53
53
  });
54
54
  }
55
55
  constructor(options) {
56
+ _BaseApiClient_instances.add(this);
56
57
  _BaseApiClient_queryClientInstance.set(this, void 0);
57
58
  this.clientProduct = options.clientProduct;
58
59
  this.clientVersion = options.clientVersion;
59
60
  this.getBearerToken = options.getBearerToken;
61
+ this.authTokenTimeout =
62
+ options.authTokenTimeout ?? shared_types_js_1.DEFAULT_AUTH_TOKEN_TIMEOUT;
60
63
  __classPrivateFieldSet(this, _BaseApiClient_queryClientInstance, options.queryClient ??
61
64
  new query_core_1.QueryClient({
62
65
  defaultOptions: {
@@ -102,31 +105,9 @@ class BaseApiClient {
102
105
  if (this.clientVersion) {
103
106
  headers['x-metamask-clientversion'] = this.clientVersion;
104
107
  }
105
- // Get bearer token using fetchQuery for automatic deduplication
106
- if (this.getBearerToken) {
107
- const queryKey = exports.authQueryKeys.bearerToken();
108
- const { getBearerToken } = this;
109
- try {
110
- // fetchQuery handles caching and deduplicates concurrent requests
111
- const token = await __classPrivateFieldGet(this, _BaseApiClient_queryClientInstance, "f").fetchQuery({
112
- queryKey,
113
- queryFn: async () => {
114
- const result = await getBearerToken();
115
- // Throw if no token - prevents caching null/undefined
116
- // so subsequent requests can retry (e.g., after user logs in)
117
- if (!result) {
118
- throw new Error('No bearer token available');
119
- }
120
- return result;
121
- },
122
- staleTime: shared_types_js_1.STALE_TIMES.AUTH_TOKEN,
123
- retry: false, // Don't retry auth failures
124
- });
125
- headers.Authorization = `Bearer ${token}`;
126
- }
127
- catch {
128
- // No token available - continue without auth header
129
- }
108
+ const token = await __classPrivateFieldGet(this, _BaseApiClient_instances, "m", _BaseApiClient_fetchBearerToken).call(this);
109
+ if (token) {
110
+ headers.Authorization = `Bearer ${token}`;
130
111
  }
131
112
  const response = await fetch(url.toString(), {
132
113
  method: 'GET',
@@ -147,5 +128,50 @@ class BaseApiClient {
147
128
  }
148
129
  }
149
130
  exports.BaseApiClient = BaseApiClient;
150
- _BaseApiClient_queryClientInstance = new WeakMap();
131
+ _BaseApiClient_queryClientInstance = new WeakMap(), _BaseApiClient_instances = new WeakSet(), _BaseApiClient_fetchBearerToken =
132
+ /**
133
+ * Resolve the bearer token, giving up after `authTokenTimeout` so that a slow
134
+ * token provider does not delay the request. When the wait times out the
135
+ * request goes out unauthenticated (lower rate limit) while the in-flight
136
+ * `fetchQuery` keeps resolving `getBearerToken` for later requests.
137
+ *
138
+ * @returns The bearer token, or undefined if unavailable in time.
139
+ */
140
+ async function _BaseApiClient_fetchBearerToken() {
141
+ const { getBearerToken } = this;
142
+ if (!getBearerToken) {
143
+ return undefined;
144
+ }
145
+ // fetchQuery de-duplicates concurrent callers. staleTime is 0 so we do not
146
+ // cache the JWT here — AuthenticationController already owns token lifetime.
147
+ const tokenPromise = __classPrivateFieldGet(this, _BaseApiClient_queryClientInstance, "f")
148
+ .fetchQuery({
149
+ queryKey: exports.authQueryKeys.bearerToken(),
150
+ queryFn: async () => {
151
+ const result = await getBearerToken();
152
+ // Throw if no token - prevents caching null/undefined
153
+ // so subsequent requests can retry (e.g., after user logs in)
154
+ if (!result) {
155
+ throw new Error('No bearer token available');
156
+ }
157
+ return result;
158
+ },
159
+ staleTime: 0,
160
+ retry: false, // Don't retry auth failures
161
+ })
162
+ .catch(() => undefined);
163
+ if (this.authTokenTimeout <= 0) {
164
+ return await tokenPromise;
165
+ }
166
+ let timeoutId;
167
+ const timeoutPromise = new Promise((resolve) => {
168
+ timeoutId = setTimeout(() => resolve(undefined), this.authTokenTimeout);
169
+ });
170
+ try {
171
+ return await Promise.race([tokenPromise, timeoutPromise]);
172
+ }
173
+ finally {
174
+ clearTimeout(timeoutId);
175
+ }
176
+ };
151
177
  //# sourceMappingURL=base-client.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-client.cjs","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Base API Client - Shared HTTP functionality for all API clients.\n */\n\nimport { QueryClient } from '@tanstack/query-core';\nimport type { QueryKey } from '@tanstack/query-core';\n\nimport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n calculateRetryDelay,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\nimport type { ApiPlatformClientOptions } from './shared-types.js';\n\n// Auth query keys - shared for token management across clients\nexport const authQueryKeys = {\n bearerToken: (): QueryKey => ['auth', 'bearerToken'],\n} as const;\n\nexport type { ApiPlatformClientOptions };\n\n/**\n * Internal fetch options for HTTP requests.\n */\nexport type InternalFetchOptions = {\n signal?: AbortSignal;\n params?: Record<\n string,\n string | string[] | number | number[] | boolean | undefined\n >;\n};\n\n/**\n * Base API Client with shared HTTP and caching functionality.\n * Extended by all specific API clients.\n */\nexport class BaseApiClient {\n protected readonly clientProduct: string;\n\n protected readonly clientVersion?: string;\n\n protected readonly getBearerToken?: () => Promise<string | undefined>;\n\n readonly #queryClientInstance: QueryClient;\n\n /**\n * Get the underlying QueryClient instance.\n * Exposed for cache management operations.\n *\n * @returns The QueryClient instance.\n */\n get queryClient(): QueryClient {\n return this.#queryClientInstance;\n }\n\n /**\n * Invalidate the cached auth token.\n * Call this when the user logs out or the token expires.\n *\n * Uses resetQueries() instead of invalidateQueries() to completely remove\n * the cached value, ensuring the next request fetches a fresh token immediately.\n */\n async invalidateAuthToken(): Promise<void> {\n await this.#queryClientInstance.resetQueries({\n queryKey: authQueryKeys.bearerToken(),\n });\n }\n\n constructor(options: ApiPlatformClientOptions) {\n this.clientProduct = options.clientProduct;\n this.clientVersion = options.clientVersion;\n this.getBearerToken = options.getBearerToken;\n\n this.#queryClientInstance =\n options.queryClient ??\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: STALE_TIMES.DEFAULT,\n gcTime: GC_TIMES.DEFAULT,\n retry: shouldRetry,\n retryDelay: calculateRetryDelay,\n refetchOnWindowFocus: false,\n networkMode: 'always',\n },\n },\n });\n }\n\n /**\n * Internal HTTP fetch method with authentication and error handling.\n *\n * @param baseUrl - The base URL for the API.\n * @param path - The API endpoint path.\n * @param options - Optional fetch configuration.\n * @returns The parsed JSON response.\n */\n protected async fetch<ResponseType>(\n baseUrl: string,\n path: string,\n options?: InternalFetchOptions,\n ): Promise<ResponseType> {\n const url = new URL(path, baseUrl);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value === undefined) {\n continue;\n }\n if (Array.isArray(value)) {\n // Convert array values (including number[]) to comma-separated string\n url.searchParams.set(key, value.map(String).join(','));\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-metamask-clientproduct': this.clientProduct,\n };\n\n if (this.clientVersion) {\n headers['x-metamask-clientversion'] = this.clientVersion;\n }\n\n // Get bearer token using fetchQuery for automatic deduplication\n if (this.getBearerToken) {\n const queryKey = authQueryKeys.bearerToken();\n const { getBearerToken } = this;\n\n try {\n // fetchQuery handles caching and deduplicates concurrent requests\n const token = await this.#queryClientInstance.fetchQuery({\n queryKey,\n queryFn: async () => {\n const result = await getBearerToken();\n // Throw if no token - prevents caching null/undefined\n // so subsequent requests can retry (e.g., after user logs in)\n if (!result) {\n throw new Error('No bearer token available');\n }\n return result;\n },\n staleTime: STALE_TIMES.AUTH_TOKEN,\n retry: false, // Don't retry auth failures\n });\n\n headers.Authorization = `Bearer ${token}`;\n } catch {\n // No token available - continue without auth header\n }\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers,\n signal: options?.signal,\n });\n\n if (!response.ok) {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n // Response body is not JSON or is empty, leave body as undefined\n }\n throw new HttpError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n url.toString(),\n body,\n );\n }\n\n return response.json() as Promise<ResponseType>;\n }\n}\n\n// Re-export constants for use by API clients\nexport { API_URLS, STALE_TIMES, GC_TIMES, HttpError };\n"]}
1
+ {"version":3,"file":"base-client.cjs","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Base API Client - Shared HTTP functionality for all API clients.\n */\n\nimport { QueryClient } from '@tanstack/query-core';\nimport type { QueryKey } from '@tanstack/query-core';\n\nimport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n DEFAULT_AUTH_TOKEN_TIMEOUT,\n calculateRetryDelay,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\nimport type { ApiPlatformClientOptions } from './shared-types.js';\n\n// Auth query keys - shared for token management across clients\nexport const authQueryKeys = {\n bearerToken: (): QueryKey => ['auth', 'bearerToken'],\n} as const;\n\nexport type { ApiPlatformClientOptions };\n\n/**\n * Internal fetch options for HTTP requests.\n */\nexport type InternalFetchOptions = {\n signal?: AbortSignal;\n params?: Record<\n string,\n string | string[] | number | number[] | boolean | undefined\n >;\n};\n\n/**\n * Base API Client with shared HTTP and caching functionality.\n * Extended by all specific API clients.\n */\nexport class BaseApiClient {\n protected readonly clientProduct: string;\n\n protected readonly clientVersion?: string;\n\n protected readonly getBearerToken?: () => Promise<string | undefined>;\n\n protected readonly authTokenTimeout: number;\n\n readonly #queryClientInstance: QueryClient;\n\n /**\n * Get the underlying QueryClient instance.\n * Exposed for cache management operations.\n *\n * @returns The QueryClient instance.\n */\n get queryClient(): QueryClient {\n return this.#queryClientInstance;\n }\n\n /**\n * Invalidate the cached auth token.\n * Call this when the user logs out or the token expires.\n *\n * Uses resetQueries() instead of invalidateQueries() to completely remove\n * the cached value, ensuring the next request fetches a fresh token immediately.\n */\n async invalidateAuthToken(): Promise<void> {\n await this.#queryClientInstance.resetQueries({\n queryKey: authQueryKeys.bearerToken(),\n });\n }\n\n constructor(options: ApiPlatformClientOptions) {\n this.clientProduct = options.clientProduct;\n this.clientVersion = options.clientVersion;\n this.getBearerToken = options.getBearerToken;\n this.authTokenTimeout =\n options.authTokenTimeout ?? DEFAULT_AUTH_TOKEN_TIMEOUT;\n\n this.#queryClientInstance =\n options.queryClient ??\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: STALE_TIMES.DEFAULT,\n gcTime: GC_TIMES.DEFAULT,\n retry: shouldRetry,\n retryDelay: calculateRetryDelay,\n refetchOnWindowFocus: false,\n networkMode: 'always',\n },\n },\n });\n }\n\n /**\n * Resolve the bearer token, giving up after `authTokenTimeout` so that a slow\n * token provider does not delay the request. When the wait times out the\n * request goes out unauthenticated (lower rate limit) while the in-flight\n * `fetchQuery` keeps resolving `getBearerToken` for later requests.\n *\n * @returns The bearer token, or undefined if unavailable in time.\n */\n async #fetchBearerToken(): Promise<string | undefined> {\n const { getBearerToken } = this;\n if (!getBearerToken) {\n return undefined;\n }\n\n // fetchQuery de-duplicates concurrent callers. staleTime is 0 so we do not\n // cache the JWT here — AuthenticationController already owns token lifetime.\n const tokenPromise = this.#queryClientInstance\n .fetchQuery({\n queryKey: authQueryKeys.bearerToken(),\n queryFn: async () => {\n const result = await getBearerToken();\n // Throw if no token - prevents caching null/undefined\n // so subsequent requests can retry (e.g., after user logs in)\n if (!result) {\n throw new Error('No bearer token available');\n }\n return result;\n },\n staleTime: 0,\n retry: false, // Don't retry auth failures\n })\n .catch(() => undefined);\n\n if (this.authTokenTimeout <= 0) {\n return await tokenPromise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<undefined>((resolve) => {\n timeoutId = setTimeout(() => resolve(undefined), this.authTokenTimeout);\n });\n\n try {\n return await Promise.race([tokenPromise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Internal HTTP fetch method with authentication and error handling.\n *\n * @param baseUrl - The base URL for the API.\n * @param path - The API endpoint path.\n * @param options - Optional fetch configuration.\n * @returns The parsed JSON response.\n */\n protected async fetch<ResponseType>(\n baseUrl: string,\n path: string,\n options?: InternalFetchOptions,\n ): Promise<ResponseType> {\n const url = new URL(path, baseUrl);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value === undefined) {\n continue;\n }\n if (Array.isArray(value)) {\n // Convert array values (including number[]) to comma-separated string\n url.searchParams.set(key, value.map(String).join(','));\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-metamask-clientproduct': this.clientProduct,\n };\n\n if (this.clientVersion) {\n headers['x-metamask-clientversion'] = this.clientVersion;\n }\n\n const token = await this.#fetchBearerToken();\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers,\n signal: options?.signal,\n });\n\n if (!response.ok) {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n // Response body is not JSON or is empty, leave body as undefined\n }\n throw new HttpError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n url.toString(),\n body,\n );\n }\n\n return response.json() as Promise<ResponseType>;\n }\n}\n\n// Re-export constants for use by API clients\nexport { API_URLS, STALE_TIMES, GC_TIMES, HttpError };\n"]}
@@ -24,6 +24,7 @@ export declare class BaseApiClient {
24
24
  protected readonly clientProduct: string;
25
25
  protected readonly clientVersion?: string;
26
26
  protected readonly getBearerToken?: () => Promise<string | undefined>;
27
+ protected readonly authTokenTimeout: number;
27
28
  /**
28
29
  * Get the underlying QueryClient instance.
29
30
  * Exposed for cache management operations.
@@ -1 +1 @@
1
- {"version":3,"file":"base-client.d.cts","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,6BAA6B;AAGnD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EAGR,SAAS,EACV,2BAA0B;AAC3B,OAAO,KAAK,EAAE,wBAAwB,EAAE,2BAA0B;AAGlE,eAAO,MAAM,aAAa;;CAEhB,CAAC;AAEX,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,CAC5D,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,qBAAa,aAAa;;IACxB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAEzC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAItE;;;;;OAKG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;gBAM9B,OAAO,EAAE,wBAAwB;IAqB7C;;;;;;;OAOG;cACa,KAAK,CAAC,YAAY,EAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC;CA8EzB;AAGD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"base-client.d.cts","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,6BAA6B;AAGnD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EAIR,SAAS,EACV,2BAA0B;AAC3B,OAAO,KAAK,EAAE,wBAAwB,EAAE,2BAA0B;AAGlE,eAAO,MAAM,aAAa;;CAEhB,CAAC;AAEX,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,CAC5D,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,qBAAa,aAAa;;IACxB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAEzC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEtE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAI5C;;;;;OAKG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;gBAM9B,OAAO,EAAE,wBAAwB;IAwE7C;;;;;;;OAOG;cACa,KAAK,CAAC,YAAY,EAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC;CAuDzB;AAGD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC"}
@@ -24,6 +24,7 @@ export declare class BaseApiClient {
24
24
  protected readonly clientProduct: string;
25
25
  protected readonly clientVersion?: string;
26
26
  protected readonly getBearerToken?: () => Promise<string | undefined>;
27
+ protected readonly authTokenTimeout: number;
27
28
  /**
28
29
  * Get the underlying QueryClient instance.
29
30
  * Exposed for cache management operations.
@@ -1 +1 @@
1
- {"version":3,"file":"base-client.d.mts","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,6BAA6B;AAGnD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EAGR,SAAS,EACV,2BAA0B;AAC3B,OAAO,KAAK,EAAE,wBAAwB,EAAE,2BAA0B;AAGlE,eAAO,MAAM,aAAa;;CAEhB,CAAC;AAEX,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,CAC5D,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,qBAAa,aAAa;;IACxB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAEzC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAItE;;;;;OAKG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;gBAM9B,OAAO,EAAE,wBAAwB;IAqB7C;;;;;;;OAOG;cACa,KAAK,CAAC,YAAY,EAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC;CA8EzB;AAGD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"base-client.d.mts","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,6BAA6B;AAGnD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EAIR,SAAS,EACV,2BAA0B;AAC3B,OAAO,KAAK,EAAE,wBAAwB,EAAE,2BAA0B;AAGlE,eAAO,MAAM,aAAa;;CAEhB,CAAC;AAEX,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,CAC5D,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,qBAAa,aAAa;;IACxB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAEzC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEtE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAI5C;;;;;OAKG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;gBAM9B,OAAO,EAAE,wBAAwB;IAwE7C;;;;;;;OAOG;cACa,KAAK,CAAC,YAAY,EAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC;CAuDzB;AAGD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC"}
@@ -12,9 +12,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
12
12
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
13
13
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
14
14
  };
15
- var _BaseApiClient_queryClientInstance;
15
+ var _BaseApiClient_instances, _BaseApiClient_queryClientInstance, _BaseApiClient_fetchBearerToken;
16
16
  import { QueryClient } from "@tanstack/query-core";
17
- import { API_URLS, STALE_TIMES, GC_TIMES, calculateRetryDelay, shouldRetry, HttpError } from "./shared-types.mjs";
17
+ import { API_URLS, STALE_TIMES, GC_TIMES, DEFAULT_AUTH_TOKEN_TIMEOUT, calculateRetryDelay, shouldRetry, HttpError } from "./shared-types.mjs";
18
18
  // Auth query keys - shared for token management across clients
19
19
  export const authQueryKeys = {
20
20
  bearerToken: () => ['auth', 'bearerToken'],
@@ -46,10 +46,13 @@ export class BaseApiClient {
46
46
  });
47
47
  }
48
48
  constructor(options) {
49
+ _BaseApiClient_instances.add(this);
49
50
  _BaseApiClient_queryClientInstance.set(this, void 0);
50
51
  this.clientProduct = options.clientProduct;
51
52
  this.clientVersion = options.clientVersion;
52
53
  this.getBearerToken = options.getBearerToken;
54
+ this.authTokenTimeout =
55
+ options.authTokenTimeout ?? DEFAULT_AUTH_TOKEN_TIMEOUT;
53
56
  __classPrivateFieldSet(this, _BaseApiClient_queryClientInstance, options.queryClient ??
54
57
  new QueryClient({
55
58
  defaultOptions: {
@@ -95,31 +98,9 @@ export class BaseApiClient {
95
98
  if (this.clientVersion) {
96
99
  headers['x-metamask-clientversion'] = this.clientVersion;
97
100
  }
98
- // Get bearer token using fetchQuery for automatic deduplication
99
- if (this.getBearerToken) {
100
- const queryKey = authQueryKeys.bearerToken();
101
- const { getBearerToken } = this;
102
- try {
103
- // fetchQuery handles caching and deduplicates concurrent requests
104
- const token = await __classPrivateFieldGet(this, _BaseApiClient_queryClientInstance, "f").fetchQuery({
105
- queryKey,
106
- queryFn: async () => {
107
- const result = await getBearerToken();
108
- // Throw if no token - prevents caching null/undefined
109
- // so subsequent requests can retry (e.g., after user logs in)
110
- if (!result) {
111
- throw new Error('No bearer token available');
112
- }
113
- return result;
114
- },
115
- staleTime: STALE_TIMES.AUTH_TOKEN,
116
- retry: false, // Don't retry auth failures
117
- });
118
- headers.Authorization = `Bearer ${token}`;
119
- }
120
- catch {
121
- // No token available - continue without auth header
122
- }
101
+ const token = await __classPrivateFieldGet(this, _BaseApiClient_instances, "m", _BaseApiClient_fetchBearerToken).call(this);
102
+ if (token) {
103
+ headers.Authorization = `Bearer ${token}`;
123
104
  }
124
105
  const response = await fetch(url.toString(), {
125
106
  method: 'GET',
@@ -139,7 +120,52 @@ export class BaseApiClient {
139
120
  return response.json();
140
121
  }
141
122
  }
142
- _BaseApiClient_queryClientInstance = new WeakMap();
123
+ _BaseApiClient_queryClientInstance = new WeakMap(), _BaseApiClient_instances = new WeakSet(), _BaseApiClient_fetchBearerToken =
124
+ /**
125
+ * Resolve the bearer token, giving up after `authTokenTimeout` so that a slow
126
+ * token provider does not delay the request. When the wait times out the
127
+ * request goes out unauthenticated (lower rate limit) while the in-flight
128
+ * `fetchQuery` keeps resolving `getBearerToken` for later requests.
129
+ *
130
+ * @returns The bearer token, or undefined if unavailable in time.
131
+ */
132
+ async function _BaseApiClient_fetchBearerToken() {
133
+ const { getBearerToken } = this;
134
+ if (!getBearerToken) {
135
+ return undefined;
136
+ }
137
+ // fetchQuery de-duplicates concurrent callers. staleTime is 0 so we do not
138
+ // cache the JWT here — AuthenticationController already owns token lifetime.
139
+ const tokenPromise = __classPrivateFieldGet(this, _BaseApiClient_queryClientInstance, "f")
140
+ .fetchQuery({
141
+ queryKey: authQueryKeys.bearerToken(),
142
+ queryFn: async () => {
143
+ const result = await getBearerToken();
144
+ // Throw if no token - prevents caching null/undefined
145
+ // so subsequent requests can retry (e.g., after user logs in)
146
+ if (!result) {
147
+ throw new Error('No bearer token available');
148
+ }
149
+ return result;
150
+ },
151
+ staleTime: 0,
152
+ retry: false, // Don't retry auth failures
153
+ })
154
+ .catch(() => undefined);
155
+ if (this.authTokenTimeout <= 0) {
156
+ return await tokenPromise;
157
+ }
158
+ let timeoutId;
159
+ const timeoutPromise = new Promise((resolve) => {
160
+ timeoutId = setTimeout(() => resolve(undefined), this.authTokenTimeout);
161
+ });
162
+ try {
163
+ return await Promise.race([tokenPromise, timeoutPromise]);
164
+ }
165
+ finally {
166
+ clearTimeout(timeoutId);
167
+ }
168
+ };
143
169
  // Re-export constants for use by API clients
144
170
  export { API_URLS, STALE_TIMES, GC_TIMES, HttpError };
145
171
  //# sourceMappingURL=base-client.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-client.mjs","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Base API Client - Shared HTTP functionality for all API clients.\n */\n\nimport { QueryClient } from '@tanstack/query-core';\nimport type { QueryKey } from '@tanstack/query-core';\n\nimport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n calculateRetryDelay,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\nimport type { ApiPlatformClientOptions } from './shared-types.js';\n\n// Auth query keys - shared for token management across clients\nexport const authQueryKeys = {\n bearerToken: (): QueryKey => ['auth', 'bearerToken'],\n} as const;\n\nexport type { ApiPlatformClientOptions };\n\n/**\n * Internal fetch options for HTTP requests.\n */\nexport type InternalFetchOptions = {\n signal?: AbortSignal;\n params?: Record<\n string,\n string | string[] | number | number[] | boolean | undefined\n >;\n};\n\n/**\n * Base API Client with shared HTTP and caching functionality.\n * Extended by all specific API clients.\n */\nexport class BaseApiClient {\n protected readonly clientProduct: string;\n\n protected readonly clientVersion?: string;\n\n protected readonly getBearerToken?: () => Promise<string | undefined>;\n\n readonly #queryClientInstance: QueryClient;\n\n /**\n * Get the underlying QueryClient instance.\n * Exposed for cache management operations.\n *\n * @returns The QueryClient instance.\n */\n get queryClient(): QueryClient {\n return this.#queryClientInstance;\n }\n\n /**\n * Invalidate the cached auth token.\n * Call this when the user logs out or the token expires.\n *\n * Uses resetQueries() instead of invalidateQueries() to completely remove\n * the cached value, ensuring the next request fetches a fresh token immediately.\n */\n async invalidateAuthToken(): Promise<void> {\n await this.#queryClientInstance.resetQueries({\n queryKey: authQueryKeys.bearerToken(),\n });\n }\n\n constructor(options: ApiPlatformClientOptions) {\n this.clientProduct = options.clientProduct;\n this.clientVersion = options.clientVersion;\n this.getBearerToken = options.getBearerToken;\n\n this.#queryClientInstance =\n options.queryClient ??\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: STALE_TIMES.DEFAULT,\n gcTime: GC_TIMES.DEFAULT,\n retry: shouldRetry,\n retryDelay: calculateRetryDelay,\n refetchOnWindowFocus: false,\n networkMode: 'always',\n },\n },\n });\n }\n\n /**\n * Internal HTTP fetch method with authentication and error handling.\n *\n * @param baseUrl - The base URL for the API.\n * @param path - The API endpoint path.\n * @param options - Optional fetch configuration.\n * @returns The parsed JSON response.\n */\n protected async fetch<ResponseType>(\n baseUrl: string,\n path: string,\n options?: InternalFetchOptions,\n ): Promise<ResponseType> {\n const url = new URL(path, baseUrl);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value === undefined) {\n continue;\n }\n if (Array.isArray(value)) {\n // Convert array values (including number[]) to comma-separated string\n url.searchParams.set(key, value.map(String).join(','));\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-metamask-clientproduct': this.clientProduct,\n };\n\n if (this.clientVersion) {\n headers['x-metamask-clientversion'] = this.clientVersion;\n }\n\n // Get bearer token using fetchQuery for automatic deduplication\n if (this.getBearerToken) {\n const queryKey = authQueryKeys.bearerToken();\n const { getBearerToken } = this;\n\n try {\n // fetchQuery handles caching and deduplicates concurrent requests\n const token = await this.#queryClientInstance.fetchQuery({\n queryKey,\n queryFn: async () => {\n const result = await getBearerToken();\n // Throw if no token - prevents caching null/undefined\n // so subsequent requests can retry (e.g., after user logs in)\n if (!result) {\n throw new Error('No bearer token available');\n }\n return result;\n },\n staleTime: STALE_TIMES.AUTH_TOKEN,\n retry: false, // Don't retry auth failures\n });\n\n headers.Authorization = `Bearer ${token}`;\n } catch {\n // No token available - continue without auth header\n }\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers,\n signal: options?.signal,\n });\n\n if (!response.ok) {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n // Response body is not JSON or is empty, leave body as undefined\n }\n throw new HttpError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n url.toString(),\n body,\n );\n }\n\n return response.json() as Promise<ResponseType>;\n }\n}\n\n// Re-export constants for use by API clients\nexport { API_URLS, STALE_TIMES, GC_TIMES, HttpError };\n"]}
1
+ {"version":3,"file":"base-client.mjs","sourceRoot":"","sources":["../../src/api/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Base API Client - Shared HTTP functionality for all API clients.\n */\n\nimport { QueryClient } from '@tanstack/query-core';\nimport type { QueryKey } from '@tanstack/query-core';\n\nimport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n DEFAULT_AUTH_TOKEN_TIMEOUT,\n calculateRetryDelay,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\nimport type { ApiPlatformClientOptions } from './shared-types.js';\n\n// Auth query keys - shared for token management across clients\nexport const authQueryKeys = {\n bearerToken: (): QueryKey => ['auth', 'bearerToken'],\n} as const;\n\nexport type { ApiPlatformClientOptions };\n\n/**\n * Internal fetch options for HTTP requests.\n */\nexport type InternalFetchOptions = {\n signal?: AbortSignal;\n params?: Record<\n string,\n string | string[] | number | number[] | boolean | undefined\n >;\n};\n\n/**\n * Base API Client with shared HTTP and caching functionality.\n * Extended by all specific API clients.\n */\nexport class BaseApiClient {\n protected readonly clientProduct: string;\n\n protected readonly clientVersion?: string;\n\n protected readonly getBearerToken?: () => Promise<string | undefined>;\n\n protected readonly authTokenTimeout: number;\n\n readonly #queryClientInstance: QueryClient;\n\n /**\n * Get the underlying QueryClient instance.\n * Exposed for cache management operations.\n *\n * @returns The QueryClient instance.\n */\n get queryClient(): QueryClient {\n return this.#queryClientInstance;\n }\n\n /**\n * Invalidate the cached auth token.\n * Call this when the user logs out or the token expires.\n *\n * Uses resetQueries() instead of invalidateQueries() to completely remove\n * the cached value, ensuring the next request fetches a fresh token immediately.\n */\n async invalidateAuthToken(): Promise<void> {\n await this.#queryClientInstance.resetQueries({\n queryKey: authQueryKeys.bearerToken(),\n });\n }\n\n constructor(options: ApiPlatformClientOptions) {\n this.clientProduct = options.clientProduct;\n this.clientVersion = options.clientVersion;\n this.getBearerToken = options.getBearerToken;\n this.authTokenTimeout =\n options.authTokenTimeout ?? DEFAULT_AUTH_TOKEN_TIMEOUT;\n\n this.#queryClientInstance =\n options.queryClient ??\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: STALE_TIMES.DEFAULT,\n gcTime: GC_TIMES.DEFAULT,\n retry: shouldRetry,\n retryDelay: calculateRetryDelay,\n refetchOnWindowFocus: false,\n networkMode: 'always',\n },\n },\n });\n }\n\n /**\n * Resolve the bearer token, giving up after `authTokenTimeout` so that a slow\n * token provider does not delay the request. When the wait times out the\n * request goes out unauthenticated (lower rate limit) while the in-flight\n * `fetchQuery` keeps resolving `getBearerToken` for later requests.\n *\n * @returns The bearer token, or undefined if unavailable in time.\n */\n async #fetchBearerToken(): Promise<string | undefined> {\n const { getBearerToken } = this;\n if (!getBearerToken) {\n return undefined;\n }\n\n // fetchQuery de-duplicates concurrent callers. staleTime is 0 so we do not\n // cache the JWT here — AuthenticationController already owns token lifetime.\n const tokenPromise = this.#queryClientInstance\n .fetchQuery({\n queryKey: authQueryKeys.bearerToken(),\n queryFn: async () => {\n const result = await getBearerToken();\n // Throw if no token - prevents caching null/undefined\n // so subsequent requests can retry (e.g., after user logs in)\n if (!result) {\n throw new Error('No bearer token available');\n }\n return result;\n },\n staleTime: 0,\n retry: false, // Don't retry auth failures\n })\n .catch(() => undefined);\n\n if (this.authTokenTimeout <= 0) {\n return await tokenPromise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<undefined>((resolve) => {\n timeoutId = setTimeout(() => resolve(undefined), this.authTokenTimeout);\n });\n\n try {\n return await Promise.race([tokenPromise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Internal HTTP fetch method with authentication and error handling.\n *\n * @param baseUrl - The base URL for the API.\n * @param path - The API endpoint path.\n * @param options - Optional fetch configuration.\n * @returns The parsed JSON response.\n */\n protected async fetch<ResponseType>(\n baseUrl: string,\n path: string,\n options?: InternalFetchOptions,\n ): Promise<ResponseType> {\n const url = new URL(path, baseUrl);\n\n if (options?.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value === undefined) {\n continue;\n }\n if (Array.isArray(value)) {\n // Convert array values (including number[]) to comma-separated string\n url.searchParams.set(key, value.map(String).join(','));\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-metamask-clientproduct': this.clientProduct,\n };\n\n if (this.clientVersion) {\n headers['x-metamask-clientversion'] = this.clientVersion;\n }\n\n const token = await this.#fetchBearerToken();\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers,\n signal: options?.signal,\n });\n\n if (!response.ok) {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n // Response body is not JSON or is empty, leave body as undefined\n }\n throw new HttpError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n url.toString(),\n body,\n );\n }\n\n return response.json() as Promise<ResponseType>;\n }\n}\n\n// Re-export constants for use by API clients\nexport { API_URLS, STALE_TIMES, GC_TIMES, HttpError };\n"]}
@@ -4,11 +4,12 @@
4
4
  * Re-exports all types and clients from the API folder.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.createApiPlatformClient = exports.ApiPlatformClient = exports.BaseApiClient = exports.TokensApiClient = exports.TokenApiClient = exports.PricesApiClient = exports.V6_DEFI_POSITION_TYPES = exports.AccountsApiClient = exports.HttpError = exports.shouldRetry = exports.getQueryOptionsOverrides = exports.calculateRetryDelay = exports.RETRY_CONFIG = exports.GC_TIMES = exports.STALE_TIMES = exports.API_URLS = void 0;
7
+ exports.createApiPlatformClient = exports.ApiPlatformClient = exports.BaseApiClient = exports.TokensApiClient = exports.TokenApiClient = exports.PricesApiClient = exports.V6_DEFI_POSITION_TYPES = exports.AccountsApiClient = exports.HttpError = exports.shouldRetry = exports.getQueryOptionsOverrides = exports.calculateRetryDelay = exports.RETRY_CONFIG = exports.DEFAULT_AUTH_TOKEN_TIMEOUT = exports.GC_TIMES = exports.STALE_TIMES = exports.API_URLS = void 0;
8
8
  var shared_types_js_1 = require("./shared-types.cjs");
9
9
  Object.defineProperty(exports, "API_URLS", { enumerable: true, get: function () { return shared_types_js_1.API_URLS; } });
10
10
  Object.defineProperty(exports, "STALE_TIMES", { enumerable: true, get: function () { return shared_types_js_1.STALE_TIMES; } });
11
11
  Object.defineProperty(exports, "GC_TIMES", { enumerable: true, get: function () { return shared_types_js_1.GC_TIMES; } });
12
+ Object.defineProperty(exports, "DEFAULT_AUTH_TOKEN_TIMEOUT", { enumerable: true, get: function () { return shared_types_js_1.DEFAULT_AUTH_TOKEN_TIMEOUT; } });
12
13
  Object.defineProperty(exports, "RETRY_CONFIG", { enumerable: true, get: function () { return shared_types_js_1.RETRY_CONFIG; } });
13
14
  Object.defineProperty(exports, "calculateRetryDelay", { enumerable: true, get: function () { return shared_types_js_1.calculateRetryDelay; } });
14
15
  Object.defineProperty(exports, "getQueryOptionsOverrides", { enumerable: true, get: function () { return shared_types_js_1.getQueryOptionsOverrides; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAUH,sDAS2B;AARzB,2GAAA,QAAQ,OAAA;AACR,8GAAA,WAAW,OAAA;AACX,2GAAA,QAAQ,OAAA;AACR,+GAAA,YAAY,OAAA;AACZ,sHAAA,mBAAmB,OAAA;AACnB,2HAAA,wBAAwB,OAAA;AACxB,8GAAA,WAAW,OAAA;AACX,4GAAA,SAAS,OAAA;AAGX,eAAe;AACf,iDAAgF;AAAvE,6GAAA,iBAAiB,OAAA;AAAE,kHAAA,sBAAsB,OAAA;AA2BlD,aAAa;AACb,+CAAoD;AAA3C,2GAAA,eAAe,OAAA;AAWxB,YAAY;AACZ,8CAAkD;AAAzC,0GAAA,cAAc,OAAA;AAavB,aAAa;AACb,+CAAoD;AAA3C,2GAAA,eAAe,OAAA;AAOxB,cAAc;AACd,oDAAiD;AAAxC,+GAAA,aAAa,OAAA;AAGtB,uCAAuC;AACvC,gEAGgC;AAF9B,yHAAA,iBAAiB,OAAA;AACjB,+HAAA,uBAAuB,OAAA","sourcesContent":["/**\n * API barrel export.\n * Re-exports all types and clients from the API folder.\n */\n\n// Shared types and utilities\nexport type {\n PageInfo,\n SupportedCurrency,\n MarketDataDetails,\n ApiPlatformClientOptions,\n FetchOptions,\n} from './shared-types.js';\nexport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n RETRY_CONFIG,\n calculateRetryDelay,\n getQueryOptionsOverrides,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\n\n// Accounts API\nexport { AccountsApiClient, V6_DEFI_POSITION_TYPES } from './accounts/index.js';\nexport type {\n V5BalanceItem,\n V5BalancesResponse,\n V2BalanceItem,\n V2BalancesResponse,\n V4BalancesResponse,\n V6VsCurrency,\n V6DeFiPositionType,\n V6BalanceMetadata,\n V6TokenMetadata,\n V6BalanceItem,\n V6BalancesResponse,\n V1SupportedNetworksResponse,\n V2SupportedNetworksResponse,\n V2ActiveNetworksResponse,\n V1TransactionByHashResponse,\n V1AccountTransactionsResponse,\n V4MultiAccountTransactionsResponse,\n ValueTransfer,\n V1AccountRelationshipResult,\n NftItem,\n V2NftsResponse,\n TokenDiscoveryItem,\n V2TokensResponse,\n} from './accounts/index.js';\n\n// Prices API\nexport { PricesApiClient } from './prices/index.js';\nexport type {\n V3SpotPricesResponse,\n CoinGeckoSpotPrice,\n ExchangeRateInfo,\n V1ExchangeRatesResponse,\n PriceSupportedNetworksResponse,\n V1HistoricalPricesResponse,\n V3HistoricalPricesResponse,\n} from './prices/index.js';\n\n// Token API\nexport { TokenApiClient } from './token/index.js';\nexport type {\n TokenMetadata,\n V1TokenDescriptionResponse,\n NetworkInfo,\n TopAsset,\n TrendingSortBy,\n TrendingToken,\n TopGainersSortOption,\n TrendingSortOption,\n V1SuggestedOccurrenceFloorsResponse,\n} from './token/index.js';\n\n// Tokens API\nexport { TokensApiClient } from './tokens/index.js';\nexport type {\n V1TokenSupportedNetworksResponse,\n V2TokenSupportedNetworksResponse,\n V3AssetResponse,\n} from './tokens/index.js';\n\n// Base client\nexport { BaseApiClient } from './base-client.js';\nexport type { InternalFetchOptions } from './base-client.js';\n\n// API Platform Client (unified client)\nexport {\n ApiPlatformClient,\n createApiPlatformClient,\n} from './ApiPlatformClient.js';\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAUH,sDAU2B;AATzB,2GAAA,QAAQ,OAAA;AACR,8GAAA,WAAW,OAAA;AACX,2GAAA,QAAQ,OAAA;AACR,6HAAA,0BAA0B,OAAA;AAC1B,+GAAA,YAAY,OAAA;AACZ,sHAAA,mBAAmB,OAAA;AACnB,2HAAA,wBAAwB,OAAA;AACxB,8GAAA,WAAW,OAAA;AACX,4GAAA,SAAS,OAAA;AAGX,eAAe;AACf,iDAAgF;AAAvE,6GAAA,iBAAiB,OAAA;AAAE,kHAAA,sBAAsB,OAAA;AA2BlD,aAAa;AACb,+CAAoD;AAA3C,2GAAA,eAAe,OAAA;AAWxB,YAAY;AACZ,8CAAkD;AAAzC,0GAAA,cAAc,OAAA;AAavB,aAAa;AACb,+CAAoD;AAA3C,2GAAA,eAAe,OAAA;AAOxB,cAAc;AACd,oDAAiD;AAAxC,+GAAA,aAAa,OAAA;AAGtB,uCAAuC;AACvC,gEAGgC;AAF9B,yHAAA,iBAAiB,OAAA;AACjB,+HAAA,uBAAuB,OAAA","sourcesContent":["/**\n * API barrel export.\n * Re-exports all types and clients from the API folder.\n */\n\n// Shared types and utilities\nexport type {\n PageInfo,\n SupportedCurrency,\n MarketDataDetails,\n ApiPlatformClientOptions,\n FetchOptions,\n} from './shared-types.js';\nexport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n DEFAULT_AUTH_TOKEN_TIMEOUT,\n RETRY_CONFIG,\n calculateRetryDelay,\n getQueryOptionsOverrides,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\n\n// Accounts API\nexport { AccountsApiClient, V6_DEFI_POSITION_TYPES } from './accounts/index.js';\nexport type {\n V5BalanceItem,\n V5BalancesResponse,\n V2BalanceItem,\n V2BalancesResponse,\n V4BalancesResponse,\n V6VsCurrency,\n V6DeFiPositionType,\n V6BalanceMetadata,\n V6TokenMetadata,\n V6BalanceItem,\n V6BalancesResponse,\n V1SupportedNetworksResponse,\n V2SupportedNetworksResponse,\n V2ActiveNetworksResponse,\n V1TransactionByHashResponse,\n V1AccountTransactionsResponse,\n V4MultiAccountTransactionsResponse,\n ValueTransfer,\n V1AccountRelationshipResult,\n NftItem,\n V2NftsResponse,\n TokenDiscoveryItem,\n V2TokensResponse,\n} from './accounts/index.js';\n\n// Prices API\nexport { PricesApiClient } from './prices/index.js';\nexport type {\n V3SpotPricesResponse,\n CoinGeckoSpotPrice,\n ExchangeRateInfo,\n V1ExchangeRatesResponse,\n PriceSupportedNetworksResponse,\n V1HistoricalPricesResponse,\n V3HistoricalPricesResponse,\n} from './prices/index.js';\n\n// Token API\nexport { TokenApiClient } from './token/index.js';\nexport type {\n TokenMetadata,\n V1TokenDescriptionResponse,\n NetworkInfo,\n TopAsset,\n TrendingSortBy,\n TrendingToken,\n TopGainersSortOption,\n TrendingSortOption,\n V1SuggestedOccurrenceFloorsResponse,\n} from './token/index.js';\n\n// Tokens API\nexport { TokensApiClient } from './tokens/index.js';\nexport type {\n V1TokenSupportedNetworksResponse,\n V2TokenSupportedNetworksResponse,\n V3AssetResponse,\n} from './tokens/index.js';\n\n// Base client\nexport { BaseApiClient } from './base-client.js';\nexport type { InternalFetchOptions } from './base-client.js';\n\n// API Platform Client (unified client)\nexport {\n ApiPlatformClient,\n createApiPlatformClient,\n} from './ApiPlatformClient.js';\n"]}
@@ -3,7 +3,7 @@
3
3
  * Re-exports all types and clients from the API folder.
4
4
  */
5
5
  export type { PageInfo, SupportedCurrency, MarketDataDetails, ApiPlatformClientOptions, FetchOptions, } from "./shared-types.cjs";
6
- export { API_URLS, STALE_TIMES, GC_TIMES, RETRY_CONFIG, calculateRetryDelay, getQueryOptionsOverrides, shouldRetry, HttpError, } from "./shared-types.cjs";
6
+ export { API_URLS, STALE_TIMES, GC_TIMES, DEFAULT_AUTH_TOKEN_TIMEOUT, RETRY_CONFIG, calculateRetryDelay, getQueryOptionsOverrides, shouldRetry, HttpError, } from "./shared-types.cjs";
7
7
  export { AccountsApiClient, V6_DEFI_POSITION_TYPES } from "./accounts/index.cjs";
8
8
  export type { V5BalanceItem, V5BalancesResponse, V2BalanceItem, V2BalancesResponse, V4BalancesResponse, V6VsCurrency, V6DeFiPositionType, V6BalanceMetadata, V6TokenMetadata, V6BalanceItem, V6BalancesResponse, V1SupportedNetworksResponse, V2SupportedNetworksResponse, V2ActiveNetworksResponse, V1TransactionByHashResponse, V1AccountTransactionsResponse, V4MultiAccountTransactionsResponse, ValueTransfer, V1AccountRelationshipResult, NftItem, V2NftsResponse, TokenDiscoveryItem, V2TokensResponse, } from "./accounts/index.cjs";
9
9
  export { PricesApiClient } from "./prices/index.cjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,GACb,2BAA0B;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,SAAS,GACV,2BAA0B;AAG3B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,6BAA4B;AAChF,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,6BAA6B,EAC7B,kCAAkC,EAClC,aAAa,EACb,2BAA2B,EAC3B,OAAO,EACP,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,6BAA4B;AAG7B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,0BAA0B,GAC3B,2BAA0B;AAG3B,OAAO,EAAE,cAAc,EAAE,0BAAyB;AAClD,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,WAAW,EACX,QAAQ,EACR,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,mCAAmC,GACpC,0BAAyB;AAG1B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,gCAAgC,EAChC,gCAAgC,EAChC,eAAe,GAChB,2BAA0B;AAG3B,OAAO,EAAE,aAAa,EAAE,0BAAyB;AACjD,YAAY,EAAE,oBAAoB,EAAE,0BAAyB;AAG7D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,gCAA+B"}
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,GACb,2BAA0B;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,0BAA0B,EAC1B,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,SAAS,GACV,2BAA0B;AAG3B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,6BAA4B;AAChF,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,6BAA6B,EAC7B,kCAAkC,EAClC,aAAa,EACb,2BAA2B,EAC3B,OAAO,EACP,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,6BAA4B;AAG7B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,0BAA0B,GAC3B,2BAA0B;AAG3B,OAAO,EAAE,cAAc,EAAE,0BAAyB;AAClD,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,WAAW,EACX,QAAQ,EACR,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,mCAAmC,GACpC,0BAAyB;AAG1B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,gCAAgC,EAChC,gCAAgC,EAChC,eAAe,GAChB,2BAA0B;AAG3B,OAAO,EAAE,aAAa,EAAE,0BAAyB;AACjD,YAAY,EAAE,oBAAoB,EAAE,0BAAyB;AAG7D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,gCAA+B"}
@@ -3,7 +3,7 @@
3
3
  * Re-exports all types and clients from the API folder.
4
4
  */
5
5
  export type { PageInfo, SupportedCurrency, MarketDataDetails, ApiPlatformClientOptions, FetchOptions, } from "./shared-types.mjs";
6
- export { API_URLS, STALE_TIMES, GC_TIMES, RETRY_CONFIG, calculateRetryDelay, getQueryOptionsOverrides, shouldRetry, HttpError, } from "./shared-types.mjs";
6
+ export { API_URLS, STALE_TIMES, GC_TIMES, DEFAULT_AUTH_TOKEN_TIMEOUT, RETRY_CONFIG, calculateRetryDelay, getQueryOptionsOverrides, shouldRetry, HttpError, } from "./shared-types.mjs";
7
7
  export { AccountsApiClient, V6_DEFI_POSITION_TYPES } from "./accounts/index.mjs";
8
8
  export type { V5BalanceItem, V5BalancesResponse, V2BalanceItem, V2BalancesResponse, V4BalancesResponse, V6VsCurrency, V6DeFiPositionType, V6BalanceMetadata, V6TokenMetadata, V6BalanceItem, V6BalancesResponse, V1SupportedNetworksResponse, V2SupportedNetworksResponse, V2ActiveNetworksResponse, V1TransactionByHashResponse, V1AccountTransactionsResponse, V4MultiAccountTransactionsResponse, ValueTransfer, V1AccountRelationshipResult, NftItem, V2NftsResponse, TokenDiscoveryItem, V2TokensResponse, } from "./accounts/index.mjs";
9
9
  export { PricesApiClient } from "./prices/index.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,GACb,2BAA0B;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,SAAS,GACV,2BAA0B;AAG3B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,6BAA4B;AAChF,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,6BAA6B,EAC7B,kCAAkC,EAClC,aAAa,EACb,2BAA2B,EAC3B,OAAO,EACP,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,6BAA4B;AAG7B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,0BAA0B,GAC3B,2BAA0B;AAG3B,OAAO,EAAE,cAAc,EAAE,0BAAyB;AAClD,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,WAAW,EACX,QAAQ,EACR,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,mCAAmC,GACpC,0BAAyB;AAG1B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,gCAAgC,EAChC,gCAAgC,EAChC,eAAe,GAChB,2BAA0B;AAG3B,OAAO,EAAE,aAAa,EAAE,0BAAyB;AACjD,YAAY,EAAE,oBAAoB,EAAE,0BAAyB;AAG7D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,gCAA+B"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,GACb,2BAA0B;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,0BAA0B,EAC1B,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,SAAS,GACV,2BAA0B;AAG3B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,6BAA4B;AAChF,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,6BAA6B,EAC7B,kCAAkC,EAClC,aAAa,EACb,2BAA2B,EAC3B,OAAO,EACP,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,6BAA4B;AAG7B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,0BAA0B,GAC3B,2BAA0B;AAG3B,OAAO,EAAE,cAAc,EAAE,0BAAyB;AAClD,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,WAAW,EACX,QAAQ,EACR,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,mCAAmC,GACpC,0BAAyB;AAG1B,OAAO,EAAE,eAAe,EAAE,2BAA0B;AACpD,YAAY,EACV,gCAAgC,EAChC,gCAAgC,EAChC,eAAe,GAChB,2BAA0B;AAG3B,OAAO,EAAE,aAAa,EAAE,0BAAyB;AACjD,YAAY,EAAE,oBAAoB,EAAE,0BAAyB;AAG7D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,gCAA+B"}
@@ -2,7 +2,7 @@
2
2
  * API barrel export.
3
3
  * Re-exports all types and clients from the API folder.
4
4
  */
5
- export { API_URLS, STALE_TIMES, GC_TIMES, RETRY_CONFIG, calculateRetryDelay, getQueryOptionsOverrides, shouldRetry, HttpError } from "./shared-types.mjs";
5
+ export { API_URLS, STALE_TIMES, GC_TIMES, DEFAULT_AUTH_TOKEN_TIMEOUT, RETRY_CONFIG, calculateRetryDelay, getQueryOptionsOverrides, shouldRetry, HttpError } from "./shared-types.mjs";
6
6
  // Accounts API
7
7
  export { AccountsApiClient, V6_DEFI_POSITION_TYPES } from "./accounts/index.mjs";
8
8
  // Prices API
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,SAAS,EACV,2BAA0B;AAE3B,eAAe;AACf,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,6BAA4B;AA2BhF,aAAa;AACb,OAAO,EAAE,eAAe,EAAE,2BAA0B;AAWpD,YAAY;AACZ,OAAO,EAAE,cAAc,EAAE,0BAAyB;AAalD,aAAa;AACb,OAAO,EAAE,eAAe,EAAE,2BAA0B;AAOpD,cAAc;AACd,OAAO,EAAE,aAAa,EAAE,0BAAyB;AAGjD,uCAAuC;AACvC,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACxB,gCAA+B","sourcesContent":["/**\n * API barrel export.\n * Re-exports all types and clients from the API folder.\n */\n\n// Shared types and utilities\nexport type {\n PageInfo,\n SupportedCurrency,\n MarketDataDetails,\n ApiPlatformClientOptions,\n FetchOptions,\n} from './shared-types.js';\nexport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n RETRY_CONFIG,\n calculateRetryDelay,\n getQueryOptionsOverrides,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\n\n// Accounts API\nexport { AccountsApiClient, V6_DEFI_POSITION_TYPES } from './accounts/index.js';\nexport type {\n V5BalanceItem,\n V5BalancesResponse,\n V2BalanceItem,\n V2BalancesResponse,\n V4BalancesResponse,\n V6VsCurrency,\n V6DeFiPositionType,\n V6BalanceMetadata,\n V6TokenMetadata,\n V6BalanceItem,\n V6BalancesResponse,\n V1SupportedNetworksResponse,\n V2SupportedNetworksResponse,\n V2ActiveNetworksResponse,\n V1TransactionByHashResponse,\n V1AccountTransactionsResponse,\n V4MultiAccountTransactionsResponse,\n ValueTransfer,\n V1AccountRelationshipResult,\n NftItem,\n V2NftsResponse,\n TokenDiscoveryItem,\n V2TokensResponse,\n} from './accounts/index.js';\n\n// Prices API\nexport { PricesApiClient } from './prices/index.js';\nexport type {\n V3SpotPricesResponse,\n CoinGeckoSpotPrice,\n ExchangeRateInfo,\n V1ExchangeRatesResponse,\n PriceSupportedNetworksResponse,\n V1HistoricalPricesResponse,\n V3HistoricalPricesResponse,\n} from './prices/index.js';\n\n// Token API\nexport { TokenApiClient } from './token/index.js';\nexport type {\n TokenMetadata,\n V1TokenDescriptionResponse,\n NetworkInfo,\n TopAsset,\n TrendingSortBy,\n TrendingToken,\n TopGainersSortOption,\n TrendingSortOption,\n V1SuggestedOccurrenceFloorsResponse,\n} from './token/index.js';\n\n// Tokens API\nexport { TokensApiClient } from './tokens/index.js';\nexport type {\n V1TokenSupportedNetworksResponse,\n V2TokenSupportedNetworksResponse,\n V3AssetResponse,\n} from './tokens/index.js';\n\n// Base client\nexport { BaseApiClient } from './base-client.js';\nexport type { InternalFetchOptions } from './base-client.js';\n\n// API Platform Client (unified client)\nexport {\n ApiPlatformClient,\n createApiPlatformClient,\n} from './ApiPlatformClient.js';\n"]}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,0BAA0B,EAC1B,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,SAAS,EACV,2BAA0B;AAE3B,eAAe;AACf,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,6BAA4B;AA2BhF,aAAa;AACb,OAAO,EAAE,eAAe,EAAE,2BAA0B;AAWpD,YAAY;AACZ,OAAO,EAAE,cAAc,EAAE,0BAAyB;AAalD,aAAa;AACb,OAAO,EAAE,eAAe,EAAE,2BAA0B;AAOpD,cAAc;AACd,OAAO,EAAE,aAAa,EAAE,0BAAyB;AAGjD,uCAAuC;AACvC,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACxB,gCAA+B","sourcesContent":["/**\n * API barrel export.\n * Re-exports all types and clients from the API folder.\n */\n\n// Shared types and utilities\nexport type {\n PageInfo,\n SupportedCurrency,\n MarketDataDetails,\n ApiPlatformClientOptions,\n FetchOptions,\n} from './shared-types.js';\nexport {\n API_URLS,\n STALE_TIMES,\n GC_TIMES,\n DEFAULT_AUTH_TOKEN_TIMEOUT,\n RETRY_CONFIG,\n calculateRetryDelay,\n getQueryOptionsOverrides,\n shouldRetry,\n HttpError,\n} from './shared-types.js';\n\n// Accounts API\nexport { AccountsApiClient, V6_DEFI_POSITION_TYPES } from './accounts/index.js';\nexport type {\n V5BalanceItem,\n V5BalancesResponse,\n V2BalanceItem,\n V2BalancesResponse,\n V4BalancesResponse,\n V6VsCurrency,\n V6DeFiPositionType,\n V6BalanceMetadata,\n V6TokenMetadata,\n V6BalanceItem,\n V6BalancesResponse,\n V1SupportedNetworksResponse,\n V2SupportedNetworksResponse,\n V2ActiveNetworksResponse,\n V1TransactionByHashResponse,\n V1AccountTransactionsResponse,\n V4MultiAccountTransactionsResponse,\n ValueTransfer,\n V1AccountRelationshipResult,\n NftItem,\n V2NftsResponse,\n TokenDiscoveryItem,\n V2TokensResponse,\n} from './accounts/index.js';\n\n// Prices API\nexport { PricesApiClient } from './prices/index.js';\nexport type {\n V3SpotPricesResponse,\n CoinGeckoSpotPrice,\n ExchangeRateInfo,\n V1ExchangeRatesResponse,\n PriceSupportedNetworksResponse,\n V1HistoricalPricesResponse,\n V3HistoricalPricesResponse,\n} from './prices/index.js';\n\n// Token API\nexport { TokenApiClient } from './token/index.js';\nexport type {\n TokenMetadata,\n V1TokenDescriptionResponse,\n NetworkInfo,\n TopAsset,\n TrendingSortBy,\n TrendingToken,\n TopGainersSortOption,\n TrendingSortOption,\n V1SuggestedOccurrenceFloorsResponse,\n} from './token/index.js';\n\n// Tokens API\nexport { TokensApiClient } from './tokens/index.js';\nexport type {\n V1TokenSupportedNetworksResponse,\n V2TokenSupportedNetworksResponse,\n V3AssetResponse,\n} from './tokens/index.js';\n\n// Base client\nexport { BaseApiClient } from './base-client.js';\nexport type { InternalFetchOptions } from './base-client.js';\n\n// API Platform Client (unified client)\nexport {\n ApiPlatformClient,\n createApiPlatformClient,\n} from './ApiPlatformClient.js';\n"]}
@@ -3,7 +3,7 @@
3
3
  * Shared types, constants, and utilities for the API Platform Client.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.HttpError = exports.shouldRetry = exports.calculateRetryDelay = exports.RETRY_CONFIG = exports.GC_TIMES = exports.STALE_TIMES = exports.API_URLS = exports.getQueryOptionsOverrides = void 0;
6
+ exports.HttpError = exports.shouldRetry = exports.calculateRetryDelay = exports.RETRY_CONFIG = exports.GC_TIMES = exports.DEFAULT_AUTH_TOKEN_TIMEOUT = exports.STALE_TIMES = exports.API_URLS = exports.getQueryOptionsOverrides = void 0;
7
7
  /**
8
8
  * Returns options with queryKey and queryFn omitted, for merging into
9
9
  * get*QueryOptions return values without overwriting the client's queryKey/queryFn.
@@ -33,7 +33,6 @@ exports.API_URLS = {
33
33
  };
34
34
  /** Stale times for different data types (ms) */
35
35
  exports.STALE_TIMES = {
36
- AUTH_TOKEN: 5 * 60 * 1000, // 5 minutes - cache the auth token
37
36
  PRICES: 30 * 1000, // 30 seconds
38
37
  BALANCES: 60 * 1000, // 1 minute
39
38
  NETWORKS: 10 * 60 * 1000, // 10 minutes
@@ -45,6 +44,11 @@ exports.STALE_TIMES = {
45
44
  TRANSACTIONS: 30 * 1000, // 30 seconds
46
45
  DEFAULT: 30 * 1000, // 30 seconds
47
46
  };
47
+ /**
48
+ * Default max time (ms) to wait for the bearer token before falling back to an
49
+ * unauthenticated request.
50
+ */
51
+ exports.DEFAULT_AUTH_TOKEN_TIMEOUT = 500;
48
52
  /** Garbage collection times (ms) */
49
53
  exports.GC_TIMES = {
50
54
  DEFAULT: 5 * 60 * 1000, // 5 minutes
@@ -1 +1 @@
1
- {"version":3,"file":"shared-types.cjs","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared types, constants, and utilities for the API Platform Client.\n */\n\nimport type { FetchQueryOptions, QueryClient } from '@tanstack/query-core';\n\n// ============================================================================\n// SHARED TYPES\n// ============================================================================\n\n/**\n * Pagination info for paginated responses\n */\nexport type PageInfo = {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n};\n\n/**\n * Supported currencies for Price API\n */\nexport type SupportedCurrency =\n // Crypto\n | 'btc'\n | 'eth'\n | 'ltc'\n | 'bch'\n | 'bnb'\n | 'eos'\n | 'xrp'\n | 'xlm'\n | 'link'\n | 'dot'\n | 'yfi'\n // Fiat\n | 'usd'\n | 'aed'\n | 'ars'\n | 'aud'\n | 'bdt'\n | 'bhd'\n | 'bmd'\n | 'brl'\n | 'cad'\n | 'chf'\n | 'clp'\n | 'cny'\n | 'czk'\n | 'dkk'\n | 'eur'\n | 'gbp'\n | 'gel'\n | 'hkd'\n | 'huf'\n | 'idr'\n | 'ils'\n | 'inr'\n | 'jpy'\n | 'krw'\n | 'kwd'\n | 'lkr'\n | 'mmk'\n | 'mxn'\n | 'myr'\n | 'ngn'\n | 'nok'\n | 'nzd'\n | 'php'\n | 'pkr'\n | 'pln'\n | 'rub'\n | 'sar'\n | 'sek'\n | 'sgd'\n | 'thb'\n | 'try'\n | 'twd'\n | 'uah'\n | 'vef'\n | 'vnd'\n | 'zar';\n\n/**\n * Market data details from Price API spot-prices endpoint\n */\nexport type MarketDataDetails = {\n /** Current price in the requested currency */\n price: number;\n /** Currency code (e.g., 'ETH', 'USD') */\n currency: string;\n /** 24h price change amount */\n priceChange1d: number;\n /** 24h price change percentage */\n pricePercentChange1d: number;\n /** 1h price change percentage */\n pricePercentChange1h: number;\n /** 7d price change percentage */\n pricePercentChange7d: number;\n /** 14d price change percentage */\n pricePercentChange14d: number;\n /** 30d price change percentage */\n pricePercentChange30d: number;\n /** 200d price change percentage */\n pricePercentChange200d: number;\n /** 1y price change percentage */\n pricePercentChange1y: number;\n /** Market capitalization */\n marketCap: number;\n /** Market cap 24h change percentage */\n marketCapPercentChange1d: number;\n /** All-time high price */\n allTimeHigh: number;\n /** All-time low price */\n allTimeLow: number;\n /** 24h high price */\n high1d: number;\n /** 24h low price */\n low1d: number;\n /** Total trading volume */\n totalVolume: number;\n /** Circulating supply */\n circulatingSupply: number;\n /** Diluted market cap */\n dilutedMarketCap: number;\n};\n\n// ============================================================================\n// CLIENT OPTIONS\n// ============================================================================\n\nexport type ApiPlatformClientOptions = {\n /** Client product identifier (e.g., 'metamask-extension') */\n clientProduct: string;\n /** Optional client version */\n clientVersion?: string;\n /** Function to get bearer token for authenticated requests */\n getBearerToken?: () => Promise<string | undefined>;\n /** Optional custom QueryClient instance */\n queryClient?: QueryClient;\n};\n\n/**\n * Options for API fetch and query methods.\n * Extends TanStack Query options (e.g. select, initialPageParam, retry) so callers\n * can pass them through to useQuery / useInfiniteQuery. queryKey and queryFn are\n * always set by the client and cannot be overridden.\n * staleTime and gcTime are explicitly number (not function) so that client defaults apply without type conflicts.\n */\nexport type FetchOptions = {\n /** Custom stale time (ms). */\n staleTime?: number;\n /** Custom GC time (ms). */\n gcTime?: number;\n /**\n * When true, bypass caching for this request: the client-side query cache is\n * skipped (stale time defaults to 0) and, on endpoints that support it, a\n * random `bypassServerCache` query param is appended so server-side HTTP caches\n * (keyed on the full URL) miss. Use sparingly — only when a hard refresh is\n * required, e.g. right after a transaction confirms.\n */\n bypassServerCache?: boolean;\n} & Partial<\n Omit<\n FetchQueryOptions<unknown, Error, unknown>,\n 'queryKey' | 'queryFn' | 'staleTime' | 'gcTime'\n >\n> & {\n /** Allowed for infinite query options (e.g. useInfiniteQuery). */\n initialPageParam?: unknown;\n };\n\n/**\n * Returns options with queryKey and queryFn omitted, for merging into\n * get*QueryOptions return values without overwriting the client's queryKey/queryFn.\n * Return type is intentionally loose so that spreading into FetchQueryOptions<T>\n * does not conflict with T-specific option types (e.g. select, staleTime).\n *\n * @param options - Optional FetchOptions from the caller.\n * @returns Options safe to spread into query options, or undefined.\n */\nexport function getQueryOptionsOverrides(\n options?: FetchOptions,\n): Record<string, unknown> | undefined {\n if (options === null || options === undefined) {\n return undefined;\n }\n const {\n queryKey: _qk,\n queryFn: _qf,\n bypassServerCache: _bc,\n ...rest\n } = options as FetchOptions & {\n queryKey?: unknown;\n queryFn?: unknown;\n };\n return rest as Record<string, unknown>;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** API Base URLs */\nexport const API_URLS = {\n ACCOUNTS: 'https://accounts.api.cx.metamask.io',\n PRICES: 'https://price.api.cx.metamask.io',\n TOKEN: 'https://token.api.cx.metamask.io',\n TOKENS: 'https://tokens.api.cx.metamask.io',\n} as const;\n\n/** Stale times for different data types (ms) */\nexport const STALE_TIMES = {\n AUTH_TOKEN: 5 * 60 * 1000, // 5 minutes - cache the auth token\n PRICES: 30 * 1000, // 30 seconds\n BALANCES: 60 * 1000, // 1 minute\n NETWORKS: 10 * 60 * 1000, // 10 minutes\n SUPPORTED_NETWORKS: 30 * 60 * 1000, // 30 minutes\n TOKEN_METADATA: 5 * 60 * 1000, // 5 minutes\n TOKEN_LIST: 10 * 60 * 1000, // 10 minutes\n EXCHANGE_RATES: 5 * 60 * 1000, // 5 minutes\n TRENDING: 2 * 60 * 1000, // 2 minutes\n TRANSACTIONS: 30 * 1000, // 30 seconds\n DEFAULT: 30 * 1000, // 30 seconds\n} as const;\n\n/** Garbage collection times (ms) */\nexport const GC_TIMES = {\n DEFAULT: 5 * 60 * 1000, // 5 minutes\n EXTENDED: 30 * 60 * 1000, // 30 minutes\n SHORT: 2 * 60 * 1000, // 2 minutes\n} as const;\n\n/** Retry configuration */\nexport const RETRY_CONFIG = {\n MAX_RETRIES: 3,\n BASE_DELAY: 1000,\n MAX_DELAY: 5_000,\n} as const;\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Calculate retry delay with exponential backoff and jitter.\n *\n * @param attemptIndex - The current retry attempt (0-indexed).\n * @returns The delay in milliseconds before the next retry.\n */\nexport function calculateRetryDelay(attemptIndex: number): number {\n const delay = Math.min(\n RETRY_CONFIG.BASE_DELAY * 2 ** attemptIndex,\n RETRY_CONFIG.MAX_DELAY,\n );\n return delay / 2 + Math.random() * (delay / 2);\n}\n\n/**\n * Determine if a failed request should be retried.\n *\n * @param failureCount - The number of failures so far (1 = first failure).\n * @param error - The error from the failed request.\n * @returns True if the request should be retried, false otherwise.\n */\nexport function shouldRetry(failureCount: number, error: unknown): boolean {\n // Allow up to MAX_RETRIES retries (e.g., MAX_RETRIES=3 means 4 total attempts)\n if (failureCount > RETRY_CONFIG.MAX_RETRIES) {\n return false;\n }\n\n if (error instanceof Error && 'status' in error) {\n const { status } = error as { status: number };\n // Don't retry 4xx except 429 (rate limit) and 408 (timeout)\n if (status >= 400 && status < 500 && status !== 429 && status !== 408) {\n return false;\n }\n }\n return true;\n}\n\n// ============================================================================\n// HTTP ERROR\n// ============================================================================\n\nexport class HttpError extends Error {\n readonly status: number;\n\n readonly statusText: string;\n\n readonly url: string;\n\n readonly body: unknown;\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n url: string,\n body?: unknown,\n ) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n this.body = body;\n }\n}\n"]}
1
+ {"version":3,"file":"shared-types.cjs","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared types, constants, and utilities for the API Platform Client.\n */\n\nimport type { FetchQueryOptions, QueryClient } from '@tanstack/query-core';\n\n// ============================================================================\n// SHARED TYPES\n// ============================================================================\n\n/**\n * Pagination info for paginated responses\n */\nexport type PageInfo = {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n};\n\n/**\n * Supported currencies for Price API\n */\nexport type SupportedCurrency =\n // Crypto\n | 'btc'\n | 'eth'\n | 'ltc'\n | 'bch'\n | 'bnb'\n | 'eos'\n | 'xrp'\n | 'xlm'\n | 'link'\n | 'dot'\n | 'yfi'\n // Fiat\n | 'usd'\n | 'aed'\n | 'ars'\n | 'aud'\n | 'bdt'\n | 'bhd'\n | 'bmd'\n | 'brl'\n | 'cad'\n | 'chf'\n | 'clp'\n | 'cny'\n | 'czk'\n | 'dkk'\n | 'eur'\n | 'gbp'\n | 'gel'\n | 'hkd'\n | 'huf'\n | 'idr'\n | 'ils'\n | 'inr'\n | 'jpy'\n | 'krw'\n | 'kwd'\n | 'lkr'\n | 'mmk'\n | 'mxn'\n | 'myr'\n | 'ngn'\n | 'nok'\n | 'nzd'\n | 'php'\n | 'pkr'\n | 'pln'\n | 'rub'\n | 'sar'\n | 'sek'\n | 'sgd'\n | 'thb'\n | 'try'\n | 'twd'\n | 'uah'\n | 'vef'\n | 'vnd'\n | 'zar';\n\n/**\n * Market data details from Price API spot-prices endpoint\n */\nexport type MarketDataDetails = {\n /** Current price in the requested currency */\n price: number;\n /** Currency code (e.g., 'ETH', 'USD') */\n currency: string;\n /** 24h price change amount */\n priceChange1d: number;\n /** 24h price change percentage */\n pricePercentChange1d: number;\n /** 1h price change percentage */\n pricePercentChange1h: number;\n /** 7d price change percentage */\n pricePercentChange7d: number;\n /** 14d price change percentage */\n pricePercentChange14d: number;\n /** 30d price change percentage */\n pricePercentChange30d: number;\n /** 200d price change percentage */\n pricePercentChange200d: number;\n /** 1y price change percentage */\n pricePercentChange1y: number;\n /** Market capitalization */\n marketCap: number;\n /** Market cap 24h change percentage */\n marketCapPercentChange1d: number;\n /** All-time high price */\n allTimeHigh: number;\n /** All-time low price */\n allTimeLow: number;\n /** 24h high price */\n high1d: number;\n /** 24h low price */\n low1d: number;\n /** Total trading volume */\n totalVolume: number;\n /** Circulating supply */\n circulatingSupply: number;\n /** Diluted market cap */\n dilutedMarketCap: number;\n};\n\n// ============================================================================\n// CLIENT OPTIONS\n// ============================================================================\n\nexport type ApiPlatformClientOptions = {\n /** Client product identifier (e.g., 'metamask-extension') */\n clientProduct: string;\n /** Optional client version */\n clientVersion?: string;\n /** Function to get bearer token for authenticated requests */\n getBearerToken?: () => Promise<string | undefined>;\n /**\n * Max time (ms) to wait for `getBearerToken` before sending the request\n * unauthenticated. The token keeps resolving in the background and is used by\n * later requests. Set to `0` to always wait for the token.\n * Defaults to {@link DEFAULT_AUTH_TOKEN_TIMEOUT}.\n */\n authTokenTimeout?: number;\n /** Optional custom QueryClient instance */\n queryClient?: QueryClient;\n};\n\n/**\n * Options for API fetch and query methods.\n * Extends TanStack Query options (e.g. select, initialPageParam, retry) so callers\n * can pass them through to useQuery / useInfiniteQuery. queryKey and queryFn are\n * always set by the client and cannot be overridden.\n * staleTime and gcTime are explicitly number (not function) so that client defaults apply without type conflicts.\n */\nexport type FetchOptions = {\n /** Custom stale time (ms). */\n staleTime?: number;\n /** Custom GC time (ms). */\n gcTime?: number;\n /**\n * When true, bypass caching for this request: the client-side query cache is\n * skipped (stale time defaults to 0) and, on endpoints that support it, a\n * random `bypassServerCache` query param is appended so server-side HTTP caches\n * (keyed on the full URL) miss. Use sparingly — only when a hard refresh is\n * required, e.g. right after a transaction confirms.\n */\n bypassServerCache?: boolean;\n} & Partial<\n Omit<\n FetchQueryOptions<unknown, Error, unknown>,\n 'queryKey' | 'queryFn' | 'staleTime' | 'gcTime'\n >\n> & {\n /** Allowed for infinite query options (e.g. useInfiniteQuery). */\n initialPageParam?: unknown;\n };\n\n/**\n * Returns options with queryKey and queryFn omitted, for merging into\n * get*QueryOptions return values without overwriting the client's queryKey/queryFn.\n * Return type is intentionally loose so that spreading into FetchQueryOptions<T>\n * does not conflict with T-specific option types (e.g. select, staleTime).\n *\n * @param options - Optional FetchOptions from the caller.\n * @returns Options safe to spread into query options, or undefined.\n */\nexport function getQueryOptionsOverrides(\n options?: FetchOptions,\n): Record<string, unknown> | undefined {\n if (options === null || options === undefined) {\n return undefined;\n }\n const {\n queryKey: _qk,\n queryFn: _qf,\n bypassServerCache: _bc,\n ...rest\n } = options as FetchOptions & {\n queryKey?: unknown;\n queryFn?: unknown;\n };\n return rest as Record<string, unknown>;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** API Base URLs */\nexport const API_URLS = {\n ACCOUNTS: 'https://accounts.api.cx.metamask.io',\n PRICES: 'https://price.api.cx.metamask.io',\n TOKEN: 'https://token.api.cx.metamask.io',\n TOKENS: 'https://tokens.api.cx.metamask.io',\n} as const;\n\n/** Stale times for different data types (ms) */\nexport const STALE_TIMES = {\n PRICES: 30 * 1000, // 30 seconds\n BALANCES: 60 * 1000, // 1 minute\n NETWORKS: 10 * 60 * 1000, // 10 minutes\n SUPPORTED_NETWORKS: 30 * 60 * 1000, // 30 minutes\n TOKEN_METADATA: 5 * 60 * 1000, // 5 minutes\n TOKEN_LIST: 10 * 60 * 1000, // 10 minutes\n EXCHANGE_RATES: 5 * 60 * 1000, // 5 minutes\n TRENDING: 2 * 60 * 1000, // 2 minutes\n TRANSACTIONS: 30 * 1000, // 30 seconds\n DEFAULT: 30 * 1000, // 30 seconds\n} as const;\n\n/**\n * Default max time (ms) to wait for the bearer token before falling back to an\n * unauthenticated request.\n */\nexport const DEFAULT_AUTH_TOKEN_TIMEOUT = 500;\n\n/** Garbage collection times (ms) */\nexport const GC_TIMES = {\n DEFAULT: 5 * 60 * 1000, // 5 minutes\n EXTENDED: 30 * 60 * 1000, // 30 minutes\n SHORT: 2 * 60 * 1000, // 2 minutes\n} as const;\n\n/** Retry configuration */\nexport const RETRY_CONFIG = {\n MAX_RETRIES: 3,\n BASE_DELAY: 1000,\n MAX_DELAY: 5_000,\n} as const;\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Calculate retry delay with exponential backoff and jitter.\n *\n * @param attemptIndex - The current retry attempt (0-indexed).\n * @returns The delay in milliseconds before the next retry.\n */\nexport function calculateRetryDelay(attemptIndex: number): number {\n const delay = Math.min(\n RETRY_CONFIG.BASE_DELAY * 2 ** attemptIndex,\n RETRY_CONFIG.MAX_DELAY,\n );\n return delay / 2 + Math.random() * (delay / 2);\n}\n\n/**\n * Determine if a failed request should be retried.\n *\n * @param failureCount - The number of failures so far (1 = first failure).\n * @param error - The error from the failed request.\n * @returns True if the request should be retried, false otherwise.\n */\nexport function shouldRetry(failureCount: number, error: unknown): boolean {\n // Allow up to MAX_RETRIES retries (e.g., MAX_RETRIES=3 means 4 total attempts)\n if (failureCount > RETRY_CONFIG.MAX_RETRIES) {\n return false;\n }\n\n if (error instanceof Error && 'status' in error) {\n const { status } = error as { status: number };\n // Don't retry 4xx except 429 (rate limit) and 408 (timeout)\n if (status >= 400 && status < 500 && status !== 429 && status !== 408) {\n return false;\n }\n }\n return true;\n}\n\n// ============================================================================\n// HTTP ERROR\n// ============================================================================\n\nexport class HttpError extends Error {\n readonly status: number;\n\n readonly statusText: string;\n\n readonly url: string;\n\n readonly body: unknown;\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n url: string,\n body?: unknown,\n ) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n this.body = body;\n }\n}\n"]}
@@ -64,6 +64,13 @@ export type ApiPlatformClientOptions = {
64
64
  clientVersion?: string;
65
65
  /** Function to get bearer token for authenticated requests */
66
66
  getBearerToken?: () => Promise<string | undefined>;
67
+ /**
68
+ * Max time (ms) to wait for `getBearerToken` before sending the request
69
+ * unauthenticated. The token keeps resolving in the background and is used by
70
+ * later requests. Set to `0` to always wait for the token.
71
+ * Defaults to {@link DEFAULT_AUTH_TOKEN_TIMEOUT}.
72
+ */
73
+ authTokenTimeout?: number;
67
74
  /** Optional custom QueryClient instance */
68
75
  queryClient?: QueryClient;
69
76
  };
@@ -110,7 +117,6 @@ export declare const API_URLS: {
110
117
  };
111
118
  /** Stale times for different data types (ms) */
112
119
  export declare const STALE_TIMES: {
113
- readonly AUTH_TOKEN: number;
114
120
  readonly PRICES: number;
115
121
  readonly BALANCES: number;
116
122
  readonly NETWORKS: number;
@@ -122,6 +128,11 @@ export declare const STALE_TIMES: {
122
128
  readonly TRANSACTIONS: number;
123
129
  readonly DEFAULT: number;
124
130
  };
131
+ /**
132
+ * Default max time (ms) to wait for the bearer token before falling back to an
133
+ * unauthenticated request.
134
+ */
135
+ export declare const DEFAULT_AUTH_TOKEN_TIMEOUT = 500;
125
136
  /** Garbage collection times (ms) */
126
137
  export declare const GC_TIMES: {
127
138
  readonly DEFAULT: number;
@@ -1 +1 @@
1
- {"version":3,"file":"shared-types.d.cts","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared-types.d.cts","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"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"}
@@ -64,6 +64,13 @@ export type ApiPlatformClientOptions = {
64
64
  clientVersion?: string;
65
65
  /** Function to get bearer token for authenticated requests */
66
66
  getBearerToken?: () => Promise<string | undefined>;
67
+ /**
68
+ * Max time (ms) to wait for `getBearerToken` before sending the request
69
+ * unauthenticated. The token keeps resolving in the background and is used by
70
+ * later requests. Set to `0` to always wait for the token.
71
+ * Defaults to {@link DEFAULT_AUTH_TOKEN_TIMEOUT}.
72
+ */
73
+ authTokenTimeout?: number;
67
74
  /** Optional custom QueryClient instance */
68
75
  queryClient?: QueryClient;
69
76
  };
@@ -110,7 +117,6 @@ export declare const API_URLS: {
110
117
  };
111
118
  /** Stale times for different data types (ms) */
112
119
  export declare const STALE_TIMES: {
113
- readonly AUTH_TOKEN: number;
114
120
  readonly PRICES: number;
115
121
  readonly BALANCES: number;
116
122
  readonly NETWORKS: number;
@@ -122,6 +128,11 @@ export declare const STALE_TIMES: {
122
128
  readonly TRANSACTIONS: number;
123
129
  readonly DEFAULT: number;
124
130
  };
131
+ /**
132
+ * Default max time (ms) to wait for the bearer token before falling back to an
133
+ * unauthenticated request.
134
+ */
135
+ export declare const DEFAULT_AUTH_TOKEN_TIMEOUT = 500;
125
136
  /** Garbage collection times (ms) */
126
137
  export declare const GC_TIMES: {
127
138
  readonly DEFAULT: number;
@@ -1 +1 @@
1
- {"version":3,"file":"shared-types.d.mts","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared-types.d.mts","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,6 @@ export const API_URLS = {
29
29
  };
30
30
  /** Stale times for different data types (ms) */
31
31
  export const STALE_TIMES = {
32
- AUTH_TOKEN: 5 * 60 * 1000, // 5 minutes - cache the auth token
33
32
  PRICES: 30 * 1000, // 30 seconds
34
33
  BALANCES: 60 * 1000, // 1 minute
35
34
  NETWORKS: 10 * 60 * 1000, // 10 minutes
@@ -41,6 +40,11 @@ export const STALE_TIMES = {
41
40
  TRANSACTIONS: 30 * 1000, // 30 seconds
42
41
  DEFAULT: 30 * 1000, // 30 seconds
43
42
  };
43
+ /**
44
+ * Default max time (ms) to wait for the bearer token before falling back to an
45
+ * unauthenticated request.
46
+ */
47
+ export const DEFAULT_AUTH_TOKEN_TIMEOUT = 500;
44
48
  /** Garbage collection times (ms) */
45
49
  export const GC_TIMES = {
46
50
  DEFAULT: 5 * 60 * 1000, // 5 minutes
@@ -1 +1 @@
1
- {"version":3,"file":"shared-types.mjs","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared types, constants, and utilities for the API Platform Client.\n */\n\nimport type { FetchQueryOptions, QueryClient } from '@tanstack/query-core';\n\n// ============================================================================\n// SHARED TYPES\n// ============================================================================\n\n/**\n * Pagination info for paginated responses\n */\nexport type PageInfo = {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n};\n\n/**\n * Supported currencies for Price API\n */\nexport type SupportedCurrency =\n // Crypto\n | 'btc'\n | 'eth'\n | 'ltc'\n | 'bch'\n | 'bnb'\n | 'eos'\n | 'xrp'\n | 'xlm'\n | 'link'\n | 'dot'\n | 'yfi'\n // Fiat\n | 'usd'\n | 'aed'\n | 'ars'\n | 'aud'\n | 'bdt'\n | 'bhd'\n | 'bmd'\n | 'brl'\n | 'cad'\n | 'chf'\n | 'clp'\n | 'cny'\n | 'czk'\n | 'dkk'\n | 'eur'\n | 'gbp'\n | 'gel'\n | 'hkd'\n | 'huf'\n | 'idr'\n | 'ils'\n | 'inr'\n | 'jpy'\n | 'krw'\n | 'kwd'\n | 'lkr'\n | 'mmk'\n | 'mxn'\n | 'myr'\n | 'ngn'\n | 'nok'\n | 'nzd'\n | 'php'\n | 'pkr'\n | 'pln'\n | 'rub'\n | 'sar'\n | 'sek'\n | 'sgd'\n | 'thb'\n | 'try'\n | 'twd'\n | 'uah'\n | 'vef'\n | 'vnd'\n | 'zar';\n\n/**\n * Market data details from Price API spot-prices endpoint\n */\nexport type MarketDataDetails = {\n /** Current price in the requested currency */\n price: number;\n /** Currency code (e.g., 'ETH', 'USD') */\n currency: string;\n /** 24h price change amount */\n priceChange1d: number;\n /** 24h price change percentage */\n pricePercentChange1d: number;\n /** 1h price change percentage */\n pricePercentChange1h: number;\n /** 7d price change percentage */\n pricePercentChange7d: number;\n /** 14d price change percentage */\n pricePercentChange14d: number;\n /** 30d price change percentage */\n pricePercentChange30d: number;\n /** 200d price change percentage */\n pricePercentChange200d: number;\n /** 1y price change percentage */\n pricePercentChange1y: number;\n /** Market capitalization */\n marketCap: number;\n /** Market cap 24h change percentage */\n marketCapPercentChange1d: number;\n /** All-time high price */\n allTimeHigh: number;\n /** All-time low price */\n allTimeLow: number;\n /** 24h high price */\n high1d: number;\n /** 24h low price */\n low1d: number;\n /** Total trading volume */\n totalVolume: number;\n /** Circulating supply */\n circulatingSupply: number;\n /** Diluted market cap */\n dilutedMarketCap: number;\n};\n\n// ============================================================================\n// CLIENT OPTIONS\n// ============================================================================\n\nexport type ApiPlatformClientOptions = {\n /** Client product identifier (e.g., 'metamask-extension') */\n clientProduct: string;\n /** Optional client version */\n clientVersion?: string;\n /** Function to get bearer token for authenticated requests */\n getBearerToken?: () => Promise<string | undefined>;\n /** Optional custom QueryClient instance */\n queryClient?: QueryClient;\n};\n\n/**\n * Options for API fetch and query methods.\n * Extends TanStack Query options (e.g. select, initialPageParam, retry) so callers\n * can pass them through to useQuery / useInfiniteQuery. queryKey and queryFn are\n * always set by the client and cannot be overridden.\n * staleTime and gcTime are explicitly number (not function) so that client defaults apply without type conflicts.\n */\nexport type FetchOptions = {\n /** Custom stale time (ms). */\n staleTime?: number;\n /** Custom GC time (ms). */\n gcTime?: number;\n /**\n * When true, bypass caching for this request: the client-side query cache is\n * skipped (stale time defaults to 0) and, on endpoints that support it, a\n * random `bypassServerCache` query param is appended so server-side HTTP caches\n * (keyed on the full URL) miss. Use sparingly — only when a hard refresh is\n * required, e.g. right after a transaction confirms.\n */\n bypassServerCache?: boolean;\n} & Partial<\n Omit<\n FetchQueryOptions<unknown, Error, unknown>,\n 'queryKey' | 'queryFn' | 'staleTime' | 'gcTime'\n >\n> & {\n /** Allowed for infinite query options (e.g. useInfiniteQuery). */\n initialPageParam?: unknown;\n };\n\n/**\n * Returns options with queryKey and queryFn omitted, for merging into\n * get*QueryOptions return values without overwriting the client's queryKey/queryFn.\n * Return type is intentionally loose so that spreading into FetchQueryOptions<T>\n * does not conflict with T-specific option types (e.g. select, staleTime).\n *\n * @param options - Optional FetchOptions from the caller.\n * @returns Options safe to spread into query options, or undefined.\n */\nexport function getQueryOptionsOverrides(\n options?: FetchOptions,\n): Record<string, unknown> | undefined {\n if (options === null || options === undefined) {\n return undefined;\n }\n const {\n queryKey: _qk,\n queryFn: _qf,\n bypassServerCache: _bc,\n ...rest\n } = options as FetchOptions & {\n queryKey?: unknown;\n queryFn?: unknown;\n };\n return rest as Record<string, unknown>;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** API Base URLs */\nexport const API_URLS = {\n ACCOUNTS: 'https://accounts.api.cx.metamask.io',\n PRICES: 'https://price.api.cx.metamask.io',\n TOKEN: 'https://token.api.cx.metamask.io',\n TOKENS: 'https://tokens.api.cx.metamask.io',\n} as const;\n\n/** Stale times for different data types (ms) */\nexport const STALE_TIMES = {\n AUTH_TOKEN: 5 * 60 * 1000, // 5 minutes - cache the auth token\n PRICES: 30 * 1000, // 30 seconds\n BALANCES: 60 * 1000, // 1 minute\n NETWORKS: 10 * 60 * 1000, // 10 minutes\n SUPPORTED_NETWORKS: 30 * 60 * 1000, // 30 minutes\n TOKEN_METADATA: 5 * 60 * 1000, // 5 minutes\n TOKEN_LIST: 10 * 60 * 1000, // 10 minutes\n EXCHANGE_RATES: 5 * 60 * 1000, // 5 minutes\n TRENDING: 2 * 60 * 1000, // 2 minutes\n TRANSACTIONS: 30 * 1000, // 30 seconds\n DEFAULT: 30 * 1000, // 30 seconds\n} as const;\n\n/** Garbage collection times (ms) */\nexport const GC_TIMES = {\n DEFAULT: 5 * 60 * 1000, // 5 minutes\n EXTENDED: 30 * 60 * 1000, // 30 minutes\n SHORT: 2 * 60 * 1000, // 2 minutes\n} as const;\n\n/** Retry configuration */\nexport const RETRY_CONFIG = {\n MAX_RETRIES: 3,\n BASE_DELAY: 1000,\n MAX_DELAY: 5_000,\n} as const;\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Calculate retry delay with exponential backoff and jitter.\n *\n * @param attemptIndex - The current retry attempt (0-indexed).\n * @returns The delay in milliseconds before the next retry.\n */\nexport function calculateRetryDelay(attemptIndex: number): number {\n const delay = Math.min(\n RETRY_CONFIG.BASE_DELAY * 2 ** attemptIndex,\n RETRY_CONFIG.MAX_DELAY,\n );\n return delay / 2 + Math.random() * (delay / 2);\n}\n\n/**\n * Determine if a failed request should be retried.\n *\n * @param failureCount - The number of failures so far (1 = first failure).\n * @param error - The error from the failed request.\n * @returns True if the request should be retried, false otherwise.\n */\nexport function shouldRetry(failureCount: number, error: unknown): boolean {\n // Allow up to MAX_RETRIES retries (e.g., MAX_RETRIES=3 means 4 total attempts)\n if (failureCount > RETRY_CONFIG.MAX_RETRIES) {\n return false;\n }\n\n if (error instanceof Error && 'status' in error) {\n const { status } = error as { status: number };\n // Don't retry 4xx except 429 (rate limit) and 408 (timeout)\n if (status >= 400 && status < 500 && status !== 429 && status !== 408) {\n return false;\n }\n }\n return true;\n}\n\n// ============================================================================\n// HTTP ERROR\n// ============================================================================\n\nexport class HttpError extends Error {\n readonly status: number;\n\n readonly statusText: string;\n\n readonly url: string;\n\n readonly body: unknown;\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n url: string,\n body?: unknown,\n ) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n this.body = body;\n }\n}\n"]}
1
+ {"version":3,"file":"shared-types.mjs","sourceRoot":"","sources":["../../src/api/shared-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiLH;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAsB;IAEtB,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EACJ,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE,GAAG,EACZ,iBAAiB,EAAE,GAAG,EACtB,GAAG,IAAI,EACR,GAAG,OAGH,CAAC;IACF,OAAO,IAA+B,CAAC;AACzC,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,oBAAoB;AACpB,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,qCAAqC;IAC/C,MAAM,EAAE,kCAAkC;IAC1C,KAAK,EAAE,kCAAkC;IACzC,MAAM,EAAE,mCAAmC;CACnC,CAAC;AAEX,gDAAgD;AAChD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,aAAa;IAChC,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW;IAChC,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACvC,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACjD,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IAC3C,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACzC,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IAC3C,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IACrC,YAAY,EAAE,EAAE,GAAG,IAAI,EAAE,aAAa;IACtC,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,aAAa;CACzB,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAE9C,oCAAoC;AACpC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IACpC,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACvC,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;CAC1B,CAAC;AAEX,0BAA0B;AAC1B,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAK;CACR,CAAC;AAEX,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACtD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,YAAY,CAAC,UAAU,GAAG,CAAC,IAAI,YAAY,EAC3C,YAAY,CAAC,SAAS,CACvB,CAAC;IACF,OAAO,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,YAAoB,EAAE,KAAc;IAC9D,+EAA+E;IAC/E,IAAI,YAAY,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QAChD,MAAM,EAAE,MAAM,EAAE,GAAG,KAA2B,CAAC;QAC/C,4DAA4D;QAC5D,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACtE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,MAAM,OAAO,SAAU,SAAQ,KAAK;IASlC,YACE,OAAe,EACf,MAAc,EACd,UAAkB,EAClB,GAAW,EACX,IAAc;QAEd,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF","sourcesContent":["/**\n * Shared types, constants, and utilities for the API Platform Client.\n */\n\nimport type { FetchQueryOptions, QueryClient } from '@tanstack/query-core';\n\n// ============================================================================\n// SHARED TYPES\n// ============================================================================\n\n/**\n * Pagination info for paginated responses\n */\nexport type PageInfo = {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n};\n\n/**\n * Supported currencies for Price API\n */\nexport type SupportedCurrency =\n // Crypto\n | 'btc'\n | 'eth'\n | 'ltc'\n | 'bch'\n | 'bnb'\n | 'eos'\n | 'xrp'\n | 'xlm'\n | 'link'\n | 'dot'\n | 'yfi'\n // Fiat\n | 'usd'\n | 'aed'\n | 'ars'\n | 'aud'\n | 'bdt'\n | 'bhd'\n | 'bmd'\n | 'brl'\n | 'cad'\n | 'chf'\n | 'clp'\n | 'cny'\n | 'czk'\n | 'dkk'\n | 'eur'\n | 'gbp'\n | 'gel'\n | 'hkd'\n | 'huf'\n | 'idr'\n | 'ils'\n | 'inr'\n | 'jpy'\n | 'krw'\n | 'kwd'\n | 'lkr'\n | 'mmk'\n | 'mxn'\n | 'myr'\n | 'ngn'\n | 'nok'\n | 'nzd'\n | 'php'\n | 'pkr'\n | 'pln'\n | 'rub'\n | 'sar'\n | 'sek'\n | 'sgd'\n | 'thb'\n | 'try'\n | 'twd'\n | 'uah'\n | 'vef'\n | 'vnd'\n | 'zar';\n\n/**\n * Market data details from Price API spot-prices endpoint\n */\nexport type MarketDataDetails = {\n /** Current price in the requested currency */\n price: number;\n /** Currency code (e.g., 'ETH', 'USD') */\n currency: string;\n /** 24h price change amount */\n priceChange1d: number;\n /** 24h price change percentage */\n pricePercentChange1d: number;\n /** 1h price change percentage */\n pricePercentChange1h: number;\n /** 7d price change percentage */\n pricePercentChange7d: number;\n /** 14d price change percentage */\n pricePercentChange14d: number;\n /** 30d price change percentage */\n pricePercentChange30d: number;\n /** 200d price change percentage */\n pricePercentChange200d: number;\n /** 1y price change percentage */\n pricePercentChange1y: number;\n /** Market capitalization */\n marketCap: number;\n /** Market cap 24h change percentage */\n marketCapPercentChange1d: number;\n /** All-time high price */\n allTimeHigh: number;\n /** All-time low price */\n allTimeLow: number;\n /** 24h high price */\n high1d: number;\n /** 24h low price */\n low1d: number;\n /** Total trading volume */\n totalVolume: number;\n /** Circulating supply */\n circulatingSupply: number;\n /** Diluted market cap */\n dilutedMarketCap: number;\n};\n\n// ============================================================================\n// CLIENT OPTIONS\n// ============================================================================\n\nexport type ApiPlatformClientOptions = {\n /** Client product identifier (e.g., 'metamask-extension') */\n clientProduct: string;\n /** Optional client version */\n clientVersion?: string;\n /** Function to get bearer token for authenticated requests */\n getBearerToken?: () => Promise<string | undefined>;\n /**\n * Max time (ms) to wait for `getBearerToken` before sending the request\n * unauthenticated. The token keeps resolving in the background and is used by\n * later requests. Set to `0` to always wait for the token.\n * Defaults to {@link DEFAULT_AUTH_TOKEN_TIMEOUT}.\n */\n authTokenTimeout?: number;\n /** Optional custom QueryClient instance */\n queryClient?: QueryClient;\n};\n\n/**\n * Options for API fetch and query methods.\n * Extends TanStack Query options (e.g. select, initialPageParam, retry) so callers\n * can pass them through to useQuery / useInfiniteQuery. queryKey and queryFn are\n * always set by the client and cannot be overridden.\n * staleTime and gcTime are explicitly number (not function) so that client defaults apply without type conflicts.\n */\nexport type FetchOptions = {\n /** Custom stale time (ms). */\n staleTime?: number;\n /** Custom GC time (ms). */\n gcTime?: number;\n /**\n * When true, bypass caching for this request: the client-side query cache is\n * skipped (stale time defaults to 0) and, on endpoints that support it, a\n * random `bypassServerCache` query param is appended so server-side HTTP caches\n * (keyed on the full URL) miss. Use sparingly — only when a hard refresh is\n * required, e.g. right after a transaction confirms.\n */\n bypassServerCache?: boolean;\n} & Partial<\n Omit<\n FetchQueryOptions<unknown, Error, unknown>,\n 'queryKey' | 'queryFn' | 'staleTime' | 'gcTime'\n >\n> & {\n /** Allowed for infinite query options (e.g. useInfiniteQuery). */\n initialPageParam?: unknown;\n };\n\n/**\n * Returns options with queryKey and queryFn omitted, for merging into\n * get*QueryOptions return values without overwriting the client's queryKey/queryFn.\n * Return type is intentionally loose so that spreading into FetchQueryOptions<T>\n * does not conflict with T-specific option types (e.g. select, staleTime).\n *\n * @param options - Optional FetchOptions from the caller.\n * @returns Options safe to spread into query options, or undefined.\n */\nexport function getQueryOptionsOverrides(\n options?: FetchOptions,\n): Record<string, unknown> | undefined {\n if (options === null || options === undefined) {\n return undefined;\n }\n const {\n queryKey: _qk,\n queryFn: _qf,\n bypassServerCache: _bc,\n ...rest\n } = options as FetchOptions & {\n queryKey?: unknown;\n queryFn?: unknown;\n };\n return rest as Record<string, unknown>;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** API Base URLs */\nexport const API_URLS = {\n ACCOUNTS: 'https://accounts.api.cx.metamask.io',\n PRICES: 'https://price.api.cx.metamask.io',\n TOKEN: 'https://token.api.cx.metamask.io',\n TOKENS: 'https://tokens.api.cx.metamask.io',\n} as const;\n\n/** Stale times for different data types (ms) */\nexport const STALE_TIMES = {\n PRICES: 30 * 1000, // 30 seconds\n BALANCES: 60 * 1000, // 1 minute\n NETWORKS: 10 * 60 * 1000, // 10 minutes\n SUPPORTED_NETWORKS: 30 * 60 * 1000, // 30 minutes\n TOKEN_METADATA: 5 * 60 * 1000, // 5 minutes\n TOKEN_LIST: 10 * 60 * 1000, // 10 minutes\n EXCHANGE_RATES: 5 * 60 * 1000, // 5 minutes\n TRENDING: 2 * 60 * 1000, // 2 minutes\n TRANSACTIONS: 30 * 1000, // 30 seconds\n DEFAULT: 30 * 1000, // 30 seconds\n} as const;\n\n/**\n * Default max time (ms) to wait for the bearer token before falling back to an\n * unauthenticated request.\n */\nexport const DEFAULT_AUTH_TOKEN_TIMEOUT = 500;\n\n/** Garbage collection times (ms) */\nexport const GC_TIMES = {\n DEFAULT: 5 * 60 * 1000, // 5 minutes\n EXTENDED: 30 * 60 * 1000, // 30 minutes\n SHORT: 2 * 60 * 1000, // 2 minutes\n} as const;\n\n/** Retry configuration */\nexport const RETRY_CONFIG = {\n MAX_RETRIES: 3,\n BASE_DELAY: 1000,\n MAX_DELAY: 5_000,\n} as const;\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Calculate retry delay with exponential backoff and jitter.\n *\n * @param attemptIndex - The current retry attempt (0-indexed).\n * @returns The delay in milliseconds before the next retry.\n */\nexport function calculateRetryDelay(attemptIndex: number): number {\n const delay = Math.min(\n RETRY_CONFIG.BASE_DELAY * 2 ** attemptIndex,\n RETRY_CONFIG.MAX_DELAY,\n );\n return delay / 2 + Math.random() * (delay / 2);\n}\n\n/**\n * Determine if a failed request should be retried.\n *\n * @param failureCount - The number of failures so far (1 = first failure).\n * @param error - The error from the failed request.\n * @returns True if the request should be retried, false otherwise.\n */\nexport function shouldRetry(failureCount: number, error: unknown): boolean {\n // Allow up to MAX_RETRIES retries (e.g., MAX_RETRIES=3 means 4 total attempts)\n if (failureCount > RETRY_CONFIG.MAX_RETRIES) {\n return false;\n }\n\n if (error instanceof Error && 'status' in error) {\n const { status } = error as { status: number };\n // Don't retry 4xx except 429 (rate limit) and 408 (timeout)\n if (status >= 400 && status < 500 && status !== 429 && status !== 408) {\n return false;\n }\n }\n return true;\n}\n\n// ============================================================================\n// HTTP ERROR\n// ============================================================================\n\nexport class HttpError extends Error {\n readonly status: number;\n\n readonly statusText: string;\n\n readonly url: string;\n\n readonly body: unknown;\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n url: string,\n body?: unknown,\n ) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n this.body = body;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/core-backend",
3
- "version": "9.0.0-preview-5bb6dba48",
3
+ "version": "9.0.0-preview-d8fceeabc",
4
4
  "description": "Core backend services for MetaMask",
5
5
  "keywords": [
6
6
  "Ethereum",