From 0c305598cf37053db91abf5ef4fbc51c69f19751 Mon Sep 17 00:00:00 2001 From: Usame Algan Date: Tue, 24 Sep 2024 13:48:35 +0200 Subject: [PATCH] fix: Add no-unused-vars and await-thenable eslint rules --- .eslintrc.json | 9 +- .../address-book/ImportDialog/index.tsx | 2 +- .../common/AddressBookInput/index.test.tsx | 26 +++--- .../common/AddressBookInput/index.tsx | 2 +- .../common/CheckWallet/index.test.tsx | 2 +- .../common/CookieAndTermBanner/index.tsx | 1 - .../common/DatePickerInput/index.tsx | 2 +- src/components/common/DateTime/index.test.tsx | 6 +- .../common/EthHashInfo/index.test.tsx | 13 +-- src/components/common/NameInput/index.tsx | 4 +- src/components/common/TxModalDialog/index.tsx | 9 +- .../ActivityRewardsSection/index.tsx | 4 +- .../PendingTxs/PendingTxListItem.tsx | 2 - .../SafeAppsDashboardSection.test.tsx | 2 +- .../create/steps/ReviewStep/index.tsx | 2 +- .../safe-apps/AddCustomAppModal/index.tsx | 2 +- .../safe-messages/SingleMsg/index.tsx | 2 +- .../PushNotifications/__tests__/logic.test.ts | 2 +- .../settings/PushNotifications/index.tsx | 2 - .../tx-flow/common/TxNonce/index.tsx | 3 +- .../flows/SafeAppsTx/ReviewSafeAppsTx.tsx | 2 - .../flows/SignMessage/SignMessage.test.tsx | 21 +++-- .../tx/ApprovalEditor/ApprovalEditor.test.tsx | 4 +- .../tx/SignOrExecuteForm/ExecuteForm.tsx | 1 - .../__test__/ExecuteThroughRoleForm.test.tsx | 2 - .../__test__/hooks.test.ts | 2 +- .../ExecuteThroughRoleForm/index.tsx | 1 - .../tx/security/blockaid/BlockaidHint.tsx | 3 +- .../blockaid/__tests__/useBlockaid.test.ts | 2 +- src/components/tx/security/blockaid/index.tsx | 11 +-- .../tenderly/__tests__/useSimulation.test.ts | 5 +- .../counterfactual/ActivateAccountFlow.tsx | 2 +- .../counterfactual/CounterfactualForm.tsx | 5 -- .../hooks/usePendingSafeStatuses.ts | 2 +- .../services/__tests__/recovery-state.test.ts | 8 +- .../walletconnect/WalletConnectContext.tsx | 2 +- src/hooks/__tests__/useDecodeTx.test.ts | 2 +- .../__tests__/useRemainingRelays.test.ts | 6 +- .../__tests__/useSafeTokenAllocation.test.ts | 6 +- src/hooks/__tests__/useWalletCanPay.test.ts | 5 +- .../coreSDK/__tests__/safeCoreSDK.test.ts | 45 ++-------- src/hooks/safe-apps/useCategoryFilter.ts | 2 +- src/hooks/useWalletCanPay.ts | 10 +-- src/services/ens/index.ts | 5 -- .../security/modules/BlockaidModule/index.ts | 2 +- src/services/tx/__tests__/txMonitor.test.ts | 84 +++++++++++-------- .../tx/tx-sender/__tests__/ts-sender.test.ts | 4 +- src/store/broadcast.ts | 2 +- src/store/pendingTxsSlice.ts | 2 - src/store/txHistorySlice.ts | 2 +- src/tests/pages/apps.test.tsx | 80 +++++++++--------- src/utils/__tests__/SimpleTxWatcher.test.ts | 2 +- src/utils/transactions.ts | 7 +- src/utils/tx-history-filter.ts | 2 +- 54 files changed, 192 insertions(+), 246 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 81eafda606..63839322a5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,6 +6,9 @@ "plugin:storybook/recommended" ], "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": ["./tsconfig.json"] + }, "rules": { "@next/next/no-img-element": "off", "@next/next/google-font-display": "off", @@ -13,7 +16,9 @@ "@next/next/no-page-custom-font": "off", "unused-imports/no-unused-imports-ts": "error", "@typescript-eslint/consistent-type-imports": "error", + "@typescript-eslint/await-thenable": "error", "no-constant-condition": "warn", + "no-unused-vars": ["error", { "varsIgnorePattern": "^_" }], "react-hooks/exhaustive-deps": [ "warn", { @@ -28,7 +33,9 @@ "ignorePatterns": [ "node_modules/", ".next/", - ".github/" + ".github/", + "cypress/", + "src/types/contracts/" ], "plugins": [ "unused-imports", diff --git a/src/components/address-book/ImportDialog/index.tsx b/src/components/address-book/ImportDialog/index.tsx index 7b83a40d8b..dedd74a3f4 100644 --- a/src/components/address-book/ImportDialog/index.tsx +++ b/src/components/address-book/ImportDialog/index.tsx @@ -114,7 +114,7 @@ const ImportDialog = ({ handleClose }: { handleClose: () => void }): ReactElemen }} > {/* https://github.com/Bunlong/react-papaparse/blob/master/src/useCSVReader.tsx */} - {({ getRootProps, acceptedFile, ProgressBar, getRemoveFileProps, Remove }: any) => { + {({ getRootProps, acceptedFile, getRemoveFileProps }: any) => { const { onClick } = getRemoveFileProps() const onRemove = (e: MouseEvent) => { diff --git a/src/components/common/AddressBookInput/index.test.tsx b/src/components/common/AddressBookInput/index.test.tsx index 449e0eead9..ee910e6dcc 100644 --- a/src/components/common/AddressBookInput/index.test.tsx +++ b/src/components/common/AddressBookInput/index.test.tsx @@ -1,4 +1,5 @@ -import { act, fireEvent, render, waitFor } from '@/tests/test-utils' +import { act } from 'react' +import { fireEvent, render, waitFor } from '@/tests/test-utils' import { FormProvider, useForm } from 'react-hook-form' import AddressBookInput from '.' import type { AddressInputProps } from '../AddressInput' @@ -147,12 +148,12 @@ describe('AddressBookInput', () => { expect(input).toHaveAttribute('aria-expanded', 'false') - await act(() => { + act(() => { fireEvent.mouseDown(input) fireEvent.mouseUp(input) }) - await act(() => { + act(() => { fireEvent.change(input, { target: { value: invalidAddress } }) jest.advanceTimersByTime(1000) }) @@ -160,7 +161,8 @@ describe('AddressBookInput', () => { await waitFor(() => expect(utils.getByLabelText(validationError, { exact: false })).toBeDefined()) const address = checksumAddress(faker.finance.ethereumAddress()) - await act(() => { + + act(() => { fireEvent.change(input, { target: { value: address } }) jest.advanceTimersByTime(1000) }) @@ -187,14 +189,14 @@ describe('AddressBookInput', () => { expect(input).toHaveAttribute('aria-expanded', 'false') - await act(() => { + act(() => { fireEvent.mouseDown(input) fireEvent.mouseUp(input) }) expect(input).toHaveAttribute('aria-expanded', 'true') - await act(() => { + act(() => { fireEvent.click(utils.getByText('InvalidAddress')) fireEvent.blur(input) jest.advanceTimersByTime(1000) @@ -206,7 +208,7 @@ describe('AddressBookInput', () => { }) // Clear the input by clicking on the readonly input - await act(() => { + act(() => { // first click clears input fireEvent.click(utils.getByLabelText(validationError, { exact: false })) }) @@ -215,13 +217,13 @@ describe('AddressBookInput', () => { const newInput = utils.getByLabelText(validationError, { exact: false }) expect(newInput).toBeVisible() - await act(() => { + act(() => { // mousedown opens autocompletion again fireEvent.mouseDown(newInput) fireEvent.mouseUp(newInput) }) - await act(() => { + act(() => { fireEvent.click(utils.getByText('ValidAddress')) fireEvent.blur(newInput) @@ -239,7 +241,7 @@ describe('AddressBookInput', () => { const { input, utils } = setup('', {}, undefined, true) const newAddress = checksumAddress(faker.finance.ethereumAddress()) - await act(() => { + act(() => { fireEvent.change(input, { target: { value: newAddress } }) jest.advanceTimersByTime(1000) }) @@ -253,7 +255,7 @@ describe('AddressBookInput', () => { }) const nameInput = utils.getByLabelText('Name', { exact: false }) - await act(() => { + act(() => { fireEvent.change(nameInput, { target: { value: 'Tim Testermann' } }) fireEvent.submit(nameInput) }) @@ -265,7 +267,7 @@ describe('AddressBookInput', () => { const { input, utils } = setup('', {}, undefined, false) const newAddress = checksumAddress(faker.finance.ethereumAddress()) - await act(() => { + act(() => { fireEvent.change(input, { target: { value: newAddress } }) jest.advanceTimersByTime(1000) }) diff --git a/src/components/common/AddressBookInput/index.tsx b/src/components/common/AddressBookInput/index.tsx index 3ae7b1f6b5..4c8828623a 100644 --- a/src/components/common/AddressBookInput/index.tsx +++ b/src/components/common/AddressBookInput/index.tsx @@ -62,7 +62,7 @@ const AddressBookInput = ({ name, canAdd, ...props }: AddressInputProps & { canA ( + render={({ field: { ...field } }) => ( { ;(useIsSafeOwner as jest.MockedFunction).mockReturnValueOnce(true) const renderButtonWithNetworkCheck = () => - render({(isOk) => }) + render({() => }) const { container } = renderButtonWithNetworkCheck() diff --git a/src/components/common/CookieAndTermBanner/index.tsx b/src/components/common/CookieAndTermBanner/index.tsx index e8f650276b..559684508e 100644 --- a/src/components/common/CookieAndTermBanner/index.tsx +++ b/src/components/common/CookieAndTermBanner/index.tsx @@ -149,7 +149,6 @@ export const CookieAndTermBanner = ({ const CookieBannerPopup = (): ReactElement | null => { const cookiePopup = useAppSelector(selectCookieBanner) - const cookies = useAppSelector(selectCookies) const dispatch = useAppDispatch() const hasAccepted = useAppSelector(hasAcceptedTerms) diff --git a/src/components/common/DatePickerInput/index.tsx b/src/components/common/DatePickerInput/index.tsx index ed760e712e..1d8ca61372 100644 --- a/src/components/common/DatePickerInput/index.tsx +++ b/src/components/common/DatePickerInput/index.tsx @@ -53,7 +53,7 @@ const DatePickerInput = ({ inputFormat="dd/MM/yyyy" {...field} disableFuture={disableFuture} - renderInput={({ label, error: _, ...params }) => ( + renderInput={({ label, ...params }) => ( )} PaperProps={{ diff --git a/src/components/common/DateTime/index.test.tsx b/src/components/common/DateTime/index.test.tsx index a749c21d71..d0e07ad038 100644 --- a/src/components/common/DateTime/index.test.tsx +++ b/src/components/common/DateTime/index.test.tsx @@ -70,13 +70,11 @@ describe('DateTime', () => { date.setDate(date.getDate() - days) - const { queryByText } = render(, { + const { getByText } = render(, { routerProps: { pathname: '/transactions/history' }, }) - const expected = formatDateTime(date.getTime()) - - expect(queryByText('3 days ago')).toBeInTheDocument() + expect(getByText('3 days ago')).toBeInTheDocument() }) it('should render the full date and time after threshold on the filter', () => { diff --git a/src/components/common/EthHashInfo/index.test.tsx b/src/components/common/EthHashInfo/index.test.tsx index 0facb02d3d..3ae9e9282d 100644 --- a/src/components/common/EthHashInfo/index.test.tsx +++ b/src/components/common/EthHashInfo/index.test.tsx @@ -1,7 +1,8 @@ import { blo } from 'blo' +import { act } from 'react' import type { ChainInfo } from '@safe-global/safe-gateway-typescript-sdk' -import { act, fireEvent, render, waitFor } from '@/tests/test-utils' +import { fireEvent, render, waitFor } from '@/tests/test-utils' import * as useAllAddressBooks from '@/hooks/useAllAddressBooks' import * as useChainId from '@/hooks/useChainId' import * as store from '@/store' @@ -258,7 +259,7 @@ describe('EthHashInfo', () => { const button = container.querySelector('button') - await act(() => { + act(() => { fireEvent.click(button!) }) @@ -288,7 +289,7 @@ describe('EthHashInfo', () => { const button = container.querySelector('button') - await act(() => { + act(() => { fireEvent.click(button!) }) @@ -320,7 +321,7 @@ describe('EthHashInfo', () => { const button = container.querySelector('button') - await act(() => { + act(() => { fireEvent.click(button!) }) @@ -349,7 +350,7 @@ describe('EthHashInfo', () => { const button = container.querySelector('button') - await act(() => { + act(() => { fireEvent.click(button!) }) @@ -375,7 +376,7 @@ describe('EthHashInfo', () => { const button = container.querySelector('button') - await act(() => { + act(() => { fireEvent.click(button!) }) diff --git a/src/components/common/NameInput/index.tsx b/src/components/common/NameInput/index.tsx index 09289fc8a4..ac3a1ed27c 100644 --- a/src/components/common/NameInput/index.tsx +++ b/src/components/common/NameInput/index.tsx @@ -1,17 +1,15 @@ import type { TextFieldProps } from '@mui/material' import { TextField } from '@mui/material' import get from 'lodash/get' -import { type FieldError, type Validate, useFormContext } from 'react-hook-form' +import { type FieldError, useFormContext } from 'react-hook-form' import inputCss from '@/styles/inputs.module.css' const NameInput = ({ name, - validate, required = false, ...props }: Omit & { name: string - validate?: Validate required?: boolean }) => { const { register, formState } = useFormContext() || {} diff --git a/src/components/common/TxModalDialog/index.tsx b/src/components/common/TxModalDialog/index.tsx index 6c4cad1877..62f5978674 100644 --- a/src/components/common/TxModalDialog/index.tsx +++ b/src/components/common/TxModalDialog/index.tsx @@ -4,20 +4,13 @@ import type { ReactElement } from 'react' import CloseIcon from '@mui/icons-material/Close' import css from './styles.module.css' -interface ModalDialogProps extends DialogProps { - dialogTitle?: React.ReactNode - hideChainIndicator?: boolean -} - const TxModalDialog = ({ - dialogTitle, - hideChainIndicator, children, onClose, fullScreen = false, fullWidth = false, ...restProps -}: ModalDialogProps): ReactElement => { +}: DialogProps): ReactElement => { return ( { - Learn more + + Learn more + diff --git a/src/components/dashboard/PendingTxs/PendingTxListItem.tsx b/src/components/dashboard/PendingTxs/PendingTxListItem.tsx index ab409da7d0..e48c888421 100644 --- a/src/components/dashboard/PendingTxs/PendingTxListItem.tsx +++ b/src/components/dashboard/PendingTxs/PendingTxListItem.tsx @@ -10,7 +10,6 @@ import TxInfo from '@/components/transactions/TxInfo' import TxType from '@/components/transactions/TxType' import css from './styles.module.css' import { AppRoutes } from '@/config/routes' -import useSafeInfo from '@/hooks/useSafeInfo' import TxConfirmations from '@/components/transactions/TxConfirmations' type PendingTxType = { @@ -20,7 +19,6 @@ type PendingTxType = { const PendingTx = ({ transaction }: PendingTxType): ReactElement => { const router = useRouter() const { id } = transaction - const { safe } = useSafeInfo() const url = useMemo( () => ({ diff --git a/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx b/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx index 66b758eac1..047ce6e3bf 100644 --- a/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx +++ b/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx @@ -6,7 +6,7 @@ import { LS_NAMESPACE } from '@/config/constants' jest.mock('@safe-global/safe-gateway-typescript-sdk', () => ({ ...jest.requireActual('@safe-global/safe-gateway-typescript-sdk'), - getSafeApps: (chainId: string): Promise => + getSafeApps: (): Promise => Promise.resolve([ { id: 13, diff --git a/src/components/new-safe/create/steps/ReviewStep/index.tsx b/src/components/new-safe/create/steps/ReviewStep/index.tsx index dacaf084c3..fde7545e66 100644 --- a/src/components/new-safe/create/steps/ReviewStep/index.tsx +++ b/src/components/new-safe/create/steps/ReviewStep/index.tsx @@ -143,7 +143,7 @@ const ReviewStep = ({ data, onSubmit, onBack, setStep }: StepRenderProps({ defaultValues: { riskAcknowledgement: false }, mode: 'onChange' }) - const onSubmit: SubmitHandler = (_, __) => { + const onSubmit: SubmitHandler = () => { if (safeApp) { onSave(safeApp) trackSafeAppEvent(SAFE_APPS_EVENTS.ADD_CUSTOM_APP, safeApp.url) diff --git a/src/components/safe-messages/SingleMsg/index.tsx b/src/components/safe-messages/SingleMsg/index.tsx index dc5c181659..90fc41d067 100644 --- a/src/components/safe-messages/SingleMsg/index.tsx +++ b/src/components/safe-messages/SingleMsg/index.tsx @@ -9,7 +9,7 @@ const SingleMsg = () => { const router = useRouter() const { messageHash } = router.query const safeMessageHash = Array.isArray(messageHash) ? messageHash[0] : messageHash - const [safeMessage, _, messageError] = useSafeMessage(safeMessageHash) + const [safeMessage, , messageError] = useSafeMessage(safeMessageHash) if (safeMessage) { return ( diff --git a/src/components/settings/PushNotifications/__tests__/logic.test.ts b/src/components/settings/PushNotifications/__tests__/logic.test.ts index cb59932378..7a103f5b13 100644 --- a/src/components/settings/PushNotifications/__tests__/logic.test.ts +++ b/src/components/settings/PushNotifications/__tests__/logic.test.ts @@ -123,7 +123,7 @@ describe('Notifications', () => { const mockProvider = new BrowserProvider(MockEip1193Provider) - jest.spyOn(mockProvider, 'getSigner').mockImplementation((address?: string | number | undefined) => + jest.spyOn(mockProvider, 'getSigner').mockImplementation(() => Promise.resolve({ signMessage: jest.fn().mockResolvedValueOnce(MM_SIGNATURE), } as unknown as JsonRpcSigner), diff --git a/src/components/settings/PushNotifications/index.tsx b/src/components/settings/PushNotifications/index.tsx index c3ae4f1c11..a03d43453f 100644 --- a/src/components/settings/PushNotifications/index.tsx +++ b/src/components/settings/PushNotifications/index.tsx @@ -29,7 +29,6 @@ import { PUSH_NOTIFICATION_EVENTS } from '@/services/analytics/events/push-notif import { AppRoutes } from '@/config/routes' import CheckWallet from '@/components/common/CheckWallet' import { useIsMac } from '@/hooks/useIsMac' -import useOnboard from '@/hooks/wallets/useOnboard' import ExternalLink from '@/components/common/ExternalLink' import css from './styles.module.css' @@ -41,7 +40,6 @@ export const PushNotifications = (): ReactElement => { const isMac = useIsMac() const [isRegistering, setIsRegistering] = useState(false) const [isUpdatingIndexedDb, setIsUpdatingIndexedDb] = useState(false) - const onboard = useOnboard() const theme = useTheme() const isLargeScreen = useMediaQuery(theme.breakpoints.up('lg')) diff --git a/src/components/tx-flow/common/TxNonce/index.tsx b/src/components/tx-flow/common/TxNonce/index.tsx index 9fb124ca5a..5d3f243e39 100644 --- a/src/components/tx-flow/common/TxNonce/index.tsx +++ b/src/components/tx-flow/common/TxNonce/index.tsx @@ -33,11 +33,10 @@ import classNames from 'classnames' const CustomPopper = function ({ // Don't set width of Popper to that of the field - style: _, className, ...props }: PopperProps) { - return + return } const NonceFormHeader = memo(function NonceFormSubheader({ children, ...props }: ListSubheaderProps) { diff --git a/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx b/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx index 100f4a4869..9b28b681fc 100644 --- a/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx +++ b/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx @@ -8,7 +8,6 @@ import { trackSafeAppTxCount } from '@/services/safe-apps/track-app-usage-count' import { getTxOrigin } from '@/utils/transactions' import { createMultiSendCallOnlyTx, createTx, dispatchSafeAppsTx } from '@/services/tx/tx-sender' import useOnboard from '@/hooks/wallets/useOnboard' -import useSafeInfo from '@/hooks/useSafeInfo' import useHighlightHiddenTab from '@/hooks/useHighlightHiddenTab' import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider' import { isTxValid } from '@/components/safe-apps/utils' @@ -24,7 +23,6 @@ const ReviewSafeAppsTx = ({ safeAppsTx: { txs, requestId, params, appId, app }, onSubmit, }: ReviewSafeAppsTxProps): ReactElement => { - const { safe } = useSafeInfo() const onboard = useOnboard() const wallet = useWallet() const { safeTx, setSafeTx, safeTxError, setSafeTxError } = useContext(SafeTxContext) diff --git a/src/components/tx-flow/flows/SignMessage/SignMessage.test.tsx b/src/components/tx-flow/flows/SignMessage/SignMessage.test.tsx index 1b888e4573..0699137ea8 100644 --- a/src/components/tx-flow/flows/SignMessage/SignMessage.test.tsx +++ b/src/components/tx-flow/flows/SignMessage/SignMessage.test.tsx @@ -1,3 +1,4 @@ +import { act } from 'react' import { extendedSafeInfoBuilder } from '@/tests/builders/safe' import { hexlify, zeroPadValue, toUtf8Bytes } from 'ethers' import type { SafeInfo, SafeMessage } from '@safe-global/safe-gateway-typescript-sdk' @@ -12,7 +13,7 @@ import * as useChainsHook from '@/hooks/useChains' import * as sender from '@/services/safe-messages/safeMsgSender' import * as onboard from '@/hooks/wallets/useOnboard' import * as useSafeMessage from '@/hooks/messages/useSafeMessage' -import { render, act, fireEvent, waitFor } from '@/tests/test-utils' +import { render, fireEvent, waitFor } from '@/tests/test-utils' import type { ConnectedWallet } from '@/hooks/wallets/useOnboard' import type { EIP1193Provider, WalletState, AppState, OnboardAPI } from '@web3-onboard/core' import { generateSafeMessageHash } from '@/utils/safe-messages' @@ -240,7 +241,7 @@ describe('SignMessage', () => { const button = getByText('Sign') - await act(() => { + act(() => { fireEvent.click(button) }) @@ -254,9 +255,11 @@ describe('SignMessage', () => { ) // Immediately refetches message and displays confirmation - expect(baseElement).toHaveTextContent('0x0000...0002') - expect(baseElement).toHaveTextContent('1 of 2') - expect(baseElement).toHaveTextContent('Confirmation #2') + await waitFor(() => { + expect(baseElement).toHaveTextContent('0x0000...0002') + expect(baseElement).toHaveTextContent('1 of 2') + expect(baseElement).toHaveTextContent('Confirmation #2') + }) }) it('confirms the message if already proposed', async () => { @@ -323,7 +326,7 @@ describe('SignMessage', () => { ;(getSafeMessage as jest.Mock).mockResolvedValue(newMsg) - await act(() => { + act(() => { fireEvent.click(button) }) @@ -371,7 +374,7 @@ describe('SignMessage', () => { jest.spyOn(useChainsHook, 'useCurrentChain').mockReturnValue(chainBuilder().build()) jest.spyOn(useSafeMessage, 'default').mockImplementation(() => [undefined, jest.fn(), undefined]) - const { getByText, queryByText, container } = render( + const { getByText, queryByText } = render( { const button = getByText('Sign') expect(button).not.toBeDisabled() - await act(() => { + act(() => { fireEvent.click(button) }) @@ -555,7 +558,7 @@ describe('SignMessage', () => { expect(button).toBeEnabled() - await act(() => { + act(() => { fireEvent.click(button) }) diff --git a/src/components/tx/ApprovalEditor/ApprovalEditor.test.tsx b/src/components/tx/ApprovalEditor/ApprovalEditor.test.tsx index a2e473df33..b2e6fd8295 100644 --- a/src/components/tx/ApprovalEditor/ApprovalEditor.test.tsx +++ b/src/components/tx/ApprovalEditor/ApprovalEditor.test.tsx @@ -61,7 +61,7 @@ describe('ApprovalEditor', () => { const result = render() - expect(await result.queryByText('Error while decoding approval transactions.')).toBeInTheDocument() + expect(result.getByText('Error while decoding approval transactions.')).toBeInTheDocument() }) it('renders a loading skeleton', async () => { @@ -70,7 +70,7 @@ describe('ApprovalEditor', () => { const result = render() - expect(await result.queryByTestId('approval-editor-loading')).toBeInTheDocument() + expect(result.getByTestId('approval-editor-loading')).toBeInTheDocument() }) it('renders a read-only view if the transaction contains signatures', async () => { diff --git a/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx b/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx index 522fd3c771..61d3acbd32 100644 --- a/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx +++ b/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx @@ -116,7 +116,6 @@ export const ExecuteForm = ({ const walletCanPay = useWalletCanPay({ gasLimit, maxFeePerGas: advancedParams.maxFeePerGas, - maxPriorityFeePerGas: advancedParams.maxPriorityFeePerGas, }) const cannotPropose = !isOwner && !onlyExecute diff --git a/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/ExecuteThroughRoleForm.test.tsx b/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/ExecuteThroughRoleForm.test.tsx index 5c17fc5922..ee0382dcd5 100644 --- a/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/ExecuteThroughRoleForm.test.tsx +++ b/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/ExecuteThroughRoleForm.test.tsx @@ -202,8 +202,6 @@ const SAFE_INFO = extendedSafeInfoBuilder().build() SAFE_INFO.modules = [{ value: ROLES_MOD_ADDRESS }] SAFE_INFO.chainId = '1' -const lowercaseSafeAddress = SAFE_INFO.address.value.toLowerCase() - const WETH_ADDRESS = '0xfff9976782d46cc05630d1f6ebab18b2324d6b14' const TEST_ROLE_OK: hooksModule.Role = { diff --git a/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/hooks.test.ts b/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/hooks.test.ts index 2bd85d3a75..3e01cdb74a 100644 --- a/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/hooks.test.ts +++ b/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/__test__/hooks.test.ts @@ -135,7 +135,7 @@ describe('useRoles', () => { operation: OperationType.Call, }) - const { result, rerender } = renderHook(() => useRoles(safeTxOk)) + const { result } = renderHook(() => useRoles(safeTxOk)) // wait for the Roles mod to be fetched & and the cache state update to be propagated await waitFor(() => { diff --git a/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/index.tsx b/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/index.tsx index 30078edaad..39acb5a1d1 100644 --- a/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/index.tsx +++ b/src/components/tx/SignOrExecuteForm/ExecuteThroughRoleForm/index.tsx @@ -136,7 +136,6 @@ export const ExecuteThroughRoleForm = ({ const walletCanPay = useWalletCanPay({ gasLimit, maxFeePerGas: advancedParams.maxFeePerGas, - maxPriorityFeePerGas: advancedParams.maxPriorityFeePerGas, }) const submitDisabled = !txThroughRole || isPending || disableSubmit || (needsRiskConfirmation && !isRiskConfirmed) diff --git a/src/components/tx/security/blockaid/BlockaidHint.tsx b/src/components/tx/security/blockaid/BlockaidHint.tsx index e006c222ad..8c7e2192a6 100644 --- a/src/components/tx/security/blockaid/BlockaidHint.tsx +++ b/src/components/tx/security/blockaid/BlockaidHint.tsx @@ -1,7 +1,6 @@ -import { type SecuritySeverity } from '@/services/security/modules/types' import { List, ListItem, Typography } from '@mui/material' -export const BlockaidHint = ({ severity, warnings }: { severity: SecuritySeverity; warnings: string[] }) => { +export const BlockaidHint = ({ warnings }: { warnings: string[] }) => { return ( {warnings.map((warning) => ( diff --git a/src/components/tx/security/blockaid/__tests__/useBlockaid.test.ts b/src/components/tx/security/blockaid/__tests__/useBlockaid.test.ts index 5f7d407c5d..0043375c3f 100644 --- a/src/components/tx/security/blockaid/__tests__/useBlockaid.test.ts +++ b/src/components/tx/security/blockaid/__tests__/useBlockaid.test.ts @@ -13,7 +13,7 @@ import { safeInfoBuilder } from '@/tests/builders/safe' import { CLASSIFICATION_MAPPING, REASON_MAPPING } from '..' import { renderHook, waitFor } from '@/tests/test-utils' -const setupFetchStub = (data: any) => (_url: string) => { +const setupFetchStub = (data: any) => () => { return Promise.resolve({ json: () => Promise.resolve(data), status: 200, diff --git a/src/components/tx/security/blockaid/index.tsx b/src/components/tx/security/blockaid/index.tsx index f1c18f9736..79cfe84608 100644 --- a/src/components/tx/security/blockaid/index.tsx +++ b/src/components/tx/security/blockaid/index.tsx @@ -165,9 +165,8 @@ export const Blockaid = () => { } const BlockaidWarning = () => { - const { blockaidResponse, setIsRiskConfirmed, needsRiskConfirmation, isRiskConfirmed, isRiskIgnored } = - useContext(TxSecurityContext) - const { severity, warnings, isLoading, error } = blockaidResponse ?? {} + const { blockaidResponse, setIsRiskConfirmed, needsRiskConfirmation, isRiskConfirmed } = useContext(TxSecurityContext) + const { severity, isLoading, error } = blockaidResponse ?? {} const { safeTx } = useContext(SafeTxContext) @@ -217,11 +216,7 @@ export const BlockaidMessage = () => { return ( {sortedSeverities.map((key) => ( - warning.description)} - /> + warning.description)} /> ))} ) diff --git a/src/components/tx/security/tenderly/__tests__/useSimulation.test.ts b/src/components/tx/security/tenderly/__tests__/useSimulation.test.ts index 9e671ee8fc..3280269dc0 100644 --- a/src/components/tx/security/tenderly/__tests__/useSimulation.test.ts +++ b/src/components/tx/security/tenderly/__tests__/useSimulation.test.ts @@ -1,11 +1,12 @@ +import { act } from 'react' import type { SafeInfo } from '@safe-global/safe-gateway-typescript-sdk' -import { act, renderHook, waitFor } from '@/tests/test-utils' +import { renderHook, waitFor } from '@/tests/test-utils' import { useSimulation } from '@/components/tx/security/tenderly/useSimulation' import * as utils from '@/components/tx/security/tenderly/utils' import { FETCH_STATUS, type TenderlySimulation } from '@/components/tx/security/tenderly/types' -const setupFetchStub = (data: any) => (_url: string) => { +const setupFetchStub = (data: any) => () => { return Promise.resolve({ json: () => Promise.resolve(data), status: 200, diff --git a/src/features/counterfactual/ActivateAccountFlow.tsx b/src/features/counterfactual/ActivateAccountFlow.tsx index f58b8046ca..15eecb5e7c 100644 --- a/src/features/counterfactual/ActivateAccountFlow.tsx +++ b/src/features/counterfactual/ActivateAccountFlow.tsx @@ -51,7 +51,7 @@ const useActivateAccount = () => { : { gasPrice: maxFeePerGas?.toString(), gasLimit: gasLimit?.totalGas.toString() } const totalFee = getTotalFeeFormatted(maxFeePerGas, gasLimit?.totalGas, chain) - const walletCanPay = useWalletCanPay({ gasLimit: gasLimit?.totalGas, maxFeePerGas, maxPriorityFeePerGas }) + const walletCanPay = useWalletCanPay({ gasLimit: gasLimit?.totalGas, maxFeePerGas }) return { options, totalFee, walletCanPay } } diff --git a/src/features/counterfactual/CounterfactualForm.tsx b/src/features/counterfactual/CounterfactualForm.tsx index de779ab68c..98d59a5712 100644 --- a/src/features/counterfactual/CounterfactualForm.tsx +++ b/src/features/counterfactual/CounterfactualForm.tsx @@ -1,11 +1,9 @@ import { TxModalContext } from '@/components/tx-flow' import useDeployGasLimit from '@/features/counterfactual/hooks/useDeployGasLimit' import { deploySafeAndExecuteTx } from '@/features/counterfactual/utils' -import useChainId from '@/hooks/useChainId' import { getTotalFeeFormatted } from '@/hooks/useGasPrice' import useSafeInfo from '@/hooks/useSafeInfo' import useWalletCanPay from '@/hooks/useWalletCanPay' -import useOnboard from '@/hooks/wallets/useOnboard' import useWallet from '@/hooks/wallets/useWallet' import { OVERVIEW_EVENTS, trackEvent, WALLET_EVENTS } from '@/services/analytics' import { TX_EVENTS, TX_TYPES } from '@/services/analytics/events/transactions' @@ -47,9 +45,7 @@ export const CounterfactualForm = ({ safeTx?: SafeTransaction }): ReactElement => { const wallet = useWallet() - const onboard = useOnboard() const chain = useCurrentChain() - const chainId = useChainId() const { safeAddress } = useSafeInfo() // Form state @@ -102,7 +98,6 @@ export const CounterfactualForm = ({ const walletCanPay = useWalletCanPay({ gasLimit: gasLimit?.totalGas, maxFeePerGas: advancedParams.maxFeePerGas, - maxPriorityFeePerGas: advancedParams.maxPriorityFeePerGas, }) const cannotPropose = !isOwner && !onlyExecute diff --git a/src/features/counterfactual/hooks/usePendingSafeStatuses.ts b/src/features/counterfactual/hooks/usePendingSafeStatuses.ts index 296765c48f..acca28f50d 100644 --- a/src/features/counterfactual/hooks/usePendingSafeStatuses.ts +++ b/src/features/counterfactual/hooks/usePendingSafeStatuses.ts @@ -40,7 +40,7 @@ const usePendingSafeMonitor = (): void => { // Monitor pending safe creation mining/validating progress useEffect(() => { - Object.entries(undeployedSafesByChain).forEach(([chainId, undeployedSafes]) => { + Object.entries(undeployedSafesByChain).forEach(([, undeployedSafes]) => { Object.entries(undeployedSafes).forEach(([safeAddress, undeployedSafe]) => { if (undeployedSafe?.status.status === PendingSafeStatus.AWAITING_EXECUTION) { monitoredSafes.current[safeAddress] = false diff --git a/src/features/recovery/services/__tests__/recovery-state.test.ts b/src/features/recovery/services/__tests__/recovery-state.test.ts index 73a5d49e40..b9826bd0f0 100644 --- a/src/features/recovery/services/__tests__/recovery-state.test.ts +++ b/src/features/recovery/services/__tests__/recovery-state.test.ts @@ -278,7 +278,7 @@ describe('recovery-state', () => { blockHash: faker.string.alphanumeric(), } as TransactionReceipt - global.fetch = jest.fn().mockImplementation((_url: string) => { + global.fetch = jest.fn().mockImplementation(() => { return Promise.resolve({ json: () => Promise.resolve({ transactionHash }), status: 200, @@ -308,7 +308,7 @@ describe('recovery-state', () => { blockHash: faker.string.alphanumeric(), } as TransactionReceipt - global.fetch = jest.fn().mockImplementation((_url: string) => { + global.fetch = jest.fn().mockImplementation(() => { return Promise.resolve({ json: () => Promise.resolve({ transactionHash }), status: 200, @@ -336,7 +336,7 @@ describe('recovery-state', () => { const transactionService = faker.internet.url({ appendSlash: false }) const safeAddress = faker.finance.ethereumAddress() - global.fetch = jest.fn().mockImplementation((_url: string) => { + global.fetch = jest.fn().mockImplementation(() => { return Promise.resolve({ status: 500, ok: false, @@ -376,7 +376,7 @@ describe('recovery-state', () => { .mockResolvedValue(transactionAddedReceipt), } as unknown as JsonRpcProvider - global.fetch = jest.fn().mockImplementation((_url: string) => { + global.fetch = jest.fn().mockImplementation(() => { return Promise.resolve({ json: () => Promise.resolve({ transactionHash }), status: 200, diff --git a/src/features/walletconnect/WalletConnectContext.tsx b/src/features/walletconnect/WalletConnectContext.tsx index c17820132a..757f021fb1 100644 --- a/src/features/walletconnect/WalletConnectContext.tsx +++ b/src/features/walletconnect/WalletConnectContext.tsx @@ -17,7 +17,7 @@ export const WalletConnectContext = createContext({ error: null, setError: () => {}, open: false, - setOpen: (_open: boolean) => {}, + setOpen: () => {}, isLoading: undefined, setIsLoading: () => {}, }) diff --git a/src/hooks/__tests__/useDecodeTx.test.ts b/src/hooks/__tests__/useDecodeTx.test.ts index 99889dc11f..4127c2ce0e 100644 --- a/src/hooks/__tests__/useDecodeTx.test.ts +++ b/src/hooks/__tests__/useDecodeTx.test.ts @@ -86,7 +86,7 @@ describe('useDecodeTx', () => { value: '1000000', }) - const { result } = renderHook(() => useDecodeTx(safeTx)) + renderHook(() => useDecodeTx(safeTx)) await waitFor(async () => { expect(getConfirmationView).toHaveBeenCalledTimes(1) diff --git a/src/hooks/__tests__/useRemainingRelays.test.ts b/src/hooks/__tests__/useRemainingRelays.test.ts index e167618f93..9be3ed1f44 100644 --- a/src/hooks/__tests__/useRemainingRelays.test.ts +++ b/src/hooks/__tests__/useRemainingRelays.test.ts @@ -98,7 +98,7 @@ describe('fetch remaining relays hooks', () => { const ownerAddresses = ['0x00', '0x01', '0x02'] it('should return 0 if one of the owners has no remaining relays', async () => { - const mockFetch = jest + jest .spyOn(gateway, 'getRelayCount') .mockResolvedValue({ limit: 5, remaining: 3 }) .mockResolvedValueOnce({ limit: 5, remaining: 0 }) @@ -112,7 +112,7 @@ describe('fetch remaining relays hooks', () => { }) it('should return the minimum number of relays amongst owners', async () => { - const mockFetch = jest + jest .spyOn(gateway, 'getRelayCount') .mockResolvedValue({ limit: 5, remaining: 3 }) .mockResolvedValueOnce({ limit: 5, remaining: 2 }) @@ -126,7 +126,7 @@ describe('fetch remaining relays hooks', () => { }) it('should return 0 if there is an error fetching the remaining relays', async () => { - const mockFetch = jest + jest .spyOn(gateway, 'getRelayCount') .mockResolvedValue({ limit: 5, remaining: 3 }) .mockRejectedValueOnce('Failed to fetch') diff --git a/src/hooks/__tests__/useSafeTokenAllocation.test.ts b/src/hooks/__tests__/useSafeTokenAllocation.test.ts index e029f067ad..6b66b3c44d 100644 --- a/src/hooks/__tests__/useSafeTokenAllocation.test.ts +++ b/src/hooks/__tests__/useSafeTokenAllocation.test.ts @@ -12,7 +12,7 @@ import { ZERO_ADDRESS } from '@safe-global/protocol-kit/dist/src/utils/constants const setupFetchStub = (data: any, status: number = 200) => - (_url: string) => { + () => { return Promise.resolve({ json: () => Promise.resolve(data), status, @@ -32,8 +32,8 @@ describe('_getRedeemDeadline', () => { jest.clearAllMocks() }) - it('should should only call the provider once per address on a chain', async () => { - for await (const _ of Array.from({ length: 10 })) { + it('should only call the provider once per address on a chain', async () => { + for (let i = 0; i < 10; i++) { await _getRedeemDeadline({ chainId: 1, contract: toBeHex('0x1', 20) } as VestingData, mockProvider) } diff --git a/src/hooks/__tests__/useWalletCanPay.test.ts b/src/hooks/__tests__/useWalletCanPay.test.ts index 565a6828ca..954145ab56 100644 --- a/src/hooks/__tests__/useWalletCanPay.test.ts +++ b/src/hooks/__tests__/useWalletCanPay.test.ts @@ -8,13 +8,13 @@ describe('useWalletCanPay', () => { }) it('should return true if gasLimit is missing', () => { - const { result } = renderHook(() => useWalletCanPay({ maxFeePerGas: BigInt(1), maxPriorityFeePerGas: BigInt(1) })) + const { result } = renderHook(() => useWalletCanPay({ maxFeePerGas: BigInt(1) })) expect(result.current).toEqual(true) }) it('should return true if maxFeePerGas is missing', () => { - const { result } = renderHook(() => useWalletCanPay({ gasLimit: BigInt(21000), maxPriorityFeePerGas: BigInt(1) })) + const { result } = renderHook(() => useWalletCanPay({ gasLimit: BigInt(21000) })) expect(result.current).toEqual(true) }) @@ -66,7 +66,6 @@ describe('useWalletCanPay', () => { useWalletCanPay({ gasLimit: BigInt(21000), maxFeePerGas: BigInt(1), - maxPriorityFeePerGas: BigInt(1), }), ) diff --git a/src/hooks/coreSDK/__tests__/safeCoreSDK.test.ts b/src/hooks/coreSDK/__tests__/safeCoreSDK.test.ts index 1cfcea9834..0e77d1088c 100644 --- a/src/hooks/coreSDK/__tests__/safeCoreSDK.test.ts +++ b/src/hooks/coreSDK/__tests__/safeCoreSDK.test.ts @@ -1,6 +1,5 @@ import { Gnosis_safe__factory } from '@/types/contracts' import { JsonRpcProvider, toBeHex } from 'ethers' -import { id, AbiCoder, type Eip1193Provider } from 'ethers' import Safe from '@safe-global/protocol-kit' import { getProxyFactoryContract, @@ -105,34 +104,12 @@ describe('safeCoreSDK', () => { }) }) - const getMockProvider = (chainId: string, version: string) => { - const mockProvider: Eip1193Provider = { - request: jest.fn((request: { method: string; params?: Array | Record }) => { - const { method, params } = request - const VERSION_SIG_HASH = id('VERSION()').slice(0, 10) - - if (method === 'eth_chainId') { - return Promise.resolve(+chainId) - } - - if (method === 'eth_call' && Array.isArray(params) && params?.[0].data.startsWith(VERSION_SIG_HASH)) { - const encodedVersion = AbiCoder.defaultAbiCoder().encode(['string'], [version]) - return Promise.resolve(encodedVersion) - } - - return Promise.resolve() - }), - } - - return new JsonRpcProvider() - } - describe('Supported contracts', () => { it('should return an SDK instance', async () => { const chainId = '1' const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) await initSafeSDK({ @@ -151,7 +128,7 @@ describe('safeCoreSDK', () => { const chainId = '1' const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) await initSafeSDK({ @@ -174,7 +151,7 @@ describe('safeCoreSDK', () => { const chainId = '137' // Polygon const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) await initSafeSDK({ @@ -197,7 +174,7 @@ describe('safeCoreSDK', () => { const chainId = '137' // Polygon const version = '1.0.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) await initSafeSDK({ @@ -220,7 +197,7 @@ describe('safeCoreSDK', () => { const chainId = '10' // Optimism mainnet const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) await initSafeSDK({ @@ -244,9 +221,8 @@ describe('safeCoreSDK', () => { // Note: backend returns a null version for unsupported contracts it('should retrieve the Safe version from the contract if not provided', async () => { const chainId = '1' - const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) await initSafeSDK({ @@ -263,9 +239,8 @@ describe('safeCoreSDK', () => { it('should return an L1 SDK instance for L1 contracts not deployed on mainnet', async () => { const chainId = '137' // Polygon - const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) await initSafeSDK({ @@ -286,9 +261,8 @@ describe('safeCoreSDK', () => { it('should return undefined for unsupported mastercopies', async () => { const chainId = '1' - const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) const sdk = await initSafeSDK({ @@ -307,9 +281,8 @@ describe('safeCoreSDK', () => { it('should return undefined if provider does not match safe', async () => { const chainId = '1' const safeChainId = '100' - const version = '1.3.0' - const mockProvider = getMockProvider(chainId, version) + const mockProvider = new JsonRpcProvider() mockProvider.getNetwork = jest.fn().mockReturnValue({ chainId: BigInt(chainId) }) const sdk = await initSafeSDK({ diff --git a/src/hooks/safe-apps/useCategoryFilter.ts b/src/hooks/safe-apps/useCategoryFilter.ts index 9e70991779..4757252ff5 100644 --- a/src/hooks/safe-apps/useCategoryFilter.ts +++ b/src/hooks/safe-apps/useCategoryFilter.ts @@ -31,7 +31,7 @@ const useCategoryFilter = ({ }, [router.isReady, router.query.categories, safeAppsList, selectedCategories.length, setSelectedCategories]) const onSelectCategories = async (selectedCategories: string[]) => { - const { categories, ...restProps } = router.query + const { categories: _, ...restProps } = router.query await router.push( { diff --git a/src/hooks/useWalletCanPay.ts b/src/hooks/useWalletCanPay.ts index 58a65094cf..8d32c5f9ca 100644 --- a/src/hooks/useWalletCanPay.ts +++ b/src/hooks/useWalletCanPay.ts @@ -1,15 +1,7 @@ import { getTotalFee } from '@/hooks/useGasPrice' import useWalletBalance from '@/hooks/wallets/useWalletBalance' -const useWalletCanPay = ({ - gasLimit, - maxFeePerGas, - maxPriorityFeePerGas, -}: { - gasLimit?: bigint - maxFeePerGas?: bigint | null - maxPriorityFeePerGas?: bigint | null -}) => { +const useWalletCanPay = ({ gasLimit, maxFeePerGas }: { gasLimit?: bigint; maxFeePerGas?: bigint | null }) => { const [walletBalance] = useWalletBalance() // Take an optimistic approach and assume the wallet can pay diff --git a/src/services/ens/index.ts b/src/services/ens/index.ts index 295f1368fc..60990a26c7 100644 --- a/src/services/ens/index.ts +++ b/src/services/ens/index.ts @@ -14,11 +14,6 @@ export function isDomain(domain: string): boolean { } export const resolveName = async (rpcProvider: Provider, name: string): Promise => { - let chainId = '' - try { - chainId = (await rpcProvider.getNetwork()).chainId.toString() - } catch {} - try { return (await rpcProvider.resolveName(name)) || undefined } catch (e) { diff --git a/src/services/security/modules/BlockaidModule/index.ts b/src/services/security/modules/BlockaidModule/index.ts index 0f85c195c1..a58e4b998e 100644 --- a/src/services/security/modules/BlockaidModule/index.ts +++ b/src/services/security/modules/BlockaidModule/index.ts @@ -90,7 +90,7 @@ export class BlockaidModule implements SecurityModule (_url: string) => { +const setupFetchStub = (data: any) => () => { return Promise.resolve({ json: () => Promise.resolve(data), status: 200, @@ -25,7 +26,6 @@ describe('txMonitor', () => { const simpleTxWatcherInstance = SimpleTxWatcher.getInstance() let txDispatchSpy = jest.spyOn(txEvents, 'txDispatch') - let waitForTxSpy = jest.spyOn(provider, 'waitForTransaction') // let simpleWatcherSpy = jest.spyOn(SimpleTxWatcher, 'getInstance') const safeAddress = toBeHex('0x123', 20) @@ -36,7 +36,7 @@ describe('txMonitor', () => { jest.resetAllMocks() txDispatchSpy = jest.spyOn(txEvents, 'txDispatch') - waitForTxSpy = jest.spyOn(provider, 'waitForTransaction') + jest.spyOn(provider, 'waitForTransaction') watchTxHashSpy = jest.spyOn(simpleTxWatcherInstance, 'watchTxHash') }) @@ -88,16 +88,18 @@ describe('txMonitor', () => { waitForRelayedTx('0x1', ['0x2'], safeAddress, 1) - await act(() => { + act(() => { jest.advanceTimersByTime(15_000 + 1) }) - expect(mockFetch).toHaveBeenCalledTimes(1) - expect(txDispatchSpy).toHaveBeenCalledWith('PROCESSED', { txId: '0x2', safeAddress, nonce: 1 }) + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1) + expect(txDispatchSpy).toHaveBeenCalledWith('PROCESSED', { txId: '0x2', safeAddress, nonce: 1 }) + }) // The relay timeout should have been cancelled txDispatchSpy.mockClear() - await act(() => { + act(() => { jest.advanceTimersByTime(3 * 60_000 + 1) }) expect(txDispatchSpy).not.toHaveBeenCalled() @@ -115,20 +117,22 @@ describe('txMonitor', () => { waitForRelayedTx('0x1', ['0x2'], safeAddress, 1) - await act(() => { + act(() => { jest.advanceTimersByTime(15_000 + 1) }) - expect(mockFetch).toHaveBeenCalledTimes(1) - expect(txDispatchSpy).toHaveBeenCalledWith('REVERTED', { - nonce: 1, - txId: '0x2', - error: new Error(`Relayed transaction reverted by EVM.`), + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1) + expect(txDispatchSpy).toHaveBeenCalledWith('REVERTED', { + nonce: 1, + txId: '0x2', + error: new Error(`Relayed transaction reverted by EVM.`), + }) }) // The relay timeout should have been cancelled txDispatchSpy.mockClear() - await act(() => { + act(() => { jest.advanceTimersByTime(3 * 60_000 + 1) }) expect(txDispatchSpy).not.toHaveBeenCalled() @@ -146,20 +150,22 @@ describe('txMonitor', () => { waitForRelayedTx('0x1', ['0x2'], safeAddress, 1) - await act(() => { + act(() => { jest.advanceTimersByTime(15_000 + 1) }) - expect(mockFetch).toHaveBeenCalledTimes(1) - expect(txDispatchSpy).toHaveBeenCalledWith('FAILED', { - nonce: 1, - txId: '0x2', - error: new Error(`Relayed transaction was blacklisted by relay provider.`), + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1) + expect(txDispatchSpy).toHaveBeenCalledWith('FAILED', { + nonce: 1, + txId: '0x2', + error: new Error(`Relayed transaction was blacklisted by relay provider.`), + }) }) // The relay timeout should have been cancelled txDispatchSpy.mockClear() - await act(() => { + act(() => { jest.advanceTimersByTime(3 * 60_000 + 1) }) expect(txDispatchSpy).not.toHaveBeenCalled() @@ -177,20 +183,22 @@ describe('txMonitor', () => { waitForRelayedTx('0x1', ['0x2'], safeAddress, 1) - await act(() => { + act(() => { jest.advanceTimersByTime(15_000 + 1) }) - expect(mockFetch).toHaveBeenCalledTimes(1) - expect(txDispatchSpy).toHaveBeenCalledWith('FAILED', { - nonce: 1, - txId: '0x2', - error: new Error(`Relayed transaction was cancelled by relay provider.`), + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1) + expect(txDispatchSpy).toHaveBeenCalledWith('FAILED', { + nonce: 1, + txId: '0x2', + error: new Error(`Relayed transaction was cancelled by relay provider.`), + }) }) // The relay timeout should have been cancelled txDispatchSpy.mockClear() - await act(() => { + act(() => { jest.advanceTimersByTime(3 * 60_000 + 1) }) expect(txDispatchSpy).not.toHaveBeenCalled() @@ -208,20 +216,22 @@ describe('txMonitor', () => { waitForRelayedTx('0x1', ['0x2'], safeAddress, 1) - await act(() => { + act(() => { jest.advanceTimersByTime(15_000 + 1) }) - expect(mockFetch).toHaveBeenCalledTimes(1) - expect(txDispatchSpy).toHaveBeenCalledWith('FAILED', { - nonce: 1, - txId: '0x2', - error: new Error(`Relayed transaction was not found.`), + await waitFor(() => { + expect(mockFetch).toHaveBeenCalledTimes(1) + expect(txDispatchSpy).toHaveBeenCalledWith('FAILED', { + nonce: 1, + txId: '0x2', + error: new Error(`Relayed transaction was not found.`), + }) }) // The relay timeout should have been cancelled txDispatchSpy.mockClear() - await act(() => { + act(() => { jest.advanceTimersByTime(3 * 60_000 + 1) }) expect(txDispatchSpy).not.toHaveBeenCalled() @@ -237,7 +247,7 @@ describe('txMonitor', () => { waitForRelayedTx('0x1', ['0x2'], safeAddress, 1) - await act(() => { + act(() => { jest.advanceTimersByTime(3 * 60_000 + 1) }) diff --git a/src/services/tx/tx-sender/__tests__/ts-sender.test.ts b/src/services/tx/tx-sender/__tests__/ts-sender.test.ts index b483390ad1..40ce5714e3 100644 --- a/src/services/tx/tx-sender/__tests__/ts-sender.test.ts +++ b/src/services/tx/tx-sender/__tests__/ts-sender.test.ts @@ -26,7 +26,7 @@ import * as safeContracts from '@/services/contracts/safeContracts' import * as web3 from '@/hooks/wallets/web3' -const setupFetchStub = (data: any) => (_url: string) => { +const setupFetchStub = (data: any) => () => { return Promise.resolve({ json: () => Promise.resolve(data), status: 200, @@ -102,7 +102,7 @@ describe('txSender', () => { const mockBrowserProvider = new BrowserProvider(MockEip1193Provider) jest.spyOn(mockBrowserProvider, 'getSigner').mockImplementation( - async (address?: string | number | undefined) => + async () => Promise.resolve({ getAddress: jest.fn(() => Promise.resolve('0x0000000000000000000000000000000000000123')), provider: MockEip1193Provider, diff --git a/src/store/broadcast.ts b/src/store/broadcast.ts index 4c33ec7ce7..8253f42731 100644 --- a/src/store/broadcast.ts +++ b/src/store/broadcast.ts @@ -7,7 +7,7 @@ const tabId = Math.random().toString(32).slice(2) let broadcast: BroadcastChannel | undefined export const broadcastState = (sliceNames: K[]): Middleware<{}, RootState> => { - return (_) => (next) => (action: unknown) => { + return () => (next) => (action: unknown) => { const result = next(action) // Broadcast actions that aren't being already broadcasted diff --git a/src/store/pendingTxsSlice.ts b/src/store/pendingTxsSlice.ts index a8d249ec80..671c550a08 100644 --- a/src/store/pendingTxsSlice.ts +++ b/src/store/pendingTxsSlice.ts @@ -17,8 +17,6 @@ export enum PendingTxType { SAFE_TX = 'SAFE_TX', } -const ActivePendingStates = [PendingStatus.RELAYING, PendingStatus.INDEXING, PendingStatus.PROCESSING] - export type PendingTxCommonProps = { chainId: string safeAddress: string diff --git a/src/store/txHistorySlice.ts b/src/store/txHistorySlice.ts index 6424131da1..80b1e35aeb 100644 --- a/src/store/txHistorySlice.ts +++ b/src/store/txHistorySlice.ts @@ -37,7 +37,7 @@ export const txHistoryListener = (listenerMiddleware: typeof listenerMiddlewareI continue } - const pendingTxByNonce = Object.entries(pendingTxs).find(([txId, pendingTx]) => + const pendingTxByNonce = Object.entries(pendingTxs).find(([, pendingTx]) => isMultisigExecutionInfo(result.transaction.executionInfo) ? pendingTx.nonce === result.transaction.executionInfo.nonce : false, diff --git a/src/tests/pages/apps.test.tsx b/src/tests/pages/apps.test.tsx index 84e0d11298..1349af7d11 100644 --- a/src/tests/pages/apps.test.tsx +++ b/src/tests/pages/apps.test.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import { userEvent } from '@testing-library/user-event' +import React, { act } from 'react' import * as safeAppsGatewaySDK from '@safe-global/safe-gateway-typescript-sdk' import { SafeAppFeatures } from '@safe-global/safe-gateway-typescript-sdk' import type { SafeAppData } from '@safe-global/safe-gateway-typescript-sdk' @@ -8,7 +9,6 @@ import { screen, waitFor, fireEvent, - act, getByRole, getByText, waitForElementToBeRemoved, @@ -22,7 +22,7 @@ import * as chainHooks from '@/hooks/useChains' jest.mock('@safe-global/safe-gateway-typescript-sdk', () => ({ ...jest.requireActual('@safe-global/safe-gateway-typescript-sdk'), - getSafeApps: (chainId: string) => Promise.resolve(mockedSafeApps), + getSafeApps: () => Promise.resolve(mockedSafeApps), })) jest.mock('next/navigation', () => ({ @@ -201,7 +201,7 @@ describe('AppsPage', () => { // Add custom app modal is not present expect(screen.queryByRole('presentation')).not.toBeInTheDocument() - await act(() => { + act(() => { fireEvent.click(screen.getByRole('button', { name: 'Add custom Safe App' })) }) @@ -258,7 +258,7 @@ describe('AppsPage', () => { }), ).toBeInTheDocument(), ) - await act(() => { + act(() => { fireEvent.click(screen.getByText('Add')) }) @@ -298,7 +298,7 @@ describe('AppsPage', () => { }) await waitFor(() => expect(screen.getByText('Add custom Safe App')).toBeInTheDocument()) const addCustomAppButton = screen.getByText('Add custom Safe App') - await act(() => { + act(() => { fireEvent.click(addCustomAppButton) }) await waitFor(() => expect(screen.getByLabelText(/Safe App URL/)).toBeInTheDocument(), { timeout: 3000 }) @@ -336,23 +336,22 @@ describe('AppsPage', () => { }, }) await waitFor(() => expect(screen.getByText('Add custom Safe App')).toBeInTheDocument()) + const addCustomAppButton = screen.getByText('Add custom Safe App') - await act(() => { - fireEvent.click(addCustomAppButton) - }) + await userEvent.click(addCustomAppButton) + await waitFor(() => expect(screen.getByLabelText(/Safe App URL/)).toBeInTheDocument(), { timeout: 3000 }) + const appURLInput = screen.getByLabelText(/Safe App URL/) - fireEvent.change(appURLInput, { target: { value: APP_URL } }) + await userEvent.type(appURLInput, APP_URL) + const riskCheckbox = await screen.findByText( /This Safe App is not part of Safe{Wallet} and I agree to use it at my own risk\./, ) - await act(() => { - fireEvent.click(riskCheckbox) - }) - await act(() => { - fireEvent.click(riskCheckbox) - }) - fireEvent.click(screen.getByText('Add')) + + await userEvent.click(riskCheckbox) + await userEvent.click(riskCheckbox) + await waitFor(() => expect(screen.getByText('Accepting the disclaimer is mandatory')).toBeInTheDocument()) }) @@ -399,7 +398,7 @@ describe('AppsPage', () => { }), ).toBeInTheDocument(), ) - await act(() => { + act(() => { fireEvent.click(screen.getByText('Add')) }) @@ -408,14 +407,14 @@ describe('AppsPage', () => { const removeCustomSafeAppButton = screen.getByLabelText('Delete Custom test Safe app') - await act(() => { + act(() => { fireEvent.click(removeCustomSafeAppButton) }) await waitFor(() => expect(screen.getByText('Confirm Safe App removal')).toBeInTheDocument()) const confirmRemovalButton = screen.getByRole('button', { name: 'Remove' }) - await act(() => { + act(() => { fireEvent.click(confirmRemovalButton) }) @@ -511,7 +510,7 @@ describe('AppsPage', () => { const searchInput = screen.getByPlaceholderText('Search by name or category') - await act(() => fireEvent.change(searchInput, { target: { value: query } })) + act(() => fireEvent.change(searchInput, { target: { value: query } })) await waitFor(() => { expect(screen.queryByText('Compound', { selector: 'h5' })).not.toBeInTheDocument() @@ -546,7 +545,7 @@ describe('AppsPage', () => { const categorySelector = screen.getByText('Select category') - await act(() => fireEvent.mouseDown(categorySelector)) + act(() => fireEvent.mouseDown(categorySelector)) const categoriesDropdown = within(screen.getByRole('listbox')) @@ -557,22 +556,23 @@ describe('AppsPage', () => { await waitFor(() => expect(categoriesDropdown.queryByText('transaction-builder')).not.toBeInTheDocument()) // filter by Infrastructure category - await act(() => fireEvent.click(categoriesDropdown.getByText('Infrastructure'))) + act(() => { + fireEvent.click(categoriesDropdown.getByText('Infrastructure')) + }) // close the dropdown - await act(() => + act(() => { fireEvent.keyDown(screen.getByRole('listbox'), { key: 'Escape', code: 'Escape', keyCode: 27, charCode: 27, - }), - ) - - // 1 categories selected label - expect(screen.queryByText('1 categories selected')).toBeInTheDocument() + }) + }) await waitFor(() => { + // 1 categories selected label + expect(screen.queryByText('1 categories selected')).toBeInTheDocument() expect(screen.queryByText('Compound', { selector: 'h5' })).not.toBeInTheDocument() expect(screen.queryByText('ENS App', { selector: 'h5' })).not.toBeInTheDocument() expect(screen.queryByText('Transaction Builder', { selector: 'h5' })).toBeInTheDocument() @@ -599,12 +599,12 @@ describe('AppsPage', () => { const categorySelector = screen.getByText('Select category') - await act(() => fireEvent.mouseDown(categorySelector)) + act(() => fireEvent.mouseDown(categorySelector)) const categoriesDropdown = within(screen.getByRole('listbox')) // filter by Infrastructure category - await act(() => fireEvent.click(categoriesDropdown.getByText('Infrastructure'))) + act(() => fireEvent.click(categoriesDropdown.getByText('Infrastructure'))) await waitFor(() => { expect(screen.queryByText('Compound', { selector: 'h5' })).not.toBeInTheDocument() @@ -614,10 +614,10 @@ describe('AppsPage', () => { }) // clear active Infrastructure filter - await act(() => fireEvent.click(categoriesDropdown.getByText('Infrastructure'))) + act(() => fireEvent.click(categoriesDropdown.getByText('Infrastructure'))) // close the dropdown - await act(() => + act(() => fireEvent.keyDown(screen.getByRole('listbox'), { key: 'Escape', code: 'Escape', @@ -654,12 +654,12 @@ describe('AppsPage', () => { const categorySelector = screen.getByText('Select category') - await act(() => fireEvent.mouseDown(categorySelector)) + act(() => fireEvent.mouseDown(categorySelector)) const categoriesDropdown = within(screen.getByRole('listbox')) // filter by Infrastructure category - await act(() => fireEvent.click(categoriesDropdown.getByText('Infrastructure'))) + act(() => fireEvent.click(categoriesDropdown.getByText('Infrastructure'))) await waitFor(() => { expect(screen.queryByText('Compound', { selector: 'h5' })).not.toBeInTheDocument() @@ -669,7 +669,7 @@ describe('AppsPage', () => { }) // close the dropdown - await act(() => + act(() => fireEvent.keyDown(screen.getByRole('listbox'), { key: 'Escape', code: 'Escape', @@ -679,7 +679,7 @@ describe('AppsPage', () => { ) // clear all selected filters - await act(() => fireEvent.click(screen.getByLabelText('clear selected categories'))) + act(() => fireEvent.click(screen.getByLabelText('clear selected categories'))) // show all safe apps again await waitFor(() => { @@ -710,7 +710,7 @@ describe('AppsPage', () => { }) // filter by optimized for batch transactions - await act(() => fireEvent.click(screen.getByRole('checkbox', { checked: false }))) + act(() => fireEvent.click(screen.getByRole('checkbox', { checked: false }))) // show only transaction builder safe app await waitFor(() => { @@ -739,10 +739,10 @@ describe('AppsPage', () => { }) // filter by optimized for batch transactions - await act(() => fireEvent.click(screen.getByRole('checkbox', { checked: false }))) + act(() => fireEvent.click(screen.getByRole('checkbox', { checked: false }))) // clears the optimized for batch transactions filter - await act(() => fireEvent.click(screen.getByRole('checkbox', { checked: true }))) + act(() => fireEvent.click(screen.getByRole('checkbox', { checked: true }))) // show all safe apps await waitFor(() => { diff --git a/src/utils/__tests__/SimpleTxWatcher.test.ts b/src/utils/__tests__/SimpleTxWatcher.test.ts index 32e8457715..5e27b09aee 100644 --- a/src/utils/__tests__/SimpleTxWatcher.test.ts +++ b/src/utils/__tests__/SimpleTxWatcher.test.ts @@ -167,7 +167,7 @@ describe('SimpleTxWatcher', () => { off: jest.fn(), } as unknown as JsonRpcProvider const txHash = `0x${faker.number.hex()}` - const result = watcher.watchTxHash(txHash, faker.finance.ethereumAddress(), 0, mockProvider).catch((error) => error) + watcher.watchTxHash(txHash, faker.finance.ethereumAddress(), 0, mockProvider).catch((error) => error) expect(mockProvider.on).toHaveBeenCalledTimes(1) expect(mockProvider.getTransactionReceipt).not.toHaveBeenCalled() diff --git a/src/utils/transactions.ts b/src/utils/transactions.ts index 304f5555e1..cf2ff95c8b 100644 --- a/src/utils/transactions.ts +++ b/src/utils/transactions.ts @@ -4,7 +4,6 @@ import type { MultisigExecutionDetails, MultisigExecutionInfo, SafeAppData, - SafeInfo, Transaction, TransactionDetails, TransactionListPage, @@ -95,9 +94,9 @@ export const makeTxFromDetails = (txDetails: TransactionDetails): Transaction => const getSignatures = (confirmations: Record) => { return Object.entries(confirmations) - .filter(([_, signature]) => Boolean(signature)) + .filter(([, signature]) => Boolean(signature)) .sort(([signerA], [signerB]) => signerA.toLowerCase().localeCompare(signerB.toLowerCase())) - .reduce((prev, [_, signature]) => { + .reduce((prev, [, signature]) => { return prev + signature.slice(2) }, '0x') } @@ -200,8 +199,6 @@ export const getTxOrigin = (app?: Partial): string | undefined => { return origin } -export const hasEnoughSignatures = (tx: SafeTransaction, safe: SafeInfo) => tx.signatures.size >= safe.threshold - const multiSendInterface = Multi_send__factory.createInterface() const multiSendFragment = multiSendInterface.getFunction('multiSend') diff --git a/src/utils/tx-history-filter.ts b/src/utils/tx-history-filter.ts index e6f4b8e1db..62788697d3 100644 --- a/src/utils/tx-history-filter.ts +++ b/src/utils/tx-history-filter.ts @@ -31,7 +31,7 @@ export type TxFilter = { export const _omitNullish = (data: { [key: string]: any }) => { return Object.fromEntries( - Object.entries(data).filter(([_, value]) => { + Object.entries(data).filter(([, value]) => { return value !== '' && value != null }), )