@metamask-previews/shield-controller 5.1.3-preview-d79fb25d4 → 5.1.3-preview-beea66146

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 +0 -14
  2. package/dist/ShieldController.cjs +9 -7
  3. package/dist/ShieldController.cjs.map +1 -1
  4. package/dist/ShieldController.d.cts +3 -7
  5. package/dist/ShieldController.d.cts.map +1 -1
  6. package/dist/ShieldController.d.mts +3 -7
  7. package/dist/ShieldController.d.mts.map +1 -1
  8. package/dist/ShieldController.mjs +9 -7
  9. package/dist/ShieldController.mjs.map +1 -1
  10. package/dist/backend.cjs +289 -0
  11. package/dist/backend.cjs.map +1 -0
  12. package/dist/backend.d.cts +72 -0
  13. package/dist/backend.d.cts.map +1 -0
  14. package/dist/backend.d.mts +72 -0
  15. package/dist/backend.d.mts.map +1 -0
  16. package/dist/backend.mjs +283 -0
  17. package/dist/backend.mjs.map +1 -0
  18. package/dist/constants.cjs +1 -33
  19. package/dist/constants.cjs.map +1 -1
  20. package/dist/constants.d.cts +0 -20
  21. package/dist/constants.d.cts.map +1 -1
  22. package/dist/constants.d.mts +0 -20
  23. package/dist/constants.d.mts.map +1 -1
  24. package/dist/constants.mjs +0 -31
  25. package/dist/constants.mjs.map +1 -1
  26. package/dist/index.cjs +4 -10
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +2 -5
  29. package/dist/index.d.cts.map +1 -1
  30. package/dist/index.d.mts +2 -5
  31. package/dist/index.d.mts.map +1 -1
  32. package/dist/index.mjs +1 -2
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/types.cjs.map +1 -1
  35. package/dist/types.d.cts +6 -0
  36. package/dist/types.d.cts.map +1 -1
  37. package/dist/types.d.mts +6 -0
  38. package/dist/types.d.mts.map +1 -1
  39. package/dist/types.mjs.map +1 -1
  40. package/package.json +1 -4
  41. package/dist/shield-api-service-method-action-types.cjs +0 -7
  42. package/dist/shield-api-service-method-action-types.cjs.map +0 -1
  43. package/dist/shield-api-service-method-action-types.d.cts +0 -48
  44. package/dist/shield-api-service-method-action-types.d.cts.map +0 -1
  45. package/dist/shield-api-service-method-action-types.d.mts +0 -48
  46. package/dist/shield-api-service-method-action-types.d.mts.map +0 -1
  47. package/dist/shield-api-service-method-action-types.mjs +0 -6
  48. package/dist/shield-api-service-method-action-types.mjs.map +0 -1
  49. package/dist/shield-api-service.cjs +0 -371
  50. package/dist/shield-api-service.cjs.map +0 -1
  51. package/dist/shield-api-service.d.cts +0 -161
  52. package/dist/shield-api-service.d.cts.map +0 -1
  53. package/dist/shield-api-service.d.mts +0 -161
  54. package/dist/shield-api-service.d.mts.map +0 -1
  55. package/dist/shield-api-service.mjs +0 -365
  56. package/dist/shield-api-service.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,22 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Added
