From bd8113d018ec30b43d5464d4befc4274017b850f Mon Sep 17 00:00:00 2001 From: Tina <59578595+tinaszheng@users.noreply.github.com> Date: Fri, 12 May 2023 11:05:22 -0400 Subject: [PATCH] chore: Goodbye widget :( (#6543) * goodbye widget :( * remove unused function * modify trace tests * fix lint * is github down? --- .github/dependabot.yml | 1 - cypress/e2e/token-details.test.ts | 6 +- package.json | 15 +- .../FeatureFlagModal/FeatureFlagModal.tsx | 7 - src/components/Tokens/TokenDetails/index.tsx | 59 +---- src/components/Widget/index.tsx | 204 ------------------ src/components/Widget/inputs.tsx | 202 ----------------- src/components/Widget/settings.ts | 64 ------ src/components/Widget/theme.ts | 68 ------ src/components/Widget/transactions.ts | 163 -------------- src/featureFlags/flags/featureFlags.ts | 1 - src/featureFlags/flags/removeWidgetTdp.ts | 11 - src/hooks/Tokens.ts | 16 +- src/hooks/useUniversalRouter.ts | 126 ++++++----- src/pages/Pool/PositionPage.tsx | 3 +- src/state/routing/slice.ts | 1 - src/state/user/hooks.tsx | 2 +- src/tracing/trace.test.ts | 15 +- src/tracing/trace.ts | 5 +- yarn.lock | 146 ++----------- 20 files changed, 110 insertions(+), 1005 deletions(-) delete mode 100644 src/components/Widget/index.tsx delete mode 100644 src/components/Widget/inputs.tsx delete mode 100644 src/components/Widget/settings.ts delete mode 100644 src/components/Widget/theme.ts delete mode 100644 src/components/Widget/transactions.ts delete mode 100644 src/featureFlags/flags/removeWidgetTdp.ts diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7923d21174..698c8a0049 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,6 +8,5 @@ updates: allow: - dependency-name: '@uniswap/default-token-list' - dependency-name: '@uniswap/token-lists' - - dependency-name: '@uniswap/widgets' reviewers: - 'Uniswap/dependabot-reviewers' diff --git a/cypress/e2e/token-details.test.ts b/cypress/e2e/token-details.test.ts index bc16b854b3..cd63dacdd7 100644 --- a/cypress/e2e/token-details.test.ts +++ b/cypress/e2e/token-details.test.ts @@ -1,7 +1,6 @@ import { SupportedChainId, WETH9 } from '@uniswap/sdk-core' import { UNI } from '../../src/constants/tokens' -import { FeatureFlag } from '../../src/featureFlags/flags/featureFlags' import { getTestSelector } from '../utils' const UNI_MAINNET = UNI[SupportedChainId.MAINNET] @@ -96,7 +95,6 @@ describe('Token details', () => { cy.viewport(1200, 800) cy.visit(`/tokens/ethereum/${UNI_MAINNET.address}`, { ethereum: 'hardhat', - featureFlags: [FeatureFlag.removeWidget], }).then(() => { cy.wait('@eth_blockNumber') cy.scrollTo('top') @@ -121,7 +119,7 @@ describe('Token details', () => { cy.get(`#swap-currency-output .token-symbol-container`).should('contain.text', 'UNI') cy.get(`#swap-currency-input .open-currency-select-button`).click() cy.contains('WETH').click() - cy.visit('/swap', { featureFlags: [FeatureFlag.removeWidget] }) + cy.visit('/swap') cy.contains('UNI').should('not.exist') cy.contains('WETH').should('not.exist') }) @@ -147,7 +145,7 @@ describe('Token details', () => { }) it('should show a L2 token even if the user is connected to a different network', () => { - cy.visit('/tokens', { ethereum: 'hardhat', featureFlags: [FeatureFlag.removeWidget] }) + cy.visit('/tokens', { ethereum: 'hardhat' }) cy.get(getTestSelector('tokens-network-filter-selected')).click() cy.get(getTestSelector('tokens-network-filter-option-arbitrum')).click() cy.get(getTestSelector('tokens-network-filter-selected')).should('contain', 'Arbitrum') diff --git a/package.json b/package.json index fb3d3fa2d1..cba2158067 100644 --- a/package.json +++ b/package.json @@ -98,8 +98,8 @@ "@types/ua-parser-js": "^0.7.35", "@types/uuid": "^8.3.4", "@types/wcag-contrast": "^3.0.0", - "@uniswap/eslint-config": "^1.2.0", "@uniswap/default-token-list": "^9.4.0", + "@uniswap/eslint-config": "^1.2.0", "@vanilla-extract/babel-plugin": "^1.1.7", "@vanilla-extract/jest-transform": "^1.1.1", "@vanilla-extract/webpack-plugin": "^2.1.11", @@ -169,7 +169,6 @@ "@uniswap/v3-core": "1.0.0", "@uniswap/v3-periphery": "^1.1.1", "@uniswap/v3-sdk": "^3.9.0", - "@uniswap/widgets": "^2.49.0", "@vanilla-extract/css": "^1.7.2", "@vanilla-extract/css-utils": "^0.1.2", "@vanilla-extract/dynamic": "^2.0.2", @@ -254,18 +253,6 @@ "workbox-routing": "^6.1.0", "zustand": "^4.3.6" }, - "resolutions": { - "@web3-react/coinbase-wallet": "^8.2.0", - "@web3-react/core": "^8.2.0", - "@web3-react/eip1193": "^8.2.0", - "@web3-react/empty": "^8.2.0", - "@web3-react/gnosis-safe": "^8.2.0", - "@web3-react/metamask": "^8.2.0", - "@web3-react/network": "^8.2.0", - "@web3-react/types": "^8.2.0", - "@web3-react/url": "^8.2.0", - "@web3-react/walletconnect": "^8.2.0" - }, "engines": { "npm": "please-use-yarn", "node": "14", diff --git a/src/components/FeatureFlagModal/FeatureFlagModal.tsx b/src/components/FeatureFlagModal/FeatureFlagModal.tsx index 8847839ca1..d3b9a77ff8 100644 --- a/src/components/FeatureFlagModal/FeatureFlagModal.tsx +++ b/src/components/FeatureFlagModal/FeatureFlagModal.tsx @@ -1,6 +1,5 @@ import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'featureFlags' import { DetailsV2Variant, useDetailsV2Flag } from 'featureFlags/flags/nftDetails' -import { useWidgetRemovalFlag, WidgetRemovalVariant } from 'featureFlags/flags/removeWidgetTdp' import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc' import { useUpdateAtom } from 'jotai/utils' import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react' @@ -208,12 +207,6 @@ export default function FeatureFlagModal() { featureFlag={FeatureFlag.detailsV2} label="Use the new details page for nfts" /> - { - const newDefaultToken = tokens[Field.OUTPUT] ?? tokens.default - const address = newDefaultToken?.isNative ? NATIVE_CHAIN_ID : newDefaultToken?.address - startTokenTransition(() => - navigate( - getTokenDetailsURL({ - address, - chain, - inputAddress: tokens[Field.INPUT] ? getTokenAddress(tokens[Field.INPUT] as Currency) : null, - }) - ) - ) - }, - [chain, navigate] - ) const handleCurrencyChange = useCallback( (tokens: Pick) => { @@ -202,12 +178,6 @@ export default function TokenDetails({ const [openTokenSafetyModal, setOpenTokenSafetyModal] = useState(false) - const shouldShowSpeedbump = !useIsUserAddedTokenOnChain(address, pageChainId) && tokenWarning !== null - const onReviewSwapClick = useCallback( - () => new Promise((resolve) => (shouldShowSpeedbump ? setContinueSwap({ resolve }) : resolve(true))), - [shouldShowSpeedbump] - ) - const onResolveSwap = useCallback( (value: boolean) => { continueSwap?.resolve(value) @@ -268,26 +238,15 @@ export default function TokenDetails({ isBlockedToken && setOpenTokenSafetyModal(true)}>
- {widgetRemovalEnabled ? ( - - ) : ( - - )} +
{tokenWarning && } {detailedToken && } diff --git a/src/components/Widget/index.tsx b/src/components/Widget/index.tsx deleted file mode 100644 index 3a4f53213f..0000000000 --- a/src/components/Widget/index.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import { sendAnalyticsEvent, useTrace } from '@uniswap/analytics' -import { - InterfaceEventName, - InterfaceSectionName, - SwapEventName, - SwapPriceUpdateUserResponse, -} from '@uniswap/analytics-events' -import { Trade } from '@uniswap/router-sdk' -import { Currency, TradeType } from '@uniswap/sdk-core' -import { - AddEthereumChainParameter, - DialogAnimationType, - EMPTY_TOKEN_LIST, - OnReviewSwapClick, - SwapWidget, - SwapWidgetSkeleton, -} from '@uniswap/widgets' -import { useWeb3React } from '@web3-react/core' -import { useToggleAccountDrawer } from 'components/AccountDrawer' -import { useActiveLocale } from 'hooks/useActiveLocale' -import { - formatPercentInBasisPointsNumber, - formatSwapQuoteReceivedEventProperties, - formatToDecimal, - getDurationFromDateMilliseconds, - getPriceUpdateBasisPoints, - getTokenAddress, -} from 'lib/utils/analytics' -import { useCallback, useState } from 'react' -import { useIsDarkMode } from 'theme/components/ThemeToggle' -import { computeRealizedPriceImpact } from 'utils/prices' -import { switchChain } from 'utils/switchChain' - -import { DefaultTokens, SwapTokens, useSyncWidgetInputs } from './inputs' -import { useSyncWidgetSettings } from './settings' -import { DARK_THEME, LIGHT_THEME } from './theme' -import { useSyncWidgetTransactions } from './transactions' - -const DEFAULT_WIDGET_WIDTH = 360 - -const WIDGET_ROUTER_URL = 'https://api.uniswap.org/v1/' - -function useWidgetTheme() { - return useIsDarkMode() ? DARK_THEME : LIGHT_THEME -} - -interface WidgetProps { - defaultTokens: DefaultTokens - width?: number | string - onDefaultTokenChange?: (tokens: SwapTokens) => void - onReviewSwapClick?: OnReviewSwapClick -} - -// TODO: Remove this component once the TDP is fully migrated to the swap component. -// eslint-disable-next-line import/no-unused-modules -export default function Widget({ - defaultTokens, - width = DEFAULT_WIDGET_WIDTH, - onDefaultTokenChange, - onReviewSwapClick, -}: WidgetProps) { - const { connector, provider, chainId } = useWeb3React() - const locale = useActiveLocale() - const theme = useWidgetTheme() - const { inputs, tokenSelector } = useSyncWidgetInputs({ - defaultTokens, - onDefaultTokenChange, - }) - const { settings } = useSyncWidgetSettings() - const { transactions } = useSyncWidgetTransactions() - - const toggleWalletDrawer = useToggleAccountDrawer() - const onConnectWalletClick = useCallback(() => { - toggleWalletDrawer() - return false // prevents the in-widget wallet modal from opening - }, [toggleWalletDrawer]) - - const onSwitchChain = useCallback( - // TODO(WEB-1757): Widget should not break if this rejects - upstream the catch to ignore it. - ({ chainId }: AddEthereumChainParameter) => switchChain(connector, Number(chainId)).catch(() => undefined), - [connector] - ) - - const trace = useTrace({ section: InterfaceSectionName.WIDGET }) - const [initialQuoteDate, setInitialQuoteDate] = useState() - const onInitialSwapQuote = useCallback( - (trade: Trade) => { - setInitialQuoteDate(new Date()) - const eventProperties = { - // TODO(1416): Include undefined values. - ...formatSwapQuoteReceivedEventProperties( - trade, - /* gasUseEstimateUSD= */ undefined, - /* fetchingSwapQuoteStartTime= */ undefined - ), - ...trace, - } - sendAnalyticsEvent(SwapEventName.SWAP_QUOTE_RECEIVED, eventProperties) - }, - [trace] - ) - const onApproveToken = useCallback(() => { - const input = inputs.value.INPUT - if (!input) return - const eventProperties = { - chain_id: input.chainId, - token_symbol: input.symbol, - token_address: getTokenAddress(input), - ...trace, - } - sendAnalyticsEvent(InterfaceEventName.APPROVE_TOKEN_TXN_SUBMITTED, eventProperties) - }, [inputs.value.INPUT, trace]) - const onExpandSwapDetails = useCallback(() => { - sendAnalyticsEvent(SwapEventName.SWAP_DETAILS_EXPANDED, { ...trace }) - }, [trace]) - const onSwapPriceUpdateAck = useCallback( - (stale: Trade, update: Trade) => { - const eventProperties = { - chain_id: update.inputAmount.currency.chainId, - response: SwapPriceUpdateUserResponse.ACCEPTED, - token_in_symbol: update.inputAmount.currency.symbol, - token_out_symbol: update.outputAmount.currency.symbol, - price_update_basis_points: getPriceUpdateBasisPoints(stale.executionPrice, update.executionPrice), - ...trace, - } - sendAnalyticsEvent(SwapEventName.SWAP_PRICE_UPDATE_ACKNOWLEDGED, eventProperties) - }, - [trace] - ) - const onSubmitSwapClick = useCallback( - (trade: Trade) => { - const eventProperties = { - // TODO(1416): Include undefined values. - estimated_network_fee_usd: undefined, - transaction_deadline_seconds: undefined, - token_in_address: getTokenAddress(trade.inputAmount.currency), - token_out_address: getTokenAddress(trade.outputAmount.currency), - token_in_symbol: trade.inputAmount.currency.symbol, - token_out_symbol: trade.outputAmount.currency.symbol, - token_in_amount: formatToDecimal(trade.inputAmount, trade.inputAmount.currency.decimals), - token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals), - token_in_amount_usd: undefined, - token_out_amount_usd: undefined, - price_impact_basis_points: formatPercentInBasisPointsNumber(computeRealizedPriceImpact(trade)), - allowed_slippage_basis_points: undefined, - is_auto_router_api: undefined, - is_auto_slippage: undefined, - chain_id: trade.inputAmount.currency.chainId, - duration_from_first_quote_to_swap_submission_milliseconds: getDurationFromDateMilliseconds(initialQuoteDate), - swap_quote_block_number: undefined, - ...trace, - } - sendAnalyticsEvent(SwapEventName.SWAP_SUBMITTED_BUTTON_CLICKED, eventProperties) - }, - [initialQuoteDate, trace] - ) - - if (!(inputs.value.INPUT || inputs.value.OUTPUT)) { - return - } - - return ( - <> -
- { - sendAnalyticsEvent(SwapEventName.SWAP_ERROR, { error, errorInfo, ...trace }) - }} - /> -
- {tokenSelector} - - ) -} - -function WidgetSkeleton({ width = DEFAULT_WIDGET_WIDTH }: { width?: number | string }) { - const theme = useWidgetTheme() - return -} diff --git a/src/components/Widget/inputs.tsx b/src/components/Widget/inputs.tsx deleted file mode 100644 index a1e4dcb55e..0000000000 --- a/src/components/Widget/inputs.tsx +++ /dev/null @@ -1,202 +0,0 @@ -import { sendAnalyticsEvent, useTrace } from '@uniswap/analytics' -import { InterfaceSectionName, SwapEventName } from '@uniswap/analytics-events' -import { Currency, Field, SwapController, SwapEventHandlers, TradeType } from '@uniswap/widgets' -import { useWeb3React } from '@web3-react/core' -import CurrencySearchModal from 'components/SearchModal/CurrencySearchModal' -import { isSupportedChain } from 'constants/chains' -import usePrevious from 'hooks/usePrevious' -import { useCallback, useEffect, useMemo, useState } from 'react' - -const EMPTY_AMOUNT = '' - -type SwapValue = Required['value'] -export type SwapTokens = Pick & { default?: Currency } -export type DefaultTokens = Partial - -function missingDefaultToken(tokens: SwapTokens) { - if (!tokens.default) return false - return !tokens[Field.INPUT]?.equals(tokens.default) && !tokens[Field.OUTPUT]?.equals(tokens.default) -} - -function currenciesEqual(a: Currency | undefined, b: Currency | undefined) { - if (a && b) { - return a.equals(b) - } else { - return !a && !b - } -} - -function tokensEqual(a: SwapTokens | undefined, b: SwapTokens | undefined) { - if (!a || !b) { - return !a && !b - } - return ( - currenciesEqual(a[Field.INPUT], b[Field.INPUT]) && - currenciesEqual(a[Field.OUTPUT], b[Field.OUTPUT]) && - currenciesEqual(a.default, b.default) - ) -} - -/** - * Integrates the Widget's inputs. - * Treats the Widget as a controlled component, using the app's own token selector for selection. - * Enforces that token is a part of the returned value. - */ -export function useSyncWidgetInputs({ - defaultTokens, - onDefaultTokenChange, -}: { - defaultTokens: DefaultTokens - onDefaultTokenChange?: (tokens: SwapTokens) => void -}) { - const trace = useTrace({ section: InterfaceSectionName.WIDGET }) - - const { chainId } = useWeb3React() - const previousChainId = usePrevious(chainId) - - const [type, setType] = useState(TradeType.EXACT_INPUT) - const [amount, setAmount] = useState(EMPTY_AMOUNT) - const [tokens, setTokens] = useState({ - ...defaultTokens, - [Field.OUTPUT]: defaultTokens[Field.OUTPUT] ?? defaultTokens.default, - }) - - // The most recent set of defaults, which can be used to check when the defaults are actually changing. - const baseTokens = usePrevious(defaultTokens) - useEffect(() => { - if (!tokensEqual(baseTokens, defaultTokens)) { - const input = defaultTokens[Field.INPUT] - const output = defaultTokens[Field.OUTPUT] ?? defaultTokens.default - setTokens({ - ...defaultTokens, - [Field.OUTPUT]: currenciesEqual(output, input) ? undefined : output, - }) - } - }, [baseTokens, defaultTokens]) - - /** - * Clear the tokens if the chain changes. - */ - useEffect(() => { - if (chainId !== previousChainId && !!previousChainId && isSupportedChain(chainId)) { - setTokens({ - ...defaultTokens, - [Field.OUTPUT]: defaultTokens[Field.OUTPUT] ?? defaultTokens.default, - }) - setAmount(EMPTY_AMOUNT) - } - }, [chainId, defaultTokens, previousChainId, tokens]) - - const onAmountChange = useCallback( - (field: Field, amount: string, origin?: 'max') => { - if (origin === 'max') { - sendAnalyticsEvent(SwapEventName.SWAP_MAX_TOKEN_AMOUNT_SELECTED, { ...trace }) - } - setType(field === Field.INPUT ? TradeType.EXACT_INPUT : TradeType.EXACT_OUTPUT) - setAmount(amount) - }, - [trace] - ) - - const onSwitchTokens = useCallback(() => { - sendAnalyticsEvent(SwapEventName.SWAP_TOKENS_REVERSED, { ...trace }) - setType((type) => invertTradeType(type)) - setTokens((tokens) => ({ - [Field.INPUT]: tokens[Field.OUTPUT], - [Field.OUTPUT]: tokens[Field.INPUT], - default: tokens.default, - })) - }, [trace]) - - const [selectingField, setSelectingField] = useState() - const onTokenSelectorClick = useCallback((field: Field) => { - setSelectingField(field) - return false - }, []) - - const onTokenSelect = useCallback( - (selectingToken: Currency) => { - if (selectingField === undefined) return - - const otherField = invertField(selectingField) - const isFlip = tokens[otherField]?.equals(selectingToken) - const update: SwapTokens = { - [selectingField]: selectingToken, - [otherField]: isFlip ? tokens[selectingField] : tokens[otherField], - default: tokens.default, - } - - setType((type) => { - // If flipping the tokens, also flip the type/amount. - if (isFlip) { - return invertTradeType(type) - } - - // Setting a new token should clear its amount, if it is set. - const activeField = type === TradeType.EXACT_INPUT ? Field.INPUT : Field.OUTPUT - if (selectingField === activeField) { - setAmount(() => EMPTY_AMOUNT) - } - - return type - }) - - if (missingDefaultToken(update)) { - onDefaultTokenChange?.({ - ...update, - default: update[Field.OUTPUT] ?? selectingToken, - }) - return - } - setTokens(update) - }, - [onDefaultTokenChange, selectingField, tokens] - ) - - const tokenSelector = ( - setSelectingField(undefined)} - selectedCurrency={selectingField && tokens[selectingField]} - otherSelectedCurrency={selectingField && tokens[invertField(selectingField)]} - onCurrencySelect={onTokenSelect} - showCommonBases - /> - ) - - const value: SwapValue = useMemo( - () => ({ - type, - amount, - // If the initial state has not yet been set, preemptively disable the widget by passing no tokens. Effectively, - // this resets the widget - avoiding rendering stale state - because with no tokens the skeleton will be rendered. - ...(tokens[Field.INPUT] || tokens[Field.OUTPUT] ? tokens : undefined), - }), - [amount, tokens, type] - ) - const valueHandlers: SwapEventHandlers = useMemo( - () => ({ onAmountChange, onSwitchTokens, onTokenSelectorClick }), - [onAmountChange, onSwitchTokens, onTokenSelectorClick] - ) - return { inputs: { value, ...valueHandlers }, tokenSelector } -} - -// TODO(zzmp): Move to @uniswap/widgets. -function invertField(field: Field) { - switch (field) { - case Field.INPUT: - return Field.OUTPUT - case Field.OUTPUT: - return Field.INPUT - } -} - -// TODO(zzmp): Include in @uniswap/sdk-core (on TradeType, if possible). -function invertTradeType(tradeType: TradeType) { - switch (tradeType) { - case TradeType.EXACT_INPUT: - return TradeType.EXACT_OUTPUT - case TradeType.EXACT_OUTPUT: - return TradeType.EXACT_INPUT - } -} diff --git a/src/components/Widget/settings.ts b/src/components/Widget/settings.ts deleted file mode 100644 index 5d4554365d..0000000000 --- a/src/components/Widget/settings.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Percent } from '@uniswap/sdk-core' -import { RouterPreference, Slippage, SwapController, SwapEventHandlers } from '@uniswap/widgets' -import { DEFAULT_DEADLINE_FROM_NOW } from 'constants/misc' -import { useCallback, useMemo, useState } from 'react' -import { useUserSlippageTolerance, useUserTransactionTTL } from 'state/user/hooks' -import { SlippageTolerance } from 'state/user/types' - -/** - * Integrates the Widget's settings, keeping the widget and app settings in sync. - * NB: This acts as an integration layer, so certain values are duplicated in order to translate - * between app and widget representations. - */ -export function useSyncWidgetSettings() { - const [appTtl, setAppTtl] = useUserTransactionTTL() - const [widgetTtl, setWidgetTtl] = useState(appTtl / 60) - const onTransactionDeadlineChange = useCallback( - (widgetTtl: number | undefined) => { - setWidgetTtl(widgetTtl) - const appTtl = widgetTtl === undefined ? widgetTtl : widgetTtl * 60 - setAppTtl(appTtl ?? DEFAULT_DEADLINE_FROM_NOW) - }, - [setAppTtl] - ) - - const [appSlippage, setAppSlippage] = useUserSlippageTolerance() - const [widgetSlippage, setWidgetSlippage] = useState( - appSlippage === SlippageTolerance.Auto ? undefined : appSlippage.toFixed(2) - ) - const onSlippageChange = useCallback( - (widgetSlippage: Slippage) => { - setWidgetSlippage(widgetSlippage.max) - if (widgetSlippage.auto || !widgetSlippage.max) { - setAppSlippage(SlippageTolerance.Auto) - } else { - setAppSlippage(new Percent(Math.floor(Number(widgetSlippage.max) * 100), 10_000)) - } - }, - [setAppSlippage] - ) - - const [routerPreference, onRouterPreferenceChange] = useState(RouterPreference.API) - - const onSettingsReset = useCallback(() => { - setWidgetTtl(undefined) - setAppTtl(DEFAULT_DEADLINE_FROM_NOW) - setWidgetSlippage(undefined) - setAppSlippage(SlippageTolerance.Auto) - }, [setAppSlippage, setAppTtl]) - - const settings: SwapController['settings'] = useMemo(() => { - const auto = appSlippage === SlippageTolerance.Auto - return { - slippage: { auto, max: widgetSlippage }, - transactionTtl: widgetTtl, - routerPreference, - } - }, [appSlippage, widgetSlippage, widgetTtl, routerPreference]) - const settingsHandlers: SwapEventHandlers = useMemo( - () => ({ onSettingsReset, onSlippageChange, onTransactionDeadlineChange, onRouterPreferenceChange }), - [onSettingsReset, onSlippageChange, onTransactionDeadlineChange, onRouterPreferenceChange] - ) - - return { settings: { settings, ...settingsHandlers } } -} diff --git a/src/components/Widget/theme.ts b/src/components/Widget/theme.ts deleted file mode 100644 index a80218d0fa..0000000000 --- a/src/components/Widget/theme.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Theme } from '@uniswap/widgets' -import { darkTheme, lightTheme } from 'theme/colors' -import { Z_INDEX } from 'theme/zIndex' - -const zIndex = { - modal: Z_INDEX.modal, -} - -const fonts = { - fontFamily: 'Inter custom', -} - -export const LIGHT_THEME: Theme = { - // surface - accent: lightTheme.accentAction, - accentSoft: lightTheme.accentActionSoft, - container: lightTheme.backgroundSurface, - module: lightTheme.backgroundModule, - interactive: lightTheme.backgroundInteractive, - outline: lightTheme.backgroundOutline, - dialog: lightTheme.backgroundBackdrop, - scrim: lightTheme.backgroundScrim, - // text - onAccent: lightTheme.white, - primary: lightTheme.textPrimary, - secondary: lightTheme.textSecondary, - hint: lightTheme.textTertiary, - onInteractive: lightTheme.accentTextDarkPrimary, - // shadow - deepShadow: lightTheme.deepShadow, - networkDefaultShadow: lightTheme.networkDefaultShadow, - - // state - success: lightTheme.accentSuccess, - warning: lightTheme.accentWarning, - error: lightTheme.accentCritical, - - ...fonts, - zIndex, -} - -export const DARK_THEME: Theme = { - // surface - accent: darkTheme.accentAction, - accentSoft: darkTheme.accentActionSoft, - container: darkTheme.backgroundSurface, - module: darkTheme.backgroundModule, - interactive: darkTheme.backgroundInteractive, - outline: darkTheme.backgroundOutline, - dialog: darkTheme.backgroundBackdrop, - scrim: darkTheme.backgroundScrim, - // text - onAccent: darkTheme.white, - primary: darkTheme.textPrimary, - secondary: darkTheme.textSecondary, - hint: darkTheme.textTertiary, - onInteractive: darkTheme.accentTextLightPrimary, - // shadow - deepShadow: darkTheme.deepShadow, - networkDefaultShadow: darkTheme.networkDefaultShadow, - // state - success: darkTheme.accentSuccess, - warning: darkTheme.accentWarning, - error: darkTheme.accentCritical, - - ...fonts, - zIndex, -} diff --git a/src/components/Widget/transactions.ts b/src/components/Widget/transactions.ts deleted file mode 100644 index 69962862e1..0000000000 --- a/src/components/Widget/transactions.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { sendAnalyticsEvent, useTrace } from '@uniswap/analytics' -import { InterfaceEventName, InterfaceSectionName, SwapEventName } from '@uniswap/analytics-events' -import { Trade } from '@uniswap/router-sdk' -import { Currency, Percent } from '@uniswap/sdk-core' -import { - OnTxSuccess, - TradeType, - Transaction, - TransactionEventHandlers, - TransactionInfo, - TransactionType, - TransactionType as WidgetTransactionType, -} from '@uniswap/widgets' -import { useWeb3React } from '@web3-react/core' -import { - formatPercentInBasisPointsNumber, - formatSwapSignedAnalyticsEventProperties, - formatToDecimal, - getTokenAddress, -} from 'lib/utils/analytics' -import { useCallback, useMemo } from 'react' -import { useTransactionAdder } from 'state/transactions/hooks' -import { - ExactInputSwapTransactionInfo, - ExactOutputSwapTransactionInfo, - TransactionType as AppTransactionType, - WrapTransactionInfo, -} from 'state/transactions/types' -import { currencyId } from 'utils/currencyId' -import { computeRealizedPriceImpact } from 'utils/prices' - -interface AnalyticsEventProps { - trade: Trade - gasUsed: string | undefined - blockNumber: number | undefined - hash: string | undefined - allowedSlippage: Percent - succeeded: boolean -} - -const formatAnalyticsEventProperties = ({ - trade, - hash, - allowedSlippage, - succeeded, - gasUsed, - blockNumber, -}: AnalyticsEventProps) => ({ - estimated_network_fee_usd: gasUsed, - transaction_hash: hash, - token_in_address: getTokenAddress(trade.inputAmount.currency), - token_out_address: getTokenAddress(trade.outputAmount.currency), - token_in_symbol: trade.inputAmount.currency.symbol, - token_out_symbol: trade.outputAmount.currency.symbol, - token_in_amount: formatToDecimal(trade.inputAmount, trade.inputAmount.currency.decimals), - token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals), - price_impact_basis_points: formatPercentInBasisPointsNumber(computeRealizedPriceImpact(trade)), - allowed_slippage_basis_points: formatPercentInBasisPointsNumber(allowedSlippage), - chain_id: - trade.inputAmount.currency.chainId === trade.outputAmount.currency.chainId - ? trade.inputAmount.currency.chainId - : undefined, - swap_quote_block_number: blockNumber, - succeeded, -}) - -/** Integrates the Widget's transactions, showing the widget's transactions in the app. */ -export function useSyncWidgetTransactions() { - const trace = useTrace({ section: InterfaceSectionName.WIDGET }) - - const { chainId } = useWeb3React() - const addTransaction = useTransactionAdder() - - const onTxSubmit = useCallback( - (_hash: string, transaction: Transaction) => { - const { type, response } = transaction.info - - if (!type || !response) { - return - } else if (type === WidgetTransactionType.WRAP || type === WidgetTransactionType.UNWRAP) { - const { type, amount: transactionAmount } = transaction.info - - const eventProperties = { - // get this info from widget handlers - token_in_address: getTokenAddress(transactionAmount.currency), - token_out_address: getTokenAddress(transactionAmount.currency.wrapped), - token_in_symbol: transactionAmount.currency.symbol, - token_out_symbol: transactionAmount.currency.wrapped.symbol, - chain_id: transactionAmount.currency.chainId, - amount: transactionAmount - ? formatToDecimal(transactionAmount, transactionAmount?.currency.decimals) - : undefined, - type: type === WidgetTransactionType.WRAP ? TransactionType.WRAP : TransactionType.UNWRAP, - ...trace, - } - sendAnalyticsEvent(InterfaceEventName.WRAP_TOKEN_TXN_SUBMITTED, eventProperties) - const { amount } = transaction.info - addTransaction(response, { - type: AppTransactionType.WRAP, - unwrapped: type === WidgetTransactionType.UNWRAP, - currencyAmountRaw: amount.quotient.toString(), - chainId, - } as WrapTransactionInfo) - } else if (type === WidgetTransactionType.SWAP) { - const { slippageTolerance, trade, tradeType } = transaction.info - - const eventProperties = { - ...formatSwapSignedAnalyticsEventProperties({ - trade, - // TODO: add once Widgets adds fiat values to callback - fiatValues: { amountIn: undefined, amountOut: undefined }, - txHash: transaction.receipt?.transactionHash ?? '', - }), - ...trace, - } - sendAnalyticsEvent(SwapEventName.SWAP_SIGNED, eventProperties) - const baseTxInfo = { - type: AppTransactionType.SWAP, - tradeType, - inputCurrencyId: currencyId(trade.inputAmount.currency), - outputCurrencyId: currencyId(trade.outputAmount.currency), - } - if (tradeType === TradeType.EXACT_OUTPUT) { - addTransaction(response, { - ...baseTxInfo, - maximumInputCurrencyAmountRaw: trade.maximumAmountIn(slippageTolerance).quotient.toString(), - outputCurrencyAmountRaw: trade.outputAmount.quotient.toString(), - expectedInputCurrencyAmountRaw: trade.inputAmount.quotient.toString(), - } as ExactOutputSwapTransactionInfo) - } else { - addTransaction(response, { - ...baseTxInfo, - inputCurrencyAmountRaw: trade.inputAmount.quotient.toString(), - expectedOutputCurrencyAmountRaw: trade.outputAmount.quotient.toString(), - minimumOutputCurrencyAmountRaw: trade.minimumAmountOut(slippageTolerance).quotient.toString(), - } as ExactInputSwapTransactionInfo) - } - } - }, - [addTransaction, chainId, trace] - ) - - const onTxSuccess: OnTxSuccess = useCallback((hash: string, tx) => { - if (tx.info.type === TransactionType.SWAP) { - const { trade, slippageTolerance } = tx.info - sendAnalyticsEvent( - SwapEventName.SWAP_TRANSACTION_COMPLETED, - formatAnalyticsEventProperties({ - trade, - hash, - gasUsed: tx.receipt?.gasUsed?.toString(), - blockNumber: tx.receipt?.blockNumber, - allowedSlippage: slippageTolerance, - succeeded: tx.receipt?.status === 1, - }) - ) - } - }, []) - - const txHandlers: TransactionEventHandlers = useMemo(() => ({ onTxSubmit, onTxSuccess }), [onTxSubmit, onTxSuccess]) - - return { transactions: { ...txHandlers } } -} diff --git a/src/featureFlags/flags/featureFlags.ts b/src/featureFlags/flags/featureFlags.ts index b6cfaf7de4..5c037eff61 100644 --- a/src/featureFlags/flags/featureFlags.ts +++ b/src/featureFlags/flags/featureFlags.ts @@ -6,5 +6,4 @@ export enum FeatureFlag { permit2 = 'permit2', fiatOnRampButtonOnSwap = 'fiat_on_ramp_button_on_swap_page', detailsV2 = 'details_v2', - removeWidget = 'remove_widget_tdp', } diff --git a/src/featureFlags/flags/removeWidgetTdp.ts b/src/featureFlags/flags/removeWidgetTdp.ts deleted file mode 100644 index 241948cd08..0000000000 --- a/src/featureFlags/flags/removeWidgetTdp.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BaseVariant, FeatureFlag, useBaseFlag } from '../index' - -export function useWidgetRemovalFlag(): BaseVariant { - return useBaseFlag(FeatureFlag.removeWidget, BaseVariant.Control) -} - -export function useWidgetRemovalEnabled(): boolean { - return useWidgetRemovalFlag() === BaseVariant.Enabled -} - -export { BaseVariant as WidgetRemovalVariant } diff --git a/src/hooks/Tokens.ts b/src/hooks/Tokens.ts index 030a44f7d8..714542b259 100644 --- a/src/hooks/Tokens.ts +++ b/src/hooks/Tokens.ts @@ -12,7 +12,7 @@ import { isL2ChainId } from 'utils/chains' import { useAllLists, useCombinedActiveList, useCombinedTokenMapFromUrls } from '../state/lists/hooks' import { WrappedTokenInfo } from '../state/lists/wrappedTokenInfo' -import { deserializeToken, useUserAddedTokens, useUserAddedTokensOnChain } from '../state/user/hooks' +import { deserializeToken, useUserAddedTokens } from '../state/user/hooks' import { useUnsupportedTokenList } from './../state/lists/hooks' type Maybe = T | null | undefined @@ -182,20 +182,6 @@ export function useIsUserAddedToken(currency: Currency | undefined | null): bool return !!userAddedTokens.find((token) => currency.equals(token)) } -// Check if currency on specific chain is included in custom list from user storage -export function useIsUserAddedTokenOnChain( - address: string | undefined | null, - chain: number | undefined | null -): boolean { - const userAddedTokens = useUserAddedTokensOnChain(chain) - - if (!address || !chain) { - return false - } - - return !!userAddedTokens.find((token) => token.address === address) -} - // undefined if invalid or does not exist // null if loading or null was passed // otherwise returns the token diff --git a/src/hooks/useUniversalRouter.ts b/src/hooks/useUniversalRouter.ts index 02973243bd..1ee2a2f13c 100644 --- a/src/hooks/useUniversalRouter.ts +++ b/src/hooks/useUniversalRouter.ts @@ -52,77 +52,73 @@ export function useUniversalRouterSwapCallback( const analyticsContext = useTrace() return useCallback(async (): Promise => { - return trace( - 'swap.send', - async ({ setTraceData, setTraceStatus, setTraceError }) => { + return trace('swap.send', async ({ setTraceData, setTraceStatus, setTraceError }) => { + try { + if (!account) throw new Error('missing account') + if (!chainId) throw new Error('missing chainId') + if (!provider) throw new Error('missing provider') + if (!trade) throw new Error('missing trade') + + setTraceData('slippageTolerance', options.slippageTolerance.toFixed(2)) + const { calldata: data, value } = SwapRouter.swapERC20CallParameters(trade, { + slippageTolerance: options.slippageTolerance, + deadlineOrPreviousBlockhash: options.deadline?.toString(), + inputTokenPermit: options.permit, + fee: options.feeOptions, + }) + const tx = { + from: account, + to: UNIVERSAL_ROUTER_ADDRESS(chainId), + data, + // TODO(https://github.com/Uniswap/universal-router-sdk/issues/113): universal-router-sdk returns a non-hexlified value. + ...(value && !isZero(value) ? { value: toHex(value) } : {}), + } + + let gasEstimate: BigNumber try { - if (!account) throw new Error('missing account') - if (!chainId) throw new Error('missing chainId') - if (!provider) throw new Error('missing provider') - if (!trade) throw new Error('missing trade') - - setTraceData('slippageTolerance', options.slippageTolerance.toFixed(2)) - const { calldata: data, value } = SwapRouter.swapERC20CallParameters(trade, { - slippageTolerance: options.slippageTolerance, - deadlineOrPreviousBlockhash: options.deadline?.toString(), - inputTokenPermit: options.permit, - fee: options.feeOptions, - }) - const tx = { - from: account, - to: UNIVERSAL_ROUTER_ADDRESS(chainId), - data, - // TODO(https://github.com/Uniswap/universal-router-sdk/issues/113): universal-router-sdk returns a non-hexlified value. - ...(value && !isZero(value) ? { value: toHex(value) } : {}), - } - - let gasEstimate: BigNumber - try { - gasEstimate = await provider.estimateGas(tx) - } catch (gasError) { - setTraceStatus('failed_precondition') - setTraceError(gasError) - console.warn(gasError) - throw new GasEstimationError() - } - const gasLimit = calculateGasMargin(gasEstimate) - setTraceData('gasLimit', gasLimit.toNumber()) - const response = await provider - .getSigner() - .sendTransaction({ ...tx, gasLimit }) - .then((response) => { - sendAnalyticsEvent(SwapEventName.SWAP_SIGNED, { - ...formatSwapSignedAnalyticsEventProperties({ - trade, - fiatValues, - txHash: response.hash, - }), + gasEstimate = await provider.estimateGas(tx) + } catch (gasError) { + setTraceStatus('failed_precondition') + setTraceError(gasError) + console.warn(gasError) + throw new GasEstimationError() + } + const gasLimit = calculateGasMargin(gasEstimate) + setTraceData('gasLimit', gasLimit.toNumber()) + const response = await provider + .getSigner() + .sendTransaction({ ...tx, gasLimit }) + .then((response) => { + sendAnalyticsEvent(SwapEventName.SWAP_SIGNED, { + ...formatSwapSignedAnalyticsEventProperties({ + trade, + fiatValues, + txHash: response.hash, + }), + ...analyticsContext, + }) + if (tx.data !== response.data) { + sendAnalyticsEvent(SwapEventName.SWAP_MODIFIED_IN_WALLET, { + txHash: response.hash, ...analyticsContext, }) - if (tx.data !== response.data) { - sendAnalyticsEvent(SwapEventName.SWAP_MODIFIED_IN_WALLET, { - txHash: response.hash, - ...analyticsContext, - }) - throw new ModifiedSwapError() - } - return response - }) - return response - } catch (swapError: unknown) { - if (swapError instanceof ModifiedSwapError) throw swapError + throw new ModifiedSwapError() + } + return response + }) + return response + } catch (swapError: unknown) { + if (swapError instanceof ModifiedSwapError) throw swapError - // Cancellations are not failures, and must be accounted for as 'cancelled'. - if (didUserReject(swapError)) setTraceStatus('cancelled') + // Cancellations are not failures, and must be accounted for as 'cancelled'. + if (didUserReject(swapError)) setTraceStatus('cancelled') - // GasEstimationErrors are already traced when they are thrown. - if (!(swapError instanceof GasEstimationError)) setTraceError(swapError) + // GasEstimationErrors are already traced when they are thrown. + if (!(swapError instanceof GasEstimationError)) setTraceError(swapError) - throw new Error(swapErrorToUserReadableMessage(swapError)) - } - }, - { tags: { is_widget: false } } - ) + throw new Error(swapErrorToUserReadableMessage(swapError)) + } + }) }, [ account, analyticsContext, diff --git a/src/pages/Pool/PositionPage.tsx b/src/pages/Pool/PositionPage.tsx index 0278ac99ea..35fc703bdb 100644 --- a/src/pages/Pool/PositionPage.tsx +++ b/src/pages/Pool/PositionPage.tsx @@ -6,7 +6,6 @@ import { InterfacePageName } from '@uniswap/analytics-events' import { formatPrice, NumberType } from '@uniswap/conedison/format' import { Currency, CurrencyAmount, Fraction, Percent, Price, Token } from '@uniswap/sdk-core' import { NonfungiblePositionManager, Pool, Position } from '@uniswap/v3-sdk' -import { SupportedChainId } from '@uniswap/widgets' import { useWeb3React } from '@web3-react/core' import { sendEvent } from 'components/analytics' import Badge from 'components/Badge' @@ -20,7 +19,7 @@ import { RowBetween, RowFixed } from 'components/Row' import { Dots } from 'components/swap/styleds' import Toggle from 'components/Toggle' import TransactionConfirmationModal, { ConfirmationModalContent } from 'components/TransactionConfirmationModal' -import { CHAIN_IDS_TO_NAMES, isSupportedChain } from 'constants/chains' +import { CHAIN_IDS_TO_NAMES, isSupportedChain, SupportedChainId } from 'constants/chains' import { isGqlSupportedChain } from 'graphql/data/util' import { useToken } from 'hooks/Tokens' import { useV3NFTPositionManagerContract } from 'hooks/useContract' diff --git a/src/state/routing/slice.ts b/src/state/routing/slice.ts index 135a8b5b5f..a3edb92a03 100644 --- a/src/state/routing/slice.ts +++ b/src/state/routing/slice.ts @@ -115,7 +115,6 @@ export const routingApi = createApi({ isAutoRouter: args.routerPreference === RouterPreference.AUTO || args.routerPreference === RouterPreference.API, }, - tags: { is_widget: false }, } ) }, diff --git a/src/state/user/hooks.tsx b/src/state/user/hooks.tsx index e23e7bbcc9..91bb2eedf8 100644 --- a/src/state/user/hooks.tsx +++ b/src/state/user/hooks.tsx @@ -209,7 +209,7 @@ export function useAddUserToken(): (token: Token) => void { ) } -export function useUserAddedTokensOnChain(chainId: number | undefined | null): Token[] { +function useUserAddedTokensOnChain(chainId: number | undefined | null): Token[] { const serializedTokensMap = useAppSelector(({ user: { tokens } }) => tokens) return useMemo(() => { diff --git a/src/tracing/trace.test.ts b/src/tracing/trace.test.ts index f1f56e8bdf..2d6da02e4a 100644 --- a/src/tracing/trace.test.ts +++ b/src/tracing/trace.test.ts @@ -38,12 +38,13 @@ describe('trace', () => { }) it('records transaction', async () => { - const metadata = { data: { a: 'a', b: 2 }, tags: { is_widget: true } } + const metadata = { data: { a: 'a', b: 2 }, tags: { test_tag: true } } + // @ts-ignore test_tag is not an expected key for `tags` but force it for testing purposes await trace('test', () => Promise.resolve(), metadata) const transaction = getTransaction() expect(transaction.name).toBe('test') expect(transaction.data).toEqual({ a: 'a', b: 2 }) - expect(transaction.tags).toEqual({ is_widget: true }) + expect(transaction.tags).toEqual({ test_tag: true }) }) describe('defaults status', () => { @@ -77,11 +78,12 @@ describe('trace', () => { describe('setTraceTag', () => { it('sets a transaction tag', async () => { await trace('test', ({ setTraceTag }) => { - setTraceTag('is_widget', true) + // @ts-ignore test_tag is not an expected key for `tags` but force it for testing purposes + setTraceTag('test_tag', true) return Promise.resolve() }) const transaction = getTransaction() - expect(transaction.tags).toEqual({ is_widget: true }) + expect(transaction.tags).toEqual({ test_tag: true }) }) }) @@ -166,7 +168,8 @@ describe('trace', () => { describe('traceChild', () => { it('starts a span under a transaction', async () => { await trace('test', ({ traceChild }) => { - traceChild('child', () => Promise.resolve(), { data: { e: 'e' }, tags: { is_widget: true } }) + // @ts-ignore test_tag is not an expected key for `tags` but force it for testing purposes + traceChild('child', () => Promise.resolve(), { data: { e: 'e' }, tags: { test_tag: true } }) return Promise.resolve() }) const transaction = getTransaction() @@ -174,7 +177,7 @@ describe('trace', () => { assert(span) expect(span.op).toBe('child') expect(span.data).toEqual({ e: 'e' }) - expect(span.tags).toEqual({ is_widget: true }) + expect(span.tags).toEqual({ test_tag: true }) }) }) }) diff --git a/src/tracing/trace.ts b/src/tracing/trace.ts index 12b917d12d..07b872b3a1 100644 --- a/src/tracing/trace.ts +++ b/src/tracing/trace.ts @@ -1,9 +1,8 @@ import * as Sentry from '@sentry/react' import { Span, SpanStatusType } from '@sentry/tracing' -type TraceTags = { - is_widget: boolean -} +// Modify this type if you want to add any Trace tags. +type TraceTags = Record interface TraceMetadata { /** Arbitrary data stored on a trace. */ diff --git a/yarn.lock b/yarn.lock index 2bf5c22a6d..93f2409f91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1158,7 +1158,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@>=7.17.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== @@ -5157,7 +5157,7 @@ react "^18.2.0" react-dom "^18.2.0" -"@uniswap/conedison@^1.4.0", "@uniswap/conedison@^1.5.3": +"@uniswap/conedison@^1.4.0": version "1.5.3" resolved "https://registry.yarnpkg.com/@uniswap/conedison/-/conedison-1.5.3.tgz#2a2fc9ca848644f21944a2d087de54032a6acf93" integrity sha512-b8j2/0FzqLU4Qq+M+QEPGzacnZxNrzAHp7yoAWRvNJiFyLjBvcgfaT9ORS8rw17M8XBLWjh83faj5Kymc+62qw== @@ -5243,7 +5243,7 @@ "@uniswap/v2-sdk" "^3.0.1" "@uniswap/v3-sdk" "^3.8.3" -"@uniswap/sdk-core@^3.0.0-alpha.3", "@uniswap/sdk-core@^3.0.1", "@uniswap/sdk-core@^3.1.0", "@uniswap/sdk-core@^3.2.0", "@uniswap/sdk-core@^3.2.2": +"@uniswap/sdk-core@^3.0.0-alpha.3", "@uniswap/sdk-core@^3.0.1", "@uniswap/sdk-core@^3.1.0", "@uniswap/sdk-core@^3.2.2": version "3.2.2" resolved "https://registry.yarnpkg.com/@uniswap/sdk-core/-/sdk-core-3.2.2.tgz#50dbc6f2543d088680f36fb61e01bb90d4d8fa71" integrity sha512-dPA34T8EVfFzKtw1NC1Mr7M0aXpY1UN+lUpdBv757JxKKMlGQTg96XTIfjYCflqEshxlBdz2+IVQgk6H+dMu5g== @@ -5255,7 +5255,7 @@ tiny-invariant "^1.1.0" toformat "^2.0.0" -"@uniswap/smart-order-router@^3.6.0", "@uniswap/smart-order-router@^3.6.1": +"@uniswap/smart-order-router@^3.6.1": version "3.6.1" resolved "https://registry.yarnpkg.com/@uniswap/smart-order-router/-/smart-order-router-3.6.1.tgz#658497b907b1033d68fe8b7f613d624d31e33d80" integrity sha512-UKCEeqzryu8kREOGEG2gomXApkGGJ301rp1j1sdDhTeMW2C6EiDo2jkfGjKYMb9CHJnb0YkXB7E6XIT8U4UYXA== @@ -5305,7 +5305,7 @@ dotenv "^14.2.0" hardhat-watcher "^2.1.1" -"@uniswap/token-lists@^1.0.0-beta.25", "@uniswap/token-lists@^1.0.0-beta.30", "@uniswap/token-lists@^1.0.0-beta.31": +"@uniswap/token-lists@^1.0.0-beta.25", "@uniswap/token-lists@^1.0.0-beta.31": version "1.0.0-beta.31" resolved "https://registry.yarnpkg.com/@uniswap/token-lists/-/token-lists-1.0.0-beta.31.tgz#ff3852bd505ec7b4c276625c762ea79a93a919ec" integrity sha512-BQVoelKCRf64IToPEs1wxiXOnhr/ukwPOF78XG11PrTAOL4F8umjYKFb8ZPv1/dIJsPaC7GhLSriEqyp94SasQ== @@ -5400,7 +5400,7 @@ base64-sol "1.0.1" hardhat-watcher "^2.1.1" -"@uniswap/v3-sdk@^3.7.0", "@uniswap/v3-sdk@^3.8.2", "@uniswap/v3-sdk@^3.8.3", "@uniswap/v3-sdk@^3.9.0": +"@uniswap/v3-sdk@^3.7.0", "@uniswap/v3-sdk@^3.8.3", "@uniswap/v3-sdk@^3.9.0": version "3.9.0" resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.9.0.tgz#de93fa19f89c29d460996aa4d0b4bb6531641105" integrity sha512-LuoF3UcY1DxSAQKJ3E4/1Eq4HaNp+x+7q9mvbpiu+/PBj+O1DjLforAMrKxu+RsA0aarmZtz7yBnAPy+akgfgQ== @@ -5423,69 +5423,6 @@ "@uniswap/v3-core" "1.0.0" "@uniswap/v3-periphery" "^1.0.1" -"@uniswap/widgets@^2.49.0": - version "2.49.0" - resolved "https://registry.yarnpkg.com/@uniswap/widgets/-/widgets-2.49.0.tgz#a59ebb0b13b8e4501891c88e6f8dd03dcc8f04d5" - integrity sha512-w/UhOmhcmgwyP/iQVFQ4u3naOrykUlfxGBnqN2PbI9BY5fNjE6Y0+mnsNcBF+cVoY2vBfFrwIJH/Ug2Cts5skg== - dependencies: - "@babel/runtime" ">=7.17.0" - "@fontsource/ibm-plex-mono" "^4.5.1" - "@fontsource/inter" "^4.5.1" - "@popperjs/core" "^2.4.4" - "@reduxjs/toolkit" "^1.6.1" - "@uniswap/conedison" "^1.5.3" - "@uniswap/permit2-sdk" "^1.2.0" - "@uniswap/redux-multicall" "^1.1.8" - "@uniswap/router-sdk" "^1.3.0" - "@uniswap/sdk-core" "^3.2.0" - "@uniswap/smart-order-router" "^3.6.0" - "@uniswap/token-lists" "^1.0.0-beta.30" - "@uniswap/universal-router-sdk" "^1.3.8" - "@uniswap/v2-sdk" "^3.0.1" - "@uniswap/v3-sdk" "^3.8.2" - "@web3-react/core" "8.1.2-beta.0" - "@web3-react/eip1193" "8.1.2-beta.0" - "@web3-react/empty" "8.1.2-beta.0" - "@web3-react/metamask" "8.1.2-beta.0" - "@web3-react/network" "8.1.2-beta.0" - "@web3-react/types" "8.1.2-beta.0" - "@web3-react/url" "8.1.2-beta.0" - "@web3-react/walletconnect" "8.1.2-beta.0" - ajv "^8.11.0" - ajv-formats "^2.1.1" - cids "^1.0.0" - ethers "^5.7.2" - immer "^9.0.6" - jotai "1.4.0" - jsbi "^3.1.4" - make-plural "^7.0.0" - ms.macro "^2.0.0" - multicodec "^3.0.1" - multihashes "^4.0.2" - node-vibrant "^3.2.1-alpha.1" - polished "^3.3.2" - popper-max-size-modifier "^0.2.0" - qrcode "^1.5.0" - react ">=17.0.1" - react-dom ">=17.0.1" - react-feather "^2.0.8" - react-popper "^2.2.3" - react-redux ">=7.2.2" - react-virtualized-auto-sizer "^1.0.2" - react-window "^1.8.5" - rebass "^4.0.7" - redux ">=4.1.2" - resize-observer-polyfill "^1.5.1" - setimmediate "^1.0.5" - styled-components ">=5" - tiny-invariant "^1.2.0" - wcag-contrast "^3.0.0" - wicg-inert "^3.1.1" - optionalDependencies: - bufferutil "^4.0.6" - encoding "^0.1.13" - utf-8-validate "^5.0.8" - "@vanilla-extract/babel-plugin-debug-ids@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.0.2.tgz#24674b4d09e98236c883d23aef6f37d1a326af28" @@ -6013,7 +5950,7 @@ dependencies: "@web3-react/types" "^8.2.0" -"@web3-react/core@8.1.2-beta.0", "@web3-react/core@^8.2.0": +"@web3-react/core@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/core/-/core-8.2.0.tgz#95fb615bb283be520e6f61b5e48cfb0047943808" integrity sha512-r7dmK2E8Jrpvm/DF93hGMB+8lECHSI3Oo0NrHbhxkisK6in6rdgAXeYFhZtM48LBAm9py6fQvLzjCM6Qx9q0oQ== @@ -6024,7 +5961,7 @@ optionalDependencies: "@ethersproject/providers" "^5" -"@web3-react/eip1193@8.1.2-beta.0", "@web3-react/eip1193@^8.2.0": +"@web3-react/eip1193@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/eip1193/-/eip1193-8.2.0.tgz#a7953769f9d0bec54472aceb01f72c889458378f" integrity sha512-Ugbt+FisHO8aLD5o5B4AZdtgSVpjrbmtC5MgHrOEBw+IwFqr20EJreh052u8ExI2OrPjARIVOkNcp50Xxs7oUw== @@ -6032,7 +5969,7 @@ "@web3-react/types" "^8.2.0" eventemitter3 "^4.0.7" -"@web3-react/empty@8.1.2-beta.0", "@web3-react/empty@^8.2.0": +"@web3-react/empty@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/empty/-/empty-8.2.0.tgz#dac248ab22867700b5be716cd5a3f8f95308e8c5" integrity sha512-U8BIF56lW1GHXFz9cPAJnlmKM8VcsjpXr+LXNXGS+9mr5AEjNcjbn9T9EnQf4hY4YXUPHAnjsVcZoUfw3q6u7Q== @@ -6048,7 +5985,7 @@ "@safe-global/safe-apps-sdk" "^7.10.0" "@web3-react/types" "^8.2.0" -"@web3-react/metamask@8.1.2-beta.0", "@web3-react/metamask@^8.2.0": +"@web3-react/metamask@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/metamask/-/metamask-8.2.0.tgz#4f822e36bcbc37bbbce6f97f55c10537eeb5014d" integrity sha512-nitDOHFZOUi9FWBmGAKlvExZDxZPWSJaXZn0lxl7LKaM6rPwBoEWKI2wJJvWCf+h5q9+p6ifiaFd7JKqucS6rQ== @@ -6056,7 +5993,7 @@ "@metamask/detect-provider" "^1.2.0" "@web3-react/types" "^8.2.0" -"@web3-react/network@8.1.2-beta.0", "@web3-react/network@^8.2.0": +"@web3-react/network@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/network/-/network-8.2.0.tgz#225ae9e135711e8c64ab3123570abaa5b82b8145" integrity sha512-3OcJwuaot8A+VTSoCe17MZv/K/TNVw7DjtYoS7lBRS/CmzYIwP53Tosea4MkliOuXiUUKj7Ge1D2FpWohq6pHw== @@ -6073,14 +6010,14 @@ "@web3-react/types" "^8.2.0" zustand "^4.3.5" -"@web3-react/types@8.1.2-beta.0", "@web3-react/types@^8.2.0": +"@web3-react/types@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/types/-/types-8.2.0.tgz#195464ebb94cb417e6dc3c16951573f9b6b3832a" integrity sha512-TBYTFlqJZaEpVbuAAKRJFX5PZc3lI1TqDZzY94zwCrCh4GBepwwK7+PxmRAppMFuNa5x0vFX/ghLEC44e6TCFg== dependencies: zustand "^4.3.5" -"@web3-react/url@8.1.2-beta.0", "@web3-react/url@^8.2.0": +"@web3-react/url@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/url/-/url-8.2.0.tgz#5df80f213bf6b6f382aa842ae37ad0703d413a37" integrity sha512-dt1i8AgZso6y0sX67JSZ1DzsU511iFu4Gcxksbw/yJPlFybsHco+Fcg94WLjWj4ec26kVRUBySUVCyXrYlg0kQ== @@ -6088,7 +6025,7 @@ "@ethersproject/providers" "^5" "@web3-react/types" "^8.2.0" -"@web3-react/walletconnect@8.1.2-beta.0", "@web3-react/walletconnect@^8.2.0": +"@web3-react/walletconnect@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@web3-react/walletconnect/-/walletconnect-8.2.0.tgz#e4e325132f04f03a07a19cd193b4b97bfe6a9914" integrity sha512-Yl1C0beRnwohtFZ9c6xz6mOci2MqoES2hYKhJI4X7qKqcmQJC6TOeLjlYfzjdUTUvP8IDf0A7flYZVeBUvL/fg== @@ -7682,7 +7619,7 @@ buffer@^6.0.3, buffer@~6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -bufferutil@^4.0.1, bufferutil@^4.0.6: +bufferutil@^4.0.1: version "4.0.7" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== @@ -10016,23 +9953,11 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== -encode-utf8@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" - integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== - encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -12326,7 +12251,7 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@0.6, iconv-lite@^0.6.2: +iconv-lite@0.6: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -13735,7 +13660,7 @@ jest@26.6.0: import-local "^3.0.2" jest-cli "^26.6.0" -jotai@1.4.0, jotai@^1.3.7: +jotai@^1.3.7: version "1.4.0" resolved "https://registry.yarnpkg.com/jotai/-/jotai-1.4.0.tgz#0f350f65a968dd3ee2f9ad3618a3af635cd10220" integrity sha512-CUB+A3N+WjtimZvtDnMXvVRognzKh86KB3rKnQlbRvpnmGYU+O9aOZMWSgTaxstXc4Y5GYy02LBEjiv4Rs8MAg== @@ -16050,11 +15975,6 @@ pngjs@^3.0.0, pngjs@^3.3.0, pngjs@^3.3.3: resolved "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz" integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== -pngjs@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" - integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== - pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -16079,11 +15999,6 @@ polyfill-object.fromentries@^1.0.1: resolved "https://registry.nlark.com/polyfill-object.fromentries/download/polyfill-object.fromentries-1.0.1.tgz#1a5d89e3777684a852c9b6a6a1d2c3f9c262fc86" integrity sha1-Gl2J43d2hKhSybamodLD+cJi/IY= -popper-max-size-modifier@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/popper-max-size-modifier/-/popper-max-size-modifier-0.2.0.tgz#1574744401296a488b4974909d130a85db94256f" - integrity sha512-UerPt9pZfTFnpSpIBVJrR3ibHMuU1k5K01AyNLfMUWCr4z1MFH+dsayPlAF9ZeYExa02HPiQn5OIMqUSVtJEbg== - portfinder@^1.0.26: version "1.0.28" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" @@ -17016,16 +16931,6 @@ qrcode@1.4.4: pngjs "^3.3.0" yargs "^13.2.4" -qrcode@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.1.tgz#0103f97317409f7bc91772ef30793a54cd59f0cb" - integrity sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg== - dependencies: - dijkstrajs "^1.0.1" - encode-utf8 "^1.0.3" - pngjs "^5.0.0" - yargs "^15.3.1" - qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -17215,7 +17120,7 @@ react-dev-utils@^11.0.3: strip-ansi "6.0.0" text-table "0.2.0" -react-dom@>=17.0.1, react-dom@^18.2.0: +react-dom@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== @@ -17310,7 +17215,7 @@ react-query@^3.39.1: broadcast-channel "^3.4.1" match-sorter "^6.0.2" -react-redux@>=7.2.2, react-redux@^8.0.2: +react-redux@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.2.tgz#bc2a304bb21e79c6808e3e47c50fe1caf62f7aad" integrity sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA== @@ -17476,7 +17381,7 @@ react-window@^1.8.5: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" -react@>=17.0.1, react@^18.2.0: +react@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== @@ -17597,7 +17502,7 @@ redux-thunk@^2.4.1: resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== -redux@>=4.1.2, redux@^4.0.0, redux@^4.1.2: +redux@^4.0.0, redux@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== @@ -19170,7 +19075,7 @@ style-loader@1.3.0: loader-utils "^2.0.0" schema-utils "^2.7.0" -styled-components@>=5, styled-components@^5.3.5: +styled-components@^5.3.5: version "5.3.5" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.5.tgz#a750a398d01f1ca73af16a241dec3da6deae5ec4" integrity sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg== @@ -20201,7 +20106,7 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -utf-8-validate@^5.0.2, utf-8-validate@^5.0.8: +utf-8-validate@^5.0.2: version "5.0.10" resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== @@ -20715,11 +20620,6 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" -wicg-inert@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/wicg-inert/-/wicg-inert-3.1.2.tgz#df10cf756b773a96fce107c3ddcd43be5d1e3944" - integrity sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang== - widest-line@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz"