@metamask-previews/phishing-controller 13.1.0-preview-5a701133 → 14.0.0-preview-c20b7569

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/dist/CacheManager.cjs +177 -0
  3. package/dist/CacheManager.cjs.map +1 -0
  4. package/dist/CacheManager.d.cts +104 -0
  5. package/dist/CacheManager.d.cts.map +1 -0
  6. package/dist/CacheManager.d.mts +104 -0
  7. package/dist/CacheManager.d.mts.map +1 -0
  8. package/dist/CacheManager.mjs +173 -0
  9. package/dist/CacheManager.mjs.map +1 -0
  10. package/dist/PhishingController.cjs +186 -8
  11. package/dist/PhishingController.cjs.map +1 -1
  12. package/dist/PhishingController.d.cts +41 -6
  13. package/dist/PhishingController.d.cts.map +1 -1
  14. package/dist/PhishingController.d.mts +41 -6
  15. package/dist/PhishingController.d.mts.map +1 -1
  16. package/dist/PhishingController.mjs +186 -8
  17. package/dist/PhishingController.mjs.map +1 -1
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +1 -1
  20. package/dist/index.d.cts.map +1 -1
  21. package/dist/index.d.mts +1 -1
  22. package/dist/index.d.mts.map +1 -1
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/tests/utils.cjs +79 -1
  25. package/dist/tests/utils.cjs.map +1 -1
  26. package/dist/tests/utils.d.cts +59 -0
  27. package/dist/tests/utils.d.cts.map +1 -1
  28. package/dist/tests/utils.d.mts +59 -0
  29. package/dist/tests/utils.d.mts.map +1 -1
  30. package/dist/tests/utils.mjs +75 -0
  31. package/dist/tests/utils.mjs.map +1 -1
  32. package/dist/types.cjs +35 -1
  33. package/dist/types.cjs.map +1 -1
  34. package/dist/types.d.cts +68 -0
  35. package/dist/types.d.cts.map +1 -1
  36. package/dist/types.d.mts +68 -0
  37. package/dist/types.d.mts.map +1 -1
  38. package/dist/types.mjs +34 -0
  39. package/dist/types.mjs.map +1 -1
  40. package/dist/utils.cjs +54 -1
  41. package/dist/utils.cjs.map +1 -1
  42. package/dist/utils.d.cts +55 -0
  43. package/dist/utils.d.cts.map +1 -1
  44. package/dist/utils.d.mts +55 -0
  45. package/dist/utils.d.mts.map +1 -1
  46. package/dist/utils.mjs +50 -0
  47. package/dist/utils.mjs.map +1 -1
  48. package/package.json +5 -1
  49. package/dist/UrlScanCache.cjs +0 -127
  50. package/dist/UrlScanCache.cjs.map +0 -1
  51. package/dist/UrlScanCache.d.cts +0 -67
  52. package/dist/UrlScanCache.d.cts.map +0 -1
  53. package/dist/UrlScanCache.d.mts +0 -67
  54. package/dist/UrlScanCache.d.mts.map +0 -1
  55. package/dist/UrlScanCache.mjs +0 -123
  56. package/dist/UrlScanCache.mjs.map +0 -1
@@ -1,7 +1,8 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
2
2
  import { BaseController } from "@metamask/base-controller";
3
- import { type PhishingDetectorResult, type PhishingDetectionScanResult } from "./types.cjs";
4
- import { type UrlScanCacheEntry } from "./UrlScanCache.cjs";
3
+ import type { TransactionControllerStateChangeEvent } from "@metamask/transaction-controller";
4
+ import { type CacheEntry } from "./CacheManager.cjs";
5
+ import { type PhishingDetectorResult, type PhishingDetectionScanResult, type TokenScanCacheData, type BulkTokenScanResponse, type BulkTokenScanRequest } from "./types.cjs";
5
6
  export declare const PHISHING_CONFIG_BASE_URL = "https://phishing-detection.api.cx.metamask.io";
6
7
  export declare const METAMASK_STALELIST_FILE = "/v1/stalelist";
7
8
  export declare const METAMASK_HOTLIST_DIFF_FILE = "/v1/diffsSince";
@@ -10,6 +11,12 @@ export declare const C2_DOMAIN_BLOCKLIST_ENDPOINT = "/v1/request-blocklist";
10
11
  export declare const PHISHING_DETECTION_BASE_URL = "https://dapp-scanning.api.cx.metamask.io";
11
12
  export declare const PHISHING_DETECTION_SCAN_ENDPOINT = "v2/scan";
12
13
  export declare const PHISHING_DETECTION_BULK_SCAN_ENDPOINT = "bulk-scan";
14
+ export declare const SECURITY_ALERTS_BASE_URL = "https://security-alerts.api.cx.metamask.io";
15
+ export declare const TOKEN_BULK_SCANNING_ENDPOINT = "/token/scan-bulk";
16
+ export declare const DEFAULT_URL_SCAN_CACHE_TTL: number;
17
+ export declare const DEFAULT_URL_SCAN_CACHE_MAX_SIZE = 250;
18
+ export declare const DEFAULT_TOKEN_SCAN_CACHE_TTL: number;
19
+ export declare const DEFAULT_TOKEN_SCAN_CACHE_MAX_SIZE = 1000;
13
20
  export declare const C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL: number;
