Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 0 additions & 48 deletions .eslintrc.js

This file was deleted.

84 changes: 84 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import base, { createConfig } from '@metamask/eslint-config';
import jest from '@metamask/eslint-config-jest';
import nodejs from '@metamask/eslint-config-nodejs';
import typescript from '@metamask/eslint-config-typescript';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const tsconfigRootDir = path.dirname(fileURLToPath(import.meta.url));

const config = createConfig([
...base,
{
ignores: ['coverage/**', 'dist/**', 'docs/**', '.yarn/**'],
},
{
linterOptions: {
reportUnusedDisableDirectives: 'error',
},
},
{
files: ['**/*.{js,cjs,mjs}', '**/*.test.{js,ts}', '**/tests/**/*.{js,ts}'],
extends: [nodejs],
},
{
files: ['**/*.{js,cjs}'],
languageOptions: {
sourceType: 'script',
ecmaVersion: 2020,
},
},
{
files: ['**/*.mjs'],
languageOptions: {
sourceType: 'module',
},
},
{
files: ['**/*.ts'],
extends: [typescript],
languageOptions: {
parserOptions: {
tsconfigRootDir,
},
},
},
{
files: ['**/*.test.{js,ts}', '**/tests/**/*.{js,ts}'],
extends: [jest],
},
// Project-wide rule overrides — placed AFTER all extends so they win.
{
rules: {
// TODO: Fix jsdoc comments and re-enable these rules.
'jsdoc/check-alignment': 'off',
'jsdoc/check-types': 'off',
'jsdoc/match-description': 'off',
'jsdoc/require-asterisk-prefix': 'off',
'jsdoc/require-description': 'off',
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-param': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/require-returns-description': 'off',
'jsdoc/tag-lines': 'off',
},
},
{
files: ['**/*.ts'],
rules: {
'@typescript-eslint/naming-convention': 'off',
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/prefer-enum-initializers': 'off',
'@typescript-eslint/restrict-template-expressions': 'warn',
'no-restricted-syntax': 'off',
// TODO: Re-enable these rules — they weren't enforced under the
// legacy eslint-config v12 and surfacing them across the codebase
// is out of scope for the v15 migration.
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
},
},
]);

