@metamask-previews/phishing-controller 12.4.1-preview-6df5889d → 12.5.0-preview-72122b6f

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.
@@ -1,6 +1,7 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import { type PhishingDetectorResult, type PhishingDetectionScanResult } from "./types.cjs";
4
+ import { type UrlScanCacheEntry } from "./UrlScanCache.cjs";
4
5
  export declare const PHISHING_CONFIG_BASE_URL = "https://phishing-detection.api.cx.metamask.io";
5
6
  export declare const METAMASK_STALELIST_FILE = "/v1/stalelist";
6
7
  export declare const METAMASK_HOTLIST_DIFF_FILE = "/v1/diffsSince";
@@ -8,6 +9,7 @@ export declare const CLIENT_SIDE_DETECION_BASE_URL = "https://client-side-detect
8
9
  export declare const C2_DOMAIN_BLOCKLIST_ENDPOINT = "/v1/request-blocklist";
9
10
  export declare const PHISHING_DETECTION_BASE_URL = "https://dapp-scanning.api.cx.metamask.io";
10
11
  export declare const PHISHING_DETECTION_SCAN_ENDPOINT = "scan";
12
+ export declare const PHISHING_DETECTION_BULK_SCAN_ENDPOINT = "bulk-scan";
11
13
  export declare const C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL: number;
12
14
  export declare const HOTLIST_REFRESH_INTERVAL: number;
13
15
  export declare const STALELIST_REFRESH_INTERVAL: number;
@@ -151,19 +153,24 @@ export type PhishingControllerState = {
151
153
  hotlistLastFetched: number;
152
154
  stalelistLastFetched: number;
153
155
  c2DomainBlocklistLastFetched: number;
156
+ urlScanCache: Record<string, UrlScanCacheEntry>;
154
157
  };
155
158
  /**
156
- * @type PhishingControllerOptions
159
+ * PhishingControllerOptions
157
160
  *
158
161
  * Phishing controller options
159
- * @property stalelistRefreshInterval - Polling interval used to fetch stale list.
160
- * @property hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
161
- * @property c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
162
+ * stalelistRefreshInterval - Polling interval used to fetch stale list.
163
+ * hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
164
+ * c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
165
+ * urlScanCacheTTL - Time to live in seconds for cached scan results.
166
+ * urlScanCacheMaxSize - Maximum number of entries in the scan cache.
162
167
  */
163
168
  export type PhishingControllerOptions = {
164
169
  stalelistRefreshInterval?: number;
165
170
  hotlistRefreshInterval?: number;
166
171
  c2DomainBlocklistRefreshInterval?: number;
172
+ urlScanCacheTTL?: number;
173
+ urlScanCacheMaxSize?: number;
167
174
  messenger: PhishingControllerMessenger;
168
175
  state?: Partial<PhishingControllerState>;
169
176
  };
@@ -180,6 +187,18 @@ export type PhishingControllerActions = PhishingControllerGetStateAction | Maybe
180
187
  export type PhishingControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, PhishingControllerState>;
181
188
  export type PhishingControllerEvents = PhishingControllerStateChangeEvent;
182
189
  export type PhishingControllerMessenger = RestrictedMessenger<typeof controllerName, PhishingControllerActions, PhishingControllerEvents, never, never>;
190
+ /**
191
+ * BulkPhishingDetectionScanResponse
192
+ *
193
+ * Response for bulk phishing detection scan requests
194
+ * results - Record of domain names and their corresponding phishing detection scan results
195
+ *
196
+ * errors - Record of domain names and their corresponding errors
197
+ */
198
+ export type BulkPhishingDetectionScanResponse = {
199
+ results: Record<string, PhishingDetectionScanResult>;
200
+ errors: Record<string, string[]>;
201
+ };
183
202
  /**
184
203
  * Controller that manages community-maintained lists of approved and unapproved website origins.
185
204
  */
@@ -192,10 +211,12 @@ export declare class PhishingController extends BaseController<typeof controller
192
211
  * @param config.stalelistRefreshInterval - Polling interval used to fetch stale list.
193
212
  * @param config.hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
194
213
  * @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
214
+ * @param config.urlScanCacheTTL - Time to live in seconds for cached scan results.
215
+ * @param config.urlScanCacheMaxSize - Maximum number of entries in the scan cache.
195
216
  * @param config.messenger - The controller restricted messenger.
196
217
  * @param config.state - Initial state to set on this controller.
197
218
  */
