chore: Goodbye widget :( (#6543)
* goodbye widget :( * remove unused function * modify trace tests * fix lint * is github down?
This commit is contained in:
parent
14e3ef044e
commit
bd8113d018
1
.github/dependabot.yml
vendored
1
.github/dependabot.yml
vendored
@ -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'
|
||||
|
@ -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')
|
||||
|
15
package.json
15
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",
|
||||
|
@ -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"
|
||||
/>
|
||||
<FeatureFlagOption
|
||||
variant={WidgetRemovalVariant}
|
||||
value={useWidgetRemovalFlag()}
|
||||
featureFlag={FeatureFlag.removeWidget}
|
||||
label="Swap Component on TDP"
|
||||
/>
|
||||
<FeatureFlagGroup name="Debug">
|
||||
<FeatureFlagOption
|
||||
variant={TraceJsonRpcVariant}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { Trace } from '@uniswap/analytics'
|
||||
import { InterfacePageName } from '@uniswap/analytics-events'
|
||||
import { Currency } from '@uniswap/widgets'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import CurrencyLogo from 'components/Logo/CurrencyLogo'
|
||||
import { AboutSection } from 'components/Tokens/TokenDetails/About'
|
||||
@ -22,19 +21,14 @@ import TokenDetailsSkeleton, {
|
||||
import StatsSection from 'components/Tokens/TokenDetails/StatsSection'
|
||||
import TokenSafetyMessage from 'components/TokenSafety/TokenSafetyMessage'
|
||||
import TokenSafetyModal from 'components/TokenSafety/TokenSafetyModal'
|
||||
import Widget from 'components/Widget'
|
||||
import { SwapTokens } from 'components/Widget/inputs'
|
||||
import { NATIVE_CHAIN_ID, nativeOnChain } from 'constants/tokens'
|
||||
import { checkWarning } from 'constants/tokenSafety'
|
||||
import { useWidgetRemovalEnabled } from 'featureFlags/flags/removeWidgetTdp'
|
||||
import { TokenPriceQuery } from 'graphql/data/__generated__/types-and-hooks'
|
||||
import { Chain, TokenQuery, TokenQueryData } from 'graphql/data/Token'
|
||||
import { QueryToken } from 'graphql/data/Token'
|
||||
import { CHAIN_NAME_TO_CHAIN_ID, getTokenDetailsURL } from 'graphql/data/util'
|
||||
import { useIsUserAddedTokenOnChain } from 'hooks/Tokens'
|
||||
import { useOnGlobalChainSwitch } from 'hooks/useGlobalChainSwitch'
|
||||
import { UNKNOWN_TOKEN_SYMBOL, useTokenFromActiveNetwork } from 'lib/hooks/useCurrency'
|
||||
import { getTokenAddress } from 'lib/utils/analytics'
|
||||
import { Swap } from 'pages/Swap'
|
||||
import { useCallback, useMemo, useState, useTransition } from 'react'
|
||||
import { ArrowLeft } from 'react-feather'
|
||||
@ -130,12 +124,10 @@ export default function TokenDetails({
|
||||
)
|
||||
|
||||
const { token: detailedToken, didFetchFromChain } = useRelevantToken(address, pageChainId, tokenQueryData)
|
||||
const { token: widgetInputToken } = useRelevantToken(inputTokenAddress, pageChainId, undefined)
|
||||
|
||||
const tokenWarning = address ? checkWarning(address) : null
|
||||
const isBlockedToken = tokenWarning?.canProceed === false
|
||||
const navigate = useNavigate()
|
||||
const widgetRemovalEnabled = useWidgetRemovalEnabled()
|
||||
|
||||
// Wrapping navigate in a transition prevents Suspense from unnecessarily showing fallbacks again.
|
||||
const [isPending, startTokenTransition] = useTransition()
|
||||
@ -152,22 +144,6 @@ export default function TokenDetails({
|
||||
[address, crossChainMap, didFetchFromChain, navigate, detailedToken?.isNative]
|
||||
)
|
||||
useOnGlobalChainSwitch(navigateToTokenForChain)
|
||||
const navigateToWidgetSelectedToken = useCallback(
|
||||
(tokens: SwapTokens) => {
|
||||
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<SwapState, Field.INPUT | Field.OUTPUT>) => {
|
||||
@ -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<boolean>((resolve) => (shouldShowSpeedbump ? setContinueSwap({ resolve }) : resolve(true))),
|
||||
[shouldShowSpeedbump]
|
||||
)
|
||||
|
||||
const onResolveSwap = useCallback(
|
||||
(value: boolean) => {
|
||||
continueSwap?.resolve(value)
|
||||
@ -268,7 +238,6 @@ export default function TokenDetails({
|
||||
|
||||
<RightPanel onClick={() => isBlockedToken && setOpenTokenSafetyModal(true)}>
|
||||
<div style={{ pointerEvents: isBlockedToken ? 'none' : 'auto' }}>
|
||||
{widgetRemovalEnabled ? (
|
||||
<Swap
|
||||
chainId={pageChainId}
|
||||
prefilledState={{
|
||||
@ -278,16 +247,6 @@ export default function TokenDetails({
|
||||
onCurrencyChange={handleCurrencyChange}
|
||||
disableTokenInputs={pageChainId !== connectedChainId}
|
||||
/>
|
||||
) : (
|
||||
<Widget
|
||||
defaultTokens={{
|
||||
[Field.INPUT]: widgetInputToken ?? undefined,
|
||||
default: detailedToken ?? undefined,
|
||||
}}
|
||||
onDefaultTokenChange={navigateToWidgetSelectedToken}
|
||||
onReviewSwapClick={onReviewSwapClick}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{tokenWarning && <TokenSafetyMessage tokenAddress={address} warning={tokenWarning} />}
|
||||
{detailedToken && <BalanceSummary token={detailedToken} />}
|
||||
|
@ -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<Date>()
|
||||
const onInitialSwapQuote = useCallback(
|
||||
(trade: Trade<Currency, Currency, TradeType>) => {
|
||||
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<Currency, Currency, TradeType>, update: Trade<Currency, Currency, TradeType>) => {
|
||||
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<Currency, Currency, TradeType>) => {
|
||||
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 <WidgetSkeleton />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ zIndex: 1, position: 'relative' }}>
|
||||
<SwapWidget
|
||||
hideConnectionUI
|
||||
brandedFooter={false}
|
||||
permit2
|
||||
routerUrl={WIDGET_ROUTER_URL}
|
||||
locale={locale}
|
||||
theme={theme}
|
||||
width={width}
|
||||
defaultChainId={chainId}
|
||||
onConnectWalletClick={onConnectWalletClick}
|
||||
provider={provider}
|
||||
onSwitchChain={onSwitchChain}
|
||||
tokenList={EMPTY_TOKEN_LIST} // prevents loading the default token list, as we use our own token selector UI
|
||||
{...inputs}
|
||||
{...settings}
|
||||
{...transactions}
|
||||
onExpandSwapDetails={onExpandSwapDetails}
|
||||
onReviewSwapClick={onReviewSwapClick}
|
||||
onSubmitSwapClick={onSubmitSwapClick}
|
||||
onSwapApprove={onApproveToken}
|
||||
onInitialSwapQuote={onInitialSwapQuote}
|
||||
onSwapPriceUpdateAck={onSwapPriceUpdateAck}
|
||||
dialogOptions={{
|
||||
pageCentered: true,
|
||||
animationType: DialogAnimationType.FADE,
|
||||
}}
|
||||
onError={(error, errorInfo) => {
|
||||
sendAnalyticsEvent(SwapEventName.SWAP_ERROR, { error, errorInfo, ...trace })
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{tokenSelector}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function WidgetSkeleton({ width = DEFAULT_WIDGET_WIDTH }: { width?: number | string }) {
|
||||
const theme = useWidgetTheme()
|
||||
return <SwapWidgetSkeleton theme={theme} width={width} />
|
||||
}
|
@ -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<SwapController>['value']
|
||||
export type SwapTokens = Pick<SwapValue, Field.INPUT | Field.OUTPUT> & { default?: Currency }
|
||||
export type DefaultTokens = Partial<SwapTokens>
|
||||
|
||||
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<SwapValue['type']>(TradeType.EXACT_INPUT)
|
||||
const [amount, setAmount] = useState<SwapValue['amount']>(EMPTY_AMOUNT)
|
||||
const [tokens, setTokens] = useState<SwapTokens>({
|
||||
...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<Field>()
|
||||
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 = (
|
||||
<CurrencySearchModal
|
||||
isOpen={selectingField !== undefined}
|
||||
onDismiss={() => 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
|
||||
}
|
||||
}
|
@ -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<number | undefined>(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<string | undefined>(
|
||||
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 } }
|
||||
}
|
@ -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,
|
||||
}
|
@ -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<Currency, Currency, TradeType>
|
||||
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<TransactionInfo>) => {
|
||||
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 } }
|
||||
}
|
@ -6,5 +6,4 @@ export enum FeatureFlag {
|
||||
permit2 = 'permit2',
|
||||
fiatOnRampButtonOnSwap = 'fiat_on_ramp_button_on_swap_page',
|
||||
detailsV2 = 'details_v2',
|
||||
removeWidget = 'remove_widget_tdp',
|
||||
}
|
||||
|
@ -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 }
|
@ -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> = 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
|
||||
|
@ -52,9 +52,7 @@ export function useUniversalRouterSwapCallback(
|
||||
const analyticsContext = useTrace()
|
||||
|
||||
return useCallback(async (): Promise<TransactionResponse> => {
|
||||
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')
|
||||
@ -120,9 +118,7 @@ export function useUniversalRouterSwapCallback(
|
||||
|
||||
throw new Error(swapErrorToUserReadableMessage(swapError))
|
||||
}
|
||||
},
|
||||
{ tags: { is_widget: false } }
|
||||
)
|
||||
})
|
||||
}, [
|
||||
account,
|
||||
analyticsContext,
|
||||
|
@ -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'
|
||||
|
@ -115,7 +115,6 @@ export const routingApi = createApi({
|
||||
isAutoRouter:
|
||||
args.routerPreference === RouterPreference.AUTO || args.routerPreference === RouterPreference.API,
|
||||
},
|
||||
tags: { is_widget: false },
|
||||
}
|
||||
)
|
||||
},
|
||||
|
@ -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(() => {
|
||||
|
@ -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 })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -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<string, never>
|
||||
|
||||
interface TraceMetadata {
|
||||
/** Arbitrary data stored on a trace. */
|
||||
|
146
yarn.lock
146
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"
|
||||
|
Loading…
Reference in New Issue
Block a user