@metamask-previews/shield-controller 0.3.2-preview-7b18fd52 → 0.3.2-preview-a2a9f78c
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 +9 -0
- package/dist/ShieldController.cjs +8 -11
- package/dist/ShieldController.cjs.map +1 -1
- package/dist/ShieldController.d.cts.map +1 -1
- package/dist/ShieldController.d.mts.map +1 -1
- package/dist/ShieldController.mjs +9 -12
- package/dist/ShieldController.mjs.map +1 -1
- package/dist/backend.cjs +14 -15
- package/dist/backend.cjs.map +1 -1
- package/dist/backend.d.cts.map +1 -1
- package/dist/backend.d.mts.map +1 -1
- package/dist/backend.mjs +14 -15
- package/dist/backend.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Updated internal coverage result polling and log logic. ([#6847](https://github.com/MetaMask/core/pull/6847))
|
|
13
|
+
- Added cancellation logic to the polling.
|
|
14
|
+
- Updated implementation of timeout.
|
|
15
|
+
- Cancel any pending requests before starting new polling or logging.
|
|
16
|
+
- Updated TransactionMeta comparison in `TransactionController:stateChange` subscriber to avoid triggering multiple check coverage result unnecessarily. ([#6847](https://github.com/MetaMask/core/pull/6847))
|
|
17
|
+
- Removed `Personal Sign` check from the check signature coverage result. ([#6847](https://github.com/MetaMask/core/pull/6847))
|
|
18
|
+
|
|
10
19
|
## [0.3.2]
|
|
11
20
|
|
|
12
21
|
### Changed
|
|
@@ -139,8 +139,7 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
139
139
|
const previousSignatureRequest = previousSignatureRequestsById.get(signatureRequest.id);
|
|
140
140
|
// Check coverage if the signature request is new and has type
|
|
141
141
|
// `personal_sign`.
|
|
142
|
-
if (!previousSignatureRequest
|
|
143
|
-
signatureRequest.type === signature_controller_1.SignatureRequestType.PersonalSign) {
|
|
142
|
+
if (!previousSignatureRequest) {
|
|
144
143
|
this.checkSignatureCoverage(signatureRequest).catch(
|
|
145
144
|
// istanbul ignore next
|
|
146
145
|
(error) => log('Error checking coverage:', error));
|
|
@@ -157,13 +156,11 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
157
156
|
const previousTransactionsById = new Map(previousTransactions?.map((tx) => [tx.id, tx]) ?? []);
|
|
158
157
|
for (const transaction of transactions) {
|
|
159
158
|
const previousTransaction = previousTransactionsById.get(transaction.id);
|
|
160
|
-
|
|
159
|
+
// Check if the simulation data has changed.
|
|
160
|
+
const simulationDataChanged = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_compareTransactionSimulationData).call(this, transaction.simulationData, previousTransaction?.simulationData);
|
|
161
161
|
// Check coverage if the transaction is new or if the simulation data has
|
|
162
162
|
// changed.
|
|
163
|
-
if (!previousTransaction ||
|
|
164
|
-
// Checking reference equality is sufficient because this object is
|
|
165
|
-
// replaced if the simulation data has changed.
|
|
166
|
-
simulationDataChanged) {
|
|
163
|
+
if (!previousTransaction || simulationDataChanged) {
|
|
167
164
|
this.checkCoverage(transaction).catch(
|
|
168
165
|
// istanbul ignore next
|
|
169
166
|
(error) => log('Error checking coverage:', error));
|
|
@@ -272,10 +269,10 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
272
269
|
return true;
|
|
273
270
|
}
|
|
274
271
|
// check the token balance changes
|
|
275
|
-
if (simulationData?.tokenBalanceChanges
|
|
276
|
-
previousSimulationData?.tokenBalanceChanges
|
|
277
|
-
simulationData?.tokenBalanceChanges
|
|
278
|
-
previousSimulationData?.tokenBalanceChanges[index]
|
|
272
|
+
if (simulationData?.tokenBalanceChanges?.length !==
|
|
273
|
+
previousSimulationData?.tokenBalanceChanges?.length ||
|
|
274
|
+
simulationData?.tokenBalanceChanges?.some((tokenBalanceChange, index) => tokenBalanceChange.difference !==
|
|
275
|
+
previousSimulationData?.tokenBalanceChanges?.[index]?.difference)) {
|
|
279
276
|
return true;
|
|
280
277
|
}
|
|
281
278
|
// check the isUpdatedAfterSecurityCheck
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n SignatureRequestStatus,\n SignatureRequestType,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { CoverageResult, ShieldBackend } from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions = ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external actions available to the ShieldController.\n */\ntype AllowedActions = never;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messagingSystem.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messagingSystem.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new and has type\n // `personal_sign`.\n if (\n !previousSignatureRequest &&\n signatureRequest.type === SignatureRequestType.PersonalSign\n ) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n const simulationDataChanged = this.#compareTransactionSimulationData(\n previousTransaction?.simulationData,\n transaction.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (\n !previousTransaction ||\n // Checking reference equality is sufficient because this object is\n // replaced if the simulation data has changed.\n simulationDataChanged\n ) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // 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 /**\n * Compares the simulation data of a transaction.\n *\n * @param simulationData - The simulation data of the transaction.\n * @param previousSimulationData - The previous simulation data of the transaction.\n * @returns Whether the simulation data has changed.\n */\n #compareTransactionSimulationData(\n simulationData?: TransactionMeta['simulationData'],\n previousSimulationData?: TransactionMeta['simulationData'],\n ) {\n if (!simulationData && !previousSimulationData) {\n return false;\n }\n\n // check the simulation error\n if (\n simulationData?.error?.code !== previousSimulationData?.error?.code ||\n simulationData?.error?.message !== previousSimulationData?.error?.message\n ) {\n return true;\n }\n\n // check the native balance change\n if (\n simulationData?.nativeBalanceChange?.difference !==\n previousSimulationData?.nativeBalanceChange?.difference ||\n simulationData?.nativeBalanceChange?.newBalance !==\n previousSimulationData?.nativeBalanceChange?.newBalance ||\n simulationData?.nativeBalanceChange?.previousBalance !==\n previousSimulationData?.nativeBalanceChange?.previousBalance ||\n simulationData?.nativeBalanceChange?.isDecrease !==\n previousSimulationData?.nativeBalanceChange?.isDecrease\n ) {\n return true;\n }\n\n // check the token balance changes\n if (\n simulationData?.tokenBalanceChanges.length !==\n previousSimulationData?.tokenBalanceChanges.length ||\n simulationData?.tokenBalanceChanges.some(\n (tokenBalanceChange, index) =>\n tokenBalanceChange.difference !==\n previousSimulationData?.tokenBalanceChanges[index].difference,\n )\n ) {\n return true;\n }\n\n // check the isUpdatedAfterSecurityCheck\n return (\n simulationData?.isUpdatedAfterSecurityCheck !==\n previousSimulationData?.isUpdatedAfterSecurityCheck\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ShieldController.cjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n SignatureRequestStatus,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { CoverageResult, ShieldBackend } from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions = ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external actions available to the ShieldController.\n */\ntype AllowedActions = never;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messagingSystem.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messagingSystem.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new and has type\n // `personal_sign`.\n if (!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 // Check if the simulation data has changed.\n const simulationDataChanged = this.#compareTransactionSimulationData(\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.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // 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 /**\n * Compares the simulation data of a transaction.\n *\n * @param simulationData - The simulation data of the transaction.\n * @param previousSimulationData - The previous simulation data of the transaction.\n * @returns Whether the simulation data has changed.\n */\n #compareTransactionSimulationData(\n simulationData?: TransactionMeta['simulationData'],\n previousSimulationData?: TransactionMeta['simulationData'],\n ) {\n if (!simulationData && !previousSimulationData) {\n return false;\n }\n\n // check the simulation error\n if (\n simulationData?.error?.code !== previousSimulationData?.error?.code ||\n simulationData?.error?.message !== previousSimulationData?.error?.message\n ) {\n return true;\n }\n\n // check the native balance change\n if (\n simulationData?.nativeBalanceChange?.difference !==\n previousSimulationData?.nativeBalanceChange?.difference ||\n simulationData?.nativeBalanceChange?.newBalance !==\n previousSimulationData?.nativeBalanceChange?.newBalance ||\n simulationData?.nativeBalanceChange?.previousBalance !==\n previousSimulationData?.nativeBalanceChange?.previousBalance ||\n simulationData?.nativeBalanceChange?.isDecrease !==\n previousSimulationData?.nativeBalanceChange?.isDecrease\n ) {\n return true;\n }\n\n // check the token balance changes\n if (\n simulationData?.tokenBalanceChanges?.length !==\n previousSimulationData?.tokenBalanceChanges?.length ||\n simulationData?.tokenBalanceChanges?.some(\n (tokenBalanceChange, index) =>\n tokenBalanceChange.difference !==\n previousSimulationData?.tokenBalanceChanges?.[index]?.difference,\n )\n ) {\n return true;\n }\n\n // check the isUpdatedAfterSecurityCheck\n return (\n simulationData?.isUpdatedAfterSecurityCheck !==\n previousSimulationData?.isUpdatedAfterSecurityCheck\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.d.cts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"ShieldController.d.cts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,uCAAuC;AACxC,OAAO,EAEL,KAAK,qCAAqC,EAC1C,KAAK,eAAe,EACrB,yCAAyC;AAE1C,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAI7D,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF;;OAEG;IACH,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;CAC5C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,mCAAmC,CAAC;AAE1E,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,yBAAyB,CAAC;IACxD,OAAO,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,KAAK,aAAa,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CACzD,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,EACtC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAqBF,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,yBAAyB,CAAC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,OAAO,EAAE,aAAa,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAmBa,OAAO,EAAE,uBAAuB;IA4B5C,KAAK;IAmBL,IAAI;IA4FJ;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAoBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CA0K3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.d.mts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"ShieldController.d.mts","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;AACnC,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,uCAAuC;AACxC,OAAO,EAEL,KAAK,qCAAqC,EAC1C,KAAK,eAAe,EACrB,yCAAyC;AAE1C,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAgB;AAI7D,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,eAAe,EAAE,MAAM,CACrB,MAAM,EAAE,OAAO;IACf,yBAAyB,CAC1B,CAAC;IACF;;OAEG;IACH,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAKvE;AAED,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,gBAAgB,CAAC;IAC/C,OAAO,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;CAC5C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,mCAAmC,CAAC;AAE1E,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,yBAAyB,CAAC;IACxD,OAAO,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,KAAK,aAAa,GACd,oBAAoB,GACpB,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CACzD,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,EACtC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAqBF,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,yBAAyB,CAAC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,OAAO,EAAE,aAAa,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAmBa,OAAO,EAAE,uBAAuB;IA4B5C,KAAK;IAmBL,IAAI;IA4FJ;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAoBrE;;;;;OAKG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,cAAc,CAAC;CA0K3B"}
|
|
@@ -11,7 +11,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _ShieldController_instances, _ShieldController_backend, _ShieldController_coverageHistoryLimit, _ShieldController_transactionHistoryLimit, _ShieldController_transactionControllerStateChangeHandler, _ShieldController_signatureControllerStateChangeHandler, _ShieldController_started, _ShieldController_handleSignatureControllerStateChange, _ShieldController_handleTransactionControllerStateChange, _ShieldController_addCoverageResult, _ShieldController_logSignature, _ShieldController_logTransaction, _ShieldController_getCoverageStatus, _ShieldController_getLatestCoverageId, _ShieldController_compareTransactionSimulationData;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
|
-
import { SignatureRequestStatus
|
|
14
|
+
import { SignatureRequestStatus } from "@metamask/signature-controller";
|
|
15
15
|
import { TransactionStatus } from "@metamask/transaction-controller";
|
|
16
16
|
import { controllerName } from "./constants.mjs";
|
|
17
17
|
import { projectLogger, createModuleLogger } from "./logger.mjs";
|
|
@@ -134,8 +134,7 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
134
134
|
const previousSignatureRequest = previousSignatureRequestsById.get(signatureRequest.id);
|
|
135
135
|
// Check coverage if the signature request is new and has type
|
|
136
136
|
// `personal_sign`.
|
|
137
|
-
if (!previousSignatureRequest
|
|
138
|
-
signatureRequest.type === SignatureRequestType.PersonalSign) {
|
|
137
|
+
if (!previousSignatureRequest) {
|
|
139
138
|
this.checkSignatureCoverage(signatureRequest).catch(
|
|
140
139
|
// istanbul ignore next
|
|
141
140
|
(error) => log('Error checking coverage:', error));
|
|
@@ -152,13 +151,11 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
152
151
|
const previousTransactionsById = new Map(previousTransactions?.map((tx) => [tx.id, tx]) ?? []);
|
|
153
152
|
for (const transaction of transactions) {
|
|
154
153
|
const previousTransaction = previousTransactionsById.get(transaction.id);
|
|
155
|
-
|
|
154
|
+
// Check if the simulation data has changed.
|
|
155
|
+
const simulationDataChanged = __classPrivateFieldGet(this, _ShieldController_instances, "m", _ShieldController_compareTransactionSimulationData).call(this, transaction.simulationData, previousTransaction?.simulationData);
|
|
156
156
|
// Check coverage if the transaction is new or if the simulation data has
|
|
157
157
|
// changed.
|
|
158
|
-
if (!previousTransaction ||
|
|
159
|
-
// Checking reference equality is sufficient because this object is
|
|
160
|
-
// replaced if the simulation data has changed.
|
|
161
|
-
simulationDataChanged) {
|
|
158
|
+
if (!previousTransaction || simulationDataChanged) {
|
|
162
159
|
this.checkCoverage(transaction).catch(
|
|
163
160
|
// istanbul ignore next
|
|
164
161
|
(error) => log('Error checking coverage:', error));
|
|
@@ -267,10 +264,10 @@ _ShieldController_backend = new WeakMap(), _ShieldController_coverageHistoryLimi
|
|
|
267
264
|
return true;
|
|
268
265
|
}
|
|
269
266
|
// check the token balance changes
|
|
270
|
-
if (simulationData?.tokenBalanceChanges
|
|
271
|
-
previousSimulationData?.tokenBalanceChanges
|
|
272
|
-
simulationData?.tokenBalanceChanges
|
|
273
|
-
previousSimulationData?.tokenBalanceChanges[index]
|
|
267
|
+
if (simulationData?.tokenBalanceChanges?.length !==
|
|
268
|
+
previousSimulationData?.tokenBalanceChanges?.length ||
|
|
269
|
+
simulationData?.tokenBalanceChanges?.some((tokenBalanceChange, index) => tokenBalanceChange.difference !==
|
|
270
|
+
previousSimulationData?.tokenBalanceChanges?.[index]?.difference)) {
|
|
274
271
|
return true;
|
|
275
272
|
}
|
|
276
273
|
// check the isUpdatedAfterSecurityCheck
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldController.mjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n SignatureRequestStatus,\n SignatureRequestType,\n type SignatureRequest,\n type SignatureStateChange,\n} from '@metamask/signature-controller';\nimport {\n TransactionStatus,\n type TransactionControllerStateChangeEvent,\n type TransactionMeta,\n} from '@metamask/transaction-controller';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { CoverageResult, ShieldBackend } from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions = ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external actions available to the ShieldController.\n */\ntype AllowedActions = never;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messagingSystem.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messagingSystem.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new and has type\n // `personal_sign`.\n if (\n !previousSignatureRequest &&\n signatureRequest.type === SignatureRequestType.PersonalSign\n ) {\n this.checkSignatureCoverage(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log signature once the signature request has been fulfilled.\n if (\n signatureRequest.status === SignatureRequestStatus.Signed &&\n signatureRequest.status !== previousSignatureRequest?.status\n ) {\n this.#logSignature(signatureRequest).catch(\n // istanbul ignore next\n (error) => log('Error logging signature:', error),\n );\n }\n }\n }\n\n #handleTransactionControllerStateChange(\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) {\n const previousTransactionsById = new Map<string, TransactionMeta>(\n previousTransactions?.map((tx) => [tx.id, tx]) ?? [],\n );\n for (const transaction of transactions) {\n const previousTransaction = previousTransactionsById.get(transaction.id);\n const simulationDataChanged = this.#compareTransactionSimulationData(\n previousTransaction?.simulationData,\n transaction.simulationData,\n );\n\n // Check coverage if the transaction is new or if the simulation data has\n // changed.\n if (\n !previousTransaction ||\n // Checking reference equality is sufficient because this object is\n // replaced if the simulation data has changed.\n simulationDataChanged\n ) {\n this.checkCoverage(transaction).catch(\n // istanbul ignore next\n (error) => log('Error checking coverage:', error),\n );\n }\n\n // Log transaction once it has been submitted.\n if (\n transaction.status === TransactionStatus.submitted &&\n transaction.status !== previousTransaction?.status\n ) {\n this.#logTransaction(transaction).catch(\n // istanbul ignore next\n (error) => log('Error logging transaction:', error),\n );\n }\n }\n }\n\n /**\n * Checks the coverage of a transaction.\n *\n * @param txMeta - The transaction to check coverage for.\n * @returns The coverage result.\n */\n async checkCoverage(txMeta: TransactionMeta): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(txMeta.id);\n const coverageResult = await this.#backend.checkCoverage({\n txMeta,\n coverageId,\n });\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // 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 /**\n * Compares the simulation data of a transaction.\n *\n * @param simulationData - The simulation data of the transaction.\n * @param previousSimulationData - The previous simulation data of the transaction.\n * @returns Whether the simulation data has changed.\n */\n #compareTransactionSimulationData(\n simulationData?: TransactionMeta['simulationData'],\n previousSimulationData?: TransactionMeta['simulationData'],\n ) {\n if (!simulationData && !previousSimulationData) {\n return false;\n }\n\n // check the simulation error\n if (\n simulationData?.error?.code !== previousSimulationData?.error?.code ||\n simulationData?.error?.message !== previousSimulationData?.error?.message\n ) {\n return true;\n }\n\n // check the native balance change\n if (\n simulationData?.nativeBalanceChange?.difference !==\n previousSimulationData?.nativeBalanceChange?.difference ||\n simulationData?.nativeBalanceChange?.newBalance !==\n previousSimulationData?.nativeBalanceChange?.newBalance ||\n simulationData?.nativeBalanceChange?.previousBalance !==\n previousSimulationData?.nativeBalanceChange?.previousBalance ||\n simulationData?.nativeBalanceChange?.isDecrease !==\n previousSimulationData?.nativeBalanceChange?.isDecrease\n ) {\n return true;\n }\n\n // check the token balance changes\n if (\n simulationData?.tokenBalanceChanges.length !==\n previousSimulationData?.tokenBalanceChanges.length ||\n simulationData?.tokenBalanceChanges.some(\n (tokenBalanceChange, index) =>\n tokenBalanceChange.difference !==\n previousSimulationData?.tokenBalanceChanges[index].difference,\n )\n ) {\n return true;\n }\n\n // check the isUpdatedAfterSecurityCheck\n return (\n simulationData?.isUpdatedAfterSecurityCheck !==\n previousSimulationData?.isUpdatedAfterSecurityCheck\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ShieldController.mjs","sourceRoot":"","sources":["../src/ShieldController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,OAAO,EACL,sBAAsB,EAGvB,uCAAuC;AACxC,OAAO,EACL,iBAAiB,EAGlB,yCAAyC;AAE1C,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAC7C,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,qBAAiB;AAG7D,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;AAuBlE;;;;GAIG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO;QACL,eAAe,EAAE,EAAE;QACnB,yBAAyB,EAAE,EAAE;KAC9B,CAAC;AACJ,CAAC;AAoDD;;;GAGG;AACH,MAAM,QAAQ,GAAG;IACf,eAAe,EAAE;QACf,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,IAAI;KACf;IACD,yBAAyB,EAAE;QACzB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,KAAK;KAChB;CACF,CAAC;AAUF,MAAM,OAAO,gBAAiB,SAAQ,cAIrC;IAmBC,YAAY,OAAgC;QAC1C,MAAM,EACJ,SAAS,EACT,KAAK,EACL,OAAO,EACP,uBAAuB,GAAG,GAAG,EAC7B,oBAAoB,GAAG,EAAE,GAC1B,GAAG,OAAO,CAAC;QACZ,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,QAAQ;YACR,SAAS;YACT,KAAK,EAAE;gBACL,GAAG,+BAA+B,EAAE;gBACpC,GAAG,KAAK;aACT;SACF,CAAC,CAAC;;QAlCI,4CAAwB;QAExB,yDAA8B;QAE9B,4DAAiC;QAEjC,4EAGC;QAED,0EAGC;QAEV,4CAAkB;QAoBhB,uBAAA,IAAI,6BAAY,OAAO,MAAA,CAAC;QACxB,uBAAA,IAAI,0CAAyB,oBAAoB,MAAA,CAAC;QAClD,uBAAA,IAAI,6CAA4B,uBAAuB,MAAA,CAAC;QACxD,uBAAA,IAAI,6DACF,uBAAA,IAAI,6FAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAA,CAAC;QAC1D,uBAAA,IAAI,2DACF,uBAAA,IAAI,2FAAsC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAA,CAAC;QACxD,uBAAA,IAAI,6BAAY,KAAK,MAAA,CAAC;IACxB,CAAC;IAED,KAAK;QACH,IAAI,uBAAA,IAAI,iCAAS,EAAE;YACjB,OAAO;SACR;QACD,uBAAA,IAAI,6BAAY,IAAI,MAAA,CAAC;QAErB,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,mCAAmC,EACnC,uBAAA,IAAI,iEAAyC,EAC7C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAC9B,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,iCAAiC,EACjC,uBAAA,IAAI,+DAAuC,EAC3C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,CACnC,CAAC;IACJ,CAAC;IAED,IAAI;QACF,IAAI,CAAC,uBAAA,IAAI,iCAAS,EAAE;YAClB,OAAO;SACR;QACD,uBAAA,IAAI,6BAAY,KAAK,MAAA,CAAC;QAEtB,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,mCAAmC,EACnC,uBAAA,IAAI,iEAAyC,CAC9C,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,WAAW,CAC9B,iCAAiC,EACjC,uBAAA,IAAI,+DAAuC,CAC5C,CAAC;IACJ,CAAC;IA6ED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,MAAuB;QACzC,iBAAiB;QACjB,MAAM,UAAU,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,MAAM,cAAc,GAAG,MAAM,uBAAA,IAAI,iCAAS,CAAC,aAAa,CAAC;YACvD,MAAM;YACN,UAAU;SACX,CAAC,CAAC;QAEH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,GAAG,cAAc,yBAAyB,EAC1C,cAAc,CACf,CAAC;QAEF,eAAe;QACf,uBAAA,IAAI,wEAAmB,MAAvB,IAAI,EAAoB,MAAM,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAEnD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,sBAAsB,CAC1B,gBAAkC;QAElC,iBAAiB;QACjB,MAAM,UAAU,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAClE,MAAM,cAAc,GAAG,MAAM,uBAAA,IAAI,iCAAS,CAAC,sBAAsB,CAAC;YAChE,gBAAgB;YAChB,UAAU;SACX,CAAC,CAAC;QAEH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,GAAG,cAAc,yBAAyB,EAC1C,cAAc,CACf,CAAC;QAEF,eAAe;QACf,uBAAA,IAAI,wEAAmB,MAAvB,IAAI,EAAoB,gBAAgB,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAE7D,OAAO,cAAc,CAAC;IACxB,CAAC;CAwJF;mgBAtRG,iBAAmD,EACnD,yBAAuE;IAEvE,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChE,MAAM,8BAA8B,GAAG,MAAM,CAAC,MAAM,CAClD,yBAAyB,IAAI,EAAE,CAChC,CAAC;IACF,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAC3C,8BAA8B,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CACvE,CAAC;IACF,KAAK,MAAM,gBAAgB,IAAI,sBAAsB,EAAE;QACrD,MAAM,wBAAwB,GAAG,6BAA6B,CAAC,GAAG,CAChE,gBAAgB,CAAC,EAAE,CACpB,CAAC;QAEF,8DAA8D;QAC9D,mBAAmB;QACnB,IAAI,CAAC,wBAAwB,EAAE;YAC7B,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC,KAAK;YACjD,uBAAuB;YACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAClD,CAAC;SACH;QAED,+DAA+D;QAC/D,IACE,gBAAgB,CAAC,MAAM,KAAK,sBAAsB,CAAC,MAAM;YACzD,gBAAgB,CAAC,MAAM,KAAK,wBAAwB,EAAE,MAAM,EAC5D;YACA,uBAAA,IAAI,mEAAc,MAAlB,IAAI,EAAe,gBAAgB,CAAC,CAAC,KAAK;YACxC,uBAAuB;YACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAClD,CAAC;SACH;KACF;AACH,CAAC,+HAGC,YAA+B,EAC/B,oBAAmD;IAEnD,MAAM,wBAAwB,GAAG,IAAI,GAAG,CACtC,oBAAoB,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CACrD,CAAC;IACF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE;QACtC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACzE,4CAA4C;QAC5C,MAAM,qBAAqB,GAAG,uBAAA,IAAI,uFAAkC,MAAtC,IAAI,EAChC,WAAW,CAAC,cAAc,EAC1B,mBAAmB,EAAE,cAAc,CACpC,CAAC;QAEF,yEAAyE;QACzE,WAAW;QACX,IAAI,CAAC,mBAAmB,IAAI,qBAAqB,EAAE;YACjD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK;YACnC,uBAAuB;YACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAClD,CAAC;SACH;QAED,8CAA8C;QAC9C,IACE,WAAW,CAAC,MAAM,KAAK,iBAAiB,CAAC,SAAS;YAClD,WAAW,CAAC,MAAM,KAAK,mBAAmB,EAAE,MAAM,EAClD;YACA,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,WAAW,CAAC,CAAC,KAAK;YACrC,uBAAuB;YACvB,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,4BAA4B,EAAE,KAAK,CAAC,CACpD,CAAC;SACH;KACF;AACH,CAAC,qFAwDkB,IAAY,EAAE,cAA8B;IAC7D,wCAAwC;IACxC,MAAM,gBAAgB,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,IAAI,CAAC,CAAC;IACzD,IAAI,gBAAgB,IAAI,cAAc,CAAC,UAAU,KAAK,gBAAgB,EAAE;QACtE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;KAC5C;IAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACpB,+BAA+B;QAC/B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,mBAAmB,GAAG,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAEtD,iCAAiC;QACjC,IAAI,CAAC,mBAAmB,EAAE;YACxB,QAAQ,GAAG,IAAI,CAAC;YAChB,mBAAmB,GAAG;gBACpB,OAAO,EAAE,EAAE;aACZ,CAAC;YACF,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC;SACnD;QAED,sCAAsC;QACtC,IAAI,mBAAmB,CAAC,OAAO,CAAC,MAAM,IAAI,uBAAA,IAAI,8CAAsB,EAAE;YACpE,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;SACnC;QAED,kBAAkB;QAClB,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEpD,+BAA+B;QAC/B,MAAM,EAAE,yBAAyB,EAAE,GAAG,KAAK,CAAC;QAC5C,IAAI,WAA+B,CAAC;QACpC,IAAI,QAAQ,EAAE;YACZ,yCAAyC;YACzC,IAAI,yBAAyB,CAAC,MAAM,IAAI,uBAAA,IAAI,iDAAyB,EAAE;gBACrE,WAAW,GAAG,yBAAyB,CAAC,GAAG,EAAE,CAAC;gBAC9C,8CAA8C;gBAC9C,IAAI,WAAW,EAAE;oBACf,OAAO,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;iBAC3C;aACF;YACD,kBAAkB;YAClB,yBAAyB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SACzC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,mCAED,KAAK,yCAAe,gBAAkC;IACpD,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAC1C,IAAI,CAAC,SAAS,EAAE;QACd,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;KACxC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,uBAAA,IAAI,wEAAmB,MAAvB,IAAI,EAAoB,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAEhE,MAAM,uBAAA,IAAI,iCAAS,CAAC,YAAY,CAAC;QAC/B,gBAAgB;QAChB,SAAS;QACT,MAAM;KACP,CAAC,CAAC;AACL,CAAC,qCAED,KAAK,2CAAiB,MAAuB;IAC3C,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC;IACpC,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;KAC/C;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,uBAAA,IAAI,wEAAmB,MAAvB,IAAI,EAAoB,MAAM,CAAC,EAAE,CAAC,CAAC;IAEtD,MAAM,uBAAA,IAAI,iCAAS,CAAC,cAAc,CAAC;QACjC,MAAM;QACN,eAAe;QACf,MAAM;KACP,CAAC,CAAC;AACL,CAAC,qFAEkB,MAAc;IAC/B,qCAAqC;IACrC,gCAAgC;IAChC,0CAA0C;IAC1C,MAAM,UAAU,GAAG,uBAAA,IAAI,0EAAqB,MAAzB,IAAI,EAAsB,MAAM,CAAC,CAAC;IACrD,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,IAAI,CAAC,UAAU,EAAE;QACf,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,GAAG,WAAW,CAAC;KACtB;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC,yFAEoB,MAAc;IACjC,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;AACpE,CAAC,mHAUC,cAAkD,EAClD,sBAA0D;IAE1D,IAAI,CAAC,cAAc,IAAI,CAAC,sBAAsB,EAAE;QAC9C,OAAO,KAAK,CAAC;KACd;IAED,6BAA6B;IAC7B,IACE,cAAc,EAAE,KAAK,EAAE,IAAI,KAAK,sBAAsB,EAAE,KAAK,EAAE,IAAI;QACnE,cAAc,EAAE,KAAK,EAAE,OAAO,KAAK,sBAAsB,EAAE,KAAK,EAAE,OAAO,EACzE;QACA,OAAO,IAAI,CAAC;KACb;IAED,kCAAkC;IAClC,IACE,cAAc,EAAE,mBAAmB,EAAE,UAAU;QAC7C,sBAAsB,EAAE,mBAAmB,EAAE,UAAU;QACzD,cAAc,EAAE,mBAAmB,EAAE,UAAU;YAC7C,sBAAsB,EAAE,mBAAmB,EAAE,UAAU;QACzD,cAAc,EAAE,mBAAmB,EAAE,eAAe;YAClD,sBAAsB,EAAE,mBAAmB,EAAE,eAAe;QAC9D,cAAc,EAAE,mBAAmB,EAAE,UAAU;YAC7C,sBAAsB,EAAE,mBAAmB,EAAE,UAAU,EACzD;QACA,OAAO,IAAI,CAAC;KACb;IAED,kCAAkC;IAClC,IACE,cAAc,EAAE,mBAAmB,EAAE,MAAM;QACzC,sBAAsB,EAAE,mBAAmB,EAAE,MAAM;QACrD,cAAc,EAAE,mBAAmB,EAAE,IAAI,CACvC,CAAC,kBAAkB,EAAE,KAAK,EAAE,EAAE,CAC5B,kBAAkB,CAAC,UAAU;YAC7B,sBAAsB,EAAE,mBAAmB,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,CACnE,EACD;QACA,OAAO,IAAI,CAAC;KACb;IAED,wCAAwC;IACxC,OAAO,CACL,cAAc,EAAE,2BAA2B;QAC3C,sBAAsB,EAAE,2BAA2B,CACpD,CAAC;AACJ,CAAC","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\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';\n\nimport { controllerName } from './constants';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { CoverageResult, ShieldBackend } from './types';\n\nconst log = createModuleLogger(projectLogger, 'ShieldController');\n\nexport type CoverageResultRecordEntry = {\n /**\n * History of coverage results, latest first.\n */\n results: CoverageResult[];\n};\n\nexport type ShieldControllerState = {\n /**\n * Coverage results by transaction ID.\n */\n coverageResults: Record<\n string, // txId\n CoverageResultRecordEntry\n >;\n /**\n * List of txIds ordered by time, latest first.\n */\n orderedTransactionHistory: string[];\n};\n\n/**\n * Get the default state for the ShieldController.\n *\n * @returns The default state for the ShieldController.\n */\nexport function getDefaultShieldControllerState(): ShieldControllerState {\n return {\n coverageResults: {},\n orderedTransactionHistory: [],\n };\n}\n\nexport type ShieldControllerCheckCoverageAction = {\n type: `${typeof controllerName}:checkCoverage`;\n handler: ShieldController['checkCoverage'];\n};\n\n/**\n * The internal actions available to the ShieldController.\n */\nexport type ShieldControllerActions = ShieldControllerCheckCoverageAction;\n\nexport type ShieldControllerCoverageResultReceivedEvent = {\n type: `${typeof controllerName}:coverageResultReceived`;\n payload: [coverageResult: CoverageResult];\n};\n\nexport type ShieldControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ShieldControllerState\n>;\n\n/**\n * The internal events available to the ShieldController.\n */\nexport type ShieldControllerEvents =\n | ShieldControllerCoverageResultReceivedEvent\n | ShieldControllerStateChangeEvent;\n\n/**\n * The external actions available to the ShieldController.\n */\ntype AllowedActions = never;\n\n/**\n * The external events available to the ShieldController.\n */\ntype AllowedEvents =\n | SignatureStateChange\n | TransactionControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link ShieldController}.\n */\nexport type ShieldControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n ShieldControllerActions | AllowedActions,\n ShieldControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Metadata for the ShieldController state, describing how to \"anonymize\"\n * the state and which parts should be persisted.\n */\nconst metadata = {\n coverageResults: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n orderedTransactionHistory: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: false,\n },\n};\n\nexport type ShieldControllerOptions = {\n messenger: ShieldControllerMessenger;\n state?: Partial<ShieldControllerState>;\n backend: ShieldBackend;\n transactionHistoryLimit?: number;\n coverageHistoryLimit?: number;\n};\n\nexport class ShieldController extends BaseController<\n typeof controllerName,\n ShieldControllerState,\n ShieldControllerMessenger\n> {\n readonly #backend: ShieldBackend;\n\n readonly #coverageHistoryLimit: number;\n\n readonly #transactionHistoryLimit: number;\n\n readonly #transactionControllerStateChangeHandler: (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => void;\n\n readonly #signatureControllerStateChangeHandler: (\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) => void;\n\n #started: boolean;\n\n constructor(options: ShieldControllerOptions) {\n const {\n messenger,\n state,\n backend,\n transactionHistoryLimit = 100,\n coverageHistoryLimit = 10,\n } = options;\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultShieldControllerState(),\n ...state,\n },\n });\n\n this.#backend = backend;\n this.#coverageHistoryLimit = coverageHistoryLimit;\n this.#transactionHistoryLimit = transactionHistoryLimit;\n this.#transactionControllerStateChangeHandler =\n this.#handleTransactionControllerStateChange.bind(this);\n this.#signatureControllerStateChangeHandler =\n this.#handleSignatureControllerStateChange.bind(this);\n this.#started = false;\n }\n\n start() {\n if (this.#started) {\n return;\n }\n this.#started = true;\n\n this.messagingSystem.subscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n (state) => state.transactions,\n );\n\n this.messagingSystem.subscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n (state) => state.signatureRequests,\n );\n }\n\n stop() {\n if (!this.#started) {\n return;\n }\n this.#started = false;\n\n this.messagingSystem.unsubscribe(\n 'TransactionController:stateChange',\n this.#transactionControllerStateChangeHandler,\n );\n\n this.messagingSystem.unsubscribe(\n 'SignatureController:stateChange',\n this.#signatureControllerStateChangeHandler,\n );\n }\n\n #handleSignatureControllerStateChange(\n signatureRequests: Record<string, SignatureRequest>,\n previousSignatureRequests: Record<string, SignatureRequest> | undefined,\n ) {\n const signatureRequestsArray = Object.values(signatureRequests);\n const previousSignatureRequestsArray = Object.values(\n previousSignatureRequests ?? {},\n );\n const previousSignatureRequestsById = new Map<string, SignatureRequest>(\n previousSignatureRequestsArray.map((request) => [request.id, request]),\n );\n for (const signatureRequest of signatureRequestsArray) {\n const previousSignatureRequest = previousSignatureRequestsById.get(\n signatureRequest.id,\n );\n\n // Check coverage if the signature request is new and has type\n // `personal_sign`.\n if (!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 // Check if the simulation data has changed.\n const simulationDataChanged = this.#compareTransactionSimulationData(\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.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(txMeta.id, coverageResult);\n\n return coverageResult;\n }\n\n /**\n * Checks the coverage of a signature request.\n *\n * @param signatureRequest - The signature request to check coverage for.\n * @returns The coverage result.\n */\n async checkSignatureCoverage(\n signatureRequest: SignatureRequest,\n ): Promise<CoverageResult> {\n // Check coverage\n const coverageId = this.#getLatestCoverageId(signatureRequest.id);\n const coverageResult = await this.#backend.checkSignatureCoverage({\n signatureRequest,\n coverageId,\n });\n\n // Publish coverage result\n this.messagingSystem.publish(\n `${controllerName}:coverageResultReceived`,\n coverageResult,\n );\n\n // Update state\n this.#addCoverageResult(signatureRequest.id, coverageResult);\n\n return coverageResult;\n }\n\n #addCoverageResult(txId: string, coverageResult: CoverageResult) {\n // 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 /**\n * Compares the simulation data of a transaction.\n *\n * @param simulationData - The simulation data of the transaction.\n * @param previousSimulationData - The previous simulation data of the transaction.\n * @returns Whether the simulation data has changed.\n */\n #compareTransactionSimulationData(\n simulationData?: TransactionMeta['simulationData'],\n previousSimulationData?: TransactionMeta['simulationData'],\n ) {\n if (!simulationData && !previousSimulationData) {\n return false;\n }\n\n // check the simulation error\n if (\n simulationData?.error?.code !== previousSimulationData?.error?.code ||\n simulationData?.error?.message !== previousSimulationData?.error?.message\n ) {\n return true;\n }\n\n // check the native balance change\n if (\n simulationData?.nativeBalanceChange?.difference !==\n previousSimulationData?.nativeBalanceChange?.difference ||\n simulationData?.nativeBalanceChange?.newBalance !==\n previousSimulationData?.nativeBalanceChange?.newBalance ||\n simulationData?.nativeBalanceChange?.previousBalance !==\n previousSimulationData?.nativeBalanceChange?.previousBalance ||\n simulationData?.nativeBalanceChange?.isDecrease !==\n previousSimulationData?.nativeBalanceChange?.isDecrease\n ) {\n return true;\n }\n\n // check the token balance changes\n if (\n simulationData?.tokenBalanceChanges?.length !==\n previousSimulationData?.tokenBalanceChanges?.length ||\n simulationData?.tokenBalanceChanges?.some(\n (tokenBalanceChange, index) =>\n tokenBalanceChange.difference !==\n previousSimulationData?.tokenBalanceChanges?.[index]?.difference,\n )\n ) {\n return true;\n }\n\n // check the isUpdatedAfterSecurityCheck\n return (\n simulationData?.isUpdatedAfterSecurityCheck !==\n previousSimulationData?.isUpdatedAfterSecurityCheck\n );\n }\n}\n"]}
|
package/dist/backend.cjs
CHANGED
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _ShieldRemoteBackend_instances, _ShieldRemoteBackend_getAccessToken, _ShieldRemoteBackend_getCoverageResultTimeout, _ShieldRemoteBackend_getCoverageResultPollInterval, _ShieldRemoteBackend_baseUrl, _ShieldRemoteBackend_fetch, _ShieldRemoteBackend_abortController, _ShieldRemoteBackend_initCoverageCheck, _ShieldRemoteBackend_getCoverageResult, _ShieldRemoteBackend_createHeaders;
|
|
13
|
+
var _ShieldRemoteBackend_instances, _ShieldRemoteBackend_getAccessToken, _ShieldRemoteBackend_getCoverageResultTimeout, _ShieldRemoteBackend_getCoverageResultPollInterval, _ShieldRemoteBackend_baseUrl, _ShieldRemoteBackend_fetch, _ShieldRemoteBackend_abortController, _ShieldRemoteBackend_initCoverageCheck, _ShieldRemoteBackend_getCoverageResult, _ShieldRemoteBackend_createHeaders, _ShieldRemoteBackend_abortPendingPollingRequests;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.ShieldRemoteBackend = void 0;
|
|
16
16
|
class ShieldRemoteBackend {
|
|
@@ -72,9 +72,7 @@ class ShieldRemoteBackend {
|
|
|
72
72
|
...initBody,
|
|
73
73
|
};
|
|
74
74
|
// cancel/abort any pending coverage result polling before logging the signature
|
|
75
|
-
|
|
76
|
-
__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").abort();
|
|
77
|
-
}
|
|
75
|
+
__classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_abortPendingPollingRequests).call(this);
|
|
78
76
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/signature/coverage/log`, {
|
|
79
77
|
method: 'POST',
|
|
80
78
|
headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
|
|
@@ -92,9 +90,7 @@ class ShieldRemoteBackend {
|
|
|
92
90
|
...initBody,
|
|
93
91
|
};
|
|
94
92
|
// cancel/abort any pending coverage result polling before logging the transaction
|
|
95
|
-
|
|
96
|
-
__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").abort();
|
|
97
|
-
}
|
|
93
|
+
__classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_abortPendingPollingRequests).call(this);
|
|
98
94
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/transaction/coverage/log`, {
|
|
99
95
|
method: 'POST',
|
|
100
96
|
headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
|
|
@@ -126,13 +122,13 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
|
|
|
126
122
|
const reqBody = {
|
|
127
123
|
coverageId,
|
|
128
124
|
};
|
|
125
|
+
const headers = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this);
|
|
129
126
|
const timeout = configs?.timeout ?? __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultTimeout, "f");
|
|
130
127
|
const pollInterval = configs?.pollInterval ?? __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, "f");
|
|
131
|
-
let
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
while (retryCount < 5 && !abortController.signal.aborted) {
|
|
128
|
+
let shouldContinuePolling = true;
|
|
129
|
+
const poll = async () => {
|
|
130
|
+
// Poll until the coverage result is ready or the abort signal is triggered.
|
|
131
|
+
while (shouldContinuePolling && !abortController.signal.aborted) {
|
|
136
132
|
const startTime = Date.now();
|
|
137
133
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, configs.coverageResultUrl, {
|
|
138
134
|
method: 'POST',
|
|
@@ -141,13 +137,12 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
|
|
|
141
137
|
signal: abortController.signal,
|
|
142
138
|
});
|
|
143
139
|
if (res.status === 200) {
|
|
144
|
-
|
|
140
|
+
shouldContinuePolling = false;
|
|
145
141
|
return (await res.json());
|
|
146
142
|
}
|
|
147
143
|
if (!abortController.signal.aborted) {
|
|
148
144
|
await sleep(pollInterval - (Date.now() - startTime));
|
|
149
145
|
}
|
|
150
|
-
retryCount += 1;
|
|
151
146
|
}
|
|
152
147
|
// The following line will not have an effect as the upper level promise
|
|
153
148
|
// will already be rejected by now.
|
|
@@ -160,6 +155,10 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
|
|
|
160
155
|
'Content-Type': 'application/json',
|
|
161
156
|
Authorization: `Bearer ${accessToken}`,
|
|
162
157
|
};
|
|
158
|
+
}, _ShieldRemoteBackend_abortPendingPollingRequests = function _ShieldRemoteBackend_abortPendingPollingRequests() {
|
|
159
|
+
if (__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f") && !__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").signal.aborted) {
|
|
160
|
+
__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").abort();
|
|
161
|
+
}
|
|
163
162
|
};
|
|
164
163
|
/**
|
|
165
164
|
* Sleep for a specified amount of time.
|
|
@@ -244,7 +243,7 @@ async function withTimeoutAndCancellation(callback, timeout, abortController) {
|
|
|
244
243
|
abortController.signal.addEventListener('abort', abortHandler);
|
|
245
244
|
});
|
|
246
245
|
const result = await Promise.race([
|
|
247
|
-
callback(
|
|
246
|
+
callback(),
|
|
248
247
|
timeOutPromise,
|
|
249
248
|
abortPromise,
|
|
250
249
|
]);
|
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 type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\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: string;\n from: string;\n method: string;\n origin?: string;\n};\n\nexport type InitCoverageCheckResponse = {\n coverageId: string;\n};\n\nexport type GetCoverageResultRequest = {\n coverageId: string;\n};\n\nexport type GetCoverageResultResponse = {\n message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #getCoverageResultTimeout: number;\n\n readonly #getCoverageResultPollInterval: number;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n #abortController: AbortController | undefined;\n\n constructor({\n getAccessToken,\n getCoverageResultTimeout = 5000, // milliseconds\n getCoverageResultPollInterval = 1000, // milliseconds\n baseUrl,\n fetch: fetchFn,\n }: {\n getAccessToken: () => Promise<string>;\n getCoverageResultTimeout?: number;\n getCoverageResultPollInterval?: number;\n baseUrl: string;\n fetch: typeof globalThis.fetch;\n }) {\n this.#getAccessToken = getAccessToken;\n this.#getCoverageResultTimeout = getCoverageResultTimeout;\n this.#getCoverageResultPollInterval = getCoverageResultPollInterval;\n this.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n }\n\n async checkCoverage(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(coverageId, {\n coverageResultUrl: 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(coverageId, {\n coverageResultUrl: 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/abort any pending coverage result polling before logging the signature\n if (this.#abortController && !this.#abortController.signal.aborted) {\n this.#abortController.abort();\n }\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/abort any pending coverage result polling before logging the transaction\n if (this.#abortController && !this.#abortController.signal.aborted) {\n this.#abortController.abort();\n }\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 coverageId: string,\n configs: {\n coverageResultUrl: string;\n timeout?: number;\n pollInterval?: number;\n },\n ): Promise<GetCoverageResultResponse> {\n if (this.#abortController && !this.#abortController.signal.aborted) {\n // cancel the previous ongoing requests/polling before starting a new one\n this.#abortController.abort();\n }\n const abortController = new AbortController();\n this.#abortController = abortController;\n\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const timeout = configs?.timeout ?? this.#getCoverageResultTimeout;\n const pollInterval =\n configs?.pollInterval ?? this.#getCoverageResultPollInterval;\n\n let retryCount = 0;\n const headers = await this.#createHeaders();\n const poll = async (\n _timeoutId: NodeJS.Timeout | null,\n ): Promise<GetCoverageResultResponse> => {\n // The timeoutReached variable is modified in the timeout callback.\n while (retryCount < 5 && !abortController.signal.aborted) {\n const startTime = Date.now();\n const res = await this.#fetch(configs.coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal: abortController.signal,\n });\n if (res.status === 200) {\n retryCount = 5; // setting retryCount to 5 to break the loop\n return (await res.json()) as GetCoverageResultResponse;\n }\n if (!abortController.signal.aborted) {\n await sleep(pollInterval - (Date.now() - startTime));\n }\n retryCount += 1;\n }\n // The following line will not have an effect as the upper level promise\n // will already be rejected by now.\n throw new Error('unexpected error');\n };\n\n return await withTimeoutAndCancellation<GetCoverageResultResponse>(\n poll,\n timeout,\n abortController,\n );\n }\n\n async #createHeaders() {\n const accessToken = await this.#getAccessToken();\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n };\n }\n}\n\n/**\n * Sleep for a specified amount of time.\n *\n * @param ms - The number of milliseconds to sleep.\n * @returns A promise that resolves after the specified amount of time.\n */\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\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 if (typeof signatureRequest.messageParams.data !== 'string') {\n throw new Error('Signature data must be a string');\n }\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data as string,\n from: signatureRequest.messageParams.from,\n method: signatureRequest.type,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Execute a callback with a timeout and cancellation.\n *\n * @param callback - The callback to execute.\n * @param timeout - The timeout in milliseconds.\n * @param abortController - The abort controller.\n * @returns The result of the callback.\n */\nasync function withTimeoutAndCancellation<Type>(\n callback: (timeoutId: NodeJS.Timeout | null) => Promise<Type>,\n timeout: number,\n abortController: AbortController,\n): Promise<Type> {\n let timeoutId: NodeJS.Timeout | null = null;\n let abortHandler: (() => void) | null = null;\n const cleanupFn = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n if (abortHandler) {\n // remove the abort handler since it is no longer needed\n abortController.signal.removeEventListener('abort', abortHandler);\n abortHandler = null;\n }\n };\n\n try {\n const timeOutPromise = new Promise((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error('Timeout waiting for coverage result'));\n }, timeout);\n });\n\n const abortPromise = new Promise((_resolve, reject) => {\n abortHandler = () => {\n reject(new Error('Coverage result polling cancelled'));\n };\n abortController.signal.addEventListener('abort', abortHandler);\n });\n\n const result = await Promise.race([\n callback(timeoutId),\n timeOutPromise,\n abortPromise,\n ]);\n cleanupFn();\n return result as Type;\n } catch (error) {\n cleanupFn();\n throw error;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"backend.cjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\nimport type {\n 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: string;\n from: string;\n method: string;\n origin?: string;\n};\n\nexport type InitCoverageCheckResponse = {\n coverageId: string;\n};\n\nexport type GetCoverageResultRequest = {\n coverageId: string;\n};\n\nexport type GetCoverageResultResponse = {\n message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #getCoverageResultTimeout: number;\n\n readonly #getCoverageResultPollInterval: number;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n #abortController: AbortController | undefined;\n\n constructor({\n getAccessToken,\n getCoverageResultTimeout = 5000, // milliseconds\n getCoverageResultPollInterval = 1000, // milliseconds\n baseUrl,\n fetch: fetchFn,\n }: {\n getAccessToken: () => Promise<string>;\n getCoverageResultTimeout?: number;\n getCoverageResultPollInterval?: number;\n baseUrl: string;\n fetch: typeof globalThis.fetch;\n }) {\n this.#getAccessToken = getAccessToken;\n this.#getCoverageResultTimeout = getCoverageResultTimeout;\n this.#getCoverageResultPollInterval = getCoverageResultPollInterval;\n this.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n }\n\n async checkCoverage(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(coverageId, {\n coverageResultUrl: 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(coverageId, {\n coverageResultUrl: 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/abort any pending coverage result polling before logging the signature\n this.#abortPendingPollingRequests();\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/abort any pending coverage result polling before logging the transaction\n this.#abortPendingPollingRequests();\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 coverageId: string,\n configs: {\n coverageResultUrl: string;\n timeout?: number;\n pollInterval?: number;\n },\n ): Promise<GetCoverageResultResponse> {\n if (this.#abortController && !this.#abortController.signal.aborted) {\n // cancel the previous ongoing requests/polling before starting a new one\n this.#abortController.abort();\n }\n const abortController = new AbortController();\n this.#abortController = abortController;\n\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n const timeout = configs?.timeout ?? this.#getCoverageResultTimeout;\n const pollInterval =\n configs?.pollInterval ?? this.#getCoverageResultPollInterval;\n\n let shouldContinuePolling = true;\n const poll = async (): Promise<GetCoverageResultResponse> => {\n // Poll until the coverage result is ready or the abort signal is triggered.\n while (shouldContinuePolling && !abortController.signal.aborted) {\n const startTime = Date.now();\n const res = await this.#fetch(configs.coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal: abortController.signal,\n });\n if (res.status === 200) {\n shouldContinuePolling = false;\n return (await res.json()) as GetCoverageResultResponse;\n }\n if (!abortController.signal.aborted) {\n await sleep(pollInterval - (Date.now() - startTime));\n }\n }\n // The following line will not have an effect as the upper level promise\n // will already be rejected by now.\n throw new Error('unexpected error');\n };\n\n return await withTimeoutAndCancellation<GetCoverageResultResponse>(\n poll,\n timeout,\n abortController,\n );\n }\n\n async #createHeaders() {\n const accessToken = await this.#getAccessToken();\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n };\n }\n\n #abortPendingPollingRequests() {\n if (this.#abortController && !this.#abortController.signal.aborted) {\n this.#abortController.abort();\n }\n }\n}\n\n/**\n * Sleep for a specified amount of time.\n *\n * @param ms - The number of milliseconds to sleep.\n * @returns A promise that resolves after the specified amount of time.\n */\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\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 if (typeof signatureRequest.messageParams.data !== 'string') {\n throw new Error('Signature data must be a string');\n }\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data as string,\n from: signatureRequest.messageParams.from,\n method: signatureRequest.type,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Execute a callback with a timeout and cancellation.\n *\n * @param callback - The callback to execute.\n * @param timeout - The timeout in milliseconds.\n * @param abortController - The abort controller.\n * @returns The result of the callback.\n */\nasync function withTimeoutAndCancellation<Type>(\n callback: () => Promise<Type>,\n timeout: number,\n abortController: AbortController,\n): Promise<Type> {\n let timeoutId: NodeJS.Timeout | null = null;\n let abortHandler: (() => void) | null = null;\n const cleanupFn = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n if (abortHandler) {\n // remove the abort handler since it is no longer needed\n abortController.signal.removeEventListener('abort', abortHandler);\n abortHandler = null;\n }\n };\n\n try {\n const timeOutPromise = new Promise((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error('Timeout waiting for coverage result'));\n }, timeout);\n });\n\n const abortPromise = new Promise((_resolve, reject) => {\n abortHandler = () => {\n reject(new Error('Coverage result polling cancelled'));\n };\n abortController.signal.addEventListener('abort', abortHandler);\n });\n\n const result = await Promise.race([\n callback(),\n timeOutPromise,\n abortPromise,\n ]);\n cleanupFn();\n return result as Type;\n } catch (error) {\n cleanupFn();\n throw error;\n }\n}\n"]}
|
package/dist/backend.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.cts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAGA,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,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAa3C,EACV,cAAc,EACd,wBAA+B,EAAE,eAAe;IAChD,6BAAoC,EAAE,eAAe;IACrD,OAAO,EACP,KAAK,EAAE,OAAO,GACf,EAAE;QACD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QACvC,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQK,aAAa,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBjE,sBAAsB,CAC1B,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,cAAc,CAAC;IAsBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"backend.d.cts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAGA,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,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAa3C,EACV,cAAc,EACd,wBAA+B,EAAE,eAAe;IAChD,6BAAoC,EAAE,eAAe;IACrD,OAAO,EACP,KAAK,EAAE,OAAO,GACf,EAAE;QACD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QACvC,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQK,aAAa,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBjE,sBAAsB,CAC1B,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,cAAc,CAAC;IAsBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBrD,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CA2GhE"}
|
package/dist/backend.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.mts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAGA,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,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAa3C,EACV,cAAc,EACd,wBAA+B,EAAE,eAAe;IAChD,6BAAoC,EAAE,eAAe;IACrD,OAAO,EACP,KAAK,EAAE,OAAO,GACf,EAAE;QACD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QACvC,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQK,aAAa,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBjE,sBAAsB,CAC1B,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,cAAc,CAAC;IAsBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"backend.d.mts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAGA,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,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,qBAAa,mBAAoB,YAAW,aAAa;;gBAa3C,EACV,cAAc,EACd,wBAA+B,EAAE,eAAe;IAChD,6BAAoC,EAAE,eAAe;IACrD,OAAO,EACP,KAAK,EAAE,OAAO,GACf,EAAE;QACD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,6BAA6B,CAAC,EAAE,MAAM,CAAC;QACvC,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;KAChC;IAQK,aAAa,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBjE,sBAAsB,CAC1B,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,cAAc,CAAC;IAsBpB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBrD,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CA2GhE"}
|
package/dist/backend.mjs
CHANGED
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _ShieldRemoteBackend_instances, _ShieldRemoteBackend_getAccessToken, _ShieldRemoteBackend_getCoverageResultTimeout, _ShieldRemoteBackend_getCoverageResultPollInterval, _ShieldRemoteBackend_baseUrl, _ShieldRemoteBackend_fetch, _ShieldRemoteBackend_abortController, _ShieldRemoteBackend_initCoverageCheck, _ShieldRemoteBackend_getCoverageResult, _ShieldRemoteBackend_createHeaders;
|
|
12
|
+
var _ShieldRemoteBackend_instances, _ShieldRemoteBackend_getAccessToken, _ShieldRemoteBackend_getCoverageResultTimeout, _ShieldRemoteBackend_getCoverageResultPollInterval, _ShieldRemoteBackend_baseUrl, _ShieldRemoteBackend_fetch, _ShieldRemoteBackend_abortController, _ShieldRemoteBackend_initCoverageCheck, _ShieldRemoteBackend_getCoverageResult, _ShieldRemoteBackend_createHeaders, _ShieldRemoteBackend_abortPendingPollingRequests;
|
|
13
13
|
export class ShieldRemoteBackend {
|
|
14
14
|
constructor({ getAccessToken, getCoverageResultTimeout = 5000, // milliseconds
|
|
15
15
|
getCoverageResultPollInterval = 1000, // milliseconds
|
|
@@ -69,9 +69,7 @@ export class ShieldRemoteBackend {
|
|
|
69
69
|
...initBody,
|
|
70
70
|
};
|
|
71
71
|
// cancel/abort any pending coverage result polling before logging the signature
|
|
72
|
-
|
|
73
|
-
__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").abort();
|
|
74
|
-
}
|
|
72
|
+
__classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_abortPendingPollingRequests).call(this);
|
|
75
73
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/signature/coverage/log`, {
|
|
76
74
|
method: 'POST',
|
|
77
75
|
headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
|
|
@@ -89,9 +87,7 @@ export class ShieldRemoteBackend {
|
|
|
89
87
|
...initBody,
|
|
90
88
|
};
|
|
91
89
|
// cancel/abort any pending coverage result polling before logging the transaction
|
|
92
|
-
|
|
93
|
-
__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").abort();
|
|
94
|
-
}
|
|
90
|
+
__classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_abortPendingPollingRequests).call(this);
|
|
95
91
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, `${__classPrivateFieldGet(this, _ShieldRemoteBackend_baseUrl, "f")}/v1/transaction/coverage/log`, {
|
|
96
92
|
method: 'POST',
|
|
97
93
|
headers: await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this),
|
|
@@ -122,13 +118,13 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
|
|
|
122
118
|
const reqBody = {
|
|
123
119
|
coverageId,
|
|
124
120
|
};
|
|
121
|
+
const headers = await __classPrivateFieldGet(this, _ShieldRemoteBackend_instances, "m", _ShieldRemoteBackend_createHeaders).call(this);
|
|
125
122
|
const timeout = configs?.timeout ?? __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultTimeout, "f");
|
|
126
123
|
const pollInterval = configs?.pollInterval ?? __classPrivateFieldGet(this, _ShieldRemoteBackend_getCoverageResultPollInterval, "f");
|
|
127
|
-
let
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
while (retryCount < 5 && !abortController.signal.aborted) {
|
|
124
|
+
let shouldContinuePolling = true;
|
|
125
|
+
const poll = async () => {
|
|
126
|
+
// Poll until the coverage result is ready or the abort signal is triggered.
|
|
127
|
+
while (shouldContinuePolling && !abortController.signal.aborted) {
|
|
132
128
|
const startTime = Date.now();
|
|
133
129
|
const res = await __classPrivateFieldGet(this, _ShieldRemoteBackend_fetch, "f").call(this, configs.coverageResultUrl, {
|
|
134
130
|
method: 'POST',
|
|
@@ -137,13 +133,12 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
|
|
|
137
133
|
signal: abortController.signal,
|
|
138
134
|
});
|
|
139
135
|
if (res.status === 200) {
|
|
140
|
-
|
|
136
|
+
shouldContinuePolling = false;
|
|
141
137
|
return (await res.json());
|
|
142
138
|
}
|
|
143
139
|
if (!abortController.signal.aborted) {
|
|
144
140
|
await sleep(pollInterval - (Date.now() - startTime));
|
|
145
141
|
}
|
|
146
|
-
retryCount += 1;
|
|
147
142
|
}
|
|
148
143
|
// The following line will not have an effect as the upper level promise
|
|
149
144
|
// will already be rejected by now.
|
|
@@ -156,6 +151,10 @@ _ShieldRemoteBackend_getAccessToken = new WeakMap(), _ShieldRemoteBackend_getCov
|
|
|
156
151
|
'Content-Type': 'application/json',
|
|
157
152
|
Authorization: `Bearer ${accessToken}`,
|
|
158
153
|
};
|
|
154
|
+
}, _ShieldRemoteBackend_abortPendingPollingRequests = function _ShieldRemoteBackend_abortPendingPollingRequests() {
|
|
155
|
+
if (__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f") && !__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").signal.aborted) {
|
|
156
|
+
__classPrivateFieldGet(this, _ShieldRemoteBackend_abortController, "f").abort();
|
|
157
|
+
}
|
|
159
158
|
};
|
|
160
159
|
/**
|
|
161
160
|
* Sleep for a specified amount of time.
|
|
@@ -240,7 +239,7 @@ async function withTimeoutAndCancellation(callback, timeout, abortController) {
|
|
|
240
239
|
abortController.signal.addEventListener('abort', abortHandler);
|
|
241
240
|
});
|
|
242
241
|
const result = await Promise.race([
|
|
243
|
-
callback(
|
|
242
|
+
callback(),
|
|
244
243
|
timeOutPromise,
|
|
245
244
|
abortPromise,
|
|
246
245
|
]);
|
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 type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\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: string;\n from: string;\n method: string;\n origin?: string;\n};\n\nexport type InitCoverageCheckResponse = {\n coverageId: string;\n};\n\nexport type GetCoverageResultRequest = {\n coverageId: string;\n};\n\nexport type GetCoverageResultResponse = {\n message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #getCoverageResultTimeout: number;\n\n readonly #getCoverageResultPollInterval: number;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n #abortController: AbortController | undefined;\n\n constructor({\n getAccessToken,\n getCoverageResultTimeout = 5000, // milliseconds\n getCoverageResultPollInterval = 1000, // milliseconds\n baseUrl,\n fetch: fetchFn,\n }: {\n getAccessToken: () => Promise<string>;\n getCoverageResultTimeout?: number;\n getCoverageResultPollInterval?: number;\n baseUrl: string;\n fetch: typeof globalThis.fetch;\n }) {\n this.#getAccessToken = getAccessToken;\n this.#getCoverageResultTimeout = getCoverageResultTimeout;\n this.#getCoverageResultPollInterval = getCoverageResultPollInterval;\n this.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n }\n\n async checkCoverage(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(coverageId, {\n coverageResultUrl: 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(coverageId, {\n coverageResultUrl: 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/abort any pending coverage result polling before logging the signature\n if (this.#abortController && !this.#abortController.signal.aborted) {\n this.#abortController.abort();\n }\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/abort any pending coverage result polling before logging the transaction\n if (this.#abortController && !this.#abortController.signal.aborted) {\n this.#abortController.abort();\n }\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 coverageId: string,\n configs: {\n coverageResultUrl: string;\n timeout?: number;\n pollInterval?: number;\n },\n ): Promise<GetCoverageResultResponse> {\n if (this.#abortController && !this.#abortController.signal.aborted) {\n // cancel the previous ongoing requests/polling before starting a new one\n this.#abortController.abort();\n }\n const abortController = new AbortController();\n this.#abortController = abortController;\n\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const timeout = configs?.timeout ?? this.#getCoverageResultTimeout;\n const pollInterval =\n configs?.pollInterval ?? this.#getCoverageResultPollInterval;\n\n let retryCount = 0;\n const headers = await this.#createHeaders();\n const poll = async (\n _timeoutId: NodeJS.Timeout | null,\n ): Promise<GetCoverageResultResponse> => {\n // The timeoutReached variable is modified in the timeout callback.\n while (retryCount < 5 && !abortController.signal.aborted) {\n const startTime = Date.now();\n const res = await this.#fetch(configs.coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal: abortController.signal,\n });\n if (res.status === 200) {\n retryCount = 5; // setting retryCount to 5 to break the loop\n return (await res.json()) as GetCoverageResultResponse;\n }\n if (!abortController.signal.aborted) {\n await sleep(pollInterval - (Date.now() - startTime));\n }\n retryCount += 1;\n }\n // The following line will not have an effect as the upper level promise\n // will already be rejected by now.\n throw new Error('unexpected error');\n };\n\n return await withTimeoutAndCancellation<GetCoverageResultResponse>(\n poll,\n timeout,\n abortController,\n );\n }\n\n async #createHeaders() {\n const accessToken = await this.#getAccessToken();\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n };\n }\n}\n\n/**\n * Sleep for a specified amount of time.\n *\n * @param ms - The number of milliseconds to sleep.\n * @returns A promise that resolves after the specified amount of time.\n */\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\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 if (typeof signatureRequest.messageParams.data !== 'string') {\n throw new Error('Signature data must be a string');\n }\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data as string,\n from: signatureRequest.messageParams.from,\n method: signatureRequest.type,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Execute a callback with a timeout and cancellation.\n *\n * @param callback - The callback to execute.\n * @param timeout - The timeout in milliseconds.\n * @param abortController - The abort controller.\n * @returns The result of the callback.\n */\nasync function withTimeoutAndCancellation<Type>(\n callback: (timeoutId: NodeJS.Timeout | null) => Promise<Type>,\n timeout: number,\n abortController: AbortController,\n): Promise<Type> {\n let timeoutId: NodeJS.Timeout | null = null;\n let abortHandler: (() => void) | null = null;\n const cleanupFn = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n if (abortHandler) {\n // remove the abort handler since it is no longer needed\n abortController.signal.removeEventListener('abort', abortHandler);\n abortHandler = null;\n }\n };\n\n try {\n const timeOutPromise = new Promise((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error('Timeout waiting for coverage result'));\n }, timeout);\n });\n\n const abortPromise = new Promise((_resolve, reject) => {\n abortHandler = () => {\n reject(new Error('Coverage result polling cancelled'));\n };\n abortController.signal.addEventListener('abort', abortHandler);\n });\n\n const result = await Promise.race([\n callback(timeoutId),\n timeOutPromise,\n abortPromise,\n ]);\n cleanupFn();\n return result as Type;\n } catch (error) {\n cleanupFn();\n throw error;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"backend.mjs","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignatureRequest } from '@metamask/signature-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\n\nimport type {\n 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: string;\n from: string;\n method: string;\n origin?: string;\n};\n\nexport type InitCoverageCheckResponse = {\n coverageId: string;\n};\n\nexport type GetCoverageResultRequest = {\n coverageId: string;\n};\n\nexport type GetCoverageResultResponse = {\n message?: string;\n reasonCode?: string;\n status: CoverageStatus;\n};\n\nexport class ShieldRemoteBackend implements ShieldBackend {\n readonly #getAccessToken: () => Promise<string>;\n\n readonly #getCoverageResultTimeout: number;\n\n readonly #getCoverageResultPollInterval: number;\n\n readonly #baseUrl: string;\n\n readonly #fetch: typeof globalThis.fetch;\n\n #abortController: AbortController | undefined;\n\n constructor({\n getAccessToken,\n getCoverageResultTimeout = 5000, // milliseconds\n getCoverageResultPollInterval = 1000, // milliseconds\n baseUrl,\n fetch: fetchFn,\n }: {\n getAccessToken: () => Promise<string>;\n getCoverageResultTimeout?: number;\n getCoverageResultPollInterval?: number;\n baseUrl: string;\n fetch: typeof globalThis.fetch;\n }) {\n this.#getAccessToken = getAccessToken;\n this.#getCoverageResultTimeout = getCoverageResultTimeout;\n this.#getCoverageResultPollInterval = getCoverageResultPollInterval;\n this.#baseUrl = baseUrl;\n this.#fetch = fetchFn;\n }\n\n async checkCoverage(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(coverageId, {\n coverageResultUrl: 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(coverageId, {\n coverageResultUrl: 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/abort any pending coverage result polling before logging the signature\n this.#abortPendingPollingRequests();\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/abort any pending coverage result polling before logging the transaction\n this.#abortPendingPollingRequests();\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 coverageId: string,\n configs: {\n coverageResultUrl: string;\n timeout?: number;\n pollInterval?: number;\n },\n ): Promise<GetCoverageResultResponse> {\n if (this.#abortController && !this.#abortController.signal.aborted) {\n // cancel the previous ongoing requests/polling before starting a new one\n this.#abortController.abort();\n }\n const abortController = new AbortController();\n this.#abortController = abortController;\n\n const reqBody: GetCoverageResultRequest = {\n coverageId,\n };\n\n const headers = await this.#createHeaders();\n const timeout = configs?.timeout ?? this.#getCoverageResultTimeout;\n const pollInterval =\n configs?.pollInterval ?? this.#getCoverageResultPollInterval;\n\n let shouldContinuePolling = true;\n const poll = async (): Promise<GetCoverageResultResponse> => {\n // Poll until the coverage result is ready or the abort signal is triggered.\n while (shouldContinuePolling && !abortController.signal.aborted) {\n const startTime = Date.now();\n const res = await this.#fetch(configs.coverageResultUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(reqBody),\n signal: abortController.signal,\n });\n if (res.status === 200) {\n shouldContinuePolling = false;\n return (await res.json()) as GetCoverageResultResponse;\n }\n if (!abortController.signal.aborted) {\n await sleep(pollInterval - (Date.now() - startTime));\n }\n }\n // The following line will not have an effect as the upper level promise\n // will already be rejected by now.\n throw new Error('unexpected error');\n };\n\n return await withTimeoutAndCancellation<GetCoverageResultResponse>(\n poll,\n timeout,\n abortController,\n );\n }\n\n async #createHeaders() {\n const accessToken = await this.#getAccessToken();\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n };\n }\n\n #abortPendingPollingRequests() {\n if (this.#abortController && !this.#abortController.signal.aborted) {\n this.#abortController.abort();\n }\n }\n}\n\n/**\n * Sleep for a specified amount of time.\n *\n * @param ms - The number of milliseconds to sleep.\n * @returns A promise that resolves after the specified amount of time.\n */\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\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 if (typeof signatureRequest.messageParams.data !== 'string') {\n throw new Error('Signature data must be a string');\n }\n\n return {\n chainId: signatureRequest.chainId,\n data: signatureRequest.messageParams.data as string,\n from: signatureRequest.messageParams.from,\n method: signatureRequest.type,\n origin: signatureRequest.messageParams.origin,\n };\n}\n\n/**\n * Execute a callback with a timeout and cancellation.\n *\n * @param callback - The callback to execute.\n * @param timeout - The timeout in milliseconds.\n * @param abortController - The abort controller.\n * @returns The result of the callback.\n */\nasync function withTimeoutAndCancellation<Type>(\n callback: () => Promise<Type>,\n timeout: number,\n abortController: AbortController,\n): Promise<Type> {\n let timeoutId: NodeJS.Timeout | null = null;\n let abortHandler: (() => void) | null = null;\n const cleanupFn = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n if (abortHandler) {\n // remove the abort handler since it is no longer needed\n abortController.signal.removeEventListener('abort', abortHandler);\n abortHandler = null;\n }\n };\n\n try {\n const timeOutPromise = new Promise((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error('Timeout waiting for coverage result'));\n }, timeout);\n });\n\n const abortPromise = new Promise((_resolve, reject) => {\n abortHandler = () => {\n reject(new Error('Coverage result polling cancelled'));\n };\n abortController.signal.addEventListener('abort', abortHandler);\n });\n\n const result = await Promise.race([\n callback(),\n timeOutPromise,\n abortPromise,\n ]);\n cleanupFn();\n return result as Type;\n } catch (error) {\n cleanupFn();\n throw error;\n }\n}\n"]}
|