14
21
  export declare const HOTLIST_REFRESH_INTERVAL: number;
15
22
  export declare const STALELIST_REFRESH_INTERVAL: number;
@@ -153,7 +160,8 @@ export type PhishingControllerState = {
153
160
  hotlistLastFetched: number;
154
161
  stalelistLastFetched: number;
155
162
  c2DomainBlocklistLastFetched: number;
156
- urlScanCache: Record<string, UrlScanCacheEntry>;
163
+ urlScanCache: Record<string, CacheEntry<PhishingDetectionScanResult>>;
164
+ tokenScanCache: Record<string, CacheEntry<TokenScanCacheData>>;
157
165
  };
158
166
  /**
159
167
  * PhishingControllerOptions
@@ -164,6 +172,8 @@ export type PhishingControllerState = {
164
172
  * c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
165
173
  * urlScanCacheTTL - Time to live in seconds for cached scan results.
166
174
  * urlScanCacheMaxSize - Maximum number of entries in the scan cache.
175
+ * tokenScanCacheTTL - Time to live in seconds for cached token scan results.
176
+ * tokenScanCacheMaxSize - Maximum number of entries in the token scan cache.
167
177
  */
168
178
  export type PhishingControllerOptions = {
169
179
  stalelistRefreshInterval?: number;
@@ -171,6 +181,8 @@ export type PhishingControllerOptions = {
171
181
  c2DomainBlocklistRefreshInterval?: number;
172
182
  urlScanCacheTTL?: number;
173
183
  urlScanCacheMaxSize?: number;
184
+ tokenScanCacheTTL?: number;
185
+ tokenScanCacheMaxSize?: number;
174
186
  messenger: PhishingControllerMessenger;
175
187
  state?: Partial<PhishingControllerState>;
176
188
  };
@@ -186,11 +198,23 @@ export type PhishingControllerBulkScanUrlsAction = {
186
198
  type: `${typeof controllerName}:bulkScanUrls`;
187
199
  handler: PhishingController['bulkScanUrls'];
188
200
  };
201
+ export type PhishingControllerBulkScanTokensAction = {
202
+ type: `${typeof controllerName}:bulkScanTokens`;
203
+ handler: PhishingController['bulkScanTokens'];
204
+ };
189
205
  export type PhishingControllerGetStateAction = ControllerGetStateAction<typeof controllerName, PhishingControllerState>;
190
- export type PhishingControllerActions = PhishingControllerGetStateAction | MaybeUpdateState | TestOrigin | PhishingControllerBulkScanUrlsAction;
206
+ export type PhishingControllerActions = PhishingControllerGetStateAction | MaybeUpdateState | TestOrigin | PhishingControllerBulkScanUrlsAction | PhishingControllerBulkScanTokensAction;
191
207
  export type PhishingControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, PhishingControllerState>;
192
208
  export type PhishingControllerEvents = PhishingControllerStateChangeEvent;
193
- export type PhishingControllerMessenger = RestrictedMessenger<typeof controllerName, PhishingControllerActions, PhishingControllerEvents, never, never>;
209
+ /**
210
+ * The external actions available to the PhishingController.
211
+ */
212
+ type AllowedActions = never;
213
+ /**
214
+ * The external events available to the PhishingController.
215
+ */
216
+ export type AllowedEvents = TransactionControllerStateChangeEvent;
217
+ export type PhishingControllerMessenger = RestrictedMessenger<typeof controllerName, PhishingControllerActions | AllowedActions, PhishingControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
194
218
  /**
195
219
  * BulkPhishingDetectionScanResponse
196
220
  *
@@ -217,10 +241,12 @@ export declare class PhishingController extends BaseController<typeof controller
217
241
  * @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
218
242
  * @param config.urlScanCacheTTL - Time to live in seconds for cached scan results.
219
243
  * @param config.urlScanCacheMaxSize - Maximum number of entries in the scan cache.
244
+ * @param config.tokenScanCacheTTL - Time to live in seconds for cached token scan results.
245
+ * @param config.tokenScanCacheMaxSize - Maximum number of entries in the token scan cache.
220
246
  * @param config.messenger - The controller restricted messenger.
221
247
  * @param config.state - Initial state to set on this controller.
222
248
  */
223
- constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, urlScanCacheTTL, urlScanCacheMaxSize, messenger, state, }: PhishingControllerOptions);
249
+ constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, urlScanCacheTTL, urlScanCacheMaxSize, tokenScanCacheTTL, tokenScanCacheMaxSize, messenger, state, }: PhishingControllerOptions);
224
250
  /**
225
251
  * Updates this.detector with an instance of PhishingDetector using the current state.
226
252
  */
@@ -357,6 +383,15 @@ export declare class PhishingController extends BaseController<typeof controller
357
383
  * @returns A mapping of URLs to their phishing detection scan results and errors.
