diff --git a/packages/accounts-controller/package.json b/packages/accounts-controller/package.json index 37e1ef375c..07e90d9af7 100644 --- a/packages/accounts-controller/package.json +++ b/packages/accounts-controller/package.json @@ -41,7 +41,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@metamask/keyring-controller": "^8.1.0", "@metamask/snaps-controllers": "^3.2.0", "@types/jest": "^27.4.1", diff --git a/packages/address-book-controller/package.json b/packages/address-book-controller/package.json index 6c693162db..3d12e67146 100644 --- a/packages/address-book-controller/package.json +++ b/packages/address-book-controller/package.json @@ -35,7 +35,7 @@ "@metamask/utils": "^8.2.0" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/announcement-controller/package.json b/packages/announcement-controller/package.json index 79d05074f8..6880aca19f 100644 --- a/packages/announcement-controller/package.json +++ b/packages/announcement-controller/package.json @@ -33,7 +33,7 @@ "@metamask/base-controller": "^3.2.3" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "immer": "^9.0.6", diff --git a/packages/approval-controller/package.json b/packages/approval-controller/package.json index e5d5f64787..c437f32cbb 100644 --- a/packages/approval-controller/package.json +++ b/packages/approval-controller/package.json @@ -37,7 +37,7 @@ "nanoid": "^3.1.31" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/assets-controllers/package.json b/packages/assets-controllers/package.json index 92c25b05eb..7dff4139b7 100644 --- a/packages/assets-controllers/package.json +++ b/packages/assets-controllers/package.json @@ -55,7 +55,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "@types/node": "^16.18.54", "deepmerge": "^4.2.2", diff --git a/packages/base-controller/package.json b/packages/base-controller/package.json index 3c3583b52d..1197743585 100644 --- a/packages/base-controller/package.json +++ b/packages/base-controller/package.json @@ -34,7 +34,7 @@ "immer": "^9.0.6" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "@types/sinon": "^9.0.10", "deepmerge": "^4.2.2", diff --git a/packages/composable-controller/package.json b/packages/composable-controller/package.json index 6d608f52b3..0006b03970 100644 --- a/packages/composable-controller/package.json +++ b/packages/composable-controller/package.json @@ -33,7 +33,7 @@ "@metamask/base-controller": "^3.2.3" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "immer": "^9.0.6", diff --git a/packages/controller-utils/package.json b/packages/controller-utils/package.json index d4a2025072..f1b3874c9b 100644 --- a/packages/controller-utils/package.json +++ b/packages/controller-utils/package.json @@ -38,7 +38,7 @@ "fast-deep-equal": "^3.1.3" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@metamask/eth-query": "^3.0.1", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", diff --git a/packages/ens-controller/package.json b/packages/ens-controller/package.json index 580c4b6d85..09a7555dbc 100644 --- a/packages/ens-controller/package.json +++ b/packages/ens-controller/package.json @@ -39,7 +39,7 @@ "punycode": "^2.1.1" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/eth-json-rpc-provider/package.json b/packages/eth-json-rpc-provider/package.json index d95c11c82e..6fa70d70f0 100644 --- a/packages/eth-json-rpc-provider/package.json +++ b/packages/eth-json-rpc-provider/package.json @@ -42,7 +42,7 @@ "@metamask/utils": "^8.2.0" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "depcheck": "^1.4.3", diff --git a/packages/gas-fee-controller/package.json b/packages/gas-fee-controller/package.json index 04a54622ff..1530380ca3 100644 --- a/packages/gas-fee-controller/package.json +++ b/packages/gas-fee-controller/package.json @@ -43,7 +43,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "@types/jest-when": "^2.7.3", "deepmerge": "^4.2.2", diff --git a/packages/json-rpc-engine/README.md b/packages/json-rpc-engine/README.md index 30b804cd2f..f4ce817972 100644 --- a/packages/json-rpc-engine/README.md +++ b/packages/json-rpc-engine/README.md @@ -2,6 +2,14 @@ A tool for processing JSON-RPC requests and responses. +## Installation + +`yarn add @metamask/json-rpc-engine` + +or + +`npm install @metamask/json-rpc-engine` + ## Usage ```js @@ -191,14 +199,6 @@ engine.push(function (req, res, next, end) { }); ``` -## Running tests +## Contributing -Build the project if not already built: - -```bash -yarn build -``` - -```bash -yarn test -``` +This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme). diff --git a/packages/json-rpc-engine/package.json b/packages/json-rpc-engine/package.json index 537fb27011..3cc933ecbc 100644 --- a/packages/json-rpc-engine/package.json +++ b/packages/json-rpc-engine/package.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@lavamoat/allow-scripts": "^2.3.1", - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "depcheck": "^1.4.3", diff --git a/packages/keyring-controller/package.json b/packages/keyring-controller/package.json index cd1347811a..59e923ac23 100644 --- a/packages/keyring-controller/package.json +++ b/packages/keyring-controller/package.json @@ -45,7 +45,7 @@ "@ethereumjs/common": "^3.2.0", "@ethereumjs/tx": "^4.2.0", "@keystonehq/bc-ur-registry-eth": "^0.9.0", - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@metamask/eth-sig-util": "^7.0.0", "@metamask/scure-bip39": "^2.1.0", "@types/jest": "^27.4.1", diff --git a/packages/logging-controller/package.json b/packages/logging-controller/package.json index 95b9e88a8b..bfc80f1e58 100644 --- a/packages/logging-controller/package.json +++ b/packages/logging-controller/package.json @@ -35,7 +35,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/message-manager/package.json b/packages/message-manager/package.json index a7bd13a14b..ae05fc7caf 100644 --- a/packages/message-manager/package.json +++ b/packages/message-manager/package.json @@ -40,7 +40,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/name-controller/package.json b/packages/name-controller/package.json index f672187dfb..40a2e1f4f0 100644 --- a/packages/name-controller/package.json +++ b/packages/name-controller/package.json @@ -37,7 +37,7 @@ "immer": "^9.0.6" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/network-controller/package.json b/packages/network-controller/package.json index 5e382bb474..c63382ac7f 100644 --- a/packages/network-controller/package.json +++ b/packages/network-controller/package.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@json-rpc-specification/meta-schema": "^1.0.6", - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "@types/jest-when": "^2.7.3", "@types/lodash": "^4.14.191", diff --git a/packages/notification-controller/package.json b/packages/notification-controller/package.json index 1a3fdff4e8..f5e1a09902 100644 --- a/packages/notification-controller/package.json +++ b/packages/notification-controller/package.json @@ -36,7 +36,7 @@ "nanoid": "^3.1.31" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/permission-controller/package.json b/packages/permission-controller/package.json index 27355fc786..6a588f3e27 100644 --- a/packages/permission-controller/package.json +++ b/packages/permission-controller/package.json @@ -42,7 +42,7 @@ "nanoid": "^3.1.31" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/phishing-controller/package.json b/packages/phishing-controller/package.json index 7fb314dd83..f74cf3c47e 100644 --- a/packages/phishing-controller/package.json +++ b/packages/phishing-controller/package.json @@ -37,7 +37,7 @@ "punycode": "^2.1.1" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/polling-controller/package.json b/packages/polling-controller/package.json index 288a9277e3..d5279b6d67 100644 --- a/packages/polling-controller/package.json +++ b/packages/polling-controller/package.json @@ -39,7 +39,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/preferences-controller/package.json b/packages/preferences-controller/package.json index 7e6cc1816e..1ba9e98799 100644 --- a/packages/preferences-controller/package.json +++ b/packages/preferences-controller/package.json @@ -34,7 +34,7 @@ "@metamask/controller-utils": "^5.0.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/queued-request-controller/package.json b/packages/queued-request-controller/package.json index 966a9abcb2..ca1dfc1f71 100644 --- a/packages/queued-request-controller/package.json +++ b/packages/queued-request-controller/package.json @@ -41,7 +41,7 @@ }, "devDependencies": { "@metamask/approval-controller": "^4.1.0", - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "immer": "^9.0.6", diff --git a/packages/rate-limit-controller/package.json b/packages/rate-limit-controller/package.json index c656723518..e84032b647 100644 --- a/packages/rate-limit-controller/package.json +++ b/packages/rate-limit-controller/package.json @@ -35,7 +35,7 @@ "immer": "^9.0.6" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", diff --git a/packages/selected-network-controller/package.json b/packages/selected-network-controller/package.json index b3a7596fcf..a77a24c455 100644 --- a/packages/selected-network-controller/package.json +++ b/packages/selected-network-controller/package.json @@ -36,7 +36,7 @@ "@metamask/swappable-obj-proxy": "^2.1.0" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "immer": "^9.0.6", diff --git a/packages/signature-controller/package.json b/packages/signature-controller/package.json index 06ebcfcbb9..f7ea0560b0 100644 --- a/packages/signature-controller/package.json +++ b/packages/signature-controller/package.json @@ -42,7 +42,7 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@metamask/keyring-controller": "^8.1.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", diff --git a/packages/transaction-controller/jest.config.js b/packages/transaction-controller/jest.config.js index 93b4dc3fa7..c4759f83db 100644 --- a/packages/transaction-controller/jest.config.js +++ b/packages/transaction-controller/jest.config.js @@ -17,7 +17,7 @@ module.exports = merge(baseConfig, { // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { - branches: 88.5, + branches: 88.48, functions: 94, lines: 98.5, statements: 98, diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index 8353842472..1b9d2c9aac 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -51,7 +51,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/auto-changelog": "^3.4.2", + "@metamask/auto-changelog": "^3.4.3", "@types/jest": "^27.4.1", "@types/node": "^16.18.54", "babel-runtime": "^6.26.0", diff --git a/packages/transaction-controller/src/TransactionController.test.ts b/packages/transaction-controller/src/TransactionController.test.ts index 0c481f0316..29e0b4f334 100644 --- a/packages/transaction-controller/src/TransactionController.test.ts +++ b/packages/transaction-controller/src/TransactionController.test.ts @@ -37,6 +37,7 @@ import type { DappSuggestedGasFees, TransactionParams, TransactionHistoryEntry, + TransactionError, } from './types'; import { TransactionStatus, TransactionType, WalletDevice } from './types'; import { estimateGas, updateGas } from './utils/gas'; @@ -721,7 +722,7 @@ describe('TransactionController', () => { code: errorCodes.provider.userRejectedRequest, }; }); - const consoleSpy = jest.spyOn(console, 'error'); + const consoleSpy = jest.spyOn(console, 'error').mockImplementation(); newController({ state: mockedControllerState as any, @@ -865,6 +866,9 @@ describe('TransactionController', () => { return Promise.resolve(); }); + // Second gas update will fail, in order to keep the console clean during test mock console.error once + jest.spyOn(console, 'error').mockImplementation(); + const controller = newController({ state: mockedControllerState as any, }); @@ -1672,7 +1676,9 @@ describe('TransactionController', () => { const finishedPromise = waitForTransactionFinished(controller); - await expect(result).rejects.toThrow('User rejected the transaction'); + await expect(result).rejects.toThrow( + 'MetaMask Tx Signature: User denied transaction signature.', + ); const { txParams, status } = await finishedPromise; expect(txParams.from).toBe(ACCOUNT_MOCK); @@ -2741,7 +2747,7 @@ describe('TransactionController', () => { mockSendFlowHistory, ), ) - .toThrow(`Can only call updateTransactionSendFlowHistory on an unapproved transaction. + .toThrow(`TransactionsController: Can only call updateTransactionSendFlowHistory on an unapproved transaction. Current tx status: submitted`); }); }); @@ -2924,19 +2930,18 @@ describe('TransactionController', () => { controller.updateTransactionGasFees(transactionId, { gasPrice: '0x1', }), - ).toThrow(`Can only call ${fnName} on an unapproved transaction. + ) + .toThrow(`TransactionsController: Can only call ${fnName} on an unapproved transaction. Current tx status: ${status}`); }); - it('updates provided gas values', async () => { + it('updates provided legacy gas values', async () => { const transactionId = '123'; const controller = newController(); const gas = '0xgas'; const gasLimit = '0xgasLimit'; const gasPrice = '0xgasPrice'; - const maxPriorityFeePerGas = '0xmaxPriorityFeePerGas'; - const maxFeePerGas = '0xmaxFeePerGas'; const estimateUsed = '0xestimateUsed'; const estimateSuggested = '0xestimateSuggested'; const defaultGasEstimates = '0xdefaultGasEstimates'; @@ -2963,8 +2968,6 @@ describe('TransactionController', () => { gas, gasLimit, gasPrice, - maxPriorityFeePerGas, - maxFeePerGas, estimateUsed, estimateSuggested, defaultGasEstimates, @@ -2973,15 +2976,13 @@ describe('TransactionController', () => { userFeeLevel, }); - const transaction = controller.state.transactions[0]; + const transaction = controller.state.transactions.find( + ({ id }) => id === transactionId, + ); expect(transaction?.txParams?.gas).toBe(gas); expect(transaction?.txParams?.gasLimit).toBe(gasLimit); expect(transaction?.txParams?.gasPrice).toBe(gasPrice); - expect(transaction?.txParams?.maxPriorityFeePerGas).toBe( - maxPriorityFeePerGas, - ); - expect(transaction?.txParams?.maxFeePerGas).toBe(maxFeePerGas); expect(transaction?.estimateUsed).toBe(estimateUsed); expect(transaction?.estimateSuggested).toBe(estimateSuggested); expect(transaction?.defaultGasEstimates).toBe(defaultGasEstimates); @@ -2989,6 +2990,45 @@ describe('TransactionController', () => { expect(transaction?.userEditedGasLimit).toBe(userEditedGasLimit); expect(transaction?.userFeeLevel).toBe(userFeeLevel); }); + + it('updates provided 1559 gas values', async () => { + const maxPriorityFeePerGas = '0xmaxPriorityFeePerGas'; + const maxFeePerGas = '0xmaxFeePerGas'; + const transactionId = '123'; + + const controller = newController(); + + controller.state.transactions.push({ + id: transactionId, + chainId: '0x1', + time: 123456789, + status: TransactionStatus.unapproved as const, + history: [ + {} as TransactionMeta, + ...([{}] as TransactionHistoryEntry[]), + ], + txParams: { + from: ACCOUNT_MOCK, + to: ACCOUNT_2_MOCK, + }, + }); + + controller.updateTransactionGasFees(transactionId, { + maxPriorityFeePerGas, + maxFeePerGas, + }); + + const txToBeUpdatedWithoutGasPrice = controller.state.transactions.find( + ({ id }) => id === transactionId, + ); + + expect(txToBeUpdatedWithoutGasPrice?.txParams?.maxPriorityFeePerGas).toBe( + maxPriorityFeePerGas, + ); + expect(txToBeUpdatedWithoutGasPrice?.txParams?.maxFeePerGas).toBe( + maxFeePerGas, + ); + }); }); describe('updatePreviousGasParams', () => { @@ -3014,7 +3054,8 @@ describe('TransactionController', () => { controller.updatePreviousGasParams(transactionId, { maxFeePerGas: '0x1', }), - ).toThrow(`Can only call ${fnName} on an unapproved transaction. + ) + .toThrow(`TransactionsController: Can only call ${fnName} on an unapproved transaction. Current tx status: ${status}`); }); @@ -3105,19 +3146,28 @@ describe('TransactionController', () => { options: { disableHistory: true }, }); + const errorMock = new Error('TestError'); + const expectedTransactionError: TransactionError = { + message: errorMock.message, + name: errorMock.name, + stack: errorMock.stack, + code: undefined, + rpc: undefined, + }; + controller.state.transactions = [{ ...TRANSACTION_META_MOCK }]; firePendingTransactionTrackerEvent( 'transaction-failed', TRANSACTION_META_MOCK, - new Error('TestError'), + errorMock, ); expect(controller.state.transactions).toStrictEqual([ { ...TRANSACTION_META_MOCK, status: TransactionStatus.failed, - error: new Error('TestError'), + error: expectedTransactionError, }, ]); }); diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index b31fb2ee18..e9092ae6fe 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -80,6 +80,7 @@ import { validateGasValues, validateIfTransactionUnapproved, validateMinimumIncrease, + normalizeTxError, } from './utils/utils'; import { validateTransactionOrigin, @@ -257,7 +258,7 @@ export class TransactionController extends BaseController< ) { const newTransactionMeta = { ...transactionMeta, - error, + error: normalizeTxError(error), status: TransactionStatus.failed, }; this.hub.emit('transaction-failed', { @@ -1535,7 +1536,7 @@ export class TransactionController extends BaseController< this.cancelTransaction(transactionId, actionId); throw providerErrors.userRejectedRequest( - 'User rejected the transaction', + 'MetaMask Tx Signature: User denied transaction signature.', ); } else { this.failTransaction(meta, error, actionId); diff --git a/packages/transaction-controller/src/types.ts b/packages/transaction-controller/src/types.ts index 216c441b21..198696ff96 100644 --- a/packages/transaction-controller/src/types.ts +++ b/packages/transaction-controller/src/types.ts @@ -42,7 +42,10 @@ export type Events = { export type TransactionMeta = TransactionMetaBase & ( | { status: Exclude } - | { status: TransactionStatus.failed; error: Error } + | { + status: TransactionStatus.failed; + error: TransactionError; + } ); /** @@ -825,3 +828,33 @@ export type DefaultGasEstimates = { */ maxPriorityFeePerGas?: string; }; + +/** + * Data concerning an error while processing a transaction. + */ +export type TransactionError = { + /** + * A descriptive error name. + */ + name: string; + + /** + * A descriptive error message providing details about the encountered error. + */ + message: string; + + /** + * The stack trace associated with the error, if available. + */ + stack?: string; + + /** + * An optional error code associated with the error. + */ + code?: string; + + /** + * The rpc property holds additional information related to the error. + */ + rpc?: unknown; +}; diff --git a/packages/transaction-controller/src/utils/utils.test.ts b/packages/transaction-controller/src/utils/utils.test.ts index b3ec27aeac..4971618587 100644 --- a/packages/transaction-controller/src/utils/utils.test.ts +++ b/packages/transaction-controller/src/utils/utils.test.ts @@ -239,4 +239,37 @@ describe('utils', () => { expect(result).toStrictEqual(expectedResult); }); }); + + describe('normalizeTxError', () => { + const errorBase = { + name: 'TxError', + message: 'An error occurred', + stack: 'Error stack trace', + }; + it('returns the error object with no code and rpc properties', () => { + const normalizedError = util.normalizeTxError(errorBase); + + expect(normalizedError).toStrictEqual({ + ...errorBase, + code: undefined, + rpc: undefined, + }); + }); + + it('returns the error object with code and rpc properties', () => { + const error = { + ...errorBase, + code: 'ERROR_CODE', + value: { code: 'rpc data' }, + }; + + const normalizedError = util.normalizeTxError(error); + + expect(normalizedError).toStrictEqual({ + ...errorBase, + code: 'ERROR_CODE', + rpc: { code: 'rpc data' }, + }); + }); + }); }); diff --git a/packages/transaction-controller/src/utils/utils.ts b/packages/transaction-controller/src/utils/utils.ts index 05453df70d..1b3f548def 100644 --- a/packages/transaction-controller/src/utils/utils.ts +++ b/packages/transaction-controller/src/utils/utils.ts @@ -8,7 +8,11 @@ import type { FeeMarketEIP1559Values, } from '../TransactionController'; import { TransactionStatus } from '../types'; -import type { TransactionParams, TransactionMeta } from '../types'; +import type { + TransactionParams, + TransactionMeta, + TransactionError, +} from '../types'; export const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error'; @@ -162,8 +166,26 @@ export function validateIfTransactionUnapproved( ) { if (transactionMeta?.status !== TransactionStatus.unapproved) { throw new Error( - `Can only call ${fnName} on an unapproved transaction. + `TransactionsController: Can only call ${fnName} on an unapproved transaction. Current tx status: ${transactionMeta?.status}`, ); } } + +/** + * Normalizes properties on transaction params. + * + * @param error - The error to be normalize. + * @returns Normalized transaction error. + */ +export function normalizeTxError( + error: Error & { code?: string; value?: unknown }, +): TransactionError { + return { + name: error.name, + message: error.message, + stack: error.stack, + code: error?.code, + rpc: error?.value, + }; +} diff --git a/packages/transaction-controller/src/utils/validation.test.ts b/packages/transaction-controller/src/utils/validation.test.ts index 377678c1bc..34a7914263 100644 --- a/packages/transaction-controller/src/utils/validation.test.ts +++ b/packages/transaction-controller/src/utils/validation.test.ts @@ -1,5 +1,6 @@ import { rpcErrors } from '@metamask/rpc-errors'; +import { TransactionEnvelopeType } from '../types'; import { validateTxParams } from './validation'; describe('validation', () => { @@ -11,24 +12,20 @@ describe('validation', () => { it('should throw if no from address', () => { expect(() => validateTxParams({} as any)).toThrow( rpcErrors.invalidParams( - 'Invalid "from" address: undefined must be a valid string.', + 'Invalid "from" address undefined: not a string.', ), ); }); it('should throw if non-string from address', () => { expect(() => validateTxParams({ from: 1337 } as any)).toThrow( - rpcErrors.invalidParams( - 'Invalid "from" address: 1337 must be a valid string.', - ), + rpcErrors.invalidParams('Invalid "from" address 1337: not a string.'), ); }); it('should throw if invalid from address', () => { expect(() => validateTxParams({ from: '1337' } as any)).toThrow( - rpcErrors.invalidParams( - 'Invalid "from" address: 1337 must be a valid string.', - ), + rpcErrors.invalidParams('Invalid "from" address.'), ); }); @@ -38,21 +35,13 @@ describe('validation', () => { from: '0x3244e191f1b4903970224322180f1fbbc415696b', to: '0x', } as any), - ).toThrow( - rpcErrors.invalidParams( - 'Invalid "to" address: 0x must be a valid string.', - ), - ); + ).toThrow(rpcErrors.invalidParams('Invalid "to" address.')); expect(() => validateTxParams({ from: '0x3244e191f1b4903970224322180f1fbbc415696b', } as any), - ).toThrow( - rpcErrors.invalidParams( - 'Invalid "to" address: undefined must be a valid string.', - ), - ); + ).toThrow(rpcErrors.invalidParams('Invalid "to" address.')); }); it('should delete data', () => { @@ -71,11 +60,7 @@ describe('validation', () => { from: '0x3244e191f1b4903970224322180f1fbbc415696b', to: '1337', } as any), - ).toThrow( - rpcErrors.invalidParams( - 'Invalid "to" address: 1337 must be a valid string.', - ), - ); + ).toThrow(rpcErrors.invalidParams('Invalid "to" address.')); }); it('should throw if value is invalid', () => { @@ -87,7 +72,7 @@ describe('validation', () => { } as any), ).toThrow( rpcErrors.invalidParams( - 'Invalid "value": 133-7 is not a positive number.', + 'Invalid transaction value "133-7": not a positive number.', ), ); @@ -99,7 +84,7 @@ describe('validation', () => { } as any), ).toThrow( rpcErrors.invalidParams( - 'Invalid "value": 133.7 number must be denominated in wei.', + 'Invalid transaction value "133.7": number must be in wei.', ), ); @@ -111,7 +96,7 @@ describe('validation', () => { } as any), ).toThrow( rpcErrors.invalidParams( - 'Invalid "value": hello number must be a valid number.', + 'Invalid transaction value hello: number must be a valid number.', ), ); @@ -123,7 +108,7 @@ describe('validation', () => { } as any), ).toThrow( rpcErrors.invalidParams( - 'Invalid "value": one million dollar$ number must be a valid number.', + 'Invalid transaction value one million dollar$: number must be a valid number.', ), ); @@ -187,5 +172,139 @@ describe('validation', () => { } as any), ).not.toThrow(); }); + + describe('gas fees', () => { + it('throws if gasPrice is defined but type is feeMarket', () => { + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + gasPrice: '0x01', + type: TransactionEnvelopeType.feeMarket, + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction envelope type: specified type "0x2" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas', + ), + ); + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + gasPrice: '0x01', + } as any), + ).not.toThrow(); + }); + + it('throws if gasPrice is defined along with maxFeePerGas or maxPriorityFeePerGas', () => { + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + gasPrice: '0x01', + maxFeePerGas: '0x01', + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction params: specified gasPrice but also included maxFeePerGas, these cannot be mixed', + ), + ); + + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + gasPrice: '0x01', + maxPriorityFeePerGas: '0x01', + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction params: specified gasPrice but also included maxPriorityFeePerGas, these cannot be mixed', + ), + ); + }); + + it('throws if gasPrice, maxPriorityFeePerGas or maxFeePerGas is not string', () => { + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + gasPrice: 1, + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction params: gasPrice is not a string. got: (1)', + ), + ); + + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + maxPriorityFeePerGas: 1, + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction params: maxPriorityFeePerGas is not a string. got: (1)', + ), + ); + + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + maxFeePerGas: 1, + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction params: maxFeePerGas is not a string. got: (1)', + ), + ); + }); + + it('throws if maxPriorityFeePerGas is defined but type is not feeMarket', () => { + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + maxPriorityFeePerGas: '0x01', + type: TransactionEnvelopeType.accessList, + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction envelope type: specified type "0x1" but including maxFeePerGas and maxPriorityFeePerGas requires type: "0x2"', + ), + ); + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + maxPriorityFeePerGas: '0x01', + } as any), + ).not.toThrow(); + }); + + it('throws if maxFeePerGas is defined but type is not feeMarket', () => { + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + maxFeePerGas: '0x01', + type: TransactionEnvelopeType.accessList, + } as any), + ).toThrow( + rpcErrors.invalidParams( + 'Invalid transaction envelope type: specified type "0x1" but including maxFeePerGas and maxPriorityFeePerGas requires type: "0x2"', + ), + ); + expect(() => + validateTxParams({ + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + to: '0xfbb5595c18ca76bab52d66188e4ca50c7d95f77a', + maxFeePerGas: '0x01', + } as any), + ).not.toThrow(); + }); + }); }); }); diff --git a/packages/transaction-controller/src/utils/validation.ts b/packages/transaction-controller/src/utils/validation.ts index 4e0e3770ba..84b2eed48e 100644 --- a/packages/transaction-controller/src/utils/validation.ts +++ b/packages/transaction-controller/src/utils/validation.ts @@ -3,9 +3,11 @@ import { ORIGIN_METAMASK, isValidHexAddress } from '@metamask/controller-utils'; import { abiERC20 } from '@metamask/metamask-eth-abis'; import { providerErrors, rpcErrors } from '@metamask/rpc-errors'; -import type { TransactionParams } from '../types'; +import { TransactionEnvelopeType, type TransactionParams } from '../types'; import { isEIP1559Transaction } from './utils'; +type GasFieldsToValidate = 'gasPrice' | 'maxFeePerGas' | 'maxPriorityFeePerGas'; + /** * Validates whether a transaction initiated by a specific 'from' address is permitted by the origin. * @@ -59,6 +61,7 @@ export function validateTxParams( validateParamValue(txParams.value); validateParamData(txParams.data); validateParamChainId(txParams.chainId); + validateGasFeeParams(txParams); } /** @@ -94,13 +97,13 @@ function validateParamValue(value?: string) { if (value !== undefined) { if (value.includes('-')) { throw rpcErrors.invalidParams( - `Invalid "value": ${value} is not a positive number.`, + `Invalid transaction value "${value}": not a positive number.`, ); } if (value.includes('.')) { throw rpcErrors.invalidParams( - `Invalid "value": ${value} number must be denominated in wei.`, + `Invalid transaction value "${value}": number must be in wei.`, ); } const intValue = parseInt(value, 10); @@ -111,7 +114,7 @@ function validateParamValue(value?: string) { Number.isSafeInteger(intValue); if (!isValid) { throw rpcErrors.invalidParams( - `Invalid "value": ${value} number must be a valid number.`, + `Invalid transaction value ${value}: number must be a valid number.`, ); } } @@ -131,14 +134,10 @@ function validateParamRecipient(txParams: TransactionParams) { if (txParams.data) { delete txParams.to; } else { - throw new Error( - `Invalid "to" address: ${txParams.to} must be a valid string.`, - ); + throw rpcErrors.invalidParams(`Invalid "to" address.`); } } else if (txParams.to !== undefined && !isValidHexAddress(txParams.to)) { - throw new Error( - `Invalid "to" address: ${txParams.to} must be a valid string.`, - ); + throw rpcErrors.invalidParams(`Invalid "to" address.`); } } @@ -152,8 +151,13 @@ function validateParamRecipient(txParams: TransactionParams) { * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown. */ function validateParamFrom(from: string) { - if (!from || typeof from !== 'string' || !isValidHexAddress(from)) { - throw new Error(`Invalid "from" address: ${from} must be a valid string.`); + if (!from || typeof from !== 'string') { + throw rpcErrors.invalidParams( + `Invalid "from" address ${from}: not a string.`, + ); + } + if (!isValidHexAddress(from)) { + throw rpcErrors.invalidParams('Invalid "from" address.'); } } @@ -194,3 +198,128 @@ function validateParamChainId(chainId: number | string | undefined) { ); } } + +/** + * Validates gas values. + * + * @param txParams - The transaction parameters to validate. + */ +function validateGasFeeParams(txParams: TransactionParams) { + if (txParams.gasPrice) { + ensureProperTransactionEnvelopeTypeProvided(txParams, 'gasPrice'); + ensureMutuallyExclusiveFieldsNotProvided( + txParams, + 'gasPrice', + 'maxFeePerGas', + ); + ensureMutuallyExclusiveFieldsNotProvided( + txParams, + 'gasPrice', + 'maxPriorityFeePerGas', + ); + ensureFieldIsString(txParams, 'gasPrice'); + } + + if (txParams.maxFeePerGas) { + ensureProperTransactionEnvelopeTypeProvided(txParams, 'maxFeePerGas'); + ensureMutuallyExclusiveFieldsNotProvided( + txParams, + 'maxFeePerGas', + 'gasPrice', + ); + ensureFieldIsString(txParams, 'maxFeePerGas'); + } + + if (txParams.maxPriorityFeePerGas) { + ensureProperTransactionEnvelopeTypeProvided( + txParams, + 'maxPriorityFeePerGas', + ); + ensureMutuallyExclusiveFieldsNotProvided( + txParams, + 'maxPriorityFeePerGas', + 'gasPrice', + ); + ensureFieldIsString(txParams, 'maxPriorityFeePerGas'); + } +} + +/** + * Ensures that the provided txParams has the proper 'type' specified for the + * given field, if it is provided. If types do not match throws an + * invalidParams error. + * + * @param txParams - The transaction parameters object + * @param field - The current field being validated + * @throws {ethErrors.rpc.invalidParams} Throws if type does not match the + * expectations for provided field. + */ +function ensureProperTransactionEnvelopeTypeProvided( + txParams: TransactionParams, + field: GasFieldsToValidate, +) { + switch (field) { + case 'maxFeePerGas': + case 'maxPriorityFeePerGas': + if ( + txParams.type && + txParams.type !== TransactionEnvelopeType.feeMarket + ) { + throw rpcErrors.invalidParams( + `Invalid transaction envelope type: specified type "${txParams.type}" but including maxFeePerGas and maxPriorityFeePerGas requires type: "${TransactionEnvelopeType.feeMarket}"`, + ); + } + break; + case 'gasPrice': + default: + if ( + txParams.type && + txParams.type === TransactionEnvelopeType.feeMarket + ) { + throw rpcErrors.invalidParams( + `Invalid transaction envelope type: specified type "${txParams.type}" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas`, + ); + } + } +} + +/** + * Given two fields, ensure that the second field is not included in txParams, + * and if it is throw an invalidParams error. + * + * @param txParams - The transaction parameters object + * @param fieldBeingValidated - The current field being validated + * @param mutuallyExclusiveField - The field to ensure is not provided + * @throws {ethErrors.rpc.invalidParams} Throws if mutuallyExclusiveField is + * present in txParams. + */ +function ensureMutuallyExclusiveFieldsNotProvided( + txParams: TransactionParams, + fieldBeingValidated: GasFieldsToValidate, + mutuallyExclusiveField: GasFieldsToValidate, +) { + if (typeof txParams[mutuallyExclusiveField] !== 'undefined') { + throw rpcErrors.invalidParams( + `Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`, + ); + } +} + +/** + * Ensures that the provided value for field is a string, throws an + * invalidParams error if field is not a string. + * + * @param txParams - The transaction parameters object + * @param field - The current field being validated + * @throws {rpcErrors.invalidParams} Throws if field is not a string + */ +function ensureFieldIsString( + txParams: TransactionParams, + field: GasFieldsToValidate, +) { + if (typeof txParams[field] !== 'string') { + throw rpcErrors.invalidParams( + `Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`, + ); + } +} diff --git a/yarn.lock b/yarn.lock index b9832bf921..ad0dc54026 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1369,7 +1369,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/accounts-controller@workspace:packages/accounts-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/eth-snap-keyring": ^2.0.0 "@metamask/keyring-api": ^1.1.0 @@ -1408,7 +1408,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/address-book-controller@workspace:packages/address-book-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/utils": ^8.2.0 @@ -1426,7 +1426,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/announcement-controller@workspace:packages/announcement-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 @@ -1443,7 +1443,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/approval-controller@workspace:packages/approval-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/rpc-errors": ^6.1.0 "@metamask/utils": ^8.2.0 @@ -1470,7 +1470,7 @@ __metadata: "@ethersproject/providers": ^5.7.0 "@metamask/abi-utils": ^2.0.2 "@metamask/approval-controller": ^4.1.0 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/contract-metadata": ^2.4.0 "@metamask/controller-utils": ^5.0.2 @@ -1507,9 +1507,9 @@ __metadata: languageName: unknown linkType: soft -"@metamask/auto-changelog@npm:^3.4.2": - version: 3.4.2 - resolution: "@metamask/auto-changelog@npm:3.4.2" +"@metamask/auto-changelog@npm:^3.4.3": + version: 3.4.3 + resolution: "@metamask/auto-changelog@npm:3.4.3" dependencies: diff: ^5.0.0 execa: ^5.1.1 @@ -1518,7 +1518,7 @@ __metadata: yargs: ^17.0.1 bin: auto-changelog: dist/cli.js - checksum: b922db20b3ff8a1957b71128d481c08fdf5ae465a89a03bccacf31cba227e56e48f6b1654ff4c78150cc0cfd3ae57a615d3ab5ab6760f7437e0b9e8aa6aec390 + checksum: 3405f1f85d02684a95945ab253523619014bdae5da6121fb540140f8b21ddf2dda104683d91a24176c4c67a44fb9446d2e607d94a532a2bbb4f08a08a1e5a605 languageName: node linkType: hard @@ -1526,7 +1526,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/base-controller@workspace:packages/base-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/utils": ^8.2.0 "@types/jest": ^27.4.1 "@types/sinon": ^9.0.10 @@ -1552,7 +1552,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/composable-controller@workspace:packages/composable-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 @@ -1577,7 +1577,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/controller-utils@workspace:packages/controller-utils" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/eth-query": ^3.0.1 "@metamask/utils": ^8.2.0 "@spruceid/siwe-parser": 1.1.3 @@ -1660,7 +1660,7 @@ __metadata: resolution: "@metamask/ens-controller@workspace:packages/ens-controller" dependencies: "@ethersproject/providers": ^5.7.0 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/network-controller": ^15.1.0 @@ -1776,7 +1776,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/eth-json-rpc-provider@workspace:packages/eth-json-rpc-provider" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/json-rpc-engine": ^7.2.0 "@metamask/safe-event-emitter": ^3.0.0 "@metamask/utils": ^8.2.0 @@ -1864,7 +1864,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/gas-fee-controller@workspace:packages/gas-fee-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/eth-query": ^3.0.1 @@ -1897,7 +1897,7 @@ __metadata: resolution: "@metamask/json-rpc-engine@workspace:packages/json-rpc-engine" dependencies: "@lavamoat/allow-scripts": ^2.3.1 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/rpc-errors": ^6.1.0 "@metamask/safe-event-emitter": ^3.0.0 "@metamask/utils": ^8.2.0 @@ -1973,7 +1973,7 @@ __metadata: "@ethereumjs/tx": ^4.2.0 "@keystonehq/bc-ur-registry-eth": ^0.9.0 "@keystonehq/metamask-airgapped-keyring": ^0.13.1 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/eth-keyring-controller": ^14.0.0 "@metamask/eth-sig-util": ^7.0.0 @@ -2003,7 +2003,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/logging-controller@workspace:packages/logging-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@types/jest": ^27.4.1 @@ -2021,7 +2021,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/message-manager@workspace:packages/message-manager" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/eth-sig-util": ^7.0.0 @@ -2051,7 +2051,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/name-controller@workspace:packages/name-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/utils": ^8.2.0 "@types/jest": ^27.4.1 @@ -2071,7 +2071,7 @@ __metadata: resolution: "@metamask/network-controller@workspace:packages/network-controller" dependencies: "@json-rpc-specification/meta-schema": ^1.0.6 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/eth-json-rpc-infura": ^9.0.0 @@ -2106,7 +2106,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/notification-controller@workspace:packages/notification-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/utils": ^8.2.0 "@types/jest": ^27.4.1 @@ -2157,7 +2157,7 @@ __metadata: resolution: "@metamask/permission-controller@workspace:packages/permission-controller" dependencies: "@metamask/approval-controller": ^4.1.0 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/json-rpc-engine": ^7.2.0 @@ -2183,7 +2183,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/phishing-controller@workspace:packages/phishing-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@types/jest": ^27.4.1 @@ -2205,7 +2205,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/polling-controller@workspace:packages/polling-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/network-controller": ^15.1.0 @@ -2240,7 +2240,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/preferences-controller@workspace:packages/preferences-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@types/jest": ^27.4.1 @@ -2277,7 +2277,7 @@ __metadata: resolution: "@metamask/queued-request-controller@workspace:packages/queued-request-controller" dependencies: "@metamask/approval-controller": ^4.1.0 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/json-rpc-engine": ^7.2.0 @@ -2307,7 +2307,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/rate-limit-controller@workspace:packages/rate-limit-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/rpc-errors": ^6.1.0 "@types/jest": ^27.4.1 @@ -2359,7 +2359,7 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/selected-network-controller@workspace:packages/selected-network-controller" dependencies: - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/json-rpc-engine": ^7.2.0 "@metamask/network-controller": ^15.1.0 @@ -2385,7 +2385,7 @@ __metadata: resolution: "@metamask/signature-controller@workspace:packages/signature-controller" dependencies: "@metamask/approval-controller": ^4.1.0 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/keyring-controller": ^8.1.0 @@ -2604,7 +2604,7 @@ __metadata: "@ethereumjs/tx": ^4.2.0 "@ethersproject/abi": ^5.7.0 "@metamask/approval-controller": ^4.1.0 - "@metamask/auto-changelog": ^3.4.2 + "@metamask/auto-changelog": ^3.4.3 "@metamask/base-controller": ^3.2.3 "@metamask/controller-utils": ^5.0.2 "@metamask/eth-query": ^3.0.1