198
- constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, messenger, state, }: PhishingControllerOptions);
219
+ constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, urlScanCacheTTL, urlScanCacheMaxSize, messenger, state, }: PhishingControllerOptions);
199
220
  /**
200
221
  * Updates this.detector with an instance of PhishingDetector using the current state.
201
222
  */
@@ -224,6 +245,22 @@ export declare class PhishingController extends BaseController<typeof controller
224
245
  * @param interval - the new interval, in ms.
225
246
  */
226
247
  setC2DomainBlocklistRefreshInterval(interval: number): void;
248
+ /**
249
+ * Set the time-to-live for URL scan cache entries.
250
+ *
251
+ * @param ttl - The TTL in seconds.
252
+ */
253
+ setUrlScanCacheTTL(ttl: number): void;
254
+ /**
255
+ * Set the maximum number of entries in the URL scan cache.
256
+ *
257
+ * @param maxSize - The maximum cache size.
258
+ */
259
+ setUrlScanCacheMaxSize(maxSize: number): void;
260
+ /**
261
+ * Clear the URL scan cache.
262
+ */
263
+ clearUrlScanCache(): void;
227
264
  /**
228
265
  * Determine if an update to the stalelist configuration is needed.
229
266
  *
@@ -308,6 +345,14 @@ export declare class PhishingController extends BaseController<typeof controller
308
345
  * @returns The phishing detection scan result.
309
346
  */
310
347
  scanUrl: (url: string) => Promise<PhishingDetectionScanResult>;
348
+ /**
349
+ * Scan multiple URLs for phishing in bulk. It will only scan the hostnames of the URLs.
350
+ * It also only supports web URLs.
351
+ *
352
+ * @param urls - The URLs to scan.
353
+ * @returns A mapping of URLs to their phishing detection scan results and errors.
354
+ */
355
+ bulkScanUrls: (urls: string[]) => Promise<BulkPhishingDetectionScanResponse>;
311
356
  }
312
357
  export default PhishingController;
313
358
  export type { PhishingDetectorResult };
