@metamask/shield-controller 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/dist/ShieldController.cjs.map +1 -1
- package/dist/ShieldController.mjs.map +1 -1
- package/dist/backend.cjs +13 -1
- package/dist/backend.cjs.map +1 -1
- package/dist/backend.d.cts +3 -0
- package/dist/backend.d.cts.map +1 -1
- package/dist/backend.d.mts +3 -0
- package/dist/backend.d.mts.map +1 -1
- package/dist/backend.mjs +13 -1
- package/dist/backend.mjs.map +1 -1
- package/dist/polling-with-policy.cjs.map +1 -1
- package/dist/polling-with-policy.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +3 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +3 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.1.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Added metrics in the Shield coverage response to track the latency ( [#7133](https://github.com/MetaMask/core/pull/7133))
|
|
15
|
+
|
|
10
16
|
## [2.0.0]
|
|
11
17
|
|
|
12
18
|
### Changed
|
|
@@ -124,7 +130,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
124
130
|
|
|
125
131
|
- Initial release of the shield-controller package ([#6137](https://github.com/MetaMask/core/pull/6137)
|
|
126
132
|
|
|
127
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@2.
|
|
133
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@2.1.0...HEAD
|
|
134
|
+
[2.1.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@2.0.0...@metamask/shield-controller@2.1.0
|
|
128
135
|
[2.0.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@1.2.0...@metamask/shield-controller@2.0.0
|
|
129
136
|
[1.2.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@1.1.0...@metamask/shield-controller@1.2.0
|
|
130
137
|
[1.1.0]: https://github.com/MetaMask/core/compare/@metamask/shield-controller@1.0.0...@metamask/shield-controller@1.1.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n SignatureRequestStatus,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n Boolean(previousTransaction?.simulationData) &&\n !isEqual(\n transaction.simulationData,\n previousTransaction?.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest) {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const { status } = this.#getCoverageStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n status,\n });\n }\n\n #getCoverageStatus(itemId: string) {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n SignatureRequestStatus,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n Boolean(previousTransaction?.simulationData) &&\n !isEqual(\n transaction.simulationData,\n previousTransaction?.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest) {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const { status } = this.#getCoverageStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n status,\n });\n }\n\n #getCoverageStatus(itemId: string) {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.mjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n SignatureRequestStatus,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n Boolean(previousTransaction?.simulationData) &&\n !isEqual(\n transaction.simulationData,\n previousTransaction?.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest) {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const { status } = this.#getCoverageStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n status,\n });\n }\n\n #getCoverageStatus(itemId: string) {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ShieldController.mjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n SignatureRequestStatus,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { cloneDeep, isEqual } from 'lodash';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type {\n CoverageResult,\n NormalizeSignatureRequestFn,\n ShieldBackend,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ShieldControllerState\n>;\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions =\n | ShieldControllerGetStateAction\n | ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = Messenger<\n typeof controllerName,\n ShieldControllerActions,\n ShieldControllerEvents | AllowedEvents\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n /**\n * Normalize the signature request before sending it to the backend.\n * Please note that the reason this is not being done internally is to\n * align the request body (data & params) with the security-alerts API.\n * The same normalization function which is used to normalize security-alerts request should be used here.\n *\n * @param signatureRequest - The signature request to normalize.\n * @returns The normalized signature request.\n */\n normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #normalizeSignatureRequest?: NormalizeSignatureRequestFn;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n normalizeSignatureRequest,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n this.#normalizeSignatureRequest = normalizeSignatureRequest;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messenger.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messenger.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messenger.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messenger.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new.\n if (!previousSignatureRequest) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n\n // Check if the simulation data has changed.\n const simulationDataChanged =\n // only check if the previous transaction has simulation data and if it has changed\n // this is to avoid checking coverage for the `TWICE` (once when it's added to the state and once when it's simulated for the first time).\n // we only need to update the coverage result when the simulation data has changed.\n Boolean(previousTransaction?.simulationData) &&\n !isEqual(\n transaction.simulationData,\n previousTransaction?.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (!previousTransaction || simulationDataChanged) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n\n // Normalize the signature request before sending it to the backend.\n // This is to ensure that the signature data is normalized and consistent as the security alerts api calls.\n const clonedSignatureRequest = cloneDeep(signatureRequest);\n const normalizedSignatureRequest =\n this.#normalizeSignatureRequest?.(clonedSignatureRequest) ??\n clonedSignatureRequest;\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest: normalizedSignatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messenger.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // Assert the coverageId hasn't changed.\n const latestCoverageId = this.#getLatestCoverageId(txId);\n if (latestCoverageId && coverageResult.coverageId !== latestCoverageId) {\n throw new Error('Coverage ID has changed');\n }\n\n this.update((draft) => {\n // Fetch coverage result entry.\n let newEntry = false;\n let coverageResultEntry = draft.coverageResults[txId];\n\n // Create new entry if necessary.\n if (!coverageResultEntry) {\n newEntry = true;\n coverageResultEntry = {\n results: [],\n };\n draft.coverageResults[txId] = coverageResultEntry;\n }\n\n // Trim coverage history if necessary.\n if (coverageResultEntry.results.length >= this.#coverageHistoryLimit) {\n coverageResultEntry.results.pop();\n }\n\n // Add new result.\n coverageResultEntry.results.unshift(coverageResult);\n\n // Add to history if new entry.\n const { orderedTransactionHistory } = draft;\n let removedTxId: string | undefined;\n if (newEntry) {\n // Trim transaction history if necessary.\n if (orderedTransactionHistory.length >= this.#transactionHistoryLimit) {\n removedTxId = orderedTransactionHistory.pop();\n // Delete corresponding coverage result entry.\n if (removedTxId) {\n delete draft.coverageResults[removedTxId];\n }\n }\n // Add to history.\n orderedTransactionHistory.unshift(txId);\n }\n });\n }\n\n async #logSignature(signatureRequest: SignatureRequest) {\n const signature = signatureRequest.rawSig;\n if (!signature) {\n throw new Error('Signature not found');\n }\n\n const { status } = this.#getCoverageStatus(signatureRequest.id);\n\n await this.#backend.logSignature({\n signatureRequest,\n signature,\n status,\n });\n }\n\n async #logTransaction(txMeta: TransactionMeta) {\n const transactionHash = txMeta.hash;\n if (!transactionHash) {\n throw new Error('Transaction hash not found');\n }\n\n const { status } = this.#getCoverageStatus(txMeta.id);\n\n await this.#backend.logTransaction({\n txMeta,\n transactionHash,\n status,\n });\n }\n\n #getCoverageStatus(itemId: string) {\n // The status is assigned as follows:\n // - 'shown' if we have a result\n // - 'not_shown' if we don't have a result\n const coverageId = this.#getLatestCoverageId(itemId);\n let status = 'shown';\n if (!coverageId) {\n log('Coverage ID not found for', itemId);\n status = 'not_shown';\n }\n return { status };\n }\n\n #getLatestCoverageId(itemId: string): string | undefined {\n return this.state.coverageResults[itemId]?.results[0]?.coverageId;\n }\n}\n"]}
|
package/dist/backend.cjs
CHANGED
|
@@ -48,6 +48,7 @@ class ShieldRemoteBackend {
|
|
|
48
48
|
message: coverageResult.message,
|
|
49
49
|
reasonCode: coverageResult.reasonCode,
|
|
50
50
|
status: coverageResult.status,
|
|
51
|
+
metrics: coverageResult.metrics,
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
async checkSignatureCoverage(req) {
|
|
@@ -63,6 +64,7 @@ class ShieldRemoteBackend {
|
|
|
63
64
|
message: coverageResult.message,
|
|
64
65
|
reasonCode: coverageResult.reasonCode,
|
|
65
66
|
status: coverageResult.status,
|
|
67
|
+
metrics: coverageResult.metrics,
|
|
66
68
|
};
|
|
67
69
|
}
|
|
68
70
|
async logSignature(req) {
|
|
@@ -118,6 +120,8 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_baseUr
|
|
|
118
120
|
coverageId,
|
|
119
121
|
};
|
|
120
122
|
const headers = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this);
|
|
123
|
+
// Start measuring total end-to-end latency including retries and delays
|
|
124
|
+
const startTime = Date.now();
|
|
121
125
|
const getCoverageResultFn = async (signal) => {
|
|
122
126
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, coverageResultUrl, {
|
|
123
127
|
method: 'POST',
|
|
@@ -126,6 +130,7 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_baseUr
|
|
|
126
130
|
signal,
|
|
127
131
|
});
|
|
128
132
|
if (res.status === 200) {
|
|
133
|
+
// Return the result without latency here - we'll add total latency after polling completes
|
|
129
134
|
return (await res.json());
|
|
130
135
|
}
|
|
131
136
|
// parse the error message from the response body
|
|
@@ -139,7 +144,14 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_baseUr
|
|
|
139
144
|
}
|
|
140
145
|
throw new controller_utils_1.HttpError(res.status, errorMessage);
|
|
141
146
|
};
|
|
142
|
-
|
|
147
|
+
const result = await __classPrivateFieldGet(this, _ShieldRemoteBackend_pollingPolicy, "f").start(requestId, getCoverageResultFn);
|
|
148
|
+
// Calculate total end-to-end latency including all retries and delays
|
|
149
|
+
const now = Date.now();
|
|
150
|
+
const totalLatency = now - startTime;
|
|
151
|
+
return {
|
|
152
|
+
...result,
|
|
153
|
+
metrics: { latency: totalLatency },
|
|
154
|
+
};
|
|
143
155
|
}, _ShieldRemoteBackend_createHeaders = async function _ShieldRemoteBackend_createHeaders() {
|
|
144
156
|
const accessToken = await __classPrivateFieldGet(this, _ShieldRemoteBackend_getAccessToken, "f").call(this);
|
|
145
157
|
return {
|
package/dist/backend.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.cjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ConstantBackoff,\n DEFAULT_MAX_RETRIES,\n HttpError,\n} from '@metamask/controller-utils';\nimport {\n EthMethod,\n SignatureRequestType,\n type SignatureRequest,\n} from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Json } from '@metamask/utils';\n\nimport { SignTypedDataVersion } from './constants';\nimport { PollingWithCockatielPolicy } from './polling-with-policy';\nimport type {\n CheckCoverageRequest,\n CheckSignatureCoverageRequest,\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: Json;\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 message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n readonly #pollingPolicy: PollingWithCockatielPolicy;\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.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n\n const { backoff, maxRetries } = computePollingIntervalAndRetryCount(\n getCoverageResultTimeout,\n getCoverageResultPollInterval,\n );\n\n this.#pollingPolicy = new PollingWithCockatielPolicy({\n backoff,\n maxRetries,\n });\n }\n\n async checkCoverage(req: CheckCoverageRequest): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitCoverageCheckBody(req.txMeta);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/transaction/coverage/init',\n reqBody,\n ));\n }\n\n const txCoverageResultUrl = `${this.#baseUrl}/v1/transaction/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.txMeta.id,\n coverageId,\n txCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n };\n }\n\n async checkSignatureCoverage(\n req: CheckSignatureCoverageRequest,\n ): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/signature/coverage/init',\n reqBody,\n ));\n }\n\n const signatureCoverageResultUrl = `${this.#baseUrl}/v1/signature/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.signatureRequest.id,\n coverageId,\n signatureCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n };\n }\n\n async logSignature(req: LogSignatureRequest): Promise<void> {\n const initBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n const body = {\n signature: req.signature,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.signatureRequest.id);\n\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(body),\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 initBody = makeInitCoverageCheckBody(req.txMeta);\n const body = {\n transactionHash: req.transactionHash,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.txMeta.id);\n\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(body),\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 requestId: string,\n coverageId: string,\n coverageResultUrl: string,\n ): Promise<GetCoverageResultResponse> {\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n\n const getCoverageResultFn = async (signal: AbortSignal) => {\n const res = await this.#fetch(coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal,\n });\n if (res.status === 200) {\n return (await res.json()) as GetCoverageResultResponse;\n }\n\n // parse the error message from the response body\n let errorMessage = 'Timeout waiting for coverage result';\n try {\n const errorJson = await res.json();\n errorMessage = `Failed to get coverage result: ${errorJson.message || errorJson.status}`;\n } catch {\n errorMessage = `Failed to get coverage result: ${res.status}`;\n }\n throw new HttpError(res.status, errorMessage);\n };\n\n return this.#pollingPolicy.start(requestId, getCoverageResultFn);\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 * Make the body for the init coverage check request.\n *\n * @param txMeta - The transaction metadata.\n * @returns The body for the init coverage check request.\n */\nfunction makeInitCoverageCheckBody(\n txMeta: TransactionMeta,\n): InitCoverageCheckRequest {\n return {\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\n/**\n * Make the body for the init signature coverage check request.\n *\n * @param signatureRequest - The signature request.\n * @returns The body for the init signature coverage check request.\n */\nfunction makeInitSignatureCoverageCheckBody(\n signatureRequest: SignatureRequest,\n): InitSignatureCoverageCheckRequest {\n // TODO: confirm that do we still need to validate the signature data?\n // signature controller already validates the signature data before adding it to the state.\n // @link https://github.com/MetaMask/core/blob/main/packages/signature-controller/src/SignatureController.ts#L408\n const method = parseSignatureRequestMethod(signatureRequest);\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data,\n from: signatureRequest.messageParams.from,\n method,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Parse the JSON-RPC method from the signature request.\n *\n * @param signatureRequest - The signature request.\n * @returns The JSON-RPC method.\n */\nexport function parseSignatureRequestMethod(\n signatureRequest: SignatureRequest,\n): string {\n if (signatureRequest.type === SignatureRequestType.TypedSign) {\n switch (signatureRequest.version) {\n case SignTypedDataVersion.V3:\n return EthMethod.SignTypedDataV3;\n case SignTypedDataVersion.V4:\n return EthMethod.SignTypedDataV4;\n case SignTypedDataVersion.V1:\n default:\n return SignatureRequestType.TypedSign;\n }\n }\n\n return signatureRequest.type;\n}\n\n/**\n * Compute the polling interval and retry count for the Cockatiel policy based on the timeout and poll interval given.\n *\n * @param timeout - The timeout in milliseconds.\n * @param pollInterval - The poll interval in milliseconds.\n * @returns The polling interval and retry count.\n */\nfunction computePollingIntervalAndRetryCount(\n timeout: number,\n pollInterval: number,\n) {\n const backoff = new ConstantBackoff(pollInterval);\n const computedMaxRetries = Math.floor(timeout / pollInterval) + 1;\n\n const maxRetries =\n isNaN(computedMaxRetries) || !isFinite(computedMaxRetries)\n ? DEFAULT_MAX_RETRIES\n : computedMaxRetries;\n\n return {\n backoff,\n maxRetries,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"backend.cjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ConstantBackoff,\n DEFAULT_MAX_RETRIES,\n HttpError,\n} from '@metamask/controller-utils';\nimport {\n EthMethod,\n SignatureRequestType,\n type SignatureRequest,\n} from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Json } from '@metamask/utils';\n\nimport { SignTypedDataVersion } from './constants';\nimport { PollingWithCockatielPolicy } from './polling-with-policy';\nimport type {\n CheckCoverageRequest,\n CheckSignatureCoverageRequest,\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: Json;\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 message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n metrics: {\n latency?: number;\n };\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n readonly #pollingPolicy: PollingWithCockatielPolicy;\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.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n\n const { backoff, maxRetries } = computePollingIntervalAndRetryCount(\n getCoverageResultTimeout,\n getCoverageResultPollInterval,\n );\n\n this.#pollingPolicy = new PollingWithCockatielPolicy({\n backoff,\n maxRetries,\n });\n }\n\n async checkCoverage(req: CheckCoverageRequest): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitCoverageCheckBody(req.txMeta);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/transaction/coverage/init',\n reqBody,\n ));\n }\n\n const txCoverageResultUrl = `${this.#baseUrl}/v1/transaction/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.txMeta.id,\n coverageId,\n txCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n metrics: coverageResult.metrics,\n };\n }\n\n async checkSignatureCoverage(\n req: CheckSignatureCoverageRequest,\n ): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/signature/coverage/init',\n reqBody,\n ));\n }\n\n const signatureCoverageResultUrl = `${this.#baseUrl}/v1/signature/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.signatureRequest.id,\n coverageId,\n signatureCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n metrics: coverageResult.metrics,\n };\n }\n\n async logSignature(req: LogSignatureRequest): Promise<void> {\n const initBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n const body = {\n signature: req.signature,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.signatureRequest.id);\n\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(body),\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 initBody = makeInitCoverageCheckBody(req.txMeta);\n const body = {\n transactionHash: req.transactionHash,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.txMeta.id);\n\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(body),\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 requestId: string,\n coverageId: string,\n coverageResultUrl: string,\n ): Promise<GetCoverageResultResponse> {\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n\n // Start measuring total end-to-end latency including retries and delays\n const startTime = Date.now();\n\n const getCoverageResultFn = async (signal: AbortSignal) => {\n const res = await this.#fetch(coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal,\n });\n\n if (res.status === 200) {\n // Return the result without latency here - we'll add total latency after polling completes\n return (await res.json()) as Omit<GetCoverageResultResponse, 'metrics'>;\n }\n\n // parse the error message from the response body\n let errorMessage = 'Timeout waiting for coverage result';\n try {\n const errorJson = await res.json();\n errorMessage = `Failed to get coverage result: ${errorJson.message || errorJson.status}`;\n } catch {\n errorMessage = `Failed to get coverage result: ${res.status}`;\n }\n throw new HttpError(res.status, errorMessage);\n };\n\n const result = await this.#pollingPolicy.start(\n requestId,\n getCoverageResultFn,\n );\n\n // Calculate total end-to-end latency including all retries and delays\n const now = Date.now();\n const totalLatency = now - startTime;\n\n return {\n ...result,\n metrics: { latency: totalLatency },\n } as GetCoverageResultResponse;\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 * Make the body for the init coverage check request.\n *\n * @param txMeta - The transaction metadata.\n * @returns The body for the init coverage check request.\n */\nfunction makeInitCoverageCheckBody(\n txMeta: TransactionMeta,\n): InitCoverageCheckRequest {\n return {\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\n/**\n * Make the body for the init signature coverage check request.\n *\n * @param signatureRequest - The signature request.\n * @returns The body for the init signature coverage check request.\n */\nfunction makeInitSignatureCoverageCheckBody(\n signatureRequest: SignatureRequest,\n): InitSignatureCoverageCheckRequest {\n // TODO: confirm that do we still need to validate the signature data?\n // signature controller already validates the signature data before adding it to the state.\n // @link https://github.com/MetaMask/core/blob/main/packages/signature-controller/src/SignatureController.ts#L408\n const method = parseSignatureRequestMethod(signatureRequest);\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data,\n from: signatureRequest.messageParams.from,\n method,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Parse the JSON-RPC method from the signature request.\n *\n * @param signatureRequest - The signature request.\n * @returns The JSON-RPC method.\n */\nexport function parseSignatureRequestMethod(\n signatureRequest: SignatureRequest,\n): string {\n if (signatureRequest.type === SignatureRequestType.TypedSign) {\n switch (signatureRequest.version) {\n case SignTypedDataVersion.V3:\n return EthMethod.SignTypedDataV3;\n case SignTypedDataVersion.V4:\n return EthMethod.SignTypedDataV4;\n case SignTypedDataVersion.V1:\n default:\n return SignatureRequestType.TypedSign;\n }\n }\n\n return signatureRequest.type;\n}\n\n/**\n * Compute the polling interval and retry count for the Cockatiel policy based on the timeout and poll interval given.\n *\n * @param timeout - The timeout in milliseconds.\n * @param pollInterval - The poll interval in milliseconds.\n * @returns The polling interval and retry count.\n */\nfunction computePollingIntervalAndRetryCount(\n timeout: number,\n pollInterval: number,\n) {\n const backoff = new ConstantBackoff(pollInterval);\n const computedMaxRetries = Math.floor(timeout / pollInterval) + 1;\n\n const maxRetries =\n isNaN(computedMaxRetries) || !isFinite(computedMaxRetries)\n ? DEFAULT_MAX_RETRIES\n : computedMaxRetries;\n\n return {\n backoff,\n maxRetries,\n };\n}\n"]}
|
package/dist/backend.d.cts
CHANGED
package/dist/backend.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.cts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,gBAAgB,EACtB,uCAAuC;AAExC,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAI5C,OAAO,KAAK,EACV,oBAAoB,EACpB,6BAA6B,EAC7B,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,IAAI,CAAC;IACX,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"backend.d.cts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,gBAAgB,EACtB,uCAAuC;AAExC,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAI5C,OAAO,KAAK,EACV,oBAAoB,EACpB,6BAA6B,EAC7B,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,IAAI,CAAC;IACX,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAS3C,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;IAgBK,aAAa,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAyBjE,sBAAsB,CAC1B,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,cAAc,CAAC;IAyBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBrD,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAmGhE;AAiDD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,gBAAgB,EAAE,gBAAgB,GACjC,MAAM,CAcR"}
|
package/dist/backend.d.mts
CHANGED
package/dist/backend.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.mts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,gBAAgB,EACtB,uCAAuC;AAExC,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAI5C,OAAO,KAAK,EACV,oBAAoB,EACpB,6BAA6B,EAC7B,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,IAAI,CAAC;IACX,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"backend.d.mts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,gBAAgB,EACtB,uCAAuC;AAExC,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAI5C,OAAO,KAAK,EACV,oBAAoB,EACpB,6BAA6B,EAC7B,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,IAAI,CAAC;IACX,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAS3C,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;IAgBK,aAAa,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAyBjE,sBAAsB,CAC1B,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,cAAc,CAAC;IAyBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBrD,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAmGhE;AAiDD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,gBAAgB,EAAE,gBAAgB,GACjC,MAAM,CAcR"}
|
package/dist/backend.mjs
CHANGED
|
@@ -45,6 +45,7 @@ export class ShieldRemoteBackend {
|
|
|
45
45
|
message: coverageResult.message,
|
|
46
46
|
reasonCode: coverageResult.reasonCode,
|
|
47
47
|
status: coverageResult.status,
|
|
48
|
+
metrics: coverageResult.metrics,
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
51
|
async checkSignatureCoverage(req) {
|
|
@@ -60,6 +61,7 @@ export class ShieldRemoteBackend {
|
|
|
60
61
|
message: coverageResult.message,
|
|
61
62
|
reasonCode: coverageResult.reasonCode,
|
|
62
63
|
status: coverageResult.status,
|
|
64
|
+
metrics: coverageResult.metrics,
|
|
63
65
|
};
|
|
64
66
|
}
|
|
65
67
|
async logSignature(req) {
|
|
@@ -114,6 +116,8 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_baseUr
|
|
|
114
116
|
coverageId,
|
|
115
117
|
};
|
|
116
118
|
const headers = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this);
|
|
119
|
+
// Start measuring total end-to-end latency including retries and delays
|
|
120
|
+
const startTime = Date.now();
|
|
117
121
|
const getCoverageResultFn = async (signal) => {
|
|
118
122
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, coverageResultUrl, {
|
|
119
123
|
method: 'POST',
|
|
@@ -122,6 +126,7 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_baseUr
|
|
|
122
126
|
signal,
|
|
123
127
|
});
|
|
124
128
|
if (res.status === 200) {
|
|
129
|
+
// Return the result without latency here - we'll add total latency after polling completes
|
|
125
130
|
return (await res.json());
|
|
126
131
|
}
|
|
127
132
|
// parse the error message from the response body
|
|
@@ -135,7 +140,14 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_baseUr
|
|
|
135
140
|
}
|
|
136
141
|
throw new HttpError(res.status, errorMessage);
|
|
137
142
|
};
|
|
138
|
-
|
|
143
|
+
const result = await __classPrivateFieldGet(this, _ShieldRemoteBackend_pollingPolicy, "f").start(requestId, getCoverageResultFn);
|
|
144
|
+
// Calculate total end-to-end latency including all retries and delays
|
|
145
|
+
const now = Date.now();
|
|
146
|
+
const totalLatency = now - startTime;
|
|
147
|
+
return {
|
|
148
|
+
...result,
|
|
149
|
+
metrics: { latency: totalLatency },
|
|
150
|
+
};
|
|
139
151
|
}, _ShieldRemoteBackend_createHeaders = async function _ShieldRemoteBackend_createHeaders() {
|
|
140
152
|
const accessToken = await __classPrivateFieldGet(this, _ShieldRemoteBackend_getAccessToken, "f").call(this);
|
|
141
153
|
return {
|
package/dist/backend.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.mjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ConstantBackoff,\n DEFAULT_MAX_RETRIES,\n HttpError,\n} from '@metamask/controller-utils';\nimport {\n EthMethod,\n SignatureRequestType,\n type SignatureRequest,\n} from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Json } from '@metamask/utils';\n\nimport { SignTypedDataVersion } from './constants';\nimport { PollingWithCockatielPolicy } from './polling-with-policy';\nimport type {\n CheckCoverageRequest,\n CheckSignatureCoverageRequest,\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: Json;\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 message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n readonly #pollingPolicy: PollingWithCockatielPolicy;\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.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n\n const { backoff, maxRetries } = computePollingIntervalAndRetryCount(\n getCoverageResultTimeout,\n getCoverageResultPollInterval,\n );\n\n this.#pollingPolicy = new PollingWithCockatielPolicy({\n backoff,\n maxRetries,\n });\n }\n\n async checkCoverage(req: CheckCoverageRequest): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitCoverageCheckBody(req.txMeta);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/transaction/coverage/init',\n reqBody,\n ));\n }\n\n const txCoverageResultUrl = `${this.#baseUrl}/v1/transaction/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.txMeta.id,\n coverageId,\n txCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n };\n }\n\n async checkSignatureCoverage(\n req: CheckSignatureCoverageRequest,\n ): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/signature/coverage/init',\n reqBody,\n ));\n }\n\n const signatureCoverageResultUrl = `${this.#baseUrl}/v1/signature/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.signatureRequest.id,\n coverageId,\n signatureCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n };\n }\n\n async logSignature(req: LogSignatureRequest): Promise<void> {\n const initBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n const body = {\n signature: req.signature,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.signatureRequest.id);\n\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(body),\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 initBody = makeInitCoverageCheckBody(req.txMeta);\n const body = {\n transactionHash: req.transactionHash,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.txMeta.id);\n\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(body),\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 requestId: string,\n coverageId: string,\n coverageResultUrl: string,\n ): Promise<GetCoverageResultResponse> {\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n\n const getCoverageResultFn = async (signal: AbortSignal) => {\n const res = await this.#fetch(coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal,\n });\n if (res.status === 200) {\n return (await res.json()) as GetCoverageResultResponse;\n }\n\n // parse the error message from the response body\n let errorMessage = 'Timeout waiting for coverage result';\n try {\n const errorJson = await res.json();\n errorMessage = `Failed to get coverage result: ${errorJson.message || errorJson.status}`;\n } catch {\n errorMessage = `Failed to get coverage result: ${res.status}`;\n }\n throw new HttpError(res.status, errorMessage);\n };\n\n return this.#pollingPolicy.start(requestId, getCoverageResultFn);\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 * Make the body for the init coverage check request.\n *\n * @param txMeta - The transaction metadata.\n * @returns The body for the init coverage check request.\n */\nfunction makeInitCoverageCheckBody(\n txMeta: TransactionMeta,\n): InitCoverageCheckRequest {\n return {\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\n/**\n * Make the body for the init signature coverage check request.\n *\n * @param signatureRequest - The signature request.\n * @returns The body for the init signature coverage check request.\n */\nfunction makeInitSignatureCoverageCheckBody(\n signatureRequest: SignatureRequest,\n): InitSignatureCoverageCheckRequest {\n // TODO: confirm that do we still need to validate the signature data?\n // signature controller already validates the signature data before adding it to the state.\n // @link https://github.com/MetaMask/core/blob/main/packages/signature-controller/src/SignatureController.ts#L408\n const method = parseSignatureRequestMethod(signatureRequest);\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data,\n from: signatureRequest.messageParams.from,\n method,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Parse the JSON-RPC method from the signature request.\n *\n * @param signatureRequest - The signature request.\n * @returns The JSON-RPC method.\n */\nexport function parseSignatureRequestMethod(\n signatureRequest: SignatureRequest,\n): string {\n if (signatureRequest.type === SignatureRequestType.TypedSign) {\n switch (signatureRequest.version) {\n case SignTypedDataVersion.V3:\n return EthMethod.SignTypedDataV3;\n case SignTypedDataVersion.V4:\n return EthMethod.SignTypedDataV4;\n case SignTypedDataVersion.V1:\n default:\n return SignatureRequestType.TypedSign;\n }\n }\n\n return signatureRequest.type;\n}\n\n/**\n * Compute the polling interval and retry count for the Cockatiel policy based on the timeout and poll interval given.\n *\n * @param timeout - The timeout in milliseconds.\n * @param pollInterval - The poll interval in milliseconds.\n * @returns The polling interval and retry count.\n */\nfunction computePollingIntervalAndRetryCount(\n timeout: number,\n pollInterval: number,\n) {\n const backoff = new ConstantBackoff(pollInterval);\n const computedMaxRetries = Math.floor(timeout / pollInterval) + 1;\n\n const maxRetries =\n isNaN(computedMaxRetries) || !isFinite(computedMaxRetries)\n ? DEFAULT_MAX_RETRIES\n : computedMaxRetries;\n\n return {\n backoff,\n maxRetries,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"backend.mjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACV,mCAAmC;AACpC,OAAO,EACL,SAAS,EACT,oBAAoB,EAErB,uCAAuC;AAIxC,OAAO,EAAE,oBAAoB,EAAE,wBAAoB;AACnD,OAAO,EAAE,0BAA0B,EAAE,kCAA8B;AAkDnE,MAAM,OAAO,mBAAmB;IAS9B,YAAY,EACV,cAAc,EACd,wBAAwB,GAAG,IAAI,EAAE,eAAe;IAChD,6BAA6B,GAAG,IAAI,EAAE,eAAe;IACrD,OAAO,EACP,KAAK,EAAE,OAAO,GAOf;;QApBQ,sDAAuC;QAEvC,+CAAiB;QAEjB,6CAAgC;QAEhC,qDAA2C;QAelD,uBAAA,IAAI,uCAAmB,cAAc,MAAA,CAAC;QACtC,uBAAA,IAAI,gCAAY,OAAO,MAAA,CAAC;QACxB,uBAAA,IAAI,8BAAU,OAAO,MAAA,CAAC;QAEtB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,mCAAmC,CACjE,wBAAwB,EACxB,6BAA6B,CAC9B,CAAC;QAEF,uBAAA,IAAI,sCAAkB,IAAI,0BAA0B,CAAC;YACnD,OAAO;YACP,UAAU;SACX,CAAC,MAAA,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAyB;QAC3C,IAAI,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC;QACzB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtD,CAAC,EAAE,UAAU,EAAE,GAAG,MAAM,uBAAA,IAAI,8EAAmB,MAAvB,IAAI,EAC1B,8BAA8B,EAC9B,OAAO,CACR,CAAC,CAAC;QACL,CAAC;QAED,MAAM,mBAAmB,GAAG,GAAG,uBAAA,IAAI,oCAAS,iCAAiC,CAAC;QAC9E,MAAM,cAAc,GAAG,MAAM,uBAAA,IAAI,8EAAmB,MAAvB,IAAI,EAC/B,GAAG,CAAC,MAAM,CAAC,EAAE,EACb,UAAU,EACV,mBAAmB,CACpB,CAAC;QACF,OAAO;YACL,UAAU;YACV,OAAO,EAAE,cAAc,CAAC,OAAO;YAC/B,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;SAChC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,GAAkC;QAElC,IAAI,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC;QACzB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,kCAAkC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YACzE,CAAC,EAAE,UAAU,EAAE,GAAG,MAAM,uBAAA,IAAI,8EAAmB,MAAvB,IAAI,EAC1B,4BAA4B,EAC5B,OAAO,CACR,CAAC,CAAC;QACL,CAAC;QAED,MAAM,0BAA0B,GAAG,GAAG,uBAAA,IAAI,oCAAS,+BAA+B,CAAC;QACnF,MAAM,cAAc,GAAG,MAAM,uBAAA,IAAI,8EAAmB,MAAvB,IAAI,EAC/B,GAAG,CAAC,gBAAgB,CAAC,EAAE,EACvB,UAAU,EACV,0BAA0B,CAC3B,CAAC;QACF,OAAO;YACL,UAAU;YACV,OAAO,EAAE,cAAc,CAAC,OAAO;YAC/B,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;SAChC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAwB;QACzC,MAAM,QAAQ,GAAG,kCAAkC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC1E,MAAM,IAAI,GAAG;YACX,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,QAAQ;SACZ,CAAC;QAEF,iDAAiD;QACjD,uBAAA,IAAI,0CAAe,CAAC,mBAAmB,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAEjE,MAAM,GAAG,GAAG,MAAM,uBAAA,IAAI,kCAAO,MAAX,IAAI,EACpB,GAAG,uBAAA,IAAI,oCAAS,4BAA4B,EAC5C;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,MAAM,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB;YACpC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CACF,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,GAA0B;QAC7C,MAAM,QAAQ,GAAG,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG;YACX,eAAe,EAAE,GAAG,CAAC,eAAe;YACpC,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,QAAQ;SACZ,CAAC;QAEF,iDAAiD;QACjD,uBAAA,IAAI,0CAAe,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAEvD,MAAM,GAAG,GAAG,MAAM,uBAAA,IAAI,kCAAO,MAAX,IAAI,EACpB,GAAG,uBAAA,IAAI,oCAAS,8BAA8B,EAC9C;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,MAAM,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB;YACpC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CACF,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CA6EF;4RA3EC,KAAK,iDACH,IAAY,EACZ,OAAgB;IAEhB,MAAM,GAAG,GAAG,MAAM,uBAAA,IAAI,kCAAO,MAAX,IAAI,EAAQ,GAAG,uBAAA,IAAI,oCAAS,IAAI,IAAI,EAAE,EAAE;QACxD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,MAAM,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB;QACpC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;IACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA8B,CAAC;AACzD,CAAC,2CAED,KAAK,iDACH,SAAiB,EACjB,UAAkB,EAClB,iBAAyB;IAEzB,MAAM,OAAO,GAA6B;QACxC,UAAU;KACX,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB,CAAC;IAE5C,wEAAwE;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,MAAM,mBAAmB,GAAG,KAAK,EAAE,MAAmB,EAAE,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,uBAAA,IAAI,kCAAO,MAAX,IAAI,EAAQ,iBAAiB,EAAE;YAC/C,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAC7B,MAAM;SACP,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,2FAA2F;YAC3F,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA+C,CAAC;QAC1E,CAAC;QAED,iDAAiD;QACjD,IAAI,YAAY,GAAG,qCAAqC,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACnC,YAAY,GAAG,kCAAkC,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QAC3F,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,GAAG,kCAAkC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChE,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,0CAAe,CAAC,KAAK,CAC5C,SAAS,EACT,mBAAmB,CACpB,CAAC;IAEF,sEAAsE;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,YAAY,GAAG,GAAG,GAAG,SAAS,CAAC;IAErC,OAAO;QACL,GAAG,MAAM;QACT,OAAO,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE;KACN,CAAC;AACjC,CAAC,uCAED,KAAK;IACH,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,2CAAgB,MAApB,IAAI,CAAkB,CAAC;IACjD,OAAO;QACL,cAAc,EAAE,kBAAkB;QAClC,aAAa,EAAE,UAAU,WAAW,EAAE;KACvC,CAAC;AACJ,CAAC;AAGH;;;;;GAKG;AACH,SAAS,yBAAyB,CAChC,MAAuB;IAEvB,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;gBAC1B,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;gBACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;gBAC5B,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;gBAC1B,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;aAC7B;SACF;QACD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,kCAAkC,CACzC,gBAAkC;IAElC,sEAAsE;IACtE,2FAA2F;IAC3F,iHAAiH;IACjH,MAAM,MAAM,GAAG,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;IAE7D,OAAO;QACL,OAAO,EAAE,gBAAgB,CAAC,OAAO;QACjC,IAAI,EAAE,gBAAgB,CAAC,aAAa,CAAC,IAAI;QACzC,IAAI,EAAE,gBAAgB,CAAC,aAAa,CAAC,IAAI;QACzC,MAAM;QACN,MAAM,EAAE,gBAAgB,CAAC,aAAa,CAAC,MAAM;KAC9C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CACzC,gBAAkC;IAElC,IAAI,gBAAgB,CAAC,IAAI,KAAK,oBAAoB,CAAC,SAAS,EAAE,CAAC;QAC7D,QAAQ,gBAAgB,CAAC,OAAO,EAAE,CAAC;YACjC,KAAK,oBAAoB,CAAC,EAAE;gBAC1B,OAAO,SAAS,CAAC,eAAe,CAAC;YACnC,KAAK,oBAAoB,CAAC,EAAE;gBAC1B,OAAO,SAAS,CAAC,eAAe,CAAC;YACnC,KAAK,oBAAoB,CAAC,EAAE,CAAC;YAC7B;gBACE,OAAO,oBAAoB,CAAC,SAAS,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mCAAmC,CAC1C,OAAe,EACf,YAAoB;IAEpB,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAElE,MAAM,UAAU,GACd,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QACxD,CAAC,CAAC,mBAAmB;QACrB,CAAC,CAAC,kBAAkB,CAAC;IAEzB,OAAO;QACL,OAAO;QACP,UAAU;KACX,CAAC;AACJ,CAAC","sourcesContent":["import {\n ConstantBackoff,\n DEFAULT_MAX_RETRIES,\n HttpError,\n} from '@metamask/controller-utils';\nimport {\n EthMethod,\n SignatureRequestType,\n type SignatureRequest,\n} from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Json } from '@metamask/utils';\n\nimport { SignTypedDataVersion } from './constants';\nimport { PollingWithCockatielPolicy } from './polling-with-policy';\nimport type {\n CheckCoverageRequest,\n CheckSignatureCoverageRequest,\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: Json;\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 message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n metrics: {\n latency?: number;\n };\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n readonly #pollingPolicy: PollingWithCockatielPolicy;\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.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n\n const { backoff, maxRetries } = computePollingIntervalAndRetryCount(\n getCoverageResultTimeout,\n getCoverageResultPollInterval,\n );\n\n this.#pollingPolicy = new PollingWithCockatielPolicy({\n backoff,\n maxRetries,\n });\n }\n\n async checkCoverage(req: CheckCoverageRequest): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitCoverageCheckBody(req.txMeta);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/transaction/coverage/init',\n reqBody,\n ));\n }\n\n const txCoverageResultUrl = `${this.#baseUrl}/v1/transaction/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.txMeta.id,\n coverageId,\n txCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n metrics: coverageResult.metrics,\n };\n }\n\n async checkSignatureCoverage(\n req: CheckSignatureCoverageRequest,\n ): Promise<CoverageResult> {\n let { coverageId } = req;\n if (!coverageId) {\n const reqBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n ({ coverageId } = await this.#initCoverageCheck(\n 'v1/signature/coverage/init',\n reqBody,\n ));\n }\n\n const signatureCoverageResultUrl = `${this.#baseUrl}/v1/signature/coverage/result`;\n const coverageResult = await this.#getCoverageResult(\n req.signatureRequest.id,\n coverageId,\n signatureCoverageResultUrl,\n );\n return {\n coverageId,\n message: coverageResult.message,\n reasonCode: coverageResult.reasonCode,\n status: coverageResult.status,\n metrics: coverageResult.metrics,\n };\n }\n\n async logSignature(req: LogSignatureRequest): Promise<void> {\n const initBody = makeInitSignatureCoverageCheckBody(req.signatureRequest);\n const body = {\n signature: req.signature,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.signatureRequest.id);\n\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(body),\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 initBody = makeInitCoverageCheckBody(req.txMeta);\n const body = {\n transactionHash: req.transactionHash,\n status: req.status,\n ...initBody,\n };\n\n // cancel the pending get coverage result request\n this.#pollingPolicy.abortPendingRequest(req.txMeta.id);\n\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(body),\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 requestId: string,\n coverageId: string,\n coverageResultUrl: string,\n ): Promise<GetCoverageResultResponse> {\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n\n // Start measuring total end-to-end latency including retries and delays\n const startTime = Date.now();\n\n const getCoverageResultFn = async (signal: AbortSignal) => {\n const res = await this.#fetch(coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal,\n });\n\n if (res.status === 200) {\n // Return the result without latency here - we'll add total latency after polling completes\n return (await res.json()) as Omit<GetCoverageResultResponse, 'metrics'>;\n }\n\n // parse the error message from the response body\n let errorMessage = 'Timeout waiting for coverage result';\n try {\n const errorJson = await res.json();\n errorMessage = `Failed to get coverage result: ${errorJson.message || errorJson.status}`;\n } catch {\n errorMessage = `Failed to get coverage result: ${res.status}`;\n }\n throw new HttpError(res.status, errorMessage);\n };\n\n const result = await this.#pollingPolicy.start(\n requestId,\n getCoverageResultFn,\n );\n\n // Calculate total end-to-end latency including all retries and delays\n const now = Date.now();\n const totalLatency = now - startTime;\n\n return {\n ...result,\n metrics: { latency: totalLatency },\n } as GetCoverageResultResponse;\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 * Make the body for the init coverage check request.\n *\n * @param txMeta - The transaction metadata.\n * @returns The body for the init coverage check request.\n */\nfunction makeInitCoverageCheckBody(\n txMeta: TransactionMeta,\n): InitCoverageCheckRequest {\n return {\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\n/**\n * Make the body for the init signature coverage check request.\n *\n * @param signatureRequest - The signature request.\n * @returns The body for the init signature coverage check request.\n */\nfunction makeInitSignatureCoverageCheckBody(\n signatureRequest: SignatureRequest,\n): InitSignatureCoverageCheckRequest {\n // TODO: confirm that do we still need to validate the signature data?\n // signature controller already validates the signature data before adding it to the state.\n // @link https://github.com/MetaMask/core/blob/main/packages/signature-controller/src/SignatureController.ts#L408\n const method = parseSignatureRequestMethod(signatureRequest);\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data,\n from: signatureRequest.messageParams.from,\n method,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Parse the JSON-RPC method from the signature request.\n *\n * @param signatureRequest - The signature request.\n * @returns The JSON-RPC method.\n */\nexport function parseSignatureRequestMethod(\n signatureRequest: SignatureRequest,\n): string {\n if (signatureRequest.type === SignatureRequestType.TypedSign) {\n switch (signatureRequest.version) {\n case SignTypedDataVersion.V3:\n return EthMethod.SignTypedDataV3;\n case SignTypedDataVersion.V4:\n return EthMethod.SignTypedDataV4;\n case SignTypedDataVersion.V1:\n default:\n return SignatureRequestType.TypedSign;\n }\n }\n\n return signatureRequest.type;\n}\n\n/**\n * Compute the polling interval and retry count for the Cockatiel policy based on the timeout and poll interval given.\n *\n * @param timeout - The timeout in milliseconds.\n * @param pollInterval - The poll interval in milliseconds.\n * @returns The polling interval and retry count.\n */\nfunction computePollingIntervalAndRetryCount(\n timeout: number,\n pollInterval: number,\n) {\n const backoff = new ConstantBackoff(pollInterval);\n const computedMaxRetries = Math.floor(timeout / pollInterval) + 1;\n\n const maxRetries =\n isNaN(computedMaxRetries) || !isFinite(computedMaxRetries)\n ? DEFAULT_MAX_RETRIES\n : computedMaxRetries;\n\n return {\n backoff,\n maxRetries,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polling-with-policy.cjs","sourceRoot":"","sources":["../src/polling-with-policy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,iEAKoC;AACpC,yCAAuC;AAMvC,MAAa,0BAA0B;IAKrC,YAAY,gBAA4C,EAAE;;QAJjD,qDAAuB;QAEvB,mDAAgB,IAAI,GAAG,EAA2B,EAAC;QAG1D,MAAM,iBAAiB,GAAG,IAAA,sBAAU,EAAC,uBAAA,IAAI,sFAAa,CAAC,CAAC;QACxD,uBAAA,IAAI,sCAAW,IAAA,sCAAmB,EAAC;YACjC,GAAG,aAAa;YAChB,iBAAiB;SAClB,CAAC,MAAA,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAa,SAAiB,EAAE,SAAgC;QACzE,MAAM,eAAe,GAAG,uBAAA,IAAI,6FAAoB,MAAxB,IAAI,EAAqB,SAAS,CAAC,CAAC;QAE5D,IAAI;
|
|
1
|
+
{"version":3,"file":"polling-with-policy.cjs","sourceRoot":"","sources":["../src/polling-with-policy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,iEAKoC;AACpC,yCAAuC;AAMvC,MAAa,0BAA0B;IAKrC,YAAY,gBAA4C,EAAE;;QAJjD,qDAAuB;QAEvB,mDAAgB,IAAI,GAAG,EAA2B,EAAC;QAG1D,MAAM,iBAAiB,GAAG,IAAA,sBAAU,EAAC,uBAAA,IAAI,sFAAa,CAAC,CAAC;QACxD,uBAAA,IAAI,sCAAW,IAAA,sCAAmB,EAAC;YACjC,GAAG,aAAa;YAChB,iBAAiB;SAClB,CAAC,MAAA,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAa,SAAiB,EAAE,SAAgC;QACzE,MAAM,eAAe,GAAG,uBAAA,IAAI,6FAAoB,MAAxB,IAAI,EAAqB,SAAS,CAAC,CAAC;QAE5D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,0CAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC7D,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3B,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;YAC3B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,wFAAwF;YACxF,oGAAoG;YACpG,oFAAoF;YACpF,IAAI,eAAe,KAAK,uBAAA,IAAI,gDAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1D,uBAAA,IAAI,kFAAS,MAAb,IAAI,EAAU,SAAS,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,mBAAmB,CAAC,SAAiB;QACnC,MAAM,eAAe,GAAG,uBAAA,IAAI,gDAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1D,eAAe,EAAE,KAAK,EAAE,CAAC;QACzB,uBAAA,IAAI,kFAAS,MAAb,IAAI,EAAU,SAAS,CAAC,CAAC;IAC3B,CAAC;CAwBF;AAhED,gEAgEC;8QAtBqB,SAAiB;IACnC,0CAA0C;IAC1C,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAEpC,oDAAoD;IACpD,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,uBAAA,IAAI,gDAAc,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACnD,OAAO,eAAe,CAAC;AACzB,CAAC,qFAEQ,SAAiB;IACxB,uBAAA,IAAI,gDAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACvC,CAAC,6FAEY,KAAY;IACvB,IAAI,KAAK,YAAY,4BAAS,EAAE,CAAC;QAC/B,0DAA0D;QAC1D,2EAA2E;QAC3E,OAAO,KAAK,CAAC,UAAU,GAAG,GAAG,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import {\n createServicePolicy,\n HttpError,\n type CreateServicePolicyOptions,\n type ServicePolicy,\n} from '@metamask/controller-utils';\nimport { handleWhen } from 'cockatiel';\n\nexport type RequestFn<ReturnType> = (\n signal: AbortSignal,\n) => Promise<ReturnType>;\n\nexport class PollingWithCockatielPolicy {\n readonly #policy: ServicePolicy;\n\n readonly #requestEntry = new Map<string, AbortController>();\n\n constructor(policyOptions: CreateServicePolicyOptions = {}) {\n const retryFilterPolicy = handleWhen(this.#shouldRetry);\n this.#policy = createServicePolicy({\n ...policyOptions,\n retryFilterPolicy,\n });\n }\n\n async start<ReturnType>(requestId: string, requestFn: RequestFn<ReturnType>) {\n const abortController = this.#addNewRequestEntry(requestId);\n\n try {\n const result = await this.#policy.execute(async ({ signal }) => {\n return requestFn(signal);\n }, abortController.signal);\n return result;\n } catch (error) {\n if (abortController.signal.aborted) {\n throw new Error('Request cancelled');\n }\n throw error;\n } finally {\n // Only cleanup if this abort controller is still active. If a new request with the same\n // requestId started while this one was running, it would have replaced with a new abort controller.\n // We must not delete the new request's controller when this older request finishes.\n if (abortController === this.#requestEntry.get(requestId)) {\n this.#cleanup(requestId);\n }\n }\n }\n\n abortPendingRequest(requestId: string) {\n const abortController = this.#requestEntry.get(requestId);\n abortController?.abort();\n this.#cleanup(requestId);\n }\n\n #addNewRequestEntry(requestId: string) {\n // abort the previous request if it exists\n this.abortPendingRequest(requestId);\n\n // create a new abort controller for the new request\n const abortController = new AbortController();\n this.#requestEntry.set(requestId, abortController);\n return abortController;\n }\n\n #cleanup(requestId: string) {\n this.#requestEntry.delete(requestId);\n }\n\n #shouldRetry(error: Error): boolean {\n if (error instanceof HttpError) {\n // Note: we don't retry on 5xx errors, only on 4xx errors.\n // but we won't retry on 400 coz it means that the request body is invalid.\n return error.httpStatus > 400 && error.httpStatus < 500;\n }\n return false;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polling-with-policy.mjs","sourceRoot":"","sources":["../src/polling-with-policy.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EACL,mBAAmB,EACnB,SAAS,EAGV,mCAAmC;AACpC,OAAO,EAAE,UAAU,EAAE,kBAAkB;AAMvC,MAAM,OAAO,0BAA0B;IAKrC,YAAY,gBAA4C,EAAE;;QAJjD,qDAAuB;QAEvB,mDAAgB,IAAI,GAAG,EAA2B,EAAC;QAG1D,MAAM,iBAAiB,GAAG,UAAU,CAAC,uBAAA,IAAI,sFAAa,CAAC,CAAC;QACxD,uBAAA,IAAI,sCAAW,mBAAmB,CAAC;YACjC,GAAG,aAAa;YAChB,iBAAiB;SAClB,CAAC,MAAA,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAa,SAAiB,EAAE,SAAgC;QACzE,MAAM,eAAe,GAAG,uBAAA,IAAI,6FAAoB,MAAxB,IAAI,EAAqB,SAAS,CAAC,CAAC;QAE5D,IAAI;
|
|
1
|
+
{"version":3,"file":"polling-with-policy.mjs","sourceRoot":"","sources":["../src/polling-with-policy.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EACL,mBAAmB,EACnB,SAAS,EAGV,mCAAmC;AACpC,OAAO,EAAE,UAAU,EAAE,kBAAkB;AAMvC,MAAM,OAAO,0BAA0B;IAKrC,YAAY,gBAA4C,EAAE;;QAJjD,qDAAuB;QAEvB,mDAAgB,IAAI,GAAG,EAA2B,EAAC;QAG1D,MAAM,iBAAiB,GAAG,UAAU,CAAC,uBAAA,IAAI,sFAAa,CAAC,CAAC;QACxD,uBAAA,IAAI,sCAAW,mBAAmB,CAAC;YACjC,GAAG,aAAa;YAChB,iBAAiB;SAClB,CAAC,MAAA,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAa,SAAiB,EAAE,SAAgC;QACzE,MAAM,eAAe,GAAG,uBAAA,IAAI,6FAAoB,MAAxB,IAAI,EAAqB,SAAS,CAAC,CAAC;QAE5D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,0CAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC7D,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3B,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;YAC3B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,wFAAwF;YACxF,oGAAoG;YACpG,oFAAoF;YACpF,IAAI,eAAe,KAAK,uBAAA,IAAI,gDAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1D,uBAAA,IAAI,kFAAS,MAAb,IAAI,EAAU,SAAS,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,mBAAmB,CAAC,SAAiB;QACnC,MAAM,eAAe,GAAG,uBAAA,IAAI,gDAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1D,eAAe,EAAE,KAAK,EAAE,CAAC;QACzB,uBAAA,IAAI,kFAAS,MAAb,IAAI,EAAU,SAAS,CAAC,CAAC;IAC3B,CAAC;CAwBF;8QAtBqB,SAAiB;IACnC,0CAA0C;IAC1C,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAEpC,oDAAoD;IACpD,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,uBAAA,IAAI,gDAAc,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACnD,OAAO,eAAe,CAAC;AACzB,CAAC,qFAEQ,SAAiB;IACxB,uBAAA,IAAI,gDAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACvC,CAAC,6FAEY,KAAY;IACvB,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;QAC/B,0DAA0D;QAC1D,2EAA2E;QAC3E,OAAO,KAAK,CAAC,UAAU,GAAG,GAAG,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import {\n createServicePolicy,\n HttpError,\n type CreateServicePolicyOptions,\n type ServicePolicy,\n} from '@metamask/controller-utils';\nimport { handleWhen } from 'cockatiel';\n\nexport type RequestFn<ReturnType> = (\n signal: AbortSignal,\n) => Promise<ReturnType>;\n\nexport class PollingWithCockatielPolicy {\n readonly #policy: ServicePolicy;\n\n readonly #requestEntry = new Map<string, AbortController>();\n\n constructor(policyOptions: CreateServicePolicyOptions = {}) {\n const retryFilterPolicy = handleWhen(this.#shouldRetry);\n this.#policy = createServicePolicy({\n ...policyOptions,\n retryFilterPolicy,\n });\n }\n\n async start<ReturnType>(requestId: string, requestFn: RequestFn<ReturnType>) {\n const abortController = this.#addNewRequestEntry(requestId);\n\n try {\n const result = await this.#policy.execute(async ({ signal }) => {\n return requestFn(signal);\n }, abortController.signal);\n return result;\n } catch (error) {\n if (abortController.signal.aborted) {\n throw new Error('Request cancelled');\n }\n throw error;\n } finally {\n // Only cleanup if this abort controller is still active. If a new request with the same\n // requestId started while this one was running, it would have replaced with a new abort controller.\n // We must not delete the new request's controller when this older request finishes.\n if (abortController === this.#requestEntry.get(requestId)) {\n this.#cleanup(requestId);\n }\n }\n }\n\n abortPendingRequest(requestId: string) {\n const abortController = this.#requestEntry.get(requestId);\n abortController?.abort();\n this.#cleanup(requestId);\n }\n\n #addNewRequestEntry(requestId: string) {\n // abort the previous request if it exists\n this.abortPendingRequest(requestId);\n\n // create a new abort controller for the new request\n const abortController = new AbortController();\n this.#requestEntry.set(requestId, abortController);\n return abortController;\n }\n\n #cleanup(requestId: string) {\n this.#requestEntry.delete(requestId);\n }\n\n #shouldRetry(error: Error): boolean {\n if (error instanceof HttpError) {\n // Note: we don't retry on 5xx errors, only on 4xx errors.\n // but we won't retry on 400 coz it means that the request body is invalid.\n return error.httpStatus > 400 && error.httpStatus < 500;\n }\n return false;\n }\n}\n"]}
|
package/dist/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAaa,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 message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n metrics: {\n latency?: number;\n };\n};\n\nexport const coverageStatuses = ['covered', 'malicious', 'unknown'] as const;\nexport type CoverageStatus = (typeof coverageStatuses)[number];\n\nexport type LogSignatureRequest = {\n signatureRequest: SignatureRequest;\n signature: string;\n status: string;\n};\n\nexport type LogTransactionRequest = {\n txMeta: TransactionMeta;\n transactionHash: string;\n status: string;\n};\n\nexport type CheckCoverageRequest = {\n coverageId?: string;\n txMeta: TransactionMeta;\n};\n\nexport type CheckSignatureCoverageRequest = {\n coverageId?: string;\n signatureRequest: SignatureRequest;\n};\n\nexport type ShieldBackend = {\n logSignature: (req: LogSignatureRequest) => Promise<void>;\n logTransaction: (req: LogTransactionRequest) => Promise<void>;\n checkCoverage: (req: CheckCoverageRequest) => Promise<CoverageResult>;\n checkSignatureCoverage: (\n req: CheckSignatureCoverageRequest,\n ) => Promise<CoverageResult>;\n};\n\nexport type NormalizeSignatureRequestFn = (\n signatureRequest: SignatureRequest,\n) => SignatureRequest;\n"]}
|
package/dist/types.d.cts
CHANGED
|
@@ -5,6 +5,9 @@ export type CoverageResult = {
|
|
|
5
5
|
message?: string;
|
|
6
6
|
reasonCode?: string;
|
|
7
7
|
status: CoverageStatus;
|
|
8
|
+
metrics: {
|
|
9
|
+
latency?: number;
|
|
10
|
+
};
|
|
8
11
|
};
|
|
9
12
|
export declare const coverageStatuses: readonly ["covered", "malicious", "unknown"];
|
|
10
13
|
export type CoverageStatus = (typeof coverageStatuses)[number];
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,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,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,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,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACtE,sBAAsB,EAAE,CACtB,GAAG,EAAE,6BAA6B,KAC/B,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,CACxC,gBAAgB,EAAE,gBAAgB,KAC/B,gBAAgB,CAAC"}
|
package/dist/types.d.mts
CHANGED
|
@@ -5,6 +5,9 @@ export type CoverageResult = {
|
|
|
5
5
|
message?: string;
|
|
6
6
|
reasonCode?: string;
|
|
7
7
|
status: CoverageStatus;
|
|
8
|
+
metrics: {
|
|
9
|
+
latency?: number;
|
|
10
|
+
};
|
|
8
11
|
};
|
|
9
12
|
export declare const coverageStatuses: readonly ["covered", "malicious", "unknown"];
|
|
10
13
|
export type CoverageStatus = (typeof coverageStatuses)[number];
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,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,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,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,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACtE,sBAAsB,EAAE,CACtB,GAAG,EAAE,6BAA6B,KAC/B,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,CACxC,gBAAgB,EAAE,gBAAgB,KAC/B,gBAAgB,CAAC"}
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA,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 message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n metrics: {\n latency?: number;\n };\n};\n\nexport const coverageStatuses = ['covered', 'malicious', 'unknown'] as const;\nexport type CoverageStatus = (typeof coverageStatuses)[number];\n\nexport type LogSignatureRequest = {\n signatureRequest: SignatureRequest;\n signature: string;\n status: string;\n};\n\nexport type LogTransactionRequest = {\n txMeta: TransactionMeta;\n transactionHash: string;\n status: string;\n};\n\nexport type CheckCoverageRequest = {\n coverageId?: string;\n txMeta: TransactionMeta;\n};\n\nexport type CheckSignatureCoverageRequest = {\n coverageId?: string;\n signatureRequest: SignatureRequest;\n};\n\nexport type ShieldBackend = {\n logSignature: (req: LogSignatureRequest) => Promise<void>;\n logTransaction: (req: LogTransactionRequest) => Promise<void>;\n checkCoverage: (req: CheckCoverageRequest) => Promise<CoverageResult>;\n checkSignatureCoverage: (\n req: CheckSignatureCoverageRequest,\n ) => Promise<CoverageResult>;\n};\n\nexport type NormalizeSignatureRequestFn = (\n signatureRequest: SignatureRequest,\n) => SignatureRequest;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/shield-controller",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Controller handling shield transaction coverage logic",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@lavamoat/preinstall-always-fail": "^2.1.0",
|
|
61
61
|
"@metamask/auto-changelog": "^3.4.4",
|
|
62
62
|
"@metamask/signature-controller": "^36.0.0",
|
|
63
|
-
"@metamask/transaction-controller": "^61.
|
|
63
|
+
"@metamask/transaction-controller": "^61.2.0",
|
|
64
64
|
"@ts-bridge/cli": "^0.6.4",
|
|
65
65
|
"@types/jest": "^27.4.1",
|
|
66
66
|
"deepmerge": "^4.2.2",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"ts-jest": "^27.1.4",
|
|
70
70
|
"typedoc": "^0.24.8",
|
|
71
71
|
"typedoc-plugin-missing-exports": "^2.0.0",
|
|
72
|
-
"typescript": "~5.
|
|
72
|
+
"typescript": "~5.3.3",
|
|
73
73
|
"uuid": "^8.3.2"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|