@metamask/shield-controller 0.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +20 -0
  3. package/README.md +15 -0
  4. package/dist/ShieldController.cjs +144 -0
  5. package/dist/ShieldController.cjs.map +1 -0
  6. package/dist/ShieldController.d.cts +70 -0
  7. package/dist/ShieldController.d.cts.map +1 -0
  8. package/dist/ShieldController.d.mts +70 -0
  9. package/dist/ShieldController.d.mts.map +1 -0
  10. package/dist/ShieldController.mjs +139 -0
  11. package/dist/ShieldController.mjs.map +1 -0
  12. package/dist/backend.cjs +110 -0
  13. package/dist/backend.cjs.map +1 -0
  14. package/dist/backend.d.cts +39 -0
  15. package/dist/backend.d.cts.map +1 -0
  16. package/dist/backend.d.mts +39 -0
  17. package/dist/backend.d.mts.map +1 -0
  18. package/dist/backend.mjs +106 -0
  19. package/dist/backend.mjs.map +1 -0
  20. package/dist/constants.cjs +8 -0
  21. package/dist/constants.cjs.map +1 -0
  22. package/dist/constants.d.cts +5 -0
  23. package/dist/constants.d.cts.map +1 -0
  24. package/dist/constants.d.mts +5 -0
  25. package/dist/constants.d.mts.map +1 -0
  26. package/dist/constants.mjs +5 -0
  27. package/dist/constants.mjs.map +1 -0
  28. package/dist/index.cjs +7 -0
  29. package/dist/index.cjs.map +1 -0
  30. package/dist/index.d.cts +4 -0
  31. package/dist/index.d.cts.map +1 -0
  32. package/dist/index.d.mts +4 -0
  33. package/dist/index.d.mts.map +1 -0
  34. package/dist/index.mjs +2 -0
  35. package/dist/index.mjs.map +1 -0
  36. package/dist/logger.cjs +8 -0
  37. package/dist/logger.cjs.map +1 -0
  38. package/dist/logger.d.cts +5 -0
  39. package/dist/logger.d.cts.map +1 -0
  40. package/dist/logger.d.mts +5 -0
  41. package/dist/logger.d.mts.map +1 -0
  42. package/dist/logger.mjs +5 -0
  43. package/dist/logger.mjs.map +1 -0
  44. package/dist/types.cjs +5 -0
  45. package/dist/types.cjs.map +1 -0
  46. package/dist/types.d.cts +10 -0
  47. package/dist/types.d.cts.map +1 -0
  48. package/dist/types.d.mts +10 -0
  49. package/dist/types.d.mts.map +1 -0
  50. package/dist/types.mjs +2 -0
  51. package/dist/types.mjs.map +1 -0
  52. package/package.json +84 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0]