@@ -1 +1 @@
1
- {"version":3,"file":"PhishingController.d.cts","sourceRoot":"","sources":["../src/PhishingController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAQ3D,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAEjC,oBAAgB;AASjB,eAAO,MAAM,wBAAwB,kDACY,CAAC;AAClD,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AACvD,eAAO,MAAM,0BAA0B,mBAAmB,CAAC;AAE3D,eAAO,MAAM,6BAA6B,qDACU,CAAC;AACrD,eAAO,MAAM,4BAA4B,0BAA0B,CAAC;AAEpE,eAAO,MAAM,2BAA2B,6CACI,CAAC;AAC7C,eAAO,MAAM,gCAAgC,SAAS,CAAC;AAEvD,eAAO,MAAM,oCAAoC,QAAS,CAAC;AAC3D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,eAAO,MAAM,0BAA0B,QAAoB,CAAC;AAE5D,eAAO,MAAM,sBAAsB,+DAA0D,CAAC;AAC9F,eAAO,MAAM,yBAAyB,gEAA6D,CAAC;AACpG,eAAO,MAAM,uBAAuB,0EAAoE,CAAC;AAEzG;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,WAAW,GACX,WAAW,GACX,mBAAmB,CAAC;AAExB;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAG9B,0BAA0B,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,GAAG,QAAQ,IAAI,SAAS,EAAE,CAAC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAIF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;AAEpC;;;GAGG;AACH,oBAAY,QAAQ;IAClB,uBAAuB,+BAA+B;CACvD;AAED;;GAEG;AACH,oBAAY,SAAS;IACnB,QAAQ,aAAa;CACtB;AAUD;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;CAElC,CAAC;AAEF,QAAA,MAAM,cAAc,uBAAuB,CAAC;AAwB5C;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,4BAA4B,EAAE,MAAM,CAAC;CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,SAAS,EAAE,2BAA2B,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,GAAG,OAAO,cAAc,mBAAmB,CAAC;IAClD,OAAO,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,GAAG,OAAO,cAAc,aAAa,CAAC;IAC5C,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,gBAAgB,GAChB,UAAU,CAAC;AAEf,MAAM,MAAM,kCAAkC,GAAG,0BAA0B,CACzE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,kCAAkC,CAAC;AAE1E,MAAM,MAAM,2BAA2B,GAAG,mBAAmB,CAC3D,OAAO,cAAc,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,KAAK,EACL,KAAK,CACN,CAAC;AAEF;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;IAiBC;;;;;;;;;OASG;gBACS,EACV,wBAAqD,EACrD,sBAAiD,EACjD,gCAAuE,EACvE,SAAS,EACT,KAAU,GACX,EAAE,yBAAyB;IAmC5B;;OAEG;IACH,sBAAsB;IAItB;;;;;;OAMG;IACH,2BAA2B,CAAC,QAAQ,EAAE,MAAM;IAI5C;;;;;;OAMG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM;IAI1C;;;;;;OAMG;IACH,mCAAmC,CAAC,QAAQ,EAAE,MAAM;IAIpD;;;;OAIG;IACH,oBAAoB;IAOpB;;;;OAIG;IACH,kBAAkB;IAOlB;;;;OAIG;IACH,4BAA4B;IAO5B;;;;;;;OAOG;IACG,gBAAgB;IAgBtB;;;;;;;;;OASG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB;IAS5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB;IASxD;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM;IAYrB;;;;;OAKG;IACG,uBAAuB;IAc7B;;;;;OAKG;IACG,aAAa;IAcnB;;;;;OAKG;IACG,eAAe;IAcrB;;;;;;OAMG;IACH,OAAO,QAAe,MAAM,KAAG,QAAQ,2BAA2B,CAAC,CAoDjE;CA8LH;AAED,eAAe,kBAAkB,CAAC;AAElC,YAAY,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"PhishingController.d.cts","sourceRoot":"","sources":["../src/PhishingController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAQ3D,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAEjC,oBAAgB;AACjB,OAAO,EAIL,KAAK,iBAAiB,EACvB,2BAAuB;AASxB,eAAO,MAAM,wBAAwB,kDACY,CAAC;AAClD,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AACvD,eAAO,MAAM,0BAA0B,mBAAmB,CAAC;AAE3D,eAAO,MAAM,6BAA6B,qDACU,CAAC;AACrD,eAAO,MAAM,4BAA4B,0BAA0B,CAAC;AAEpE,eAAO,MAAM,2BAA2B,6CACI,CAAC;AAC7C,eAAO,MAAM,gCAAgC,SAAS,CAAC;AACvD,eAAO,MAAM,qCAAqC,cAAc,CAAC;AAEjE,eAAO,MAAM,oCAAoC,QAAS,CAAC;AAC3D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,eAAO,MAAM,0BAA0B,QAAoB,CAAC;AAE5D,eAAO,MAAM,sBAAsB,+DAA0D,CAAC;AAC9F,eAAO,MAAM,yBAAyB,gEAA6D,CAAC;AACpG,eAAO,MAAM,uBAAuB,0EAAoE,CAAC;AAEzG;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,WAAW,GACX,WAAW,GACX,mBAAmB,CAAC;AAExB;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAG9B,0BAA0B,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,GAAG,QAAQ,IAAI,SAAS,EAAE,CAAC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAIF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;AAEpC;;;GAGG;AACH,oBAAY,QAAQ;IAClB,uBAAuB,+BAA+B;CACvD;AAED;;GAEG;AACH,oBAAY,SAAS;IACnB,QAAQ,aAAa;CACtB;AAUD;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;CAElC,CAAC;AAEF,QAAA,MAAM,cAAc,uBAAuB,CAAC;AA0B5C;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,4BAA4B,EAAE,MAAM,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACjD,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,2BAA2B,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,GAAG,OAAO,cAAc,mBAAmB,CAAC;IAClD,OAAO,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,GAAG,OAAO,cAAc,aAAa,CAAC;IAC5C,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,gBAAgB,GAChB,UAAU,CAAC;AAEf,MAAM,MAAM,kCAAkC,GAAG,0BAA0B,CACzE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,kCAAkC,CAAC;AAE1E,MAAM,MAAM,2BAA2B,GAAG,mBAAmB,CAC3D,OAAO,cAAc,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,KAAK,EACL,KAAK,CACN,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IACrD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAClC,CAAC;AAEF;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;IAmBC;;;;;;;;;;;OAWG;gBACS,EACV,wBAAqD,EACrD,sBAAiD,EACjD,gCAAuE,EACvE,eAA4C,EAC5C,mBAAqD,EACrD,SAAS,EACT,KAAU,GACX,EAAE,yBAAyB;IA8C5B;;OAEG;IACH,sBAAsB;IAItB;;;;;;OAMG;IACH,2BAA2B,CAAC,QAAQ,EAAE,MAAM;IAI5C;;;;;;OAMG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM;IAI1C;;;;;;OAMG;IACH,mCAAmC,CAAC,QAAQ,EAAE,MAAM;IAIpD;;;;OAIG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM;IAI9B;;;;OAIG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM;IAItC;;OAEG;IACH,iBAAiB;IAIjB;;;;OAIG;IACH,oBAAoB;IAOpB;;;;OAIG;IACH,kBAAkB;IAOlB;;;;OAIG;IACH,4BAA4B;IAO5B;;;;;;;OAOG;IACG,gBAAgB;IAgBtB;;;;;;;;;OASG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB;IAS5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB;IASxD;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM;IAYrB;;;;;OAKG;IACG,uBAAuB;IAc7B;;;;;OAKG;IACG,aAAa;IAcnB;;;;;OAKG;IACG,eAAe;IAcrB;;;;;;OAMG;IACH,OAAO,QAAe,MAAM,KAAG,QAAQ,2BAA2B,CAAC,CA6DjE;IAEF;;;;;;OAMG;IACH,YAAY,SACJ,MAAM,EAAE,KACb,QAAQ,iCAAiC,CAAC,CA6F3C;CA8PH;AAED,eAAe,kBAAkB,CAAC;AAElC,YAAY,EAAE,sBAAsB,EAAE,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import { type PhishingDetectorResult, type PhishingDetectionScanResult } from "./types.mjs";
4
+ import { type UrlScanCacheEntry } from "./UrlScanCache.mjs";
4
5
  export declare const PHISHING_CONFIG_BASE_URL = "https://phishing-detection.api.cx.metamask.io";
5
6
  export declare const METAMASK_STALELIST_FILE = "/v1/stalelist";
6
7
  export declare const METAMASK_HOTLIST_DIFF_FILE = "/v1/diffsSince";
@@ -8,6 +9,7 @@ export declare const CLIENT_SIDE_DETECION_BASE_URL = "https://client-side-detect
8
9
  export declare const C2_DOMAIN_BLOCKLIST_ENDPOINT = "/v1/request-blocklist";
9
10
  export declare const PHISHING_DETECTION_BASE_URL = "https://dapp-scanning.api.cx.metamask.io";
10
11
  export declare const PHISHING_DETECTION_SCAN_ENDPOINT = "scan";
12
+ export declare const PHISHING_DETECTION_BULK_SCAN_ENDPOINT = "bulk-scan";
11
13
  export declare const C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL: number;
12
14
  export declare const HOTLIST_REFRESH_INTERVAL: number;
13
15
  export declare const STALELIST_REFRESH_INTERVAL: number;
@@ -151,19 +153,24 @@ export type PhishingControllerState = {
151
153
  hotlistLastFetched: number;
152
154
  stalelistLastFetched: number;
153
155
  c2DomainBlocklistLastFetched: number;
156
+ urlScanCache: Record<string, UrlScanCacheEntry>;
154
157
  };
155
158
  /**
156
- * @type PhishingControllerOptions
159
+ * PhishingControllerOptions
157
160
  *
158
161
  * Phishing controller options
159
- * @property stalelistRefreshInterval - Polling interval used to fetch stale list.
160
- * @property hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
161
- * @property c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
162
+ * stalelistRefreshInterval - Polling interval used to fetch stale list.
163
+ * hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
164
+ * c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
165
+ * urlScanCacheTTL - Time to live in seconds for cached scan results.
166
+ * urlScanCacheMaxSize - Maximum number of entries in the scan cache.
162
167
  */
163
168
  export type PhishingControllerOptions = {
164
169
  stalelistRefreshInterval?: number;
165
170
  hotlistRefreshInterval?: number;
166
171
  c2DomainBlocklistRefreshInterval?: number;
172
+ urlScanCacheTTL?: number;
173
+ urlScanCacheMaxSize?: number;
167
174
  messenger: PhishingControllerMessenger;
168
175
  state?: Partial<PhishingControllerState>;
169
176
  };
@@ -180,6 +187,18 @@ export type PhishingControllerActions = PhishingControllerGetStateAction | Maybe
180
187
  export type PhishingControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, PhishingControllerState>;
181
188
  export type PhishingControllerEvents = PhishingControllerStateChangeEvent;
182
189
  export type PhishingControllerMessenger = RestrictedMessenger<typeof controllerName, PhishingControllerActions, PhishingControllerEvents, never, never>;
190
+ /**
191
+ * BulkPhishingDetectionScanResponse
192
+ *
193
+ * Response for bulk phishing detection scan requests
194
+ * results - Record of domain names and their corresponding phishing detection scan results
195
+ *
196
+ * errors - Record of domain names and their corresponding errors
197
+ */
198
+ export type BulkPhishingDetectionScanResponse = {
199
+ results: Record<string, PhishingDetectionScanResult>;
200
+ errors: Record<string, string[]>;
201
+ };
183
202
  /**
184
203
  * Controller that manages community-maintained lists of approved and unapproved website origins.
185
204
  */
@@ -192,10 +211,12 @@ export declare class PhishingController extends BaseController<typeof controller
192
211
  * @param config.stalelistRefreshInterval - Polling interval used to fetch stale list.
193
212
  * @param config.hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
194
213
  * @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
214
+ * @param config.urlScanCacheTTL - Time to live in seconds for cached scan results.
215
+ * @param config.urlScanCacheMaxSize - Maximum number of entries in the scan cache.
195
216
  * @param config.messenger - The controller restricted messenger.
196
217
  * @param config.state - Initial state to set on this controller.
197
218
  */
198
- constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, messenger, state, }: PhishingControllerOptions);
219
+ constructor({ stalelistRefreshInterval, hotlistRefreshInterval, c2DomainBlocklistRefreshInterval, urlScanCacheTTL, urlScanCacheMaxSize, messenger, state, }: PhishingControllerOptions);
199
220
  /**
200
221
  * Updates this.detector with an instance of PhishingDetector using the current state.
201
222
  */
