@metamask/shield-controller 0.1.1 → 0.2.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 CHANGED
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.0]
11
+
12
+ ### Added
13
+
14
+ - Add two new controller state metadata properties: `includeInStateLogs` and `usedInUi` ([#6504](https://github.com/MetaMask/core/pull/6504))
15
+ - Add signature coverage checking ([#6501](https://github.com/MetaMask/core/pull/6501))
16
+ - Add transaction and signature logging ([#6633](https://github.com/MetaMask/core/pull/6633))
17
+
18
+ ### Changed
19
+
20
+ - Bump `@metamask/signature-controller` from `^33.0.0` to `^34.0.0` ([#6702](https://github.com/MetaMask/core/pull/6702))
21
+ - Bump `@metamask/base-controller` from `^8.2.0` to `^8.4.0` ([#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632))
22
+ - Bump `@metamask/utils` from `^11.4.2` to `^11.8.0` ([#6588](https://github.com/MetaMask/core/pull/6588))
23
+
24
+ ## [0.1.2]
25
+
26
+ ### Fixed
27
+
28
+ - Fixed backend URL paths ([#6433](https://github.com/MetaMask/core/pull/6433))
29
+
10
30
  ## [0.1.1]
11
31
 
12
32
  ### Fixed
@@ -19,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
19
39
 
20
40
  - Initial release of the shield-controller package ([#6137](https://github.com/MetaMask/core/pull/6137)
21
41
 
22
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@0.1.1...HEAD
42
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@0.2.0...HEAD
43
+ [0.2.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@0.1.2...@metamask/shield-controller@0.2.0
44
+ [0.1.2]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@0.1.1...@metamask/shield-controller@0.1.2
23
45
  [0.1.1]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@0.1.0...@metamask/shield-controller@0.1.1
24
46
  [0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/shield-controller@0.1.0
@@ -10,10 +10,12 @@ 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_transactionControllerStateChangeHandler, _ShieldController_handleTransactionControllerStateChange, _ShieldController_fetchCoverageResult, _ShieldController_addCoverageResult;
13
+ var _ShieldController_instances, _ShieldController_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction, _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");
17
+ const signature_controller_1 = require("@metamask/signature-controller");
18
+ const transaction_controller_1 = require("@metamask/transaction-controller");
17
19
  const constants_1 = require("./constants.cjs");
18
20
  const logger_1 = require("./logger.cjs");
19
21
  const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, 'ShieldController');
@@ -35,12 +37,16 @@ exports.getDefaultShieldControllerState = getDefaultShieldControllerState;
35
37
  */
36
38
  const metadata = {
37
39
  coverageResults: {
40
+ includeInStateLogs: true,
38
41
  persist: true,
39
42
  anonymous: false,
43
+ usedInUi: true,
40
44
  },
41
45
  orderedTransactionHistory: {
46
+ includeInStateLogs: true,
42
47
  persist: true,
43
48
  anonymous: false,
49
+ usedInUi: false,
44
50
  },
45
51
  };
46
52
  class ShieldController extends base_controller_1.BaseController {
@@ -60,16 +66,20 @@ class ShieldController extends base_controller_1.BaseController {
60
66
  _ShieldController_coverageHistoryLimit.set(this, void 0);
61
67
  _ShieldController_transactionHistoryLimit.set(this, void 0);
62
68
  _ShieldController_transactionControllerStateChangeHandler.set(this, void 0);
69
+ _ShieldController_signatureControllerStateChangeHandler.set(this, void 0);
63
70
  __classPrivateFieldSet(this, _ShieldController_backend, backend, "f");
64
71
  __classPrivateFieldSet(this, _ShieldController_coverageHistoryLimit, coverageHistoryLimit, "f");
65
72
  __classPrivateFieldSet(this, _ShieldController_transactionHistoryLimit, transactionHistoryLimit, "f");
66
73
  __classPrivateFieldSet(this, _ShieldController_transactionControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleTransactionControllerStateChange).bind(this), "f");
74
+ __classPrivateFieldSet(this, _ShieldController_signatureControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleSignatureControllerStateChange).bind(this), "f");
67
75
  }
68
76
  start() {
69
77
  this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"), (state) => state.transactions);
78
+ this.messagingSystem.subscribe('SignatureController:stateChange', __classPrivateFieldGet(this, _ShieldController_signatureControllerStateChangeHandler, "f"), (state) => state.signatureRequests);
70
79
  }
71
80
  stop() {
72
81
  this.messagingSystem.unsubscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"));
82
+ this.messagingSystem.unsubscribe('SignatureController:stateChange', __classPrivateFieldGet(this, _ShieldController_signatureControllerStateChangeHandler, "f"));
73
83
  }
74
84
  /**
75
85
  * Checks the coverage of a transaction.
@@ -79,16 +89,53 @@ class ShieldController extends base_controller_1.BaseController {
79
89
  */
80
90
  async checkCoverage(txMeta) {
81
91
  // Check coverage
82
- const coverageResult = await __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_fetchCoverageResult).call(this, txMeta);
92
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage(txMeta);
83
93
  // Publish coverage result
84
94
  this.messagingSystem.publish(`${constants_1.controllerName}:coverageResultReceived`, coverageResult);
85
95
  // Update state
86
96
  __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_addCoverageResult).call(this, txMeta.id, coverageResult);
87
97
  return coverageResult;
88
98
  }
99
+ /**
100
+ * Checks the coverage of a signature request.
101
+ *
102
+ * @param signatureRequest - The signature request to check coverage for.
103
+ * @returns The coverage result.
104
+ */
105
+ async checkSignatureCoverage(signatureRequest) {
106
+ // Check coverage
107
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkSignatureCoverage(signatureRequest);
108
+ // Publish coverage result
109
+ this.messagingSystem.publish(`${constants_1.controllerName}:coverageResultReceived`, coverageResult);
110
+ // Update state
111
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_addCoverageResult).call(this, signatureRequest.id, coverageResult);
112
+ return coverageResult;
113
+ }
89
114
  }
90
115
  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) {
116
+ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_signatureControllerStateChangeHandler = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleSignatureControllerStateChange = function _ShieldController_handleSignatureControllerStateChange(signatureRequests, previousSignatureRequests) {
117
+ const signatureRequestsArray = Object.values(signatureRequests);
118
+ const previousSignatureRequestsArray = Object.values(previousSignatureRequests ?? {});
119
+ const previousSignatureRequestsById = new Map(previousSignatureRequestsArray.map((request) => [request.id, request]));
120
+ for (const signatureRequest of signatureRequestsArray) {
121
+ const previousSignatureRequest = previousSignatureRequestsById.get(signatureRequest.id);
122
+ // Check coverage if the signature request is new and has type
123
+ // `personal_sign`.
124
+ if (!previousSignatureRequest &&
125
+ signatureRequest.type === signature_controller_1.SignatureRequestType.PersonalSign) {
126
+ this.checkSignatureCoverage(signatureRequest).catch(
127
+ // istanbul ignore next
128
+ (error) => log('Error checking coverage:', error));
129
+ }
130
+ // Log signature once the signature request has been fulfilled.
131
+ if (signatureRequest.status === signature_controller_1.SignatureRequestStatus.Signed &&
132
+ signatureRequest.status !== previousSignatureRequest?.status) {
133
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_logSignature).call(this, signatureRequest).catch(
134
+ // istanbul ignore next
135
+ (error) => log('Error logging signature:', error));
136
+ }
137
+ }
138
+ }, _ShieldController_handleTransactionControllerStateChange = function _ShieldController_handleTransactionControllerStateChange(transactions, previousTransactions) {
92
139
  const previousTransactionsById = new Map(previousTransactions?.map((tx) => [tx.id, tx]) ?? []);
93
140
  for (const transaction of transactions) {
94
141
  const previousTransaction = previousTransactionsById.get(transaction.id);
@@ -102,9 +149,14 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
102
149
  // istanbul ignore next
103
150
  (error) => log('Error checking coverage:', error));
104
151
  }
152
+ // Log transaction once it has been submitted.
153
+ if (transaction.status === transaction_controller_1.TransactionStatus.submitted &&
154
+ transaction.status !== previousTransaction?.status) {
155
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_logTransaction).call(this, transaction).catch(
156
+ // istanbul ignore next
157
+ (error) => log('Error logging transaction:', error));
158
+ }
105
159
  }
106
- }, _ShieldController_fetchCoverageResult = async function _ShieldController_fetchCoverageResult(txMeta) {
107
- return __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage(txMeta);
108
160
  }, _ShieldController_addCoverageResult = function _ShieldController_addCoverageResult(txId, coverageResult) {
109
161
  this.update((draft) => {
110
162
  // Fetch coverage result entry.
@@ -140,5 +192,41 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
140
192
  orderedTransactionHistory.unshift(txId);
141
193
  }
142
194
  });
195
+ }, _ShieldController_logSignature = async function _ShieldController_logSignature(signatureRequest) {
196
+ const coverageId = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getLatestCoverageId).call(this, signatureRequest.id);
197
+ if (!coverageId) {
198
+ throw new Error('Coverage ID not found');
199
+ }
200
+ const sig = signatureRequest.rawSig;
201
+ if (!sig) {
202
+ throw new Error('Signature not found');
203
+ }
204
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logSignature({
205
+ coverageId,
206
+ signature: sig,
207
+ // Status is 'shown' because the coverageId can only be retrieved after
208
+ // the result is in the state. If the result is in the state, we assume
209
+ // that it has been shown.
210
+ status: 'shown',
211
+ });
212
+ }, _ShieldController_logTransaction = async function _ShieldController_logTransaction(txMeta) {
213
+ const coverageId = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getLatestCoverageId).call(this, txMeta.id);
214
+ if (!coverageId) {
215
+ throw new Error('Coverage ID not found');
216
+ }
217
+ const txHash = txMeta.hash;
218
+ if (!txHash) {
219
+ throw new Error('Transaction hash not found');
220
+ }
221
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logTransaction({
222
+ coverageId,
223
+ transactionHash: txHash,
224
+ // Status is 'shown' because the coverageId can only be retrieved after
225
+ // the result is in the state. If the result is in the state, we assume
226
+ // that it has been shown.
227
+ status: 'shown',
228
+ });
229
+ }, _ShieldController_getLatestCoverageId = function _ShieldController_getLatestCoverageId(itemId) {
230
+ return this.state.coverageResults[itemId]?.results[0]?.coverageId;
143
231
  };
144
232
  //# sourceMappingURL=ShieldController.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n 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 /**\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 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"]}
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 {\n SignatureRequestStatus,\n SignatureRequestType,\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';\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 /**\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 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 =\n | SignatureStateChange\n | 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 includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n anonymous: 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\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 readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | 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 this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n }\n\n start() {\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messagingSystem.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messagingSystem.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 and has type\n // `personal_sign`.\n if (\n !previousSignatureRequest &&\n signatureRequest.type === SignatureRequestType.PersonalSign\n ) {\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 // 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 // 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 coverageResult = await this.#backend.checkCoverage(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 /**\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 coverageResult =\n await this.#backend.checkSignatureCoverage(signatureRequest);\n\n // Publish coverage result\n this.messagingSystem.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 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 coverageId = this.#getLatestCoverageId(signatureRequest.id);\n if (!coverageId) {\n throw new Error('Coverage ID not found');\n }\n\n const sig = signatureRequest.rawSig;\n if (!sig) {\n throw new Error('Signature not found');\n }\n\n await this.#backend.logSignature({\n coverageId,\n signature: sig,\n // Status is 'shown' because the coverageId can only be retrieved after\n // the result is in the state. If the result is in the state, we assume\n // that it has been shown.\n status: 'shown',\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n if (!coverageId) {\n throw new Error('Coverage ID not found');\n }\n\n const txHash = txMeta.hash;\n if (!txHash) {\n throw new Error('Transaction hash not found');\n }\n await this.#backend.logTransaction({\n coverageId,\n transactionHash: txHash,\n // Status is 'shown' because the coverageId can only be retrieved after\n // the result is in the state. If the result is in the state, we assume\n // that it has been shown.\n status: 'shown',\n });\n }\n\n #getLatestCoverageId(itemId: string) {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { BaseController } from "@metamask/base-controller";
2
2
  import type { ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
- import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
3
+ import { type SignatureRequest, type SignatureStateChange } from "@metamask/signature-controller";
4
+ import { type TransactionControllerStateChangeEvent, type TransactionMeta } from "@metamask/transaction-controller";
4
5
  import { controllerName } from "./constants.cjs";
5
6
  import type { CoverageResult, ShieldBackend } from "./types.cjs";
6
7
  export type CoverageResultRecordEntry = {
@@ -50,7 +51,7 @@ type AllowedActions = never;
50
51
  /**
51
52
  * The external events available to the ShieldController.
52
53
  */
53
- type AllowedEvents = TransactionControllerStateChangeEvent;
54
+ type AllowedEvents = SignatureStateChange | TransactionControllerStateChangeEvent;
54
55
  /**
55
56
  * The messenger of the {@link ShieldController}.
56
57
  */
@@ -74,6 +75,13 @@ export declare class ShieldController extends BaseController<typeof controllerNa
74
75
  * @returns The coverage result.
75
76
  */
76
77
  checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult>;
78
+ /**
79
+ * Checks the coverage of a signature request.
80
+ *
81
+ * @param signatureRequest - The signature request to check coverage for.
82
+ * @returns The coverage result.
83
+ */
84
+ checkSignatureCoverage(signatureRequest: SignatureRequest): Promise<CoverageResult>;
77
85
  }
78
86
  export {};
79
87
  //# sourceMappingURL=ShieldController.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ShieldController.d.cts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,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;;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,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"}
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,EAGL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,uCAAuC;AACxC,OAAO,EAEL,KAAK,qCAAqC,EAC1C,KAAK,eAAe,EACrB,yCAAyC;AAE1C,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAI7D,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,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,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;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;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;CAC/B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAiBa,OAAO,EAAE,uBAAuB;IA2B5C,KAAK;IAcL,IAAI;IA0FJ;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAgBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CAsG3B"}
@@ -1,6 +1,7 @@
1
1
  import { BaseController } from "@metamask/base-controller";
2
2
  import type { ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
- import type { TransactionControllerStateChangeEvent, TransactionMeta } from "@metamask/transaction-controller";
3
+ import { type SignatureRequest, type SignatureStateChange } from "@metamask/signature-controller";
4
+ import { type TransactionControllerStateChangeEvent, type TransactionMeta } from "@metamask/transaction-controller";
4
5
  import { controllerName } from "./constants.mjs";
5
6
  import type { CoverageResult, ShieldBackend } from "./types.mjs";
6
7
  export type CoverageResultRecordEntry = {
@@ -50,7 +51,7 @@ type AllowedActions = never;
50
51
  /**
51
52
  * The external events available to the ShieldController.
52
53
  */
53
- type AllowedEvents = TransactionControllerStateChangeEvent;
54
+ type AllowedEvents = SignatureStateChange | TransactionControllerStateChangeEvent;
54
55
  /**
55
56
  * The messenger of the {@link ShieldController}.
56
57
  */
@@ -74,6 +75,13 @@ export declare class ShieldController extends BaseController<typeof controllerNa
74
75
  * @returns The coverage result.
75
76
  */
76
77
  checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult>;
78
+ /**
79
+ * Checks the coverage of a signature request.
80
+ *
81
+ * @param signatureRequest - The signature request to check coverage for.
82
+ * @returns The coverage result.
83
+ */
84
+ checkSignatureCoverage(signatureRequest: SignatureRequest): Promise<CoverageResult>;
77
85
  }
78
86
  export {};
79
87
  //# sourceMappingURL=ShieldController.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ShieldController.d.mts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,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;;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,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"}
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,EAGL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,uCAAuC;AACxC,OAAO,EAEL,KAAK,qCAAqC,EAC1C,KAAK,eAAe,EACrB,yCAAyC;AAE1C,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAI7D,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,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,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;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;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;CAC/B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAiBa,OAAO,EAAE,uBAAuB;IA2B5C,KAAK;IAcL,IAAI;IA0FJ;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAgBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CAsG3B"}
@@ -9,8 +9,10 @@ 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_transactionControllerStateChangeHandler, _ShieldController_handleTransactionControllerStateChange, _ShieldController_fetchCoverageResult, _ShieldController_addCoverageResult;
12
+ var _ShieldController_instances, _ShieldController_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction, _ShieldController_getLatestCoverageId;
13
13
  import { BaseController } from "@metamask/base-controller";
14
+ import { SignatureRequestStatus, SignatureRequestType } from "@metamask/signature-controller";
15
+ import { TransactionStatus } from "@metamask/transaction-controller";
14
16
  import { controllerName } from "./constants.mjs";
15
17
  import { projectLogger, createModuleLogger } from "./logger.mjs";
16
18
  const log = createModuleLogger(projectLogger, 'ShieldController');
@@ -31,12 +33,16 @@ export function getDefaultShieldControllerState() {
31
33
  */
32
34
  const metadata = {
33
35
  coverageResults: {
36
+ includeInStateLogs: true,
34
37
  persist: true,
35
38
  anonymous: false,
39
+ usedInUi: true,
36
40
  },
37
41
  orderedTransactionHistory: {
42
+ includeInStateLogs: true,
38
43
  persist: true,
39
44
  anonymous: false,
45
+ usedInUi: false,
40
46
  },
41
47
  };
42
48
  export class ShieldController extends BaseController {
@@ -56,16 +62,20 @@ export class ShieldController extends BaseController {
56
62
  _ShieldController_coverageHistoryLimit.set(this, void 0);
57
63
  _ShieldController_transactionHistoryLimit.set(this, void 0);
58
64
  _ShieldController_transactionControllerStateChangeHandler.set(this, void 0);
65
+ _ShieldController_signatureControllerStateChangeHandler.set(this, void 0);
59
66
  __classPrivateFieldSet(this, _ShieldController_backend, backend, "f");
60
67
  __classPrivateFieldSet(this, _ShieldController_coverageHistoryLimit, coverageHistoryLimit, "f");
61
68
  __classPrivateFieldSet(this, _ShieldController_transactionHistoryLimit, transactionHistoryLimit, "f");
62
69
  __classPrivateFieldSet(this, _ShieldController_transactionControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleTransactionControllerStateChange).bind(this), "f");
70
+ __classPrivateFieldSet(this, _ShieldController_signatureControllerStateChangeHandler, __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_handleSignatureControllerStateChange).bind(this), "f");
63
71
  }
64
72
  start() {
65
73
  this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"), (state) => state.transactions);
74
+ this.messagingSystem.subscribe('SignatureController:stateChange', __classPrivateFieldGet(this, _ShieldController_signatureControllerStateChangeHandler, "f"), (state) => state.signatureRequests);
66
75
  }
67
76
  stop() {
68
77
  this.messagingSystem.unsubscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _ShieldController_transactionControllerStateChangeHandler, "f"));
78
+ this.messagingSystem.unsubscribe('SignatureController:stateChange', __classPrivateFieldGet(this, _ShieldController_signatureControllerStateChangeHandler, "f"));
69
79
  }
70
80
  /**
71
81
  * Checks the coverage of a transaction.
@@ -75,15 +85,52 @@ export class ShieldController extends BaseController {
75
85
  */
76
86
  async checkCoverage(txMeta) {
77
87
  // Check coverage
78
- const coverageResult = await __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_fetchCoverageResult).call(this, txMeta);
88
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage(txMeta);
79
89
  // Publish coverage result
80
90
  this.messagingSystem.publish(`${controllerName}:coverageResultReceived`, coverageResult);
81
91
  // Update state
82
92
  __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_addCoverageResult).call(this, txMeta.id, coverageResult);
83
93
  return coverageResult;
84
94
  }
95
+ /**
96
+ * Checks the coverage of a signature request.
97
+ *
98
+ * @param signatureRequest - The signature request to check coverage for.
99
+ * @returns The coverage result.
100
+ */
101
+ async checkSignatureCoverage(signatureRequest) {
102
+ // Check coverage
103
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldController_backend, "f").checkSignatureCoverage(signatureRequest);
104
+ // Publish coverage result
105
+ this.messagingSystem.publish(`${controllerName}:coverageResultReceived`, coverageResult);
106
+ // Update state
107
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_addCoverageResult).call(this, signatureRequest.id, coverageResult);
108
+ return coverageResult;
109
+ }
85
110
  }
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) {
111
+ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimit = new WeakMap(), _ShieldController_transactionHistoryLimit = new WeakMap(), _ShieldController_transactionControllerStateChangeHandler = new WeakMap(), _ShieldController_signatureControllerStateChangeHandler = new WeakMap(), _ShieldController_instances = new WeakSet(), _ShieldController_handleSignatureControllerStateChange = function _ShieldController_handleSignatureControllerStateChange(signatureRequests, previousSignatureRequests) {
112
+ const signatureRequestsArray = Object.values(signatureRequests);
113
+ const previousSignatureRequestsArray = Object.values(previousSignatureRequests ?? {});
114
+ const previousSignatureRequestsById = new Map(previousSignatureRequestsArray.map((request) => [request.id, request]));
115
+ for (const signatureRequest of signatureRequestsArray) {
116
+ const previousSignatureRequest = previousSignatureRequestsById.get(signatureRequest.id);
117
+ // Check coverage if the signature request is new and has type
118
+ // `personal_sign`.
119
+ if (!previousSignatureRequest &&
120
+ signatureRequest.type === SignatureRequestType.PersonalSign) {
121
+ this.checkSignatureCoverage(signatureRequest).catch(
122
+ // istanbul ignore next
123
+ (error) => log('Error checking coverage:', error));
124
+ }
125
+ // Log signature once the signature request has been fulfilled.
126
+ if (signatureRequest.status === SignatureRequestStatus.Signed &&
127
+ signatureRequest.status !== previousSignatureRequest?.status) {
128
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_logSignature).call(this, signatureRequest).catch(
129
+ // istanbul ignore next
130
+ (error) => log('Error logging signature:', error));
131
+ }
132
+ }
133
+ }, _ShieldController_handleTransactionControllerStateChange = function _ShieldController_handleTransactionControllerStateChange(transactions, previousTransactions) {
87
134
  const previousTransactionsById = new Map(previousTransactions?.map((tx) => [tx.id, tx]) ?? []);
88
135
  for (const transaction of transactions) {
89
136
  const previousTransaction = previousTransactionsById.get(transaction.id);
@@ -97,9 +144,14 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
97
144
  // istanbul ignore next
98
145
  (error) => log('Error checking coverage:', error));
99
146
  }