358
384
  */
359
385
  bulkScanUrls: (urls: string[]) => Promise<BulkPhishingDetectionScanResponse>;
386
+ /**
387
+ * Scan multiple tokens for malicious activity in bulk.
388
+ *
389
+ * @param request - The bulk scan request containing chainId and tokens.
390
+ * @param request.chainId - The chain ID in hex format (e.g., '0x1' for Ethereum).
391
+ * @param request.tokens - Array of token addresses to scan.
392
+ * @returns A mapping of lowercase token addresses to their scan results. Tokens that fail to scan are omitted.
393
+ */
394
+ bulkScanTokens: (request: BulkTokenScanRequest) => Promise<BulkTokenScanResponse>;
360
395
  }
361
396
  export default PhishingController;
362
397
  export type { PhishingDetectorResult };
@@ -1 +1 @@
1
- {"version":3,"file":"PhishingController.d.cts","sourceRoot":"","sources":["../src/PhishingController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PhishingController.d.cts","sourceRoot":"","sources":["../src/PhishingController.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
2
2
  import { BaseController } from "@metamask/base-controller";
3
- import { type PhishingDetectorResult, type PhishingDetectionScanResult } from "./types.mjs";
4
- import { type UrlScanCacheEntry } from "./UrlScanCache.mjs";
3
+ import type { TransactionControllerStateChangeEvent } from "@metamask/transaction-controller";
4
+ import { type CacheEntry } from "./CacheManager.mjs";
5
+ import { type PhishingDetectorResult, type PhishingDetectionScanResult, type TokenScanCacheData, type BulkTokenScanResponse, type BulkTokenScanRequest } from "./types.mjs";
5
6
  export declare const PHISHING_CONFIG_BASE_URL = "https://phishing-detection.api.cx.metamask.io";
6
7
  export declare const METAMASK_STALELIST_FILE = "/v1/stalelist";
7
8
  export declare const METAMASK_HOTLIST_DIFF_FILE = "/v1/diffsSince";
@@ -10,6 +11,12 @@ export declare const C2_DOMAIN_BLOCKLIST_ENDPOINT = "/v1/request-blocklist";
10
11
  export declare const PHISHING_DETECTION_BASE_URL = "https://dapp-scanning.api.cx.metamask.io";
11
12
  export declare const PHISHING_DETECTION_SCAN_ENDPOINT = "v2/scan";
12
13
  export declare const PHISHING_DETECTION_BULK_SCAN_ENDPOINT = "bulk-scan";
14
+ export declare const SECURITY_ALERTS_BASE_URL = "https://security-alerts.api.cx.metamask.io";
15
+ export declare const TOKEN_BULK_SCANNING_ENDPOINT = "/token/scan-bulk";
16
+ export declare const DEFAULT_URL_SCAN_CACHE_TTL: number;
17
+ export declare const DEFAULT_URL_SCAN_CACHE_MAX_SIZE = 250;
18
+ export declare const DEFAULT_TOKEN_SCAN_CACHE_TTL: number;
19
+ export declare const DEFAULT_TOKEN_SCAN_CACHE_MAX_SIZE = 1000;
13
20
  export declare const C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL: number;
14
21
  export declare const HOTLIST_REFRESH_INTERVAL: number;
15
22
  export declare const STALELIST_REFRESH_INTERVAL: number;
@@ -153,7 +160,8 @@ export type PhishingControllerState = {
153
160
  hotlistLastFetched: number;
154
161
  stalelistLastFetched: number;
155
162
  c2DomainBlocklistLastFetched: number;
156
- urlScanCache: Record<string, UrlScanCacheEntry>;
163
+ urlScanCache: Record<string, CacheEntry<PhishingDetectionScanResult>>;
164
+ tokenScanCache: Record<string, CacheEntry<TokenScanCacheData>>;
157
165
  };
158
166
  /**
159
167
  * PhishingControllerOptions
@@ -164,6 +172,8 @@ export type PhishingControllerState = {
164
172
  * c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
165
173
  * urlScanCacheTTL - Time to live in seconds for cached scan results.
166
174
  * urlScanCacheMaxSize - Maximum number of entries in the scan cache.
175
+ * tokenScanCacheTTL - Time to live in seconds for cached token scan results.
176
+ * tokenScanCacheMaxSize - Maximum number of entries in the token scan cache.
167
177
  */
168
178
  export type PhishingControllerOptions = {
169
179
  stalelistRefreshInterval?: number;
@@ -171,6 +181,8 @@ export type PhishingControllerOptions = {
171
181
  c2DomainBlocklistRefreshInterval?: number;
172
182
  urlScanCacheTTL?: number;
173
183
  urlScanCacheMaxSize?: number;
184
+ tokenScanCacheTTL?: number;
185
+ tokenScanCacheMaxSize?: number;
174
186
  messenger: PhishingControllerMessenger;
175
187
  state?: Partial<PhishingControllerState>;
176
188
  };
@@ -186,11 +198,23 @@ export type PhishingControllerBulkScanUrlsAction = {
186
198
  type: `${typeof controllerName}:bulkScanUrls`;
187
199
  handler: PhishingController['bulkScanUrls'];
188
200
  };
201
+ export type PhishingControllerBulkScanTokensAction = {
202
+ type: `${typeof controllerName}:bulkScanTokens`;
203
+ handler: PhishingController['bulkScanTokens'];
204
+ };
189
205
  export type PhishingControllerGetStateAction = ControllerGetStateAction<typeof controllerName, PhishingControllerState>;
190
- export type PhishingControllerActions = PhishingControllerGetStateAction | MaybeUpdateState | TestOrigin | PhishingControllerBulkScanUrlsAction;
206
+ export type PhishingControllerActions = PhishingControllerGetStateAction | MaybeUpdateState | TestOrigin | PhishingControllerBulkScanUrlsAction | PhishingControllerBulkScanTokensAction;
191
207
  export type PhishingControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, PhishingControllerState>;
192
208
  export type PhishingControllerEvents = PhishingControllerStateChangeEvent;
193
- export type PhishingControllerMessenger = RestrictedMessenger<typeof controllerName, PhishingControllerActions, PhishingControllerEvents, never, never>;
209
+ /**
210
+ * The external actions available to the PhishingController.
211
+ */
212
+ type AllowedActions = never;
213
+ /**
214
+ * The external events available to the PhishingController.
215
+ */
216
+ export type AllowedEvents = TransactionControllerStateChangeEvent;
217
+ export type PhishingControllerMessenger = RestrictedMessenger<typeof controllerName, PhishingControllerActions | AllowedActions, PhishingControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
194
218
  /**
195
219
  * BulkPhishingDetectionScanResponse
196
220
  *
@@ -217,10 +241,12 @@ export declare class PhishingController extends BaseController<typeof controller
217
241
  * @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
218
242
  * @param config.urlScanCacheTTL - Time to live in seconds for cached scan results.
219
243
  * @param config.urlScanCacheMaxSize - Maximum number of entries in the scan cache.
244
+ * @param config.tokenScanCacheTTL - Time to live in seconds for cached token scan results.
245
+ * @param config.tokenScanCacheMaxSize - Maximum number of entries in the token scan cache.
220
246
  * @param config.messenger - The controller restricted messenger.
221
247
  * @param config.state - Initial state to set on this controller.
222
248
  */
223
- constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, urlScanCacheTTL, urlScanCacheMaxSize, messenger, state, }: PhishingControllerOptions);
249
+ constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, urlScanCacheTTL, urlScanCacheMaxSize, tokenScanCacheTTL, tokenScanCacheMaxSize, messenger, state, }: PhishingControllerOptions);
224
250
  /**
225
251
  * Updates this.detector with an instance of PhishingDetector using the current state.
226
252
  */