11
+
12
+ ### Added
13
+
14
+ - Initial release of the shield-controller package ([#6137](https://github.com/MetaMask/core/pull/6137)
15
+
16
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@0.1.0...HEAD
17
+ [0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/shield-controller@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 MetaMask
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # `@metamask/shield-controller`
2
+
3
+ Controller handling shield transaction coverage logic.
4
+
5
+ ## Installation
6
+
7
+ `yarn add @metamask/shield-controller`
8
+
9
+ or
10
+
11
+ `npm install @metamask/shield-controller`
12
+
13
+ ## Contributing
14
+
15
+ This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme).
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _ShieldController_instances, _ShieldController_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_handleTransactionControllerStateChange, _ShieldController_fetchCoverageResult, _ShieldController_addCoverageResult;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ShieldController = exports.getDefaultShieldControllerState = void 0;
16
+ const base_controller_1 = require("@metamask/base-controller");
17
+ const constants_1 = require("./constants.cjs");
18
+ const logger_1 = require("./logger.cjs");
19
+ const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, 'ShieldController');
20
+ /**
21
+ * Get the default state for the ShieldController.
22
+ *
23
+ * @returns The default state for the ShieldController.
24
+ */
25
+ function getDefaultShieldControllerState() {
26
+ return {
27
+ coverageResults: {},
28
+ orderedTransactionHistory: [],
29
+ };
30
+ }
31
+ exports.getDefaultShieldControllerState = getDefaultShieldControllerState;
32
+ /**
33
+ * Metadata for the ShieldController state, describing how to "anonymize"
34
+ * the state and which parts should be persisted.
35
+ */
36
+ const metadata = {
37
+ coverageResults: {
38
+ persist: true,
39
+ anonymous: false,
40
+ },
41
+ orderedTransactionHistory: {
42
+ persist: true,
43
+ anonymous: false,
44
+ },
45
+ };
46
+ class ShieldController extends base_controller_1.BaseController {
47
+ constructor(options) {
48
+ const { messenger, state, backend, transactionHistoryLimit = 100, coverageHistoryLimit = 10, } = options;
49
+ super({
50
+ name: constants_1.controllerName,
51
+ metadata,
52
+ messenger,
53
+ state: {
54
+ ...getDefaultShieldControllerState(),
55
+ ...state,
56
+ },
57
+ });
58
+ _ShieldController_instances.add(this);
59
+ _ShieldController_backend.set(this, void 0);
60
+ _ShieldController_coverageHistoryLimit.set(this, void 0);
61
+ _ShieldController_transactionHistoryLimit.set(this, void 0);
62
+ _ShieldController_transactionControllerStateChangeHandler.set(this, void 0);
63
+ __classPrivateFieldSet(this, _ShieldController_backend, backend, "f");
64
+ __classPrivateFieldSet(this, _ShieldController_coverageHistoryLimit, coverageHistoryLimit, "f");
65
+ __classPrivateFieldSet(this, _ShieldController_transactionHistoryLimit, transactionHistoryLimit, "f");
66
+ __classPrivateFieldSet(this, _ShieldController_transactionControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleTransactionControllerStateChange).bind(this), "f");
67
+ }
68
+ start() {
69
+ this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"), (state) => state.transactions);
70
+ }
71
+ stop() {
72
+ this.messagingSystem.unsubscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"));
73
+ }
74
+ /**
75
+ * Checks the coverage of a transaction.
76
+ *
77
+ * @param txMeta - The transaction to check coverage for.
78
+ * @returns The coverage result.
79
+ */
80
+ async checkCoverage(txMeta) {
81
+ // Check coverage
82
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_fetchCoverageResult).call(this, txMeta);
83
+ // Publish coverage result
84
+ this.messagingSystem.publish(`${constants_1.controllerName}:coverageResultReceived`, coverageResult);
85
+ // Update state
86
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_addCoverageResult).call(this, txMeta.id, coverageResult);
87
+ return coverageResult;
88
+ }
89
+ }
90
+ exports.ShieldController = ShieldController;
91
+ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleTransactionControllerStateChange = function _ShieldController_handleTransactionControllerStateChange(transactions, previousTransactions) {
92
+ const previousTransactionsById = new Map(previousTransactions?.map((tx) => [tx.id, tx]) ?? []);
93
+ for (const transaction of transactions) {
94
+ const previousTransaction = previousTransactionsById.get(transaction.id);
95
+ // Check coverage if the transaction is new or if the simulation data has
96
+ // changed.
97
+ if (!previousTransaction ||
98
+ // Checking reference equality is sufficient because this object is
99
+ // replaced if the simulation data has changed.
100
+ previousTransaction.simulationData !== transaction.simulationData) {
101
+ this.checkCoverage(transaction).catch(
102
+ // istanbul ignore next
103
+ (error) => log('Error checking coverage:', error));
104
+ }
105
+ }
106
+ }, _ShieldController_fetchCoverageResult = async function _ShieldController_fetchCoverageResult(txMeta) {
107
+ return __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage(txMeta);
108
+ }, _ShieldController_addCoverageResult = function _ShieldController_addCoverageResult(txId, coverageResult) {
109
+ this.update((draft) => {
110
+ // Fetch coverage result entry.
111
+ let newEntry = false;
112
+ let coverageResultEntry = draft.coverageResults[txId];
113
+ // Create new entry if necessary.
114
+ if (!coverageResultEntry) {
115
+ newEntry = true;
116
+ coverageResultEntry = {
117
+ results: [],
118
+ };
119
+ draft.coverageResults[txId] = coverageResultEntry;
120
+ }
121
+ // Trim coverage history if necessary.
122
+ if (coverageResultEntry.results.length >= __classPrivateFieldGet(this, _ShieldController_coverageHistoryLimit, "f")) {
123
+ coverageResultEntry.results.pop();
124
+ }
125
+ // Add new result.
126
+ coverageResultEntry.results.unshift(coverageResult);
127
+ // Add to history if new entry.
128
+ const { orderedTransactionHistory } = draft;
129
+ let removedTxId;
130
+ if (newEntry) {
131
+ // Trim transaction history if necessary.
132
+ if (orderedTransactionHistory.length >= __classPrivateFieldGet(this, _ShieldController_transactionHistoryLimit, "f")) {
133
+ removedTxId = orderedTransactionHistory.pop();
134
+ // Delete corresponding coverage result entry.
135
+ if (removedTxId) {
136
+ delete draft.coverageResults[removedTxId];
137
+ }
138
+ }
139
+ // Add to history.
140
+ orderedTransactionHistory.unshift(txId);
141
+ }
142
+ });
143
+ };
144
+ //# sourceMappingURL=ShieldController.cjs.map
@@ -0,0 +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 ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport type {\n TransactionControllerStateChangeEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { CoverageResult, ShieldBackend } from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n results: CoverageResult[]; // history of coverage results, latest first\n};\n\nexport type ShieldControllerState = {\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n orderedTransactionHistory: string[]; // List of txIds ordered by time, latest first\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 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 = 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 actions available to the ShieldController.\n */\ntype AllowedActions = never;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents = TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\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 persist: true,\n anonymous: false,\n },\n orderedTransactionHistory: {\n persist: true,\n anonymous: 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\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 #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\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 }\n\n start() {\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n }\n\n stop() {\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\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 // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (\n !previousTransaction ||\n // Checking reference equality is sufficient because this object is\n // replaced if the simulation data has changed.\n previousTransaction.simulationData !== transaction.simulationData\n ) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', 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 coverageResult = await this.#fetchCoverageResult(txMeta);\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n async #fetchCoverageResult(txMeta: TransactionMeta): Promise<CoverageResult> {\n return this.#backend.checkCoverage(txMeta);\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\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"]}
@@ -0,0 +1,70 @@
1
+ import { BaseController } from "@metamask/base-controller";
2
+ import type { ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
+ import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
4
+ import { controllerName } from "./constants.cjs";
5
+ import type { CoverageResult, ShieldBackend } from "./types.cjs";
6
+ export type CoverageResultRecordEntry = {
7
+ results: CoverageResult[];
8
+ };
9
+ export type ShieldControllerState = {
10
+ coverageResults: Record<string, // txId
11
+ CoverageResultRecordEntry>;
12
+ orderedTransactionHistory: string[];
13
+ };
14
+ /**
15
+ * Get the default state for the ShieldController.
16
+ *
17
+ * @returns The default state for the ShieldController.
18
+ */
19
+ export declare function getDefaultShieldControllerState(): ShieldControllerState;
20
+ export type ShieldControllerCheckCoverageAction = {
21
+ type: `${typeof controllerName}:checkCoverage`;
22
+ handler: ShieldController['checkCoverage'];
23
+ };
24
+ /**
25
+ * The internal actions available to the ShieldController.
26
+ */
27
+ export type ShieldControllerActions = ShieldControllerCheckCoverageAction;
28
+ export type ShieldControllerCoverageResultReceivedEvent = {
29
+ type: `${typeof controllerName}:coverageResultReceived`;
30
+ payload: [coverageResult: CoverageResult];
31
+ };
32
+ export type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, ShieldControllerState>;
33
+ /**
34
+ * The internal events available to the ShieldController.
35
+ */
36
+ export type ShieldControllerEvents = ShieldControllerCoverageResultReceivedEvent | ShieldControllerStateChangeEvent;
37
+ /**
38
+ * The external actions available to the ShieldController.
39
+ */
40
+ type AllowedActions = never;
41
+ /**
42
+ * The external events available to the ShieldController.
43
+ */
44
+ type AllowedEvents = TransactionControllerStateChangeEvent;
45
+ /**
46
+ * The messenger of the {@link ShieldController}.
47
+ */
48
+ export type ShieldControllerMessenger = RestrictedMessenger<typeof controllerName, ShieldControllerActions | AllowedActions, ShieldControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
49
+ export type ShieldControllerOptions = {
50
+ messenger: ShieldControllerMessenger;
51
+ state?: Partial<ShieldControllerState>;
52
+ backend: ShieldBackend;
53
+ transactionHistoryLimit?: number;
54
+ coverageHistoryLimit?: number;
55
+ };
56
+ export declare class ShieldController extends BaseController<typeof controllerName, ShieldControllerState, ShieldControllerMessenger> {
57
+ #private;
58
+ constructor(options: ShieldControllerOptions);
59
+ start(): void;
60
+ stop(): void;
61
+ /**
62
+ * Checks the coverage of a transaction.
63
+ *
64
+ * @param txMeta - The transaction to check coverage for.
65
+ * @returns The coverage result.
66
+ */
67
+ checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult>;
68
+ }
69
+ export {};
70
+ //# sourceMappingURL=ShieldController.d.cts.map
@@ -0,0 +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,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,KAAK,EACV,qCAAqC,EACrC,eAAe,EAChB,yCAAyC;AAE1C,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAI7D,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,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,GAAG,mCAAmC,CAAC;AAE1E,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,KAAK,CAAC;AAE5B;;GAEG;AACH,KAAK,aAAa,GAAG,qCAAqC,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CACzD,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,EACtC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAiBF,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;CAC/B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAYa,OAAO,EAAE,uBAAuB;IAyB5C,KAAK;IAQL,IAAI;IAiCJ;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CA4DtE"}
@@ -0,0 +1,70 @@
1
+ import { BaseController } from "@metamask/base-controller";
2
+ import type { ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
+ import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
4
+ import { controllerName } from "./constants.mjs";
5
+ import type { CoverageResult, ShieldBackend } from "./types.mjs";
6
+ export type CoverageResultRecordEntry = {
7
+ results: CoverageResult[];
8
+ };
9
+ export type ShieldControllerState = {
10
+ coverageResults: Record<string, // txId
11
+ CoverageResultRecordEntry>;
12
+ orderedTransactionHistory: string[];
13
+ };
14
+ /**
15
+ * Get the default state for the ShieldController.
16
+ *
17
+ * @returns The default state for the ShieldController.
18
+ */
19
+ export declare function getDefaultShieldControllerState(): ShieldControllerState;
20
+ export type ShieldControllerCheckCoverageAction = {
21
+ type: `${typeof controllerName}:checkCoverage`;
22
+ handler: ShieldController['checkCoverage'];
23
+ };
24
+ /**
25
+ * The internal actions available to the ShieldController.
26
+ */
27
+ export type ShieldControllerActions = ShieldControllerCheckCoverageAction;
28
+ export type ShieldControllerCoverageResultReceivedEvent = {
29
+ type: `${typeof controllerName}:coverageResultReceived`;
30
+ payload: [coverageResult: CoverageResult];
31
+ };
32
+ export type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, ShieldControllerState>;
33
+ /**
34
+ * The internal events available to the ShieldController.
35
+ */
36
+ export type ShieldControllerEvents = ShieldControllerCoverageResultReceivedEvent | ShieldControllerStateChangeEvent;
37
+ /**
38
+ * The external actions available to the ShieldController.
39
+ */
40
+ type AllowedActions = never;
41
+ /**
42
+ * The external events available to the ShieldController.
43
+ */
44
+ type AllowedEvents = TransactionControllerStateChangeEvent;
45
+ /**
46
+ * The messenger of the {@link ShieldController}.
47
+ */
48
+ export type ShieldControllerMessenger = RestrictedMessenger<typeof controllerName, ShieldControllerActions | AllowedActions, ShieldControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
49
+ export type ShieldControllerOptions = {
50
+ messenger: ShieldControllerMessenger;
51
+ state?: Partial<ShieldControllerState>;
52
+ backend: ShieldBackend;
53
+ transactionHistoryLimit?: number;
54
+ coverageHistoryLimit?: number;
55
+ };
56
+ export declare class ShieldController extends BaseController<typeof controllerName, ShieldControllerState, ShieldControllerMessenger> {
57
+ #private;
58
+ constructor(options: ShieldControllerOptions);
59
+ start(): void;
60
+ stop(): void;
61
+ /**
62
+ * Checks the coverage of a transaction.
63
+ *
64
+ * @param txMeta - The transaction to check coverage for.
65
+ * @returns The coverage result.
66
+ */
67
+ checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult>;
68
+ }
69
+ export {};
70
+ //# sourceMappingURL=ShieldController.d.mts.map
@@ -0,0 +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,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,KAAK,EACV,qCAAqC,EACrC,eAAe,EAChB,yCAAyC;AAE1C,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAI7D,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,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,GAAG,mCAAmC,CAAC;AAE1E,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,KAAK,CAAC;AAE5B;;GAEG;AACH,KAAK,aAAa,GAAG,qCAAqC,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CACzD,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,EACtC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAiBF,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;CAC/B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAYa,OAAO,EAAE,uBAAuB;IAyB5C,KAAK;IAQL,IAAI;IAiCJ;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CA4DtE"}
@@ -0,0 +1,139 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _ShieldController_instances, _ShieldController_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_handleTransactionControllerStateChange, _ShieldController_fetchCoverageResult, _ShieldController_addCoverageResult;
13
+ import { BaseController } from "@metamask/base-controller";
14
+ import { controllerName } from "./constants.mjs";
15
+ import { projectLogger, createModuleLogger } from "./logger.mjs";
16
+ const log = createModuleLogger(projectLogger, 'ShieldController');
17
+ /**
18
+ * Get the default state for the ShieldController.
19
+ *
20
+ * @returns The default state for the ShieldController.
21
+ */
22
+ export function getDefaultShieldControllerState() {
23
+ return {
24
+ coverageResults: {},
25
+ orderedTransactionHistory: [],
26
+ };
27
+ }
28
+ /**
29
+ * Metadata for the ShieldController state, describing how to "anonymize"
30
+ * the state and which parts should be persisted.
31
+ */
32
+ const metadata = {
33
+ coverageResults: {
34
+ persist: true,
35
+ anonymous: false,
36
+ },
37
+ orderedTransactionHistory: {
38
+ persist: true,
39
+ anonymous: false,
40
+ },
41
+ };
42
+ export class ShieldController extends BaseController {
43
+ constructor(options) {
44
+ const { messenger, state, backend, transactionHistoryLimit = 100, coverageHistoryLimit = 10, } = options;
45
+ super({
46
+ name: controllerName,
47
+ metadata,
48
+ messenger,
49
+ state: {
50
+ ...getDefaultShieldControllerState(),
51
+ ...state,
52
+ },
53
+ });
54
+ _ShieldController_instances.add(this);
55
+ _ShieldController_backend.set(this, void 0);
56
+ _ShieldController_coverageHistoryLimit.set(this, void 0);
57
+ _ShieldController_transactionHistoryLimit.set(this, void 0);
58
+ _ShieldController_transactionControllerStateChangeHandler.set(this, void 0);
59
+ __classPrivateFieldSet(this, _ShieldController_backend, backend, "f");
60
+ __classPrivateFieldSet(this, _ShieldController_coverageHistoryLimit, coverageHistoryLimit, "f");
61
+ __classPrivateFieldSet(this, _ShieldController_transactionHistoryLimit, transactionHistoryLimit, "f");
62
+ __classPrivateFieldSet(this, _ShieldController_transactionControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleTransactionControllerStateChange).bind(this), "f");
63
+ }
64
+ start() {
65
+ this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"), (state) => state.transactions);
66
+ }
67
+ stop() {
68
+ this.messagingSystem.unsubscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"));
69
+ }
70
+ /**
71
+ * Checks the coverage of a transaction.
72
+ *
73
+ * @param txMeta - The transaction to check coverage for.
74
+ * @returns The coverage result.
75
+ */
76
+ async checkCoverage(txMeta) {
77
+ // Check coverage
78
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_fetchCoverageResult).call(this, txMeta);
79
+ // Publish coverage result
80
+ this.messagingSystem.publish(`${controllerName}:coverageResultReceived`, coverageResult);
81
+ // Update state
82
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_addCoverageResult).call(this, txMeta.id, coverageResult);
83
+ return coverageResult;
84
+ }
85
+ }
86
+ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleTransactionControllerStateChange = function _ShieldController_handleTransactionControllerStateChange(transactions, previousTransactions) {
87
+ const previousTransactionsById = new Map(previousTransactions?.map((tx) => [tx.id, tx]) ?? []);
88
+ for (const transaction of transactions) {
89
+ const previousTransaction = previousTransactionsById.get(transaction.id);
90
+ // Check coverage if the transaction is new or if the simulation data has
91
+ // changed.
92
+ if (!previousTransaction ||
93
+ // Checking reference equality is sufficient because this object is
94
+ // replaced if the simulation data has changed.
95
+ previousTransaction.simulationData !== transaction.simulationData) {
96
+ this.checkCoverage(transaction).catch(
97
+ // istanbul ignore next
98
+ (error) => log('Error checking coverage:', error));
99
+ }
100
+ }
101
+ }, _ShieldController_fetchCoverageResult = async function _ShieldController_fetchCoverageResult(txMeta) {
102
+ return __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage(txMeta);
103
+ }, _ShieldController_addCoverageResult = function _ShieldController_addCoverageResult(txId, coverageResult) {
104
+ this.update((draft) => {
105
+ // Fetch coverage result entry.
106
+ let newEntry = false;
107
+ let coverageResultEntry = draft.coverageResults[txId];
108
+ // Create new entry if necessary.
109
+ if (!coverageResultEntry) {
110
+ newEntry = true;
111
+ coverageResultEntry = {
112
+ results: [],
113
+ };
114
+ draft.coverageResults[txId] = coverageResultEntry;
115
+ }
116
+ // Trim coverage history if necessary.
117
+ if (coverageResultEntry.results.length >= __classPrivateFieldGet(this, _ShieldController_coverageHistoryLimit, "f")) {
118
+ coverageResultEntry.results.pop();
119
+ }
120
+ // Add new result.
121
+ coverageResultEntry.results.unshift(coverageResult);
122
+ // Add to history if new entry.
123
+ const { orderedTransactionHistory } = draft;
124
+ let removedTxId;
125
+ if (newEntry) {
126
+ // Trim transaction history if necessary.
127
+ if (orderedTransactionHistory.length >= __classPrivateFieldGet(this, _ShieldController_transactionHistoryLimit, "f")) {
128
+ removedTxId = orderedTransactionHistory.pop();
129
+ // Delete corresponding coverage result entry.
130
+ if (removedTxId) {
131
+ delete draft.coverageResults[removedTxId];
132
+ }
133
+ }
134
+ // Add to history.
135
+ orderedTransactionHistory.unshift(txId);
136
+ }
137
+ });
138
+ };
139
+ //# sourceMappingURL=ShieldController.mjs.map
@@ -0,0 +1 @@
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 ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport type {\n TransactionControllerStateChangeEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { CoverageResult, ShieldBackend } from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n results: CoverageResult[]; // history of coverage results, latest first\n};\n\nexport type ShieldControllerState = {\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n orderedTransactionHistory: string[]; // List of txIds ordered by time, latest first\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 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 = 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 actions available to the ShieldController.\n */\ntype AllowedActions = never;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents = TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\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 persist: true,\n anonymous: false,\n },\n orderedTransactionHistory: {\n persist: true,\n anonymous: 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\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 #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\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 }\n\n start() {\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n }\n\n stop() {\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\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 // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (\n !previousTransaction ||\n // Checking reference equality is sufficient because this object is\n // replaced if the simulation data has changed.\n previousTransaction.simulationData !== transaction.simulationData\n ) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', 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 coverageResult = await this.#fetchCoverageResult(txMeta);\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n async #fetchCoverageResult(txMeta: TransactionMeta): Promise<CoverageResult> {\n return this.#backend.checkCoverage(txMeta);\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\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"]}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _ShieldRemoteBackend_instances, _ShieldRemoteBackend_getAccessToken, _ShieldRemoteBackend_getCoverageResultTimeout, _ShieldRemoteBackend_getCoverageResultPollInterval, _ShieldRemoteBackend_baseUrl, _ShieldRemoteBackend_fetch, _ShieldRemoteBackend_initCoverageCheck, _ShieldRemoteBackend_getCoverageResult, _ShieldRemoteBackend_createHeaders;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ShieldRemoteBackend = exports.BASE_URL = void 0;
16
+ exports.BASE_URL = 'https://rule-engine.metamask.io';
17
+ class ShieldRemoteBackend {
18
+ constructor({ getAccessToken, getCoverageResultTimeout = 5000, // milliseconds
19
+ getCoverageResultPollInterval = 1000, // milliseconds
20
+ baseUrl = exports.BASE_URL, fetch: fetchFn, }) {
21
+ _ShieldRemoteBackend_instances.add(this);
22
+ _ShieldRemoteBackend_getAccessToken.set(this, void 0);
23
+ _ShieldRemoteBackend_getCoverageResultTimeout.set(this, void 0);
24
+ _ShieldRemoteBackend_getCoverageResultPollInterval.set(this, void 0);
25
+ _ShieldRemoteBackend_baseUrl.set(this, void 0);
26
+ _ShieldRemoteBackend_fetch.set(this, void 0);
27
+ this.checkCoverage = async (txMeta) => {
28
+ const reqBody = {
29
+ txParams: [
30
+ {
31
+ from: txMeta.txParams.from,
32
+ to: txMeta.txParams.to,
33
+ value: txMeta.txParams.value,
34
+ data: txMeta.txParams.data,
35
+ nonce: txMeta.txParams.nonce,
36
+ },
37
+ ],
38
+ chainId: txMeta.chainId,
39
+ origin: txMeta.origin,
40
+ };
41
+ const { coverageId } = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_initCoverageCheck).call(this, reqBody);
42
+ return __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_getCoverageResult).call(this, coverageId);
43
+ };
44
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_getAccessToken, getAccessToken, "f");
45
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultTimeout, getCoverageResultTimeout, "f");
46
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, getCoverageResultPollInterval, "f");
47
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_baseUrl, baseUrl, "f");
48
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_fetch, fetchFn, "f");
49
+ }
50
+ }
51
+ exports.ShieldRemoteBackend = ShieldRemoteBackend;
52
+ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCoverageResultTimeout = new WeakMap(), _ShieldRemoteBackend_getCoverageResultPollInterval = new WeakMap(), _ShieldRemoteBackend_baseUrl = new WeakMap(), _ShieldRemoteBackend_fetch = new WeakMap(), _ShieldRemoteBackend_instances = new WeakSet(), _ShieldRemoteBackend_initCoverageCheck = async function _ShieldRemoteBackend_initCoverageCheck(reqBody) {
53
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/api/v1/coverage/init`, {
54
+ method: 'POST',
55
+ headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
56
+ body: JSON.stringify(reqBody),
57
+ });
58
+ if (res.status !== 200) {
59
+ throw new Error(`Failed to init coverage check: ${res.status}`);
60
+ }
61
+ return (await res.json());
62
+ }, _ShieldRemoteBackend_getCoverageResult = async function _ShieldRemoteBackend_getCoverageResult(coverageId, timeout = __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultTimeout, "f"), pollInterval = __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, "f")) {
63
+ const reqBody = {
64
+ coverageId,
65
+ };
66
+ const headers = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this);
67
+ return await new Promise((resolve, reject) => {
68
+ let timeoutReached = false;
69
+ setTimeout(() => {
70
+ timeoutReached = true;
71
+ reject(new Error('Timeout waiting for coverage result'));
72
+ }, timeout);
73
+ const poll = async () => {
74
+ // The timeoutReached variable is modified in the timeout callback.
75
+ // eslint-disable-next-line no-unmodified-loop-condition
76
+ while (!timeoutReached) {
77
+ const startTime = Date.now();
78
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/api/v1/coverage/result`, {
79
+ method: 'POST',
80
+ headers,
81
+ body: JSON.stringify(reqBody),
82
+ });
83
+ if (res.status === 200) {
84
+ return (await res.json());
85
+ }
86
+ await sleep(pollInterval - (Date.now() - startTime));
87
+ }
88
+ // The following line will not have an effect as the upper level promise
89
+ // will already be rejected by now.
90
+ throw new Error('unexpected error');
91
+ };
92
+ poll().then(resolve).catch(reject);
93
+ });
94
+ }, _ShieldRemoteBackend_createHeaders = async function _ShieldRemoteBackend_createHeaders() {
95
+ const accessToken = await __classPrivateFieldGet(this, _ShieldRemoteBackend_getAccessToken, "f").call(this);
96
+ return {
97
+ 'Content-Type': 'application/json',
98
+ Authorization: `Bearer ${accessToken}`,
99
+ };
100
+ };
101
+ /**
102
+ * Sleep for a specified amount of time.
103
+ *
104
+ * @param ms - The number of milliseconds to sleep.
105
+ * @returns A promise that resolves after the specified amount of time.
106
+ */
107
+ async function sleep(ms) {
108
+ return new Promise((resolve) => setTimeout(resolve, ms));
109
+ }
110
+ //# sourceMappingURL=backend.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.cjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\n\nimport type { CoverageResult, CoverageStatus, ShieldBackend } from './types';\n\nexport const BASE_URL = 'https://rule-engine.metamask.io';\n\nexport type InitCoverageCheckRequest = {\n txParams: [\n {\n from: string;\n to?: string;\n value?: string;\n data?: string;\n nonce?: string;\n },\n ];\n chainId: string;\n origin?: string;\n};\n\nexport type InitCoverageCheckResponse = {\n coverageId: string;\n};\n\nexport type GetCoverageResultRequest = {\n coverageId: string;\n};\n\nexport type GetCoverageResultResponse = {\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #getCoverageResultTimeout: number;\n\n readonly #getCoverageResultPollInterval: number;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n constructor({\n getAccessToken,\n getCoverageResultTimeout = 5000, // milliseconds\n getCoverageResultPollInterval = 1000, // milliseconds\n baseUrl = BASE_URL,\n fetch: fetchFn,\n }: {\n getAccessToken: () => Promise<string>;\n getCoverageResultTimeout?: number;\n getCoverageResultPollInterval?: number;\n baseUrl?: string;\n fetch: typeof globalThis.fetch;\n }) {\n this.#getAccessToken = getAccessToken;\n this.#getCoverageResultTimeout = getCoverageResultTimeout;\n this.#getCoverageResultPollInterval = getCoverageResultPollInterval;\n this.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n }\n\n checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult> = async (\n txMeta,\n ) => {\n const reqBody: InitCoverageCheckRequest = {\n txParams: [\n {\n from: txMeta.txParams.from,\n to: txMeta.txParams.to,\n value: txMeta.txParams.value,\n data: txMeta.txParams.data,\n nonce: txMeta.txParams.nonce,\n },\n ],\n chainId: txMeta.chainId,\n origin: txMeta.origin,\n };\n\n const { coverageId } = await this.#initCoverageCheck(reqBody);\n\n return this.#getCoverageResult(coverageId);\n };\n\n async #initCoverageCheck(\n reqBody: InitCoverageCheckRequest,\n ): Promise<InitCoverageCheckResponse> {\n const res = await this.#fetch(`${this.#baseUrl}/api/v1/coverage/init`, {\n method: 'POST',\n headers: await this.#createHeaders(),\n body: JSON.stringify(reqBody),\n });\n if (res.status !== 200) {\n throw new Error(`Failed to init coverage check: ${res.status}`);\n }\n return (await res.json()) as InitCoverageCheckResponse;\n }\n\n async #getCoverageResult(\n coverageId: string,\n timeout: number = this.#getCoverageResultTimeout,\n pollInterval: number = this.#getCoverageResultPollInterval,\n ): Promise<GetCoverageResultResponse> {\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n return await new Promise((resolve, reject) => {\n let timeoutReached = false;\n setTimeout(() => {\n timeoutReached = true;\n reject(new Error('Timeout waiting for coverage result'));\n }, timeout);\n\n const poll = async (): Promise<GetCoverageResultResponse> => {\n // The timeoutReached variable is modified in the timeout callback.\n // eslint-disable-next-line no-unmodified-loop-condition\n while (!timeoutReached) {\n const startTime = Date.now();\n const res = await this.#fetch(\n `${this.#baseUrl}/api/v1/coverage/result`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n },\n );\n if (res.status === 200) {\n return (await res.json()) as GetCoverageResultResponse;\n }\n await sleep(pollInterval - (Date.now() - startTime));\n }\n // The following line will not have an effect as the upper level promise\n // will already be rejected by now.\n throw new Error('unexpected error');\n };\n\n poll().then(resolve).catch(reject);\n });\n }\n\n async #createHeaders() {\n const accessToken = await this.#getAccessToken();\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n };\n }\n}\n\n/**\n * Sleep for a specified amount of time.\n *\n * @param ms - The number of milliseconds to sleep.\n * @returns A promise that resolves after the specified amount of time.\n */\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import type { TransactionMeta } from "@metamask/transaction-controller";
2
+ import type { CoverageResult, CoverageStatus, ShieldBackend } from "./types.cjs";
3
+ export declare const BASE_URL = "https://rule-engine.metamask.io";
4
+ export type InitCoverageCheckRequest = {
5
+ txParams: [
6
+ {
7
+ from: string;
8
+ to?: string;
9
+ value?: string;
10
+ data?: string;
11
+ nonce?: string;
12
+ }
13
+ ];
14
+ chainId: string;
15
+ origin?: string;
16
+ };
17
+ export type InitCoverageCheckResponse = {
18
+ coverageId: string;
19
+ };
20
+ export type GetCoverageResultRequest = {
21
+ coverageId: string;
22
+ };
23
+ export type GetCoverageResultResponse = {
24
+ status: CoverageStatus;
25
+ };
26
+ export declare class ShieldRemoteBackend implements ShieldBackend {
27
+ #private;
28
+ constructor({ getAccessToken, getCoverageResultTimeout, // milliseconds
29
+ getCoverageResultPollInterval, // milliseconds
30
+ baseUrl, fetch: fetchFn, }: {
31
+ getAccessToken: () => Promise<string>;
32
+ getCoverageResultTimeout?: number;
33
+ getCoverageResultPollInterval?: number;
34
+ baseUrl?: string;
35
+ fetch: typeof globalThis.fetch;
36
+ });
37
+ checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
38
+ }
39
+ //# sourceMappingURL=backend.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.cts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAE7E,eAAO,MAAM,QAAQ,oCAAoC,CAAC;AAE1D,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,MAAM,CAAC;YACb,EAAE,CAAC,EAAE,MAAM,CAAC;YACZ,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB;KACF,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAW3C,EACV,cAAc,EACd,wBAA+B,EAAE,eAAe;IAChD,6BAAoC,EAAE,eAAe;IACrD,OAAkB,EAClB,KAAK,EAAE,OAAO,GACf,EAAE;QACD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QACvC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQD,aAAa,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAoBjE;CAmEH"}
@@ -0,0 +1,39 @@
1
+ import type { TransactionMeta } from "@metamask/transaction-controller";
2
+ import type { CoverageResult, CoverageStatus, ShieldBackend } from "./types.mjs";
3
+ export declare const BASE_URL = "https://rule-engine.metamask.io";
4
+ export type InitCoverageCheckRequest = {
5
+ txParams: [
6
+ {
7
+ from: string;
8
+ to?: string;
9
+ value?: string;
10
+ data?: string;
11
+ nonce?: string;
12
+ }
13
+ ];
14
+ chainId: string;
15
+ origin?: string;
16
+ };
17
+ export type InitCoverageCheckResponse = {
18
+ coverageId: string;
19
+ };
20
+ export type GetCoverageResultRequest = {
21
+ coverageId: string;
22
+ };
23
+ export type GetCoverageResultResponse = {
24
+ status: CoverageStatus;
25
+ };
26
+ export declare class ShieldRemoteBackend implements ShieldBackend {
27
+ #private;
28
+ constructor({ getAccessToken, getCoverageResultTimeout, // milliseconds
29
+ getCoverageResultPollInterval, // milliseconds
30
+ baseUrl, fetch: fetchFn, }: {
31
+ getAccessToken: () => Promise<string>;
32
+ getCoverageResultTimeout?: number;
33
+ getCoverageResultPollInterval?: number;
34
+ baseUrl?: string;
35
+ fetch: typeof globalThis.fetch;
36
+ });
37
+ checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
38
+ }
39
+ //# sourceMappingURL=backend.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.mts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAE7E,eAAO,MAAM,QAAQ,oCAAoC,CAAC;AAE1D,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,MAAM,CAAC;YACb,EAAE,CAAC,EAAE,MAAM,CAAC;YACZ,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB;KACF,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAW3C,EACV,cAAc,EACd,wBAA+B,EAAE,eAAe;IAChD,6BAAoC,EAAE,eAAe;IACrD,OAAkB,EAClB,KAAK,EAAE,OAAO,GACf,EAAE;QACD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QACvC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQD,aAAa,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAoBjE;CAmEH"}
@@ -0,0 +1,106 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _ShieldRemoteBackend_instances, _ShieldRemoteBackend_getAccessToken, _ShieldRemoteBackend_getCoverageResultTimeout, _ShieldRemoteBackend_getCoverageResultPollInterval, _ShieldRemoteBackend_baseUrl, _ShieldRemoteBackend_fetch, _ShieldRemoteBackend_initCoverageCheck, _ShieldRemoteBackend_getCoverageResult, _ShieldRemoteBackend_createHeaders;
13
+ export const BASE_URL = 'https://rule-engine.metamask.io';
14
+ export class ShieldRemoteBackend {
15
+ constructor({ getAccessToken, getCoverageResultTimeout = 5000, // milliseconds
16
+ getCoverageResultPollInterval = 1000, // milliseconds
17
+ baseUrl = BASE_URL, fetch: fetchFn, }) {
18
+ _ShieldRemoteBackend_instances.add(this);
19
+ _ShieldRemoteBackend_getAccessToken.set(this, void 0);
20
+ _ShieldRemoteBackend_getCoverageResultTimeout.set(this, void 0);
21
+ _ShieldRemoteBackend_getCoverageResultPollInterval.set(this, void 0);
22
+ _ShieldRemoteBackend_baseUrl.set(this, void 0);
23
+ _ShieldRemoteBackend_fetch.set(this, void 0);
24
+ this.checkCoverage = async (txMeta) => {
25
+ const reqBody = {
26
+ txParams: [
27
+ {
28
+ from: txMeta.txParams.from,
29
+ to: txMeta.txParams.to,
30
+ value: txMeta.txParams.value,
31
+ data: txMeta.txParams.data,
32
+ nonce: txMeta.txParams.nonce,
33
+ },
34
+ ],
35
+ chainId: txMeta.chainId,
36
+ origin: txMeta.origin,
37
+ };
38
+ const { coverageId } = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_initCoverageCheck).call(this, reqBody);
39
+ return __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_getCoverageResult).call(this, coverageId);
40
+ };
41
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_getAccessToken, getAccessToken, "f");
42
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultTimeout, getCoverageResultTimeout, "f");
43
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, getCoverageResultPollInterval, "f");
44
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_baseUrl, baseUrl, "f");
45
+ __classPrivateFieldSet(this, _ShieldRemoteBackend_fetch, fetchFn, "f");
46
+ }
47
+ }
48
+ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCoverageResultTimeout = new WeakMap(), _ShieldRemoteBackend_getCoverageResultPollInterval = new WeakMap(), _ShieldRemoteBackend_baseUrl = new WeakMap(), _ShieldRemoteBackend_fetch = new WeakMap(), _ShieldRemoteBackend_instances = new WeakSet(), _ShieldRemoteBackend_initCoverageCheck = async function _ShieldRemoteBackend_initCoverageCheck(reqBody) {
49
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/api/v1/coverage/init`, {
50
+ method: 'POST',
51
+ headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
52
+ body: JSON.stringify(reqBody),
53
+ });
54
+ if (res.status !== 200) {
55
+ throw new Error(`Failed to init coverage check: ${res.status}`);
56
+ }
57
+ return (await res.json());
58
+ }, _ShieldRemoteBackend_getCoverageResult = async function _ShieldRemoteBackend_getCoverageResult(coverageId, timeout = __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultTimeout, "f"), pollInterval = __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, "f")) {
59
+ const reqBody = {
60
+ coverageId,
61
+ };
62
+ const headers = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this);
63
+ return await new Promise((resolve, reject) => {
64
+ let timeoutReached = false;
65
+ setTimeout(() => {
66
+ timeoutReached = true;
67
+ reject(new Error('Timeout waiting for coverage result'));
68
+ }, timeout);
69
+ const poll = async () => {
70
+ // The timeoutReached variable is modified in the timeout callback.
71
+ // eslint-disable-next-line no-unmodified-loop-condition
72
+ while (!timeoutReached) {
73
+ const startTime = Date.now();
74
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/api/v1/coverage/result`, {
75
+ method: 'POST',
76
+ headers,
77
+ body: JSON.stringify(reqBody),
78
+ });
79
+ if (res.status === 200) {
80
+ return (await res.json());
81
+ }
82
+ await sleep(pollInterval - (Date.now() - startTime));
83
+ }
84
+ // The following line will not have an effect as the upper level promise
85
+ // will already be rejected by now.
86
+ throw new Error('unexpected error');
87
+ };
88
+ poll().then(resolve).catch(reject);
89
+ });
90
+ }, _ShieldRemoteBackend_createHeaders = async function _ShieldRemoteBackend_createHeaders() {
91
+ const accessToken = await __classPrivateFieldGet(this, _ShieldRemoteBackend_getAccessToken, "f").call(this);
92
+ return {
93
+ 'Content-Type': 'application/json',
94
+ Authorization: `Bearer ${accessToken}`,
95
+ };
96
+ };
97
+ /**
98
+ * Sleep for a specified amount of time.
99
+ *
100
+ * @param ms - The number of milliseconds to sleep.
101
+ * @returns A promise that resolves after the specified amount of time.
102
+ */
103
+ async function sleep(ms) {
104
+ return new Promise((resolve) => setTimeout(resolve, ms));
105
+ }
106
+ //# sourceMappingURL=backend.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.mjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\n\nimport type { CoverageResult, CoverageStatus, ShieldBackend } from './types';\n\nexport const BASE_URL = 'https://rule-engine.metamask.io';\n\nexport type InitCoverageCheckRequest = {\n txParams: [\n {\n from: string;\n to?: string;\n value?: string;\n data?: string;\n nonce?: string;\n },\n ];\n chainId: string;\n origin?: string;\n};\n\nexport type InitCoverageCheckResponse = {\n coverageId: string;\n};\n\nexport type GetCoverageResultRequest = {\n coverageId: string;\n};\n\nexport type GetCoverageResultResponse = {\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #getCoverageResultTimeout: number;\n\n readonly #getCoverageResultPollInterval: number;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n constructor({\n getAccessToken,\n getCoverageResultTimeout = 5000, // milliseconds\n getCoverageResultPollInterval = 1000, // milliseconds\n baseUrl = BASE_URL,\n fetch: fetchFn,\n }: {\n getAccessToken: () => Promise<string>;\n getCoverageResultTimeout?: number;\n getCoverageResultPollInterval?: number;\n baseUrl?: string;\n fetch: typeof globalThis.fetch;\n }) {\n this.#getAccessToken = getAccessToken;\n this.#getCoverageResultTimeout = getCoverageResultTimeout;\n this.#getCoverageResultPollInterval = getCoverageResultPollInterval;\n this.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n }\n\n checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult> = async (\n txMeta,\n ) => {\n const reqBody: InitCoverageCheckRequest = {\n txParams: [\n {\n from: txMeta.txParams.from,\n to: txMeta.txParams.to,\n value: txMeta.txParams.value,\n data: txMeta.txParams.data,\n nonce: txMeta.txParams.nonce,\n },\n ],\n chainId: txMeta.chainId,\n origin: txMeta.origin,\n };\n\n const { coverageId } = await this.#initCoverageCheck(reqBody);\n\n return this.#getCoverageResult(coverageId);\n };\n\n async #initCoverageCheck(\n reqBody: InitCoverageCheckRequest,\n ): Promise<InitCoverageCheckResponse> {\n const res = await this.#fetch(`${this.#baseUrl}/api/v1/coverage/init`, {\n method: 'POST',\n headers: await this.#createHeaders(),\n body: JSON.stringify(reqBody),\n });\n if (res.status !== 200) {\n throw new Error(`Failed to init coverage check: ${res.status}`);\n }\n return (await res.json()) as InitCoverageCheckResponse;\n }\n\n async #getCoverageResult(\n coverageId: string,\n timeout: number = this.#getCoverageResultTimeout,\n pollInterval: number = this.#getCoverageResultPollInterval,\n ): Promise<GetCoverageResultResponse> {\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n return await new Promise((resolve, reject) => {\n let timeoutReached = false;\n setTimeout(() => {\n timeoutReached = true;\n reject(new Error('Timeout waiting for coverage result'));\n }, timeout);\n\n const poll = async (): Promise<GetCoverageResultResponse> => {\n // The timeoutReached variable is modified in the timeout callback.\n // eslint-disable-next-line no-unmodified-loop-condition\n while (!timeoutReached) {\n const startTime = Date.now();\n const res = await this.#fetch(\n `${this.#baseUrl}/api/v1/coverage/result`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n },\n );\n if (res.status === 200) {\n return (await res.json()) as GetCoverageResultResponse;\n }\n await sleep(pollInterval - (Date.now() - startTime));\n }\n // The following line will not have an effect as the upper level promise\n // will already be rejected by now.\n throw new Error('unexpected error');\n };\n\n poll().then(resolve).catch(reject);\n });\n }\n\n async #createHeaders() {\n const accessToken = await this.#getAccessToken();\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n };\n }\n}\n\n/**\n * Sleep for a specified amount of time.\n *\n * @param ms - The number of milliseconds to sleep.\n * @returns A promise that resolves after the specified amount of time.\n */\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"]}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.controllerName = void 0;
4
+ /**
5
+ * The name of the {@link ShieldController}.
6
+ */
7
+ exports.controllerName = 'ShieldController';
8
+ //# sourceMappingURL=constants.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,cAAc,GAAG,kBAAkB,CAAC","sourcesContent":["/**\n * The name of the {@link ShieldController}.\n */\nexport const controllerName = 'ShieldController';\n"]}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The name of the {@link ShieldController}.
3
+ */
4
+ export declare const controllerName = "ShieldController";
5
+ //# sourceMappingURL=constants.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The name of the {@link ShieldController}.
3
+ */
4
+ export declare const controllerName = "ShieldController";
5
+ //# sourceMappingURL=constants.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The name of the {@link ShieldController}.
3
+ */
4
+ export const controllerName = 'ShieldController';
5
+ //# sourceMappingURL=constants.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC","sourcesContent":["/**\n * The name of the {@link ShieldController}.\n */\nexport const controllerName = 'ShieldController';\n"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDefaultShieldControllerState = exports.ShieldController = void 0;
4
+ var ShieldController_1 = require("./ShieldController.cjs");
5
+ Object.defineProperty(exports, "ShieldController", { enumerable: true, get: function () { return ShieldController_1.ShieldController; } });
6
+ Object.defineProperty(exports, "getDefaultShieldControllerState", { enumerable: true, get: function () { return ShieldController_1.getDefaultShieldControllerState; } });
7
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAUA,2DAG4B;AAF1B,oHAAA,gBAAgB,OAAA;AAChB,mIAAA,+BAA+B,OAAA","sourcesContent":["export type { CoverageStatus } from './types';\nexport type {\n ShieldControllerActions,\n ShieldControllerEvents,\n ShieldControllerMessenger,\n ShieldControllerState,\n ShieldControllerCheckCoverageAction,\n ShieldControllerCoverageResultReceivedEvent,\n ShieldControllerStateChangeEvent,\n} from './ShieldController';\nexport {\n ShieldController,\n getDefaultShieldControllerState,\n} from './ShieldController';\n"]}
@@ -0,0 +1,4 @@
1
+ export type { CoverageStatus } from "./types.cjs";
2
+ export type { ShieldControllerActions, ShieldControllerEvents, ShieldControllerMessenger, ShieldControllerState, ShieldControllerCheckCoverageAction, ShieldControllerCoverageResultReceivedEvent, ShieldControllerStateChangeEvent, } from "./ShieldController.cjs";
3
+ export { ShieldController, getDefaultShieldControllerState, } from "./ShieldController.cjs";
4
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,oBAAgB;AAC9C,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,mCAAmC,EACnC,2CAA2C,EAC3C,gCAAgC,GACjC,+BAA2B;AAC5B,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA2B"}
@@ -0,0 +1,4 @@
1
+ export type { CoverageStatus } from "./types.mjs";
2
+ export type { ShieldControllerActions, ShieldControllerEvents, ShieldControllerMessenger, ShieldControllerState, ShieldControllerCheckCoverageAction, ShieldControllerCoverageResultReceivedEvent, ShieldControllerStateChangeEvent, } from "./ShieldController.mjs";
3
+ export { ShieldController, getDefaultShieldControllerState, } from "./ShieldController.mjs";
4
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,oBAAgB;AAC9C,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,mCAAmC,EACnC,2CAA2C,EAC3C,gCAAgC,GACjC,+BAA2B;AAC5B,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA2B"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export { ShieldController, getDefaultShieldControllerState } from "./ShieldController.mjs";
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,EAChC,+BAA2B","sourcesContent":["export type { CoverageStatus } from './types';\nexport type {\n ShieldControllerActions,\n ShieldControllerEvents,\n ShieldControllerMessenger,\n ShieldControllerState,\n ShieldControllerCheckCoverageAction,\n ShieldControllerCoverageResultReceivedEvent,\n ShieldControllerStateChangeEvent,\n} from './ShieldController';\nexport {\n ShieldController,\n getDefaultShieldControllerState,\n} from './ShieldController';\n"]}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createModuleLogger = exports.projectLogger = void 0;
4
+ const utils_1 = require("@metamask/utils");
5
+ Object.defineProperty(exports, "createModuleLogger", { enumerable: true, get: function () { return utils_1.createModuleLogger; } });
6
+ const constants_1 = require("./constants.cjs");
7
+ exports.projectLogger = (0, utils_1.createProjectLogger)(constants_1.controllerName);
8
+ //# sourceMappingURL=logger.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.cjs","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;AAAA,2CAA0E;AAMjE,mGANqB,0BAAkB,OAMrB;AAJ3B,+CAA6C;AAEhC,QAAA,aAAa,GAAG,IAAA,2BAAmB,EAAC,0BAAc,CAAC,CAAC","sourcesContent":["import { createProjectLogger, createModuleLogger } from '@metamask/utils';\n\nimport { controllerName } from './constants';\n\nexport const projectLogger = createProjectLogger(controllerName);\n\nexport { createModuleLogger };\n"]}
@@ -0,0 +1,5 @@
1
+ /// <reference types="debug" />
2
+ import { createModuleLogger } from "@metamask/utils";
3
+ export declare const projectLogger: import("debug").Debugger;
4
+ export { createModuleLogger };
5
+ //# sourceMappingURL=logger.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.cts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA,OAAO,EAAuB,kBAAkB,EAAE,wBAAwB;AAI1E,eAAO,MAAM,aAAa,0BAAsC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /// <reference types="debug" />
2
+ import { createModuleLogger } from "@metamask/utils";
3
+ export declare const projectLogger: import("debug").Debugger;
4
+ export { createModuleLogger };
5
+ //# sourceMappingURL=logger.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.mts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA,OAAO,EAAuB,kBAAkB,EAAE,wBAAwB;AAI1E,eAAO,MAAM,aAAa,0BAAsC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { createProjectLogger, createModuleLogger } from "@metamask/utils";
2
+ import { controllerName } from "./constants.mjs";
3
+ export const projectLogger = createProjectLogger(controllerName);
4
+ export { createModuleLogger };
5
+ //# sourceMappingURL=logger.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.mjs","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,wBAAwB;AAE1E,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["import { createProjectLogger, createModuleLogger } from '@metamask/utils';\n\nimport { controllerName } from './constants';\n\nexport const projectLogger = createProjectLogger(controllerName);\n\nexport { createModuleLogger };\n"]}
package/dist/types.cjs ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.coverageStatuses = void 0;
4
+ exports.coverageStatuses = ['covered', 'malicious', 'unknown'];
5
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAMa,QAAA,gBAAgB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,CAAU,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\n\nexport type CoverageResult = {\n status: CoverageStatus;\n};\n\nexport const coverageStatuses = ['covered', 'malicious', 'unknown'] as const;\nexport type CoverageStatus = (typeof coverageStatuses)[number];\n\nexport type ShieldBackend = {\n checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;\n};\n"]}
@@ -0,0 +1,10 @@
1
+ import type { TransactionMeta } from "@metamask/transaction-controller";
2
+ export type CoverageResult = {
3
+ status: CoverageStatus;
4
+ };
5
+ export declare const coverageStatuses: readonly ["covered", "malicious", "unknown"];
6
+ export type CoverageStatus = (typeof coverageStatuses)[number];
7
+ export type ShieldBackend = {
8
+ checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
9
+ };
10
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,8CAA+C,CAAC;AAC7E,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACrE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { TransactionMeta } from "@metamask/transaction-controller";
2
+ export type CoverageResult = {
3
+ status: CoverageStatus;
4
+ };
5
+ export declare const coverageStatuses: readonly ["covered", "malicious", "unknown"];
6
+ export type CoverageStatus = (typeof coverageStatuses)[number];
7
+ export type ShieldBackend = {
8
+ checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
9
+ };
10
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,8CAA+C,CAAC;AAC7E,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACrE,CAAC"}
package/dist/types.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export const coverageStatuses = ['covered', 'malicious', 'unknown'];
2
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,CAAU,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\n\nexport type CoverageResult = {\n status: CoverageStatus;\n};\n\nexport const coverageStatuses = ['covered', 'malicious', 'unknown'] as const;\nexport type CoverageStatus = (typeof coverageStatuses)[number];\n\nexport type ShieldBackend = {\n checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;\n};\n"]}
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@metamask/shield-controller",
3
+ "version": "0.1.0",
4
+ "description": "Controller handling shield transaction coverage logic",
5
+ "keywords": [
6
+ "MetaMask",
7
+ "Ethereum"
8
+ ],
9
+ "homepage": "https://github.com/MetaMask/core/tree/main/packages/shield-controller#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/MetaMask/core/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/MetaMask/core.git"
16
+ },
17
+ "license": "MIT",
18
+ "sideEffects": false,
19
+ "exports": {
20
+ ".": {
21
+ "import": {
22
+ "types": "./dist/index.d.mts",
23
+ "default": "./dist/index.mjs"
24
+ },
25
+ "require": {
26
+ "types": "./dist/index.d.cts",
27
+ "default": "./dist/index.cjs"
28
+ }
29
+ },
30
+ "./package.json": "./package.json"
31
+ },
32
+ "main": "./dist/index.cjs",
33
+ "types": "./dist/index.d.cts",
34
+ "files": [
35
+ "dist/"
36
+ ],
37
+ "scripts": {
38
+ "build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
39
+ "build:docs": "typedoc",
40
+ "changelog:update": "../../scripts/update-changelog.sh @metamask/shield-controller",
41
+ "changelog:validate": "../../scripts/validate-changelog.sh @metamask/shield-controller",
42
+ "publish:preview": "yarn npm publish --tag preview",
43
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=jest-silent-reporter",
44
+ "test:clean": "NODE_OPTIONS=--experimental-vm-modules jest --clearCache",
45
+ "test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
46
+ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch",
47
+ "since-latest-release": "../../scripts/since-latest-release.sh"
48
+ },
49
+ "dependencies": {
50
+ "@metamask/base-controller": "^8.2.0",
51
+ "@metamask/utils": "^11.4.2"
52
+ },
53
+ "devDependencies": {
54
+ "@babel/runtime": "^7.23.9",
55
+ "@lavamoat/allow-scripts": "^3.0.4",
56
+ "@lavamoat/preinstall-always-fail": "^2.1.0",
57
+ "@metamask/auto-changelog": "^3.4.4",
58
+ "@metamask/transaction-controller": "^60.1.0",
59
+ "@ts-bridge/cli": "^0.6.1",
60
+ "@types/jest": "^27.4.1",
61
+ "deepmerge": "^4.2.2",
62
+ "jest": "^27.5.1",
63
+ "ts-jest": "^27.1.4",
64
+ "typedoc": "^0.24.8",
65
+ "typedoc-plugin-missing-exports": "^2.0.0",
66
+ "typescript": "~5.2.2",
67
+ "uuid": "^8.3.2"
68
+ },
69
+ "peerDependencies": {
70
+ "@metamask/transaction-controller": "^60.0.0"
71
+ },
72
+ "engines": {
73
+ "node": "^18.18 || >=20"
74
+ },
75
+ "publishConfig": {
76
+ "access": "public",
77
+ "registry": "https://registry.npmjs.org/"
78
+ },
79
+ "lavamoat": {
80
+ "allowScripts": {
81
+ "@lavamoat/allow-scripts>@lavamoat/preinstall-always-fail": false
82
+ }
83
+ }
84
+ }