147
+ // Log transaction once it has been submitted.
148
+ if (transaction.status === TransactionStatus.submitted &&
149
+ transaction.status !== previousTransaction?.status) {
150
+ __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_logTransaction).call(this, transaction).catch(
151
+ // istanbul ignore next
152
+ (error) => log('Error logging transaction:', error));
153
+ }
100
154
  }
101
- }, _ShieldController_fetchCoverageResult = async function _ShieldController_fetchCoverageResult(txMeta) {
102
- return __classPrivateFieldGet(this, _ShieldController_backend, "f").checkCoverage(txMeta);
103
155
  }, _ShieldController_addCoverageResult = function _ShieldController_addCoverageResult(txId, coverageResult) {
104
156
  this.update((draft) => {
105
157
  // Fetch coverage result entry.
@@ -135,5 +187,41 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
135
187
  orderedTransactionHistory.unshift(txId);
136
188
  }
137
189
  });
190
+ }, _ShieldController_logSignature = async function _ShieldController_logSignature(signatureRequest) {
191
+ const coverageId = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getLatestCoverageId).call(this, signatureRequest.id);
192
+ if (!coverageId) {
193
+ throw new Error('Coverage ID not found');
194
+ }
195
+ const sig = signatureRequest.rawSig;
196
+ if (!sig) {
197
+ throw new Error('Signature not found');
198
+ }
199
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logSignature({
200
+ coverageId,
201
+ signature: sig,
202
+ // Status is 'shown' because the coverageId can only be retrieved after
203
+ // the result is in the state. If the result is in the state, we assume
204
+ // that it has been shown.
205
+ status: 'shown',
206
+ });
207
+ }, _ShieldController_logTransaction = async function _ShieldController_logTransaction(txMeta) {
208
+ const coverageId = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_getLatestCoverageId).call(this, txMeta.id);
209
+ if (!coverageId) {
210
+ throw new Error('Coverage ID not found');
211
+ }
212
+ const txHash = txMeta.hash;
213
+ if (!txHash) {
214
+ throw new Error('Transaction hash not found');
215
+ }
216
+ await __classPrivateFieldGet(this, _ShieldController_backend, "f").logTransaction({
217
+ coverageId,
218
+ transactionHash: txHash,
219
+ // Status is 'shown' because the coverageId can only be retrieved after
220
+ // the result is in the state. If the result is in the state, we assume
221
+ // that it has been shown.
222
+ status: 'shown',
223
+ });
224
+ }, _ShieldController_getLatestCoverageId = function _ShieldController_getLatestCoverageId(itemId) {
225
+ return this.state.coverageResults[itemId]?.results[0]?.coverageId;
138
226
  };