@@ -224,6 +245,22 @@ export declare class PhishingController extends BaseController<typeof controller
224
245
  * @param interval - the new interval, in ms.
225
246
  */
226
247
  setC2DomainBlocklistRefreshInterval(interval: number): void;
248
+ /**
249
+ * Set the time-to-live for URL scan cache entries.
250
+ *
251
+ * @param ttl - The TTL in seconds.
252
+ */
253
+ setUrlScanCacheTTL(ttl: number): void;
254
+ /**
255
+ * Set the maximum number of entries in the URL scan cache.
256
+ *
257
+ * @param maxSize - The maximum cache size.
258
+ */
259
+ setUrlScanCacheMaxSize(maxSize: number): void;
260
+ /**
261
+ * Clear the URL scan cache.
262
+ */
263
+ clearUrlScanCache(): void;
227
264
  /**
228
265
  * Determine if an update to the stalelist configuration is needed.
229
266
  *
@@ -308,6 +345,14 @@ export declare class PhishingController extends BaseController<typeof controller
308
345
  * @returns The phishing detection scan result.
309
346
  */
310
347
  scanUrl: (url: string) => Promise<PhishingDetectionScanResult>;
348
+ /**
349
+ * Scan multiple URLs for phishing in bulk. It will only scan the hostnames of the URLs.
350
+ * It also only supports web URLs.
351
+ *
352
+ * @param urls - The URLs to scan.
353
+ * @returns A mapping of URLs to their phishing detection scan results and errors.
354
+ */
355
+ bulkScanUrls: (urls: string[]) => Promise<BulkPhishingDetectionScanResponse>;
311
356
  }