export default config;
33 changes: 17 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"build": "ts-bridge --project tsconfig.build.json --clean",
"lint": "yarn lint:eslint && yarn lint:misc --check && yarn lint:changelog && yarn messenger-action-types:check",
"lint:changelog": "auto-changelog validate --prettier",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:eslint": "eslint . --cache",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write && yarn lint:changelog && yarn messenger-action-types:generate",
"lint:misc": "prettier '**/*.json' '**/*.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern",
"messenger-action-types:check": "messenger-action-types --check",
Expand Down Expand Up @@ -68,38 +68,38 @@
"@arethetypeswrong/cli": "^0.18.2",
"@lavamoat/allow-scripts": "^3.2.1",
"@lavamoat/preinstall-always-fail": "^2.1.0",
"@metamask/auto-changelog": "^3.1.0",
"@metamask/eslint-config": "^12.2.0",
"@metamask/eslint-config-jest": "^12.1.0",
"@metamask/eslint-config-nodejs": "^12.1.0",
"@metamask/eslint-config-typescript": "^12.1.0",
"@metamask/auto-changelog": "^6.1.0",
"@metamask/eslint-config": "^15.0.0",
"@metamask/eslint-config-jest": "^15.0.0",
"@metamask/eslint-config-nodejs": "^15.0.0",
"@metamask/eslint-config-typescript": "^15.0.0",
"@metamask/gas-fee-controller": "^26.2.2",
"@metamask/json-rpc-engine": "^10.5.0",
"@metamask/messenger-cli": "^0.1.0",
"@metamask/messenger-cli": "^0.2.0",
"@ts-bridge/cli": "^0.6.3",
"@types/eslint": "^9.6.1",
"@types/jest": "^26.0.24",
"@types/lodash": "^4.14.194",
"@types/node": "^18.19.17",
"@types/sinon": "^9.0.10",
"@typescript-eslint/eslint-plugin": "^5.33.0",
"@typescript-eslint/parser": "^5.33.0",
"eslint": "^8.48.0",
"eslint": "^9.39.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "~2.26.0",
"eslint-plugin-jest": "^27.1.5",
"eslint-plugin-jsdoc": "^39.2.9",
"eslint-plugin-n": "^15.7.0",
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import-x": "^4.3.0",
"eslint-plugin-jest": "^28.8.3",
"eslint-plugin-jsdoc": "^50.2.4",
"eslint-plugin-n": "^17.10.3",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-promise": "^7.1.0",
"isomorphic-fetch": "^3.0.0",
"jest": "^29.7.0",
"nock": "^14.0.0-beta.7",
"prettier": "^3.3.3",
"prettier-plugin-packagejson": "^2.4.3",
"sinon": "^9.2.4",
"ts-jest": "^29.1.4",
"typescript": "~5.3.3"
"typescript": "~5.3.3",
"typescript-eslint": "^8.39.0"
},
"peerDependenciesMeta": {
"@metamask/accounts-controller": {
Expand All @@ -126,6 +126,7 @@
"lavamoat": {
"allowScripts": {
"@lavamoat/preinstall-always-fail": false,
"eslint-plugin-import-x>unrs-resolver": false,
"@metamask/controller-utils>ethereumjs-util>ethereum-cryptography>keccak": false,
"@metamask/controller-utils>ethereumjs-util>ethereum-cryptography>secp256k1": false,
"@metamask/controller-utils>babel-runtime>core-js": false,
Expand Down
2 changes: 1 addition & 1 deletion setupJest.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// eslint-disable-next-line import/no-unassigned-import
// eslint-disable-next-line import-x/no-unassigned-import
require('isomorphic-fetch');
55 changes: 22 additions & 33 deletions src/SmartTransactionsController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,29 @@ import {
convertHexToDecimal,
ChainId,
} from '@metamask/controller-utils';
import {
Messenger,
MOCK_ANY_NAMESPACE,
type MessengerActions,
type MessengerEvents,
type MockAnyNamespace,
import { Messenger, MOCK_ANY_NAMESPACE } from '@metamask/messenger';
import type {
MessengerActions,
MessengerEvents,
MockAnyNamespace,
} from '@metamask/messenger';
import { NetworkStatus, RpcEndpointType } from '@metamask/network-controller';
import type { NetworkState } from '@metamask/network-controller';
import {
NetworkStatus,
RpcEndpointType,
type NetworkState,
} from '@metamask/network-controller';
TransactionStatus,
TransactionType,
} from '@metamask/transaction-controller';
import type {
TransactionControllerGetNonceLockAction,
TransactionControllerGetTransactionsAction,
TransactionControllerUpdateTransactionAction,
} from '@metamask/transaction-controller';
import {
type TransactionParams,
TransactionStatus,
TransactionType,
} from '@metamask/transaction-controller';
import type { TransactionParams } from '@metamask/transaction-controller';
import type { Hex } from '@metamask/utils';
import nock from 'nock';
import * as sinon from 'sinon';

import packageJson from '../package.json';
import { advanceTime, flushPromises, getFakeProvider } from '../tests/helpers';
import {
API_BASE_URL,
SENTINEL_API_BASE_URL_MAP,
Expand All @@ -41,11 +36,12 @@ import {
DEFAULT_INTERVAL,
SmartTransactionsController,
getDefaultSmartTransactionsControllerState,
type SmartTransactionsControllerMessenger,
} from './SmartTransactionsController';
import type { SmartTransactionsControllerMessenger } from './SmartTransactionsController';
import type { SmartTransaction, UnsignedTransaction } from './types';
import { SmartTransactionStatuses, ClientId } from './types';
import * as utils from './utils';
import { advanceTime, flushPromises, getFakeProvider } from '../tests/helpers';

type AllActions = MessengerActions<SmartTransactionsControllerMessenger>;

Expand All @@ -59,32 +55,27 @@ jest.mock('@metamask/eth-query', () => {
sendAsync = jest.fn(({ method, params }, callback) => {
switch (method) {
case 'eth_getBalance': {
callback(null, '0x1000');
break;
return callback(null, '0x1000');
}

case 'eth_getTransactionReceipt': {
// Return null if txHash is empty/falsy
const txHash = params?.[0];
if (txHash) {
callback(null, { blockNumber: '123' });
} else {
callback(null, null);
return callback(null, { blockNumber: '123' });
}
break;
return callback(null, null);
}

case 'eth_getBlockByNumber': {
callback(null, { baseFeePerGas: '0x123' });
break;
return callback(null, { baseFeePerGas: '0x123' });
}

case 'eth_getTransactionByHash': {
callback(null, {
return callback(null, {
maxFeePerGas: '0x123',
maxPriorityFeePerGas: '0x123',
});
break;
}

default: {
Expand Down Expand Up @@ -322,6 +313,7 @@ const trackMetaMetricsEventSpy = jest.fn();
describe('SmartTransactionsController', () => {
afterEach(async () => {
jest.clearAllMocks();
// eslint-disable-next-line import-x/no-named-as-default-member
nock.cleanAll();
});

Expand Down Expand Up @@ -2369,6 +2361,7 @@ describe('SmartTransactionsController', () => {
let clock: sinon.SinonFakeTimers;

beforeEach(() => {
// eslint-disable-next-line import-x/namespace
clock = sinon.useFakeTimers();
});

Expand Down Expand Up @@ -2819,9 +2812,7 @@ describe('SmartTransactionsController', () => {
},
},
async ({ controller }) => {
controller.updateSmartTransaction(
newSmartTransaction as SmartTransaction,
);
controller.updateSmartTransaction(newSmartTransaction);

// Allow async operations to complete
await flushPromises();
Expand Down Expand Up @@ -2870,9 +2861,7 @@ describe('SmartTransactionsController', () => {
},
},
async ({ controller }) => {
controller.updateSmartTransaction(
newSmartTransaction as SmartTransaction,
);
controller.updateSmartTransaction(newSmartTransaction);

// Allow async operations to complete
await flushPromises();
Expand Down
12 changes: 6 additions & 6 deletions src/SmartTransactionsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
safelyExecute,
ChainId,
isSafeDynamicKey,
type TraceCallback,
} from '@metamask/controller-utils';
import type { TraceCallback } from '@metamask/controller-utils';
import EthQuery from '@metamask/eth-query';
import type { Messenger } from '@metamask/messenger';
import type {
Expand Down Expand Up @@ -272,11 +272,11 @@
> {
#interval: number;

#clientId: ClientId;
readonly #clientId: ClientId;

#chainId: Hex;

#supportedChainIds: Hex[];
readonly #supportedChainIds: Hex[];

timeoutHandle?: NodeJS.Timeout;

Expand All @@ -286,7 +286,7 @@

readonly #getMetaMetricsProps: () => Promise<MetaMetricsProps>;

#trace: TraceCallback;
readonly #trace: TraceCallback;

#isStxMigrationFlagEnabled(flagName: string): boolean {
const flag = this.messenger.call('RemoteFeatureFlagController:getState')
Expand Down Expand Up @@ -451,9 +451,9 @@
isSmartTransactionPending,
);
if (!this.timeoutHandle && pendingTransactions?.length > 0) {
this.poll();

Check warning on line 454 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 454 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
} else if (this.timeoutHandle && pendingTransactions?.length === 0) {
this.stop();

Check warning on line 456 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 456 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
}
}

Expand All @@ -478,7 +478,7 @@
}

this.timeoutHandle = setInterval(() => {
safelyExecute(async () => this.updateSmartTransactions());

Check warning on line 481 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 481 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
}, this.#interval);
await safelyExecute(async () => this.updateSmartTransactions());
}
Expand Down Expand Up @@ -545,7 +545,7 @@
ethQuery = new EthQuery(provider);
}

this.#createOrUpdateSmartTransaction(smartTransaction, {

Check warning on line 548 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 548 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
chainId,
ethQuery,
});
Expand Down Expand Up @@ -741,7 +741,7 @@
.map((pendingSmartTransaction) => {
// Use the transaction's chainId (from the key) to derive a networkClientId
const networkClientIdToUse = this.#getNetworkClientId({
chainId: chainId as Hex,
chainId,
});
return {
uuid: pendingSmartTransaction.uuid,
Expand Down Expand Up @@ -1195,7 +1195,7 @@
await this.#fetch(getAPIRequestURL(APIType.LIVENESS, chainId)),
);
liveness = Boolean(response.smartTransactions);
} catch (error) {
} catch {
console.log('"fetchLiveness" API call failed');
}

Expand Down
Loading
Loading