@metamask/shield-controller 3.1.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -1
- package/dist/ShieldController.cjs +10 -4
- package/dist/ShieldController.cjs.map +1 -1
- package/dist/ShieldController.d.cts +10 -3
- package/dist/ShieldController.d.cts.map +1 -1
- package/dist/ShieldController.d.mts +10 -3
- package/dist/ShieldController.d.mts.map +1 -1
- package/dist/ShieldController.mjs +10 -4
- package/dist/ShieldController.mjs.map +1 -1
- package/dist/backend.cjs +86 -41
- package/dist/backend.cjs.map +1 -1
- package/dist/backend.d.cts +3 -2
- package/dist/backend.d.cts.map +1 -1
- package/dist/backend.d.mts +3 -2
- package/dist/backend.d.mts.map +1 -1
- package/dist/backend.mjs +85 -40
- package/dist/backend.mjs.map +1 -1
- package/dist/polling-with-policy.cjs +2 -1
- package/dist/polling-with-policy.cjs.map +1 -1
- package/dist/polling-with-policy.d.cts +1 -1
- package/dist/polling-with-policy.d.cts.map +1 -1
- package/dist/polling-with-policy.d.mts +1 -1
- package/dist/polling-with-policy.d.mts.map +1 -1
- package/dist/polling-with-policy.mjs +2 -1
- package/dist/polling-with-policy.mjs.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [4.1.0]
|
|
11
|
+
|
|
12
|
+
### Uncategorized
|
|
13
|
+
|
|
14
|
+
- Chore/w3a controllers linting ([#7455](https://github.com/MetaMask/core/pull/7455))
|
|
15
|
+
- Remove breaking designation from version bumps in changelog ([#7419](https://github.com/MetaMask/core/pull/7419))
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Add optional constructor param, `captureException` to capture any errors during coverage API calls. ([#7555](https://github.com/MetaMask/core/pull/7555))
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511))
|
|
24
|
+
- Bump `@metamask/transaction-controller` from `^62.5.0` to `^62.7.0` ([#7430](https://github.com/MetaMask/core/pull/7430), [#7494](https://github.com/MetaMask/core/pull/7494))
|
|
25
|
+
- Bump `@metamask/controller-utils` from `^11.16.0` to `^11.17.0` ([#7534](https://github.com/MetaMask/core/pull/7534))
|
|
26
|
+
|
|
27
|
+
## [4.0.0]
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- Bump `@metamask/signature-controller` from `^37.0.0` to `^38.0.0` ([#7330](https://github.com/MetaMask/core/pull/7330))
|
|
32
|
+
- Bump `@metamask/transaction-controller` from `^62.3.0` to `^62.5.0` ([#7257](https://github.com/MetaMask/core/pull/7257), [#7289](https://github.com/MetaMask/core/pull/7289), [#7325](https://github.com/MetaMask/core/pull/7325))
|
|
33
|
+
|
|
10
34
|
## [3.1.0]
|
|
11
35
|
|
|
12
36
|
### Added
|
|
@@ -162,7 +186,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
162
186
|
|
|
163
187
|
- Initial release of the shield-controller package ([#6137](https://github.com/MetaMask/core/pull/6137)
|
|
164
188
|
|
|
165
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@
|
|
189
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@4.1.0...HEAD
|
|
190
|
+
[4.1.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@4.0.0...@metamask/shield-controller@4.1.0
|
|
191
|
+
[4.0.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@3.1.0...@metamask/shield-controller@4.0.0
|
|
166
192
|
[3.1.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@3.0.0...@metamask/shield-controller@3.1.0
|
|
167
193
|
[3.0.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@2.1.1...@metamask/shield-controller@3.0.0
|
|
168
194
|
[2.1.1]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@2.1.0...@metamask/shield-controller@2.1.1
|
|
@@ -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_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_normalizeSignatureRequest, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_started, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction,
|
|
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");
|
|
@@ -78,6 +78,9 @@ class ShieldController extends base_controller_1.BaseController {
|
|
|
78
78
|
__classPrivateFieldSet(this, _ShieldController_started, false, "f");
|
|
79
79
|
__classPrivateFieldSet(this, _ShieldController_normalizeSignatureRequest, normalizeSignatureRequest, "f");
|
|
80
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Start the ShieldController and subscribe to the transaction and signature controller state changes.
|
|
83
|
+
*/
|
|
81
84
|
start() {
|
|
82
85
|
if (__classPrivateFieldGet(this, _ShieldController_started, "f")) {
|
|
83
86
|
return;
|
|
@@ -86,6 +89,9 @@ class ShieldController extends base_controller_1.BaseController {
|
|
|
86
89
|
this.messenger.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"), (state) => state.transactions);
|
|
87
90
|
this.messenger.subscribe('SignatureController:stateChange', __classPrivateFieldGet(this, _ShieldController_signatureControllerStateChangeHandler, "f"), (state) => state.signatureRequests);
|
|
88
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.
|
|
94
|
+
*/
|
|
89
95
|
stop() {
|
|
90
96
|
if (!__classPrivateFieldGet(this, _ShieldController_started, "f")) {
|
|
91
97
|
return;
|
|
@@ -235,7 +241,7 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
235
241
|
if (!signature) {
|
|
236
242
|
throw new Error('Signature not found');
|
|
237
243
|
}
|
|
238
|
-
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m",
|
|
244
|
+
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, signatureRequest.id);
|
|
239
245
|
await __classPrivateFieldGet(this, _ShieldController_backend, "f").logSignature({
|
|
240
246
|
signatureRequest,
|
|
241
247
|
signature,
|
|
@@ -250,14 +256,14 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
250
256
|
if (!rawTransactionHex) {
|
|
251
257
|
throw new Error('Raw transaction hex not found');
|
|
252
258
|
}
|
|
253
|
-
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m",
|
|
259
|
+
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, txMeta.id);
|
|
254
260
|
await __classPrivateFieldGet(this, _ShieldController_backend, "f").logTransaction({
|
|
255
261
|
txMeta,
|
|
256
262
|
transactionHash,
|
|
257
263
|
rawTransactionHex,
|
|
258
264
|
status,
|
|
259
265
|
});
|
|
260
|
-
},
|
|
266
|
+
}, _ShieldController_getCoverageShownStatus = function _ShieldController_getCoverageShownStatus(itemId) {
|
|
261
267
|
// The status is assigned as follows:
|
|
262
268
|
// - 'shown' if we have a result
|
|
263
269
|
// - 'not_shown' if we don't have a result
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n SignatureRequestStatus,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\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\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\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\n start() {\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 stop() {\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 #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\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 ) {\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) {\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) {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\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.#getCoverageStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n rawTransactionHex,\n status,\n });\n }\n\n #getCoverageStatus(itemId: 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';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\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\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\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\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 #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"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { BaseController
|
|
1
|
+
import { BaseController } from "@metamask/base-controller";
|
|
2
|
+
import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
|
|
2
3
|
import type { Messenger } from "@metamask/messenger";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import type { SignatureRequest, SignatureStateChange } from "@metamask/signature-controller";
|
|
5
|
+
import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
|
|
5
6
|
import { controllerName } from "./constants.cjs";
|
|
6
7
|
import type { CoverageResult, NormalizeSignatureRequestFn, ShieldBackend } from "./types.cjs";
|
|
7
8
|
export type CoverageResultRecordEntry = {
|
|
@@ -73,7 +74,13 @@ export type ShieldControllerOptions = {
|
|
|
73
74
|
export declare class ShieldController extends BaseController<typeof controllerName, ShieldControllerState, ShieldControllerMessenger> {
|
|
74
75
|
#private;
|
|
75
76
|
constructor(options: ShieldControllerOptions);
|
|
77
|
+
/**
|
|
78
|
+
* Start the ShieldController and subscribe to the transaction and signature controller state changes.
|
|
79
|
+
*/
|
|
76
80
|
start(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.
|
|
83
|
+
*/
|
|
77
84
|
stop(): void;
|
|
78
85
|
/**
|
|
79
86
|
* Checks the coverage of a transaction.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.d.cts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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,wBAAoB;AAE7C,OAAO,KAAK,EACV,cAAc,EACd,2BAA2B,EAC3B,aAAa,EACd,oBAAgB;AAIjB,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,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;CAC5C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,mCAAmC,CAAC;AAExC,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;IA8B5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAuGZ;;;;;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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { BaseController
|
|
1
|
+
import { BaseController } from "@metamask/base-controller";
|
|
2
|
+
import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
|
|
2
3
|
import type { Messenger } from "@metamask/messenger";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import type { SignatureRequest, SignatureStateChange } from "@metamask/signature-controller";
|
|
5
|
+
import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
|
|
5
6
|
import { controllerName } from "./constants.mjs";
|
|
6
7
|
import type { CoverageResult, NormalizeSignatureRequestFn, ShieldBackend } from "./types.mjs";
|
|
7
8
|
export type CoverageResultRecordEntry = {
|
|
@@ -73,7 +74,13 @@ export type ShieldControllerOptions = {
|
|
|
73
74
|
export declare class ShieldController extends BaseController<typeof controllerName, ShieldControllerState, ShieldControllerMessenger> {
|
|
74
75
|
#private;
|
|
75
76
|
constructor(options: ShieldControllerOptions);
|
|
77
|
+
/**
|
|
78
|
+
* Start the ShieldController and subscribe to the transaction and signature controller state changes.
|
|
79
|
+
*/
|
|
76
80
|
start(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.
|
|
83
|
+
*/
|
|
77
84
|
stop(): void;
|
|
78
85
|
/**
|
|
79
86
|
* Checks the coverage of a transaction.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.d.mts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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,wBAAoB;AAE7C,OAAO,KAAK,EACV,cAAc,EACd,2BAA2B,EAC3B,aAAa,EACd,oBAAgB;AAIjB,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,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;CAC5C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,mCAAmC,CAAC;AAExC,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;IA8B5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAuGZ;;;;;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_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_normalizeSignatureRequest, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_started, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction,
|
|
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";
|
|
@@ -75,6 +75,9 @@ export class ShieldController extends BaseController {
|
|
|
75
75
|
__classPrivateFieldSet(this, _ShieldController_started, false, "f");
|
|
76
76
|
__classPrivateFieldSet(this, _ShieldController_normalizeSignatureRequest, normalizeSignatureRequest, "f");
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Start the ShieldController and subscribe to the transaction and signature controller state changes.
|
|
80
|
+
*/
|
|
78
81
|
start() {
|
|
79
82
|
if (__classPrivateFieldGet(this, _ShieldController_started, "f")) {
|
|
80
83
|
return;
|
|
@@ -83,6 +86,9 @@ export class ShieldController extends BaseController {
|
|
|
83
86
|
this.messenger.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"), (state) => state.transactions);
|
|
84
87
|
this.messenger.subscribe('SignatureController:stateChange', __classPrivateFieldGet(this, _ShieldController_signatureControllerStateChangeHandler, "f"), (state) => state.signatureRequests);
|
|
85
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Stop the ShieldController and unsubscribe from the transaction and signature controller state changes.
|
|
91
|
+
*/
|
|
86
92
|
stop() {
|
|
87
93
|
if (!__classPrivateFieldGet(this, _ShieldController_started, "f")) {
|
|
88
94
|
return;
|
|
@@ -231,7 +237,7 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
231
237
|
if (!signature) {
|
|
232
238
|
throw new Error('Signature not found');
|
|
233
239
|
}
|
|
234
|
-
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m",
|
|
240
|
+
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, signatureRequest.id);
|
|
235
241
|
await __classPrivateFieldGet(this, _ShieldController_backend, "f").logSignature({
|
|
236
242
|
signatureRequest,
|
|
237
243
|
signature,
|
|
@@ -246,14 +252,14 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
246
252
|
if (!rawTransactionHex) {
|
|
247
253
|
throw new Error('Raw transaction hex not found');
|
|
248
254
|
}
|
|
249
|
-
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m",
|
|
255
|
+
const { status } = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getCoverageShownStatus).call(this, txMeta.id);
|
|
250
256
|
await __classPrivateFieldGet(this, _ShieldController_backend, "f").logTransaction({
|
|
251
257
|
txMeta,
|
|
252
258
|
transactionHash,
|
|
253
259
|
rawTransactionHex,
|
|
254
260
|
status,
|
|
255
261
|
});
|
|
256
|
-
},
|
|
262
|
+
}, _ShieldController_getCoverageShownStatus = function _ShieldController_getCoverageShownStatus(itemId) {
|
|
257
263
|
// The status is assigned as follows:
|
|
258
264
|
// - 'shown' if we have a result
|
|
259
265
|
// - 'not_shown' if we don't have a result
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.mjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n SignatureRequestStatus,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\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\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\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\n start() {\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 stop() {\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 #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\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 ) {\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) {\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) {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\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.#getCoverageStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n rawTransactionHex,\n status,\n });\n }\n\n #getCoverageStatus(itemId: 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';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\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\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\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\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 #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"]}
|