@@ -357,6 +383,15 @@ export declare class PhishingController extends BaseController<typeof controller
357
383
  * @returns A mapping of URLs to their phishing detection scan results and errors.
358
384
  */
359
385
  bulkScanUrls: (urls: string[]) => Promise<BulkPhishingDetectionScanResponse>;
386
+ /**
387
+ * Scan multiple tokens for malicious activity in bulk.
388
+ *
389
+ * @param request - The bulk scan request containing chainId and tokens.
390
+ * @param request.chainId - The chain ID in hex format (e.g., '0x1' for Ethereum).
391
+ * @param request.tokens - Array of token addresses to scan.
392
+ * @returns A mapping of lowercase token addresses to their scan results. Tokens that fail to scan are omitted.
393
+ */
394
+ bulkScanTokens: (request: BulkTokenScanRequest) => Promise<BulkTokenScanResponse>;
360
395
  }
361
396
  export default PhishingController;
362
397
  export type { PhishingDetectorResult };
@@ -1 +1 @@
1
- {"version":3,"file":"PhishingController.d.mts","sourceRoot":"","sources":["../src/PhishingController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PhishingController.d.mts","sourceRoot":"","sources":["../src/PhishingController.ts"],"names":[],"mappings":"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"}
@@ -9,15 +9,15 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _PhishingController_instances, _PhishingController_detector, _PhishingController_stalelistRefreshInterval, _PhishingController_hotlistRefreshInterval, _PhishingController_c2DomainBlocklistRefreshInterval, _PhishingController_urlScanCache, _PhishingController_inProgressHotlistUpdate, _PhishingController_inProgressStalelistUpdate, _PhishingController_isProgressC2DomainBlocklistUpdate, _PhishingController_registerMessageHandlers, _PhishingController_processBatch, _PhishingController_updateStalelist, _PhishingController_updateHotlist, _PhishingController_updateC2DomainBlocklist, _PhishingController_queryConfig;
12
+ var _PhishingController_instances, _PhishingController_detector, _PhishingController_stalelistRefreshInterval, _PhishingController_hotlistRefreshInterval, _PhishingController_c2DomainBlocklistRefreshInterval, _PhishingController_urlScanCache, _PhishingController_tokenScanCache, _PhishingController_inProgressHotlistUpdate, _PhishingController_inProgressStalelistUpdate, _PhishingController_isProgressC2DomainBlocklistUpdate, _PhishingController_transactionControllerStateChangeHandler, _PhishingController_subscribeToTransactionControllerStateChange, _PhishingController_registerMessageHandlers, _PhishingController_isTransactionPatch, _PhishingController_onTransactionControllerStateChange, _PhishingController_getTokensFromTransaction, _PhishingController_scanTokensByChain, _PhishingController_fetchTokenScanBulkResults, _PhishingController_processBatch, _PhishingController_updateStalelist, _PhishingController_updateHotlist, _PhishingController_updateC2DomainBlocklist, _PhishingController_queryConfig;
13
13
  import { BaseController } from "@metamask/base-controller";
14
14
  import { safelyExecute, safelyExecuteWithTimeout } from "@metamask/controller-utils";
15
15
  import $punycodepunycodejs from "punycode/punycode.js";
16
16
  const { toASCII } = $punycodepunycodejs;
17
+ import { CacheManager } from "./CacheManager.mjs";
17
18
  import { PhishingDetector } from "./PhishingDetector.mjs";
18
19
  import { PhishingDetectorResultType, RecommendedAction } from "./types.mjs";
19
- import { DEFAULT_URL_SCAN_CACHE_MAX_SIZE, DEFAULT_URL_SCAN_CACHE_TTL, UrlScanCache } from "./UrlScanCache.mjs";
20
- import { applyDiffs, fetchTimeNow, getHostnameFromUrl, roundToNearestMinute, getHostnameFromWebUrl } from "./utils.mjs";
20
+ import { applyDiffs, fetchTimeNow, getHostnameFromUrl, roundToNearestMinute, getHostnameFromWebUrl, buildCacheKey, splitCacheHits, resolveChainName } from "./utils.mjs";
21
21
  export const PHISHING_CONFIG_BASE_URL = 'https://phishing-detection.api.cx.metamask.io';
22
22
  export const METAMASK_STALELIST_FILE = '/v1/stalelist';
23
23
  export const METAMASK_HOTLIST_DIFF_FILE = '/v1/diffsSince';
@@ -26,6 +26,13 @@ export const C2_DOMAIN_BLOCKLIST_ENDPOINT = '/v1/request-blocklist';
26
26
  export const PHISHING_DETECTION_BASE_URL = 'https://dapp-scanning.api.cx.metamask.io';
27
27
  export const PHISHING_DETECTION_SCAN_ENDPOINT = 'v2/scan';
28
28
  export const PHISHING_DETECTION_BULK_SCAN_ENDPOINT = 'bulk-scan';
29
+ export const SECURITY_ALERTS_BASE_URL = 'https://security-alerts.api.cx.metamask.io';
30
+ export const TOKEN_BULK_SCANNING_ENDPOINT = '/token/scan-bulk';
31
+ // Cache configuration defaults
32
+ export const DEFAULT_URL_SCAN_CACHE_TTL = 15 * 60; // 15 minutes in seconds
33
+ export const DEFAULT_URL_SCAN_CACHE_MAX_SIZE = 250;
34
+ export const DEFAULT_TOKEN_SCAN_CACHE_TTL = 15 * 60; // 15 minutes in seconds
35
+ export const DEFAULT_TOKEN_SCAN_CACHE_MAX_SIZE = 1000;
29
36
  export const C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL = 5 * 60; // 5 mins in seconds
30
37
  export const HOTLIST_REFRESH_INTERVAL = 5 * 60; // 5 mins in seconds
31
38
  export const STALELIST_REFRESH_INTERVAL = 30 * 24 * 60 * 60; // 30 days in seconds
@@ -99,6 +106,12 @@ const metadata = {
99
106
  anonymous: false,
100
107
  usedInUi: true,
101
108
  },
109
+ tokenScanCache: {
110
+ includeInStateLogs: false,
111
+ persist: true,
112
+ anonymous: false,
113
+ usedInUi: true,
114
+ },
102
115
  };
103
116
  /**
104
117
  * Get a default empty state for the controller.
@@ -112,6 +125,7 @@ const getDefaultState = () => {
112
125
  stalelistLastFetched: 0,
113
126
  c2DomainBlocklistLastFetched: 0,
114
127
  urlScanCache: {},
128
+ tokenScanCache: {},
115
129
  };
116
130
  };
117
131
  /**
@@ -127,10 +141,12 @@ export class PhishingController extends BaseController {
127
141
  * @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
128
142
  * @param config.urlScanCacheTTL - Time to live in seconds for cached scan results.
129
143
  * @param config.urlScanCacheMaxSize - Maximum number of entries in the scan cache.
144
+ * @param config.tokenScanCacheTTL - Time to live in seconds for cached token scan results.
145
+ * @param config.tokenScanCacheMaxSize - Maximum number of entries in the token scan cache.
130
146
  * @param config.messenger - The controller restricted messenger.
131
147
  * @param config.state - Initial state to set on this controller.
132
148
  */
133
- constructor({ stalelistRefreshInterval = STALELIST_REFRESH_INTERVAL, hotlistRefreshInterval = HOTLIST_REFRESH_INTERVAL, c2DomainBlocklistRefreshInterval = C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL, urlScanCacheTTL = DEFAULT_URL_SCAN_CACHE_TTL, urlScanCacheMaxSize = DEFAULT_URL_SCAN_CACHE_MAX_SIZE, messenger, state = {}, }) {
149
+ constructor({ stalelistRefreshInterval = STALELIST_REFRESH_INTERVAL, hotlistRefreshInterval = HOTLIST_REFRESH_INTERVAL, c2DomainBlocklistRefreshInterval = C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL, urlScanCacheTTL = DEFAULT_URL_SCAN_CACHE_TTL, urlScanCacheMaxSize = DEFAULT_URL_SCAN_CACHE_MAX_SIZE, tokenScanCacheTTL = DEFAULT_TOKEN_SCAN_CACHE_TTL, tokenScanCacheMaxSize = DEFAULT_TOKEN_SCAN_CACHE_MAX_SIZE, messenger, state = {}, }) {
134
150
  super({
135
151
  name: controllerName,
136
152
  metadata,
@@ -148,9 +164,11 @@ export class PhishingController extends BaseController {
148
164
  _PhishingController_hotlistRefreshInterval.set(this, void 0);
149
165
  _PhishingController_c2DomainBlocklistRefreshInterval.set(this, void 0);
150
166
  _PhishingController_urlScanCache.set(this, void 0);
167
+ _PhishingController_tokenScanCache.set(this, void 0);
151
168
  _PhishingController_inProgressHotlistUpdate.set(this, void 0);
152
169
  _PhishingController_inProgressStalelistUpdate.set(this, void 0);
153
170
  _PhishingController_isProgressC2DomainBlocklistUpdate.set(this, void 0);
171
+ _PhishingController_transactionControllerStateChangeHandler.set(this, void 0);
154
172
  /**
155
173
  * Scan a URL for phishing. It will only scan the hostname of the URL. It also only supports
156
174
  * web URLs.
@@ -205,7 +223,7 @@ export class PhishingController extends BaseController {
205
223
  hostname,
206
224
  recommendedAction: apiResponse.recommendedAction,
207
225
  };
208
- __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").add(hostname, result);
226
+ __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").set(hostname, result);
209
227
  return result;
210
228
  };
211
229
  /**
@@ -282,7 +300,7 @@ export class PhishingController extends BaseController {
282
300
  Object.entries(batchResponse.results).forEach(([url, result]) => {
283
301
  const hostname = urlsToHostnames[url];
284
302
  if (hostname) {
285
- __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").add(hostname, result);
303
+ __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").set(hostname, result);
286
304
  }
287
305
  combinedResponse.results[url] = result;
288
306
  });
@@ -297,6 +315,102 @@ export class PhishingController extends BaseController {
297
315
  }
298
316
  return combinedResponse;
299
317
  };
318
+ /**
319
+ * Fetch bulk token scan results from the security alerts API.
320
+ *
321
+ * @param chain - The chain name.
322
+ * @param tokens - Array of token addresses to scan.
323
+ * @returns The API response or null if there was an error.
324
+ */
325
+ _PhishingController_fetchTokenScanBulkResults.set(this, async (chain, tokens) => {
326
+ const timeout = 8000; // 8 seconds
327
+ const apiResponse = await safelyExecuteWithTimeout(async () => {
328
+ const response = await fetch(`${SECURITY_ALERTS_BASE_URL}${TOKEN_BULK_SCANNING_ENDPOINT}`, {
329
+ method: 'POST',
330
+ headers: {
331
+ Accept: 'application/json',
332
+ 'Content-Type': 'application/json',
333
+ },
334
+ body: JSON.stringify({
335
+ chain,
336
+ tokens,
337
+ }),
338
+ });
339
+ if (!response.ok) {
340
+ return {
341
+ error: `${response.status} ${response.statusText}`,
342
+ status: response.status,
343
+ statusText: response.statusText,
344
+ };
345
+ }
346
+ const data = await response.json();
347
+ return data;
348
+ }, true, timeout);
349
+ if (!apiResponse) {
350
+ console.error(`Error scanning tokens: timeout of ${timeout}ms exceeded`);
351
+ return null;
352
+ }
353
+ if ('error' in apiResponse &&
354
+ 'status' in apiResponse &&
355
+ 'statusText' in apiResponse) {
356
+ console.warn(`Token bulk screening API error: ${apiResponse.status} ${apiResponse.statusText}`);
357
+ return null;
358
+ }
359
+ return apiResponse;
360
+ });
361
+ /**
362
+ * Scan multiple tokens for malicious activity in bulk.
363
+ *
364
+ * @param request - The bulk scan request containing chainId and tokens.
365
+ * @param request.chainId - The chain ID in hex format (e.g., '0x1' for Ethereum).
366
+ * @param request.tokens - Array of token addresses to scan.
367
+ * @returns A mapping of lowercase token addresses to their scan results. Tokens that fail to scan are omitted.
368
+ */
369
+ this.bulkScanTokens = async (request) => {
370
+ const { chainId, tokens } = request;
371
+ if (!tokens || tokens.length === 0) {
372
+ return {};
373
+ }
374
+ const MAX_TOKENS_PER_REQUEST = 100;
375
+ if (tokens.length > MAX_TOKENS_PER_REQUEST) {
376
+ console.warn(`Maximum of ${MAX_TOKENS_PER_REQUEST} tokens allowed per request`);
377
+ return {};
378
+ }
379
+ const normalizedChainId = chainId.toLowerCase();
380
+ const chain = resolveChainName(normalizedChainId);
381
+ if (!chain) {
382
+ console.warn(`Unknown chain ID: ${chainId}`);
383
+ return {};
384
+ }
385
+ // Split tokens into cached results and tokens that need to be fetched
386
+ const { cachedResults, tokensToFetch } = splitCacheHits(__classPrivateFieldGet(this, _PhishingController_tokenScanCache, "f"), normalizedChainId, tokens);
387
+ const results = { ...cachedResults };
388
+ // If there are tokens to fetch, call the bulk token scan API
389
+ if (tokensToFetch.length > 0) {
390
+ const apiResponse = await __classPrivateFieldGet(this, _PhishingController_fetchTokenScanBulkResults, "f").call(this, chain, tokensToFetch);
391
+ if (apiResponse?.results) {
392
+ // Process API results and update cache
393
+ for (const tokenAddress of tokensToFetch) {
394
+ const normalizedAddress = tokenAddress.toLowerCase();
395
+ const tokenResult = apiResponse.results[normalizedAddress];
396
+ if (tokenResult?.result_type) {
397
+ const result = {
398
+ result_type: tokenResult.result_type,
399
+ chain: tokenResult.chain || normalizedChainId,
400
+ address: tokenResult.address || normalizedAddress,
401
+ };
402
+ // Update cache
403
+ const cacheKey = buildCacheKey(normalizedChainId, normalizedAddress);
404
+ __classPrivateFieldGet(this, _PhishingController_tokenScanCache, "f").set(cacheKey, {
405
+ result_type: tokenResult.result_type,
406
+ });
407
+ results[normalizedAddress] = result;
408
+ }
409
+ }
410
+ }
411
+ }
412
+ return results;
413
+ };
300
414
  /**
301
415
  * Process a batch of URLs (up to 50) for phishing detection.
302
416
  *
@@ -348,7 +462,8 @@ export class PhishingController extends BaseController {
348
462
  __classPrivateFieldSet(this, _PhishingController_stalelistRefreshInterval, stalelistRefreshInterval, "f");
349
463
  __classPrivateFieldSet(this, _PhishingController_hotlistRefreshInterval, hotlistRefreshInterval, "f");
350
464
  __classPrivateFieldSet(this, _PhishingController_c2DomainBlocklistRefreshInterval, c2DomainBlocklistRefreshInterval, "f");
351
- __classPrivateFieldSet(this, _PhishingController_urlScanCache, new UrlScanCache({
465
+ __classPrivateFieldSet(this, _PhishingController_transactionControllerStateChangeHandler, __classPrivateFieldGet(this, _PhishingController_instances, "m", _PhishingController_onTransactionControllerStateChange).bind(this), "f");
466
+ __classPrivateFieldSet(this, _PhishingController_urlScanCache, new CacheManager({
352
467
  cacheTTL: urlScanCacheTTL,
353
468
  maxCacheSize: urlScanCacheMaxSize,
354
469
  initialCache: this.state.urlScanCache,
@@ -358,8 +473,19 @@ export class PhishingController extends BaseController {
358
473
  });
359
474
  },
360
475
  }), "f");
476
+ __classPrivateFieldSet(this, _PhishingController_tokenScanCache, new CacheManager({
477
+ cacheTTL: tokenScanCacheTTL,
478
+ maxCacheSize: tokenScanCacheMaxSize,
479
+ initialCache: this.state.tokenScanCache,
480
+ updateState: (cache) => {
481
+ this.update((draftState) => {
482
+ draftState.tokenScanCache = cache;
483
+ });
484
+ },
485
+ }), "f");
361
486
  __classPrivateFieldGet(this, _PhishingController_instances, "m", _PhishingController_registerMessageHandlers).call(this);
362
487
  this.updatePhishingDetector();
488
+ __classPrivateFieldGet(this, _PhishingController_instances, "m", _PhishingController_subscribeToTransactionControllerStateChange).call(this);
363
489
  }
364
490
  /**
365
491
  * Updates this.detector with an instance of PhishingDetector using the current state.
@@ -579,10 +705,62 @@ export class PhishingController extends BaseController {
579
705
  }
580
706
  }
581
707
  }
582
- _PhishingController_detector = new WeakMap(), _PhishingController_stalelistRefreshInterval = new WeakMap(), _PhishingController_hotlistRefreshInterval = new WeakMap(), _PhishingController_c2DomainBlocklistRefreshInterval = new WeakMap(), _PhishingController_urlScanCache = new WeakMap(), _PhishingController_inProgressHotlistUpdate = new WeakMap(), _PhishingController_inProgressStalelistUpdate = new WeakMap(), _PhishingController_isProgressC2DomainBlocklistUpdate = new WeakMap(), _PhishingController_processBatch = new WeakMap(), _PhishingController_instances = new WeakSet(), _PhishingController_registerMessageHandlers = function _PhishingController_registerMessageHandlers() {
708
+ _PhishingController_detector = new WeakMap(), _PhishingController_stalelistRefreshInterval = new WeakMap(), _PhishingController_hotlistRefreshInterval = new WeakMap(), _PhishingController_c2DomainBlocklistRefreshInterval = new WeakMap(), _PhishingController_urlScanCache = new WeakMap(), _PhishingController_tokenScanCache = new WeakMap(), _PhishingController_inProgressHotlistUpdate = new WeakMap(), _PhishingController_inProgressStalelistUpdate = new WeakMap(), _PhishingController_isProgressC2DomainBlocklistUpdate = new WeakMap(), _PhishingController_transactionControllerStateChangeHandler = new WeakMap(), _PhishingController_fetchTokenScanBulkResults = new WeakMap(), _PhishingController_processBatch = new WeakMap(), _PhishingController_instances = new WeakSet(), _PhishingController_subscribeToTransactionControllerStateChange = function _PhishingController_subscribeToTransactionControllerStateChange() {
709
+ this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _PhishingController_transactionControllerStateChangeHandler, "f"));
710
+ }, _PhishingController_registerMessageHandlers = function _PhishingController_registerMessageHandlers() {
583
711
  this.messagingSystem.registerActionHandler(`${controllerName}:maybeUpdateState`, this.maybeUpdateState.bind(this));
584
712
  this.messagingSystem.registerActionHandler(`${controllerName}:testOrigin`, this.test.bind(this));
585
713
  this.messagingSystem.registerActionHandler(`${controllerName}:bulkScanUrls`, this.bulkScanUrls.bind(this));
714
+ this.messagingSystem.registerActionHandler(`${controllerName}:bulkScanTokens`, this.bulkScanTokens.bind(this));
715
+ }, _PhishingController_isTransactionPatch = function _PhishingController_isTransactionPatch(patch) {
716
+ const { path } = patch;
717
+ return (path.length === 2 &&
718
+ path[0] === 'transactions' &&
719
+ typeof path[1] === 'number');
720
+ }, _PhishingController_onTransactionControllerStateChange = function _PhishingController_onTransactionControllerStateChange(_state, patches) {
721
+ try {
722
+ const tokensByChain = new Map();
723
+ for (const patch of patches) {
724
+ if (patch.op === 'remove') {
725
+ continue;
726
+ }
727
+ // Handle transaction-level patches (includes simulation data updates)
728
+ if (__classPrivateFieldGet(this, _PhishingController_instances, "m", _PhishingController_isTransactionPatch).call(this, patch)) {
729
+ const transaction = patch.value;
730
+ __classPrivateFieldGet(this, _PhishingController_instances, "m", _PhishingController_getTokensFromTransaction).call(this, transaction, tokensByChain);
731
+ }
732
+ }
733
+ __classPrivateFieldGet(this, _PhishingController_instances, "m", _PhishingController_scanTokensByChain).call(this, tokensByChain);
734
+ }
735
+ catch (error) {
736
+ console.error('Error processing transaction state change:', error);
737
+ }
738
+ }, _PhishingController_getTokensFromTransaction = function _PhishingController_getTokensFromTransaction(transaction, tokensByChain) {
739
+ // extract token addresses from simulation data
740
+ const tokenAddresses = transaction.simulationData?.tokenBalanceChanges?.map((tokenChange) => tokenChange.address.toLowerCase());
741
+ // add token addresses to the map by chainId
742
+ if (tokenAddresses && tokenAddresses.length > 0 && transaction.chainId) {
743
+ const chainId = transaction.chainId.toLowerCase();
744
+ if (!tokensByChain.has(chainId)) {
745
+ tokensByChain.set(chainId, new Set());
746
+ }
747
+ const chainTokens = tokensByChain.get(chainId);
748
+ if (chainTokens) {
749
+ for (const address of tokenAddresses) {
750
+ chainTokens.add(address);
751
+ }
752
+ }
753
+ }
754
+ }, _PhishingController_scanTokensByChain = function _PhishingController_scanTokensByChain(tokensByChain) {
755
+ for (const [chainId, tokenSet] of tokensByChain) {
756
+ if (tokenSet.size > 0) {
757
+ const tokens = Array.from(tokenSet);
758
+ this.bulkScanTokens({
759
+ chainId,
760
+ tokens,
761
+ }).catch((error) => console.error(`Error scanning tokens for chain ${chainId}:`, error));
762
+ }
763
+ }
586
764
  }, _PhishingController_updateStalelist =
587
765
  /**
588
766
  * Update the stalelist configuration.