312
357
  export default PhishingController;
313
358
  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,13 +9,14 @@ 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_inProgressHotlistUpdate, _PhishingController_inProgressStalelistUpdate, _PhishingController_isProgressC2DomainBlocklistUpdate, _PhishingController_registerMessageHandlers, _PhishingController_updateStalelist, _PhishingController_updateHotlist, _PhishingController_updateC2DomainBlocklist, _PhishingController_queryConfig;
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;
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
17
  import { PhishingDetector } from "./PhishingDetector.mjs";
18
18
  import { PhishingDetectorResultType, RecommendedAction } from "./types.mjs";
19
+ import { DEFAULT_URL_SCAN_CACHE_MAX_SIZE, DEFAULT_URL_SCAN_CACHE_TTL, UrlScanCache } from "./UrlScanCache.mjs";
19
20
  import { applyDiffs, fetchTimeNow, getHostnameFromUrl, roundToNearestMinute, getHostnameFromWebUrl } from "./utils.mjs";
20
21
  export const PHISHING_CONFIG_BASE_URL = 'https://phishing-detection.api.cx.metamask.io';
21
22
  export const METAMASK_STALELIST_FILE = '/v1/stalelist';
@@ -24,6 +25,7 @@ export const CLIENT_SIDE_DETECION_BASE_URL = 'https://client-side-detection.api.
24
25
  export const C2_DOMAIN_BLOCKLIST_ENDPOINT = '/v1/request-blocklist';
