From 87da2a602d24d5c8772ba734433a9524921b174f Mon Sep 17 00:00:00 2001 From: Josef Date: Tue, 27 Aug 2024 16:21:25 +0200 Subject: [PATCH] wip: new eslint rules and fix/ignore errors (#1721) * wip: new eslint rules and fix/ignore errors * chore: syncpack format * chore: prettier format * dirs * lint * lint, handleChange callback * lint, simplify AddressViewComponent * chore: ignore nested ternaries * feat: enable non-null assertions and ignore existing errors --------- Co-authored-by: turbocrime --- .../components/ibc/ibc-in/assets-table.tsx | 2 +- .../ibc/ibc-in/cosmos-wallet-connector.tsx | 2 +- .../src/components/ibc/ibc-in/hooks.ts | 7 +- .../components/ibc/ibc-in/ibc-in-request.tsx | 2 +- .../components/ibc/ibc-in/interchain-ui.tsx | 2 +- .../components/shared/selectors/helpers.ts | 3 +- .../shared/selectors/loading-indicator.tsx | 2 +- .../validator-state-label.tsx | 2 +- .../end-or-withdraw-all-button.tsx | 1 + .../src/components/swap/duration-slider.tsx | 2 + .../src/components/tx-details/index.tsx | 1 + .../src/components/tx-details/tx-viewer.tsx | 14 +- .../src/fetchers/balances/by-asset.ts | 1 + apps/minifront/src/fetchers/page-path.ts | 8 +- apps/minifront/src/state/helpers.ts | 1 + apps/minifront/src/state/ibc-in/index.tsx | 1 + .../parse-revision-number-from-chain-id.ts | 1 + apps/minifront/src/state/ibc-out.ts | 1 + apps/minifront/src/state/staking/index.ts | 1 + apps/minifront/src/state/swap/instant-swap.ts | 1 + apps/node-status/src/components/node-info.tsx | 2 +- apps/node-status/src/components/sync-info.tsx | 2 +- .../src/components/validator-info.tsx | 2 +- eslint.config.js | 88 +++--- package.json | 3 +- packages/bech32m/src/test/util/corrupt.ts | 2 + packages/client/src/client.ts | 1 + packages/crypto/src/mnemonic.ts | 1 + .../src/plan/view-transaction-plan.test.ts | 2 +- .../src/translators/action-view.ts | 1 + packages/query/src/block-processor.ts | 21 +- packages/query/src/queriers/shielded-pool.ts | 2 +- packages/query/src/queriers/tendermint.ts | 2 +- .../custody-service/validation/authorize.ts | 1 + .../src/view-service/app-parameters.ts | 1 + .../services/src/view-service/balances.ts | 3 +- .../view-service/transaction-planner/index.ts | 1 + .../transport-chrome/src/session-client.ts | 1 + packages/transport-dom/src/create.test.ts | 6 +- packages/transport-dom/src/messages.ts | 2 +- packages/types/src/base64.ts | 3 +- packages/types/src/hex.ts | 3 +- packages/types/src/jsonified.ts | 4 +- packages/types/src/lo-hi.test.ts | 1 + packages/types/src/lo-hi.ts | 2 + .../ui/components/ui/address-view/index.tsx | 6 +- .../ui/components/ui/asset-icon/index.tsx | 44 ++- .../components/ui/candlestick-plot/index.tsx | 2 + packages/ui/components/ui/card/index.tsx | 1 + packages/ui/components/ui/command/index.tsx | 1 + .../copy-to-clipboard-icon-button.tsx | 2 +- .../expanded-details/get-step-index.ts | 1 + .../ui/components/ui/identicon/generate.ts | 1 + .../ui/components/ui/logo/animation-logic.ts | 21 +- .../ui/components/ui/logo/perlin-noise.ts | 1 + packages/ui/components/ui/logo/static.tsx | 22 +- .../components/ui/select/select-account.tsx | 88 +++--- packages/ui/components/ui/separator/index.tsx | 2 +- packages/ui/components/ui/tx/memo-view.tsx | 1 + packages/ui/components/ui/tx/viewbox.tsx | 10 +- packages/ui/components/ui/value/index.tsx | 2 +- packages/ui/package.json | 4 +- .../AccountSelectorAddress.tsx | 1 + .../ui/src/AccountSelector/index.stories.tsx | 2 +- .../ui/src/AddressViewComponent/index.tsx | 29 +- packages/ui/src/AssetIcon/index.tsx | 7 +- packages/ui/src/Button/index.tsx | 4 +- packages/ui/src/CharacterTransition/index.tsx | 1 + packages/ui/src/Colors.stories.tsx | 15 +- packages/ui/src/ConditionalWrap/index.tsx | 1 + packages/ui/src/Dialog/index.test.tsx | 16 +- packages/ui/src/Identicon/generate.ts | 1 + packages/ui/src/PenumbraUIProvider/theme.ts | 3 +- packages/ui/src/SegmentedControl/index.tsx | 19 +- packages/ui/src/TextInput/index.tsx | 47 ++-- packages/ui/src/Toggle/index.tsx | 3 +- packages/ui/src/ValueViewComponent/index.tsx | 3 +- .../useAnimationDeferredValue/index.test.tsx | 12 +- .../ui/src/hooks/useDisabled/index.test.tsx | 4 +- packages/wasm/src/view-server.ts | 2 +- packages/zquery/src/index.test.ts | 6 +- pnpm-lock.yaml | 251 ++++++++++++++++-- 82 files changed, 551 insertions(+), 297 deletions(-) diff --git a/apps/minifront/src/components/ibc/ibc-in/assets-table.tsx b/apps/minifront/src/components/ibc/ibc-in/assets-table.tsx index 76a2485474..d79ea232eb 100644 --- a/apps/minifront/src/components/ibc/ibc-in/assets-table.tsx +++ b/apps/minifront/src/components/ibc/ibc-in/assets-table.tsx @@ -20,7 +20,7 @@ export const AssetsTable = () => { // User has not connected their wallet yet if (!address || !selectedChain) { - return <>; + return; } if (isLoading) { diff --git a/apps/minifront/src/components/ibc/ibc-in/cosmos-wallet-connector.tsx b/apps/minifront/src/components/ibc/ibc-in/cosmos-wallet-connector.tsx index 57a5f42507..fa33bd8b10 100644 --- a/apps/minifront/src/components/ibc/ibc-in/cosmos-wallet-connector.tsx +++ b/apps/minifront/src/components/ibc/ibc-in/cosmos-wallet-connector.tsx @@ -10,7 +10,7 @@ export const CosmosWalletConnector = () => { const { username, address, status, message } = useChainConnector(); if (!selectedChain) { - return <>; + return; } return ( diff --git a/apps/minifront/src/components/ibc/ibc-in/hooks.ts b/apps/minifront/src/components/ibc/ibc-in/hooks.ts index 3ea11187fd..4d7994c643 100644 --- a/apps/minifront/src/components/ibc/ibc-in/hooks.ts +++ b/apps/minifront/src/components/ibc/ibc-in/hooks.ts @@ -108,16 +108,16 @@ interface UseCosmosChainBalancesRes { } const getIconFromAsset = (asset: Asset): string | undefined => { - // Image default is "" and thus cannot do nullish-coalescing - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Image default is "" and thus cannot do nullish-coalescing const logoUri = asset.logo_URIs?.svg || asset.logo_URIs?.png; if (logoUri) { return logoUri; } if (asset.images?.length) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const first = asset.images[0]!; - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Image default is "" and thus cannot do nullish-coalescing return first.svg || first.svg; } return undefined; @@ -131,6 +131,7 @@ const generatePenumbraIbcDenoms = async (chains: Chain[]): Promise => const ibcStr = `transfer/${c.counterpartyChannelId}/upenumbra`; const encoder = new TextEncoder(); const encodedString = encoder.encode(ibcStr); + const hash = await sha256HashStr(encodedString); ibcAddrs.push(`ibc/${hash.toUpperCase()}`); } diff --git a/apps/minifront/src/components/ibc/ibc-in/ibc-in-request.tsx b/apps/minifront/src/components/ibc/ibc-in/ibc-in-request.tsx index b0c44a1cbb..3112541506 100644 --- a/apps/minifront/src/components/ibc/ibc-in/ibc-in-request.tsx +++ b/apps/minifront/src/components/ibc/ibc-in/ibc-in-request.tsx @@ -32,7 +32,7 @@ export const IbcInRequest = () => { // User is not ready to issue request if (!address || !selectedChain || !data?.length) { - return <>; + return; } return ( diff --git a/apps/minifront/src/components/ibc/ibc-in/interchain-ui.tsx b/apps/minifront/src/components/ibc/ibc-in/interchain-ui.tsx index cb44990436..bcc304ca6a 100644 --- a/apps/minifront/src/components/ibc/ibc-in/interchain-ui.tsx +++ b/apps/minifront/src/components/ibc/ibc-in/interchain-ui.tsx @@ -12,7 +12,7 @@ export const InterchainUi = () => { return
Error trying to load registry!
; } if (!data) { - return <>; + return; } if (!data.ibcConnections.length) { return
No known IBC connections available for {data.chainId}
; diff --git a/apps/minifront/src/components/shared/selectors/helpers.ts b/apps/minifront/src/components/shared/selectors/helpers.ts index 13a901cc19..94f7c0ae4e 100644 --- a/apps/minifront/src/components/shared/selectors/helpers.ts +++ b/apps/minifront/src/components/shared/selectors/helpers.ts @@ -53,7 +53,6 @@ export const useSyncSelectedBalance = ({ onChange(matchedValue); } } - // we only want to run this on new balances from ZQuery, so don't include `value` as dependency - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps -- we only want to run this on new balances from ZQuery, so don't include `value` as dependency }, [balances]); }; diff --git a/apps/minifront/src/components/shared/selectors/loading-indicator.tsx b/apps/minifront/src/components/shared/selectors/loading-indicator.tsx index af2eea0271..554d7559ac 100644 --- a/apps/minifront/src/components/shared/selectors/loading-indicator.tsx +++ b/apps/minifront/src/components/shared/selectors/loading-indicator.tsx @@ -3,7 +3,7 @@ import { LineWave } from 'react-loader-spinner'; import resolveConfig from 'tailwindcss/resolveConfig'; import tailwindConfig from '@repo/tailwind-config'; -// eslint-disable-next-line +// eslint-disable-next-line -- TODO: explain const lightGrey: string = (resolveConfig(tailwindConfig).theme.colors as any)['light-grey'].DEFAULT; /** diff --git a/apps/minifront/src/components/staking/account/delegation-value-view/validator-state-label.tsx b/apps/minifront/src/components/staking/account/delegation-value-view/validator-state-label.tsx index 53a1e94fff..e248549f0a 100644 --- a/apps/minifront/src/components/staking/account/delegation-value-view/validator-state-label.tsx +++ b/apps/minifront/src/components/staking/account/delegation-value-view/validator-state-label.tsx @@ -24,7 +24,7 @@ const getStateLabel = (state: ValidatorState_ValidatorStateEnum) => export const ValidatorStateLabel = ({ state }: { state: ValidatorState_ValidatorStateEnum }) => { if (state === ValidatorState_ValidatorStateEnum.ACTIVE) { - return <>; + return; } const { label, color } = getStateLabel(state); diff --git a/apps/minifront/src/components/swap/auction-list/end-or-withdraw-all-button.tsx b/apps/minifront/src/components/swap/auction-list/end-or-withdraw-all-button.tsx index fa82d5b59b..70c2877ea6 100644 --- a/apps/minifront/src/components/swap/auction-list/end-or-withdraw-all-button.tsx +++ b/apps/minifront/src/components/swap/auction-list/end-or-withdraw-all-button.tsx @@ -40,6 +40,7 @@ export const assembleAuctionBatch = ( a => a.addressIndex.equals(firstFoundAddressIndex), batchLimit, ); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify return { auctions: filteredBySeqAndAddressIndexAuctions, source: firstFoundAddressIndex! }; }; diff --git a/apps/minifront/src/components/swap/duration-slider.tsx b/apps/minifront/src/components/swap/duration-slider.tsx index fd63be04fa..eb26df0286 100644 --- a/apps/minifront/src/components/swap/duration-slider.tsx +++ b/apps/minifront/src/components/swap/duration-slider.tsx @@ -12,7 +12,9 @@ export const DurationSlider = () => { const { duration, setDuration } = useStoreShallow(durationSliderSelector); const handleChange = (newValue: number[]) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const value = newValue[0]!; // We don't use multiple values in the slider + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const option = DURATION_OPTIONS[value]!; setDuration(option); diff --git a/apps/minifront/src/components/tx-details/index.tsx b/apps/minifront/src/components/tx-details/index.tsx index 370e4157c4..86d9428ce5 100644 --- a/apps/minifront/src/components/tx-details/index.tsx +++ b/apps/minifront/src/components/tx-details/index.tsx @@ -16,6 +16,7 @@ export const TxDetailsErrorBoundary = () => { export const TxDetails = () => { const { hash } = useParams<{ hash: string }>(); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify const txInfo = useTransactionInfo(undefined, hash!); if ( diff --git a/apps/minifront/src/components/tx-details/tx-viewer.tsx b/apps/minifront/src/components/tx-details/tx-viewer.tsx index 61e5738c3c..211aefae31 100644 --- a/apps/minifront/src/components/tx-details/tx-viewer.tsx +++ b/apps/minifront/src/components/tx-details/tx-viewer.tsx @@ -49,7 +49,11 @@ export const TxViewer = ({ txInfo }: { txInfo?: TransactionInfo }) => { // use React-Query to invoke custom hooks that call async translators. const { data: receiverView } = useQuery( ['receiverView', txInfo, option], - () => fetchReceiverView(txInfo!), + () => + fetchReceiverView( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify + txInfo!, + ), { enabled: option === TxDetailsTab.RECEIVER && !!txInfo, }, @@ -80,7 +84,13 @@ export const TxViewer = ({ txInfo }: { txInfo?: TransactionInfo }) => { {option === TxDetailsTab.PRIVATE && txInfo && ( <> - +
Raw JSON
} /> diff --git a/apps/minifront/src/fetchers/balances/by-asset.ts b/apps/minifront/src/fetchers/balances/by-asset.ts index 292973ad0c..8e2f48a912 100644 --- a/apps/minifront/src/fetchers/balances/by-asset.ts +++ b/apps/minifront/src/fetchers/balances/by-asset.ts @@ -13,6 +13,7 @@ export const groupByAsset = (acc: ValueView[], curr: BalancesResponse): ValueVie throw new Error('No amount in value view'); } + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify const grouping = acc.find(v => hasMatchingAssetId(v, curr.balanceView!)); if (grouping) { diff --git a/apps/minifront/src/fetchers/page-path.ts b/apps/minifront/src/fetchers/page-path.ts index 1fc923ba94..8046795866 100644 --- a/apps/minifront/src/fetchers/page-path.ts +++ b/apps/minifront/src/fetchers/page-path.ts @@ -14,17 +14,17 @@ export const usePagePath = () => { export const matchPagePath = (str: string): PagePath => { /** @todo: Remove next line after we switch to v2 layout */ - str = str.replace('/v2', ''); + const strFixed = str.replace('/v2', ''); const pathValues = Object.values(PagePath); - if (pathValues.includes(str as PagePath)) { - return str as PagePath; + if (pathValues.includes(strFixed as PagePath)) { + return strFixed as PagePath; } for (const pathValue of pathValues) { if (pathValue.includes(':')) { const regex = new RegExp('^' + pathValue.replace(/:(\w+)/g, '([^/]+)') + '$'); - const match = str.match(regex); + const match = strFixed.match(regex); if (match) { return pathValue as PagePath; } diff --git a/apps/minifront/src/state/helpers.ts b/apps/minifront/src/state/helpers.ts index 6c658192bc..3ebe9df822 100644 --- a/apps/minifront/src/state/helpers.ts +++ b/apps/minifront/src/state/helpers.ts @@ -112,6 +112,7 @@ const build = async ( case 'buildProgress': break; case 'complete': + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify return status.value.transaction!; default: console.warn(`unknown ${buildFn.name} status`, status); diff --git a/apps/minifront/src/state/ibc-in/index.tsx b/apps/minifront/src/state/ibc-in/index.tsx index 557896ab5d..787d0295a8 100644 --- a/apps/minifront/src/state/ibc-in/index.tsx +++ b/apps/minifront/src/state/ibc-in/index.tsx @@ -131,6 +131,7 @@ const getExplorerPage = (txHash: string, chainId?: string) => { return undefined; } + // eslint-disable-next-line no-template-curly-in-string -- Intended template string return txPage.replace('${txHash}', txHash); }; diff --git a/apps/minifront/src/state/ibc-in/parse-revision-number-from-chain-id.ts b/apps/minifront/src/state/ibc-in/parse-revision-number-from-chain-id.ts index 0b4897b182..d366dc30d8 100644 --- a/apps/minifront/src/state/ibc-in/parse-revision-number-from-chain-id.ts +++ b/apps/minifront/src/state/ibc-in/parse-revision-number-from-chain-id.ts @@ -13,6 +13,7 @@ export const parseRevisionNumberFromChainId = (chainId: string): bigint => { return 0n; } + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const numStr = chainId.split('-').pop()!; return BigInt(numStr); }; diff --git a/apps/minifront/src/state/ibc-out.ts b/apps/minifront/src/state/ibc-out.ts index 0ccfb55e1e..516319b603 100644 --- a/apps/minifront/src/state/ibc-out.ts +++ b/apps/minifront/src/state/ibc-out.ts @@ -291,6 +291,7 @@ export const filterBalancesPerChain = ( } return chain?.channelId === match.channel; }) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify .map(m => m.penumbraAssetId!); const assetIdsToCheck = [...assetsWithMatchingChannel]; diff --git a/apps/minifront/src/state/staking/index.ts b/apps/minifront/src/state/staking/index.ts index d69c65971b..cfcb0ba846 100644 --- a/apps/minifront/src/state/staking/index.ts +++ b/apps/minifront/src/state/staking/index.ts @@ -395,6 +395,7 @@ const assembleUndelegateRequest = ({ }: StakingSlice) => { const delegation = delegationsByAccount .get(account) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify ?.find(delegation => isDelegationTokenForValidator(delegation, validatorInfo!)); if (!delegation) { throw new Error('Tried to assemble undelegate request from account with no delegation tokens'); diff --git a/apps/minifront/src/state/swap/instant-swap.ts b/apps/minifront/src/state/swap/instant-swap.ts index 8a8a751ccc..8f0f9c5227 100644 --- a/apps/minifront/src/state/swap/instant-swap.ts +++ b/apps/minifront/src/state/swap/instant-swap.ts @@ -234,6 +234,7 @@ const calculatePriceImpact = (swapExec?: SwapExecution): number | undefined => { // Get the price in the best execution trace const inputAssetId = getAssetIdFromValue(swapExec.input); const outputAssetId = getAssetIdFromValue(swapExec.output); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const bestTrace = swapExec.traces[0]!; const bestInputAmount = getMatchingAmount(bestTrace.value, inputAssetId); const bestOutputAmount = getMatchingAmount(bestTrace.value, outputAssetId); diff --git a/apps/node-status/src/components/node-info.tsx b/apps/node-status/src/components/node-info.tsx index 031176d39a..ba0c0322d4 100644 --- a/apps/node-status/src/components/node-info.tsx +++ b/apps/node-status/src/components/node-info.tsx @@ -9,7 +9,7 @@ export const NodeInfo = () => { status: { nodeInfo }, } = useLoaderData() as IndexLoaderResponse; if (!nodeInfo) { - return <>; + return; } return ( diff --git a/apps/node-status/src/components/sync-info.tsx b/apps/node-status/src/components/sync-info.tsx index 1d1dd53beb..8cfd25507e 100644 --- a/apps/node-status/src/components/sync-info.tsx +++ b/apps/node-status/src/components/sync-info.tsx @@ -23,7 +23,7 @@ export const SyncInfo = () => { latestAppHash, } = useLoaderData() as IndexLoaderResponse; if (!syncInfo) { - return <>; + return; } const { date, time } = getFormattedTime(syncInfo); diff --git a/apps/node-status/src/components/validator-info.tsx b/apps/node-status/src/components/validator-info.tsx index 2bbc97bde7..2f90de6980 100644 --- a/apps/node-status/src/components/validator-info.tsx +++ b/apps/node-status/src/components/validator-info.tsx @@ -27,7 +27,7 @@ export const ValidatorInfo = () => { status: { validatorInfo }, } = useLoaderData() as IndexLoaderResponse; if (!validatorInfo) { - return <>; + return; } return ( diff --git a/eslint.config.js b/eslint.config.js index 53d821ce81..0a3d1a1eb2 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,7 +1,8 @@ // @ts-check import { createRequire } from 'node:module'; - +// @ts-expect-error https://github.com/eslint-community/eslint-plugin-eslint-comments/issues/214 +import ESLintPluginESLintCommentsConfigs from '@eslint-community/eslint-plugin-eslint-comments/configs'; import { fixupPluginRules } from '@eslint/compat'; import eslint from '@eslint/js'; import * as import_ from 'eslint-plugin-import'; @@ -31,9 +32,17 @@ const storybookPluginConfigs = tseslint.config( }, ); +// The plugin is not currently exported from the root, so we have to get the plugin from the config. +// https://github.com/eslint-community/eslint-plugin-eslint-comments/issues/215 +const ESLintPluginESLintComments = + ESLintPluginESLintCommentsConfigs.recommended.plugins['@eslint-community/eslint-comments']; + export default tseslint.config( // completely ignored files - { name: 'custom:ignores', ignores: ['vitest.workspace.ts', 'dist', 'node_modules'] }, + { + name: 'custom:ignores', + ignores: ['vitest.workspace.ts', 'dist', 'node_modules', 'vite-env.d.ts'], + }, // base javascript config eslint.configs.recommended, @@ -47,6 +56,16 @@ export default tseslint.config( languageOptions: { parser: tseslint.parser, parserOptions: { project: true } }, }, + { + name: 'custom:eslint-comments', + plugins: { + '@eslint-community/eslint-comments': ESLintPluginESLintComments, + }, + rules: { + '@eslint-community/eslint-comments/require-description': ['error', { ignore: [] }], + }, + }, + // tailwind config { name: 'custom:tailwindcss-config', @@ -74,18 +93,15 @@ export default tseslint.config( rules: { ...react.configs.recommended.rules, ...react_hooks.configs.recommended.rules, - 'react-hooks/exhaustive-deps': 'warn', + 'react-hooks/exhaustive-deps': 'error', 'react-hooks/rules-of-hooks': 'error', - }, - }, - { - name: 'custom:react-wishlist-improvements', - rules: { - // this plugin was formerly included, but was never actually applied. + 'react/jsx-no-useless-fragment': [ + 'error', + { + allowExpressions: true, + }, + ], 'react-refresh/only-export-components': 'off', - - //'react/jsx-no-literals': 'warn', - //'react/jsx-no-useless-fragment': 'warn', }, }, @@ -177,39 +193,33 @@ export default tseslint.config( name: 'custom:typescript-wishlist-improvements', files: ['**/*.@(ts|tsx)'], rules: { - // enabled by tseslint strictTypeChecked. large diff - '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-non-null-assertion': 'error', - //'@typescript-eslint/no-redeclare': 'error', - //'@typescript-eslint/no-shadow': 'error', - //'@typescript-eslint/restrict-template-expressions': ['error', { allowNumber: true }], + // '@typescript-eslint/no-redeclare': 'error', + // '@typescript-eslint/no-shadow': 'error', + // '@typescript-eslint/restrict-template-expressions': ['error', { allowNumber: true }], }, }, { name: 'custom:eslint-wishlist-improvements', rules: { - //'array-callback-return': 'warn', - //'class-methods-use-this': 'warn', - //'consistent-return': 'warn', - //'consistent-this': 'error', - //'func-name-matching': 'warn', - //'no-await-in-loop': 'warn', - //'no-bitwise': 'warn', - //'no-console': 'warn', - //'no-continue': 'warn', - //'no-nested-ternary': 'warn', - //'no-param-reassign': 'error', - //'no-plusplus': 'error', - //'no-promise-executor-return': ['error', { allowVoid: true }], - //'no-restricted-globals': [ 'error', { message: 'Use `globalThis` instead.', name: 'global' }, { message: 'Use `globalThis` instead.', name: 'self' }, ], - //'no-self-assign': ['error', { props: true }], - //'no-template-curly-in-string': 'warn', - //'no-unreachable-loop': 'warn', - //'no-warning-comments': 'warn', - //'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }], - //'spaced-comment': 'warn', - //complexity: 'warn', + 'no-bitwise': 'error', + 'no-console': ['error', { allow: ['warn', 'error', 'debug'] }], + 'no-nested-ternary': 'warn', + 'no-param-reassign': 'error', + 'no-promise-executor-return': ['error', { allowVoid: true }], + 'no-restricted-globals': [ + 'error', + { message: 'Use `globalThis` instead.', name: 'global' }, + { message: 'Use `globalThis` instead.', name: 'self' }, + ], + 'no-self-assign': ['error', { props: true }], + 'no-template-curly-in-string': 'warn', + 'no-unreachable-loop': 'warn', + 'no-warning-comments': 'off', + 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }], + 'spaced-comment': ['error', 'always', { markers: ['/'] }], }, }, @@ -233,10 +243,12 @@ export default tseslint.config( '**/*.story.@(ts|tsx|js|jsx|mjs|cjs)', ], rules: { + 'no-console': 'off', '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/prefer-promise-reject-errors': 'off', 'react/display-name': 'off', + '@eslint-community/eslint-comments/require-description': 'off', }, }, diff --git a/package.json b/package.json index d0e2bae8db..33b4375df3 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@buf/connectrpc_eliza.bufbuild_es": "1.10.0-20230913231627-233fca715f49.1", "@buf/connectrpc_eliza.connectrpc_es": "1.4.0-20230913231627-233fca715f49.3", "@changesets/cli": "^2.27.3", + "@eslint-community/eslint-plugin-eslint-comments": "^4.4.0", "@eslint/compat": "^1.1.0", "@eslint/js": "^9.6.0", "@microsoft/api-extractor": "^7.47.0", @@ -62,7 +63,7 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-import-x": "^0.5.3", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "7.8.0-rc.0", + "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "5.1.0-rc-c3cdbec0a7-20240708", "eslint-plugin-react-refresh": "^0.4.8", "eslint-plugin-storybook": "0.9.0--canary.156.ed236ca.0", diff --git a/packages/bech32m/src/test/util/corrupt.ts b/packages/bech32m/src/test/util/corrupt.ts index d2de008754..2dbcb9cb76 100644 --- a/packages/bech32m/src/test/util/corrupt.ts +++ b/packages/bech32m/src/test/util/corrupt.ts @@ -25,8 +25,10 @@ export const corruptBech32 = (goodBech32: string, change?: { i: number; c: strin export const generateInvalid = (okBytes: Uint8Array, okString: string, innerName = 'inner') => { const prefix = okString.slice(0, okString.lastIndexOf('1')); return { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion longBytes: { [innerName]: new Uint8Array([...okBytes, okBytes[0]!]) }, shortBytes: { [innerName]: okBytes.slice(1) }, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion longString: bech32m.encode(prefix, bech32m.toWords([...okBytes, okBytes[0]!]), Infinity), shortString: bech32m.encode(prefix, bech32m.toWords(okBytes.slice(1)), Infinity), corruptString: corruptBech32(okString), diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index ff96c4e3bb..d331d0c274 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -283,6 +283,7 @@ export class PenumbraClient { /** Assert an attached provider. */ private assertAttached(): PenumbraClientAttachment { assertProviderRecord(this.attached?.origin); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify return this.attached!; } diff --git a/packages/crypto/src/mnemonic.ts b/packages/crypto/src/mnemonic.ts index 407f219256..07d52775bc 100644 --- a/packages/crypto/src/mnemonic.ts +++ b/packages/crypto/src/mnemonic.ts @@ -30,5 +30,6 @@ export const validateSeedPhrase = (seedPhrase: string[]): boolean => { }; export const isInWordList = (word: string): boolean => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion return wordlists['EN']!.includes(word); }; diff --git a/packages/perspective/src/plan/view-transaction-plan.test.ts b/packages/perspective/src/plan/view-transaction-plan.test.ts index 1cd7938e25..89ba8b789f 100644 --- a/packages/perspective/src/plan/view-transaction-plan.test.ts +++ b/packages/perspective/src/plan/view-transaction-plan.test.ts @@ -82,7 +82,7 @@ describe('viewTransactionPlan()', () => { }, }, transactionParameters: { - //fee, + // fee, chainId, expiryHeight, }, diff --git a/packages/perspective/src/translators/action-view.ts b/packages/perspective/src/translators/action-view.ts index e953ef57b6..6d21d86e58 100644 --- a/packages/perspective/src/translators/action-view.ts +++ b/packages/perspective/src/translators/action-view.ts @@ -53,6 +53,7 @@ export const asPublicActionView: Translator = actionView => { // to err on communicating private data as public than the other way around // TODO: Do proper audit of what data for each action is public default: + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion return actionView!; } }; diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 66e9114e4c..42a8d0f49f 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -48,9 +48,9 @@ import { getSwapRecordCommitment } from '@penumbra-zone/getters/swap-record'; import { CompactBlock } from '@penumbra-zone/protobuf/penumbra/core/component/compact_block/v1/compact_block_pb'; declare global { - // eslint-disable-next-line no-var + // eslint-disable-next-line no-var -- expected globals var __DEV__: boolean | undefined; - // eslint-disable-next-line no-var + // eslint-disable-next-line no-var -- expected globals var __ASSERT_ROOT__: boolean | undefined; } @@ -260,9 +260,11 @@ export class BlockProcessor implements BlockProcessorInterface { await this.identifyNewAssets(flush.newNotes); for (const spendableNoteRecord of flush.newNotes) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion recordsByCommitment.set(spendableNoteRecord.noteCommitment!, spendableNoteRecord); } for (const swapRecord of flush.newSwaps) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion recordsByCommitment.set(swapRecord.swapCommitment!, swapRecord); } } @@ -480,7 +482,7 @@ export class BlockProcessor implements BlockProcessorInterface { const metadataFromNode = await this.querier.shieldedPool.assetMetadataById(assetId); - //do not save IBC token metadata that are not in the prax registry + // do not save IBC token metadata that are not in the prax registry const isIbcAsset = metadataFromNode && assetPatterns.ibc.matches(metadataFromNode.display); if (metadataFromNode && !isIbcAsset) { @@ -694,12 +696,13 @@ export class BlockProcessor implements BlockProcessorInterface { // this loop requests delegation token metadata for each validator // individually. there may be very many, so we must artificially delay // this loop or the RPC may hard-ratelimit us. - await new Promise(resolve => - setTimeout( - resolve, - // an entire second - 1000, - ), + await new Promise( + resolve => + void setTimeout( + resolve, + // an entire second + 1000, + ), ); } } diff --git a/packages/query/src/queriers/shielded-pool.ts b/packages/query/src/queriers/shielded-pool.ts index 26f0942f14..7ca7d85832 100644 --- a/packages/query/src/queriers/shielded-pool.ts +++ b/packages/query/src/queriers/shielded-pool.ts @@ -5,7 +5,7 @@ import { AssetId, Metadata } from '@penumbra-zone/protobuf/penumbra/core/asset/v import type { ShieldedPoolQuerierInterface } from '@penumbra-zone/types/querier'; declare global { - // eslint-disable-next-line no-var + // eslint-disable-next-line no-var -- expected globals var __DEV__: boolean | undefined; } diff --git a/packages/query/src/queriers/tendermint.ts b/packages/query/src/queriers/tendermint.ts index e6045781d0..4d21e76815 100644 --- a/packages/query/src/queriers/tendermint.ts +++ b/packages/query/src/queriers/tendermint.ts @@ -6,7 +6,7 @@ import { Transaction } from '@penumbra-zone/protobuf/penumbra/core/transaction/v import type { TendermintQuerierInterface } from '@penumbra-zone/types/querier'; declare global { - // eslint-disable-next-line no-var + // eslint-disable-next-line no-var -- expected globals var __DEV__: boolean | undefined; } diff --git a/packages/services/src/custody-service/validation/authorize.ts b/packages/services/src/custody-service/validation/authorize.ts index 8c577d0be4..74e64f14ef 100644 --- a/packages/services/src/custody-service/validation/authorize.ts +++ b/packages/services/src/custody-service/validation/authorize.ts @@ -20,6 +20,7 @@ import { FullViewingKey } from '@penumbra-zone/protobuf/penumbra/core/keys/v1/ke * Add more assertions to this function as needed. */ export const assertValidAuthorizeRequest = (req: AuthorizeRequest, fvk: FullViewingKey): void => + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion assertSwapClaimAddressesBelongToCurrentUser(req.plan!, address => isControlledAddress(fvk, address), ); diff --git a/packages/services/src/view-service/app-parameters.ts b/packages/services/src/view-service/app-parameters.ts index 60fa28cecf..30d096a7c6 100644 --- a/packages/services/src/view-service/app-parameters.ts +++ b/packages/services/src/view-service/app-parameters.ts @@ -11,6 +11,7 @@ export const appParameters: Impl['appParameters'] = async (_, ctx) => { if (parameters) { return { parameters }; } + // eslint-disable-next-line no-unreachable-loop -- TODO: justify for await (const update of subscription) { return { parameters: AppParameters.fromJson(update.value) }; } diff --git a/packages/services/src/view-service/balances.ts b/packages/services/src/view-service/balances.ts index fb22a2717a..3e8942a693 100644 --- a/packages/services/src/view-service/balances.ts +++ b/packages/services/src/view-service/balances.ts @@ -37,7 +37,7 @@ export const balances: Impl['balances'] = async function* (req, ctx) { const { indexedDb, querier } = await services.getWalletServices(); // latestBlockHeight is needed to calculate the threshold of price relevance, - //it is better to use rather than fullSyncHeight to avoid displaying old prices during the synchronization process + // it is better to use rather than fullSyncHeight to avoid displaying old prices during the synchronization process const latestKnownBlockHeight = (await querier.tendermint.latestBlockHeight()) ?? (await indexedDb.getFullSyncHeight()) ?? 0n; @@ -115,6 +115,7 @@ class BalancesAggregator { this.accounts[accountNumber][assetIdBase64] ??= await this.initializeBalResponse(n); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const valueView = this.accounts[accountNumber][assetIdBase64].balanceView!; this.aggregateAmount(valueView, n); await this.aggregateEquivalentValues(valueView, n); diff --git a/packages/services/src/view-service/transaction-planner/index.ts b/packages/services/src/view-service/transaction-planner/index.ts index b26a6dc11b..ac8dcc7fa1 100644 --- a/packages/services/src/view-service/transaction-planner/index.ts +++ b/packages/services/src/view-service/transaction-planner/index.ts @@ -16,6 +16,7 @@ export const transactionPlanner: Impl['transactionPlanner'] = async (req, ctx) = // Query IndexedDB directly to check for the existence of staking token const nativeToken = await indexedDb.hasTokenBalance( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion req.source!.account, indexedDb.stakingTokenAssetId, ); diff --git a/packages/transport-chrome/src/session-client.ts b/packages/transport-chrome/src/session-client.ts index 06373bf7da..e0263dfb1b 100644 --- a/packages/transport-chrome/src/session-client.ts +++ b/packages/transport-chrome/src/session-client.ts @@ -42,6 +42,7 @@ const localErrorJson = (err: unknown, relevantMessage?: unknown) => details: [ { type: String( + // eslint-disable-next-line no-nested-ternary -- readable ternary nesting typeof err === 'function' ? err.name : typeof err === 'object' diff --git a/packages/transport-dom/src/create.test.ts b/packages/transport-dom/src/create.test.ts index d0af3262f6..03226df2ae 100644 --- a/packages/transport-dom/src/create.test.ts +++ b/packages/transport-dom/src/create.test.ts @@ -415,7 +415,7 @@ describe('transport timeouts', () => { performance.mark('stream'); try { for (const [i, r] of responses.entries()) { - await new Promise(resolve => setTimeout(resolve, defaultTimeoutMs / 3)); + await new Promise(resolve => void setTimeout(resolve, defaultTimeoutMs / 3)); performance.measure(`chunk ${i}`, 'stream'); yield Any.pack(new IntroduceResponse(r)).toJson({ typeRegistry }); } @@ -440,7 +440,7 @@ describe('transport timeouts', () => { streamRequest.then(({ message }) => Array.fromAsync(message)), ).resolves.not.toThrow(); await expect(streamDone.promise).resolves.not.toThrow(); - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- tests if (PRINT_TEST_TIMES) { console.log('measure', [ { defaultTimeoutMs }, @@ -621,7 +621,7 @@ describe('transport aborts', () => { const stream = ReadableStream.from( (async function* () { for (const r of responses) { - await new Promise(resolve => setTimeout(resolve, defaultTimeoutMs / 3)); + await new Promise(resolve => void setTimeout(resolve, defaultTimeoutMs / 3)); yield Any.pack(new IntroduceResponse(r)).toJson({ typeRegistry }); } })(), diff --git a/packages/transport-dom/src/messages.ts b/packages/transport-dom/src/messages.ts index 089ab73a03..895cdd61fd 100644 --- a/packages/transport-dom/src/messages.ts +++ b/packages/transport-dom/src/messages.ts @@ -16,7 +16,7 @@ export interface TransportEvent { requestId: I; header?: HeadersInit; trailer?: HeadersInit; - //contextValues?: object; + // contextValues?: object; } export interface TransportAbort extends TransportEvent { diff --git a/packages/types/src/base64.ts b/packages/types/src/base64.ts index 6cdfcf3a22..a2f420e7b7 100644 --- a/packages/types/src/base64.ts +++ b/packages/types/src/base64.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; declare global { - // eslint-disable-next-line no-var + // eslint-disable-next-line no-var -- expected globals var __DEV__: boolean | undefined; } @@ -23,6 +23,7 @@ export const InnerBase64Schema = z.object({ inner: Base64StringSchema }); export const base64ToUint8Array = (base64: string): Uint8Array => { const validated = globalThis.__DEV__ ? Base64StringSchema.parse(base64) : base64; const binString = atob(validated); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion return Uint8Array.from(binString, byte => byte.codePointAt(0)!); }; diff --git a/packages/types/src/hex.ts b/packages/types/src/hex.ts index 6afb094a84..81fe009b61 100644 --- a/packages/types/src/hex.ts +++ b/packages/types/src/hex.ts @@ -1,7 +1,7 @@ import { Base64StringSchema } from './base64.js'; declare global { - // eslint-disable-next-line no-var + // eslint-disable-next-line no-var -- expected globals var __DEV__: boolean | undefined; } @@ -60,6 +60,7 @@ export const hexToUint8Array = (hexString: string): Uint8Array => { } // Split the string into pairs of characters + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const hexPairs = hexString.match(/.{1,2}/g)!; // Map each hexadecimal pair to the corresponding integer and create a Uint8Array from it diff --git a/packages/types/src/jsonified.ts b/packages/types/src/jsonified.ts index dbeb323169..b088eedd40 100644 --- a/packages/types/src/jsonified.ts +++ b/packages/types/src/jsonified.ts @@ -50,11 +50,11 @@ export type Jsonified = T extends JsonValue ? T // J : T extends AnyMessage ? JsonObject // AnyMessage is a black box : T extends object ? { // any object... [P in keyof T as // ...index into... - // eslint-disable-next-line @typescript-eslint/ban-types + // eslint-disable-next-line @typescript-eslint/ban-types -- expected use of never T[P] extends (Function) ? never // ...strip function members : P extends string ? P // ...keep string keys : P extends number ? `${P}` // ...stringify number keys : never // ...strip symbol keys ]: Jsonified; // ...recurse object members - } + } : T extends undefined ? never : T; // undefined not allowed diff --git a/packages/types/src/lo-hi.test.ts b/packages/types/src/lo-hi.test.ts index 657c35870d..fd2adca080 100644 --- a/packages/types/src/lo-hi.test.ts +++ b/packages/types/src/lo-hi.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-bitwise -- expected bitwise operations */ import { describe, expect, it } from 'vitest'; import { addLoHi, fromBaseUnit, joinLoHi, splitLoHi, toBaseUnit } from './lo-hi.js'; import { BigNumber } from 'bignumber.js'; diff --git a/packages/types/src/lo-hi.ts b/packages/types/src/lo-hi.ts index 6a6c09dd23..ea59cd58ff 100644 --- a/packages/types/src/lo-hi.ts +++ b/packages/types/src/lo-hi.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-bitwise -- expected bitwise operations */ + import { BigNumber } from 'bignumber.js'; BigNumber.config({ diff --git a/packages/ui/components/ui/address-view/index.tsx b/packages/ui/components/ui/address-view/index.tsx index c902d91ae3..28368e1d2e 100644 --- a/packages/ui/components/ui/address-view/index.tsx +++ b/packages/ui/components/ui/address-view/index.tsx @@ -13,7 +13,7 @@ interface AddressViewProps { // If the view is given and is "visible", the account information will be displayed instead. export const AddressViewComponent = ({ view, copyable = true }: AddressViewProps) => { if (!view?.addressView.value?.address) { - return <>; + return; } const encodedAddress = bech32mAddress(view.addressView.value.address); @@ -27,7 +27,7 @@ export const AddressViewComponent = ({ view, copyable = true }: AddressViewProps const addressIndexLabel = isOneTimeAddress ? 'IBC Deposit Address for Account #' : 'Account #'; - copyable = isOneTimeAddress ? false : copyable; + const isCopyable = isOneTimeAddress ? false : copyable; return (
@@ -45,7 +45,7 @@ export const AddressViewComponent = ({ view, copyable = true }: AddressViewProps )} - {copyable && } + {isCopyable && }
); }; diff --git a/packages/ui/components/ui/asset-icon/index.tsx b/packages/ui/components/ui/asset-icon/index.tsx index 9e6ca82e1a..ad35fbb2d5 100644 --- a/packages/ui/components/ui/asset-icon/index.tsx +++ b/packages/ui/components/ui/asset-icon/index.tsx @@ -13,8 +13,7 @@ export const AssetIcon = ({ metadata?: Metadata; size?: 'xs' | 'sm' | 'lg'; }) => { - // Image default is "" and thus cannot do nullish-coalescing - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Image default is "" and thus cannot do nullish-coalescing const icon = metadata?.images[0]?.png || metadata?.images[0]?.svg; const className = cn( 'rounded-full', @@ -26,26 +25,25 @@ export const AssetIcon = ({ const isDelegationToken = display ? assetPatterns.delegationToken.matches(display) : false; const isUnbondingToken = display ? assetPatterns.unbondingToken.matches(display) : false; - return ( - <> - {icon ? ( - Asset icon - ) : isDelegationToken ? ( - - ) : isUnbondingToken ? ( - /** - * @todo: Render a custom unbonding token for validators that have a - * logo -- e.g., with the validator ID superimposed over the validator - * logo. - */ - - ) : ( - - )} - + // eslint-disable-next-line no-nested-ternary -- readable ternary + return icon ? ( + Asset icon + ) : // eslint-disable-next-line no-nested-ternary -- readable ternary + isDelegationToken ? ( + + ) : isUnbondingToken ? ( + /** + * @todo: Render a custom unbonding token for validators that have a + * logo -- e.g., with the validator ID superimposed over the validator + * logo. + */ + + ) : ( + ); }; diff --git a/packages/ui/components/ui/candlestick-plot/index.tsx b/packages/ui/components/ui/candlestick-plot/index.tsx index 5b1b30d9f4..9d54b9358d 100644 --- a/packages/ui/components/ui/candlestick-plot/index.tsx +++ b/packages/ui/components/ui/candlestick-plot/index.tsx @@ -260,7 +260,9 @@ export const CandlesticksTooltip = ({ return () => ac.abort('Abort tooltip date query'); }, [data, getBlockDate]); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const endBase = endMetadata.denomUnits.filter(d => !d.exponent)[0]!; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const startBase = startMetadata.denomUnits.filter(d => !d.exponent)[0]!; return ( ( ref={ref} className={cn( baseClasses, + // eslint-disable-next-line no-nested-ternary -- readable ternary light ? 'bg-stone-300' : gradient ? 'bg-card-radial' : 'bg-charcoal', className, )} diff --git a/packages/ui/components/ui/command/index.tsx b/packages/ui/components/ui/command/index.tsx index df09b80a53..f464e70f7f 100644 --- a/packages/ui/components/ui/command/index.tsx +++ b/packages/ui/components/ui/command/index.tsx @@ -40,6 +40,7 @@ const CommandInput = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( + // eslint-disable-next-line react/no-unknown-property -- TODO: justify
{ data-testid='CopyToClipboardIconButton__icon' /> } - successLabel={<>} + successLabel={null} className='size-4' /> ); diff --git a/packages/ui/components/ui/dutch-auction-component/expanded-details/get-step-index.ts b/packages/ui/components/ui/dutch-auction-component/expanded-details/get-step-index.ts index 8841addccd..d8c6a7e9c4 100644 --- a/packages/ui/components/ui/dutch-auction-component/expanded-details/get-step-index.ts +++ b/packages/ui/components/ui/dutch-auction-component/expanded-details/get-step-index.ts @@ -5,6 +5,7 @@ import { DutchAuctionDescription } from '@penumbra-zone/protobuf/penumbra/core/c * the step index to the step count. */ const clampBetweenZeroAnd = (max: bigint, value: bigint) => + // eslint-disable-next-line no-nested-ternary -- readable ternary value > max ? max : value < 0n ? 0n : value; export const getStepIndex = ( diff --git a/packages/ui/components/ui/identicon/generate.ts b/packages/ui/components/ui/identicon/generate.ts index 500c56120c..296ee3c0d9 100644 --- a/packages/ui/components/ui/identicon/generate.ts +++ b/packages/ui/components/ui/identicon/generate.ts @@ -12,6 +12,7 @@ export const generateGradient = (str: string) => { const tetrad = c.tetrad(); // 4 colors spaced around the color wheel, the first being the input const secondColorOptions = tetrad.slice(1); const index = hash % 3; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const toColor = secondColorOptions[index]!.toHexString(); return { diff --git a/packages/ui/components/ui/logo/animation-logic.ts b/packages/ui/components/ui/logo/animation-logic.ts index fca5974467..83e78b9314 100644 --- a/packages/ui/components/ui/logo/animation-logic.ts +++ b/packages/ui/components/ui/logo/animation-logic.ts @@ -7,18 +7,18 @@ interface Plot { } // Adjustable variables. Take care while adjusting these as small changes in the values can result in massive changes in the result. -const baseRadFactor = 0.0022; //the radius of the smallest ring. Adjust carefully as small changes result it large results. Generally keep wthin the range of 0.0015 and 0.0022. +const baseRadFactor = 0.0022; // the radius of the smallest ring. Adjust carefully as small changes result it large results. Generally keep wthin the range of 0.0015 and 0.0022. const octaveSpeed = 0.007 / 3; // controls the speed for animating octaves -const plotRotationSpeed = -0.009 / 3; //adjust value to control speed of plot rotation and sign to control direction. -const plotThickness = 0.3; //adjust the thickness of each plot -const wobblyConstant = 1.1; //This adjusts the frequency of the perlin noise allowing for more peaks. +const plotRotationSpeed = -0.009 / 3; // adjust value to control speed of plot rotation and sign to control direction. +const plotThickness = 0.3; // adjust the thickness of each plot +const wobblyConstant = 1.1; // This adjusts the frequency of the perlin noise allowing for more peaks. const numPoints = 250; // Resolution of the plot for each ring. This can be adjusted to get a better balance betwen performance and visual fidelity -const plotGap = 0.00017; //Distance between each plot. small changes produce large results. +const plotGap = 0.00017; // Distance between each plot. small changes produce large results. -//These variables are best left untouched as they either produce little to no visual changes or massive negative results when adjusted as the -const numPlots = 22; //this number corresponds to the number of plots in the svg section -const maxTheta = 2 * Math.PI; //Used in the polar coordinates calculation which gives the circular appearance, this variable limits the circle to just one turn. -const amplitudeFactor = 1; //this can also be used to control the distance between each plot +// These variables are best left untouched as they either produce little to no visual changes or massive negative results when adjusted as the +const numPlots = 22; // this number corresponds to the number of plots in the svg section +const maxTheta = 2 * Math.PI; // Used in the polar coordinates calculation which gives the circular appearance, this variable limits the circle to just one turn. +const amplitudeFactor = 1; // this can also be used to control the distance between each plot const frameTime = 16.67; @@ -32,7 +32,7 @@ const calculateR = ( noiseIntensity: number, octaves: number, ) => { - const baseRad = ccp * baseRadFactor; //the radius of the smallest ring. + const baseRad = ccp * baseRadFactor; // the radius of the smallest ring. const r = initialValue + baseRad + @@ -82,6 +82,7 @@ const renderPlot = ( export const initializePlotsArr = (noiseIntensityFactor: number): Plot[] => { const plots: Plot[] = []; for (let i = 0; i < numPlots; i++) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion const path = document.getElementById(`plot${i + 1}`)!; const noiseIntensity = noiseIntensityFactor * (i / (numPlots - 1)); // noise intensity control for each ring as they move towards the edge const initialValue = i * plotGap; // As the loop works itself towards the outer plots, the initialValue is increased to create a larger distance from the centre for each plot. This basically denotes the base radius of each plot. diff --git a/packages/ui/components/ui/logo/perlin-noise.ts b/packages/ui/components/ui/logo/perlin-noise.ts index 2bbcb24013..320f926f4b 100644 --- a/packages/ui/components/ui/logo/perlin-noise.ts +++ b/packages/ui/components/ui/logo/perlin-noise.ts @@ -1,3 +1,4 @@ +/* eslint-disable -- vendored file */ const p1 = [ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, diff --git a/packages/ui/components/ui/logo/static.tsx b/packages/ui/components/ui/logo/static.tsx index 9319da0bfe..9948efc18d 100644 --- a/packages/ui/components/ui/logo/static.tsx +++ b/packages/ui/components/ui/logo/static.tsx @@ -44,18 +44,16 @@ const Logo = React.forwardRef( )} - <> - - - + + ); }, diff --git a/packages/ui/components/ui/select/select-account.tsx b/packages/ui/components/ui/select/select-account.tsx index 245572ddc9..8157aea056 100644 --- a/packages/ui/components/ui/select/select-account.tsx +++ b/packages/ui/components/ui/select/select-account.tsx @@ -31,57 +31,51 @@ export const SelectAccount = ({ getAddrByIndex }: SelectAccountProps) => { })(); }, [index, ephemeral, getAddrByIndex]); - return ( - <> - {!address ? ( - <> - ) : ( -
- + return !address ? undefined : ( +
+ -
- -
-
-
- -
- -

- -

-
- +
+ +
+
+
+
- -
-
-
- -

IBC Deposit Address

- - - - - - -

- IBC transfers into Penumbra post the destination address in public on the - source chain. Use this randomized IBC deposit address to preserve privacy when - transferring funds into Penumbra. -

-
-
-
+ +

+ +

- setEphemeral(checked)} - /> +
+ +
+
+
+ +

IBC Deposit Address

+ + + + + + +

+ IBC transfers into Penumbra post the destination address in public on the source + chain. Use this randomized IBC deposit address to preserve privacy when + transferring funds into Penumbra. +

+
+
+
- )} - + setEphemeral(checked)} + /> +
+
); }; diff --git a/packages/ui/components/ui/separator/index.tsx b/packages/ui/components/ui/separator/index.tsx index 9b0fd6bc9b..e789eabaa4 100644 --- a/packages/ui/components/ui/separator/index.tsx +++ b/packages/ui/components/ui/separator/index.tsx @@ -7,6 +7,6 @@ export const Separator = () => ( // For some reason, Tailwind's ESLint config wants to change `border-b-[1px]` // to `border-b-DEFAULT`, even though that has a different effect! - // eslint-disable-next-line tailwindcss/no-unnecessary-arbitrary-value + // eslint-disable-next-line tailwindcss/no-unnecessary-arbitrary-value -- see above
); diff --git a/packages/ui/components/ui/tx/memo-view.tsx b/packages/ui/components/ui/tx/memo-view.tsx index be6e597fe5..8017f105e9 100644 --- a/packages/ui/components/ui/tx/memo-view.tsx +++ b/packages/ui/components/ui/tx/memo-view.tsx @@ -13,6 +13,7 @@ export const MemoViewComponent = ({ memo: { memoView } }: { memo: MemoView }) =>
+ {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify not using '?' operator */} diff --git a/packages/ui/components/ui/tx/viewbox.tsx b/packages/ui/components/ui/tx/viewbox.tsx index feaf2865a8..aedb54c220 100644 --- a/packages/ui/components/ui/tx/viewbox.tsx +++ b/packages/ui/components/ui/tx/viewbox.tsx @@ -15,19 +15,19 @@ const Label = ({ label }: { label: string }) => {label export const ViewBox = ({ label, visibleContent, isOpaque }: ViewBoxProps) => { // if isOpaque is undefined, set it to !visibleContent - isOpaque = isOpaque ?? !visibleContent; + const opaque = isOpaque ?? !visibleContent; return (
- - {!isOpaque &&