139
227
  //# sourceMappingURL=ShieldController.mjs.map
@@ -1 +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 /**\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 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"]}
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 {\n SignatureRequestStatus,\n SignatureRequestType,\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';\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 /**\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 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 =\n | SignatureStateChange\n | 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 includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n anonymous: 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\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 readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | 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 this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n }\n\n start() {\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messagingSystem.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messagingSystem.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 and has type\n // `personal_sign`.\n if (\n !previousSignatureRequest &&\n signatureRequest.type === SignatureRequestType.PersonalSign\n ) {\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 // 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 // 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 coverageResult = await this.#backend.checkCoverage(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 /**\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 coverageResult =\n await this.#backend.checkSignatureCoverage(signatureRequest);\n\n // Publish coverage result\n this.messagingSystem.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 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 coverageId = this.#getLatestCoverageId(signatureRequest.id);\n if (!coverageId) {\n throw new Error('Coverage ID not found');\n }\n\n const sig = signatureRequest.rawSig;\n if (!sig) {\n throw new Error('Signature not found');\n }\n\n await this.#backend.logSignature({\n coverageId,\n signature: sig,\n // Status is 'shown' because the coverageId can only be retrieved after\n // the result is in the state. If the result is in the state, we assume\n // that it has been shown.\n status: 'shown',\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n if (!coverageId) {\n throw new Error('Coverage ID not found');\n }\n\n const txHash = txMeta.hash;\n if (!txHash) {\n throw new Error('Transaction hash not found');\n }\n await this.#backend.logTransaction({\n coverageId,\n transactionHash: txHash,\n // Status is 'shown' because the coverageId can only be retrieved after\n // the result is in the state. If the result is in the state, we assume\n // that it has been shown.\n status: 'shown',\n });\n }\n\n #getLatestCoverageId(itemId: string) {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
package/dist/backend.cjs CHANGED
@@ -12,45 +12,80 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  };
13
13
  var _ShieldRemoteBackend_instances, _ShieldRemoteBackend_getAccessToken, _ShieldRemoteBackend_getCoverageResultTimeout, _ShieldRemoteBackend_getCoverageResultPollInterval, _ShieldRemoteBackend_baseUrl, _ShieldRemoteBackend_fetch, _ShieldRemoteBackend_initCoverageCheck, _ShieldRemoteBackend_getCoverageResult, _ShieldRemoteBackend_createHeaders;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.ShieldRemoteBackend = exports.BASE_URL = void 0;
16
- exports.BASE_URL = 'https://rule-engine.metamask.io';
15
+ exports.ShieldRemoteBackend = void 0;
17
16
  class ShieldRemoteBackend {
18
17
  constructor({ getAccessToken, getCoverageResultTimeout = 5000, // milliseconds
19
18
  getCoverageResultPollInterval = 1000, // milliseconds
20
- baseUrl = exports.BASE_URL, fetch: fetchFn, }) {
19
+ baseUrl, fetch: fetchFn, }) {
21
20
  _ShieldRemoteBackend_instances.add(this);
22
21
  _ShieldRemoteBackend_getAccessToken.set(this, void 0);
23
22
  _ShieldRemoteBackend_getCoverageResultTimeout.set(this, void 0);
24
23
  _ShieldRemoteBackend_getCoverageResultPollInterval.set(this, void 0);
25
24
  _ShieldRemoteBackend_baseUrl.set(this, void 0);
26
25
  _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
26
  __classPrivateFieldSet(this, _ShieldRemoteBackend_getAccessToken, getAccessToken, "f");
45
27
  __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultTimeout, getCoverageResultTimeout, "f");
46
28
  __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, getCoverageResultPollInterval, "f");
47
29
  __classPrivateFieldSet(this, _ShieldRemoteBackend_baseUrl, baseUrl, "f");
48
30
  __classPrivateFieldSet(this, _ShieldRemoteBackend_fetch, fetchFn, "f");
49
31
  }
32
+ async checkCoverage(txMeta) {
33
+ const reqBody = {
34
+ txParams: [
35
+ {
36
+ from: txMeta.txParams.from,
37
+ to: txMeta.txParams.to,
38
+ value: txMeta.txParams.value,
39
+ data: txMeta.txParams.data,
40
+ nonce: txMeta.txParams.nonce,
41
+ },
42
+ ],
43
+ chainId: txMeta.chainId,
44
+ origin: txMeta.origin,
45
+ };
46
+ const { coverageId } = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_initCoverageCheck).call(this, 'v1/transaction/coverage/init', reqBody);
47
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_getCoverageResult).call(this, coverageId);
48
+ return { coverageId, status: coverageResult.status };
49
+ }
50
+ async checkSignatureCoverage(signatureRequest) {
51
+ if (typeof signatureRequest.messageParams.data !== 'string') {
52
+ throw new Error('Signature data must be a string');
53
+ }
54
+ const reqBody = {
55
+ chainId: signatureRequest.chainId,
56
+ data: signatureRequest.messageParams.data,
57
+ from: signatureRequest.messageParams.from,
58
+ method: signatureRequest.type,
59
+ origin: signatureRequest.messageParams.origin,
60
+ };
61
+ const { coverageId } = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_initCoverageCheck).call(this, 'v1/signature/coverage/init', reqBody);
62
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_getCoverageResult).call(this, coverageId);
63
+ return { coverageId, status: coverageResult.status };
64
+ }
65
+ async logSignature(req) {
66
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/signature/coverage/log`, {
67
+ method: 'POST',
68
+ headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
69
+ body: JSON.stringify(req),
70
+ });
71
+ if (res.status !== 200) {
72
+ throw new Error(`Failed to log signature: ${res.status}`);
73
+ }
74
+ }
75
+ async logTransaction(req) {
76
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/transaction/coverage/log`, {
77
+ method: 'POST',
78
+ headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
79
+ body: JSON.stringify(req),
80
+ });
81
+ if (res.status !== 200) {
82
+ throw new Error(`Failed to log transaction: ${res.status}`);
83
+ }
84
+ }
50
85
  }
51
86
  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`, {
87
+ _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(path, reqBody) {
88
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/${path}`, {
54
89
  method: 'POST',
55
90
  headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
56
91
  body: JSON.stringify(reqBody),
@@ -75,7 +110,7 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
75
110
  // eslint-disable-next-line no-unmodified-loop-condition
76
111
  while (!timeoutReached) {
77
112
  const startTime = Date.now();
78
- const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/api/v1/coverage/result`, {
113
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/transaction/coverage/result`, {
79
114
  method: 'POST',
80
115
  headers,
81
116
  body: JSON.stringify(reqBody),
@@ -1 +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"]}
1
+ {"version":3,"file":"backend.cjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\nimport type {\n CoverageResult,\n CoverageStatus,\n LogSignatureRequest,\n LogTransactionRequest,\n ShieldBackend,\n} from './types';\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 InitSignatureCoverageCheckRequest = {\n chainId: string;\n data: string;\n from: string;\n method: 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,\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 async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\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(\n 'v1/transaction/coverage/init',\n reqBody,\n );\n\n const coverageResult = await this.#getCoverageResult(coverageId);\n return { coverageId, status: coverageResult.status };\n }\n\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n if (typeof signatureRequest.messageParams.data !== 'string') {\n throw new Error('Signature data must be a string');\n }\n\n const reqBody: InitSignatureCoverageCheckRequest = {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data,\n from: signatureRequest.messageParams.from,\n method: signatureRequest.type,\n origin: signatureRequest.messageParams.origin,\n };\n\n const { coverageId } = await this.#initCoverageCheck(\n 'v1/signature/coverage/init',\n reqBody,\n );\n\n const coverageResult = await this.#getCoverageResult(coverageId);\n return { coverageId, status: coverageResult.status };\n }\n\n async logSignature(req: LogSignatureRequest): Promise<void> {\n const res = await this.#fetch(\n `${this.#baseUrl}/v1/signature/coverage/log`,\n {\n method: 'POST',\n headers: await this.#createHeaders(),\n body: JSON.stringify(req),\n },\n );\n if (res.status !== 200) {\n throw new Error(`Failed to log signature: ${res.status}`);\n }\n }\n\n async logTransaction(req: LogTransactionRequest): Promise<void> {\n const res = await this.#fetch(\n `${this.#baseUrl}/v1/transaction/coverage/log`,\n {\n method: 'POST',\n headers: await this.#createHeaders(),\n body: JSON.stringify(req),\n },\n );\n if (res.status !== 200) {\n throw new Error(`Failed to log transaction: ${res.status}`);\n }\n }\n\n async #initCoverageCheck(\n path: string,\n reqBody: unknown,\n ): Promise<InitCoverageCheckResponse> {\n const res = await this.#fetch(`${this.#baseUrl}/${path}`, {\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}/v1/transaction/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"]}
@@ -1,6 +1,6 @@
1
+ import type { SignatureRequest } from "@metamask/signature-controller";
1
2
  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";
3
+ import type { CoverageResult, CoverageStatus, LogSignatureRequest, LogTransactionRequest, ShieldBackend } from "./types.cjs";
4
4
  export type InitCoverageCheckRequest = {
5
5
  txParams: [
6
6
  {
@@ -14,6 +14,13 @@ export type InitCoverageCheckRequest = {
14
14
  chainId: string;
15
15
  origin?: string;
16
16
  };
17
+ export type InitSignatureCoverageCheckRequest = {
18
+ chainId: string;
19
+ data: string;
20
+ from: string;
21
+ method: string;
22
+ origin?: string;
23
+ };
17
24
  export type InitCoverageCheckResponse = {
18
25
  coverageId: string;
19
26
  };
@@ -31,9 +38,12 @@ export declare class ShieldRemoteBackend implements ShieldBackend {
31
38
  getAccessToken: () => Promise<string>;
32
39
  getCoverageResultTimeout?: number;
33
40
  getCoverageResultPollInterval?: number;
34
- baseUrl?: string;
41
+ baseUrl: string;
35
42
  fetch: typeof globalThis.fetch;
36
43
  });
37
- checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
44
+ checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult>;
45
+ checkSignatureCoverage(signatureRequest: SignatureRequest): Promise<CoverageResult>;
46
+ logSignature(req: LogSignatureRequest): Promise<void>;
47
+ logTransaction(req: LogTransactionRequest): Promise<void>;
38
48
  }
39
49
  //# sourceMappingURL=backend.d.cts.map
@@ -1 +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"}
1
+ {"version":3,"file":"backend.d.cts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uCAAuC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACd,oBAAgB;AAEjB,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,iCAAiC,GAAG;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,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,OAAO,EACP,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,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQK,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAwB/D,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;IAsBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrD,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAgFhE"}
@@ -1,6 +1,6 @@
1
+ import type { SignatureRequest } from "@metamask/signature-controller";
1
2
  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";
3
+ import type { CoverageResult, CoverageStatus, LogSignatureRequest, LogTransactionRequest, ShieldBackend } from "./types.mjs";
4
4
  export type InitCoverageCheckRequest = {
5
5
  txParams: [
6
6
  {
@@ -14,6 +14,13 @@ export type InitCoverageCheckRequest = {
14
14
  chainId: string;
15
15
  origin?: string;
16
16
  };
17
+ export type InitSignatureCoverageCheckRequest = {
18
+ chainId: string;
19
+ data: string;
20
+ from: string;
21
+ method: string;
22
+ origin?: string;
23
+ };
17
24
  export type InitCoverageCheckResponse = {
18
25
  coverageId: string;
19
26
  };
@@ -31,9 +38,12 @@ export declare class ShieldRemoteBackend implements ShieldBackend {
31
38
  getAccessToken: () => Promise<string>;
32
39
  getCoverageResultTimeout?: number;
33
40
  getCoverageResultPollInterval?: number;
34
- baseUrl?: string;
41
+ baseUrl: string;
35
42
  fetch: typeof globalThis.fetch;
36
43
  });
37
- checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
44
+ checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult>;
45
+ checkSignatureCoverage(signatureRequest: SignatureRequest): Promise<CoverageResult>;
46
+ logSignature(req: LogSignatureRequest): Promise<void>;
47
+ logTransaction(req: LogTransactionRequest): Promise<void>;
38
48
  }
39
49
  //# sourceMappingURL=backend.d.mts.map
@@ -1 +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"}
1
+ {"version":3,"file":"backend.d.mts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uCAAuC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACd,oBAAgB;AAEjB,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,iCAAiC,GAAG;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,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,OAAO,EACP,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,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQK,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAwB/D,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;IAsBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrD,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAgFhE"}
package/dist/backend.mjs CHANGED
@@ -10,43 +10,78 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
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
13
  export class ShieldRemoteBackend {
15
14
  constructor({ getAccessToken, getCoverageResultTimeout = 5000, // milliseconds
16
15
  getCoverageResultPollInterval = 1000, // milliseconds
17
- baseUrl = BASE_URL, fetch: fetchFn, }) {
16
+ baseUrl, fetch: fetchFn, }) {
18
17
  _ShieldRemoteBackend_instances.add(this);
19
18
  _ShieldRemoteBackend_getAccessToken.set(this, void 0);
20
19
  _ShieldRemoteBackend_getCoverageResultTimeout.set(this, void 0);
21
20
  _ShieldRemoteBackend_getCoverageResultPollInterval.set(this, void 0);
22
21
  _ShieldRemoteBackend_baseUrl.set(this, void 0);
23
22
  _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
23
  __classPrivateFieldSet(this, _ShieldRemoteBackend_getAccessToken, getAccessToken, "f");
42
24
  __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultTimeout, getCoverageResultTimeout, "f");
43
25
  __classPrivateFieldSet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, getCoverageResultPollInterval, "f");
44
26
  __classPrivateFieldSet(this, _ShieldRemoteBackend_baseUrl, baseUrl, "f");
45
27
  __classPrivateFieldSet(this, _ShieldRemoteBackend_fetch, fetchFn, "f");
46
28
  }
29
+ async checkCoverage(txMeta) {
30
+ const reqBody = {
31
+ txParams: [
32
+ {
33
+ from: txMeta.txParams.from,
34
+ to: txMeta.txParams.to,
35
+ value: txMeta.txParams.value,
36
+ data: txMeta.txParams.data,
37
+ nonce: txMeta.txParams.nonce,
38
+ },
39
+ ],
40
+ chainId: txMeta.chainId,
41
+ origin: txMeta.origin,
42
+ };
43
+ const { coverageId } = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_initCoverageCheck).call(this, 'v1/transaction/coverage/init', reqBody);
44
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_getCoverageResult).call(this, coverageId);
45
+ return { coverageId, status: coverageResult.status };
46
+ }
47
+ async checkSignatureCoverage(signatureRequest) {
48
+ if (typeof signatureRequest.messageParams.data !== 'string') {
49
+ throw new Error('Signature data must be a string');
50
+ }
51
+ const reqBody = {
52
+ chainId: signatureRequest.chainId,
53
+ data: signatureRequest.messageParams.data,
54
+ from: signatureRequest.messageParams.from,
55
+ method: signatureRequest.type,
56
+ origin: signatureRequest.messageParams.origin,
57
+ };
58
+ const { coverageId } = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_initCoverageCheck).call(this, 'v1/signature/coverage/init', reqBody);
59
+ const coverageResult = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_getCoverageResult).call(this, coverageId);
60
+ return { coverageId, status: coverageResult.status };
61
+ }
62
+ async logSignature(req) {
63
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/signature/coverage/log`, {
64
+ method: 'POST',
65
+ headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
66
+ body: JSON.stringify(req),
67
+ });
68
+ if (res.status !== 200) {
69
+ throw new Error(`Failed to log signature: ${res.status}`);
70
+ }
71
+ }
72
+ async logTransaction(req) {
73
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/transaction/coverage/log`, {
74
+ method: 'POST',
75
+ headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
76
+ body: JSON.stringify(req),
77
+ });
78
+ if (res.status !== 200) {
79
+ throw new Error(`Failed to log transaction: ${res.status}`);
80
+ }
81
+ }
47
82
  }
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`, {
83
+ _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(path, reqBody) {
84
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/${path}`, {
50
85
  method: 'POST',
51
86
  headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
52
87
  body: JSON.stringify(reqBody),
@@ -71,7 +106,7 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
71
106
  // eslint-disable-next-line no-unmodified-loop-condition
72
107
  while (!timeoutReached) {
73
108
  const startTime = Date.now();
74
- const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/api/v1/coverage/result`, {
109
+ const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/transaction/coverage/result`, {
75
110
  method: 'POST',
76
111
  headers,
77
112
  body: JSON.stringify(reqBody),
@@ -1 +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"]}
1
+ {"version":3,"file":"backend.mjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\nimport type {\n CoverageResult,\n CoverageStatus,\n LogSignatureRequest,\n LogTransactionRequest,\n ShieldBackend,\n} from './types';\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 InitSignatureCoverageCheckRequest = {\n chainId: string;\n data: string;\n from: string;\n method: 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,\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 async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\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(\n 'v1/transaction/coverage/init',\n reqBody,\n );\n\n const coverageResult = await this.#getCoverageResult(coverageId);\n return { coverageId, status: coverageResult.status };\n }\n\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n if (typeof signatureRequest.messageParams.data !== 'string') {\n throw new Error('Signature data must be a string');\n }\n\n const reqBody: InitSignatureCoverageCheckRequest = {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data,\n from: signatureRequest.messageParams.from,\n method: signatureRequest.type,\n origin: signatureRequest.messageParams.origin,\n };\n\n const { coverageId } = await this.#initCoverageCheck(\n 'v1/signature/coverage/init',\n reqBody,\n );\n\n const coverageResult = await this.#getCoverageResult(coverageId);\n return { coverageId, status: coverageResult.status };\n }\n\n async logSignature(req: LogSignatureRequest): Promise<void> {\n const res = await this.#fetch(\n `${this.#baseUrl}/v1/signature/coverage/log`,\n {\n method: 'POST',\n headers: await this.#createHeaders(),\n body: JSON.stringify(req),\n },\n );\n if (res.status !== 200) {\n throw new Error(`Failed to log signature: ${res.status}`);\n }\n }\n\n async logTransaction(req: LogTransactionRequest): Promise<void> {\n const res = await this.#fetch(\n `${this.#baseUrl}/v1/transaction/coverage/log`,\n {\n method: 'POST',\n headers: await this.#createHeaders(),\n body: JSON.stringify(req),\n },\n );\n if (res.status !== 200) {\n throw new Error(`Failed to log transaction: ${res.status}`);\n }\n }\n\n async #initCoverageCheck(\n path: string,\n reqBody: unknown,\n ): Promise<InitCoverageCheckResponse> {\n const res = await this.#fetch(`${this.#baseUrl}/${path}`, {\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}/v1/transaction/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"]}
@@ -1 +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;AAEjC,yCAAgD;AAAvC,8GAAA,mBAAmB,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';\nexport { ShieldRemoteBackend } from './backend';\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAcA,2DAG4B;AAF1B,oHAAA,gBAAgB,OAAA;AAChB,mIAAA,+BAA+B,OAAA;AAEjC,yCAAgD;AAAvC,8GAAA,mBAAmB,OAAA","sourcesContent":["export type {\n CoverageStatus,\n LogSignatureRequest,\n LogTransactionRequest,\n} 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';\nexport { ShieldRemoteBackend } from './backend';\n"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export type { CoverageStatus } from "./types.cjs";
1
+ export type { CoverageStatus, LogSignatureRequest, LogTransactionRequest, } from "./types.cjs";
2
2
  export type { ShieldControllerActions, ShieldControllerEvents, ShieldControllerMessenger, ShieldControllerState, ShieldControllerCheckCoverageAction, ShieldControllerCoverageResultReceivedEvent, ShieldControllerStateChangeEvent, } from "./ShieldController.cjs";
3
3
  export { ShieldController, getDefaultShieldControllerState, } from "./ShieldController.cjs";
4
4
  export { ShieldRemoteBackend } from "./backend.cjs";
@@ -1 +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;AAC5B,OAAO,EAAE,mBAAmB,EAAE,sBAAkB"}
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,qBAAqB,GACtB,oBAAgB;AACjB,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;AAC5B,OAAO,EAAE,mBAAmB,EAAE,sBAAkB"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export type { CoverageStatus } from "./types.mjs";
1
+ export type { CoverageStatus, LogSignatureRequest, LogTransactionRequest, } from "./types.mjs";
2
2
  export type { ShieldControllerActions, ShieldControllerEvents, ShieldControllerMessenger, ShieldControllerState, ShieldControllerCheckCoverageAction, ShieldControllerCoverageResultReceivedEvent, ShieldControllerStateChangeEvent, } from "./ShieldController.mjs";
3
3
  export { ShieldController, getDefaultShieldControllerState, } from "./ShieldController.mjs";
4
4
  export { ShieldRemoteBackend } from "./backend.mjs";
@@ -1 +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;AAC5B,OAAO,EAAE,mBAAmB,EAAE,sBAAkB"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,qBAAqB,GACtB,oBAAgB;AACjB,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;AAC5B,OAAO,EAAE,mBAAmB,EAAE,sBAAkB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,EAChC,+BAA2B;AAC5B,OAAO,EAAE,mBAAmB,EAAE,sBAAkB","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';\nexport { ShieldRemoteBackend } from './backend';\n"]}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,EAChC,+BAA2B;AAC5B,OAAO,EAAE,mBAAmB,EAAE,sBAAkB","sourcesContent":["export type {\n CoverageStatus,\n LogSignatureRequest,\n LogTransactionRequest,\n} 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';\nexport { ShieldRemoteBackend } from './backend';\n"]}
@@ -1 +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"]}
1
+ {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAQa,QAAA,gBAAgB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,CAAU,CAAC","sourcesContent":["import type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\nexport type CoverageResult = {\n coverageId: string;\n status: CoverageStatus;\n};\n\nexport const coverageStatuses = ['covered', 'malicious', 'unknown'] as const;\nexport type CoverageStatus = (typeof coverageStatuses)[number];\n\nexport type LogSignatureRequest = {\n coverageId: string;\n signature: string;\n status: string;\n};\n\nexport type LogTransactionRequest = {\n coverageId: string;\n transactionHash: string;\n status: string;\n};\n\nexport type ShieldBackend = {\n logSignature: (req: LogSignatureRequest) => Promise<void>;\n logTransaction: (req: LogTransactionRequest) => Promise<void>;\n checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;\n checkSignatureCoverage: (\n signatureRequest: SignatureRequest,\n ) => Promise<CoverageResult>;\n};\n"]}
package/dist/types.d.cts CHANGED
@@ -1,10 +1,25 @@
1
+ import type { SignatureRequest } from "@metamask/signature-controller";
1
2
  import type { TransactionMeta } from "@metamask/transaction-controller";
2
3
  export type CoverageResult = {
4
+ coverageId: string;
3
5
  status: CoverageStatus;
4
6
  };
5
7
  export declare const coverageStatuses: readonly ["covered", "malicious", "unknown"];
6
8
  export type CoverageStatus = (typeof coverageStatuses)[number];
9
+ export type LogSignatureRequest = {
10
+ coverageId: string;
11
+ signature: string;
12
+ status: string;
13
+ };
14
+ export type LogTransactionRequest = {
15
+ coverageId: string;
16
+ transactionHash: string;
17
+ status: string;
18
+ };
7
19
  export type ShieldBackend = {
20
+ logSignature: (req: LogSignatureRequest) => Promise<void>;
21
+ logTransaction: (req: LogTransactionRequest) => Promise<void>;
8
22
  checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
23
+ checkSignatureCoverage: (signatureRequest: SignatureRequest) => Promise<CoverageResult>;
9
24
  };
10
25
  //# sourceMappingURL=types.d.cts.map
@@ -1 +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"}
1
+ {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uCAAuC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,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,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,aAAa,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACpE,sBAAsB,EAAE,CACtB,gBAAgB,EAAE,gBAAgB,KAC/B,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9B,CAAC"}
package/dist/types.d.mts CHANGED
@@ -1,10 +1,25 @@
1
+ import type { SignatureRequest } from "@metamask/signature-controller";
1
2
  import type { TransactionMeta } from "@metamask/transaction-controller";
2
3
  export type CoverageResult = {
4
+ coverageId: string;
3
5
  status: CoverageStatus;
4
6
  };
5
7
  export declare const coverageStatuses: readonly ["covered", "malicious", "unknown"];
6
8
  export type CoverageStatus = (typeof coverageStatuses)[number];
9
+ export type LogSignatureRequest = {
10
+ coverageId: string;
11
+ signature: string;
12
+ status: string;
13
+ };
14
+ export type LogTransactionRequest = {
15
+ coverageId: string;
16
+ transactionHash: string;
17
+ status: string;
18
+ };
7
19
  export type ShieldBackend = {
20
+ logSignature: (req: LogSignatureRequest) => Promise<void>;
21
+ logTransaction: (req: LogTransactionRequest) => Promise<void>;
8
22
  checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;
23
+ checkSignatureCoverage: (signatureRequest: SignatureRequest) => Promise<CoverageResult>;
9
24
  };
10
25
  //# sourceMappingURL=types.d.mts.map
@@ -1 +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"}
1
+ {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uCAAuC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,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,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,aAAa,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACpE,sBAAsB,EAAE,CACtB,gBAAgB,EAAE,gBAAgB,KAC/B,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9B,CAAC"}
@@ -1 +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"]}
1
+ {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,CAAU,CAAC","sourcesContent":["import type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\nexport type CoverageResult = {\n coverageId: string;\n status: CoverageStatus;\n};\n\nexport const coverageStatuses = ['covered', 'malicious', 'unknown'] as const;\nexport type CoverageStatus = (typeof coverageStatuses)[number];\n\nexport type LogSignatureRequest = {\n coverageId: string;\n signature: string;\n status: string;\n};\n\nexport type LogTransactionRequest = {\n coverageId: string;\n transactionHash: string;\n status: string;\n};\n\nexport type ShieldBackend = {\n logSignature: (req: LogSignatureRequest) => Promise<void>;\n logTransaction: (req: LogTransactionRequest) => Promise<void>;\n checkCoverage: (txMeta: TransactionMeta) => Promise<CoverageResult>;\n checkSignatureCoverage: (\n signatureRequest: SignatureRequest,\n ) => Promise<CoverageResult>;\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/shield-controller",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Controller handling shield transaction coverage logic",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -47,15 +47,16 @@
47
47
  "since-latest-release": "../../scripts/since-latest-release.sh"
48
48
  },
49
49
  "dependencies": {
50
- "@metamask/base-controller": "^8.2.0",
51
- "@metamask/utils": "^11.4.2"
50
+ "@metamask/base-controller": "^8.4.0",
51
+ "@metamask/utils": "^11.8.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@babel/runtime": "^7.23.9",
55
55
  "@lavamoat/allow-scripts": "^3.0.4",
56
56
  "@lavamoat/preinstall-always-fail": "^2.1.0",
57
57
  "@metamask/auto-changelog": "^3.4.4",
58
- "@metamask/transaction-controller": "^60.1.0",
58
+ "@metamask/signature-controller": "^34.0.0",
59
+ "@metamask/transaction-controller": "^60.4.0",
59
60
  "@ts-bridge/cli": "^0.6.1",
60
61
  "@types/jest": "^27.4.1",
61
62
  "deepmerge": "^4.2.2",
@@ -67,6 +68,7 @@
67
68
  "uuid": "^8.3.2"
68
69
  },
69
70
  "peerDependencies": {
71
+ "@metamask/signature-controller": "^34.0.0",
70
72
  "@metamask/transaction-controller": "^60.0.0"
71
73
  },
72
74
  "engines": {