25
26
  export const PHISHING_DETECTION_BASE_URL = 'https://dapp-scanning.api.cx.metamask.io';
26
27
  export const PHISHING_DETECTION_SCAN_ENDPOINT = 'scan';
28
+ export const PHISHING_DETECTION_BULK_SCAN_ENDPOINT = 'bulk-scan';
27
29
  export const C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL = 5 * 60; // 5 mins in seconds
28
30
  export const HOTLIST_REFRESH_INTERVAL = 5 * 60; // 5 mins in seconds
29
31
  export const STALELIST_REFRESH_INTERVAL = 30 * 24 * 60 * 60; // 30 days in seconds
@@ -66,6 +68,7 @@ const metadata = {
66
68
  hotlistLastFetched: { persist: true, anonymous: false },
67
69
  stalelistLastFetched: { persist: true, anonymous: false },
68
70
  c2DomainBlocklistLastFetched: { persist: true, anonymous: false },
71
+ urlScanCache: { persist: true, anonymous: false },
69
72
  };
70
73
  /**
71
74
  * Get a default empty state for the controller.
@@ -78,6 +81,7 @@ const getDefaultState = () => {
78
81
  hotlistLastFetched: 0,
79
82
  stalelistLastFetched: 0,
80
83
  c2DomainBlocklistLastFetched: 0,
84
+ urlScanCache: {},
81
85
  };
82
86
  };
83
87
  /**
@@ -91,10 +95,12 @@ export class PhishingController extends BaseController {
91
95
  * @param config.stalelistRefreshInterval - Polling interval used to fetch stale list.
92
96
  * @param config.hotlistRefreshInterval - Polling interval used to fetch hotlist diff list.
93
97
  * @param config.c2DomainBlocklistRefreshInterval - Polling interval used to fetch c2 domain blocklist.
98
+ * @param config.urlScanCacheTTL - Time to live in seconds for cached scan results.
99
+ * @param config.urlScanCacheMaxSize - Maximum number of entries in the scan cache.
94
100
  * @param config.messenger - The controller restricted messenger.
95
101
  * @param config.state - Initial state to set on this controller.
96
102
  */
