diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 4212ef454eea..52e53af28a1e 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1694,10 +1694,10 @@ "@metamask/network-controller>@metamask/eth-block-tracker": true, "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/network-controller>reselect": true, "@metamask/rpc-errors": true, "@metamask/utils": true, "eslint>fast-deep-equal": true, + "reselect": true, "uri-js": true, "uuid": true } @@ -1756,13 +1756,6 @@ "semver": true } }, - "@metamask/network-controller>reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true - } - }, "@metamask/notification-controller>nanoid": { "globals": { "crypto.getRandomValues": true @@ -5138,6 +5131,13 @@ "@babel/runtime": true } }, + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true + } + }, "semver": { "globals": { "console.error": true diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 4212ef454eea..52e53af28a1e 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1694,10 +1694,10 @@ "@metamask/network-controller>@metamask/eth-block-tracker": true, "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/network-controller>reselect": true, "@metamask/rpc-errors": true, "@metamask/utils": true, "eslint>fast-deep-equal": true, + "reselect": true, "uri-js": true, "uuid": true } @@ -1756,13 +1756,6 @@ "semver": true } }, - "@metamask/network-controller>reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true - } - }, "@metamask/notification-controller>nanoid": { "globals": { "crypto.getRandomValues": true @@ -5138,6 +5131,13 @@ "@babel/runtime": true } }, + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true + } + }, "semver": { "globals": { "console.error": true diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 4212ef454eea..52e53af28a1e 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1694,10 +1694,10 @@ "@metamask/network-controller>@metamask/eth-block-tracker": true, "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/network-controller>reselect": true, "@metamask/rpc-errors": true, "@metamask/utils": true, "eslint>fast-deep-equal": true, + "reselect": true, "uri-js": true, "uuid": true } @@ -1756,13 +1756,6 @@ "semver": true } }, - "@metamask/network-controller>reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true - } - }, "@metamask/notification-controller>nanoid": { "globals": { "crypto.getRandomValues": true @@ -5138,6 +5131,13 @@ "@babel/runtime": true } }, + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true + } + }, "semver": { "globals": { "console.error": true diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index 5234fe8d6fbb..b10d976bb08c 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -1786,10 +1786,10 @@ "@metamask/network-controller>@metamask/eth-block-tracker": true, "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/network-controller>reselect": true, "@metamask/rpc-errors": true, "@metamask/utils": true, "eslint>fast-deep-equal": true, + "reselect": true, "uri-js": true, "uuid": true } @@ -1848,13 +1848,6 @@ "semver": true } }, - "@metamask/network-controller>reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true - } - }, "@metamask/notification-controller>nanoid": { "globals": { "crypto.getRandomValues": true @@ -5230,6 +5223,13 @@ "@babel/runtime": true } }, + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true + } + }, "semver": { "globals": { "console.error": true diff --git a/package.json b/package.json index 893308a2ef35..6936ad051ece 100644 --- a/package.json +++ b/package.json @@ -426,7 +426,7 @@ "redux": "^4.0.5", "redux-thunk": "^2.3.0", "remove-trailing-slash": "^0.1.1", - "reselect": "^3.0.1", + "reselect": "^5.1.1", "ses": "^1.1.0", "simple-git": "^3.20.0", "single-call-balance-checker-abi": "^1.0.0", diff --git a/shared/modules/selectors/smart-transactions.ts b/shared/modules/selectors/smart-transactions.ts index c9a696ba9b9e..9367c24853c6 100644 --- a/shared/modules/selectors/smart-transactions.ts +++ b/shared/modules/selectors/smart-transactions.ts @@ -84,6 +84,7 @@ export const getSmartTransactionsOptInStatusInternal = createSelector( * @returns true if the user has explicitly opted in, false if they have opted out, * or null if they have not explicitly opted in or out. */ +// @ts-expect-error TODO: Fix types for `getSmartTransactionsOptInStatusInternal` once `getPreferences is converted to TypeScript export const getSmartTransactionsOptInStatusForMetrics = createSelector( getSmartTransactionsOptInStatusInternal, (optInStatus: boolean): boolean => optInStatus, @@ -96,6 +97,7 @@ export const getSmartTransactionsOptInStatusForMetrics = createSelector( * @param state * @returns */ +// @ts-expect-error TODO: Fix types for `getSmartTransactionsOptInStatusInternal` once `getPreferences is converted to TypeScript export const getSmartTransactionsPreferenceEnabled = createSelector( getSmartTransactionsOptInStatusInternal, (optInStatus: boolean): boolean => { diff --git a/shared/modules/selectors/util.js b/shared/modules/selectors/util.js index d44b7d905087..35153a82bc4d 100644 --- a/shared/modules/selectors/util.js +++ b/shared/modules/selectors/util.js @@ -1,9 +1,9 @@ import { TransactionStatus } from '@metamask/transaction-controller'; import { isEqual } from 'lodash'; -import { createSelectorCreator, defaultMemoize } from 'reselect'; +import { createSelectorCreator, lruMemoize } from 'reselect'; export const createDeepEqualSelector = createSelectorCreator( - defaultMemoize, + lruMemoize, isEqual, ); diff --git a/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx b/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx index fd8831f36e0f..3a52a5c43eef 100644 --- a/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx +++ b/ui/components/app/snaps/snap-authorship-pill/snap-authorship-pill.tsx @@ -22,7 +22,6 @@ const SnapAuthorshipPill: React.FC = ({ onClick, }) => { const { name: snapName } = useSelector((state) => - // @ts-expect-error ts is picking up the wrong type for the selector getSnapMetadata(state, snapId), ); diff --git a/ui/components/app/snaps/snap-icon/snap-icon.tsx b/ui/components/app/snaps/snap-icon/snap-icon.tsx index fa27616e4d97..5d81f97834b9 100644 --- a/ui/components/app/snaps/snap-icon/snap-icon.tsx +++ b/ui/components/app/snaps/snap-icon/snap-icon.tsx @@ -40,7 +40,6 @@ export const SnapIcon: FunctionComponent = ({ ); const { name: snapName } = useSelector((state) => - /* @ts-expect-error wrong type on selector. */ getSnapMetadata(state, snapId), ); diff --git a/ui/ducks/bridge/selectors.test.ts b/ui/ducks/bridge/selectors.test.ts index d90251e360f3..cd79a8e6454b 100644 --- a/ui/ducks/bridge/selectors.test.ts +++ b/ui/ducks/bridge/selectors.test.ts @@ -13,7 +13,11 @@ import { import { mockNetworkState } from '../../../test/stub/networks'; import mockErc20Erc20Quotes from '../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import mockBridgeQuotesNativeErc20 from '../../../test/data/bridge/mock-quotes-native-erc20.json'; -import { SortOrder } from '../../pages/bridge/types'; +import { + QuoteMetadata, + QuoteResponse, + SortOrder, +} from '../../pages/bridge/types'; import { getAllBridgeableNetworks, getBridgeQuotes, @@ -722,9 +726,11 @@ describe('Bridge selectors', () => { { valueInCurrency: new BigNumber('0.156562871410260918428') }, { valueInCurrency: new BigNumber('0.33900008283534602') }, ]; - result.sortedQuotes.forEach((quote, idx) => { - expect(quote.cost).toStrictEqual(EXPECTED_SORTED_COSTS[idx]); - }); + result.sortedQuotes.forEach( + (quote: QuoteMetadata & QuoteResponse, idx: number) => { + expect(quote.cost).toStrictEqual(EXPECTED_SORTED_COSTS[idx]); + }, + ); expect(result).toStrictEqual({ sortedQuotes: expect.any(Array), recommendedQuote: { @@ -827,9 +833,11 @@ describe('Bridge selectors', () => { { valueInCurrency: new BigNumber('0.15656287141025952') }, { valueInCurrency: new BigNumber('0.33900008283534464') }, ]; - result.sortedQuotes.forEach((quote, idx) => { - expect(quote.cost).toStrictEqual(EXPECTED_SORTED_COSTS[idx]); - }); + result.sortedQuotes.forEach( + (quote: QuoteMetadata & QuoteResponse, idx: number) => { + expect(quote.cost).toStrictEqual(EXPECTED_SORTED_COSTS[idx]); + }, + ); expect(result).toStrictEqual({ sortedQuotes: expect.any(Array), @@ -898,14 +906,18 @@ describe('Bridge selectors', () => { '381c23bc-e3e4-48fe-bc53-257471e388ad', ); expect(sortedQuotes).toHaveLength(2); - sortedQuotes.forEach((quote, idx) => { - expect( - quoteMetadataKeys.every((k) => Object.keys(quote ?? {}).includes(k)), - ).toBe(true); - expect(quote?.quote.requestId).toStrictEqual( - mockBridgeQuotesNativeErc20[idx]?.quote.requestId, - ); - }); + sortedQuotes.forEach( + (quote: QuoteMetadata & QuoteResponse, idx: number) => { + expect( + quoteMetadataKeys.every((k) => + Object.keys(quote ?? {}).includes(k), + ), + ).toBe(true); + expect(quote?.quote.requestId).toStrictEqual( + mockBridgeQuotesNativeErc20[idx]?.quote.requestId, + ); + }, + ); }); it('should sort quotes by ETA', () => { diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx index d251b8ab72f5..d50a2ad3bbd9 100644 --- a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx +++ b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx @@ -26,7 +26,7 @@ import { import { useI18nContext } from '../../../hooks/useI18nContext'; import { getCurrentCurrency } from '../../../selectors'; import { setSelectedQuote, setSortOrder } from '../../../ducks/bridge/actions'; -import { SortOrder } from '../types'; +import { QuoteMetadata, QuoteResponse, SortOrder } from '../types'; import { getBridgeQuotes, getBridgeSortOrder, @@ -135,127 +135,129 @@ export const BridgeQuotesModal = ({ {/* QUOTE LIST */} - {sortedQuotes.map((quote, index) => { - const { - totalNetworkFee, - estimatedProcessingTimeInSeconds, - toTokenAmount, - cost, - quote: { destAsset, bridges, requestId }, - } = quote; - const isQuoteActive = requestId === activeQuote?.quote.requestId; - const isRecommendedQuote = - requestId === recommendedQuote?.quote.requestId; + {sortedQuotes.map( + (quote: QuoteMetadata & QuoteResponse, index: number) => { + const { + totalNetworkFee, + estimatedProcessingTimeInSeconds, + toTokenAmount, + cost, + quote: { destAsset, bridges, requestId }, + } = quote; + const isQuoteActive = requestId === activeQuote?.quote.requestId; + const isRecommendedQuote = + requestId === recommendedQuote?.quote.requestId; - return ( - { - dispatch(setSelectedQuote(quote)); - // Emit QuoteSelected event after dispatching setSelectedQuote - quoteRequestProperties && - requestMetadataProperties && - quoteListProperties && - tradeProperties && - trackCrossChainSwapsEvent({ - event: MetaMetricsEventName.QuoteSelected, - properties: { - ...quoteRequestProperties, - ...requestMetadataProperties, - ...quoteListProperties, - ...tradeProperties, - is_best_quote: isRecommendedQuote, - }, - }); - onClose(); - }} - paddingInline={4} - paddingTop={3} - paddingBottom={3} - style={{ position: 'relative', height: 78 }} - > - {isQuoteActive && ( - - )} - - - {cost.valueInCurrency && - formatCurrencyAmount(cost.valueInCurrency, currency, 0)} - - {[ - totalNetworkFee?.valueInCurrency - ? t('quotedNetworkFee', [ + return ( + { + dispatch(setSelectedQuote(quote)); + // Emit QuoteSelected event after dispatching setSelectedQuote + quoteRequestProperties && + requestMetadataProperties && + quoteListProperties && + tradeProperties && + trackCrossChainSwapsEvent({ + event: MetaMetricsEventName.QuoteSelected, + properties: { + ...quoteRequestProperties, + ...requestMetadataProperties, + ...quoteListProperties, + ...tradeProperties, + is_best_quote: isRecommendedQuote, + }, + }); + onClose(); + }} + paddingInline={4} + paddingTop={3} + paddingBottom={3} + style={{ position: 'relative', height: 78 }} + > + {isQuoteActive && ( + + )} + + + {cost.valueInCurrency && + formatCurrencyAmount(cost.valueInCurrency, currency, 0)} + + {[ + totalNetworkFee?.valueInCurrency + ? t('quotedNetworkFee', [ + formatCurrencyAmount( + totalNetworkFee.valueInCurrency, + currency, + 0, + ), + ]) + : t('quotedNetworkFee', [ + formatTokenAmount( + totalNetworkFee.amount, + nativeCurrency, + ), + ]), + t( + sortOrder === SortOrder.ETA_ASC + ? 'quotedReceivingAmount' + : 'quotedReceiveAmount', + [ formatCurrencyAmount( - totalNetworkFee.valueInCurrency, + toTokenAmount.valueInCurrency, currency, 0, - ), - ]) - : t('quotedNetworkFee', [ - formatTokenAmount( - totalNetworkFee.amount, - nativeCurrency, - ), - ]), - t( - sortOrder === SortOrder.ETA_ASC - ? 'quotedReceivingAmount' - : 'quotedReceiveAmount', - [ - formatCurrencyAmount( - toTokenAmount.valueInCurrency, - currency, - 0, - ) ?? - formatTokenAmount( - toTokenAmount.amount, - destAsset.symbol, - 0, - ), - ], - ), - ] - [sortOrder === SortOrder.ETA_ASC ? 'reverse' : 'slice']() - .map((content) => ( - - {content} - - ))} - - - - {t('bridgeTimingMinutes', [ - formatEtaInMinutes(estimatedProcessingTimeInSeconds), - ])} - - - {startCase(bridges[0])} - - - - ); - })} + ) ?? + formatTokenAmount( + toTokenAmount.amount, + destAsset.symbol, + 0, + ), + ], + ), + ] + [sortOrder === SortOrder.ETA_ASC ? 'reverse' : 'slice']() + .map((content) => ( + + {content} + + ))} + + + + {t('bridgeTimingMinutes', [ + formatEtaInMinutes(estimatedProcessingTimeInSeconds), + ])} + + + {startCase(bridges[0])} + + + + ); + }, + )} diff --git a/ui/pages/confirmations/components/confirm/snaps/snaps-section/snap-insight.tsx b/ui/pages/confirmations/components/confirm/snaps/snaps-section/snap-insight.tsx index 7102970b4f84..cd46f6ea7113 100644 --- a/ui/pages/confirmations/components/confirm/snaps/snaps-section/snap-insight.tsx +++ b/ui/pages/confirmations/components/confirm/snaps/snaps-section/snap-insight.tsx @@ -27,7 +27,6 @@ export const SnapInsight: React.FunctionComponent = ({ }) => { const t = useI18nContext(); const { name: snapName } = useSelector((state) => - /* @ts-expect-error wrong type on selector. */ getSnapMetadata(state, snapId), ); diff --git a/yarn.lock b/yarn.lock index a4163ea118e5..2fbe7d7dd430 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26818,7 +26818,7 @@ __metadata: redux-thunk: "npm:^2.3.0" remote-redux-devtools: "npm:^0.5.16" remove-trailing-slash: "npm:^0.1.1" - reselect: "npm:^3.0.1" + reselect: "npm:^5.1.1" resolve-url-loader: "npm:^3.1.5" sass-embedded: "npm:^1.71.0" sass-loader: "npm:^14.1.1" @@ -32229,13 +32229,6 @@ __metadata: languageName: node linkType: hard -"reselect@npm:^3.0.1": - version: 3.0.1 - resolution: "reselect@npm:3.0.1" - checksum: 10/ebafc7b2d0e907aa1e2e16d37bb1c7c37e9291b3656a7e7bfb9c9523faeaa65ef3db9dec669da250c2b81f59f3231cf3143b0c8e76e7fc8f5a6d79f6ea50e21e - languageName: node - linkType: hard - "reselect@npm:^4.1.8": version: 4.1.8 resolution: "reselect@npm:4.1.8"