11
-
12
- - Add `ShieldApiService`, a `BaseDataService` that communicates with the Shield API and authenticates via `AuthenticationController:getBearerToken` on its own messenger ([#9616](https://github.com/MetaMask/core/pull/9616))
13
- - Exposes `checkCoverage`, `checkSignatureCoverage`, `logSignature`, and `logTransaction` as `ShieldApiService:*` messenger actions.
14
- - Also export `ShieldApiServiceMessenger`, related action/event types, and `serviceName`.
15
- - Add `Env` enum, `SHIELD_API_URL_MAP`, and `getShieldApiBaseUrl` for resolving the shield API URL per environment ([#9616](https://github.com/MetaMask/core/pull/9616))
16
- - Add `@metamask/base-data-service` `^0.1.3` and `@metamask/profile-sync-controller` `^28.3.0` as dependencies ([#9616](https://github.com/MetaMask/core/pull/9616))
17
-
18
10
  ### Changed
19
11
 
20
- - **BREAKING:** Replace `ShieldRemoteBackend` and `createShieldRemoteBackend` with `ShieldApiService` ([#9616](https://github.com/MetaMask/core/pull/9616))
21
- - Consumers must instantiate `ShieldApiService` separately and delegate `AuthenticationController:getBearerToken` to its messenger.
22
- - `ShieldController` now calls `ShieldApiService:*` actions instead of accepting an injected `backend`.
23
- - **BREAKING:** Remove `ShieldBackend`, `ShieldRemoteBackend`, `createShieldRemoteBackend`, and `CreateShieldRemoteBackendOptions` exports ([#9616](https://github.com/MetaMask/core/pull/9616))
24
- - **BREAKING:** Remove `backend` from `ShieldControllerOptions` ([#9616](https://github.com/MetaMask/core/pull/9616))
25
- - **BREAKING:** Replace `AuthenticationController:getBearerToken` on `ShieldControllerMessenger` with the four `ShieldApiService:*` actions ([#9616](https://github.com/MetaMask/core/pull/9616))
26
12
  - Bump `@metamask/transaction-controller` from `^69.0.0` to `^69.4.0` ([#9568](https://github.com/MetaMask/core/pull/9568), [#9589](https://github.com/MetaMask/core/pull/9589), [#9593](https://github.com/MetaMask/core/pull/9593), [#9693](https://github.com/MetaMask/core/pull/9693), [#9735](https://github.com/MetaMask/core/pull/9735))
27
13
  - Bump `@metamask/signature-controller` from `^39.2.7` to `^39.2.9` ([#9721](https://github.com/MetaMask/core/pull/9721), [#9735](https://github.com/MetaMask/core/pull/9735))
28
14
 
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  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");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _ShieldController_instances, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_normalizeSignatureRequest, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_started, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction, _ShieldController_getCoverageShownStatus, _ShieldController_getLatestCoverageId;
13
+ var _ShieldController_instances, _ShieldController_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_normalizeSignatureRequest, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_started, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction, _ShieldController_getCoverageShownStatus, _ShieldController_getLatestCoverageId;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ShieldController = exports.getDefaultShieldControllerState = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
@@ -59,7 +59,7 @@ const metadata = {
59
59
  };
60
60
  class ShieldController extends base_controller_1.BaseController {
61
61
  constructor(options) {
62
- const { messenger, state, transactionHistoryLimit = 100, coverageHistoryLimit = 10, normalizeSignatureRequest, } = options;
62
+ const { messenger, state, backend, transactionHistoryLimit = 100, coverageHistoryLimit = 10, normalizeSignatureRequest, } = options;
63
63
  super({
64
64
  name: constants_js_1.controllerName,
65
65
  metadata,
@@ -70,12 +70,14 @@ class ShieldController extends base_controller_1.BaseController {
70
70
  },
71
71
  });
72
72
  _ShieldController_instances.add(this);
73
+ _ShieldController_backend.set(this, void 0);
73
74
  _ShieldController_coverageHistoryLimit.set(this, void 0);
74
75
  _ShieldController_transactionHistoryLimit.set(this, void 0);
75
76
  _ShieldController_normalizeSignatureRequest.set(this, void 0);
76
77
  _ShieldController_transactionControllerStateChangeHandler.set(this, void 0);
77
78
  _ShieldController_signatureControllerStateChangeHandler.set(this, void 0);
78
79
  _ShieldController_started.set(this, void 0);
80
+ __classPrivateFieldSet(this, _ShieldController_backend, backend, "f");
79
81
  __classPrivateFieldSet(this, _ShieldController_coverageHistoryLimit, coverageHistoryLimit, "f");
80
82
  __classPrivateFieldSet(this, _ShieldController_transactionHistoryLimit, transactionHistoryLimit, "f");
81
83
  __classPrivateFieldSet(this, _ShieldController_transactionControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleTransactionControllerStateChange).bind(this), "f");
@@ -123,7 +125,7 @@ class ShieldController extends base_controller_1.BaseController {
123
125
  async checkCoverage(txMeta) {
124
126
  // Check coverage
125
127
  const coverageId = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getLatestCoverageId).call(this, txMeta.id);
126
- const coverageResult = await this.messenger.call('ShieldApiService:checkCoverage', {
128
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage({
127
129
  txMeta,
128
130
  coverageId,
129
131
  });
@@ -147,7 +149,7 @@ class ShieldController extends base_controller_1.BaseController {
147
149
  const clonedSignatureRequest = (0, lodash_1.cloneDeep)(signatureRequest);
148
150
  const normalizedSignatureRequest = __classPrivateFieldGet(this, _ShieldController_normalizeSignatureRequest, "f")?.call(this, clonedSignatureRequest) ??
149
151
  clonedSignatureRequest;
150
- const coverageResult = await this.messenger.call('ShieldApiService:checkSignatureCoverage', {
152
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkSignatureCoverage({
151
153
  signatureRequest: normalizedSignatureRequest,
152
154
  coverageId,
153
155
  });
@@ -159,7 +161,7 @@ class ShieldController extends base_controller_1.BaseController {
159
161
  }
160
162
  }
161
163
  exports.ShieldController = ShieldController;
162
- _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_normalizeSignatureRequest = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_signatureControllerStateChangeHandler = new WeakMap(), _ShieldController_started = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleSignatureControllerStateChange = function _ShieldController_handleSignatureControllerStateChange(signatureRequests, previousSignatureRequests) {
164
+ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_normalizeSignatureRequest = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_signatureControllerStateChangeHandler = new WeakMap(), _ShieldController_started = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleSignatureControllerStateChange = function _ShieldController_handleSignatureControllerStateChange(signatureRequests, previousSignatureRequests) {
163
165
  const signatureRequestsArray = Object.values(signatureRequests);
164
166
  const previousSignatureRequestsArray = Object.values(previousSignatureRequests ?? {});
165
167
  const previousSignatureRequestsById = new Map(previousSignatureRequestsArray.map((request) => [request.id, request]));
@@ -256,7 +258,7 @@ _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transa
256
258
  throw new Error('Signature not found');
257
259
  }
258
260
  const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, signatureRequest.id);
259
- await this.messenger.call('ShieldApiService:logSignature', {
261
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logSignature({
260
262
  signatureRequest,
261
263
  signature,
262
264
  status,
@@ -271,7 +273,7 @@ _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transa
271
273
  throw new Error('Raw transaction hex not found');
272
274
  }
273
275
  const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, txMeta.id);
274
- await this.messenger.call('ShieldApiService:logTransaction', {
276
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logTransaction({
275
277
  txMeta,
276
278
  transactionHash,
277
279
  rawTransactionHex,
@@ -1 +1 @@
1
- {"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { SignatureRequestStatus } from '@metamask/signature-controller';\nimport type {\n SignatureRequest,\n SignatureStateChange,\n} from '@metamask/signature-controller';\nimport { TransactionStatus } from '@metamask/transaction-controller';\nimport type {\n TransactionControllerStateChangeEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants.js';\nimport { projectLogger, createModuleLogger } from './logger.js';\nimport type { ShieldApiServiceMethodActions } from './shield-api-service-method-action-types.js';\nimport type { ShieldControllerMethodActions } from './ShieldController-method-action-types.js';\nimport type { CoverageResult, NormalizeSignatureRequestFn } from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'start',\n 'stop',\n 'clearState',\n 'checkCoverage',\n 'checkSignatureCoverage',\n] as const;\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerMethodActions;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external actions available to the ShieldController.\n */\ntype AllowedActions = ShieldApiServiceMethodActions;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Start the ShieldController and subscribe to the transaction and signature controller state changes.\n */\n start(): void {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n /**\n * Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.\n */\n stop(): void {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n /**\n * Clears the shield state and resets to default values.\n */\n clearState(): void {\n this.update(() => {\n return getDefaultShieldControllerState();\n });\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ): void {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ): void {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n if (\n // We don't need to check coverage for submitted or confirmed transactions.\n transaction.status !== TransactionStatus.submitted &&\n transaction.status !== TransactionStatus.confirmed\n ) {\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n previousTransaction?.simulationData &&\n !isEqual(\n transaction.simulationData,\n previousTransaction.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.messenger.call(\n 'ShieldApiService:checkCoverage',\n {\n txMeta,\n coverageId,\n },\n );\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.messenger.call(\n 'ShieldApiService:checkSignatureCoverage',\n {\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n },\n );\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult): void {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest): Promise<void> {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageShownStatus(signatureRequest.id);\n\n await this.messenger.call('ShieldApiService:logSignature', {\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta): Promise<void> {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const rawTransactionHex = txMeta.rawTx;\n if (!rawTransactionHex) {\n throw new Error('Raw transaction hex not found');\n }\n\n const { status } = this.#getCoverageShownStatus(txMeta.id);\n\n await this.messenger.call('ShieldApiService:logTransaction', {\n txMeta,\n transactionHash,\n rawTransactionHex,\n status,\n });\n }\n\n /**\n * Get the coverage shown status for a given item ID.\n *\n * @param itemId - The item ID to get the coverage status for.\n * @returns The coverage status.\n */\n #getCoverageShownStatus(itemId: string): { status: string } {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
1
+ {"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { SignatureRequestStatus } from '@metamask/signature-controller';\nimport type {\n SignatureRequest,\n SignatureStateChange,\n} from '@metamask/signature-controller';\nimport { TransactionStatus } from '@metamask/transaction-controller';\nimport type {\n TransactionControllerStateChangeEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants.js';\nimport { projectLogger, createModuleLogger } from './logger.js';\nimport type { ShieldControllerMethodActions } from './ShieldController-method-action-types.js';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'start',\n 'stop',\n 'clearState',\n 'checkCoverage',\n 'checkSignatureCoverage',\n] as const;\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerMethodActions;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Start the ShieldController and subscribe to the transaction and signature controller state changes.\n */\n start(): void {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n /**\n * Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.\n */\n stop(): void {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n /**\n * Clears the shield state and resets to default values.\n */\n clearState(): void {\n this.update(() => {\n return getDefaultShieldControllerState();\n });\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ): void {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ): void {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n if (\n // We don't need to check coverage for submitted or confirmed transactions.\n transaction.status !== TransactionStatus.submitted &&\n transaction.status !== TransactionStatus.confirmed\n ) {\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n previousTransaction?.simulationData &&\n !isEqual(\n transaction.simulationData,\n previousTransaction.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult): void {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest): Promise<void> {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageShownStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta): Promise<void> {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const rawTransactionHex = txMeta.rawTx;\n if (!rawTransactionHex) {\n throw new Error('Raw transaction hex not found');\n }\n\n const { status } = this.#getCoverageShownStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n rawTransactionHex,\n status,\n });\n }\n\n /**\n * Get the coverage shown status for a given item ID.\n *\n * @param itemId - The item ID to get the coverage status for.\n * @returns The coverage status.\n */\n #getCoverageShownStatus(itemId: string): { status: string } {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
@@ -4,9 +4,8 @@ import type { Messenger } from "@metamask/messenger";
4
4
  import type { SignatureRequest, SignatureStateChange } from "@metamask/signature-controller";
5
5
  import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
6
6
  import { controllerName } from "./constants.cjs";
7
- import type { ShieldApiServiceMethodActions } from "./shield-api-service-method-action-types.cjs";
8
7
  import type { ShieldControllerMethodActions } from "./ShieldController-method-action-types.cjs";
9
- import type { CoverageResult, NormalizeSignatureRequestFn } from "./types.cjs";
8
+ import type { CoverageResult, NormalizeSignatureRequestFn, ShieldBackend } from "./types.cjs";
10
9
  export type CoverageResultRecordEntry = {
11
10
  /**
12
11
  * History of coverage results, latest first.
@@ -44,10 +43,6 @@ export type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<typeof
44
43
  * The internal events available to the ShieldController.
45
44
  */
46
45
  export type ShieldControllerEvents = ShieldControllerCoverageResultReceivedEvent | ShieldControllerStateChangeEvent;
47
- /**
48
- * The external actions available to the ShieldController.
49
- */
50
- type AllowedActions = ShieldApiServiceMethodActions;
51
46
  /**
52
47
  * The external events available to the ShieldController.
53
48
  */
@@ -55,10 +50,11 @@ type AllowedEvents = SignatureStateChange | TransactionControllerStateChangeEven
55
50
  /**
56
51
  * The messenger of the {@link ShieldController}.
57
52
  */
58
- export type ShieldControllerMessenger = Messenger<typeof controllerName, ShieldControllerActions | AllowedActions, ShieldControllerEvents | AllowedEvents>;
53
+ export type ShieldControllerMessenger = Messenger<typeof controllerName, ShieldControllerActions, ShieldControllerEvents | AllowedEvents>;
59
54
  export type ShieldControllerOptions = {
60
55
  messenger: ShieldControllerMessenger;
61
56
  state?: Partial<ShieldControllerState>;
57
+ backend: ShieldBackend;
62
58
  transactionHistoryLimit?: number;
63
59
  coverageHistoryLimit?: number;
64
60
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ShieldController.d.cts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,uCAAuC;AAExC,OAAO,KAAK,EACV,qCAAqC,EACrC,eAAe,EAChB,yCAAyC;AAG1C,OAAO,EAAE,cAAc,EAAE,wBAAuB;AAEhD,OAAO,KAAK,EAAE,6BAA6B,EAAE,qDAAoD;AACjG,OAAO,KAAK,EAAE,6BAA6B,EAAE,mDAAkD;AAC/F,OAAO,KAAK,EAAE,cAAc,EAAE,2BAA2B,EAAE,oBAAmB;AAY9E,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF;;OAEG;IACH,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,MAAM,MAAM,8BAA8B,GAAG,wBAAwB,CACnE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,yBAAyB,CAAC;IACxD,OAAO,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,cAAc,GAAG,6BAA6B,CAAC;AAEpD;;GAEG;AACH,KAAK,aAAa,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAC/C,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,CACvC,CAAC;AAqBF,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,yBAAyB,CAAC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;OAQG;IACH,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;CACzD,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAmBa,OAAO,EAAE,uBAAuB;IAiC5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;OAEG;IACH,UAAU,IAAI,IAAI;IA4FlB;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAuBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CAuI3B"}
1
+ {"version":3,"file":"ShieldController.d.cts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,uCAAuC;AAExC,OAAO,KAAK,EACV,qCAAqC,EACrC,eAAe,EAChB,yCAAyC;AAG1C,OAAO,EAAE,cAAc,EAAE,wBAAuB;AAEhD,OAAO,KAAK,EAAE,6BAA6B,EAAE,mDAAkD;AAC/F,OAAO,KAAK,EACV,cAAc,EACd,2BAA2B,EAC3B,aAAa,EACd,oBAAmB;AAYpB,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF;;OAEG;IACH,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,MAAM,MAAM,8BAA8B,GAAG,wBAAwB,CACnE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,yBAAyB,CAAC;IACxD,OAAO,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,aAAa,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAC/C,OAAO,cAAc,EACrB,uBAAuB,EACvB,sBAAsB,GAAG,aAAa,CACvC,CAAC;AAqBF,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,yBAAyB,CAAC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,OAAO,EAAE,aAAa,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;OAQG;IACH,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;CACzD,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAqBa,OAAO,EAAE,uBAAuB;IAmC5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;OAEG;IACH,UAAU,IAAI,IAAI;IA4FlB;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAoBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CAoI3B"}
@@ -4,9 +4,8 @@ import type { Messenger } from "@metamask/messenger";
4
4
  import type { SignatureRequest, SignatureStateChange } from "@metamask/signature-controller";
5
5
  import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
6
6
  import { controllerName } from "./constants.mjs";
7
- import type { ShieldApiServiceMethodActions } from "./shield-api-service-method-action-types.mjs";
8
7
  import type { ShieldControllerMethodActions } from "./ShieldController-method-action-types.mjs";
9
- import type { CoverageResult, NormalizeSignatureRequestFn } from "./types.mjs";
8
+ import type { CoverageResult, NormalizeSignatureRequestFn, ShieldBackend } from "./types.mjs";
10
9
  export type CoverageResultRecordEntry = {
11
10
  /**
12
11
  * History of coverage results, latest first.
@@ -44,10 +43,6 @@ export type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<typeof
44
43
  * The internal events available to the ShieldController.
45
44
  */
46
45
  export type ShieldControllerEvents = ShieldControllerCoverageResultReceivedEvent | ShieldControllerStateChangeEvent;
47
- /**
48
- * The external actions available to the ShieldController.
49
- */
50
- type AllowedActions = ShieldApiServiceMethodActions;
51
46
  /**
52
47
  * The external events available to the ShieldController.
53
48
  */
@@ -55,10 +50,11 @@ type AllowedEvents = SignatureStateChange | TransactionControllerStateChangeEven
55
50
  /**
56
51
  * The messenger of the {@link ShieldController}.
57
52
  */
58
- export type ShieldControllerMessenger = Messenger<typeof controllerName, ShieldControllerActions | AllowedActions, ShieldControllerEvents | AllowedEvents>;
53
+ export type ShieldControllerMessenger = Messenger<typeof controllerName, ShieldControllerActions, ShieldControllerEvents | AllowedEvents>;
59
54
  export type ShieldControllerOptions = {
60
55
  messenger: ShieldControllerMessenger;
61
56
  state?: Partial<ShieldControllerState>;
57
+ backend: ShieldBackend;
62
58
  transactionHistoryLimit?: number;
63
59
  coverageHistoryLimit?: number;
64
60
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ShieldController.d.mts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,uCAAuC;AAExC,OAAO,KAAK,EACV,qCAAqC,EACrC,eAAe,EAChB,yCAAyC;AAG1C,OAAO,EAAE,cAAc,EAAE,wBAAuB;AAEhD,OAAO,KAAK,EAAE,6BAA6B,EAAE,qDAAoD;AACjG,OAAO,KAAK,EAAE,6BAA6B,EAAE,mDAAkD;AAC/F,OAAO,KAAK,EAAE,cAAc,EAAE,2BAA2B,EAAE,oBAAmB;AAY9E,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF;;OAEG;IACH,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,MAAM,MAAM,8BAA8B,GAAG,wBAAwB,CACnE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,yBAAyB,CAAC;IACxD,OAAO,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,cAAc,GAAG,6BAA6B,CAAC;AAEpD;;GAEG;AACH,KAAK,aAAa,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAC/C,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,CACvC,CAAC;AAqBF,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,yBAAyB,CAAC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;OAQG;IACH,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;CACzD,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAmBa,OAAO,EAAE,uBAAuB;IAiC5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;OAEG;IACH,UAAU,IAAI,IAAI;IA4FlB;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAuBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CAuI3B"}
1
+ {"version":3,"file":"ShieldController.d.mts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,uCAAuC;AAExC,OAAO,KAAK,EACV,qCAAqC,EACrC,eAAe,EAChB,yCAAyC;AAG1C,OAAO,EAAE,cAAc,EAAE,wBAAuB;AAEhD,OAAO,KAAK,EAAE,6BAA6B,EAAE,mDAAkD;AAC/F,OAAO,KAAK,EACV,cAAc,EACd,2BAA2B,EAC3B,aAAa,EACd,oBAAmB;AAYpB,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF;;OAEG;IACH,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,MAAM,MAAM,8BAA8B,GAAG,wBAAwB,CACnE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,yBAAyB,CAAC;IACxD,OAAO,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,aAAa,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAC/C,OAAO,cAAc,EACrB,uBAAuB,EACvB,sBAAsB,GAAG,aAAa,CACvC,CAAC;AAqBF,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,yBAAyB,CAAC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,OAAO,EAAE,aAAa,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;OAQG;IACH,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;CACzD,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAqBa,OAAO,EAAE,uBAAuB;IAmC5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;OAEG;IACH,UAAU,IAAI,IAAI;IA4FlB;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAoBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CAoI3B"}
@@ -9,7 +9,7 @@ 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 _ShieldController_instances, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_normalizeSignatureRequest, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_started, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction, _ShieldController_getCoverageShownStatus, _ShieldController_getLatestCoverageId;
12
+ var _ShieldController_instances, _ShieldController_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_normalizeSignatureRequest, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_started, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction, _ShieldController_getCoverageShownStatus, _ShieldController_getLatestCoverageId;
13
13
  import { BaseController } from "@metamask/base-controller";
14
14
  import { SignatureRequestStatus } from "@metamask/signature-controller";
15
15
  import { TransactionStatus } from "@metamask/transaction-controller";
@@ -56,7 +56,7 @@ const metadata = {
56
56
  };
57
57
  export class ShieldController extends BaseController {
58
58
  constructor(options) {
59
- const { messenger, state, transactionHistoryLimit = 100, coverageHistoryLimit = 10, normalizeSignatureRequest, } = options;
59
+ const { messenger, state, backend, transactionHistoryLimit = 100, coverageHistoryLimit = 10, normalizeSignatureRequest, } = options;
60
60
  super({
61
61
  name: controllerName,
62
62
  metadata,
@@ -67,12 +67,14 @@ export class ShieldController extends BaseController {
67
67
  },
68
68
  });
69
69
  _ShieldController_instances.add(this);
70
+ _ShieldController_backend.set(this, void 0);
70
71
  _ShieldController_coverageHistoryLimit.set(this, void 0);
71
72
  _ShieldController_transactionHistoryLimit.set(this, void 0);
72
73
  _ShieldController_normalizeSignatureRequest.set(this, void 0);
73
74
  _ShieldController_transactionControllerStateChangeHandler.set(this, void 0);
74
75
  _ShieldController_signatureControllerStateChangeHandler.set(this, void 0);
75
76
  _ShieldController_started.set(this, void 0);
77
+ __classPrivateFieldSet(this, _ShieldController_backend, backend, "f");
76
78
  __classPrivateFieldSet(this, _ShieldController_coverageHistoryLimit, coverageHistoryLimit, "f");
77
79
  __classPrivateFieldSet(this, _ShieldController_transactionHistoryLimit, transactionHistoryLimit, "f");
78
80
  __classPrivateFieldSet(this, _ShieldController_transactionControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleTransactionControllerStateChange).bind(this), "f");
@@ -120,7 +122,7 @@ export class ShieldController extends BaseController {
120
122
  async checkCoverage(txMeta) {
121
123
  // Check coverage
122
124
  const coverageId = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getLatestCoverageId).call(this, txMeta.id);
123
- const coverageResult = await this.messenger.call('ShieldApiService:checkCoverage', {
125
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage({
124
126
  txMeta,
125
127
  coverageId,
126
128
  });
@@ -144,7 +146,7 @@ export class ShieldController extends BaseController {
144
146
  const clonedSignatureRequest = cloneDeep(signatureRequest);
145
147
  const normalizedSignatureRequest = __classPrivateFieldGet(this, _ShieldController_normalizeSignatureRequest, "f")?.call(this, clonedSignatureRequest) ??
146
148
  clonedSignatureRequest;
147
- const coverageResult = await this.messenger.call('ShieldApiService:checkSignatureCoverage', {
149
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkSignatureCoverage({
148
150
  signatureRequest: normalizedSignatureRequest,
149
151
  coverageId,
150
152
  });
@@ -155,7 +157,7 @@ export class ShieldController extends BaseController {
155
157
  return coverageResult;
156
158
  }
157
159
  }
158
- _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_normalizeSignatureRequest = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_signatureControllerStateChangeHandler = new WeakMap(), _ShieldController_started = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleSignatureControllerStateChange = function _ShieldController_handleSignatureControllerStateChange(signatureRequests, previousSignatureRequests) {
160
+ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_normalizeSignatureRequest = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_signatureControllerStateChangeHandler = new WeakMap(), _ShieldController_started = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleSignatureControllerStateChange = function _ShieldController_handleSignatureControllerStateChange(signatureRequests, previousSignatureRequests) {
159
161
  const signatureRequestsArray = Object.values(signatureRequests);
160
162
  const previousSignatureRequestsArray = Object.values(previousSignatureRequests ?? {});
161
163
  const previousSignatureRequestsById = new Map(previousSignatureRequestsArray.map((request) => [request.id, request]));
@@ -252,7 +254,7 @@ _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transa
252
254
  throw new Error('Signature not found');
253
255
  }
254
256
  const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, signatureRequest.id);
255
- await this.messenger.call('ShieldApiService:logSignature', {
257
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logSignature({
256
258
  signatureRequest,
257
259
  signature,
258
260
  status,
@@ -267,7 +269,7 @@ _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transa
267
269
  throw new Error('Raw transaction hex not found');
268
270
  }
269
271
  const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, txMeta.id);
270
- await this.messenger.call('ShieldApiService:logTransaction', {
272
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logTransaction({
271
273
  txMeta,
272
274
  transactionHash,
273
275
  rawTransactionHex,
@@ -1 +1 @@
1
- {"version":3,"file":"ShieldController.mjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAM3D,OAAO,EAAE,sBAAsB,EAAE,uCAAuC;AAKxE,OAAO,EAAE,iBAAiB,EAAE,yCAAyC;;;AAOrE,OAAO,EAAE,cAAc,EAAE,wBAAuB;AAChD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,qBAAoB;AAKhE,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;AAElE,MAAM,yBAAyB,GAAG;IAChC,OAAO;IACP,MAAM;IACN,YAAY;IACZ,eAAe;IACf,wBAAwB;CAChB,CAAC;AAuBX;;;;GAIG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO;QACL,eAAe,EAAE,EAAE;QACnB,yBAAyB,EAAE,EAAE;KAC9B,CAAC;AACJ,CAAC;AAoDD;;;GAGG;AACH,MAAM,QAAQ,GAAG;IACf,eAAe,EAAE;QACf,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,yBAAyB,EAAE;QACzB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,KAAK;KAChB;CACF,CAAC;AAmBF,MAAM,OAAO,gBAAiB,SAAQ,cAIrC;IAmBC,YAAY,OAAgC;QAC1C,MAAM,EACJ,SAAS,EACT,KAAK,EACL,uBAAuB,GAAG,GAAG,EAC7B,oBAAoB,GAAG,EAAE,EACzB,yBAAyB,GAC1B,GAAG,OAAO,CAAC;QACZ,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,QAAQ;YACR,SAAS;YACT,KAAK,EAAE;gBACL,GAAG,+BAA+B,EAAE;gBACpC,GAAG,KAAK;aACT;SACF,CAAC,CAAC;;QAlCI,yDAA8B;QAE9B,4DAAiC;QAEjC,8DAAyD;QAEzD,4EAGC;QAED,0EAGC;QAEV,4CAAkB;QAoBhB,uBAAA,IAAI,0CAAyB,oBAAoB,MAAA,CAAC;QAClD,uBAAA,IAAI,6CAA4B,uBAAuB,MAAA,CAAC;QACxD,uBAAA,IAAI,6DACF,uBAAA,IAAI,6FAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAA,CAAC;QAC1D,uBAAA,IAAI,2DACF,uBAAA,IAAI,2FAAsC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAA,CAAC;QACxD,uBAAA,IAAI,6BAAY,KAAK,MAAA,CAAC;QACtB,uBAAA,IAAI,+CAA8B,yBAAyB,MAAA,CAAC;QAE5D,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,uBAAA,IAAI,iCAAS,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,uBAAA,IAAI,6BAAY,IAAI,MAAA,CAAC;QAErB,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,mCAAmC,EACnC,uBAAA,IAAI,iEAAyC,EAC7C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAC9B,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,iCAAiC,EACjC,uBAAA,IAAI,+DAAuC,EAC3C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,CACnC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,uBAAA,IAAI,iCAAS,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,uBAAA,IAAI,6BAAY,KAAK,MAAA,CAAC;QAEtB,IAAI,CAAC,SAAS,CAAC,WAAW,CACxB,mCAAmC,EACnC,uBAAA,IAAI,iEAAyC,CAC9C,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,WAAW,CACxB,iCAAiC,EACjC,uBAAA,IAAI,+DAAuC,CAC5C,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE;YACf,OAAO,+BAA+B,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAwFD;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,MAAuB;QACzC,iBAAiB;QACjB,MAAM,UAAU,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9C,gCAAgC,EAChC;YACE,MAAM;YACN,UAAU;SACX,CACF,CAAC;QAEF,0BAA0B;QAC1B,IAAI,CAAC,SAAS,CAAC,OAAO,CACpB,GAAG,cAAc,yBAAyB,EAC1C,cAAc,CACf,CAAC;QAEF,eAAe;QACf,uBAAA,IAAI,wEAAmB,MAAvB,IAAI,EAAoB,MAAM,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAEnD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,sBAAsB,CAC1B,gBAAkC;QAElC,iBAAiB;QACjB,MAAM,UAAU,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAElE,oEAAoE;QACpE,2GAA2G;QAC3G,MAAM,sBAAsB,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3D,MAAM,0BAA0B,GAC9B,uBAAA,IAAI,mDAA2B,EAAE,KAAjC,IAAI,EAA8B,sBAAsB,CAAC;YACzD,sBAAsB,CAAC;QACzB,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9C,yCAAyC,EACzC;YACE,gBAAgB,EAAE,0BAA0B;YAC5C,UAAU;SACX,CACF,CAAC;QAEF,0BAA0B;QAC1B,IAAI,CAAC,SAAS,CAAC,OAAO,CACpB,GAAG,cAAc,yBAAyB,EAC1C,cAAc,CACf,CAAC;QAEF,eAAe;QACf,uBAAA,IAAI,wEAAmB,MAAvB,IAAI,EAAoB,gBAAgB,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAE7D,OAAO,cAAc,CAAC;IACxB,CAAC;CA2GF;qhBAjQG,iBAAmD,EACnD,yBAAuE;IAEvE,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChE,MAAM,8BAA8B,GAAG,MAAM,CAAC,MAAM,CAClD,yBAAyB,IAAI,EAAE,CAChC,CAAC;IACF,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAC3C,8BAA8B,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CACvE,CAAC;IACF,KAAK,MAAM,gBAAgB,IAAI,sBAAsB,EAAE,CAAC;QACtD,MAAM,wBAAwB,GAAG,6BAA6B,CAAC,GAAG,CAChE,gBAAgB,CAAC,EAAE,CACpB,CAAC;QAEF,kDAAkD;QAClD,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAC9B,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC,KAAK;YACjD,uBAAuB;YACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAClD,CAAC;QACJ,CAAC;QAED,+DAA+D;QAC/D,IACE,gBAAgB,CAAC,MAAM,KAAK,sBAAsB,CAAC,MAAM;YACzD,gBAAgB,CAAC,MAAM,KAAK,wBAAwB,EAAE,MAAM,EAC5D,CAAC;YACD,uBAAA,IAAI,mEAAc,MAAlB,IAAI,EAAe,gBAAgB,CAAC,CAAC,KAAK;YACxC,uBAAuB;YACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAClD,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC,+HAGC,YAA+B,EAC/B,oBAAmD;IAEnD,MAAM,wBAAwB,GAAG,IAAI,GAAG,CACtC,oBAAoB,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CACrD,CAAC;IACF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAEzE;QACE,2EAA2E;QAC3E,WAAW,CAAC,MAAM,KAAK,iBAAiB,CAAC,SAAS;YAClD,WAAW,CAAC,MAAM,KAAK,iBAAiB,CAAC,SAAS,EAClD,CAAC;YACD,4CAA4C;YAC5C,MAAM,qBAAqB;YACzB,mFAAmF;YACnF,0IAA0I;YAC1I,mFAAmF;YACnF,mBAAmB,EAAE,cAAc;gBACnC,CAAC,OAAO,CACN,WAAW,CAAC,cAAc,EAC1B,mBAAmB,CAAC,cAAc,CACnC,CAAC;YAEJ,yEAAyE;YACzE,WAAW;YACX,IAAI,CAAC,mBAAmB,IAAI,qBAAqB,EAAE,CAAC;gBAClD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK;gBACnC,uBAAuB;gBACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAClD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,IACE,WAAW,CAAC,MAAM,KAAK,iBAAiB,CAAC,SAAS;YAClD,WAAW,CAAC,MAAM,KAAK,mBAAmB,EAAE,MAAM,EAClD,CAAC;YACD,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,WAAW,CAAC,CAAC,KAAK;YACrC,uBAAuB;YACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,4BAA4B,EAAE,KAAK,CAAC,CACpD,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC,qFAqEkB,IAAY,EAAE,cAA8B;IAC7D,wCAAwC;IACxC,MAAM,gBAAgB,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,IAAI,CAAC,CAAC;IACzD,IAAI,gBAAgB,IAAI,cAAc,CAAC,UAAU,KAAK,gBAAgB,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACpB,+BAA+B;QAC/B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,mBAAmB,GAAG,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAEtD,iCAAiC;QACjC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,QAAQ,GAAG,IAAI,CAAC;YAChB,mBAAmB,GAAG;gBACpB,OAAO,EAAE,EAAE;aACZ,CAAC;YACF,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC;QACpD,CAAC;QAED,sCAAsC;QACtC,IAAI,mBAAmB,CAAC,OAAO,CAAC,MAAM,IAAI,uBAAA,IAAI,8CAAsB,EAAE,CAAC;YACrE,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACpC,CAAC;QAED,kBAAkB;QAClB,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEpD,+BAA+B;QAC/B,MAAM,EAAE,yBAAyB,EAAE,GAAG,KAAK,CAAC;QAC5C,IAAI,WAA+B,CAAC;QACpC,IAAI,QAAQ,EAAE,CAAC;YACb,yCAAyC;YACzC,IAAI,yBAAyB,CAAC,MAAM,IAAI,uBAAA,IAAI,iDAAyB,EAAE,CAAC;gBACtE,WAAW,GAAG,yBAAyB,CAAC,GAAG,EAAE,CAAC;gBAC9C,8CAA8C;gBAC9C,IAAI,WAAW,EAAE,CAAC;oBAChB,OAAO,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YACD,kBAAkB;YAClB,yBAAyB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,mCAED,KAAK,yCAAe,gBAAkC;IACpD,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAC1C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,uBAAA,IAAI,6EAAwB,MAA5B,IAAI,EAAyB,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAErE,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,+BAA+B,EAAE;QACzD,gBAAgB;QAChB,SAAS;QACT,MAAM;KACP,CAAC,CAAC;AACL,CAAC,qCAED,KAAK,2CAAiB,MAAuB;IAC3C,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC;IACpC,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,CAAC;IACvC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,uBAAA,IAAI,6EAAwB,MAA5B,IAAI,EAAyB,MAAM,CAAC,EAAE,CAAC,CAAC;IAE3D,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iCAAiC,EAAE;QAC3D,MAAM;QACN,eAAe;QACf,iBAAiB;QACjB,MAAM;KACP,CAAC,CAAC;AACL,CAAC,+FAQuB,MAAc;IACpC,qCAAqC;IACrC,gCAAgC;IAChC,0CAA0C;IAC1C,MAAM,UAAU,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;IACrD,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,GAAG,WAAW,CAAC;IACvB,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC,yFAEoB,MAAc;IACjC,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;AACpE,CAAC","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { SignatureRequestStatus } from '@metamask/signature-controller';\nimport type {\n SignatureRequest,\n SignatureStateChange,\n} from '@metamask/signature-controller';\nimport { TransactionStatus } from '@metamask/transaction-controller';\nimport type {\n TransactionControllerStateChangeEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants.js';\nimport { projectLogger, createModuleLogger } from './logger.js';\nimport type { ShieldApiServiceMethodActions } from './shield-api-service-method-action-types.js';\nimport type { ShieldControllerMethodActions } from './ShieldController-method-action-types.js';\nimport type { CoverageResult, NormalizeSignatureRequestFn } from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'start',\n 'stop',\n 'clearState',\n 'checkCoverage',\n 'checkSignatureCoverage',\n] as const;\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerMethodActions;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external actions available to the ShieldController.\n */\ntype AllowedActions = ShieldApiServiceMethodActions;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Start the ShieldController and subscribe to the transaction and signature controller state changes.\n */\n start(): void {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n /**\n * Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.\n */\n stop(): void {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n /**\n * Clears the shield state and resets to default values.\n */\n clearState(): void {\n this.update(() => {\n return getDefaultShieldControllerState();\n });\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ): void {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ): void {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n if (\n // We don't need to check coverage for submitted or confirmed transactions.\n transaction.status !== TransactionStatus.submitted &&\n transaction.status !== TransactionStatus.confirmed\n ) {\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n previousTransaction?.simulationData &&\n !isEqual(\n transaction.simulationData,\n previousTransaction.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.messenger.call(\n 'ShieldApiService:checkCoverage',\n {\n txMeta,\n coverageId,\n },\n );\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.messenger.call(\n 'ShieldApiService:checkSignatureCoverage',\n {\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n },\n );\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult): void {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest): Promise<void> {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageShownStatus(signatureRequest.id);\n\n await this.messenger.call('ShieldApiService:logSignature', {\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta): Promise<void> {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const rawTransactionHex = txMeta.rawTx;\n if (!rawTransactionHex) {\n throw new Error('Raw transaction hex not found');\n }\n\n const { status } = this.#getCoverageShownStatus(txMeta.id);\n\n await this.messenger.call('ShieldApiService:logTransaction', {\n txMeta,\n transactionHash,\n rawTransactionHex,\n status,\n });\n }\n\n /**\n * Get the coverage shown status for a given item ID.\n *\n * @param itemId - The item ID to get the coverage status for.\n * @returns The coverage status.\n */\n #getCoverageShownStatus(itemId: string): { status: string } {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
1
+ {"version":3,"file":"ShieldController.mjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { SignatureRequestStatus } from '@metamask/signature-controller';\nimport type {\n SignatureRequest,\n SignatureStateChange,\n} from '@metamask/signature-controller';\nimport { TransactionStatus } from '@metamask/transaction-controller';\nimport type {\n TransactionControllerStateChangeEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants.js';\nimport { projectLogger, createModuleLogger } from './logger.js';\nimport type { ShieldControllerMethodActions } from './ShieldController-method-action-types.js';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'start',\n 'stop',\n 'clearState',\n 'checkCoverage',\n 'checkSignatureCoverage',\n] as const;\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerMethodActions;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Start the ShieldController and subscribe to the transaction and signature controller state changes.\n */\n start(): void {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n /**\n * Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.\n */\n stop(): void {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n /**\n * Clears the shield state and resets to default values.\n */\n clearState(): void {\n this.update(() => {\n return getDefaultShieldControllerState();\n });\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ): void {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ): void {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n if (\n // We don't need to check coverage for submitted or confirmed transactions.\n transaction.status !== TransactionStatus.submitted &&\n transaction.status !== TransactionStatus.confirmed\n ) {\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n previousTransaction?.simulationData &&\n !isEqual(\n transaction.simulationData,\n previousTransaction.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult): void {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest): Promise<void> {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageShownStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta): Promise<void> {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const rawTransactionHex = txMeta.rawTx;\n if (!rawTransactionHex) {\n throw new Error('Raw transaction hex not found');\n }\n\n const { status } = this.#getCoverageShownStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n rawTransactionHex,\n status,\n });\n }\n\n /**\n * Get the coverage shown status for a given item ID.\n *\n * @param itemId - The item ID to get the coverage status for.\n * @returns The coverage status.\n */\n #getCoverageShownStatus(itemId: string): { status: string } {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}