97
- constructor({ stalelistRefreshInterval = STALELIST_REFRESH_INTERVAL, hotlistRefreshInterval = HOTLIST_REFRESH_INTERVAL, c2DomainBlocklistRefreshInterval = C2_DOMAIN_BLOCKLIST_REFRESH_INTERVAL, messenger, state = {}, }) {
103
+ 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 = {}, }) {
98
104
  super({
99
105
  name: controllerName,
100
106
  metadata,
@@ -111,6 +117,7 @@ export class PhishingController extends BaseController {
111
117
  _PhishingController_stalelistRefreshInterval.set(this, void 0);
112
118
  _PhishingController_hotlistRefreshInterval.set(this, void 0);
113
119
  _PhishingController_c2DomainBlocklistRefreshInterval.set(this, void 0);
120
+ _PhishingController_urlScanCache.set(this, void 0);
114
121
  _PhishingController_inProgressHotlistUpdate.set(this, void 0);
115
122
  _PhishingController_inProgressStalelistUpdate.set(this, void 0);
116
123
  _PhishingController_isProgressC2DomainBlocklistUpdate.set(this, void 0);
@@ -130,6 +137,10 @@ export class PhishingController extends BaseController {
130
137
  fetchError: 'url is not a valid web URL',
131
138
  };
132
139
  }
140
+ const cachedResult = __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").get(hostname);
141
+ if (cachedResult) {
142
+ return cachedResult;
143
+ }
133
144
  const apiResponse = await safelyExecuteWithTimeout(async () => {
134
145
  const res = await fetch(`${PHISHING_DETECTION_BASE_URL}/${PHISHING_DETECTION_SCAN_ENDPOINT}?url=${encodeURIComponent(hostname)}`, {
135
146
  method: 'GET',
@@ -160,14 +171,163 @@ export class PhishingController extends BaseController {
160
171
  fetchError: apiResponse.error,
161
172
  };
162
173
  }
163
- return {
174
+ const result = {
164
175
  domainName: hostname,
165
176
  recommendedAction: apiResponse.recommendedAction,
166
177
  };
178
+ __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").add(hostname, result);
179
+ return result;
180
+ };
181
+ /**
182
+ * Scan multiple URLs for phishing in bulk. It will only scan the hostnames of the URLs.
183
+ * It also only supports web URLs.
184
+ *
185
+ * @param urls - The URLs to scan.
186
+ * @returns A mapping of URLs to their phishing detection scan results and errors.
187
+ */
188
+ this.bulkScanUrls = async (urls) => {
189
+ if (!urls || urls.length === 0) {
190
+ return {
191
+ results: {},
192
+ errors: {},
193
+ };
194
+ }
195
+ // we are arbitrarily limiting the number of URLs to 250
196
+ const MAX_TOTAL_URLS = 250;
197
+ if (urls.length > MAX_TOTAL_URLS) {
198
+ return {
199
+ results: {},
200
+ errors: {
201
+ too_many_urls: [
202
+ `Maximum of ${MAX_TOTAL_URLS} URLs allowed per request`,
203
+ ],
204
+ },
205
+ };
206
+ }
207
+ const MAX_URL_LENGTH = 2048;
208
+ const combinedResponse = {
209
+ results: {},
210
+ errors: {},
211
+ };
212
+ // Extract hostnames from URLs and check for validity and length constraints
213
+ const urlsToHostnames = {};
214
+ const urlsToFetch = [];
215
+ for (const url of urls) {
216
+ if (url.length > MAX_URL_LENGTH) {
217
+ combinedResponse.errors[url] = [
218
+ `URL length must not exceed ${MAX_URL_LENGTH} characters`,
219
+ ];
220
+ continue;
221
+ }
222
+ const [hostname, ok] = getHostnameFromWebUrl(url);
223
+ if (!ok) {
224
+ combinedResponse.errors[url] = ['url is not a valid web URL'];
225
+ continue;
226
+ }
227
+ // Check if result is already in cache
228
+ const cachedResult = __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").get(hostname);
229
+ if (cachedResult) {
230
+ // Use cached result
231
+ combinedResponse.results[url] = cachedResult;
232
+ }
233
+ else {
234
+ // Add to list of URLs to fetch
235
+ urlsToHostnames[url] = hostname;
236
+ urlsToFetch.push(url);
237
+ }
238
+ }
239
+ // If there are URLs to fetch, process them in batches
240
+ if (urlsToFetch.length > 0) {
241
+ // The API has a limit of 50 URLs per request, so we batch the requests
242
+ const MAX_URLS_PER_BATCH = 50;
243
+ const batches = [];
244
+ for (let i = 0; i < urlsToFetch.length; i += MAX_URLS_PER_BATCH) {
245
+ batches.push(urlsToFetch.slice(i, i + MAX_URLS_PER_BATCH));
246
+ }
247
+ // Process each batch in parallel
248
+ const batchResults = await Promise.all(batches.map((batchUrls) => __classPrivateFieldGet(this, _PhishingController_processBatch, "f").call(this, batchUrls)));
249
+ // Merge results and errors from all batches
250
+ batchResults.forEach((batchResponse) => {
251
+ // Add results to cache and combine with response
252
+ Object.entries(batchResponse.results).forEach(([url, result]) => {
253
+ const hostname = urlsToHostnames[url];
254
+ if (hostname) {
255
+ __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").add(hostname, result);
256
+ }
257
+ combinedResponse.results[url] = result;
258
+ });
259
+ // Combine errors
260
+ Object.entries(batchResponse.errors).forEach(([key, messages]) => {
261
+ combinedResponse.errors[key] = [
262
+ ...(combinedResponse.errors[key] || []),
263
+ ...messages,
264
+ ];
265
+ });
266
+ });
267
+ }
268
+ return combinedResponse;
167
269
  };
270
+ /**
271
+ * Process a batch of URLs (up to 50) for phishing detection.
272
+ *
273
+ * @param urls - A batch of URLs to scan.
274
+ * @returns The scan results and errors for this batch.
275
+ */
276
+ _PhishingController_processBatch.set(this, async (urls) => {
277
+ const apiResponse = await safelyExecuteWithTimeout(async () => {
278
+ const res = await fetch(`${PHISHING_DETECTION_BASE_URL}/${PHISHING_DETECTION_BULK_SCAN_ENDPOINT}`, {
279
+ method: 'POST',
280
+ headers: {
281
+ Accept: 'application/json',
282
+ 'Content-Type': 'application/json',
283
+ },
284
+ body: JSON.stringify({ urls }),
285
+ });
286
+ if (!res.ok) {
287
+ return {
288
+ error: `${res.status} ${res.statusText}`,
289
+ status: res.status,
290
+ statusText: res.statusText,
291
+ };
292
+ }
293
+ const data = await res.json();
294
+ return data;
295
+ }, true, 15000);
296
+ // Handle timeout or network errors
297
+ if (!apiResponse) {
298
+ return {
299
+ results: {},
300
+ errors: {
301
+ network_error: ['timeout of 15000ms exceeded'],
302
+ },
303
+ };
304
+ }
305
+ // Handle HTTP error responses
306
+ if ('error' in apiResponse &&
307
+ 'status' in apiResponse &&
308
+ 'statusText' in apiResponse) {
309
+ return {
310
+ results: {},
311
+ errors: {
312
+ api_error: [`${apiResponse.status} ${apiResponse.statusText}`],
313
+ },
314
+ };
315
+ }
316
+ return apiResponse;
317
+ });
168
318
  __classPrivateFieldSet(this, _PhishingController_stalelistRefreshInterval, stalelistRefreshInterval, "f");
169
319
  __classPrivateFieldSet(this, _PhishingController_hotlistRefreshInterval, hotlistRefreshInterval, "f");
170
320
  __classPrivateFieldSet(this, _PhishingController_c2DomainBlocklistRefreshInterval, c2DomainBlocklistRefreshInterval, "f");
321
+ __classPrivateFieldSet(this, _PhishingController_urlScanCache, new UrlScanCache({
322
+ cacheTTL: urlScanCacheTTL,
323
+ maxCacheSize: urlScanCacheMaxSize,
324
+ initialCache: this.state.urlScanCache,
325
+ updateState: (cache) => {
326
+ this.update((draftState) => {
327
+ draftState.urlScanCache = cache;
328
+ });
329
+ },
330
+ }), "f");
171
331
  __classPrivateFieldGet(this, _PhishingController_instances, "m", _PhishingController_registerMessageHandlers).call(this);
172
332
  this.updatePhishingDetector();
173
333
  }
@@ -207,6 +367,28 @@ export class PhishingController extends BaseController {
207
367
  setC2DomainBlocklistRefreshInterval(interval) {
208
368
  __classPrivateFieldSet(this, _PhishingController_c2DomainBlocklistRefreshInterval, interval, "f");
209
369
  }
370
+ /**
371
+ * Set the time-to-live for URL scan cache entries.
372
+ *
373
+ * @param ttl - The TTL in seconds.
374
+ */
375
+ setUrlScanCacheTTL(ttl) {
376
+ __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").setTTL(ttl);
377
+ }
378
+ /**
379
+ * Set the maximum number of entries in the URL scan cache.
380
+ *
381
+ * @param maxSize - The maximum cache size.
382
+ */
383
+ setUrlScanCacheMaxSize(maxSize) {
384
+ __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").setMaxSize(maxSize);
385
+ }
386
+ /**
387
+ * Clear the URL scan cache.
388
+ */
389
+ clearUrlScanCache() {
390
+ __classPrivateFieldGet(this, _PhishingController_urlScanCache, "f").clear();
391
+ }
210
392
  /**
211
393
  * Determine if an update to the stalelist configuration is needed.
212
394
  *
@@ -367,7 +549,7 @@ export class PhishingController extends BaseController {
367
549
  }
368
550
  }
369
551
  }
370
- _PhishingController_detector = new WeakMap(), _PhishingController_stalelistRefreshInterval = new WeakMap(), _PhishingController_hotlistRefreshInterval = new WeakMap(), _PhishingController_c2DomainBlocklistRefreshInterval = new WeakMap(), _PhishingController_inProgressHotlistUpdate = new WeakMap(), _PhishingController_inProgressStalelistUpdate = new WeakMap(), _PhishingController_isProgressC2DomainBlocklistUpdate = new WeakMap(), _PhishingController_instances = new WeakSet(), _PhishingController_registerMessageHandlers = function _PhishingController_registerMessageHandlers() {
552
+ _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() {
371
553
  this.messagingSystem.registerActionHandler(`${controllerName}:maybeUpdateState`, this.maybeUpdateState.bind(this));
372
554
  this.messagingSystem.registerActionHandler(`${controllerName}:testOrigin`, this.test.bind(this));
373
555
  }, _PhishingController_updateStalelist =
@@ -408,7 +590,6 @@ async function _PhishingController_updateStalelist() {
408
590
  return;
409
591
  }
410
592
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
411
- // eslint-disable-next-line @typescript-eslint/naming-convention
412
593
  const { eth_phishing_detect_config, ...partialState } = stalelistResponse.data;
413
594
  const metamaskListState = {
414
595
  ...eth_phishing_detect_config,