Commit e81e8a8f authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

fix: inadvertent merges/reverts (#2915)

* Revert "Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)"

This reverts commit 7d343dcf.

* Revert "deleted files"

This reverts commit 097b8361.
parent 7d343dcf
......@@ -8,13 +8,33 @@
"jsx": true
}
},
"ignorePatterns": ["node_modules/**/*"],
"settings": {
"react": {
"version": "detect"
}
},
"ignorePatterns": [
"src/types/v3",
"src/abis/types",
"src/locales/**/*.js",
"src/locales/**/en-US.po",
"src/state/data/generated.ts",
"node_modules",
"coverage",
"build",
"dist",
".DS_Store",
".env.local",
".env.development.local",
".env.test.local",
".env.production.local",
".idea/",
".vscode/",
"package-lock.json",
"yarn.lock"
],
"extends": [
"react-app",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
......
......@@ -11,7 +11,6 @@ on:
jobs:
run-linters:
name: Run linters
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }}
runs-on: ubuntu-latest
steps:
......@@ -39,10 +38,15 @@ jobs:
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run linters
- name: Run eslint w/ autofix
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }}
uses: wearerequired/lint-action@36c7e6689e80d785d27a22f71d970f3a3b4fcb70
with:
github_token: ${{ secrets.github_token }}
eslint: true
eslint_extensions: js,jsx,ts,tsx,json
eslint_args: "-c .eslintrc.json"
auto_fix: true
- name: Run eslint
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.owner.login != github.repository_owner }}
run: yarn eslint .
......@@ -74,6 +74,7 @@ class CustomizedBridge extends Eip1193Bridge {
}
// sets up the injected provider to be a mock ethereum provider with the given mnemonic/index
// eslint-disable-next-line no-undef
Cypress.Commands.overwrite('visit', (original, url, options) => {
return original(url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url, {
...options,
......
export default {
const linguiConfig = {
catalogs: [
{
path: '<rootDir>/src/locales/{locale}',
......@@ -52,3 +52,5 @@ export default {
runtimeConfigModule: ['@lingui/core', 'i18n'],
sourceLocale: 'en-US',
}
export default linguiConfig
......@@ -152,12 +152,6 @@
"bundle": "microbundle --tsconfig tsconfig.lib.json src/lib/index.tsx --format esm,cjs",
"cosmos": "open http://localhost:5000 && cross-env FAST_REFRESH=false cosmos"
},
"eslintConfig": {
"extends": "react-app",
"ignorePatterns": [
"node_modules"
]
},
"browserslist": {
"production": [
">0.2%",
......
......@@ -80,7 +80,7 @@ function ClaimSummary({ info: { recipient, uniAmountRaw } }: { info: ClaimTransa
)
}
function SubmitProposalTransactionSummary({}: { info: SubmitProposalTransactionInfo }) {
function SubmitProposalTransactionSummary(_: { info: SubmitProposalTransactionInfo }) {
return <Trans>Submit new proposal</Trans>
}
......@@ -147,13 +147,13 @@ function WrapSummary({ info: { currencyAmountRaw, unwrapped } }: { info: WrapTra
}
}
function DepositLiquidityStakingSummary({}: { info: DepositLiquidityStakingTransactionInfo }) {
function DepositLiquidityStakingSummary(_: { info: DepositLiquidityStakingTransactionInfo }) {
// not worth rendering the tokens since you can should no longer deposit liquidity in the staking contracts
// todo: deprecate and delete the code paths that allow this, show user more information
return <Trans>Deposit liquidity</Trans>
}
function WithdrawLiquidityStakingSummary({}: { info: WithdrawLiquidityStakingTransactionInfo }) {
function WithdrawLiquidityStakingSummary(_: { info: WithdrawLiquidityStakingTransactionInfo }) {
return <Trans>Withdraw deposited liquidity</Trans>
}
......
......@@ -10,7 +10,7 @@ import { injected, portis, walletlink } from '../../connectors'
import { SUPPORTED_WALLETS } from '../../constants/wallet'
import { useActiveWeb3React } from '../../hooks/web3'
import { clearAllTransactions } from '../../state/transactions/actions'
import { ExternalLink, LinkStyledButton, TYPE } from '../../theme'
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
import { shortenAddress } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { ButtonSecondary } from '../Button'
......@@ -378,9 +378,9 @@ export default function AccountDetails({
{!!pendingTransactions.length || !!confirmedTransactions.length ? (
<LowerSection>
<AutoRow mb={'1rem'} style={{ justifyContent: 'space-between' }}>
<TYPE.body>
<ThemedText.Body>
<Trans>Recent Transactions</Trans>
</TYPE.body>
</ThemedText.Body>
<LinkStyledButton onClick={clearAllTransactionsCallback}>
<Trans>(clear all)</Trans>
</LinkStyledButton>
......@@ -390,9 +390,9 @@ export default function AccountDetails({
</LowerSection>
) : (
<LowerSection>
<TYPE.body color={theme.text1}>
<ThemedText.Body color={theme.text1}>
<Trans>Your transactions will appear here...</Trans>
</TYPE.body>
</ThemedText.Body>
</LowerSection>
)}
</>
......
import { Trans } from '@lingui/macro'
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { t } from '@lingui/macro'
import { ReactNode, useCallback, useContext } from 'react'
import styled, { ThemeContext } from 'styled-components/macro'
import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, ThemedText } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { AutoColumn } from '../Column'
import { RowBetween } from '../Row'
......@@ -107,9 +108,9 @@ export default function AddressInputPanel({
<InputContainer>
<AutoColumn gap="md">
<RowBetween>
<TYPE.black color={theme.text2} fontWeight={500} fontSize={14}>
<ThemedText.Black color={theme.text2} fontWeight={500} fontSize={14}>
{label ?? <Trans>Recipient</Trans>}
</TYPE.black>
</ThemedText.Black>
{address && chainId && (
<ExternalLink
href={getExplorerLink(chainId, name ?? address, ExplorerDataType.ADDRESS)}
......
......@@ -4,7 +4,7 @@ import HoverInlineText from 'components/HoverInlineText'
import { useMemo } from 'react'
import useTheme from '../../hooks/useTheme'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { warningSeverity } from '../../utils/prices'
export function FiatValue({
......@@ -25,7 +25,7 @@ export function FiatValue({
}, [priceImpact, theme.green1, theme.red1, theme.text3, theme.yellow1])
return (
<TYPE.body fontSize={14} color={fiatValue ? theme.text2 : theme.text4}>
<ThemedText.Body fontSize={14} color={fiatValue ? theme.text2 : theme.text4}>
{fiatValue ? (
<Trans>
~$ <HoverInlineText text={fiatValue?.toSignificant(6, { groupSeparator: ',' })} />
......@@ -39,6 +39,6 @@ export function FiatValue({
(<Trans>{priceImpact.multiply(-1).toSignificant(3)}%</Trans>)
</span>
) : null}
</TYPE.body>
</ThemedText.Body>
)
}
......@@ -13,7 +13,7 @@ import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import useTheme from '../../hooks/useTheme'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCurrencyBalance } from '../../state/wallet/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { ButtonGray } from '../Button'
import CurrencyLogo from '../CurrencyLogo'
import DoubleCurrencyLogo from '../DoubleLogo'
......@@ -212,9 +212,9 @@ export default function CurrencyInputPanel({
<FixedContainer>
<AutoColumn gap="sm" justify="center">
<Lock />
<TYPE.label fontSize="12px" textAlign="center" padding="0 12px">
<ThemedText.Label fontSize="12px" textAlign="center" padding="0 12px">
<Trans>The market price is outside your specified price range. Single-asset deposit only.</Trans>
</TYPE.label>
</ThemedText.Label>
</AutoColumn>
</FixedContainer>
)}
......@@ -271,7 +271,7 @@ export default function CurrencyInputPanel({
<RowBetween>
{account ? (
<RowFixed style={{ height: '17px' }}>
<TYPE.body
<ThemedText.Body
onClick={onMax}
color={theme.text2}
fontWeight={400}
......@@ -287,7 +287,7 @@ export default function CurrencyInputPanel({
</Trans>
)
) : null}
</TYPE.body>
</ThemedText.Body>
{showMaxButton && selectedCurrencyBalance ? (
<StyledBalanceMax onClick={onMax}>
<Trans>(Max)</Trans>
......
......@@ -4,7 +4,7 @@ import ReactGA from 'react-ga'
import styled from 'styled-components/macro'
import store, { AppState } from '../../state'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, ThemedText } from '../../theme'
import { userAgent } from '../../utils/userAgent'
import { AutoColumn } from '../Column'
import { AutoRow } from '../Row'
......@@ -47,6 +47,8 @@ type ErrorBoundaryState = {
error: Error | null
}
const IS_UNISWAP = window.location.hostname === 'app.uniswap.org'
export default class ErrorBoundary extends React.Component<unknown, ErrorBoundaryState> {
constructor(props: unknown) {
super(props)
......@@ -67,6 +69,7 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
render() {
const { error } = this.state
if (error !== null) {
const encodedBody = encodeURIComponent(issueBody(error))
return (
......@@ -74,15 +77,16 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
<BodyWrapper>
<AutoColumn gap={'md'}>
<SomethingWentWrongWrapper>
<TYPE.label fontSize={24} fontWeight={600}>
<ThemedText.Label fontSize={24} fontWeight={600}>
<Trans>Something went wrong</Trans>
</TYPE.label>
</ThemedText.Label>
</SomethingWentWrongWrapper>
<CodeBlockWrapper>
<code>
<TYPE.main fontSize={10}>{error.stack}</TYPE.main>
<ThemedText.Main fontSize={10}>{error.stack}</ThemedText.Main>
</code>
</CodeBlockWrapper>
{IS_UNISWAP ? (
<AutoRow>
<LinkWrapper>
<ExternalLink
......@@ -92,21 +96,22 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
)}`}
target="_blank"
>
<TYPE.link fontSize={16}>
<ThemedText.Link fontSize={16}>
<Trans>Create an issue on GitHub</Trans>
<span></span>
</TYPE.link>
</ThemedText.Link>
</ExternalLink>
</LinkWrapper>
<LinkWrapper>
<ExternalLink id="get-support-on-discord" href="https://discord.gg/FCfyBSbCU5" target="_blank">
<TYPE.link fontSize={16}>
<ThemedText.Link fontSize={16}>
<Trans>Get support on Discord</Trans>
<span></span>
</TYPE.link>
</ThemedText.Link>
</ExternalLink>
</LinkWrapper>
</AutoRow>
) : null}
</AutoColumn>
</BodyWrapper>
</FallbackWrapper>
......@@ -121,7 +126,7 @@ function getRelevantState(): null | keyof AppState {
if (!path.startsWith('#/')) {
return null
}
const pieces = path.substring(2).split(/[\/\\?]/)
const pieces = path.substring(2).split(/[/\\?]/)
switch (pieces[0]) {
case 'swap':
return 'swap'
......
......@@ -6,12 +6,12 @@ import { useFeeTierDistribution } from 'hooks/useFeeTierDistribution'
import { PoolState } from 'hooks/usePools'
import React from 'react'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { FeeTierPercentageBadge } from './FeeTierPercentageBadge'
import { FEE_AMOUNT_DETAIL } from './shared'
const ResponsiveText = styled(TYPE.label)`
const ResponsiveText = styled(ThemedText.Label)`
line-height: 16px;
font-size: 14px;
......@@ -37,9 +37,9 @@ export function FeeOption({ feeAmount, active, poolState, distributions, onClick
<ResponsiveText>
<Trans>{FEE_AMOUNT_DETAIL[feeAmount].label}%</Trans>
</ResponsiveText>
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
<ThemedText.Main fontWeight={400} fontSize="12px" textAlign="left">
{FEE_AMOUNT_DETAIL[feeAmount].description}
</TYPE.main>
</ThemedText.Main>
</AutoColumn>
{distributions && (
......
......@@ -4,7 +4,7 @@ import Badge from 'components/Badge'
import { useFeeTierDistribution } from 'hooks/useFeeTierDistribution'
import { PoolState } from 'hooks/usePools'
import React from 'react'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
export function FeeTierPercentageBadge({
feeAmount,
......@@ -17,7 +17,7 @@ export function FeeTierPercentageBadge({
}) {
return (
<Badge>
<TYPE.label fontSize={10}>
<ThemedText.Label fontSize={10}>
{!distributions || poolState === PoolState.NOT_EXISTS || poolState === PoolState.INVALID ? (
<Trans>Not created</Trans>
) : distributions[feeAmount] !== undefined ? (
......@@ -25,7 +25,7 @@ export function FeeTierPercentageBadge({
) : (
<Trans>No data</Trans>
)}
</TYPE.label>
</ThemedText.Label>
</Badge>
)
}
......@@ -14,7 +14,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import ReactGA from 'react-ga'
import { Box } from 'rebass'
import styled, { keyframes } from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { FeeOption } from './FeeOption'
import { FeeTierPercentageBadge } from './FeeTierPercentageBadge'
......@@ -149,18 +149,18 @@ export default function FeeSelector({
<AutoColumn id="add-liquidity-selected-fee">
{!feeAmount ? (
<>
<TYPE.label>
<ThemedText.Label>
<Trans>Fee tier</Trans>
</TYPE.label>
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
</ThemedText.Label>
<ThemedText.Main fontWeight={400} fontSize="12px" textAlign="left">
<Trans>The % you will earn in fees.</Trans>
</TYPE.main>
</ThemedText.Main>
</>
) : (
<>
<TYPE.label className="selected-fee-label">
<ThemedText.Label className="selected-fee-label">
<Trans>{FEE_AMOUNT_DETAIL[feeAmount].label}% fee tier</Trans>
</TYPE.label>
</ThemedText.Label>
<Box style={{ width: 'fit-content', marginTop: '8px' }} className="selected-fee-percentage">
{distributions && (
<FeeTierPercentageBadge
......
......@@ -6,7 +6,7 @@ import ms from 'ms.macro'
import { useEffect, useState } from 'react'
import { useBlockNumber } from 'state/application/hooks'
import styled, { keyframes } from 'styled-components/macro'
import { ExternalLink, TYPE } from 'theme'
import { ExternalLink, ThemedText } from 'theme'
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
import { ChainConnectivityWarning } from './ChainConnectivityWarning'
......@@ -25,7 +25,7 @@ const StyledPolling = styled.div<{ warning: boolean }>`
display: none;
`}
`
const StyledPollingNumber = styled(TYPE.small)<{ breathe: boolean; hovering: boolean }>`
const StyledPollingNumber = styled(ThemedText.Small)<{ breathe: boolean; hovering: boolean }>`
transition: opacity 0.25s ease;
opacity: ${({ breathe, hovering }) => (hovering ? 0.7 : breathe ? 1 : 0.5)};
:hover {
......
......@@ -14,7 +14,7 @@ import useUSDCPrice from '../../hooks/useUSDCPrice'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTotalUniEarned } from '../../state/stake/hooks'
import { useAggregateUniBalance, useTokenBalance } from '../../state/wallet/hooks'
import { ExternalLink, StyledInternalLink, TYPE, UniTokenAnimated } from '../../theme'
import { ExternalLink, StyledInternalLink, ThemedText, UniTokenAnimated } from '../../theme'
import { computeUniCirculation } from '../../utils/computeUniCirculation'
import { AutoColumn } from '../Column'
import { Break, CardBGImage, CardNoise, CardSection, DataCard } from '../earn/styled'
......@@ -70,9 +70,9 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
<CardNoise />
<CardSection gap="md">
<RowBetween>
<TYPE.white color="white">
<ThemedText.White color="white">
<Trans>Your UNI Breakdown</Trans>
</TYPE.white>
</ThemedText.White>
<StyledClose stroke="white" onClick={() => setShowUniBalanceModal(false)} />
</RowBetween>
</CardSection>
......@@ -82,29 +82,29 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
<CardSection gap="sm">
<AutoColumn gap="md" justify="center">
<UniTokenAnimated width="48px" src={tokenLogo} />{' '}
<TYPE.white fontSize={48} fontWeight={600} color="white">
<ThemedText.White fontSize={48} fontWeight={600} color="white">
{total?.toFixed(2, { groupSeparator: ',' })}
</TYPE.white>
</ThemedText.White>
</AutoColumn>
<AutoColumn gap="md">
<RowBetween>
<TYPE.white color="white">
<ThemedText.White color="white">
<Trans>Balance:</Trans>
</TYPE.white>
<TYPE.white color="white">{uniBalance?.toFixed(2, { groupSeparator: ',' })}</TYPE.white>
</ThemedText.White>
<ThemedText.White color="white">{uniBalance?.toFixed(2, { groupSeparator: ',' })}</ThemedText.White>
</RowBetween>
<RowBetween>
<TYPE.white color="white">
<ThemedText.White color="white">
<Trans>Unclaimed:</Trans>
</TYPE.white>
<TYPE.white color="white">
</ThemedText.White>
<ThemedText.White color="white">
{uniToClaim?.toFixed(4, { groupSeparator: ',' })}{' '}
{uniToClaim && uniToClaim.greaterThan('0') && (
<StyledInternalLink onClick={() => setShowUniBalanceModal(false)} to="/uni">
<Trans>(claim)</Trans>
</StyledInternalLink>
)}
</TYPE.white>
</ThemedText.White>
</RowBetween>
</AutoColumn>
</CardSection>
......@@ -114,22 +114,22 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
<CardSection gap="sm">
<AutoColumn gap="md">
<RowBetween>
<TYPE.white color="white">
<ThemedText.White color="white">
<Trans>UNI price:</Trans>
</TYPE.white>
<TYPE.white color="white">${uniPrice?.toFixed(2) ?? '-'}</TYPE.white>
</ThemedText.White>
<ThemedText.White color="white">${uniPrice?.toFixed(2) ?? '-'}</ThemedText.White>
</RowBetween>
<RowBetween>
<TYPE.white color="white">
<ThemedText.White color="white">
<Trans>UNI in circulation:</Trans>
</TYPE.white>
<TYPE.white color="white">{circulation?.toFixed(0, { groupSeparator: ',' })}</TYPE.white>
</ThemedText.White>
<ThemedText.White color="white">{circulation?.toFixed(0, { groupSeparator: ',' })}</ThemedText.White>
</RowBetween>
<RowBetween>
<TYPE.white color="white">
<ThemedText.White color="white">
<Trans>Total Supply</Trans>
</TYPE.white>
<TYPE.white color="white">{totalSupply?.toFixed(0, { groupSeparator: ',' })}</TYPE.white>
</ThemedText.White>
<ThemedText.White color="white">{totalSupply?.toFixed(0, { groupSeparator: ',' })}</ThemedText.White>
</RowBetween>
{uni && uni.chainId === 1 ? (
<ExternalLink href={`${infoLink}/token/${uni.address}`}>
......
......@@ -15,7 +15,7 @@ import styled from 'styled-components/macro'
import { ReactComponent as Logo } from '../../assets/svg/logo.svg'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, ThemedText } from '../../theme'
import ClaimModal from '../claim/ClaimModal'
import { CardNoise } from '../earn/styled'
import Menu from '../Menu'
......@@ -309,7 +309,7 @@ export default function Header() {
{availableClaim && !showClaimPopup && (
<UNIWrapper onClick={toggleClaimModal}>
<UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}>
<TYPE.white padding="0 2px">
<ThemedText.White padding="0 2px">
{claimTxn && !claimTxn?.receipt ? (
<Dots>
<Trans>Claiming UNI</Trans>
......@@ -317,7 +317,7 @@ export default function Header() {
) : (
<Trans>Claim UNI</Trans>
)}
</TYPE.white>
</ThemedText.White>
</UNIAmount>
<CardNoise />
</UNIWrapper>
......
import jazzicon from '@metamask/jazzicon'
import useENSAvatar from 'hooks/useENSAvatar'
import { useEffect, useRef, useState } from 'react'
import { useLayoutEffect, useMemo, useRef, useState } from 'react'
import styled from 'styled-components/macro'
import { useActiveWeb3React } from '../../hooks/web3'
......@@ -20,27 +20,29 @@ const StyledAvatar = styled.img`
`
export default function Identicon() {
const ref = useRef<HTMLDivElement>(null)
const { account } = useActiveWeb3React()
const { avatar } = useENSAvatar(account ?? undefined)
const [fetchable, setFetchable] = useState(true)
useEffect(() => {
if ((!avatar || !fetchable) && account) {
const icon = jazzicon(16, parseInt(account?.slice(2, 10), 16))
const current = ref.current
const icon = useMemo(() => account && jazzicon(16, parseInt(account.slice(2, 10), 16)), [account])
const iconRef = useRef<HTMLDivElement>(null)
useLayoutEffect(() => {
const current = iconRef.current
if (icon) {
current?.appendChild(icon)
return () => {
current?.removeChild(icon)
}
}
return
}, [account, avatar, fetchable])
}, [icon, iconRef])
return (
<StyledIdenticon ref={ref}>
{avatar && fetchable && (
<StyledIdenticon>
{avatar && fetchable ? (
<StyledAvatar alt="avatar" src={avatar} onError={() => setFetchable(false)}></StyledAvatar>
) : (
<span ref={iconRef} />
)}
</StyledIdenticon>
)
......
......@@ -6,7 +6,7 @@ import { AutoColumn } from 'components/Column'
import { ReactNode, useCallback, useEffect, useState } from 'react'
import { Minus, Plus } from 'react-feather'
import styled, { keyframes } from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { Input as NumericalInput } from '../NumericalInput'
......@@ -57,13 +57,13 @@ const StyledInput = styled(NumericalInput)<{ usePercent?: boolean }>`
`};
`
const InputTitle = styled(TYPE.small)`
const InputTitle = styled(ThemedText.Small)`
color: ${({ theme }) => theme.text2};
font-size: 12px;
font-weight: 500;
`
const ButtonLabel = styled(TYPE.white)<{ disabled: boolean }>`
const ButtonLabel = styled(ThemedText.White)<{ disabled: boolean }>`
color: ${({ theme, disabled }) => (disabled ? theme.text2 : theme.text1)} !important;
`
......
......@@ -37,7 +37,7 @@ export const Area = ({
.y0(yScale(0))(
series.filter((d) => {
const value = xScale(xValue(d))
return value > 0 && value <= innerWidth
return value > 0 && value <= window.innerWidth
}) as Iterable<[number, number]>
) ?? undefined
}
......
......@@ -14,7 +14,7 @@ import { batch } from 'react-redux'
import { Bound } from 'state/mint/v3/actions'
import styled from 'styled-components/macro'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { Chart } from './Chart'
import { useDensityChartData } from './hooks'
import { ZoomLevels } from './types'
......@@ -58,9 +58,9 @@ function InfoBox({ message, icon }: { message?: ReactNode; icon: ReactNode }) {
<ColumnCenter style={{ height: '100%', justifyContent: 'center' }}>
{icon}
{message && (
<TYPE.mediumHeader padding={10} marginTop="20px" textAlign="center">
<ThemedText.MediumHeader padding={10} marginTop="20px" textAlign="center">
{message}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
)}
</ColumnCenter>
)
......
......@@ -5,7 +5,7 @@ import styled, { ThemeContext } from 'styled-components/macro'
import Circle from '../../assets/images/blue-loader.svg'
import { useActiveWeb3React } from '../../hooks/web3'
import { CloseIcon, CustomLightSpinner, TYPE } from '../../theme'
import { CloseIcon, CustomLightSpinner, ThemedText } from '../../theme'
import { ExternalLink } from '../../theme/components'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { AutoColumn, ColumnCenter } from '../Column'
......@@ -32,9 +32,9 @@ export function LoadingView({ children, onDismiss }: { children: any; onDismiss:
</ConfirmedIcon>
<AutoColumn gap="100px" justify={'center'}>
{children}
<TYPE.subHeader>
<ThemedText.SubHeader>
<Trans>Confirm this transaction in your wallet</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</AutoColumn>
</ConfirmOrLoadingWrapper>
)
......@@ -68,9 +68,9 @@ export function SubmittedView({
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
style={{ marginLeft: '4px' }}
>
<TYPE.subHeader>
<ThemedText.SubHeader>
<Trans>View transaction on Explorer</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</ExternalLink>
)}
</AutoColumn>
......
......@@ -10,7 +10,7 @@ import { useAppDispatch } from 'state/hooks'
import { resetMintState } from 'state/mint/actions'
import { resetMintState as resetMintV3State } from 'state/mint/v3/actions'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import Row, { RowBetween } from '../Row'
import SettingsTab from '../Settings'
......@@ -136,7 +136,7 @@ export function AddRemoveTabs({
>
<StyledArrowLeft stroke={theme.text2} />
</StyledHistoryLink>
<TYPE.mediumHeader
<ThemedText.MediumHeader
fontWeight={500}
fontSize={20}
style={{ flex: '1', margin: 'auto', textAlign: children ? 'start' : 'center' }}
......@@ -148,7 +148,7 @@ export function AddRemoveTabs({
) : (
<Trans>Remove Liquidity</Trans>
)}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<Box style={{ marginRight: '.5rem' }}>{children}</Box>
<SettingsTab placeholderSlippage={defaultSlippage} />
</RowBetween>
......
......@@ -6,7 +6,6 @@ import ReactGA from 'react-ga'
import styled, { keyframes } from 'styled-components/macro'
import tokenLogo from '../../assets/images/token-logo.png'
import { ButtonPrimary } from '../../components/Button'
import { useActiveWeb3React } from '../../hooks/web3'
import {
useModalOpen,
......@@ -16,7 +15,8 @@ import {
} from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { useUserHasAvailableClaim, useUserUnclaimedAmount } from '../../state/claim/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { ButtonPrimary } from '../Button'
import { AutoColumn } from '../Column'
import { CardBGImage, CardNoise } from '../earn/styled'
......@@ -98,10 +98,10 @@ export default function ClaimPopup() {
<StyledClose stroke="white" onClick={toggleShowClaimPopup} />
<AutoColumn style={{ padding: '2rem 0', zIndex: 10 }} justify="center">
<UniToken width="48px" src={tokenLogo} />{' '}
<TYPE.white style={{ marginTop: '1rem' }} fontSize={36} fontWeight={600}>
<ThemedText.White style={{ marginTop: '1rem' }} fontSize={36} fontWeight={600}>
{unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} UNI
</TYPE.white>
<TYPE.white style={{ paddingTop: '1.25rem', textAlign: 'center' }} fontWeight={600} color="white">
</ThemedText.White>
<ThemedText.White style={{ paddingTop: '1.25rem', textAlign: 'center' }} fontWeight={600} color="white">
<span role="img" aria-label="party">
🎉
</span>{' '}
......@@ -109,12 +109,12 @@ export default function ClaimPopup() {
<span role="img" aria-label="party">
🎉
</span>
</TYPE.white>
<TYPE.subHeader style={{ paddingTop: '0.5rem', textAlign: 'center' }} color="white">
</ThemedText.White>
<ThemedText.SubHeader style={{ paddingTop: '0.5rem', textAlign: 'center' }} color="white">
<Trans>
Thanks for being part of the Uniswap community <Heart size={12} />
</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</AutoColumn>
<AutoColumn style={{ zIndex: 10 }} justify="center">
<ButtonPrimary padding="8px" $borderRadius="8px" width={'fit-content'} onClick={handleToggleSelfClaimModal}>
......
......@@ -4,8 +4,8 @@ import styled, { ThemeContext } from 'styled-components/macro'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTransaction } from '../../state/transactions/hooks'
import { TYPE } from '../../theme'
import { ExternalLink } from '../../theme/components'
import { ThemedText } from '../../theme'
import { ExternalLink } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { TransactionSummary } from '../AccountDetails/TransactionSummary'
import { AutoColumn } from '../Column'
......@@ -30,9 +30,9 @@ export default function TransactionPopup({ hash }: { hash: string }) {
{success ? <CheckCircle color={theme.green1} size={24} /> : <AlertCircle color={theme.red1} size={24} />}
</div>
<AutoColumn gap="8px">
<TYPE.body fontWeight={500}>
<ThemedText.Body fontWeight={500}>
<TransactionSummary info={tx.info} />
</TYPE.body>
</ThemedText.Body>
{chainId && (
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}>
View on Explorer
......
......@@ -14,7 +14,7 @@ import { useColor } from '../../hooks/useColor'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTokenBalance } from '../../state/wallet/hooks'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, ThemedText } from '../../theme'
import { currencyId } from '../../utils/currencyId'
import { unwrappedToken } from '../../utils/unwrappedToken'
import { ButtonEmpty, ButtonPrimary, ButtonSecondary } from '../Button'
......@@ -142,7 +142,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
</GreyCard>
) : (
<LightCard>
<TYPE.subHeader style={{ textAlign: 'center' }}>
<ThemedText.SubHeader style={{ textAlign: 'center' }}>
<span role="img" aria-label="wizard-icon">
⭐️
</span>{' '}
......@@ -150,7 +150,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
By adding liquidity you&apos;ll earn 0.3% of all trades on this pair proportional to your share of the
pool. Fees are added to the pool, accrue in real time and can be claimed by withdrawing your liquidity.
</Trans>{' '}
</TYPE.subHeader>
</ThemedText.SubHeader>
</LightCard>
)}
</>
......
......@@ -13,7 +13,7 @@ import JSBI from 'jsbi'
import { ReactNode, useCallback, useContext, useState } from 'react'
import { Bound } from 'state/mint/v3/actions'
import { ThemeContext } from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { formatTickPrice } from 'utils/formatTickPrice'
import { unwrappedToken } from 'utils/unwrappedToken'
......@@ -70,9 +70,9 @@ export const PositionPreview = ({
size={24}
margin={true}
/>
<TYPE.label ml="10px" fontSize="24px">
<ThemedText.Label ml="10px" fontSize="24px">
{currency0?.symbol} / {currency1?.symbol}
</TYPE.label>
</ThemedText.Label>
</RowFixed>
<RangeBadge removed={removed} inRange={inRange} />
</RowBetween>
......@@ -82,36 +82,36 @@ export const PositionPreview = ({
<RowBetween>
<RowFixed>
<CurrencyLogo currency={currency0} />
<TYPE.label ml="8px">{currency0?.symbol}</TYPE.label>
<ThemedText.Label ml="8px">{currency0?.symbol}</ThemedText.Label>
</RowFixed>
<RowFixed>
<TYPE.label mr="8px">{position.amount0.toSignificant(4)}</TYPE.label>
<ThemedText.Label mr="8px">{position.amount0.toSignificant(4)}</ThemedText.Label>
</RowFixed>
</RowBetween>
<RowBetween>
<RowFixed>
<CurrencyLogo currency={currency1} />
<TYPE.label ml="8px">{currency1?.symbol}</TYPE.label>
<ThemedText.Label ml="8px">{currency1?.symbol}</ThemedText.Label>
</RowFixed>
<RowFixed>
<TYPE.label mr="8px">{position.amount1.toSignificant(4)}</TYPE.label>
<ThemedText.Label mr="8px">{position.amount1.toSignificant(4)}</ThemedText.Label>
</RowFixed>
</RowBetween>
<Break />
<RowBetween>
<TYPE.label>
<ThemedText.Label>
<Trans>Fee Tier</Trans>
</TYPE.label>
<TYPE.label>
</ThemedText.Label>
<ThemedText.Label>
<Trans>{position?.pool?.fee / 10000}%</Trans>
</TYPE.label>
</ThemedText.Label>
</RowBetween>
</AutoColumn>
</LightCard>
<AutoColumn gap="md">
<RowBetween>
{title ? <TYPE.main>{title}</TYPE.main> : <div />}
{title ? <ThemedText.Main>{title}</ThemedText.Main> : <div />}
<RateToggle
currencyA={sorted ? currency0 : currency1}
currencyB={sorted ? currency1 : currency0}
......@@ -122,57 +122,57 @@ export const PositionPreview = ({
<RowBetween>
<LightCard width="48%" padding="8px">
<AutoColumn gap="4px" justify="center">
<TYPE.main fontSize="12px">
<ThemedText.Main fontSize="12px">
<Trans>Min Price</Trans>
</TYPE.main>
<TYPE.mediumHeader textAlign="center">{`${formatTickPrice(
</ThemedText.Main>
<ThemedText.MediumHeader textAlign="center">{`${formatTickPrice(
priceLower,
ticksAtLimit,
Bound.LOWER
)}`}</TYPE.mediumHeader>
<TYPE.main textAlign="center" fontSize="12px">
)}`}</ThemedText.MediumHeader>
<ThemedText.Main textAlign="center" fontSize="12px">
<Trans>
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</TYPE.main>
<TYPE.small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
</ThemedText.Main>
<ThemedText.Small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
<Trans>Your position will be 100% composed of {baseCurrency?.symbol} at this price</Trans>
</TYPE.small>
</ThemedText.Small>
</AutoColumn>
</LightCard>
<LightCard width="48%" padding="8px">
<AutoColumn gap="4px" justify="center">
<TYPE.main fontSize="12px">
<ThemedText.Main fontSize="12px">
<Trans>Max Price</Trans>
</TYPE.main>
<TYPE.mediumHeader textAlign="center">{`${formatTickPrice(
</ThemedText.Main>
<ThemedText.MediumHeader textAlign="center">{`${formatTickPrice(
priceUpper,
ticksAtLimit,
Bound.UPPER
)}`}</TYPE.mediumHeader>
<TYPE.main textAlign="center" fontSize="12px">
)}`}</ThemedText.MediumHeader>
<ThemedText.Main textAlign="center" fontSize="12px">
<Trans>
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</TYPE.main>
<TYPE.small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
</ThemedText.Main>
<ThemedText.Small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
<Trans>Your position will be 100% composed of {quoteCurrency?.symbol} at this price</Trans>
</TYPE.small>
</ThemedText.Small>
</AutoColumn>
</LightCard>
</RowBetween>
<LightCard padding="12px ">
<AutoColumn gap="4px" justify="center">
<TYPE.main fontSize="12px">
<ThemedText.Main fontSize="12px">
<Trans>Current price</Trans>
</TYPE.main>
<TYPE.mediumHeader>{`${price.toSignificant(5)} `}</TYPE.mediumHeader>
<TYPE.main textAlign="center" fontSize="12px">
</ThemedText.Main>
<ThemedText.MediumHeader>{`${price.toSignificant(5)} `}</ThemedText.MediumHeader>
<ThemedText.Main textAlign="center" fontSize="12px">
<Trans>
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</TYPE.main>
</ThemedText.Main>
</AutoColumn>
</LightCard>
</AutoColumn>
......
......@@ -5,7 +5,7 @@ import { useEffect, useRef } from 'react'
import { ArrowDown, Info, X } from 'react-feather'
import ReactGA from 'react-ga'
import styled from 'styled-components/macro'
import { ExternalLink, TYPE } from 'theme'
import { ExternalLink, ThemedText } from 'theme'
import { isMobile } from 'utils/userAgent'
import { useModalOpen, useTogglePrivacyPolicy } from '../../state/application/hooks'
......@@ -91,9 +91,9 @@ export function PrivacyPolicyModal() {
<Modal isOpen={open} onDismiss={() => toggle()}>
<AutoColumn gap="12px" ref={node as any}>
<RowBetween padding="1rem 1rem 0.5rem 1rem">
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Legal & Privacy</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<HoverText onClick={() => toggle()}>
<X size={24} />
</HoverText>
......@@ -122,9 +122,9 @@ export function PrivacyPolicy() {
<RowBetween>
<AutoRow gap="4px">
<Info size={20} />
<TYPE.main fontSize={14} color={'primaryText1'}>
<ThemedText.Main fontSize={14} color={'primaryText1'}>
<Trans>Uniswap Labs&apos; Terms of Service</Trans>
</TYPE.main>
</ThemedText.Main>
</AutoRow>
<StyledLinkOut size={20} />
</RowBetween>
......@@ -135,29 +135,29 @@ export function PrivacyPolicy() {
<RowBetween>
<AutoRow gap="4px">
<Info size={20} />
<TYPE.main fontSize={14} color={'primaryText1'}>
<ThemedText.Main fontSize={14} color={'primaryText1'}>
<Trans>Protocol Disclaimer</Trans>
</TYPE.main>
</ThemedText.Main>
</AutoRow>
<StyledLinkOut size={20} />
</RowBetween>
</ExternalLink>
</StyledExternalCard>
</AutoColumn>
<TYPE.main fontSize={14}>
<ThemedText.Main fontSize={14}>
<Trans>This app uses the following third-party APIs:</Trans>
</TYPE.main>
</ThemedText.Main>
<AutoColumn gap="12px">
{EXTERNAL_APIS.map(({ name, description }, i) => (
<DarkGreyCard key={i}>
<AutoColumn gap="8px">
<AutoRow gap="4px">
<Info size={18} />
<TYPE.main fontSize={14} color={'text1'}>
<ThemedText.Main fontSize={14} color={'text1'}>
{name}
</TYPE.main>
</ThemedText.Main>
</AutoRow>
<TYPE.main fontSize={14}>{description}</TYPE.main>
<ThemedText.Main fontSize={14}>{description}</ThemedText.Main>
</AutoColumn>
</DarkGreyCard>
))}
......
......@@ -2,7 +2,7 @@ import { useContext } from 'react'
import styled from 'styled-components/macro'
import { ThemeContext } from 'styled-components/macro'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { AutoColumn } from '../Column'
const Wrapper = styled(AutoColumn)`
......@@ -65,7 +65,7 @@ export default function ProgressCircles({ steps, disabled = false, ...rest }: Pr
<Circle confirmed={step} disabled={disabled || (!steps[i - 1] && i !== 0)}>
{step ? '' : i + 1 + '.'}
</Circle>
<TYPE.main color={theme.text4}>|</TYPE.main>
<ThemedText.Main color={theme.text4}>|</ThemedText.Main>
</CircleRow>
)
})}
......
......@@ -4,7 +4,7 @@ import { AutoRow } from 'components/Row'
import React from 'react'
import ReactGA from 'react-ga'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
const Button = styled(ButtonOutlined).attrs(() => ({
padding: '8px',
......@@ -26,9 +26,9 @@ export default function PresetsButtons({ setFullRange }: { setFullRange: () => v
})
}}
>
<TYPE.body fontSize={12}>
<ThemedText.Body fontSize={12}>
<Trans>Full Range</Trans>
</TYPE.body>
</ThemedText.Body>
</Button>
</AutoRow>
)
......
......@@ -7,7 +7,7 @@ import Row, { AutoRow } from 'components/Row'
import { useTokenInfoFromActiveList } from 'hooks/useTokenInfoFromActiveList'
import { Box } from 'rebass'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { ReactComponent as DotLine } from '../../assets/svg/dot_line.svg'
......@@ -93,9 +93,9 @@ function Route({ percent, path }: { percent: RoutingDiagramEntry['percent']; pat
<DotColor />
</DottedLine>
<OpaqueBadge>
<TYPE.small fontSize={12} style={{ wordBreak: 'normal' }}>
<ThemedText.Small fontSize={12} style={{ wordBreak: 'normal' }}>
{percent.toSignificant(2)}%
</TYPE.small>
</ThemedText.Small>
</OpaqueBadge>
<AutoRow gap="1px" width="100%" style={{ justifyContent: 'space-evenly', zIndex: 2 }}>
......@@ -116,7 +116,7 @@ function Pool({ currency0, currency1, feeAmount }: { currency0: Currency; curren
<Box margin="0 5px 0 10px">
<DoubleCurrencyLogo currency0={tokenInfo1} currency1={tokenInfo0} size={20} />
</Box>
<TYPE.small fontSize={12}>{feeAmount / 10000}%</TYPE.small>
<ThemedText.Small fontSize={12}>{feeAmount / 10000}%</ThemedText.Small>
</PoolBadge>
)
}
......@@ -3,7 +3,7 @@ import { Token } from '@uniswap/sdk-core'
import { ButtonPrimary } from 'components/Button'
import { AlertCircle, ArrowLeft } from 'react-feather'
import styled from 'styled-components/macro'
import { CloseIcon, TYPE } from 'theme'
import { CloseIcon, ThemedText } from 'theme'
import TokenImportCard from './TokenImportCard'
......@@ -22,7 +22,7 @@ const Button = styled(ButtonPrimary)`
const Content = styled.div`
padding: 1em;
`
const Copy = styled(TYPE.body)`
const Copy = styled(ThemedText.Body)`
text-align: center;
margin: 0 2em 1em !important;
font-weight: 400;
......@@ -51,9 +51,9 @@ const BlockedToken = ({ onBack, onDismiss, blockedTokens }: BlockedTokenProps) =
<Wrapper>
<Header>
{onBack ? <ArrowLeft style={{ cursor: 'pointer' }} onClick={onBack} /> : <div />}
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Token not supported</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
{onDismiss ? <CloseIcon onClick={onDismiss} /> : <div />}
</Header>
<Icon />
......
......@@ -14,7 +14,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { useCombinedActiveList } from '../../state/lists/hooks'
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
import { useCurrencyBalance } from '../../state/wallet/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { isTokenOnList } from '../../utils'
import Column from '../Column'
import CurrencyLogo from '../CurrencyLogo'
......@@ -135,13 +135,13 @@ function CurrencyRow({
<Text title={currency.name} fontWeight={500}>
{currency.symbol}
</Text>
<TYPE.darkGray ml="0px" fontSize={'12px'} fontWeight={300}>
<ThemedText.DarkGray ml="0px" fontSize={'12px'} fontWeight={300}>
{!currency.isNative && !isOnSelectedList && customAdded ? (
<Trans>{currency.name} • Added by user</Trans>
) : (
currency.name
)}
</TYPE.darkGray>
</ThemedText.DarkGray>
</Column>
<TokenTags currency={currency} />
{showCurrencyAmount && (
......@@ -167,9 +167,9 @@ function BreakLineComponent({ style }: { style: CSSProperties }) {
<RowBetween>
<RowFixed>
<TokenListLogoWrapper src={TokenListLogo} />
<TYPE.main ml="6px" fontSize="12px" color={theme.text1}>
<ThemedText.Main ml="6px" fontSize="12px" color={theme.text1}>
<Trans>Expanded results from inactive Token Lists</Trans>
</TYPE.main>
</ThemedText.Main>
</RowFixed>
<QuestionHelper
text={
......
......@@ -16,7 +16,7 @@ import styled from 'styled-components/macro'
import { ExtendedEther } from '../../constants/tokens'
import { useAllTokens, useIsUserAddedToken, useSearchInactiveTokenLists, useToken } from '../../hooks/Tokens'
import { useActiveWeb3React } from '../../hooks/web3'
import { ButtonText, CloseIcon, IconWrapper, TYPE } from '../../theme'
import { ButtonText, CloseIcon, IconWrapper, ThemedText } from '../../theme'
import { isAddress } from '../../utils'
import Column from '../Column'
import Row, { RowBetween, RowFixed } from '../Row'
......@@ -224,9 +224,9 @@ export function CurrencySearch({
</div>
) : (
<Column style={{ padding: '20px', height: '100%' }}>
<TYPE.main color={theme.text3} textAlign="center" mb="20px">
<ThemedText.Main color={theme.text3} textAlign="center" mb="20px">
<Trans>No results found.</Trans>
</TYPE.main>
</ThemedText.Main>
</Column>
)}
<Footer>
......@@ -236,9 +236,9 @@ export function CurrencySearch({
<IconWrapper size="16px" marginRight="6px" stroke={theme.primaryText1}>
<Edit />
</IconWrapper>
<TYPE.main color={theme.primaryText1}>
<ThemedText.Main color={theme.primaryText1}>
<Trans>Manage Token Lists</Trans>
</TYPE.main>
</ThemedText.Main>
</RowFixed>
</ButtonText>
</Row>
......
......@@ -16,9 +16,9 @@ import { useAppDispatch } from 'state/hooks'
import { enableList, removeList } from 'state/lists/actions'
import { useAllLists } from 'state/lists/hooks'
import styled from 'styled-components/macro'
import { CloseIcon, TYPE } from 'theme'
import { CloseIcon, ThemedText } from 'theme'
import { ExternalLink } from '../../theme/components'
import { ExternalLink } from '../../theme'
import { CurrencyModalView } from './CurrencySearchModal'
import { Checkbox, PaddedColumn, TextDot } from './styleds'
......@@ -81,9 +81,9 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
<PaddedColumn gap="14px" style={{ width: '100%', flex: '1 1' }}>
<RowBetween>
<ArrowLeft style={{ cursor: 'pointer' }} onClick={() => setModalView(CurrencyModalView.manage)} />
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Import List</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<CloseIcon onClick={onDismiss} />
</RowBetween>
</PaddedColumn>
......@@ -96,18 +96,18 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
{list.logoURI && <ListLogo logoURI={list.logoURI} size="40px" />}
<AutoColumn gap="sm" style={{ marginLeft: '20px' }}>
<RowFixed>
<TYPE.body fontWeight={600} mr="6px">
<ThemedText.Body fontWeight={600} mr="6px">
{list.name}
</TYPE.body>
</ThemedText.Body>
<TextDot />
<TYPE.main fontSize={'16px'} ml="6px">
<ThemedText.Main fontSize={'16px'} ml="6px">
<Trans>{list.tokens.length} tokens</Trans>
</TYPE.main>
</ThemedText.Main>
</RowFixed>
<ExternalLink href={`https://tokenlists.org/token-list?url=${listURL}`}>
<TYPE.main fontSize={'12px'} color={theme.blue1}>
<ThemedText.Main fontSize={'12px'} color={theme.blue1}>
{listURL}
</TYPE.main>
</ThemedText.Main>
</ExternalLink>
</AutoColumn>
</RowFixed>
......@@ -116,22 +116,22 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
<Card style={{ backgroundColor: transparentize(0.8, theme.red1) }}>
<AutoColumn justify="center" style={{ textAlign: 'center', gap: '16px', marginBottom: '12px' }}>
<AlertTriangle stroke={theme.red1} size={32} />
<TYPE.body fontWeight={500} fontSize={20} color={theme.red1}>
<ThemedText.Body fontWeight={500} fontSize={20} color={theme.red1}>
<Trans>Import at your own risk</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
<AutoColumn style={{ textAlign: 'center', gap: '16px', marginBottom: '12px' }}>
<TYPE.body fontWeight={500} color={theme.red1}>
<ThemedText.Body fontWeight={500} color={theme.red1}>
<Trans>
By adding this list you are implicitly trusting that the data is correct. Anyone can create a list,
including creating fake versions of existing lists and lists that claim to represent projects that do
not have one.
</Trans>
</TYPE.body>
<TYPE.body fontWeight={600} color={theme.red1}>
</ThemedText.Body>
<ThemedText.Body fontWeight={600} color={theme.red1}>
<Trans>If you purchase a token from this list, you may not be able to sell it back.</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
<AutoRow justify="center" style={{ cursor: 'pointer' }} onClick={() => setConfirmed(!confirmed)}>
<Checkbox
......@@ -140,9 +140,9 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
checked={confirmed}
onChange={() => setConfirmed(!confirmed)}
/>
<TYPE.body ml="10px" fontSize="16px" color={theme.red1} fontWeight={500}>
<ThemedText.Body ml="10px" fontSize="16px" color={theme.red1} fontWeight={500}>
<Trans>I understand</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoRow>
</Card>
......@@ -156,9 +156,9 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
<Trans>Import</Trans>
</ButtonPrimary>
{addError ? (
<TYPE.error title={addError} style={{ textOverflow: 'ellipsis', overflow: 'hidden' }} error>
<ThemedText.Error title={addError} style={{ textOverflow: 'ellipsis', overflow: 'hidden' }} error>
{addError}
</TYPE.error>
</ThemedText.Error>
) : null}
</AutoColumn>
{/* </Card> */}
......
......@@ -10,7 +10,7 @@ import useTheme from 'hooks/useTheme'
import { CSSProperties } from 'react'
import { CheckCircle } from 'react-feather'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
......@@ -67,16 +67,16 @@ export default function ImportRow({
<CurrencyLogo currency={token} size={'24px'} style={{ opacity: dim ? '0.6' : '1' }} />
<AutoColumn gap="4px" style={{ opacity: dim ? '0.6' : '1' }}>
<AutoRow>
<TYPE.body fontWeight={500}>{token.symbol}</TYPE.body>
<TYPE.darkGray ml="8px" fontWeight={300}>
<ThemedText.Body fontWeight={500}>{token.symbol}</ThemedText.Body>
<ThemedText.DarkGray ml="8px" fontWeight={300}>
<NameOverflow title={token.name}>{token.name}</NameOverflow>
</TYPE.darkGray>
</ThemedText.DarkGray>
</AutoRow>
{list && list.logoURI && (
<RowFixed>
<TYPE.small mr="4px" color={theme.text3}>
<ThemedText.Small mr="4px" color={theme.text3}>
<Trans>via {list.name} </Trans>
</TYPE.small>
</ThemedText.Small>
<ListLogo logoURI={list.logoURI} size="12px" />
</RowFixed>
)}
......@@ -97,9 +97,9 @@ export default function ImportRow({
) : (
<RowFixed style={{ minWidth: 'fit-content' }}>
<CheckIcon />
<TYPE.main color={theme.green1}>
<ThemedText.Main color={theme.green1}>
<Trans>Active</Trans>
</TYPE.main>
</ThemedText.Main>
</RowFixed>
)}
</TokenSection>
......
......@@ -10,7 +10,7 @@ import useTheme from 'hooks/useTheme'
import { AlertCircle, ArrowLeft } from 'react-feather'
import { useAddUserToken } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { CloseIcon, TYPE } from 'theme'
import { CloseIcon, ThemedText } from 'theme'
import BlockedToken from './BlockedToken'
import { PaddedColumn } from './styleds'
......@@ -47,9 +47,9 @@ export function ImportToken(props: ImportProps) {
<PaddedColumn gap="14px" style={{ width: '100%', flex: '1 1' }}>
<RowBetween>
{onBack ? <ArrowLeft style={{ cursor: 'pointer' }} onClick={onBack} /> : <div />}
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Plural value={tokens.length} one="Import token" other="Import tokens" />
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
{onDismiss ? <CloseIcon onClick={onDismiss} /> : <div />}
</RowBetween>
</PaddedColumn>
......@@ -57,12 +57,12 @@ export function ImportToken(props: ImportProps) {
<AutoColumn gap="md" style={{ marginBottom: '32px', padding: '1rem' }}>
<AutoColumn justify="center" style={{ textAlign: 'center', gap: '16px', padding: '1rem' }}>
<AlertCircle size={48} stroke={theme.text2} strokeWidth={1} />
<TYPE.body fontWeight={400} fontSize={16}>
<ThemedText.Body fontWeight={400} fontSize={16}>
<Trans>
This token doesn&apos;t appear on the active token list(s). Make sure this is the token that you want to
trade.
</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
{tokens.map((token) => (
<TokenImportCard token={token} list={list} key={'import' + token.address} />
......
......@@ -18,7 +18,7 @@ import useTheme from '../../hooks/useTheme'
import useToggle from '../../hooks/useToggle'
import { acceptListUpdate, disableList, enableList, removeList } from '../../state/lists/actions'
import { useActiveListUrls, useAllLists, useIsListActive } from '../../state/lists/hooks'
import { ExternalLink, IconWrapper, LinkStyledButton, TYPE } from '../../theme'
import { ExternalLink, IconWrapper, LinkStyledButton, ThemedText } from '../../theme'
import listVersionLabel from '../../utils/listVersionLabel'
import { parseENSAddress } from '../../utils/parseENSAddress'
import uriToHttp from '../../utils/uriToHttp'
......@@ -75,7 +75,7 @@ const StyledTitleText = styled.div<{ active: boolean }>`
color: ${({ theme, active }) => (active ? theme.white : theme.text2)};
`
const StyledListUrlText = styled(TYPE.main)<{ active: boolean }>`
const StyledListUrlText = styled(ThemedText.Main)<{ active: boolean }>`
font-size: 12px;
color: ${({ theme, active }) => (active ? theme.white : theme.text2)};
`
......@@ -361,9 +361,9 @@ export function ManageLists({
/>
</Row>
{addError ? (
<TYPE.error title={addError} style={{ textOverflow: 'ellipsis', overflow: 'hidden' }} error>
<ThemedText.Error title={addError} style={{ textOverflow: 'ellipsis', overflow: 'hidden' }} error>
{addError}
</TYPE.error>
</ThemedText.Error>
) : null}
</PaddedColumn>
{tempList && (
......@@ -373,10 +373,10 @@ export function ManageLists({
<RowFixed>
{tempList.logoURI && <ListLogo logoURI={tempList.logoURI} size="40px" />}
<AutoColumn gap="4px" style={{ marginLeft: '20px' }}>
<TYPE.body fontWeight={600}>{tempList.name}</TYPE.body>
<TYPE.main fontSize={'12px'}>
<ThemedText.Body fontWeight={600}>{tempList.name}</ThemedText.Body>
<ThemedText.Main fontSize={'12px'}>
<Trans>{tempList.tokens.length} tokens</Trans>
</TYPE.main>
</ThemedText.Main>
</AutoColumn>
</RowFixed>
{isImported ? (
......@@ -384,9 +384,9 @@ export function ManageLists({
<IconWrapper stroke={theme.text2} size="16px" marginRight={'10px'}>
<CheckCircle />
</IconWrapper>
<TYPE.body color={theme.text2}>
<ThemedText.Body color={theme.text2}>
<Trans>Loaded</Trans>
</TYPE.body>
</ThemedText.Body>
</RowFixed>
) : (
<ButtonPrimary
......
......@@ -9,7 +9,7 @@ import { useActiveWeb3React } from 'hooks/web3'
import { RefObject, useCallback, useMemo, useRef, useState } from 'react'
import { useRemoveUserAddedToken, useUserAddedTokens } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { ButtonText, ExternalLink, ExternalLinkIcon, TrashIcon, TYPE } from 'theme'
import { ButtonText, ExternalLink, ExternalLinkIcon, ThemedText, TrashIcon } from 'theme'
import { isAddress } from 'utils'
import useTheme from '../../hooks/useTheme'
......@@ -81,9 +81,9 @@ export default function ManageTokens({
<RowFixed>
<CurrencyLogo currency={token} size={'20px'} />
<ExternalLink href={getExplorerLink(chainId, token.address, ExplorerDataType.ADDRESS)}>
<TYPE.main ml={'10px'} fontWeight={600}>
<ThemedText.Main ml={'10px'} fontWeight={600}>
{token.symbol}
</TYPE.main>
</ThemedText.Main>
</ExternalLink>
</RowFixed>
<RowFixed>
......@@ -111,9 +111,9 @@ export default function ManageTokens({
/>
</Row>
{searchQuery !== '' && !isAddressSearch && (
<TYPE.error error={true}>
<ThemedText.Error error={true}>
<Trans>Enter valid token address</Trans>
</TYPE.error>
</ThemedText.Error>
)}
{searchToken && (
<Card backgroundColor={theme.bg2} padding="10px 0">
......@@ -129,14 +129,14 @@ export default function ManageTokens({
<Separator />
<PaddedColumn gap="lg" style={{ overflow: 'auto', marginBottom: '10px' }}>
<RowBetween>
<TYPE.main fontWeight={600}>
<ThemedText.Main fontWeight={600}>
<Trans>{userAddedTokens?.length} Custom Tokens</Trans>
</TYPE.main>
</ThemedText.Main>
{userAddedTokens.length > 0 && (
<ButtonText onClick={handleRemoveAll}>
<TYPE.blue>
<ThemedText.Blue>
<Trans>Clear all</Trans>
</TYPE.blue>
</ThemedText.Blue>
</ButtonText>
)}
</RowBetween>
......@@ -144,9 +144,9 @@ export default function ManageTokens({
</PaddedColumn>
</Column>
<Footer>
<TYPE.darkGray>
<ThemedText.DarkGray>
<Trans>Tip: Custom tokens are stored locally in your browser</Trans>
</TYPE.darkGray>
</ThemedText.DarkGray>
</Footer>
</Wrapper>
)
......
......@@ -10,7 +10,7 @@ import { useActiveWeb3React } from 'hooks/web3'
import { transparentize } from 'polished'
import { AlertCircle } from 'react-feather'
import styled, { useTheme } from 'styled-components/macro'
import { ExternalLink, TYPE } from 'theme'
import { ExternalLink, ThemedText } from 'theme'
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
const WarningWrapper = styled(Card)<{ highWarning: boolean }>`
......@@ -19,7 +19,7 @@ const WarningWrapper = styled(Card)<{ highWarning: boolean }>`
width: fit-content;
`
const AddressText = styled(TYPE.blue)`
const AddressText = styled(ThemedText.Blue)`
font-size: 12px;
word-break: break-all;
......@@ -39,12 +39,12 @@ const TokenImportCard = ({ list, token }: TokenImportCardProps) => {
<AutoColumn gap="10px" justify="center">
<CurrencyLogo currency={token} size={'32px'} />
<AutoColumn gap="4px" justify="center">
<TYPE.body ml="8px" mr="8px" fontWeight={500} fontSize={20}>
<ThemedText.Body ml="8px" mr="8px" fontWeight={500} fontSize={20}>
{token.symbol}
</TYPE.body>
<TYPE.darkGray fontWeight={400} fontSize={14}>
</ThemedText.Body>
<ThemedText.DarkGray fontWeight={400} fontSize={14}>
{token.name}
</TYPE.darkGray>
</ThemedText.DarkGray>
</AutoColumn>
{chainId && (
<ExternalLink href={getExplorerLink(chainId, token.address, ExplorerDataType.ADDRESS)}>
......@@ -54,17 +54,17 @@ const TokenImportCard = ({ list, token }: TokenImportCardProps) => {
{list !== undefined ? (
<RowFixed>
{list.logoURI && <ListLogo logoURI={list.logoURI} size="16px" />}
<TYPE.small ml="6px" fontSize={14} color={theme.text3}>
<ThemedText.Small ml="6px" fontSize={14} color={theme.text3}>
<Trans>via {list.name} token list</Trans>
</TYPE.small>
</ThemedText.Small>
</RowFixed>
) : (
<WarningWrapper $borderRadius="4px" padding="4px" highWarning={true}>
<RowFixed>
<AlertCircle stroke={theme.red1} size="10px" />
<TYPE.body color={theme.red1} ml="4px" fontSize="10px" fontWeight={500}>
<ThemedText.Body color={theme.red1} ml="4px" fontSize="10px" fontWeight={500}>
<Trans>Unknown Source</Trans>
</TYPE.body>
</ThemedText.Body>
</RowFixed>
</WarningWrapper>
)}
......
......@@ -13,7 +13,7 @@ import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { useModalOpen, useToggleSettingsMenu } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { useClientSideRouter, useExpertModeManager } from '../../state/user/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { ButtonError } from '../Button'
import { AutoColumn } from '../Column'
import Modal from '../Modal'
......@@ -203,9 +203,9 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
{chainId === SupportedChainId.MAINNET && (
<RowBetween>
<RowFixed>
<TYPE.black fontWeight={400} fontSize={14} color={theme.text2}>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.text2}>
<Trans>Auto Router</Trans>
</TYPE.black>
</ThemedText.Black>
<QuestionHelper
text={<Trans>Use the Uniswap Labs API to get better pricing through a more efficient route.</Trans>}
/>
......@@ -226,9 +226,9 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
<RowBetween>
<RowFixed>
<TYPE.black fontWeight={400} fontSize={14} color={theme.text2}>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.text2}>
<Trans>Expert Mode</Trans>
</TYPE.black>
</ThemedText.Black>
<QuestionHelper
text={
<Trans>Allow high price impact trades and skip the confirm screen. Use at your own risk.</Trans>
......
......@@ -5,9 +5,9 @@ import styled from 'styled-components/macro'
import { DEFAULT_LOCALE, LOCALE_LABEL, SupportedLocale } from '../../constants/locales'
import { navigatorLocale, useActiveLocale } from '../../hooks/useActiveLocale'
import { StyledInternalLink, TYPE } from '../../theme'
import { StyledInternalLink, ThemedText } from '../../theme'
const Container = styled(TYPE.small)`
const Container = styled(ThemedText.Small)`
opacity: 0.6;
:hover {
opacity: 1;
......
import { Trans } from '@lingui/macro'
import styled from 'styled-components/macro'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
const Wrapper = styled.button<{ isActive?: boolean; activeElement?: boolean }>`
border-radius: 20px;
......@@ -25,7 +25,7 @@ const ToggleElement = styled.span<{ isActive?: boolean; bgColor?: string }>`
}
`
const StatusText = styled(TYPE.main)<{ isActive?: boolean }>`
const StatusText = styled(ThemedText.Main)<{ isActive?: boolean }>`
margin: 0 10px;
width: 24px;
color: ${({ theme, isActive }) => (isActive ? theme.text1 : theme.text3)};
......
......@@ -13,7 +13,7 @@ import Circle from '../../assets/images/blue-loader.svg'
import MetaMaskLogo from '../../assets/images/metamask.png'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink } from '../../theme'
import { CloseIcon, CustomLightSpinner } from '../../theme/components'
import { CloseIcon, CustomLightSpinner } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { TransactionSummary } from '../AccountDetails/TransactionSummary'
import { ButtonLight, ButtonPrimary } from '../Button'
......@@ -284,11 +284,11 @@ function L2Content({
</Text>
</ExternalLink>
) : (
<div style={{ height: '17px' }}></div>
<div style={{ height: '17px' }} />
)}
<Text color={theme.text3} style={{ margin: '20px 0 0 0' }} fontSize={'14px'}>
{!secondsToConfirm ? (
<div style={{ height: '24px' }}></div>
<div style={{ height: '24px' }} />
) : (
<div>
<Trans>Transaction completed in </Trans>
......
......@@ -8,7 +8,7 @@ import { useContext, useState } from 'react'
import { useSetUserSlippageTolerance, useUserSlippageTolerance, useUserTransactionTTL } from 'state/user/hooks'
import styled, { ThemeContext } from 'styled-components/macro'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { AutoColumn } from '../Column'
import QuestionHelper from '../QuestionHelper'
import { RowBetween, RowFixed } from '../Row'
......@@ -160,9 +160,9 @@ export default function TransactionSettings({ placeholderSlippage }: Transaction
<AutoColumn gap="md">
<AutoColumn gap="sm">
<RowFixed>
<TYPE.black fontWeight={400} fontSize={14} color={theme.text2}>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.text2}>
<Trans>Slippage tolerance</Trans>
</TYPE.black>
</ThemedText.Black>
<QuestionHelper
text={
<Trans>Your transaction will revert if the price changes unfavorably by more than this percentage.</Trans>
......@@ -229,9 +229,9 @@ export default function TransactionSettings({ placeholderSlippage }: Transaction
{showCustomDeadlineRow && (
<AutoColumn gap="sm">
<RowFixed>
<TYPE.black fontSize={14} fontWeight={400} color={theme.text2}>
<ThemedText.Black fontSize={14} fontWeight={400} color={theme.text2}>
<Trans>Transaction deadline</Trans>
</TYPE.black>
</ThemedText.Black>
<QuestionHelper
text={<Trans>Your transaction will revert if it is pending for more than this period of time.</Trans>}
/>
......@@ -255,9 +255,9 @@ export default function TransactionSettings({ placeholderSlippage }: Transaction
color={deadlineError ? 'red' : ''}
/>
</OptionCustom>
<TYPE.body style={{ paddingLeft: '8px' }} fontSize={14}>
<ThemedText.Body style={{ paddingLeft: '8px' }} fontSize={14}>
<Trans>minutes</Trans>
</TYPE.body>
</ThemedText.Body>
</RowFixed>
</AutoColumn>
)}
......
......@@ -19,7 +19,7 @@ import { SUPPORTED_WALLETS } from '../../constants/wallet'
import usePrevious from '../../hooks/usePrevious'
import { useModalOpen, useWalletModalToggle } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, ThemedText } from '../../theme'
import { isMobile } from '../../utils/userAgent'
import AccountDetails from '../AccountDetails'
import Card, { LightCard } from '../Card'
......@@ -344,9 +344,9 @@ export default function WalletModal({
<ArrowLeft />
</HoverText>
<Row justify="center">
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Legal & Privacy</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
</Row>
</HeaderRow>
<PrivacyPolicy />
......@@ -392,23 +392,23 @@ export default function WalletModal({
<AutoColumn gap="16px">
<LightCard>
<AutoRow style={{ flexWrap: 'nowrap' }}>
<TYPE.black fontSize={14}>
<ThemedText.Black fontSize={14}>
<Trans>
By connecting a wallet, you agree to Uniswap Labs’{' '}
<ExternalLink href="https://uniswap.org/terms-of-service/">Terms of Service</ExternalLink> and
acknowledge that you have read and understand the Uniswap{' '}
<ExternalLink href="https://uniswap.org/disclaimer/">Protocol Disclaimer</ExternalLink>.
</Trans>
</TYPE.black>
</ThemedText.Black>
</AutoRow>
</LightCard>
<LinkCard padding=".5rem" $borderRadius=".75rem" onClick={() => setWalletView(WALLET_VIEWS.LEGAL)}>
<RowBetween>
<AutoRow gap="4px">
<Info size={20} />
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>How this app uses APIs</Trans>
</TYPE.white>
</ThemedText.White>
</AutoRow>
<ArrowRight size={16} />
</RowBetween>
......
......@@ -11,7 +11,7 @@ import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks/web3'
import { useClaimCallback, useUserHasAvailableClaim, useUserUnclaimedAmount } from '../../state/claim/hooks'
import { useIsTransactionPending } from '../../state/transactions/hooks'
import { CloseIcon, CustomLightSpinner, ExternalLink, TYPE, UniTokenAnimated } from '../../theme'
import { CloseIcon, CustomLightSpinner, ExternalLink, ThemedText, UniTokenAnimated } from '../../theme'
import { shortenAddress } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import AddressInputPanel from '../AddressInputPanel'
......@@ -105,29 +105,29 @@ export default function AddressClaimModal({ isOpen, onDismiss }: { isOpen: boole
<CardNoise />
<CardSection gap="md">
<RowBetween>
<TYPE.white fontWeight={500}>
<ThemedText.White fontWeight={500}>
<Trans>Claim UNI Token</Trans>
</TYPE.white>
</ThemedText.White>
<CloseIcon onClick={wrappedOnDismiss} style={{ zIndex: 99 }} stroke="white" />
</RowBetween>
<TYPE.white fontWeight={700} fontSize={36}>
<ThemedText.White fontWeight={700} fontSize={36}>
<Trans>{unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} UNI</Trans>
</TYPE.white>
</ThemedText.White>
</CardSection>
<Break />
</ModalUpper>
<AutoColumn gap="md" style={{ padding: '1rem', paddingTop: '0' }} justify="center">
<TYPE.subHeader fontWeight={500}>
<ThemedText.SubHeader fontWeight={500}>
<Trans>
Enter an address to trigger a UNI claim. If the address has any claimable UNI it will be sent to them on
submission.
</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
<AddressInputPanel value={typed} onChange={handleRecipientType} />
{parsedAddress && !hasAvailableClaim && (
<TYPE.error error={true}>
<ThemedText.Error error={true}>
<Trans>Address has no available claim</Trans>
</TYPE.error>
</ThemedText.Error>
)}
<ButtonPrimary
disabled={!isAddress(parsedAddress ?? '') || !hasAvailableClaim}
......@@ -159,23 +159,23 @@ export default function AddressClaimModal({ isOpen, onDismiss }: { isOpen: boole
</ConfirmedIcon>
<AutoColumn gap="100px" justify={'center'}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader fontWeight={600} color="black">
<ThemedText.LargeHeader fontWeight={600} color="black">
{claimConfirmed ? <Trans>Claimed</Trans> : <Trans>Claiming</Trans>}
</TYPE.largeHeader>
</ThemedText.LargeHeader>
{!claimConfirmed && (
<Text fontSize={36} color={'#ff007a'} fontWeight={800}>
<Trans>{unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} UNI</Trans>
</Text>
)}
{parsedAddress && (
<TYPE.largeHeader fontWeight={600} color="black">
<ThemedText.LargeHeader fontWeight={600} color="black">
<Trans>for {shortenAddress(parsedAddress)}</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
)}
</AutoColumn>
{claimConfirmed && (
<>
<TYPE.subHeader fontWeight={500} color="black">
<ThemedText.SubHeader fontWeight={500} color="black">
<span role="img" aria-label="party-hat">
🎉{' '}
</span>
......@@ -183,13 +183,13 @@ export default function AddressClaimModal({ isOpen, onDismiss }: { isOpen: boole
<span role="img" aria-label="party-hat">
🎉
</span>
</TYPE.subHeader>
</ThemedText.SubHeader>
</>
)}
{attempting && !hash && (
<TYPE.subHeader color="black">
<ThemedText.SubHeader color="black">
<Trans>Confirm this transaction in your wallet</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
)}
{attempting && hash && !claimConfirmed && chainId && hash && (
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)} style={{ zIndex: 99 }}>
......
......@@ -13,7 +13,7 @@ import { useModalOpen, useToggleSelfClaimModal } from '../../state/application/h
import { ApplicationModal } from '../../state/application/reducer'
import { useClaimCallback, useUserClaimData, useUserUnclaimedAmount } from '../../state/claim/hooks'
import { useUserHasSubmittedClaim } from '../../state/transactions/hooks'
import { CloseIcon, CustomLightSpinner, ExternalLink, TYPE, UniTokenAnimated } from '../../theme'
import { CloseIcon, CustomLightSpinner, ExternalLink, ThemedText, UniTokenAnimated } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { ButtonPrimary } from '../Button'
import { AutoColumn, ColumnCenter } from '../Column'
......@@ -100,63 +100,63 @@ export default function ClaimModal() {
<CardNoise />
<CardSection gap="md">
<RowBetween>
<TYPE.white fontWeight={500}>
<ThemedText.White fontWeight={500}>
<Trans>Claim UNI</Trans>
</TYPE.white>
</ThemedText.White>
<CloseIcon onClick={toggleClaimModal} style={{ zIndex: 99 }} color="white" />
</RowBetween>
<TYPE.white fontWeight={700} fontSize={36}>
<ThemedText.White fontWeight={700} fontSize={36}>
<Trans>{unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} UNI</Trans>
</TYPE.white>
</ThemedText.White>
</CardSection>
<Break />
<CardSection gap="sm">
{userClaimData?.flags?.isSOCKS && (
<RowBetween>
<TYPE.subHeader color="white">SOCKS</TYPE.subHeader>
<TYPE.subHeader color="white">
<ThemedText.SubHeader color="white">SOCKS</ThemedText.SubHeader>
<ThemedText.SubHeader color="white">
<Trans>{SOCKS_AMOUNT} UNI</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowBetween>
)}
{userClaimData?.flags?.isLP &&
unclaimedAmount &&
JSBI.greaterThanOrEqual(unclaimedAmount.quotient, nonLPAmount) && (
<RowBetween>
<TYPE.subHeader color="white">
<ThemedText.SubHeader color="white">
<Trans>Liquidity</Trans>
</TYPE.subHeader>
<TYPE.subHeader color="white">
</ThemedText.SubHeader>
<ThemedText.SubHeader color="white">
<Trans>
{unclaimedAmount
.subtract(CurrencyAmount.fromRawAmount(unclaimedAmount.currency, nonLPAmount))
.toFixed(0, { groupSeparator: ',' })}{' '}
UNI
</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowBetween>
)}
{userClaimData?.flags?.isUser && (
<RowBetween>
<TYPE.subHeader color="white">
<ThemedText.SubHeader color="white">
<Trans>User</Trans>
</TYPE.subHeader>
<TYPE.subHeader color="white">
</ThemedText.SubHeader>
<ThemedText.SubHeader color="white">
<Trans>{USER_AMOUNT} UNI</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowBetween>
)}
</CardSection>
</ModalUpper>
<AutoColumn gap="md" style={{ padding: '1rem', paddingTop: '0' }} justify="center">
<TYPE.subHeader fontWeight={500}>
<ThemedText.SubHeader fontWeight={500}>
<Trans>
As a member of the Uniswap community you may claim UNI to be used for voting and governance.
<br />
<br />
<ExternalLink href="https://uniswap.org/blog/uni">Read more about UNI</ExternalLink>
</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
<ButtonPrimary
disabled={!isAddress(account ?? '')}
padding="16px 16px"
......@@ -187,9 +187,9 @@ export default function ClaimModal() {
</ConfirmedIcon>
<AutoColumn gap="100px" justify={'center'}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader fontWeight={600} color="black">
<ThemedText.LargeHeader fontWeight={600} color="black">
{claimConfirmed ? <Trans>Claimed!</Trans> : <Trans>Claiming</Trans>}
</TYPE.largeHeader>
</ThemedText.LargeHeader>
{!claimConfirmed && (
<Text fontSize={36} color={'#ff007a'} fontWeight={800}>
<Trans>{unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} UNI</Trans>
......@@ -198,7 +198,7 @@ export default function ClaimModal() {
</AutoColumn>
{claimConfirmed && (
<>
<TYPE.subHeader fontWeight={500} color="black">
<ThemedText.SubHeader fontWeight={500} color="black">
<Trans>
<span role="img" aria-label="party-hat">
🎉{' '}
......@@ -208,13 +208,13 @@ export default function ClaimModal() {
🎉
</span>
</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</>
)}
{attempting && !claimSubmitted && (
<TYPE.subHeader color="black">
<ThemedText.SubHeader color="black">
<Trans>Confirm this transaction in your wallet</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
)}
{attempting && claimSubmitted && !claimConfirmed && chainId && claimTxn?.hash && (
<ExternalLink
......
......@@ -8,7 +8,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { StakingInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { CloseIcon, TYPE } from '../../theme'
import { CloseIcon, ThemedText } from '../../theme'
import { ButtonError } from '../Button'
import { AutoColumn } from '../Column'
import Modal from '../Modal'
......@@ -74,24 +74,24 @@ export default function ClaimRewardModal({ isOpen, onDismiss, stakingInfo }: Sta
{!attempting && !hash && (
<ContentWrapper gap="lg">
<RowBetween>
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Claim</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<CloseIcon onClick={wrappedOnDismiss} />
</RowBetween>
{stakingInfo?.earnedAmount && (
<AutoColumn justify="center" gap="md">
<TYPE.body fontWeight={600} fontSize={36}>
<ThemedText.Body fontWeight={600} fontSize={36}>
{stakingInfo?.earnedAmount?.toSignificant(6)}
</TYPE.body>
<TYPE.body>
</ThemedText.Body>
<ThemedText.Body>
<Trans>Unclaimed UNI</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
)}
<TYPE.subHeader style={{ textAlign: 'center' }}>
<ThemedText.SubHeader style={{ textAlign: 'center' }}>
<Trans>When you claim without withdrawing your liquidity remains in the mining pool.</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
<ButtonError disabled={!!error} error={!!error && !!stakingInfo?.stakedAmount} onClick={onClaimReward}>
{error ?? <Trans>Claim</Trans>}
</ButtonError>
......@@ -100,21 +100,21 @@ export default function ClaimRewardModal({ isOpen, onDismiss, stakingInfo }: Sta
{attempting && !hash && (
<LoadingView onDismiss={wrappedOnDismiss}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.body fontSize={20}>
<ThemedText.Body fontSize={20}>
<Trans>Claiming {stakingInfo?.earnedAmount?.toSignificant(6)} UNI</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</LoadingView>
)}
{hash && (
<SubmittedView onDismiss={wrappedOnDismiss} hash={hash}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Transaction Submitted</Trans>
</TYPE.largeHeader>
<TYPE.body fontSize={20}>
</ThemedText.LargeHeader>
<ThemedText.Body fontSize={20}>
<Trans>Claimed UNI!</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</SubmittedView>
)}
......
......@@ -9,7 +9,7 @@ import { useTotalSupply } from '../../hooks/useTotalSupply'
import useUSDCPrice from '../../hooks/useUSDCPrice'
import { useV2Pair } from '../../hooks/useV2Pairs'
import { StakingInfo } from '../../state/stake/hooks'
import { StyledInternalLink, TYPE } from '../../theme'
import { StyledInternalLink, ThemedText } from '../../theme'
import { currencyId } from '../../utils/currencyId'
import { unwrappedToken } from '../../utils/unwrappedToken'
import { ButtonPrimary } from '../Button'
......@@ -115,9 +115,9 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
<TopSection>
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} size={24} />
<TYPE.white fontWeight={600} fontSize={24} style={{ marginLeft: '8px' }}>
<ThemedText.White fontWeight={600} fontSize={24} style={{ marginLeft: '8px' }}>
{currency0.symbol}-{currency1.symbol}
</TYPE.white>
</ThemedText.White>
<StyledInternalLink to={`/uni/${currencyId(currency0)}/${currencyId(currency1)}`} style={{ width: '100%' }}>
<ButtonPrimary padding="8px" $borderRadius="8px">
......@@ -128,22 +128,22 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
<StatContainer>
<RowBetween>
<TYPE.white>
<ThemedText.White>
<Trans>Total deposited</Trans>
</TYPE.white>
<TYPE.white>
</ThemedText.White>
<ThemedText.White>
{valueOfTotalStakedAmountInUSDC ? (
<Trans>${valueOfTotalStakedAmountInUSDC.toFixed(0, { groupSeparator: ',' })}</Trans>
) : (
<Trans>{valueOfTotalStakedAmountInWETH?.toSignificant(4, { groupSeparator: ',' }) ?? '-'} ETH</Trans>
)}
</TYPE.white>
</ThemedText.White>
</RowBetween>
<RowBetween>
<TYPE.white>
<ThemedText.White>
<Trans>Pool rate</Trans>
</TYPE.white>
<TYPE.white>
</ThemedText.White>
<ThemedText.White>
{stakingInfo ? (
stakingInfo.active ? (
<Trans>
......@@ -156,7 +156,7 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
) : (
'-'
)}
</TYPE.white>
</ThemedText.White>
</RowBetween>
</StatContainer>
......@@ -164,13 +164,13 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
<>
<Break />
<BottomSection showBackground={true}>
<TYPE.black color={'white'} fontWeight={500}>
<ThemedText.Black color={'white'} fontWeight={500}>
<span>
<Trans>Your rate</Trans>
</span>
</TYPE.black>
</ThemedText.Black>
<TYPE.black style={{ textAlign: 'right' }} color={'white'} fontWeight={500}>
<ThemedText.Black style={{ textAlign: 'right' }} color={'white'} fontWeight={500}>
<span role="img" aria-label="wizard-icon" style={{ marginRight: '0.5rem' }}>
</span>
......@@ -188,7 +188,7 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
) : (
'-'
)}
</TYPE.black>
</ThemedText.Black>
</BottomSection>
</>
)}
......
......@@ -13,7 +13,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { StakingInfo, useDerivedStakeInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { CloseIcon, TYPE } from '../../theme'
import { CloseIcon, ThemedText } from '../../theme'
import { formatCurrencyAmount } from '../../utils/formatCurrencyAmount'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { ButtonConfirmed, ButtonError } from '../Button'
......@@ -159,9 +159,9 @@ export default function StakingModal({ isOpen, onDismiss, stakingInfo, userLiqui
{!attempting && !hash && (
<ContentWrapper gap="lg">
<RowBetween>
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Deposit</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<CloseIcon onClick={wrappedOnDismiss} />
</RowBetween>
<CurrencyInputPanel
......@@ -178,19 +178,19 @@ export default function StakingModal({ isOpen, onDismiss, stakingInfo, userLiqui
<HypotheticalRewardRate dim={!hypotheticalRewardRate.greaterThan('0')}>
<div>
<TYPE.black fontWeight={600}>
<ThemedText.Black fontWeight={600}>
<Trans>Weekly Rewards</Trans>
</TYPE.black>
</ThemedText.Black>
</div>
<TYPE.black>
<ThemedText.Black>
<Trans>
{hypotheticalRewardRate
.multiply((60 * 60 * 24 * 7).toString())
.toSignificant(4, { groupSeparator: ',' })}{' '}
UNI / week
</Trans>
</TYPE.black>
</ThemedText.Black>
</HypotheticalRewardRate>
<RowBetween>
......@@ -216,24 +216,24 @@ export default function StakingModal({ isOpen, onDismiss, stakingInfo, userLiqui
{attempting && !hash && (
<LoadingView onDismiss={wrappedOnDismiss}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Depositing Liquidity</Trans>
</TYPE.largeHeader>
<TYPE.body fontSize={20}>
</ThemedText.LargeHeader>
<ThemedText.Body fontSize={20}>
<Trans>{parsedAmount?.toSignificant(4)} UNI-V2</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</LoadingView>
)}
{attempting && hash && (
<SubmittedView onDismiss={wrappedOnDismiss} hash={hash}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Transaction Submitted</Trans>
</TYPE.largeHeader>
<TYPE.body fontSize={20}>
</ThemedText.LargeHeader>
<ThemedText.Body fontSize={20}>
<Trans>Deposited {parsedAmount?.toSignificant(4)} UNI-V2</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</SubmittedView>
)}
......
......@@ -8,7 +8,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { StakingInfo } from '../../state/stake/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { CloseIcon, TYPE } from '../../theme'
import { CloseIcon, ThemedText } from '../../theme'
import { ButtonError } from '../Button'
import { AutoColumn } from '../Column'
import FormattedCurrencyAmount from '../FormattedCurrencyAmount'
......@@ -76,34 +76,34 @@ export default function UnstakingModal({ isOpen, onDismiss, stakingInfo }: Staki
{!attempting && !hash && (
<ContentWrapper gap="lg">
<RowBetween>
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Withdraw</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<CloseIcon onClick={wrappedOndismiss} />
</RowBetween>
{stakingInfo?.stakedAmount && (
<AutoColumn justify="center" gap="md">
<TYPE.body fontWeight={600} fontSize={36}>
<ThemedText.Body fontWeight={600} fontSize={36}>
{<FormattedCurrencyAmount currencyAmount={stakingInfo.stakedAmount} />}
</TYPE.body>
<TYPE.body>
</ThemedText.Body>
<ThemedText.Body>
<Trans>Deposited liquidity:</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
)}
{stakingInfo?.earnedAmount && (
<AutoColumn justify="center" gap="md">
<TYPE.body fontWeight={600} fontSize={36}>
<ThemedText.Body fontWeight={600} fontSize={36}>
{<FormattedCurrencyAmount currencyAmount={stakingInfo?.earnedAmount} />}
</TYPE.body>
<TYPE.body>
</ThemedText.Body>
<ThemedText.Body>
<Trans>Unclaimed UNI</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
)}
<TYPE.subHeader style={{ textAlign: 'center' }}>
<ThemedText.SubHeader style={{ textAlign: 'center' }}>
<Trans>When you withdraw, your UNI is claimed and your liquidity is removed from the mining pool.</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
<ButtonError disabled={!!error} error={!!error && !!stakingInfo?.stakedAmount} onClick={onWithdraw}>
{error ?? <Trans>Withdraw & Claim</Trans>}
</ButtonError>
......@@ -112,27 +112,27 @@ export default function UnstakingModal({ isOpen, onDismiss, stakingInfo }: Staki
{attempting && !hash && (
<LoadingView onDismiss={wrappedOndismiss}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.body fontSize={20}>
<ThemedText.Body fontSize={20}>
<Trans>Withdrawing {stakingInfo?.stakedAmount?.toSignificant(4)} UNI-V2</Trans>
</TYPE.body>
<TYPE.body fontSize={20}>
</ThemedText.Body>
<ThemedText.Body fontSize={20}>
<Trans>Claiming {stakingInfo?.earnedAmount?.toSignificant(4)} UNI</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</LoadingView>
)}
{hash && (
<SubmittedView onDismiss={wrappedOndismiss} hash={hash}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Transaction Submitted</Trans>
</TYPE.largeHeader>
<TYPE.body fontSize={20}>
</ThemedText.LargeHeader>
<ThemedText.Body fontSize={20}>
<Trans>Withdrew UNI-V2!</Trans>
</TYPE.body>
<TYPE.body fontSize={20}>
</ThemedText.Body>
<ThemedText.Body fontSize={20}>
<Trans>Claimed UNI!</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</SubmittedView>
)}
......
......@@ -6,7 +6,7 @@ import { LoadingRows } from 'components/Loader/styled'
import { useContext, useMemo } from 'react'
import { ThemeContext } from 'styled-components/macro'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { computeRealizedLPFeePercent } from '../../utils/prices'
import { AutoColumn } from '../Column'
import { RowBetween, RowFixed } from '../Row'
......@@ -56,55 +56,55 @@ export function AdvancedSwapDetails({ trade, allowedSlippage, syncing = false }:
</TransactionDetailsLabel>
<RowBetween>
<RowFixed>
<TYPE.subHeader color={theme.text1}>
<ThemedText.SubHeader color={theme.text1}>
<Trans>Liquidity Provider Fee</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowFixed>
<TextWithLoadingPlaceholder syncing={syncing} width={65}>
<TYPE.black textAlign="right" fontSize={14}>
<ThemedText.Black textAlign="right" fontSize={14}>
{realizedLPFee ? `${realizedLPFee.toSignificant(4)} ${realizedLPFee.currency.symbol}` : '-'}
</TYPE.black>
</ThemedText.Black>
</TextWithLoadingPlaceholder>
</RowBetween>
<RowBetween>
<RowFixed>
<TYPE.subHeader color={theme.text1}>
<ThemedText.SubHeader color={theme.text1}>
<Trans>Price Impact</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowFixed>
<TextWithLoadingPlaceholder syncing={syncing} width={50}>
<TYPE.black textAlign="right" fontSize={14}>
<ThemedText.Black textAlign="right" fontSize={14}>
<FormattedPriceImpact priceImpact={priceImpact} />
</TYPE.black>
</ThemedText.Black>
</TextWithLoadingPlaceholder>
</RowBetween>
<RowBetween>
<RowFixed>
<TYPE.subHeader color={theme.text1}>
<ThemedText.SubHeader color={theme.text1}>
<Trans>Allowed Slippage</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowFixed>
<TextWithLoadingPlaceholder syncing={syncing} width={45}>
<TYPE.black textAlign="right" fontSize={14}>
<ThemedText.Black textAlign="right" fontSize={14}>
{allowedSlippage.toFixed(2)}%
</TYPE.black>
</ThemedText.Black>
</TextWithLoadingPlaceholder>
</RowBetween>
<RowBetween>
<RowFixed>
<TYPE.subHeader color={theme.text1}>
<ThemedText.SubHeader color={theme.text1}>
{trade.tradeType === TradeType.EXACT_INPUT ? <Trans>Minimum received</Trans> : <Trans>Maximum sent</Trans>}
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowFixed>
<TextWithLoadingPlaceholder syncing={syncing} width={70}>
<TYPE.black textAlign="right" fontSize={14}>
<ThemedText.Black textAlign="right" fontSize={14}>
{trade.tradeType === TradeType.EXACT_INPUT
? `${trade.minimumAmountOut(allowedSlippage).toSignificant(6)} ${trade.outputAmount.currency.symbol}`
: `${trade.maximumAmountIn(allowedSlippage).toSignificant(6)} ${trade.inputAmount.currency.symbol}`}
</TYPE.black>
</ThemedText.Black>
</TextWithLoadingPlaceholder>
</RowBetween>
</AutoColumn>
......
import { Trans } from '@lingui/macro'
import { useRoutingAPIEnabled } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { ReactComponent as AutoRouterIcon } from '../../assets/svg/auto_router.svg'
import { ReactComponent as StaticRouterIcon } from '../../assets/svg/static_route.svg'
......@@ -26,7 +26,7 @@ const StyledStaticRouterIcon = styled(StaticRouterIcon)`
}
`
const StyledAutoRouterLabel = styled(TYPE.black)`
const StyledAutoRouterLabel = styled(ThemedText.Black)`
line-height: 1rem;
/* fallback color */
......@@ -51,8 +51,8 @@ export function AutoRouterLabel() {
return routingAPIEnabled ? (
<StyledAutoRouterLabel fontSize={14}>Auto Router</StyledAutoRouterLabel>
) : (
<TYPE.black fontSize={14}>
<ThemedText.Black fontSize={14}>
<Trans>Trade Route</Trans>
</TYPE.black>
</ThemedText.Black>
)
}
......@@ -2,7 +2,7 @@ import { Trans } from '@lingui/macro'
import { Percent } from '@uniswap/sdk-core'
import styled from 'styled-components/macro'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { RowBetween, RowFixed } from '../Row'
import SettingsTab from '../Settings'
......@@ -17,9 +17,9 @@ export default function SwapHeader({ allowedSlippage }: { allowedSlippage: Perce
<StyledSwapHeader>
<RowBetween>
<RowFixed>
<TYPE.black fontWeight={500} fontSize={16} style={{ marginRight: '8px' }}>
<ThemedText.Black fontWeight={500} fontSize={16} style={{ marginRight: '8px' }}>
<Trans>Swap</Trans>
</TYPE.black>
</ThemedText.Black>
</RowFixed>
<RowFixed>
<SettingsTab placeholderSlippage={allowedSlippage} />
......
......@@ -8,7 +8,7 @@ import { Text } from 'rebass'
import styled, { ThemeContext } from 'styled-components/macro'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { isAddress, shortenAddress } from '../../utils'
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
import { ButtonPrimary } from '../Button'
......@@ -64,9 +64,9 @@ export default function SwapModalHeader({
<LightCard padding="0.75rem 1rem">
<AutoColumn gap={'8px'}>
<RowBetween>
<TYPE.body color={theme.text3} fontWeight={500} fontSize={14}>
<ThemedText.Body color={theme.text3} fontWeight={500} fontSize={14}>
<Trans>From</Trans>
</TYPE.body>
</ThemedText.Body>
<FiatValue fiatValue={fiatValueInput} />
</RowBetween>
<RowBetween align="center">
......@@ -94,15 +94,15 @@ export default function SwapModalHeader({
<LightCard padding="0.75rem 1rem" style={{ marginBottom: '0.25rem' }}>
<AutoColumn gap={'8px'}>
<RowBetween>
<TYPE.body color={theme.text3} fontWeight={500} fontSize={14}>
<ThemedText.Body color={theme.text3} fontWeight={500} fontSize={14}>
<Trans>To</Trans>
</TYPE.body>
<TYPE.body fontSize={14} color={theme.text3}>
</ThemedText.Body>
<ThemedText.Body fontSize={14} color={theme.text3}>
<FiatValue
fiatValue={fiatValueOutput}
priceImpact={computeFiatValuePriceImpact(fiatValueInput, fiatValueOutput)}
/>
</TYPE.body>
</ThemedText.Body>
</RowBetween>
<RowBetween align="flex-end">
<RowFixed gap={'0px'}>
......@@ -120,9 +120,9 @@ export default function SwapModalHeader({
</AutoColumn>
</LightCard>
<RowBetween style={{ marginTop: '0.25rem', padding: '0 1rem' }}>
<TYPE.body color={theme.text2} fontWeight={500} fontSize={14}>
<ThemedText.Body color={theme.text2} fontWeight={500} fontSize={14}>
<Trans>Price</Trans>
</TYPE.body>
</ThemedText.Body>
<TradePrice price={trade.executionPrice} showInverted={showInverted} setShowInverted={setShowInverted} />
</RowBetween>
......@@ -135,9 +135,9 @@ export default function SwapModalHeader({
<RowBetween>
<RowFixed>
<AlertTriangle size={20} style={{ marginRight: '8px', minWidth: 24 }} />
<TYPE.main color={theme.primary1}>
<ThemedText.Main color={theme.primary1}>
<Trans>Price Updated</Trans>
</TYPE.main>
</ThemedText.Main>
</RowFixed>
<ButtonPrimary
style={{ padding: '.5rem', width: 'fit-content', fontSize: '0.825rem', borderRadius: '12px' }}
......@@ -151,7 +151,7 @@ export default function SwapModalHeader({
<AutoColumn justify="flex-start" gap="sm" style={{ padding: '.75rem 1rem' }}>
{trade.tradeType === TradeType.EXACT_INPUT ? (
<TYPE.italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
<ThemedText.Italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
<Trans>
Output is estimated. You will receive at least{' '}
<b>
......@@ -159,9 +159,9 @@ export default function SwapModalHeader({
</b>{' '}
or the transaction will revert.
</Trans>
</TYPE.italic>
</ThemedText.Italic>
) : (
<TYPE.italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
<ThemedText.Italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
<Trans>
Input is estimated. You will sell at most{' '}
<b>
......@@ -169,17 +169,17 @@ export default function SwapModalHeader({
</b>{' '}
or the transaction will revert.
</Trans>
</TYPE.italic>
</ThemedText.Italic>
)}
</AutoColumn>
{recipient !== null ? (
<AutoColumn justify="flex-start" gap="sm" style={{ padding: '12px 0 0 0px' }}>
<TYPE.main>
<ThemedText.Main>
<Trans>
Output will be sent to{' '}
<b title={recipient}>{isAddress(recipient) ? shortenAddress(recipient) : recipient}</b>
</Trans>
</TYPE.main>
</ThemedText.Main>
</AutoColumn>
) : null}
</AutoColumn>
......
......@@ -11,7 +11,7 @@ import { Version } from 'hooks/useToggledVersion'
import { memo } from 'react'
import { useRoutingAPIEnabled } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import { getTradeVersion } from 'utils/getTradeVersion'
import { AutoRouterLabel, AutoRouterLogo } from './RouterLabel'
......@@ -46,9 +46,9 @@ export default memo(function SwapRoute({
</LoadingRows>
) : (
<Badge>
<TYPE.black fontSize={12}>
<ThemedText.Black fontSize={12}>
{getTradeVersion(trade) === Version.v2 ? <Trans>V2</Trans> : <Trans>V3</Trans>}
</TYPE.black>
</ThemedText.Black>
</Badge>
)}
</RowBetween>
......@@ -65,9 +65,9 @@ export default memo(function SwapRoute({
/>
)}
{routingAPIEnabled && (
<TYPE.main fontSize={12} width={400}>
<ThemedText.Main fontSize={12} width={400}>
<Trans>This route optimizes your price by considering split routes, multiple hops, and gas costs.</Trans>
</TYPE.main>
</ThemedText.Main>
)}
</AutoColumn>
)
......
......@@ -4,7 +4,7 @@ import useUSDCPrice from 'hooks/useUSDCPrice'
import { useCallback, useContext } from 'react'
import { Text } from 'rebass'
import styled, { ThemeContext } from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
interface TradePriceProps {
price: Price<Currency, Currency>
......@@ -49,9 +49,9 @@ export default function TradePrice({ price, showInverted, setShowInverted }: Tra
{text}
</Text>{' '}
{usdcPrice && (
<TYPE.darkGray>
<ThemedText.DarkGray>
<Trans>(${usdcPrice.toSignificant(6, { groupSeparator: ',' })})</Trans>
</TYPE.darkGray>
</ThemedText.DarkGray>
)}
</StyledPriceContainer>
)
......
......@@ -9,7 +9,7 @@ import { AutoRow, RowBetween } from 'components/Row'
import { useActiveWeb3React } from 'hooks/web3'
import { useState } from 'react'
import styled from 'styled-components/macro'
import { CloseIcon, ExternalLink, TYPE, Z_INDEX } from 'theme'
import { CloseIcon, ExternalLink, ThemedText, Z_INDEX } from 'theme'
import { useUnsupportedTokens } from '../../hooks/Tokens'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
......@@ -37,7 +37,7 @@ const StyledButtonEmpty = styled(ButtonEmpty)`
text-decoration: none;
`
const AddressText = styled(TYPE.blue)`
const AddressText = styled(ThemedText.Blue)`
font-size: 12px;
${({ theme }) => theme.mediaWidth.upToSmall`
......@@ -70,9 +70,9 @@ export default function UnsupportedCurrencyFooter({
<Card padding="2rem">
<AutoColumn gap="lg">
<RowBetween>
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Unsupported Assets</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<CloseIcon onClick={() => setShowDetails(false)} />
</RowBetween>
{tokens.map((token) => {
......@@ -84,7 +84,7 @@ export default function UnsupportedCurrencyFooter({
<AutoColumn gap="10px">
<AutoRow gap="5px" align="center">
<CurrencyLogo currency={token} size={'24px'} />
<TYPE.body fontWeight={500}>{token.symbol}</TYPE.body>
<ThemedText.Body fontWeight={500}>{token.symbol}</ThemedText.Body>
</AutoRow>
{chainId && (
<ExternalLink href={getExplorerLink(chainId, token.address, ExplorerDataType.ADDRESS)}>
......@@ -97,20 +97,20 @@ export default function UnsupportedCurrencyFooter({
)
})}
<AutoColumn gap="lg">
<TYPE.body fontWeight={500}>
<ThemedText.Body fontWeight={500}>
<Trans>
Some assets are not available through this interface because they may not work well with the smart
contracts or we are unable to allow trading for legal reasons.
</Trans>
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</AutoColumn>
</Card>
</Modal>
<StyledButtonEmpty padding={'0'} onClick={() => setShowDetails(true)}>
<TYPE.blue>
<ThemedText.Blue>
<Trans>Read more about unsupported assets</Trans>
</TYPE.blue>
</ThemedText.Blue>
</StyledButtonEmpty>
</DetailsFooter>
)
......
......@@ -5,8 +5,8 @@ import { ReactNode } from 'react'
import { AlertTriangle } from 'react-feather'
import { Text } from 'rebass'
import styled, { css } from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from '../../theme'
import { AutoColumn } from '../Column'
import TradePrice from './TradePrice'
......@@ -133,7 +133,7 @@ export const SwapShowAcceptChanges = styled(AutoColumn)`
margin-top: 8px;
`
export const TransactionDetailsLabel = styled(TYPE.black)`
export const TransactionDetailsLabel = styled(ThemedText.Black)`
border-bottom: 1px solid ${({ theme }) => theme.bg2};
padding-bottom: 0.5rem;
`
......
......@@ -10,7 +10,7 @@ import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks/web3'
import { useDelegateCallback } from '../../state/governance/hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import AddressInputPanel from '../AddressInputPanel'
import { ButtonPrimary } from '../Button'
import { AutoColumn } from '../Column'
......@@ -95,23 +95,25 @@ export default function DelegateModal({ isOpen, onDismiss, title }: VoteModalPro
<ContentWrapper gap="lg">
<AutoColumn gap="lg" justify="center">
<RowBetween>
<TYPE.mediumHeader fontWeight={500}>{title}</TYPE.mediumHeader>
<ThemedText.MediumHeader fontWeight={500}>{title}</ThemedText.MediumHeader>
<StyledClosed stroke="black" onClick={wrappedOndismiss} />
</RowBetween>
<TYPE.body>
<ThemedText.Body>
<Trans>Earned UNI tokens represent voting shares in Uniswap governance.</Trans>
</TYPE.body>
<TYPE.body>
</ThemedText.Body>
<ThemedText.Body>
<Trans>You can either vote on each proposal yourself or delegate your votes to a third party.</Trans>
</TYPE.body>
</ThemedText.Body>
{usingDelegate && <AddressInputPanel value={typed} onChange={handleRecipientType} />}
<ButtonPrimary disabled={!isAddress(parsedAddress ?? '')} onClick={onDelegate}>
<TYPE.mediumHeader color="white">
<ThemedText.MediumHeader color="white">
{usingDelegate ? <Trans>Delegate Votes</Trans> : <Trans>Self Delegate</Trans>}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
</ButtonPrimary>
<TextButton onClick={() => setUsingDelegate(!usingDelegate)}>
<TYPE.blue>{usingDelegate ? <Trans>Remove Delegate</Trans> : <Trans>Add Delegate +</Trans>}</TYPE.blue>
<ThemedText.Blue>
{usingDelegate ? <Trans>Remove Delegate</Trans> : <Trans>Add Delegate +</Trans>}
</ThemedText.Blue>
</TextButton>
</AutoColumn>
</ContentWrapper>
......@@ -119,20 +121,20 @@ export default function DelegateModal({ isOpen, onDismiss, title }: VoteModalPro
{attempting && !hash && (
<LoadingView onDismiss={wrappedOndismiss}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
{usingDelegate ? <Trans>Delegating votes</Trans> : <Trans>Unlocking Votes</Trans>}
</TYPE.largeHeader>
<TYPE.main fontSize={36}> {formatCurrencyAmount(uniBalance, 4)}</TYPE.main>
</ThemedText.LargeHeader>
<ThemedText.Main fontSize={36}> {formatCurrencyAmount(uniBalance, 4)}</ThemedText.Main>
</AutoColumn>
</LoadingView>
)}
{hash && (
<SubmittedView onDismiss={wrappedOndismiss} hash={hash}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Transaction Submitted</Trans>
</TYPE.largeHeader>
<TYPE.main fontSize={36}>{formatCurrencyAmount(uniBalance, 4)}</TYPE.main>
</ThemedText.LargeHeader>
<ThemedText.Main fontSize={36}>{formatCurrencyAmount(uniBalance, 4)}</ThemedText.Main>
</AutoColumn>
</SubmittedView>
)}
......
......@@ -2,7 +2,7 @@ import { Trans } from '@lingui/macro'
import { L2_CHAIN_IDS } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
const EmptyProposals = styled.div`
border: 1px solid ${({ theme }) => theme.text4};
......@@ -25,14 +25,14 @@ interface EmptyStateProps {
}
const EmptyState = ({ HeaderContent, SubHeaderContent }: EmptyStateProps) => (
<EmptyProposals>
<TYPE.body style={{ marginBottom: '8px' }}>
<ThemedText.Body style={{ marginBottom: '8px' }}>
<HeaderContent />
</TYPE.body>
<TYPE.subHeader>
</ThemedText.Body>
<ThemedText.SubHeader>
<Sub>
<SubHeaderContent />
</Sub>
</TYPE.subHeader>
</ThemedText.SubHeader>
</EmptyProposals>
)
......
......@@ -8,8 +8,8 @@ import Circle from '../../assets/images/blue-loader.svg'
import { useActiveWeb3React } from '../../hooks/web3'
import { useUserVotes, useVoteCallback } from '../../state/governance/hooks'
import { VoteOption } from '../../state/governance/types'
import { CustomLightSpinner, TYPE } from '../../theme'
import { ExternalLink } from '../../theme/components'
import { CustomLightSpinner, ThemedText } from '../../theme'
import { ExternalLink } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { ButtonPrimary } from '../Button'
import { AutoColumn, ColumnCenter } from '../Column'
......@@ -85,7 +85,7 @@ export default function VoteModal({ isOpen, onDismiss, proposalId, voteOption }:
<ContentWrapper gap="lg">
<AutoColumn gap="lg" justify="center">
<RowBetween>
<TYPE.mediumHeader fontWeight={500}>
<ThemedText.MediumHeader fontWeight={500}>
{voteOption === VoteOption.Against ? (
<Trans>Vote against proposal {proposalId}</Trans>
) : voteOption === VoteOption.For ? (
......@@ -93,14 +93,14 @@ export default function VoteModal({ isOpen, onDismiss, proposalId, voteOption }:
) : (
<Trans>Vote to abstain on proposal {proposalId}</Trans>
)}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<StyledClosed stroke="black" onClick={wrappedOndismiss} />
</RowBetween>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>{formatCurrencyAmount(availableVotes, 4)} Votes</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
<ButtonPrimary onClick={onVote}>
<TYPE.mediumHeader color="white">
<ThemedText.MediumHeader color="white">
{voteOption === VoteOption.Against ? (
<Trans>Vote against proposal {proposalId}</Trans>
) : voteOption === VoteOption.For ? (
......@@ -108,7 +108,7 @@ export default function VoteModal({ isOpen, onDismiss, proposalId, voteOption }:
) : (
<Trans>Vote to abstain on proposal {proposalId}</Trans>
)}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
</ButtonPrimary>
</AutoColumn>
</ContentWrapper>
......@@ -124,13 +124,13 @@ export default function VoteModal({ isOpen, onDismiss, proposalId, voteOption }:
</ConfirmedIcon>
<AutoColumn gap="100px" justify={'center'}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Submitting Vote</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
</AutoColumn>
<TYPE.subHeader>
<ThemedText.SubHeader>
<Trans>Confirm this transaction in your wallet</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</AutoColumn>
</ConfirmOrLoadingWrapper>
)}
......@@ -145,18 +145,18 @@ export default function VoteModal({ isOpen, onDismiss, proposalId, voteOption }:
</ConfirmedIcon>
<AutoColumn gap="100px" justify={'center'}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Transaction Submitted</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
</AutoColumn>
{chainId && (
<ExternalLink
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
style={{ marginLeft: '4px' }}
>
<TYPE.subHeader>
<ThemedText.SubHeader>
<Trans>View transaction on Explorer</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</ExternalLink>
)}
</AutoColumn>
......
......@@ -5,10 +5,10 @@ export const OVERLAY_READY = 'OVERLAY_READY'
type FormaticSupportedChains = 1 | 3 | 4 | 42
const CHAIN_ID_NETWORK_ARGUMENT: { readonly [chainId in FormaticSupportedChains]: string | undefined } = {
[1]: undefined,
[3]: 'ropsten',
[4]: 'rinkeby',
[42]: 'kovan',
1: undefined,
3: 'ropsten',
4: 'rinkeby',
42: 'kovan',
}
export class FortmaticConnector extends FortmaticConnectorCore {
......
......@@ -19,5 +19,5 @@ export const DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS = 13
// Block time here is slightly higher (~1s) than average in order to avoid ongoing proposals past the displayed time
export const AVERAGE_BLOCK_TIME_IN_SECS: { [chainId: number]: number } = {
[1]: DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS,
1: DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS,
}
......@@ -13,6 +13,9 @@ import {
FRAX,
FXS,
renBTC,
rETH2,
sETH2,
SWISE,
TRIBE,
USDC,
USDC_ARBITRUM,
......@@ -53,6 +56,8 @@ export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = {
export const ADDITIONAL_BASES: { [chainId: number]: { [tokenAddress: string]: Token[] } } = {
[SupportedChainId.MAINNET]: {
'0xF16E4d813f4DcfDe4c5b44f305c908742De84eF0': [ETH2X_FLI],
[rETH2.address]: [sETH2],
[SWISE.address]: [sETH2],
[FEI.address]: [TRIBE],
[TRIBE.address]: [FEI],
[FRAX.address]: [FXS],
......
......@@ -136,6 +136,27 @@ export const ETH2X_FLI = new Token(
'ETH2x-FLI',
'ETH 2x Flexible Leverage Index'
)
export const sETH2 = new Token(
SupportedChainId.MAINNET,
'0xFe2e637202056d30016725477c5da089Ab0A043A',
18,
'sETH2',
'StakeWise Staked ETH2'
)
export const rETH2 = new Token(
SupportedChainId.MAINNET,
'0x20BC832ca081b91433ff6c17f85701B6e92486c5',
18,
'rETH2',
'StakeWise Reward ETH2'
)
export const SWISE = new Token(
SupportedChainId.MAINNET,
'0x48C3399719B582dD63eB5AADf12A40B4C3f52FA2',
18,
'SWISE',
'StakeWise'
)
export const UNI: { [chainId: number]: Token } = {
[SupportedChainId.MAINNET]: new Token(SupportedChainId.MAINNET, UNI_ADDRESS[1], 18, 'UNI', 'Uniswap'),
[SupportedChainId.RINKEBY]: new Token(SupportedChainId.RINKEBY, UNI_ADDRESS[4], 18, 'UNI', 'Uniswap'),
......
import { arrayify } from '@ethersproject/bytes'
import { parseBytes32String } from '@ethersproject/strings'
import { Currency, Token } from '@uniswap/sdk-core'
import { CHAIN_INFO, L2_CHAIN_IDS, SupportedChainId, SupportedL2ChainId } from 'constants/chains'
import { useMemo } from 'react'
import { createTokenFilterFunction } from '../components/SearchModal/filtering'
import { ExtendedEther, WETH9_EXTENDED } from '../constants/tokens'
import { useAllLists, useCombinedActiveList, useInactiveListUrls } from '../state/lists/hooks'
import { WrappedTokenInfo } from '../state/lists/wrappedTokenInfo'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useUserAddedTokens } from '../state/user/hooks'
import { isAddress } from '../utils'
import { TokenAddressMap, useUnsupportedTokenList } from './../state/lists/hooks'
import { useBytes32TokenContract, useTokenContract } from './useContract'
import { useActiveWeb3React } from './web3'
// reduce token map into standard address <-> Token mapping, optionally include user added tokens
function useTokensFromMap(tokenMap: TokenAddressMap, includeUserAdded: boolean): { [address: string]: Token } {
const { chainId } = useActiveWeb3React()
const userAddedTokens = useUserAddedTokens()
return useMemo(() => {
if (!chainId) return {}
// reduce to just tokens
const mapWithoutUrls = Object.keys(tokenMap[chainId] ?? {}).reduce<{ [address: string]: Token }>(
(newMap, address) => {
newMap[address] = tokenMap[chainId][address].token
return newMap
},
{}
)
if (includeUserAdded) {
return (
userAddedTokens
// reduce into all ALL_TOKENS filtered by the current chain
.reduce<{ [address: string]: Token }>(
(tokenMap, token) => {
tokenMap[token.address] = token
return tokenMap
},
// must make a copy because reduce modifies the map, and we do not
// want to make a copy in every iteration
{ ...mapWithoutUrls }
)
)
}
return mapWithoutUrls
}, [chainId, userAddedTokens, tokenMap, includeUserAdded])
}
export function useAllTokens(): { [address: string]: Token } {
const allTokens = useCombinedActiveList()
return useTokensFromMap(allTokens, true)
}
type BridgeInfo = Record<
SupportedChainId,
{
tokenAddress: string
originBridgeAddress: string
destBridgeAddress: string
}
>
export function useUnsupportedTokens(): { [address: string]: Token } {
const { chainId } = useActiveWeb3React()
const listsByUrl = useAllLists()
const unsupportedTokensMap = useUnsupportedTokenList()
const unsupportedTokens = useTokensFromMap(unsupportedTokensMap, false)
// checks the default L2 lists to see if `bridgeInfo` has an L1 address value that is unsupported
const l2InferredBlockedTokens: typeof unsupportedTokens = useMemo(() => {
if (!chainId || !L2_CHAIN_IDS.includes(chainId)) {
return {}
}
if (!listsByUrl) {
return {}
}
const listUrl = CHAIN_INFO[chainId as SupportedL2ChainId].defaultListUrl
const { current: list } = listsByUrl[listUrl]
if (!list) {
return {}
}
const unsupportedSet = new Set(Object.keys(unsupportedTokens))
return list.tokens.reduce((acc, tokenInfo) => {
const bridgeInfo = tokenInfo.extensions?.bridgeInfo as unknown as BridgeInfo
if (
bridgeInfo &&
bridgeInfo[SupportedChainId.MAINNET] &&
bridgeInfo[SupportedChainId.MAINNET].tokenAddress &&
unsupportedSet.has(bridgeInfo[SupportedChainId.MAINNET].tokenAddress)
) {
const address = bridgeInfo[SupportedChainId.MAINNET].tokenAddress
// don't rely on decimals--it's possible that a token could be bridged w/ different decimals on the L2
return { ...acc, [address]: new Token(SupportedChainId.MAINNET, address, tokenInfo.decimals) }
}
return acc
}, {})
}, [chainId, listsByUrl, unsupportedTokens])
return { ...unsupportedTokens, ...l2InferredBlockedTokens }
}
export function useSearchInactiveTokenLists(search: string | undefined, minResults = 10): WrappedTokenInfo[] {
const lists = useAllLists()
const inactiveUrls = useInactiveListUrls()
const { chainId } = useActiveWeb3React()
const activeTokens = useAllTokens()
return useMemo(() => {
if (!search || search.trim().length === 0) return []
const tokenFilter = createTokenFilterFunction(search)
const result: WrappedTokenInfo[] = []
const addressSet: { [address: string]: true } = {}
for (const url of inactiveUrls) {
const list = lists[url].current
if (!list) continue
for (const tokenInfo of list.tokens) {
if (tokenInfo.chainId === chainId && tokenFilter(tokenInfo)) {
const wrapped: WrappedTokenInfo = new WrappedTokenInfo(tokenInfo, list)
if (!(wrapped.address in activeTokens) && !addressSet[wrapped.address]) {
addressSet[wrapped.address] = true
result.push(wrapped)
if (result.length >= minResults) return result
}
}
}
}
return result
}, [activeTokens, chainId, inactiveUrls, lists, minResults, search])
}
export function useIsTokenActive(token: Token | undefined | null): boolean {
const activeTokens = useAllTokens()
if (!activeTokens || !token) {
return false
}
return !!activeTokens[token.address]
}
// Check if currency is included in custom list from user storage
export function useIsUserAddedToken(currency: Currency | undefined | null): boolean {
const userAddedTokens = useUserAddedTokens()
if (!currency) {
return false
}
return !!userAddedTokens.find((token) => currency.equals(token))
}
// parse a name or symbol from a token response
const BYTES32_REGEX = /^0x[a-fA-F0-9]{64}$/
function parseStringOrBytes32(str: string | undefined, bytes32: string | undefined, defaultValue: string): string {
return str && str.length > 0
? str
: // need to check for proper bytes string and valid terminator
bytes32 && BYTES32_REGEX.test(bytes32) && arrayify(bytes32)[31] === 0
? parseBytes32String(bytes32)
: defaultValue
}
// undefined if invalid or does not exist
// null if loading or null was passed
// otherwise returns the token
export function useToken(tokenAddress?: string | null): Token | undefined | null {
const { chainId } = useActiveWeb3React()
const tokens = useAllTokens()
const address = isAddress(tokenAddress)
const tokenContract = useTokenContract(address ? address : undefined, false)
const tokenContractBytes32 = useBytes32TokenContract(address ? address : undefined, false)
const token: Token | undefined = address ? tokens[address] : undefined
const tokenName = useSingleCallResult(token ? undefined : tokenContract, 'name', undefined, NEVER_RELOAD)
const tokenNameBytes32 = useSingleCallResult(
token ? undefined : tokenContractBytes32,
'name',
undefined,
NEVER_RELOAD
)
const symbol = useSingleCallResult(token ? undefined : tokenContract, 'symbol', undefined, NEVER_RELOAD)
const symbolBytes32 = useSingleCallResult(token ? undefined : tokenContractBytes32, 'symbol', undefined, NEVER_RELOAD)
const decimals = useSingleCallResult(token ? undefined : tokenContract, 'decimals', undefined, NEVER_RELOAD)
return useMemo(() => {
if (token) return token
if (tokenAddress === null) return null
if (!chainId || !address) return undefined
if (decimals.loading || symbol.loading || tokenName.loading) return null
if (decimals.result) {
return new Token(
chainId,
address,
decimals.result[0],
parseStringOrBytes32(symbol.result?.[0], symbolBytes32.result?.[0], 'UNKNOWN'),
parseStringOrBytes32(tokenName.result?.[0], tokenNameBytes32.result?.[0], 'Unknown Token')
)
}
return undefined
}, [
address,
chainId,
decimals.loading,
decimals.result,
symbol.loading,
symbol.result,
symbolBytes32.result,
token,
tokenAddress,
tokenName.loading,
tokenName.result,
tokenNameBytes32.result,
])
}
export function useCurrency(currencyId: string | null | undefined): Currency | null | undefined {
const { chainId } = useActiveWeb3React()
const isETH = currencyId?.toUpperCase() === 'ETH'
const token = useToken(isETH ? undefined : currencyId)
const extendedEther = useMemo(
() =>
chainId
? ExtendedEther.onChain(chainId)
: // display mainnet when not connected
ExtendedEther.onChain(SupportedChainId.MAINNET),
[chainId]
)
const weth = chainId ? WETH9_EXTENDED[chainId] : undefined
if (currencyId === null || currencyId === undefined) return currencyId
if (weth?.address?.toUpperCase() === currencyId?.toUpperCase()) return weth
return isETH ? extendedEther : token
}
import { DEFAULT_LOCALE, SUPPORTED_LOCALES, SupportedLocale } from 'constants/locales'
import { useMemo } from 'react'
import store from 'state'
import { useUserLocale } from 'state/user/hooks'
import useParsedQueryString from './useParsedQueryString'
import { parsedQueryString } from './useParsedQueryString'
/**
* Given a locale string (e.g. from user agent), return the best match for corresponding SupportedLocale
* @param maybeSupportedLocale the fuzzy locale identifier
*/
function parseLocale(maybeSupportedLocale: unknown): SupportedLocale | undefined {
if (typeof maybeSupportedLocale !== 'string') return undefined
const lowerMaybeSupportedLocale = maybeSupportedLocale.toLowerCase()
return SUPPORTED_LOCALES.find(
(locale) => locale.toLowerCase() === lowerMaybeSupportedLocale || locale.split('-')[0] === lowerMaybeSupportedLocale
)
}
/**
* Returns the supported locale read from the user agent (navigator)
*/
export function navigatorLocale(): SupportedLocale | undefined {
if (!navigator.language) return undefined
const [language, region] = navigator.language.split('-')
if (region) {
return parseLocale(`${language}-${region.toUpperCase()}`) ?? parseLocale(language)
}
return parseLocale(language)
}
function storeLocale(): SupportedLocale | undefined {
return store.getState().user.userLocale ?? undefined
}
export const initialLocale =
parseLocale(parsedQueryString().lng) ?? storeLocale() ?? navigatorLocale() ?? DEFAULT_LOCALE
function useUrlLocale() {
const parsed = useParsedQueryString()
return parseLocale(parsed.lng)
}
/**
* Returns the currently active locale, from a combination of user agent, query string, and user settings stored in redux
* Stores the query string locale in redux (if set) to persist across sessions
*/
export function useActiveLocale(): SupportedLocale {
const urlLocale = useUrlLocale()
const userLocale = useUserLocale()
return useMemo(() => urlLocale ?? userLocale ?? navigatorLocale() ?? DEFAULT_LOCALE, [urlLocale, userLocale])
}
import { Currency, Token } from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks/web3'
import { useCallback, useState } from 'react'
import { getTokenLogoURL } from './../components/CurrencyLogo/index'
export default function useAddTokenToMetamask(currencyToAdd: Currency | undefined): {
addToken: () => void
success: boolean | undefined
} {
const { library } = useActiveWeb3React()
const token: Token | undefined = currencyToAdd?.wrapped
const [success, setSuccess] = useState<boolean | undefined>()
const addToken = useCallback(() => {
if (library && library.provider.isMetaMask && library.provider.request && token) {
library.provider
.request({
method: 'wallet_watchAsset',
params: {
//@ts-ignore // need this for incorrect ethers provider type
type: 'ERC20',
options: {
address: token.address,
symbol: token.symbol,
decimals: token.decimals,
image: getTokenLogoURL(token.address),
},
},
})
.then((success) => {
setSuccess(success)
})
.catch(() => setSuccess(false))
} else {
setSuccess(false)
}
}, [library, token])
return { addToken, success }
}
import { Currency, Token } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { ADDITIONAL_BASES, BASES_TO_CHECK_TRADES_AGAINST, CUSTOM_BASES } from '../constants/routing'
export function useAllCurrencyCombinations(currencyA?: Currency, currencyB?: Currency): [Token, Token][] {
const chainId = currencyA?.chainId
const [tokenA, tokenB] = chainId ? [currencyA?.wrapped, currencyB?.wrapped] : [undefined, undefined]
const bases: Token[] = useMemo(() => {
if (!chainId || chainId !== tokenB?.chainId) return []
const common = BASES_TO_CHECK_TRADES_AGAINST[chainId] ?? []
const additionalA = tokenA ? ADDITIONAL_BASES[chainId]?.[tokenA.address] ?? [] : []
const additionalB = tokenB ? ADDITIONAL_BASES[chainId]?.[tokenB.address] ?? [] : []
return [...common, ...additionalA, ...additionalB]
}, [chainId, tokenA, tokenB])
const basePairs: [Token, Token][] = useMemo(
() =>
bases
.flatMap((base): [Token, Token][] => bases.map((otherBase) => [base, otherBase]))
// though redundant with the first filter below, that expression runs more often, so this is probably worthwhile
.filter(([t0, t1]) => !t0.equals(t1)),
[bases]
)
return useMemo(
() =>
tokenA && tokenB
? [
// the direct pair
[tokenA, tokenB] as [Token, Token],
// token A against all bases
...bases.map((base): [Token, Token] => [tokenA, base]),
// token B against all bases
...bases.map((base): [Token, Token] => [tokenB, base]),
// each base against all bases
...basePairs,
]
// filter out invalid pairs comprised of the same asset (e.g. WETH<>WETH)
.filter(([t0, t1]) => !t0.equals(t1))
// filter out duplicate pairs
.filter(([t0, t1], i, otherPairs) => {
// find the first index in the array at which there are the same 2 tokens as the current
const firstIndexInOtherPairs = otherPairs.findIndex(([t0Other, t1Other]) => {
return (t0.equals(t0Other) && t1.equals(t1Other)) || (t0.equals(t1Other) && t1.equals(t0Other))
})
// only accept the first occurrence of the same 2 tokens
return firstIndexInOtherPairs === i
})
// optionally filter out some pairs for tokens with custom bases defined
.filter(([tokenA, tokenB]) => {
if (!chainId) return true
const customBases = CUSTOM_BASES[chainId]
const customBasesA: Token[] | undefined = customBases?.[tokenA.address]
const customBasesB: Token[] | undefined = customBases?.[tokenB.address]
if (!customBasesA && !customBasesB) return true
if (customBasesA && !customBasesA.find((base) => tokenB.equals(base))) return false
if (customBasesB && !customBasesB.find((base) => tokenA.equals(base))) return false
return true
})
: [],
[tokenA, tokenB, bases, basePairs, chainId]
)
}
import { Currency } from '@uniswap/sdk-core'
import { Pool, Route } from '@uniswap/v3-sdk'
import { useMemo } from 'react'
import { useV3SwapPools } from './useV3SwapPools'
import { useActiveWeb3React } from './web3'
/**
* Returns true if poolA is equivalent to poolB
* @param poolA one of the two pools
* @param poolB the other pool
*/
function poolEquals(poolA: Pool, poolB: Pool): boolean {
return (
poolA === poolB ||
(poolA.token0.equals(poolB.token0) && poolA.token1.equals(poolB.token1) && poolA.fee === poolB.fee)
)
}
function computeAllRoutes(
currencyIn: Currency,
currencyOut: Currency,
pools: Pool[],
chainId: number,
currentPath: Pool[] = [],
allPaths: Route<Currency, Currency>[] = [],
startCurrencyIn: Currency = currencyIn,
maxHops = 2
): Route<Currency, Currency>[] {
const tokenIn = currencyIn?.wrapped
const tokenOut = currencyOut?.wrapped
if (!tokenIn || !tokenOut) throw new Error('Missing tokenIn/tokenOut')
for (const pool of pools) {
if (!pool.involvesToken(tokenIn) || currentPath.find((pathPool) => poolEquals(pool, pathPool))) continue
const outputToken = pool.token0.equals(tokenIn) ? pool.token1 : pool.token0
if (outputToken.equals(tokenOut)) {
allPaths.push(new Route([...currentPath, pool], startCurrencyIn, currencyOut))
} else if (maxHops > 1) {
computeAllRoutes(
outputToken,
currencyOut,
pools,
chainId,
[...currentPath, pool],
allPaths,
startCurrencyIn,
maxHops - 1
)
}
}
return allPaths
}
/**
* Returns all the routes from an input currency to an output currency
* @param currencyIn the input currency
* @param currencyOut the output currency
*/
export function useAllV3Routes(
currencyIn?: Currency,
currencyOut?: Currency
): { loading: boolean; routes: Route<Currency, Currency>[] } {
const { chainId } = useActiveWeb3React()
const { pools, loading: poolsLoading } = useV3SwapPools(currencyIn, currencyOut)
return useMemo(() => {
if (poolsLoading || !chainId || !pools || !currencyIn || !currencyOut) return { loading: true, routes: [] }
const routes = computeAllRoutes(currencyIn, currencyOut, pools, chainId, [], [], currencyIn, 2)
return { loading: false, routes }
}, [chainId, currencyIn, currencyOut, pools, poolsLoading])
}
import { useEffect } from 'react'
import { useAppDispatch } from 'state/hooks'
import { updateUserExpertMode } from '../state/user/actions'
import useParsedQueryString from './useParsedQueryString'
export default function ApeModeQueryParamReader(): null {
useApeModeQueryParamReader()
return null
}
function useApeModeQueryParamReader() {
const dispatch = useAppDispatch()
const { ape } = useParsedQueryString()
useEffect(() => {
if (typeof ape !== 'string') return
if (ape === '' || ape.toLowerCase() === 'true') {
dispatch(updateUserExpertMode({ userExpertMode: true }))
}
})
}
import ArgentWalletContractABI from '../abis/argent-wallet-contract.json'
import { ArgentWalletContract } from '../abis/types'
import { useContract } from './useContract'
import useIsArgentWallet from './useIsArgentWallet'
import { useActiveWeb3React } from './web3'
export function useArgentWalletContract(): ArgentWalletContract | null {
const { account } = useActiveWeb3React()
const isArgentWallet = useIsArgentWallet()
return useContract(
isArgentWallet ? account ?? undefined : undefined,
ArgentWalletContractABI,
true
) as ArgentWalletContract
}
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { Pair, Trade } from '@uniswap/v2-sdk'
import { useMemo } from 'react'
import { isTradeBetter } from 'utils/isTradeBetter'
import { BETTER_TRADE_LESS_HOPS_THRESHOLD } from '../constants/misc'
import { useAllCurrencyCombinations } from './useAllCurrencyCombinations'
import { PairState, useV2Pairs } from './useV2Pairs'
function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency): Pair[] {
const allCurrencyCombinations = useAllCurrencyCombinations(currencyA, currencyB)
const allPairs = useV2Pairs(allCurrencyCombinations)
return useMemo(
() =>
Object.values(
allPairs
// filter out invalid pairs
.filter((result): result is [PairState.EXISTS, Pair] => Boolean(result[0] === PairState.EXISTS && result[1]))
.map(([, pair]) => pair)
),
[allPairs]
)
}
const MAX_HOPS = 3
/**
* Returns the best v2 trade for a desired swap
* @param tradeType whether the swap is an exact in/out
* @param amountSpecified the exact amount to swap in/out
* @param otherCurrency the desired output/payment currency
*/
export function useBestV2Trade(
tradeType: TradeType.EXACT_INPUT | TradeType.EXACT_OUTPUT,
amountSpecified?: CurrencyAmount<Currency>,
otherCurrency?: Currency,
{ maxHops = MAX_HOPS } = {}
): Trade<Currency, Currency, TradeType.EXACT_INPUT | TradeType.EXACT_OUTPUT> | null {
const [currencyIn, currencyOut] = useMemo(
() =>
tradeType === TradeType.EXACT_INPUT
? [amountSpecified?.currency, otherCurrency]
: [otherCurrency, amountSpecified?.currency],
[tradeType, amountSpecified, otherCurrency]
)
const allowedPairs = useAllCommonPairs(currencyIn, currencyOut)
return useMemo(() => {
if (amountSpecified && currencyIn && currencyOut && allowedPairs.length > 0) {
if (maxHops === 1) {
const options = { maxHops: 1, maxNumResults: 1 }
if (tradeType === TradeType.EXACT_INPUT) {
const amountIn = amountSpecified
return Trade.bestTradeExactIn(allowedPairs, amountIn, currencyOut, options)[0] ?? null
} else {
const amountOut = amountSpecified
return Trade.bestTradeExactOut(allowedPairs, currencyIn, amountOut, options)[0] ?? null
}
}
// search through trades with varying hops, find best trade out of them
let bestTradeSoFar: Trade<Currency, Currency, TradeType.EXACT_INPUT | TradeType.EXACT_OUTPUT> | null = null
for (let i = 1; i <= maxHops; i++) {
const options = { maxHops: i, maxNumResults: 1 }
let currentTrade: Trade<Currency, Currency, TradeType.EXACT_INPUT | TradeType.EXACT_OUTPUT> | null
if (tradeType === TradeType.EXACT_INPUT) {
const amountIn = amountSpecified
currentTrade = Trade.bestTradeExactIn(allowedPairs, amountIn, currencyOut, options)[0] ?? null
} else {
const amountOut = amountSpecified
currentTrade = Trade.bestTradeExactOut(allowedPairs, currencyIn, amountOut, options)[0] ?? null
}
// if current trade is best yet, save it
if (isTradeBetter(bestTradeSoFar, currentTrade, BETTER_TRADE_LESS_HOPS_THRESHOLD)) {
bestTradeSoFar = currentTrade
}
}
return bestTradeSoFar
}
return null
}, [tradeType, amountSpecified, currencyIn, currencyOut, allowedPairs, maxHops])
}
import { Token } from '@uniswap/sdk-core'
import { SupportedChainId } from 'constants/chains'
import Vibrant from 'node-vibrant/lib/bundle'
import { shade } from 'polished'
import { useLayoutEffect, useState } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import uriToHttp from 'utils/uriToHttp'
import { hex } from 'wcag-contrast'
function URIForEthToken(address: string) {
return `https://raw.githubusercontent.com/uniswap/assets/master/blockchains/ethereum/assets/${address}/logo.png`
}
async function getColorFromToken(token: Token): Promise<string | null> {
if (!(token instanceof WrappedTokenInfo)) {
return null
}
const wrappedToken = token as WrappedTokenInfo
const { address } = wrappedToken
let { logoURI } = wrappedToken
if (!logoURI) {
if (token.chainId !== SupportedChainId.MAINNET) {
return null
} else {
logoURI = URIForEthToken(address)
}
}
try {
return await getColorFromUriPath(logoURI)
} catch (e) {
if (logoURI === URIForEthToken(address)) {
return null
}
try {
logoURI = URIForEthToken(address)
return await getColorFromUriPath(logoURI)
} catch (e) {}
}
return null
}
async function getColorFromUriPath(uri: string): Promise<string | null> {
const formattedPath = uriToHttp(uri)[0]
const palette = await Vibrant.from(formattedPath).getPalette()
if (!palette?.Vibrant) {
return null
}
let detectedHex = palette.Vibrant.hex
let AAscore = hex(detectedHex, '#FFF')
while (AAscore < 3) {
detectedHex = shade(0.005, detectedHex)
AAscore = hex(detectedHex, '#FFF')
}
return detectedHex
}
export function useColor(token?: Token) {
const [color, setColor] = useState('#2172E5')
useLayoutEffect(() => {
let stale = false
if (token) {
getColorFromToken(token).then((tokenColor) => {
if (!stale && tokenColor !== null) {
setColor(tokenColor)
}
})
}
return () => {
stale = true
setColor('#2172E5')
}
}, [token])
return color
}
export function useListColor(listImageUri?: string) {
const [color, setColor] = useState('#2172E5')
useLayoutEffect(() => {
let stale = false
if (listImageUri) {
getColorFromUriPath(listImageUri).then((color) => {
if (!stale && color !== null) {
setColor(color)
}
})
}
return () => {
stale = true
setColor('#2172E5')
}
}, [listImageUri])
return color
}
import { Contract } from '@ethersproject/contracts'
import { abi as GOVERNANCE_ABI } from '@uniswap/governance/build/GovernorAlpha.json'
import { abi as UNI_ABI } from '@uniswap/governance/build/Uni.json'
import { abi as STAKING_REWARDS_ABI } from '@uniswap/liquidity-staker/build/StakingRewards.json'
import { abi as MERKLE_DISTRIBUTOR_ABI } from '@uniswap/merkle-distributor/build/MerkleDistributor.json'
import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json'
import { abi as IUniswapV2Router02ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
import { abi as QuoterABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
import { abi as MulticallABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/UniswapInterfaceMulticall.sol/UniswapInterfaceMulticall.json'
import { abi as NFTPositionManagerABI } from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import { abi as V2MigratorABI } from '@uniswap/v3-periphery/artifacts/contracts/V3Migrator.sol/V3Migrator.json'
import ARGENT_WALLET_DETECTOR_ABI from 'abis/argent-wallet-detector.json'
import EIP_2612 from 'abis/eip_2612.json'
import ENS_PUBLIC_RESOLVER_ABI from 'abis/ens-public-resolver.json'
import ENS_ABI from 'abis/ens-registrar.json'
import ERC20_ABI from 'abis/erc20.json'
import ERC20_BYTES32_ABI from 'abis/erc20_bytes32.json'
import ERC721_ABI from 'abis/erc721.json'
import ERC1155_ABI from 'abis/erc1155.json'
import GOVERNOR_BRAVO_ABI from 'abis/governor-bravo.json'
import WETH_ABI from 'abis/weth.json'
import {
ARGENT_WALLET_DETECTOR_ADDRESS,
ENS_REGISTRAR_ADDRESSES,
GOVERNANCE_ALPHA_V0_ADDRESSES,
GOVERNANCE_ALPHA_V1_ADDRESSES,
GOVERNANCE_BRAVO_ADDRESSES,
MERKLE_DISTRIBUTOR_ADDRESS,
MULTICALL_ADDRESS,
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
QUOTER_ADDRESSES,
V2_ROUTER_ADDRESS,
V3_MIGRATOR_ADDRESSES,
} from 'constants/addresses'
import { useMemo } from 'react'
import { NonfungiblePositionManager, Quoter, UniswapInterfaceMulticall } from 'types/v3'
import { V3Migrator } from 'types/v3/V3Migrator'
import { getContract } from 'utils'
import { ArgentWalletDetector, EnsPublicResolver, EnsRegistrar, Erc20, Erc721, Erc1155, Weth } from '../abis/types'
import { UNI, WETH9_EXTENDED } from '../constants/tokens'
import { useActiveWeb3React } from './web3'
// returns null on errors
export function useContract<T extends Contract = Contract>(
addressOrAddressMap: string | { [chainId: number]: string } | undefined,
ABI: any,
withSignerIfPossible = true
): T | null {
const { library, account, chainId } = useActiveWeb3React()
return useMemo(() => {
if (!addressOrAddressMap || !ABI || !library || !chainId) return null
let address: string | undefined
if (typeof addressOrAddressMap === 'string') address = addressOrAddressMap
else address = addressOrAddressMap[chainId]
if (!address) return null
try {
return getContract(address, ABI, library, withSignerIfPossible && account ? account : undefined)
} catch (error) {
console.error('Failed to get contract', error)
return null
}
}, [addressOrAddressMap, ABI, library, chainId, withSignerIfPossible, account]) as T
}
export function useV2MigratorContract() {
return useContract<V3Migrator>(V3_MIGRATOR_ADDRESSES, V2MigratorABI, true)
}
export function useTokenContract(tokenAddress?: string, withSignerIfPossible?: boolean) {
return useContract<Erc20>(tokenAddress, ERC20_ABI, withSignerIfPossible)
}
export function useWETHContract(withSignerIfPossible?: boolean) {
const { chainId } = useActiveWeb3React()
return useContract<Weth>(chainId ? WETH9_EXTENDED[chainId]?.address : undefined, WETH_ABI, withSignerIfPossible)
}
export function useERC721Contract(nftAddress?: string) {
return useContract<Erc721>(nftAddress, ERC721_ABI, false)
}
export function useERC1155Contract(nftAddress?: string) {
return useContract<Erc1155>(nftAddress, ERC1155_ABI, false)
}
export function useArgentWalletDetectorContract() {
return useContract<ArgentWalletDetector>(ARGENT_WALLET_DETECTOR_ADDRESS, ARGENT_WALLET_DETECTOR_ABI, false)
}
export function useENSRegistrarContract(withSignerIfPossible?: boolean) {
return useContract<EnsRegistrar>(ENS_REGISTRAR_ADDRESSES, ENS_ABI, withSignerIfPossible)
}
export function useENSResolverContract(address: string | undefined, withSignerIfPossible?: boolean) {
return useContract<EnsPublicResolver>(address, ENS_PUBLIC_RESOLVER_ABI, withSignerIfPossible)
}
export function useBytes32TokenContract(tokenAddress?: string, withSignerIfPossible?: boolean): Contract | null {
return useContract(tokenAddress, ERC20_BYTES32_ABI, withSignerIfPossible)
}
export function useEIP2612Contract(tokenAddress?: string): Contract | null {
return useContract(tokenAddress, EIP_2612, false)
}
export function usePairContract(pairAddress?: string, withSignerIfPossible?: boolean): Contract | null {
return useContract(pairAddress, IUniswapV2PairABI, withSignerIfPossible)
}
export function useV2RouterContract(): Contract | null {
return useContract(V2_ROUTER_ADDRESS, IUniswapV2Router02ABI, true)
}
export function useMulticall2Contract() {
return useContract<UniswapInterfaceMulticall>(MULTICALL_ADDRESS, MulticallABI, false) as UniswapInterfaceMulticall
}
export function useMerkleDistributorContract() {
return useContract(MERKLE_DISTRIBUTOR_ADDRESS, MERKLE_DISTRIBUTOR_ABI, true)
}
export function useGovernanceV0Contract(): Contract | null {
return useContract(GOVERNANCE_ALPHA_V0_ADDRESSES, GOVERNANCE_ABI, false)
}
export function useGovernanceV1Contract(): Contract | null {
return useContract(GOVERNANCE_ALPHA_V1_ADDRESSES, GOVERNANCE_ABI, false)
}
export function useGovernanceBravoContract(): Contract | null {
return useContract(GOVERNANCE_BRAVO_ADDRESSES, GOVERNOR_BRAVO_ABI, true)
}
export const useLatestGovernanceContract = useGovernanceBravoContract
export function useUniContract() {
const { chainId } = useActiveWeb3React()
return useContract(chainId ? UNI[chainId]?.address : undefined, UNI_ABI, true)
}
export function useStakingContract(stakingAddress?: string, withSignerIfPossible?: boolean) {
return useContract(stakingAddress, STAKING_REWARDS_ABI, withSignerIfPossible)
}
export function useV3NFTPositionManagerContract(withSignerIfPossible?: boolean): NonfungiblePositionManager | null {
return useContract<NonfungiblePositionManager>(
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
NFTPositionManagerABI,
withSignerIfPossible
)
}
export function useV3Quoter() {
return useContract<Quoter>(QUOTER_ADDRESSES, QuoterABI)
}
import copy from 'copy-to-clipboard'
import { useCallback, useEffect, useState } from 'react'
export default function useCopyClipboard(timeout = 500): [boolean, (toCopy: string) => void] {
const [isCopied, setIsCopied] = useState(false)
const staticCopy = useCallback((text) => {
const didCopy = copy(text)
setIsCopied(didCopy)
}, [])
useEffect(() => {
if (isCopied) {
const hide = setTimeout(() => {
setIsCopied(false)
}, timeout)
return () => {
clearTimeout(hide)
}
}
return undefined
}, [isCopied, setIsCopied, timeout])
return [isCopied, staticCopy]
}
import { BigNumber } from '@ethersproject/bignumber'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useMulticall2Contract } from './useContract'
// gets the current timestamp from the blockchain
export default function useCurrentBlockTimestamp(): BigNumber | undefined {
const multicall = useMulticall2Contract()
return useSingleCallResult(multicall, 'getCurrentBlockTimestamp')?.result?.[0]
}
import { useEffect, useState } from 'react'
// modified from https://usehooks.com/useDebounce/
export default function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
// Update debounced value after delay
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
// Cancel the timeout if value changes (also on delay change or unmount)
// This is how we prevent debounced value from updating if value is changed ...
// .. within the delay period. Timeout gets cleared and restarted.
return () => {
clearTimeout(handler)
}
}, [value, delay])
return debouncedValue
}
import { useCallback, useEffect, useRef, useState } from 'react'
/**
* Easy way to debounce the handling of a rapidly changing value, e.g. a changing slider input
* @param value value that is rapidly changing
* @param onChange change handler that should receive the debounced updates to the value
* @param debouncedMs how long we should wait for changes to be applied
*/
export default function useDebouncedChangeHandler<T>(
value: T,
onChange: (newValue: T) => void,
debouncedMs = 100
): [T, (value: T) => void] {
const [inner, setInner] = useState<T>(() => value)
const timer = useRef<ReturnType<typeof setTimeout>>()
const onChangeInner = useCallback(
(newValue: T) => {
setInner(newValue)
if (timer.current) {
clearTimeout(timer.current)
}
timer.current = setTimeout(() => {
onChange(newValue)
timer.current = undefined
}, debouncedMs)
},
[debouncedMs, onChange]
)
useEffect(() => {
if (timer.current) {
clearTimeout(timer.current)
timer.current = undefined
}
setInner(value)
}, [value])
return [inner, onChangeInner]
}
import { Pool, Position } from '@uniswap/v3-sdk'
import { usePool } from 'hooks/usePools'
import { PositionDetails } from 'types/position'
import { useCurrency } from './Tokens'
export function useDerivedPositionInfo(positionDetails: PositionDetails | undefined): {
position: Position | undefined
pool: Pool | undefined
} {
const currency0 = useCurrency(positionDetails?.token0)
const currency1 = useCurrency(positionDetails?.token1)
// construct pool data
const [, pool] = usePool(currency0 ?? undefined, currency1 ?? undefined, positionDetails?.fee)
let position = undefined
if (pool && positionDetails) {
position = new Position({
pool,
liquidity: positionDetails.liquidity.toString(),
tickLower: positionDetails.tickLower,
tickUpper: positionDetails.tickUpper,
})
}
return {
position,
pool: pool ?? undefined,
}
}
import { isAddress } from '../utils'
import useENSAddress from './useENSAddress'
import useENSName from './useENSName'
/**
* Given a name or address, does a lookup to resolve to an address and name
* @param nameOrAddress ENS name or address
*/
export default function useENS(nameOrAddress?: string | null): {
loading: boolean
address: string | null
name: string | null
} {
const validated = isAddress(nameOrAddress)
const reverseLookup = useENSName(validated ? validated : undefined)
const lookup = useENSAddress(nameOrAddress)
return {
loading: reverseLookup.loading || lookup.loading,
address: validated ? validated : lookup.address,
name: reverseLookup.ENSName ? reverseLookup.ENSName : !validated && lookup.address ? nameOrAddress || null : null,
}
}
import { namehash } from '@ethersproject/hash'
import { useMemo } from 'react'
import { useSingleCallResult } from '../state/multicall/hooks'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract'
import useDebounce from './useDebounce'
/**
* Does a lookup for an ENS name to find its address.
*/
export default function useENSAddress(ensName?: string | null): { loading: boolean; address: string | null } {
const debouncedName = useDebounce(ensName, 200)
const ensNodeArgument = useMemo(() => {
if (!debouncedName) return [undefined]
try {
return debouncedName ? [namehash(debouncedName)] : [undefined]
} catch (error) {
return [undefined]
}
}, [debouncedName])
const registrarContract = useENSRegistrarContract(false)
const resolverAddress = useSingleCallResult(registrarContract, 'resolver', ensNodeArgument)
const resolverAddressResult = resolverAddress.result?.[0]
const resolverContract = useENSResolverContract(
resolverAddressResult && !isZero(resolverAddressResult) ? resolverAddressResult : undefined,
false
)
const addr = useSingleCallResult(resolverContract, 'addr', ensNodeArgument)
const changed = debouncedName !== ensName
return {
address: changed ? null : addr.result?.[0] ?? null,
loading: changed || resolverAddress.loading || addr.loading,
}
}
import { namehash } from '@ethersproject/hash'
import { useEffect, useMemo, useState } from 'react'
import uriToHttp from 'utils/uriToHttp'
import { useSingleCallResult } from '../state/multicall/hooks'
import { isAddress } from '../utils'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract, useERC721Contract, useERC1155Contract } from './useContract'
import useDebounce from './useDebounce'
import useENSName from './useENSName'
import { useActiveWeb3React } from './web3'
/**
* Returns the ENS avatar URI, if available.
* Spec: https://gist.github.com/Arachnid/9db60bd75277969ee1689c8742b75182.
*/
export default function useENSAvatar(
address?: string,
enforceOwnership = true
): { avatar: string | null; loading: boolean } {
const debouncedAddress = useDebounce(address, 200)
const node = useMemo(() => {
if (!debouncedAddress || !isAddress(debouncedAddress)) return undefined
try {
return debouncedAddress ? namehash(`${debouncedAddress.toLowerCase().substr(2)}.addr.reverse`) : undefined
} catch (error) {
return undefined
}
}, [debouncedAddress])
const addressAvatar = useAvatarFromNode(node)
const nameAvatar = useAvatarFromNode(namehash(useENSName(address).ENSName ?? ''))
let avatar = addressAvatar.avatar || nameAvatar.avatar
const nftAvatar = useAvatarFromNFT(avatar, enforceOwnership)
avatar = nftAvatar.avatar || avatar
const http = avatar && uriToHttp(avatar)[0]
const changed = debouncedAddress !== address
return {
avatar: changed ? null : http ?? null,
loading: changed || addressAvatar.loading || nameAvatar.loading || nftAvatar.loading,
}
}
function useAvatarFromNode(node?: string): { avatar?: string; loading: boolean } {
const nodeArgument = useMemo(() => [node], [node])
const textArgument = useMemo(() => [node, 'avatar'], [node])
const registrarContract = useENSRegistrarContract(false)
const resolverAddress = useSingleCallResult(registrarContract, 'resolver', nodeArgument)
const resolverAddressResult = resolverAddress.result?.[0]
const resolverContract = useENSResolverContract(
resolverAddressResult && !isZero(resolverAddressResult) ? resolverAddressResult : undefined,
false
)
const avatar = useSingleCallResult(resolverContract, 'text', textArgument)
return {
avatar: avatar.result?.[0],
loading: resolverAddress.loading || avatar.loading,
}
}
function useAvatarFromNFT(nftUri = '', enforceOwnership: boolean): { avatar?: string; loading: boolean } {
const parts = nftUri.toLowerCase().split(':')
const protocol = parts[0]
// ignore the chain from eip155
// TODO: when we are able, pull only from the specified chain
const [, erc] = parts[1]?.split('/') ?? []
const [contractAddress, id] = parts[2]?.split('/') ?? []
const isERC721 = protocol === 'eip155' && erc === 'erc721'
const isERC1155 = protocol === 'eip155' && erc === 'erc1155'
const erc721 = useERC721Uri(isERC721 ? contractAddress : undefined, id, enforceOwnership)
const erc1155 = useERC1155Uri(isERC1155 ? contractAddress : undefined, id, enforceOwnership)
const uri = erc721.uri || erc1155.uri
const http = uri && uriToHttp(uri)[0]
const [loading, setLoading] = useState(false)
const [avatar, setAvatar] = useState(undefined)
useEffect(() => {
setAvatar(undefined)
if (http) {
setLoading(true)
fetch(http)
.then((res) => res.json())
.then(({ image }) => {
setAvatar(image)
})
.catch((e) => console.warn(e))
.finally(() => {
setLoading(false)
})
}
}, [http])
return { avatar, loading: erc721.loading || erc1155.loading || loading }
}
function useERC721Uri(
contractAddress: string | undefined,
id: string | undefined,
enforceOwnership: boolean
): { uri?: string; loading: boolean } {
const idArgument = useMemo(() => [id], [id])
const { account } = useActiveWeb3React()
const contract = useERC721Contract(contractAddress)
const owner = useSingleCallResult(contract, 'ownerOf', idArgument)
const uri = useSingleCallResult(contract, 'tokenURI', idArgument)
return {
uri: !enforceOwnership || account === owner.result?.[0] ? uri.result?.[0] : undefined,
loading: owner.loading || uri.loading,
}
}
function useERC1155Uri(
contractAddress: string | undefined,
id: string | undefined,
enforceOwnership: boolean
): { uri?: string; loading: boolean } {
const { account } = useActiveWeb3React()
const idArgument = useMemo(() => [id], [id])
const accountArgument = useMemo(() => [account || '', id], [account, id])
const contract = useERC1155Contract(contractAddress)
const balance = useSingleCallResult(contract, 'balanceOf', accountArgument)
const uri = useSingleCallResult(contract, 'uri', idArgument)
return {
uri: !enforceOwnership || balance.result?.[0] > 0 ? uri.result?.[0] : undefined,
loading: balance.loading || uri.loading,
}
}
import { namehash } from '@ethersproject/hash'
import { useMemo } from 'react'
import { useSingleCallResult } from '../state/multicall/hooks'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract'
/**
* Does a lookup for an ENS name to find its contenthash.
*/
export default function useENSContentHash(ensName?: string | null): { loading: boolean; contenthash: string | null } {
const ensNodeArgument = useMemo(() => {
if (!ensName) return [undefined]
try {
return ensName ? [namehash(ensName)] : [undefined]
} catch (error) {
return [undefined]
}
}, [ensName])
const registrarContract = useENSRegistrarContract(false)
const resolverAddressResult = useSingleCallResult(registrarContract, 'resolver', ensNodeArgument)
const resolverAddress = resolverAddressResult.result?.[0]
const resolverContract = useENSResolverContract(
resolverAddress && isZero(resolverAddress) ? undefined : resolverAddress,
false
)
const contenthash = useSingleCallResult(resolverContract, 'contenthash', ensNodeArgument)
return {
contenthash: contenthash.result?.[0] ?? null,
loading: resolverAddressResult.loading || contenthash.loading,
}
}
import { namehash } from '@ethersproject/hash'
import { useMemo } from 'react'
import { useSingleCallResult } from '../state/multicall/hooks'
import { isAddress } from '../utils'
import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract'
import useDebounce from './useDebounce'
/**
* Does a reverse lookup for an address to find its ENS name.
* Note this is not the same as looking up an ENS name to find an address.
*/
export default function useENSName(address?: string): { ENSName: string | null; loading: boolean } {
const debouncedAddress = useDebounce(address, 200)
const ensNodeArgument = useMemo(() => {
if (!debouncedAddress || !isAddress(debouncedAddress)) return [undefined]
try {
return debouncedAddress ? [namehash(`${debouncedAddress.toLowerCase().substr(2)}.addr.reverse`)] : [undefined]
} catch (error) {
return [undefined]
}
}, [debouncedAddress])
const registrarContract = useENSRegistrarContract(false)
const resolverAddress = useSingleCallResult(registrarContract, 'resolver', ensNodeArgument)
const resolverAddressResult = resolverAddress.result?.[0]
const resolverContract = useENSResolverContract(
resolverAddressResult && !isZero(resolverAddressResult) ? resolverAddressResult : undefined,
false
)
const name = useSingleCallResult(resolverContract, 'name', ensNodeArgument)
const changed = debouncedAddress !== address
return {
ENSName: changed ? null : name.result?.[0] ?? null,
loading: changed || resolverAddress.loading || name.loading,
}
}
......@@ -34,23 +34,23 @@ const PERMITTABLE_TOKENS: {
[checksummedTokenAddress: string]: PermitInfo
}
} = {
[1]: {
1: {
[USDC.address]: { type: PermitType.AMOUNT, name: 'USD Coin', version: '2' },
[DAI.address]: { type: PermitType.ALLOWED, name: 'Dai Stablecoin', version: '1' },
[UNI[1].address]: { type: PermitType.AMOUNT, name: 'Uniswap' },
},
[4]: {
['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735']: { type: PermitType.ALLOWED, name: 'Dai Stablecoin', version: '1' },
4: {
'0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735': { type: PermitType.ALLOWED, name: 'Dai Stablecoin', version: '1' },
[UNI[4].address]: { type: PermitType.AMOUNT, name: 'Uniswap' },
},
[3]: {
3: {
[UNI[3].address]: { type: PermitType.AMOUNT, name: 'Uniswap' },
['0x07865c6E87B9F70255377e024ace6630C1Eaa37F']: { type: PermitType.AMOUNT, name: 'USD Coin', version: '2' },
'0x07865c6E87B9F70255377e024ace6630C1Eaa37F': { type: PermitType.AMOUNT, name: 'USD Coin', version: '2' },
},
[5]: {
5: {
[UNI[5].address]: { type: PermitType.AMOUNT, name: 'Uniswap' },
},
[42]: {
42: {
[UNI[42].address]: { type: PermitType.AMOUNT, name: 'Uniswap' },
},
}
......
import { skipToken } from '@reduxjs/toolkit/query/react'
import { Currency, Token } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import ms from 'ms.macro'
import { useMemo } from 'react'
import ReactGA from 'react-ga'
import { useBlockNumber } from 'state/application/hooks'
import { useFeeTierDistributionQuery } from 'state/data/enhanced'
import { FeeTierDistributionQuery } from 'state/data/generated'
import { PoolState, usePool } from './usePools'
// maximum number of blocks past which we consider the data stale
const MAX_DATA_BLOCK_AGE = 20
interface FeeTierDistribution {
isLoading: boolean
isError: boolean
largestUsageFeeTier?: FeeAmount | undefined
// distributions as percentages of overall liquidity
distributions?: Record<FeeAmount, number | undefined>
}
export function useFeeTierDistribution(
currencyA: Currency | undefined,
currencyB: Currency | undefined
): FeeTierDistribution {
const { isFetching, isLoading, isUninitialized, isError, distributions } = usePoolTVL(
currencyA?.wrapped,
currencyB?.wrapped
)
// fetch all pool states to determine pool state
const [poolStateVeryLow] = usePool(currencyA, currencyB, FeeAmount.LOWEST)
const [poolStateLow] = usePool(currencyA, currencyB, FeeAmount.LOW)
const [poolStateMedium] = usePool(currencyA, currencyB, FeeAmount.MEDIUM)
const [poolStateHigh] = usePool(currencyA, currencyB, FeeAmount.HIGH)
return useMemo(() => {
if (isLoading || isFetching || isUninitialized || isError || !distributions) {
return {
isLoading: isLoading || isFetching || !isUninitialized,
isError,
distributions,
}
}
const largestUsageFeeTier = Object.keys(distributions)
.map((d) => Number(d))
.filter((d: FeeAmount) => distributions[d] !== 0 && distributions[d] !== undefined)
.reduce((a: FeeAmount, b: FeeAmount) => ((distributions[a] ?? 0) > (distributions[b] ?? 0) ? a : b), -1)
const percentages =
!isLoading &&
!isError &&
distributions &&
poolStateVeryLow !== PoolState.LOADING &&
poolStateLow !== PoolState.LOADING &&
poolStateMedium !== PoolState.LOADING &&
poolStateHigh !== PoolState.LOADING
? {
[FeeAmount.LOWEST]:
poolStateVeryLow === PoolState.EXISTS ? (distributions[FeeAmount.LOWEST] ?? 0) * 100 : undefined,
[FeeAmount.LOW]: poolStateLow === PoolState.EXISTS ? (distributions[FeeAmount.LOW] ?? 0) * 100 : undefined,
[FeeAmount.MEDIUM]:
poolStateMedium === PoolState.EXISTS ? (distributions[FeeAmount.MEDIUM] ?? 0) * 100 : undefined,
[FeeAmount.HIGH]:
poolStateHigh === PoolState.EXISTS ? (distributions[FeeAmount.HIGH] ?? 0) * 100 : undefined,
}
: undefined
return {
isLoading,
isError,
distributions: percentages,
largestUsageFeeTier: largestUsageFeeTier === -1 ? undefined : largestUsageFeeTier,
}
}, [
isLoading,
isFetching,
isUninitialized,
isError,
distributions,
poolStateVeryLow,
poolStateLow,
poolStateMedium,
poolStateHigh,
])
}
function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
const latestBlock = useBlockNumber()
const { isLoading, isFetching, isUninitialized, isError, data } = useFeeTierDistributionQuery(
token0 && token1 ? { token0: token0.address.toLowerCase(), token1: token1.address.toLowerCase() } : skipToken,
{
pollingInterval: ms`30s`,
}
)
const { asToken0, asToken1, _meta } = (data as FeeTierDistributionQuery) ?? {}
return useMemo(() => {
if (!latestBlock || !_meta || !asToken0 || !asToken1) {
return {
isLoading,
isFetching,
isUninitialized,
isError,
}
}
if (latestBlock - (_meta?.block?.number ?? 0) > MAX_DATA_BLOCK_AGE) {
ReactGA.exception({
description: `Graph stale (latest block: ${latestBlock})`,
})
return {
isLoading,
isFetching,
isUninitialized,
isError,
}
}
const all = asToken0.concat(asToken1)
// sum tvl for token0 and token1 by fee tier
const tvlByFeeTier = all.reduce<{ [feeAmount: number]: [number | undefined, number | undefined] }>(
(acc, value) => {
acc[value.feeTier][0] = (acc[value.feeTier][0] ?? 0) + Number(value.totalValueLockedToken0)
acc[value.feeTier][1] = (acc[value.feeTier][1] ?? 0) + Number(value.totalValueLockedToken1)
return acc
},
{
[FeeAmount.LOWEST]: [undefined, undefined],
[FeeAmount.LOW]: [undefined, undefined],
[FeeAmount.MEDIUM]: [undefined, undefined],
[FeeAmount.HIGH]: [undefined, undefined],
} as Record<FeeAmount, [number | undefined, number | undefined]>
)
// sum total tvl for token0 and token1
const [sumToken0Tvl, sumToken1Tvl] = Object.values(tvlByFeeTier).reduce(
(acc: [number, number], value) => {
acc[0] += value[0] ?? 0
acc[1] += value[1] ?? 0
return acc
},
[0, 0]
)
// returns undefined if both tvl0 and tvl1 are undefined (pool not created)
const mean = (tvl0: number | undefined, sumTvl0: number, tvl1: number | undefined, sumTvl1: number) =>
tvl0 === undefined && tvl1 === undefined ? undefined : ((tvl0 ?? 0) + (tvl1 ?? 0)) / (sumTvl0 + sumTvl1) || 0
const distributions: Record<FeeAmount, number | undefined> = {
[FeeAmount.LOWEST]: mean(
tvlByFeeTier[FeeAmount.LOWEST][0],
sumToken0Tvl,
tvlByFeeTier[FeeAmount.LOWEST][1],
sumToken1Tvl
),
[FeeAmount.LOW]: mean(tvlByFeeTier[FeeAmount.LOW][0], sumToken0Tvl, tvlByFeeTier[FeeAmount.LOW][1], sumToken1Tvl),
[FeeAmount.MEDIUM]: mean(
tvlByFeeTier[FeeAmount.MEDIUM][0],
sumToken0Tvl,
tvlByFeeTier[FeeAmount.MEDIUM][1],
sumToken1Tvl
),
[FeeAmount.HIGH]: mean(
tvlByFeeTier[FeeAmount.HIGH][0],
sumToken0Tvl,
tvlByFeeTier[FeeAmount.HIGH][1],
sumToken1Tvl
),
}
return {
isLoading,
isFetching,
isUninitialized,
isError,
distributions,
}
}, [_meta, asToken0, asToken1, isLoading, isError, isFetching, isUninitialized, latestBlock])
}
import { nanoid } from '@reduxjs/toolkit'
import { TokenList } from '@uniswap/token-lists'
import { useCallback } from 'react'
import { useAppDispatch } from 'state/hooks'
import { getNetworkLibrary } from '../connectors'
import { fetchTokenList } from '../state/lists/actions'
import getTokenList from '../utils/getTokenList'
import resolveENSContentHash from '../utils/resolveENSContentHash'
import { useActiveWeb3React } from './web3'
export function useFetchListCallback(): (listUrl: string, sendDispatch?: boolean) => Promise<TokenList> {
const { chainId, library } = useActiveWeb3React()
const dispatch = useAppDispatch()
const ensResolver = useCallback(
async (ensName: string) => {
if (!library || chainId !== 1) {
const networkLibrary = getNetworkLibrary()
const network = await networkLibrary.getNetwork()
if (networkLibrary && network.chainId === 1) {
return resolveENSContentHash(ensName, networkLibrary)
}
throw new Error('Could not construct mainnet ENS resolver')
}
return resolveENSContentHash(ensName, library)
},
[chainId, library]
)
// note: prevent dispatch if using for list search or unsupported list
return useCallback(
async (listUrl: string, sendDispatch = true) => {
const requestId = nanoid()
sendDispatch && dispatch(fetchTokenList.pending({ requestId, url: listUrl }))
return getTokenList(listUrl, ensResolver)
.then((tokenList) => {
sendDispatch && dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId }))
return tokenList
})
.catch((error) => {
console.debug(`Failed to get list at url ${listUrl}`, error)
sendDispatch && dispatch(fetchTokenList.rejected({ url: listUrl, requestId, errorMessage: error.message }))
throw error
})
},
[dispatch, ensResolver]
)
}
import JSBI from 'jsbi'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useContract } from './useContract'
import useENSAddress from './useENSAddress'
const CHAIN_DATA_ABI = [
{
inputs: [],
name: 'latestAnswer',
outputs: [{ internalType: 'int256', name: '', type: 'int256' }],
stateMutability: 'view',
type: 'function',
},
]
/**
* Returns the price of 1 gas in WEI for the currently selected network using the chainlink fast gas price oracle
*/
export default function useGasPrice(): JSBI | undefined {
const { address } = useENSAddress('fast-gas-gwei.data.eth')
const contract = useContract(address ?? undefined, CHAIN_DATA_ABI, false)
const resultStr = useSingleCallResult(contract, 'latestAnswer').result?.[0]?.toString()
return typeof resultStr === 'string' ? JSBI.BigInt(resultStr) : undefined
}
import { useMemo } from 'react'
import contenthashToUri from '../utils/contenthashToUri'
import { parseENSAddress } from '../utils/parseENSAddress'
import uriToHttp from '../utils/uriToHttp'
import useENSContentHash from './useENSContentHash'
export default function useHttpLocations(uri: string | undefined): string[] {
const ens = useMemo(() => (uri ? parseENSAddress(uri) : undefined), [uri])
const resolvedContentHash = useENSContentHash(ens?.ensName)
return useMemo(() => {
if (ens) {
return resolvedContentHash.contenthash ? uriToHttp(contenthashToUri(resolvedContentHash.contenthash)) : []
} else {
return uri ? uriToHttp(uri) : []
}
}, [ens, resolvedContentHash.contenthash, uri])
}
import { useEffect, useRef } from 'react'
export default function useInterval(callback: () => void, delay: null | number, leading = true) {
const savedCallback = useRef<() => void>()
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback
}, [callback])
// Set up the interval.
useEffect(() => {
function tick() {
const current = savedCallback.current
current && current()
}
if (delay !== null) {
if (leading) tick()
const id = setInterval(tick, delay)
return () => clearInterval(id)
}
return undefined
}, [delay, leading])
}
import { useMemo } from 'react'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useArgentWalletDetectorContract } from './useContract'
import { useActiveWeb3React } from './web3'
export default function useIsArgentWallet(): boolean {
const { account } = useActiveWeb3React()
const argentWalletDetector = useArgentWalletDetectorContract()
const inputs = useMemo(() => [account ?? undefined], [account])
const call = useSingleCallResult(argentWalletDetector, 'isArgentWallet', inputs, NEVER_RELOAD)
return call?.result?.[0] ?? false
}
import { Currency } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { useUnsupportedTokens } from './Tokens'
/**
* Returns true if the input currency or output currency cannot be traded in the interface
* @param currencyIn the input currency to check
* @param currencyOut the output currency to check
*/
export function useIsSwapUnsupported(currencyIn?: Currency | null, currencyOut?: Currency | null): boolean {
const unsupportedTokens = useUnsupportedTokens()
return useMemo(() => {
if (!unsupportedTokens) {
return false
}
const currencyInUnsupported = Boolean(currencyIn?.isToken && unsupportedTokens[currencyIn.address])
const currencyOutUnsupported = Boolean(currencyOut?.isToken && unsupportedTokens[currencyOut.address])
return currencyInUnsupported || currencyOutUnsupported
}, [currencyIn, currencyOut, unsupportedTokens])
}
import { FeeAmount, nearestUsableTick, TICK_SPACINGS, TickMath } from '@uniswap/v3-sdk'
import { useMemo } from 'react'
import { Bound } from 'state/mint/v3/actions'
export default function useIsTickAtLimit(
feeAmount: FeeAmount | undefined,
tickLower: number | undefined,
tickUpper: number | undefined
) {
return useMemo(
() => ({
[Bound.LOWER]:
feeAmount && tickLower
? tickLower === nearestUsableTick(TickMath.MIN_TICK, TICK_SPACINGS[feeAmount as FeeAmount])
: undefined,
[Bound.UPPER]:
feeAmount && tickUpper
? tickUpper === nearestUsableTick(TickMath.MAX_TICK, TICK_SPACINGS[feeAmount as FeeAmount])
: undefined,
}),
[feeAmount, tickLower, tickUpper]
)
}
import { useCallback, useEffect, useState } from 'react'
const VISIBILITY_STATE_SUPPORTED = 'visibilityState' in document
function isWindowVisible() {
return !VISIBILITY_STATE_SUPPORTED || document.visibilityState !== 'hidden'
}
/**
* Returns whether the window is currently visible to the user.
*/
export default function useIsWindowVisible(): boolean {
const [focused, setFocused] = useState<boolean>(isWindowVisible())
const listener = useCallback(() => {
setFocused(isWindowVisible())
}, [setFocused])
useEffect(() => {
if (!VISIBILITY_STATE_SUPPORTED) return undefined
document.addEventListener('visibilitychange', listener)
return () => {
document.removeEventListener('visibilitychange', listener)
}
}, [listener])
return focused
}
import { useEffect, useState } from 'react'
/**
* Returns the last value of type T that passes a filter function
* @param value changing value
* @param filterFn function that determines whether a given value should be considered for the last value
*/
export default function useLast<T>(
value: T | undefined | null,
filterFn?: (value: T | null | undefined) => boolean
): T | null | undefined {
const [last, setLast] = useState<T | null | undefined>(filterFn && filterFn(value) ? value : undefined)
useEffect(() => {
setLast((last) => {
const shouldUse: boolean = filterFn ? filterFn(value) : true
if (shouldUse) return value
return last
})
}, [filterFn, value])
return last
}
import { SupportedLocale } from 'constants/locales'
import { LocationDescriptor } from 'history'
import useParsedQueryString from 'hooks/useParsedQueryString'
import { stringify } from 'qs'
import { useMemo } from 'react'
import ReactGA from 'react-ga'
import { useLocation } from 'react-router-dom'
import { useActiveLocale } from './useActiveLocale'
export function useLocationLinkProps(locale: SupportedLocale | null): {
to?: LocationDescriptor
onClick?: () => void
} {
const location = useLocation()
const qs = useParsedQueryString()
const activeLocale = useActiveLocale()
return useMemo(
() =>
!locale
? {}
: {
to: {
...location,
search: stringify({ ...qs, lng: locale }),
},
onClick: () => {
ReactGA.event({
category: 'Localization',
action: 'Switch Locale',
label: `${activeLocale} -> ${locale}`,
})
},
},
[location, qs, activeLocale, locale]
)
}
import { useState } from 'react'
import useInterval from './useInterval'
const useMachineTimeMs = (updateInterval: number): number => {
const [now, setNow] = useState(Date.now())
useInterval(() => {
setNow(Date.now())
}, updateInterval)
return now
}
export default useMachineTimeMs
import { TransactionResponse } from '@ethersproject/providers'
import { initializeApp } from 'firebase/app'
import { getDatabase, push, ref } from 'firebase/database'
import { useCallback } from 'react'
import { TransactionInfo, TransactionType } from 'state/transactions/actions'
import { useActiveWeb3React } from './web3'
type PartialTransactionResponse = Pick<TransactionResponse, 'hash' | 'v' | 'r' | 's'>
const SUPPORTED_TRANSACTION_TYPES = [
TransactionType.ADD_LIQUIDITY_V2_POOL,
TransactionType.ADD_LIQUIDITY_V3_POOL,
TransactionType.CREATE_V3_POOL,
TransactionType.REMOVE_LIQUIDITY_V3,
TransactionType.SWAP,
]
const FIREBASE_API_KEY = process.env.REACT_APP_FIREBASE_KEY
const firebaseEnabled = typeof FIREBASE_API_KEY !== 'undefined'
if (firebaseEnabled) initializeFirebase()
function useMonitoringEventCallback() {
const { chainId } = useActiveWeb3React()
return useCallback(
async function log(
type: string,
{
transactionResponse,
walletAddress,
}: { transactionResponse: PartialTransactionResponse; walletAddress: string | undefined }
) {
if (!firebaseEnabled) return
const db = getDatabase()
if (!walletAddress) {
console.debug('Wallet address required to log monitoring events.')
return
}
try {
push(ref(db, 'trm'), {
chainId,
origin: window.location.origin,
timestamp: Date.now(),
tx: transactionResponse,
type,
walletAddress,
})
} catch (e) {
console.debug('Error adding document: ', e)
}
},
[chainId]
)
}
export function useTransactionMonitoringEventCallback() {
const { account } = useActiveWeb3React()
const log = useMonitoringEventCallback()
return useCallback(
(info: TransactionInfo, transactionResponse: TransactionResponse) => {
if (SUPPORTED_TRANSACTION_TYPES.includes(info.type)) {
log(TransactionType[info.type], {
transactionResponse: (({ hash, v, r, s }: PartialTransactionResponse) => ({ hash, v, r, s }))(
transactionResponse
),
walletAddress: account ?? undefined,
})
}
},
[account, log]
)
}
export function useWalletConnectMonitoringEventCallback() {
const log = useMonitoringEventCallback()
return useCallback(
(walletAddress) => {
log('WALLET_CONNECTED', { transactionResponse: { hash: '', r: '', s: '', v: -1 }, walletAddress })
},
[log]
)
}
function initializeFirebase() {
initializeApp({
apiKey: process.env.REACT_APP_FIREBASE_KEY,
authDomain: 'interface-monitoring.firebaseapp.com',
databaseURL: 'https://interface-monitoring-default-rtdb.firebaseio.com',
projectId: 'interface-monitoring',
storageBucket: 'interface-monitoring.appspot.com',
messagingSenderId: '968187720053',
appId: '1:968187720053:web:acedf72dce629d470be33c',
})
}
import { RefObject, useEffect, useRef } from 'react'
export function useOnClickOutside<T extends HTMLElement>(
node: RefObject<T | undefined>,
handler: undefined | (() => void)
) {
const handlerRef = useRef<undefined | (() => void)>(handler)
useEffect(() => {
handlerRef.current = handler
}, [handler])
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
if (node.current?.contains(e.target as Node) ?? false) {
return
}
if (handlerRef.current) handlerRef.current()
}
document.addEventListener('mousedown', handleClickOutside)
return () => {
document.removeEventListener('mousedown', handleClickOutside)
}
}, [node])
}
import { parse, ParsedQs } from 'qs'
import { useMemo } from 'react'
import { useLocation } from 'react-router-dom'
export function parsedQueryString(search?: string): ParsedQs {
if (!search) {
// react-router-dom places search string in the hash
const hash = window.location.hash
search = hash.substr(hash.indexOf('?'))
}
return search && search.length > 1 ? parse(search, { parseArrays: false, ignoreQueryPrefix: true }) : {}
}
export default function useParsedQueryString(): ParsedQs {
const { search } = useLocation()
return useMemo(() => parsedQueryString(search), [search])
}
import { skipToken } from '@reduxjs/toolkit/query/react'
import { Currency } from '@uniswap/sdk-core'
import { FeeAmount, Pool, TICK_SPACINGS, tickToPrice } from '@uniswap/v3-sdk'
import JSBI from 'jsbi'
import ms from 'ms.macro'
import { useMemo } from 'react'
import { useAllV3TicksQuery } from 'state/data/enhanced'
import { AllV3TicksQuery } from 'state/data/generated'
import computeSurroundingTicks from 'utils/computeSurroundingTicks'
import { PoolState, usePool } from './usePools'
const PRICE_FIXED_DIGITS = 8
// Tick with fields parsed to JSBIs, and active liquidity computed.
export interface TickProcessed {
tickIdx: number
liquidityActive: JSBI
liquidityNet: JSBI
price0: string
}
const getActiveTick = (tickCurrent: number | undefined, feeAmount: FeeAmount | undefined) =>
tickCurrent && feeAmount ? Math.floor(tickCurrent / TICK_SPACINGS[feeAmount]) * TICK_SPACINGS[feeAmount] : undefined
// Fetches all ticks for a given pool
export function useAllV3Ticks(
currencyA: Currency | undefined,
currencyB: Currency | undefined,
feeAmount: FeeAmount | undefined
) {
const poolAddress =
currencyA && currencyB && feeAmount ? Pool.getAddress(currencyA?.wrapped, currencyB?.wrapped, feeAmount) : undefined
const { isLoading, isError, error, isUninitialized, data } = useAllV3TicksQuery(
poolAddress ? { poolAddress: poolAddress?.toLowerCase(), skip: 0 } : skipToken,
{
pollingInterval: ms`30s`,
}
)
return {
isLoading,
isUninitialized,
isError,
error,
ticks: data?.ticks as AllV3TicksQuery['ticks'],
}
}
export function usePoolActiveLiquidity(
currencyA: Currency | undefined,
currencyB: Currency | undefined,
feeAmount: FeeAmount | undefined
): {
isLoading: boolean
isUninitialized: boolean
isError: boolean
error: any
activeTick: number | undefined
data: TickProcessed[] | undefined
} {
const pool = usePool(currencyA, currencyB, feeAmount)
// Find nearest valid tick for pool in case tick is not initialized.
const activeTick = useMemo(() => getActiveTick(pool[1]?.tickCurrent, feeAmount), [pool, feeAmount])
const { isLoading, isUninitialized, isError, error, ticks } = useAllV3Ticks(currencyA, currencyB, feeAmount)
return useMemo(() => {
if (
!currencyA ||
!currencyB ||
activeTick === undefined ||
pool[0] !== PoolState.EXISTS ||
!ticks ||
ticks.length === 0 ||
isLoading ||
isUninitialized
) {
return {
isLoading: isLoading || pool[0] === PoolState.LOADING,
isUninitialized,
isError,
error,
activeTick,
data: undefined,
}
}
const token0 = currencyA?.wrapped
const token1 = currencyB?.wrapped
// find where the active tick would be to partition the array
// if the active tick is initialized, the pivot will be an element
// if not, take the previous tick as pivot
const pivot = ticks.findIndex(({ tickIdx }) => tickIdx > activeTick) - 1
if (pivot < 0) {
// consider setting a local error
console.error('TickData pivot not found')
return {
isLoading,
isUninitialized,
isError,
error,
activeTick,
data: undefined,
}
}
const activeTickProcessed: TickProcessed = {
liquidityActive: JSBI.BigInt(pool[1]?.liquidity ?? 0),
tickIdx: activeTick,
liquidityNet:
Number(ticks[pivot].tickIdx) === activeTick ? JSBI.BigInt(ticks[pivot].liquidityNet) : JSBI.BigInt(0),
price0: tickToPrice(token0, token1, activeTick).toFixed(PRICE_FIXED_DIGITS),
}
const subsequentTicks = computeSurroundingTicks(token0, token1, activeTickProcessed, ticks, pivot, true)
const previousTicks = computeSurroundingTicks(token0, token1, activeTickProcessed, ticks, pivot, false)
const ticksProcessed = previousTicks.concat(activeTickProcessed).concat(subsequentTicks)
return {
isLoading,
isUninitialized,
isError,
error,
activeTick,
data: ticksProcessed,
}
}, [currencyA, currencyB, activeTick, pool, ticks, isLoading, isUninitialized, isError, error])
}
import { Interface } from '@ethersproject/abi'
import { Currency, Token } from '@uniswap/sdk-core'
import { abi as IUniswapV3PoolStateABI } from '@uniswap/v3-core/artifacts/contracts/interfaces/pool/IUniswapV3PoolState.sol/IUniswapV3PoolState.json'
import { computePoolAddress } from '@uniswap/v3-sdk'
import { FeeAmount, Pool } from '@uniswap/v3-sdk'
import { useMemo } from 'react'
import { V3_CORE_FACTORY_ADDRESSES } from '../constants/addresses'
import { useMultipleContractSingleData } from '../state/multicall/hooks'
import { IUniswapV3PoolStateInterface } from '../types/v3/IUniswapV3PoolState'
import { useActiveWeb3React } from './web3'
const POOL_STATE_INTERFACE = new Interface(IUniswapV3PoolStateABI) as IUniswapV3PoolStateInterface
export enum PoolState {
LOADING,
NOT_EXISTS,
EXISTS,
INVALID,
}
export function usePools(
poolKeys: [Currency | undefined, Currency | undefined, FeeAmount | undefined][]
): [PoolState, Pool | null][] {
const { chainId } = useActiveWeb3React()
const transformed: ([Token, Token, FeeAmount] | null)[] = useMemo(() => {
return poolKeys.map(([currencyA, currencyB, feeAmount]) => {
if (!chainId || !currencyA || !currencyB || !feeAmount) return null
const tokenA = currencyA?.wrapped
const tokenB = currencyB?.wrapped
if (!tokenA || !tokenB || tokenA.equals(tokenB)) return null
const [token0, token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA]
return [token0, token1, feeAmount]
})
}, [chainId, poolKeys])
const poolAddresses: (string | undefined)[] = useMemo(() => {
const v3CoreFactoryAddress = chainId && V3_CORE_FACTORY_ADDRESSES[chainId]
return transformed.map((value) => {
if (!v3CoreFactoryAddress || !value) return undefined
return computePoolAddress({
factoryAddress: v3CoreFactoryAddress,
tokenA: value[0],
tokenB: value[1],
fee: value[2],
})
})
}, [chainId, transformed])
const slot0s = useMultipleContractSingleData(poolAddresses, POOL_STATE_INTERFACE, 'slot0')
const liquidities = useMultipleContractSingleData(poolAddresses, POOL_STATE_INTERFACE, 'liquidity')
return useMemo(() => {
return poolKeys.map((_key, index) => {
const [token0, token1, fee] = transformed[index] ?? []
if (!token0 || !token1 || !fee) return [PoolState.INVALID, null]
const { result: slot0, loading: slot0Loading, valid: slot0Valid } = slot0s[index]
const { result: liquidity, loading: liquidityLoading, valid: liquidityValid } = liquidities[index]
if (!slot0Valid || !liquidityValid) return [PoolState.INVALID, null]
if (slot0Loading || liquidityLoading) return [PoolState.LOADING, null]
if (!slot0 || !liquidity) return [PoolState.NOT_EXISTS, null]
if (!slot0.sqrtPriceX96 || slot0.sqrtPriceX96.eq(0)) return [PoolState.NOT_EXISTS, null]
try {
return [PoolState.EXISTS, new Pool(token0, token1, fee, slot0.sqrtPriceX96, liquidity[0], slot0.tick)]
} catch (error) {
console.error('Error when constructing the pool', error)
return [PoolState.NOT_EXISTS, null]
}
})
}, [liquidities, poolKeys, slot0s, transformed])
}
export function usePool(
currencyA: Currency | undefined,
currencyB: Currency | undefined,
feeAmount: FeeAmount | undefined
): [PoolState, Pool | null] {
const poolKeys: [Currency | undefined, Currency | undefined, FeeAmount | undefined][] = useMemo(
() => [[currencyA, currencyB, feeAmount]],
[currencyA, currencyB, feeAmount]
)
return usePools(poolKeys)[0]
}
import { BigNumber } from '@ethersproject/bignumber'
import JSBI from 'jsbi'
import { useMemo } from 'react'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useV3NFTPositionManagerContract } from './useContract'
type TokenId = number | JSBI | BigNumber
const STARTS_WITH = 'data:application/json;base64,'
type UsePositionTokenURIResult =
| {
valid: true
loading: false
result: {
name: string
description: string
image: string
}
}
| {
valid: false
loading: false
}
| {
valid: true
loading: true
}
export function usePositionTokenURI(tokenId: TokenId | undefined): UsePositionTokenURIResult {
const contract = useV3NFTPositionManagerContract()
const inputs = useMemo(
() => [tokenId instanceof BigNumber ? tokenId.toHexString() : tokenId?.toString(16)],
[tokenId]
)
const { result, error, loading, valid } = useSingleCallResult(contract, 'tokenURI', inputs, {
...NEVER_RELOAD,
gasRequired: 3_000_000,
})
return useMemo(() => {
if (error || !valid || !tokenId) {
return {
valid: false,
loading: false,
}
}
if (loading) {
return {
valid: true,
loading: true,
}
}
if (!result) {
return {
valid: false,
loading: false,
}
}
const [tokenURI] = result as [string]
if (!tokenURI || !tokenURI.startsWith(STARTS_WITH))
return {
valid: false,
loading: false,
}
try {
const json = JSON.parse(atob(tokenURI.slice(STARTS_WITH.length)))
return {
valid: true,
loading: false,
result: json,
}
} catch (error) {
return { valid: false, loading: false }
}
}, [error, loading, result, tokenId, valid])
}
import { useEffect, useRef } from 'react'
// modified from https://usehooks.com/usePrevious/
export default function usePrevious<T>(value: T) {
// The ref object is a generic container whose current property is mutable ...
// ... and can hold any value, similar to an instance property on a class
const ref = useRef<T>()
// Store current value in ref
useEffect(() => {
ref.current = value
}, [value]) // Only re-run if value changes
// Return previous value (happens before update in useEffect above)
return ref.current
}
import { Token } from '@uniswap/sdk-core'
import { SOCKS_CONTROLLER_ADDRESSES } from 'constants/addresses'
import { SupportedChainId } from 'constants/chains'
import { useMemo } from 'react'
import { useTokenBalance } from 'state/wallet/hooks'
import { useActiveWeb3React } from './web3'
// technically a 721, not an ERC20, but suffices for our purposes
const SOCKS = new Token(SupportedChainId.MAINNET, SOCKS_CONTROLLER_ADDRESSES[SupportedChainId.MAINNET], 0)
export function useHasSocks(): boolean | undefined {
const { account, chainId } = useActiveWeb3React()
const balance = useTokenBalance(account ?? undefined, chainId === SupportedChainId.MAINNET ? SOCKS : undefined)
return useMemo(() => Boolean(balance?.greaterThan(0)), [balance])
}
import { useContext } from 'react'
import { ThemeContext } from 'styled-components/macro'
export default function useTheme() {
return useContext(ThemeContext)
}
import { useCallback, useState } from 'react'
export default function useToggle(initialState = false): [boolean, () => void] {
const [state, setState] = useState(initialState)
const toggle = useCallback(() => setState((state) => !state), [])
return [state, toggle]
}
import useParsedQueryString from './useParsedQueryString'
export enum Version {
v2 = 'V2',
v3 = 'V3',
}
export default function useToggledVersion(): Version | undefined {
const { use } = useParsedQueryString()
if (typeof use !== 'string') {
return undefined
}
switch (use.toLowerCase()) {
case 'v2':
return Version.v2
case 'v3':
return Version.v3
default:
return undefined
}
}
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useTokenContract } from './useContract'
export function useTokenAllowance(token?: Token, owner?: string, spender?: string): CurrencyAmount<Token> | undefined {
const contract = useTokenContract(token?.address, false)
const inputs = useMemo(() => [owner, spender], [owner, spender])
const allowance = useSingleCallResult(contract, 'allowance', inputs).result
return useMemo(
() => (token && allowance ? CurrencyAmount.fromRawAmount(token, allowance.toString()) : undefined),
[token, allowance]
)
}
import { Currency } from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks/web3'
import { useMemo } from 'react'
import { useCombinedActiveList } from 'state/lists/hooks'
/**
* Returns a WrappedTokenInfo from the active token lists when possible,
* or the passed token otherwise. */
export function useTokenInfoFromActiveList(currency: Currency) {
const { chainId } = useActiveWeb3React()
const activeList = useCombinedActiveList()
return useMemo(() => {
if (!chainId) return
if (currency.isNative) return currency
try {
return activeList[chainId][currency.wrapped.address].token
} catch (e) {
return currency
}
}, [activeList, chainId, currency])
}
import { BigNumber } from '@ethersproject/bignumber'
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useTokenContract } from './useContract'
// returns undefined if input token is undefined, or fails to get token contract,
// or contract total supply cannot be fetched
export function useTotalSupply(token?: Currency): CurrencyAmount<Token> | undefined {
const contract = useTokenContract(token?.isToken ? token.address : undefined, false)
const totalSupply: BigNumber = useSingleCallResult(contract, 'totalSupply')?.result?.[0]
return token?.isToken && totalSupply ? CurrencyAmount.fromRawAmount(token, totalSupply.toString()) : undefined
}
import { BigNumber } from '@ethersproject/bignumber'
import { L2_CHAIN_IDS } from 'constants/chains'
import { L2_DEADLINE_FROM_NOW } from 'constants/misc'
import { useMemo } from 'react'
import { useAppSelector } from 'state/hooks'
import useCurrentBlockTimestamp from './useCurrentBlockTimestamp'
import { useActiveWeb3React } from './web3'
// combines the block timestamp with the user setting to give the deadline that should be used for any submitted transaction
export default function useTransactionDeadline(): BigNumber | undefined {
const { chainId } = useActiveWeb3React()
const ttl = useAppSelector((state) => state.user.userDeadline)
const blockTimestamp = useCurrentBlockTimestamp()
return useMemo(() => {
if (blockTimestamp && chainId && L2_CHAIN_IDS.includes(chainId)) return blockTimestamp.add(L2_DEADLINE_FROM_NOW)
if (blockTimestamp && ttl) return blockTimestamp.add(ttl)
return undefined
}, [blockTimestamp, chainId, ttl])
}
import { Interface } from '@ethersproject/abi'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json'
import { computePairAddress, Pair } from '@uniswap/v2-sdk'
import { useMemo } from 'react'
import { V2_FACTORY_ADDRESSES } from '../constants/addresses'
import { useMultipleContractSingleData } from '../state/multicall/hooks'
const PAIR_INTERFACE = new Interface(IUniswapV2PairABI)
export enum PairState {
LOADING,
NOT_EXISTS,
EXISTS,
INVALID,
}
export function useV2Pairs(currencies: [Currency | undefined, Currency | undefined][]): [PairState, Pair | null][] {
const tokens = useMemo(
() => currencies.map(([currencyA, currencyB]) => [currencyA?.wrapped, currencyB?.wrapped]),
[currencies]
)
const pairAddresses = useMemo(
() =>
tokens.map(([tokenA, tokenB]) => {
return tokenA &&
tokenB &&
tokenA.chainId === tokenB.chainId &&
!tokenA.equals(tokenB) &&
V2_FACTORY_ADDRESSES[tokenA.chainId]
? computePairAddress({ factoryAddress: V2_FACTORY_ADDRESSES[tokenA.chainId], tokenA, tokenB })
: undefined
}),
[tokens]
)
const results = useMultipleContractSingleData(pairAddresses, PAIR_INTERFACE, 'getReserves')
return useMemo(() => {
return results.map((result, i) => {
const { result: reserves, loading } = result
const tokenA = tokens[i][0]
const tokenB = tokens[i][1]
if (loading) return [PairState.LOADING, null]
if (!tokenA || !tokenB || tokenA.equals(tokenB)) return [PairState.INVALID, null]
if (!reserves) return [PairState.NOT_EXISTS, null]
const { reserve0, reserve1 } = reserves
const [token0, token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA]
return [
PairState.EXISTS,
new Pair(
CurrencyAmount.fromRawAmount(token0, reserve0.toString()),
CurrencyAmount.fromRawAmount(token1, reserve1.toString())
),
]
})
}, [results, tokens])
}
export function useV2Pair(tokenA?: Currency, tokenB?: Currency): [PairState, Pair | null] {
const inputs: [[Currency | undefined, Currency | undefined]] = useMemo(() => [[tokenA, tokenB]], [tokenA, tokenB])
return useV2Pairs(inputs)[0]
}
import { BigNumber } from '@ethersproject/bignumber'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { Pool } from '@uniswap/v3-sdk'
import { useEffect, useState } from 'react'
import { useBlockNumber } from 'state/application/hooks'
import { useSingleCallResult } from 'state/multicall/hooks'
import { unwrappedToken } from 'utils/unwrappedToken'
import { useV3NFTPositionManagerContract } from './useContract'
const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1)
// compute current + counterfactual fees for a v3 position
export function useV3PositionFees(
pool?: Pool,
tokenId?: BigNumber,
asWETH = false
): [CurrencyAmount<Currency>, CurrencyAmount<Currency>] | [undefined, undefined] {
const positionManager = useV3NFTPositionManagerContract(false)
const owner: string | undefined = useSingleCallResult(tokenId ? positionManager : null, 'ownerOf', [tokenId])
.result?.[0]
const tokenIdHexString = tokenId?.toHexString()
const latestBlockNumber = useBlockNumber()
// TODO find a way to get this into multicall
// latestBlockNumber is included to ensure data stays up-to-date every block
const [amounts, setAmounts] = useState<[BigNumber, BigNumber]>()
useEffect(() => {
let stale = false
if (positionManager && tokenIdHexString && owner && typeof latestBlockNumber === 'number') {
positionManager.callStatic
.collect(
{
tokenId: tokenIdHexString,
recipient: owner, // some tokens might fail if transferred to address(0)
amount0Max: MAX_UINT128,
amount1Max: MAX_UINT128,
},
{ from: owner } // need to simulate the call as the owner
)
.then((results) => {
if (!stale) setAmounts([results.amount0, results.amount1])
})
}
return () => {
stale = true
}
}, [positionManager, tokenIdHexString, owner, latestBlockNumber])
if (pool && amounts) {
return [
CurrencyAmount.fromRawAmount(!asWETH ? unwrappedToken(pool.token0) : pool.token0, amounts[0].toString()),
CurrencyAmount.fromRawAmount(!asWETH ? unwrappedToken(pool.token1) : pool.token1, amounts[1].toString()),
]
} else {
return [undefined, undefined]
}
}
import { BigNumber } from '@ethersproject/bignumber'
import { useMemo } from 'react'
import { Result, useSingleCallResult, useSingleContractMultipleData } from 'state/multicall/hooks'
import { PositionDetails } from 'types/position'
import { useV3NFTPositionManagerContract } from './useContract'
interface UseV3PositionsResults {
loading: boolean
positions: PositionDetails[] | undefined
}
function useV3PositionsFromTokenIds(tokenIds: BigNumber[] | undefined): UseV3PositionsResults {
const positionManager = useV3NFTPositionManagerContract()
const inputs = useMemo(() => (tokenIds ? tokenIds.map((tokenId) => [BigNumber.from(tokenId)]) : []), [tokenIds])
const results = useSingleContractMultipleData(positionManager, 'positions', inputs)
const loading = useMemo(() => results.some(({ loading }) => loading), [results])
const error = useMemo(() => results.some(({ error }) => error), [results])
const positions = useMemo(() => {
if (!loading && !error && tokenIds) {
return results.map((call, i) => {
const tokenId = tokenIds[i]
const result = call.result as Result
return {
tokenId,
fee: result.fee,
feeGrowthInside0LastX128: result.feeGrowthInside0LastX128,
feeGrowthInside1LastX128: result.feeGrowthInside1LastX128,
liquidity: result.liquidity,
nonce: result.nonce,
operator: result.operator,
tickLower: result.tickLower,
tickUpper: result.tickUpper,
token0: result.token0,
token1: result.token1,
tokensOwed0: result.tokensOwed0,
tokensOwed1: result.tokensOwed1,
}
})
}
return undefined
}, [loading, error, results, tokenIds])
return {
loading,
positions: positions?.map((position, i) => ({ ...position, tokenId: inputs[i][0] })),
}
}
interface UseV3PositionResults {
loading: boolean
position: PositionDetails | undefined
}
export function useV3PositionFromTokenId(tokenId: BigNumber | undefined): UseV3PositionResults {
const position = useV3PositionsFromTokenIds(tokenId ? [tokenId] : undefined)
return {
loading: position.loading,
position: position.positions?.[0],
}
}
export function useV3Positions(account: string | null | undefined): UseV3PositionsResults {
const positionManager = useV3NFTPositionManagerContract()
const { loading: balanceLoading, result: balanceResult } = useSingleCallResult(positionManager, 'balanceOf', [
account ?? undefined,
])
// we don't expect any account balance to ever exceed the bounds of max safe int
const accountBalance: number | undefined = balanceResult?.[0]?.toNumber()
const tokenIdsArgs = useMemo(() => {
if (accountBalance && account) {
const tokenRequests = []
for (let i = 0; i < accountBalance; i++) {
tokenRequests.push([account, i])
}
return tokenRequests
}
return []
}, [account, accountBalance])
const tokenIdResults = useSingleContractMultipleData(positionManager, 'tokenOfOwnerByIndex', tokenIdsArgs)
const someTokenIdsLoading = useMemo(() => tokenIdResults.some(({ loading }) => loading), [tokenIdResults])
const tokenIds = useMemo(() => {
if (account) {
return tokenIdResults
.map(({ result }) => result)
.filter((result): result is Result => !!result)
.map((result) => BigNumber.from(result[0]))
}
return []
}, [account, tokenIdResults])
const { positions, loading: positionsLoading } = useV3PositionsFromTokenIds(tokenIds)
return {
loading: someTokenIdsLoading || balanceLoading || positionsLoading,
positions,
}
}
import { Currency, Token } from '@uniswap/sdk-core'
import { FeeAmount, Pool } from '@uniswap/v3-sdk'
import { SupportedChainId } from 'constants/chains'
import { useMemo } from 'react'
import { useAllCurrencyCombinations } from './useAllCurrencyCombinations'
import { PoolState, usePools } from './usePools'
import { useActiveWeb3React } from './web3'
/**
* Returns all the existing pools that should be considered for swapping between an input currency and an output currency
* @param currencyIn the input currency
* @param currencyOut the output currency
*/
export function useV3SwapPools(
currencyIn?: Currency,
currencyOut?: Currency
): {
pools: Pool[]
loading: boolean
} {
const { chainId } = useActiveWeb3React()
const allCurrencyCombinations = useAllCurrencyCombinations(currencyIn, currencyOut)
const allCurrencyCombinationsWithAllFees: [Token, Token, FeeAmount][] = useMemo(
() =>
allCurrencyCombinations.reduce<[Token, Token, FeeAmount][]>((list, [tokenA, tokenB]) => {
return chainId === SupportedChainId.MAINNET
? list.concat([
[tokenA, tokenB, FeeAmount.LOW],
[tokenA, tokenB, FeeAmount.MEDIUM],
[tokenA, tokenB, FeeAmount.HIGH],
])
: list.concat([
[tokenA, tokenB, FeeAmount.LOWEST],
[tokenA, tokenB, FeeAmount.LOW],
[tokenA, tokenB, FeeAmount.MEDIUM],
[tokenA, tokenB, FeeAmount.HIGH],
])
}, []),
[allCurrencyCombinations, chainId]
)
const pools = usePools(allCurrencyCombinationsWithAllFees)
return useMemo(() => {
return {
pools: pools
.filter((tuple): tuple is [PoolState.EXISTS, Pool] => {
return tuple[0] === PoolState.EXISTS && tuple[1] !== null
})
.map(([, pool]) => pool),
loading: pools.some(([state]) => state === PoolState.LOADING),
}
}, [pools])
}
import { useEffect, useState } from 'react'
const isClient = typeof window === 'object'
function getSize() {
return {
width: isClient ? window.innerWidth : undefined,
height: isClient ? window.innerHeight : undefined,
}
}
// https://usehooks.com/useWindowSize/
export function useWindowSize() {
const [windowSize, setWindowSize] = useState(getSize)
useEffect(() => {
function handleResize() {
setWindowSize(getSize())
}
if (isClient) {
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
}
return undefined
}, [])
return windowSize
}
import { Currency } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { WETH9_EXTENDED } from '../constants/tokens'
import { tryParseAmount } from '../state/swap/hooks'
import { TransactionType } from '../state/transactions/actions'
import { useTransactionAdder } from '../state/transactions/hooks'
import { useCurrencyBalance } from '../state/wallet/hooks'
import { useWETHContract } from './useContract'
import { useActiveWeb3React } from './web3'
export enum WrapType {
NOT_APPLICABLE,
WRAP,
UNWRAP,
}
const NOT_APPLICABLE = { wrapType: WrapType.NOT_APPLICABLE }
/**
* Given the selected input and output currency, return a wrap callback
* @param inputCurrency the selected input currency
* @param outputCurrency the selected output currency
* @param typedValue the user input value
*/
export default function useWrapCallback(
inputCurrency: Currency | undefined | null,
outputCurrency: Currency | undefined | null,
typedValue: string | undefined
): { wrapType: WrapType; execute?: undefined | (() => Promise<void>); inputError?: string } {
const { chainId, account } = useActiveWeb3React()
const wethContract = useWETHContract()
const balance = useCurrencyBalance(account ?? undefined, inputCurrency ?? undefined)
// we can always parse the amount typed as the input currency, since wrapping is 1:1
const inputAmount = useMemo(() => tryParseAmount(typedValue, inputCurrency ?? undefined), [inputCurrency, typedValue])
const addTransaction = useTransactionAdder()
return useMemo(() => {
if (!wethContract || !chainId || !inputCurrency || !outputCurrency) return NOT_APPLICABLE
const weth = WETH9_EXTENDED[chainId]
if (!weth) return NOT_APPLICABLE
const hasInputAmount = Boolean(inputAmount?.greaterThan('0'))
const sufficientBalance = inputAmount && balance && !balance.lessThan(inputAmount)
if (inputCurrency.isNative && weth.equals(outputCurrency)) {
return {
wrapType: WrapType.WRAP,
execute:
sufficientBalance && inputAmount
? async () => {
try {
const txReceipt = await wethContract.deposit({ value: `0x${inputAmount.quotient.toString(16)}` })
addTransaction(txReceipt, {
type: TransactionType.WRAP,
unwrapped: false,
currencyAmountRaw: inputAmount?.quotient.toString(),
})
} catch (error) {
console.error('Could not deposit', error)
}
}
: undefined,
inputError: sufficientBalance ? undefined : hasInputAmount ? 'Insufficient ETH balance' : 'Enter ETH amount',
}
} else if (weth.equals(inputCurrency) && outputCurrency.isNative) {
return {
wrapType: WrapType.UNWRAP,
execute:
sufficientBalance && inputAmount
? async () => {
try {
const txReceipt = await wethContract.withdraw(`0x${inputAmount.quotient.toString(16)}`)
addTransaction(txReceipt, {
type: TransactionType.WRAP,
unwrapped: true,
currencyAmountRaw: inputAmount?.quotient.toString(),
})
} catch (error) {
console.error('Could not withdraw', error)
}
}
: undefined,
inputError: sufficientBalance ? undefined : hasInputAmount ? 'Insufficient WETH balance' : 'Enter WETH amount',
}
} else {
return NOT_APPLICABLE
}
}, [wethContract, chainId, inputCurrency, outputCurrency, inputAmount, balance, addTransaction])
}
import { Web3Provider } from '@ethersproject/providers'
import { useWeb3React } from '@web3-react/core'
import { useEffect, useState } from 'react'
import { gnosisSafe, injected } from '../connectors'
import { IS_IN_IFRAME, NetworkContextName } from '../constants/misc'
import { isMobile } from '../utils/userAgent'
export function useActiveWeb3React() {
const context = useWeb3React<Web3Provider>()
const contextNetwork = useWeb3React<Web3Provider>(NetworkContextName)
return context.active ? context : contextNetwork
}
export function useEagerConnect() {
const { activate, active } = useWeb3React()
const [tried, setTried] = useState(false)
// gnosisSafe.isSafeApp() races a timeout against postMessage, so it delays pageload if we are not in a safe app;
// if we are not embedded in an iframe, it is not worth checking
const [triedSafe, setTriedSafe] = useState(!IS_IN_IFRAME)
// first, try connecting to a gnosis safe
useEffect(() => {
if (!triedSafe) {
gnosisSafe.isSafeApp().then((loadedInSafe) => {
if (loadedInSafe) {
activate(gnosisSafe, undefined, true).catch(() => {
setTriedSafe(true)
})
} else {
setTriedSafe(true)
}
})
}
}, [activate, setTriedSafe, triedSafe])
// then, if that fails, try connecting to an injected connector
useEffect(() => {
if (!active && triedSafe) {
injected.isAuthorized().then((isAuthorized) => {
if (isAuthorized) {
activate(injected, undefined, true).catch(() => {
setTried(true)
})
} else {
if (isMobile && window.ethereum) {
activate(injected, undefined, true).catch(() => {
setTried(true)
})
} else {
setTried(true)
}
}
})
}
}, [activate, active, triedSafe])
// wait until we get confirmation of a connection to flip the flag
useEffect(() => {
if (active) {
setTried(true)
}
}, [active])
return tried
}
/**
* Use for network and injected - logs user in
* and out after checking what network theyre on
*/
export function useInactiveListener(suppress = false) {
const { active, error, activate } = useWeb3React()
useEffect(() => {
const { ethereum } = window
if (ethereum && ethereum.on && !active && !error && !suppress) {
const handleChainChanged = () => {
// eat errors
activate(injected, undefined, true).catch((error) => {
console.error('Failed to activate after chain changed', error)
})
}
const handleAccountsChanged = (accounts: string[]) => {
if (accounts.length > 0) {
// eat errors
activate(injected, undefined, true).catch((error) => {
console.error('Failed to activate after accounts changed', error)
})
}
}
ethereum.on('chainChanged', handleChainChanged)
ethereum.on('accountsChanged', handleAccountsChanged)
return () => {
if (ethereum.removeListener) {
ethereum.removeListener('chainChanged', handleChainChanged)
ethereum.removeListener('accountsChanged', handleAccountsChanged)
}
}
}
return undefined
}, [active, error, suppress, activate])
}
......@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-11-18 19:06\n"
"PO-Revision-Date: 2021-11-30 02:11\n"
"Last-Translator: \n"
"Language: ja_JP\n"
"Language-Team: Japanese\n"
......@@ -309,7 +309,7 @@ msgstr "安定的なペアに最適"
#: src/components/FeeSelector/shared.tsx
msgid "Best for very stable pairs."
msgstr "非常に安定したペアに最適です。"
msgstr "非常に安定したペアに最適"
#: src/components/Blocklist/index.tsx
msgid "Blocked address"
......@@ -329,7 +329,7 @@ msgstr "このリストを追加することで、データが正しいことを
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs’ <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "財布を接続することにより、あなたはUniswap Labsのに同意 <0>サービス規約</0> 、あなたが読んでUniswap理解していることを認める <1>プロトコル免責事項</1>。"
msgstr "ウォレットを接続することにより、あなたはUniswap Labsのに <0>サービス規約</0>に同意し、あなたがUniswap<1>プロトコル免責事項</1>を読み、理解していることに同意するものとします。"
#: src/pages/Vote/styled.tsx
msgid "Canceled"
......@@ -1541,7 +1541,7 @@ msgstr "スワップ"
#: src/components/AccountDetails/TransactionSummary.tsx
msgid "Swap <0/> for exactly <1/>"
msgstr "<0/> を <1/>に正確にスワップする"
msgstr "<0/> を <1/>にスワップ"
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
......@@ -1550,7 +1550,7 @@ msgstr "問題発生の可能性があるが、スワップする"
#: src/components/AccountDetails/TransactionSummary.tsx
msgid "Swap exactly <0/> for <1/>"
msgstr "正確に<0/>を<1/>に交換します"
msgstr "<0/>を<1/>にスワップ"
#: src/hooks/useSwapCallback.tsx
#: src/hooks/useSwapCallback.tsx
......
......@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-11-18 19:06\n"
"PO-Revision-Date: 2021-11-25 20:06\n"
"Last-Translator: \n"
"Language: ru_RU\n"
"Language-Team: Russian\n"
......@@ -305,11 +305,11 @@ msgstr "Подходит для большинства пар."
#: src/components/FeeSelector/shared.tsx
msgid "Best for stable pairs."
msgstr "Подходит для пар стейблкоинов."
msgstr "Подходит для стабильных пар."
#: src/components/FeeSelector/shared.tsx
msgid "Best for very stable pairs."
msgstr "Подходит для пар очень стабильных стейблкоинов."
msgstr "Подходит для очень стабильных пар."
#: src/components/Blocklist/index.tsx
msgid "Blocked address"
......
......@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-11-18 19:06\n"
"PO-Revision-Date: 2021-11-30 02:11\n"
"Last-Translator: \n"
"Language: zh_CN\n"
"Language-Team: Chinese Simplified\n"
......
......@@ -51,7 +51,7 @@ import { Bound, Field } from '../../state/mint/v3/actions'
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { useIsExpertMode, useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, ThemedText } from '../../theme'
import approveAmountCalldata from '../../utils/approveAmountCalldata'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { currencyId } from '../../utils/currencyId'
......@@ -406,9 +406,9 @@ export default function AddLiquidity({
const Buttons = () =>
addIsUnsupported ? (
<ButtonPrimary disabled={true} $borderRadius="12px" padding={'12px'}>
<TYPE.main mb="4px">
<ThemedText.Main mb="4px">
<Trans>Unsupported Asset</Trans>
</TYPE.main>
</ThemedText.Main>
</ButtonPrimary>
) : !account ? (
<ButtonLight onClick={toggleWalletModal} $borderRadius="12px" padding={'12px'}>
......@@ -517,9 +517,9 @@ export default function AddLiquidity({
<Row justifyContent="flex-end" style={{ width: 'fit-content', minWidth: 'fit-content' }}>
<MediumOnly>
<ButtonText onClick={clearAll} margin="0 15px 0 0">
<TYPE.blue fontSize="12px">
<ThemedText.Blue fontSize="12px">
<Trans>Clear All</Trans>
</TYPE.blue>
</ThemedText.Blue>
</ButtonText>
</MediumOnly>
{baseCurrency && quoteCurrency ? (
......@@ -548,9 +548,9 @@ export default function AddLiquidity({
<>
<AutoColumn gap="md">
<RowBetween paddingBottom="20px">
<TYPE.label>
<ThemedText.Label>
<Trans>Select Pair</Trans>
</TYPE.label>
</ThemedText.Label>
</RowBetween>
<RowBetween>
<CurrencyDropdown
......@@ -608,9 +608,9 @@ export default function AddLiquidity({
disabled={tickLower === undefined || tickUpper === undefined || invalidPool || invalidRange}
>
<AutoColumn gap="md">
<TYPE.label>
<ThemedText.Label>
{hasExistingPosition ? <Trans>Add more liquidity</Trans> : <Trans>Deposit Amounts</Trans>}
</TYPE.label>
</ThemedText.Label>
<CurrencyInputPanel
value={formattedAmounts[Field.CURRENCY_A]}
......@@ -653,26 +653,26 @@ export default function AddLiquidity({
{!noLiquidity ? (
<>
<RowBetween>
<TYPE.label>
<ThemedText.Label>
<Trans>Set Price Range</Trans>
</TYPE.label>
</ThemedText.Label>
</RowBetween>
{price && baseCurrency && quoteCurrency && !noLiquidity && (
<AutoRow gap="4px" justify="center" style={{ marginTop: '0.5rem' }}>
<Trans>
<TYPE.main fontWeight={500} textAlign="center" fontSize={12} color="text1">
<ThemedText.Main fontWeight={500} textAlign="center" fontSize={12} color="text1">
Current Price:
</TYPE.main>
<TYPE.body fontWeight={500} textAlign="center" fontSize={12} color="text1">
</ThemedText.Main>
<ThemedText.Body fontWeight={500} textAlign="center" fontSize={12} color="text1">
<HoverInlineText
maxCharacters={20}
text={invertPrice ? price.invert().toSignificant(6) : price.toSignificant(6)}
/>
</TYPE.body>
<TYPE.body color="text2" fontSize={12}>
</ThemedText.Body>
<ThemedText.Body color="text2" fontSize={12}>
{quoteCurrency?.symbol} per {baseCurrency.symbol}
</TYPE.body>
</ThemedText.Body>
</Trans>
</AutoRow>
)}
......@@ -695,9 +695,9 @@ export default function AddLiquidity({
) : (
<AutoColumn gap="md">
<RowBetween>
<TYPE.label>
<ThemedText.Label>
<Trans>Set Starting Price</Trans>
</TYPE.label>
</ThemedText.Label>
</RowBetween>
{noLiquidity && (
<BlueCard
......@@ -708,7 +708,7 @@ export default function AddLiquidity({
padding: '1rem 1rem',
}}
>
<TYPE.body
<ThemedText.Body
fontSize={14}
style={{ fontWeight: 500 }}
textAlign="left"
......@@ -719,7 +719,7 @@ export default function AddLiquidity({
starting price for the pool. Then, enter your liquidity price range and deposit
amount. Gas fees will be higher than usual due to the initialization transaction.
</Trans>
</TYPE.body>
</ThemedText.Body>
</BlueCard>
)}
<OutlineCard padding="12px">
......@@ -730,12 +730,12 @@ export default function AddLiquidity({
/>
</OutlineCard>
<RowBetween style={{ backgroundColor: theme.bg1, padding: '12px', borderRadius: '12px' }}>
<TYPE.main>
<ThemedText.Main>
<Trans>Current {baseCurrency?.symbol} Price:</Trans>
</TYPE.main>
<TYPE.main>
</ThemedText.Main>
<ThemedText.Main>
{price ? (
<TYPE.main>
<ThemedText.Main>
<RowFixed>
<HoverInlineText
maxCharacters={20}
......@@ -743,11 +743,11 @@ export default function AddLiquidity({
/>{' '}
<span style={{ marginLeft: '4px' }}>{quoteCurrency?.symbol}</span>
</RowFixed>
</TYPE.main>
</ThemedText.Main>
) : (
'-'
)}
</TYPE.main>
</ThemedText.Main>
</RowBetween>
</AutoColumn>
)}
......@@ -762,9 +762,9 @@ export default function AddLiquidity({
<AutoColumn gap="md">
{noLiquidity && (
<RowBetween>
<TYPE.label>
<ThemedText.Label>
<Trans>Set Price Range</Trans>
</TYPE.label>
</ThemedText.Label>
</RowBetween>
)}
<RangeSelector
......@@ -805,12 +805,12 @@ export default function AddLiquidity({
<AutoColumn gap="8px" style={{ height: '100%' }}>
<RowFixed>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="15px">
<ThemedText.Yellow ml="12px" fontSize="15px">
<Trans>Efficiency Comparison</Trans>
</TYPE.yellow>
</ThemedText.Yellow>
</RowFixed>
<RowFixed>
<TYPE.yellow ml="12px" fontSize="13px" margin={0} fontWeight={400}>
<ThemedText.Yellow ml="12px" fontSize="13px" margin={0} fontWeight={400}>
<Trans>
Full range positions may earn less fees than concentrated positions. Learn more{' '}
<ExternalLink
......@@ -823,7 +823,7 @@ export default function AddLiquidity({
</ExternalLink>
.
</Trans>
</TYPE.yellow>
</ThemedText.Yellow>
</RowFixed>
<Row>
<ButtonYellow
......@@ -836,9 +836,9 @@ export default function AddLiquidity({
getSetFullRange()
}}
>
<TYPE.black fontSize={13} color="black">
<ThemedText.Black fontSize={13} color="black">
<Trans>I understand</Trans>
</TYPE.black>
</ThemedText.Black>
</ButtonYellow>
</Row>
</AutoColumn>
......@@ -851,12 +851,12 @@ export default function AddLiquidity({
<YellowCard padding="8px 12px" $borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<ThemedText.Yellow ml="12px" fontSize="12px">
<Trans>
Your position will not earn fees or be used in trades until the market price moves into
your range.
</Trans>
</TYPE.yellow>
</ThemedText.Yellow>
</RowBetween>
</YellowCard>
) : null}
......@@ -865,9 +865,9 @@ export default function AddLiquidity({
<YellowCard padding="8px 12px" $borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<ThemedText.Yellow ml="12px" fontSize="12px">
<Trans>Invalid range selected. The min price must be lower than the max price.</Trans>
</TYPE.yellow>
</ThemedText.Yellow>
</RowBetween>
</YellowCard>
) : null}
......
......@@ -6,7 +6,7 @@ import { ButtonPrimary } from '../../components/Button'
import CurrencyLogo from '../../components/CurrencyLogo'
import { RowBetween, RowFixed } from '../../components/Row'
import { Field } from '../../state/mint/actions'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
export function ConfirmAddModalBottom({
noLiquidity,
......@@ -26,47 +26,47 @@ export function ConfirmAddModalBottom({
return (
<>
<RowBetween>
<TYPE.body>
<ThemedText.Body>
<Trans>{currencies[Field.CURRENCY_A]?.symbol} Deposited</Trans>
</TYPE.body>
</ThemedText.Body>
<RowFixed>
<CurrencyLogo currency={currencies[Field.CURRENCY_A]} style={{ marginRight: '8px' }} />
<TYPE.body>{parsedAmounts[Field.CURRENCY_A]?.toSignificant(6)}</TYPE.body>
<ThemedText.Body>{parsedAmounts[Field.CURRENCY_A]?.toSignificant(6)}</ThemedText.Body>
</RowFixed>
</RowBetween>
<RowBetween>
<TYPE.body>
<ThemedText.Body>
<Trans>{currencies[Field.CURRENCY_B]?.symbol} Deposited</Trans>
</TYPE.body>
</ThemedText.Body>
<RowFixed>
<CurrencyLogo currency={currencies[Field.CURRENCY_B]} style={{ marginRight: '8px' }} />
<TYPE.body>{parsedAmounts[Field.CURRENCY_B]?.toSignificant(6)}</TYPE.body>
<ThemedText.Body>{parsedAmounts[Field.CURRENCY_B]?.toSignificant(6)}</ThemedText.Body>
</RowFixed>
</RowBetween>
<RowBetween>
<TYPE.body>
<ThemedText.Body>
<Trans>Rates</Trans>
</TYPE.body>
<TYPE.body>
</ThemedText.Body>
<ThemedText.Body>
{`1 ${currencies[Field.CURRENCY_A]?.symbol} = ${price?.toSignificant(4)} ${
currencies[Field.CURRENCY_B]?.symbol
}`}
</TYPE.body>
</ThemedText.Body>
</RowBetween>
<RowBetween style={{ justifyContent: 'flex-end' }}>
<TYPE.body>
<ThemedText.Body>
{`1 ${currencies[Field.CURRENCY_B]?.symbol} = ${price?.invert().toSignificant(4)} ${
currencies[Field.CURRENCY_A]?.symbol
}`}
</TYPE.body>
</ThemedText.Body>
</RowBetween>
<RowBetween>
<TYPE.body>
<ThemedText.Body>
<Trans>Share of Pool:</Trans>
</TYPE.body>
<TYPE.body>
</ThemedText.Body>
<ThemedText.Body>
<Trans>{noLiquidity ? '100' : poolTokenPercentage?.toSignificant(4)}%</Trans>
</TYPE.body>
</ThemedText.Body>
</RowBetween>
<ButtonPrimary style={{ margin: '20px 0 0 0' }} onClick={onAdd}>
<Text fontWeight={500} fontSize={20}>
......
......@@ -8,7 +8,7 @@ import { AutoColumn } from '../../components/Column'
import { AutoRow } from '../../components/Row'
import { ONE_BIPS } from '../../constants/misc'
import { Field } from '../../state/mint/actions'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
export function PoolPriceBar({
currencies,
......@@ -26,7 +26,7 @@ export function PoolPriceBar({
<AutoColumn gap="md">
<AutoRow justify="space-around" gap="4px">
<AutoColumn justify="center">
<TYPE.black>{price?.toSignificant(6) ?? '-'}</TYPE.black>
<ThemedText.Black>{price?.toSignificant(6) ?? '-'}</ThemedText.Black>
<Text fontWeight={500} fontSize={14} color={theme.text2} pt={1}>
<Trans>
{currencies[Field.CURRENCY_B]?.symbol} per {currencies[Field.CURRENCY_A]?.symbol}
......@@ -34,7 +34,7 @@ export function PoolPriceBar({
</Text>
</AutoColumn>
<AutoColumn justify="center">
<TYPE.black>{price?.invert()?.toSignificant(6) ?? '-'}</TYPE.black>
<ThemedText.Black>{price?.invert()?.toSignificant(6) ?? '-'}</ThemedText.Black>
<Text fontWeight={500} fontSize={14} color={theme.text2} pt={1}>
<Trans>
{currencies[Field.CURRENCY_A]?.symbol} per {currencies[Field.CURRENCY_B]?.symbol}
......@@ -42,12 +42,12 @@ export function PoolPriceBar({
</Text>
</AutoColumn>
<AutoColumn justify="center">
<TYPE.black>
<ThemedText.Black>
{noLiquidity && price
? '100'
: (poolTokenPercentage?.lessThan(ONE_BIPS) ? '<0.01' : poolTokenPercentage?.toFixed(2)) ?? '0'}
%
</TYPE.black>
</ThemedText.Black>
<Text fontWeight={500} fontSize={14} color={theme.text2} pt={1}>
<Trans>Share of Pool</Trans>
</Text>
......
......@@ -35,7 +35,7 @@ import { useDerivedMintInfo, useMintActionHandlers, useMintState } from '../../s
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { useIsExpertMode, useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { calculateSlippageAmount } from '../../utils/calculateSlippageAmount'
import { currencyId } from '../../utils/currencyId'
......@@ -247,12 +247,12 @@ export default function AddLiquidity({
{currencies[Field.CURRENCY_A]?.symbol + '/' + currencies[Field.CURRENCY_B]?.symbol + ' Pool Tokens'}
</Text>
</Row>
<TYPE.italic fontSize={12} textAlign="left" padding={'8px 0 0 0 '}>
<ThemedText.Italic fontSize={12} textAlign="left" padding={'8px 0 0 0 '}>
<Trans>
Output is estimated. If the price changes by more than {allowedSlippage.toSignificant(4)}% your transaction
will revert.
</Trans>
</TYPE.italic>
</ThemedText.Italic>
</AutoColumn>
)
}
......@@ -344,15 +344,15 @@ export default function AddLiquidity({
<ColumnCenter>
<BlueCard>
<AutoColumn gap="10px">
<TYPE.link fontWeight={600} color={'primaryText1'}>
<ThemedText.Link fontWeight={600} color={'primaryText1'}>
<Trans>You are the first liquidity provider.</Trans>
</TYPE.link>
<TYPE.link fontWeight={400} color={'primaryText1'}>
</ThemedText.Link>
<ThemedText.Link fontWeight={400} color={'primaryText1'}>
<Trans>The ratio of tokens you add will set the price of this pool.</Trans>
</TYPE.link>
<TYPE.link fontWeight={400} color={'primaryText1'}>
</ThemedText.Link>
<ThemedText.Link fontWeight={400} color={'primaryText1'}>
<Trans>Once you are happy with the rate click supply to review.</Trans>
</TYPE.link>
</ThemedText.Link>
</AutoColumn>
</BlueCard>
</ColumnCenter>
......@@ -360,7 +360,7 @@ export default function AddLiquidity({
<ColumnCenter>
<BlueCard>
<AutoColumn gap="10px">
<TYPE.link fontWeight={400} color={'primaryText1'}>
<ThemedText.Link fontWeight={400} color={'primaryText1'}>
<Trans>
<b>
<Trans>Tip:</Trans>
......@@ -369,7 +369,7 @@ export default function AddLiquidity({
automatically earn fees proportional to your share of the pool, and can be redeemed at any
time.
</Trans>
</TYPE.link>
</ThemedText.Link>
</AutoColumn>
</BlueCard>
</ColumnCenter>
......@@ -405,13 +405,13 @@ export default function AddLiquidity({
<>
<LightCard padding="0px" $borderRadius={'20px'}>
<RowBetween padding="1rem">
<TYPE.subHeader fontWeight={500} fontSize={14}>
<ThemedText.SubHeader fontWeight={500} fontSize={14}>
{noLiquidity ? (
<Trans>Initial prices and pool share</Trans>
) : (
<Trans>Prices and pool share</Trans>
)}
</TYPE.subHeader>
</ThemedText.SubHeader>
</RowBetween>{' '}
<LightCard padding="1rem" $borderRadius={'20px'}>
<PoolPriceBar
......@@ -427,9 +427,9 @@ export default function AddLiquidity({
{addIsUnsupported ? (
<ButtonPrimary disabled={true}>
<TYPE.main mb="4px">
<ThemedText.Main mb="4px">
<Trans>Unsupported Asset</Trans>
</TYPE.main>
</ThemedText.Main>
</ButtonPrimary>
) : !account ? (
<ButtonLight onClick={toggleWalletModal}>
......
......@@ -7,7 +7,7 @@ import React, { useContext } from 'react'
import { Link } from 'react-router-dom'
import { Text } from 'rebass'
import { ThemeContext } from 'styled-components/macro'
import { ExternalLink, TYPE } from 'theme'
import { ExternalLink, ThemedText } from 'theme'
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
export const ProposalSubmissionModal = ({
......@@ -26,9 +26,9 @@ export const ProposalSubmissionModal = ({
{!hash ? (
<LoadingView onDismiss={onDismiss}>
<AutoColumn gap="12px" justify={'center'}>
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>Submitting Proposal</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
</AutoColumn>
</LoadingView>
) : (
......
......@@ -20,7 +20,7 @@ import {
} from 'state/governance/hooks'
import { tryParseAmount } from 'state/swap/hooks'
import styled from 'styled-components/macro'
import { ExternalLink, TYPE } from 'theme'
import { ExternalLink, ThemedText } from 'theme'
import { CreateProposalTabs } from '../../components/NavigationTabs'
import { UNI } from '../../constants/tokens'
......@@ -230,7 +230,7 @@ ${bodyValue}
<CreateProposalWrapper>
<BlueCard>
<AutoColumn gap="10px">
<TYPE.link fontWeight={400} color={'primaryText1'}>
<ThemedText.Link fontWeight={400} color={'primaryText1'}>
<Trans>
<strong>Tip:</strong> Select an action and describe your proposal for the community. The proposal cannot
be modified after submission, so please verify all information before submitting. The voting period will
......@@ -240,7 +240,7 @@ ${bodyValue}
</ExternalLink>
.
</Trans>
</TYPE.link>
</ThemedText.Link>
</AutoColumn>
</BlueCard>
......
import { useEffect, useMemo, useState } from 'react'
import { REWARDS_DURATION_DAYS, STAKING_GENESIS } from '../../state/stake/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
const MINUTE = 60
const HOUR = MINUTE * 60
......@@ -56,7 +56,7 @@ export function Countdown({ exactEnd }: { exactEnd?: Date }) {
const seconds = timeRemaining
return (
<TYPE.black fontWeight={400}>
<ThemedText.Black fontWeight={400}>
{message}{' '}
{Number.isFinite(timeRemaining) && (
<code>
......@@ -65,6 +65,6 @@ export function Countdown({ exactEnd }: { exactEnd?: Date }) {
.padStart(2, '0')}`}
</code>
)}
</TYPE.black>
</ThemedText.Black>
)
}
......@@ -26,7 +26,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { useWalletModalToggle } from '../../state/application/hooks'
import { useStakingInfo } from '../../state/stake/hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { currencyId } from '../../utils/currencyId'
const PageWrapper = styled(AutoColumn)`
......@@ -155,33 +155,33 @@ export default function Manage({
return (
<PageWrapper gap="lg" justify="center">
<RowBetween style={{ gap: '24px' }}>
<TYPE.mediumHeader style={{ margin: 0 }}>
<ThemedText.MediumHeader style={{ margin: 0 }}>
<Trans>
{currencyA?.symbol}-{currencyB?.symbol} Liquidity Mining
</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<DoubleCurrencyLogo currency0={currencyA ?? undefined} currency1={currencyB ?? undefined} size={24} />
</RowBetween>
<DataRow style={{ gap: '24px' }}>
<PoolData>
<AutoColumn gap="sm">
<TYPE.body style={{ margin: 0 }}>
<ThemedText.Body style={{ margin: 0 }}>
<Trans>Total deposits</Trans>
</TYPE.body>
<TYPE.body fontSize={24} fontWeight={500}>
</ThemedText.Body>
<ThemedText.Body fontSize={24} fontWeight={500}>
{valueOfTotalStakedAmountInUSDC
? `$${valueOfTotalStakedAmountInUSDC.toFixed(0, { groupSeparator: ',' })}`
: `${valueOfTotalStakedAmountInWETH?.toSignificant(4, { groupSeparator: ',' }) ?? '-'} ETH`}
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</PoolData>
<PoolData>
<AutoColumn gap="sm">
<TYPE.body style={{ margin: 0 }}>
<ThemedText.Body style={{ margin: 0 }}>
<Trans>Pool Rate</Trans>
</TYPE.body>
<TYPE.body fontSize={24} fontWeight={500}>
</ThemedText.Body>
<ThemedText.Body fontSize={24} fontWeight={500}>
{stakingInfo?.active ? (
<Trans>
{stakingInfo.totalRewardRate?.multiply(BIG_INT_SECONDS_IN_WEEK)?.toFixed(0, { groupSeparator: ',' })}{' '}
......@@ -190,7 +190,7 @@ export default function Manage({
) : (
<Trans>0 UNI / week</Trans>
)}
</TYPE.body>
</ThemedText.Body>
</AutoColumn>
</PoolData>
</DataRow>
......@@ -202,17 +202,17 @@ export default function Manage({
<CardSection>
<AutoColumn gap="md">
<RowBetween>
<TYPE.white fontWeight={600}>
<ThemedText.White fontWeight={600}>
<Trans>Step 1. Get UNI-V2 Liquidity tokens</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<RowBetween style={{ marginBottom: '1rem' }}>
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>
UNI-V2 LP tokens are required. Once you&apos;ve added liquidity to the {currencyA?.symbol}-
{currencyB?.symbol} pool you can stake your liquidity tokens on this page.
</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<ButtonPrimary
padding="8px"
......@@ -261,19 +261,19 @@ export default function Manage({
<CardNoise />
<AutoColumn gap="md">
<RowBetween>
<TYPE.white fontWeight={600}>
<ThemedText.White fontWeight={600}>
<Trans>Your liquidity deposits</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<RowBetween style={{ alignItems: 'baseline' }}>
<TYPE.white fontSize={36} fontWeight={600}>
<ThemedText.White fontSize={36} fontWeight={600}>
{stakingInfo?.stakedAmount?.toSignificant(6) ?? '-'}
</TYPE.white>
<TYPE.white>
</ThemedText.White>
<ThemedText.White>
<Trans>
UNI-V2 {currencyA?.symbol}-{currencyB?.symbol}
</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
</AutoColumn>
</CardSection>
......@@ -284,9 +284,9 @@ export default function Manage({
<AutoColumn gap="sm">
<RowBetween>
<div>
<TYPE.black>
<ThemedText.Black>
<Trans>Your unclaimed UNI</Trans>
</TYPE.black>
</ThemedText.Black>
</div>
{stakingInfo?.earnedAmount && JSBI.notEqual(BIG_INT_ZERO, stakingInfo?.earnedAmount?.quotient) && (
<ButtonEmpty
......@@ -300,7 +300,7 @@ export default function Manage({
)}
</RowBetween>
<RowBetween style={{ alignItems: 'baseline' }}>
<TYPE.largeHeader fontSize={36} fontWeight={600}>
<ThemedText.LargeHeader fontSize={36} fontWeight={600}>
<CountUp
key={countUpAmount}
isCounting
......@@ -310,8 +310,8 @@ export default function Manage({
thousandsSeparator={','}
duration={1}
/>
</TYPE.largeHeader>
<TYPE.black fontSize={16} fontWeight={500}>
</ThemedText.LargeHeader>
<ThemedText.Black fontSize={16} fontWeight={500}>
<span role="img" aria-label="wizard-icon" style={{ marginRight: '8px ' }}>
</span>
......@@ -324,17 +324,17 @@ export default function Manage({
) : (
<Trans>0 UNI / week</Trans>
)}
</TYPE.black>
</ThemedText.Black>
</RowBetween>
</AutoColumn>
</StyledBottomCard>
</BottomSection>
<TYPE.main style={{ textAlign: 'center' }} fontSize={14}>
<ThemedText.Main style={{ textAlign: 'center' }} fontSize={14}>
<span role="img" aria-label="wizard-icon" style={{ marginRight: '8px' }}>
⭐️
</span>
<Trans>When you withdraw, the contract will automagically claim UNI on your behalf!</Trans>
</TYPE.main>
</ThemedText.Main>
{!showAddLiquidityButton && (
<DataRow style={{ marginBottom: '1rem' }}>
......@@ -363,9 +363,9 @@ export default function Manage({
</DataRow>
)}
{!userLiquidityUnstaked ? null : userLiquidityUnstaked.equalTo('0') ? null : !stakingInfo?.active ? null : (
<TYPE.main>
<ThemedText.Main>
<Trans>{userLiquidityUnstaked.toSignificant(6)} UNI-V2 LP tokens available</Trans>
</TYPE.main>
</ThemedText.Main>
)}
</PositionInfo>
</PageWrapper>
......
......@@ -11,7 +11,7 @@ import { RowBetween } from '../../components/Row'
import { BIG_INT_ZERO } from '../../constants/misc'
import { useActiveWeb3React } from '../../hooks/web3'
import { STAKING_REWARDS_INFO, useStakingInfo } from '../../state/stake/hooks'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, ThemedText } from '../../theme'
import { Countdown } from './Countdown'
const PageWrapper = styled(AutoColumn)`
......@@ -63,25 +63,25 @@ export default function Earn() {
<CardSection>
<AutoColumn gap="md">
<RowBetween>
<TYPE.white fontWeight={600}>
<ThemedText.White fontWeight={600}>
<Trans>Uniswap liquidity mining</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<RowBetween>
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>
Deposit your Liquidity Provider tokens to receive UNI, the Uniswap protocol governance token.
</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>{' '}
<ExternalLink
style={{ color: 'white', textDecoration: 'underline' }}
href="https://uniswap.org/blog/uni/"
target="_blank"
>
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>Read more about UNI</Trans>
</TYPE.white>
</ThemedText.White>
</ExternalLink>
</AutoColumn>
</CardSection>
......@@ -92,9 +92,9 @@ export default function Earn() {
<AutoColumn gap="lg" style={{ width: '100%', maxWidth: '720px' }}>
<DataRow style={{ alignItems: 'baseline' }}>
<TYPE.mediumHeader style={{ marginTop: '0.5rem' }}>
<ThemedText.MediumHeader style={{ marginTop: '0.5rem' }}>
<Trans>Participating pools</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<Countdown exactEnd={stakingInfos?.[0]?.periodFinish} />
</DataRow>
......
......@@ -46,7 +46,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { NEVER_RELOAD, useSingleCallResult } from '../../state/multicall/hooks'
import { TransactionType } from '../../state/transactions/actions'
import { useTokenBalance } from '../../state/wallet/hooks'
import { BackArrow, ExternalLink, TYPE } from '../../theme'
import { BackArrow, ExternalLink, ThemedText } from '../../theme'
import { isAddress } from '../../utils'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { currencyId } from '../../utils/currencyId'
......@@ -60,7 +60,7 @@ const DEFAULT_MIGRATE_SLIPPAGE_TOLERANCE = new Percent(75, 10_000)
function EmptyState({ message }: { message: ReactNode }) {
return (
<AutoColumn style={{ minHeight: 200, justifyContent: 'center', alignItems: 'center' }}>
<TYPE.body>{message}</TYPE.body>
<ThemedText.Body>{message}</ThemedText.Body>
</AutoColumn>
)
}
......@@ -382,31 +382,31 @@ function V2PairMigration({
return (
<AutoColumn gap="20px">
<TYPE.body my={9} style={{ fontWeight: 400 }}>
<ThemedText.Body my={9} style={{ fontWeight: 400 }}>
<Trans>
This tool will safely migrate your {isNotUniswap ? 'SushiSwap' : 'V2'} liquidity to V3. The process is
completely trustless thanks to the{' '}
</Trans>
{chainId && migrator && (
<ExternalLink href={getExplorerLink(chainId, migrator.address, ExplorerDataType.ADDRESS)}>
<TYPE.blue display="inline">
<ThemedText.Blue display="inline">
<Trans>Uniswap migration contract↗</Trans>
</TYPE.blue>
</ThemedText.Blue>
</ExternalLink>
)}
.
</TYPE.body>
</ThemedText.Body>
<LightCard>
<AutoColumn gap="lg">
<RowBetween>
<RowFixed style={{ marginLeft: '8px' }}>
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} margin={false} size={20} />
<TYPE.mediumHeader style={{ marginLeft: '8px' }}>
<ThemedText.MediumHeader style={{ marginLeft: '8px' }}>
<Trans>
{currency0.symbol}/{currency1.symbol} LP Tokens
</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
</RowFixed>
<Badge variant={BadgeVariant.WARNING}>{isNotUniswap ? 'Sushi' : 'V2'}</Badge>
</RowBetween>
......@@ -423,11 +423,11 @@ function V2PairMigration({
<RowBetween>
<RowFixed style={{ marginLeft: '8px' }}>
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} margin={false} size={20} />
<TYPE.mediumHeader style={{ marginLeft: '8px' }}>
<ThemedText.MediumHeader style={{ marginLeft: '8px' }}>
<Trans>
{currency0.symbol}/{currency1.symbol} LP NFT
</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
</RowFixed>
<Badge variant={BadgeVariant.PRIMARY}>V3</Badge>
</RowBetween>
......@@ -436,28 +436,37 @@ function V2PairMigration({
{noLiquidity && (
<BlueCard style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<AlertCircle color={theme.text1} style={{ marginBottom: '12px', opacity: 0.8 }} />
<TYPE.body fontSize={14} style={{ marginBottom: 8, fontWeight: 500, opacity: 0.8 }} textAlign="center">
<ThemedText.Body
fontSize={14}
style={{ marginBottom: 8, fontWeight: 500, opacity: 0.8 }}
textAlign="center"
>
<Trans>
You are the first liquidity provider for this Uniswap V3 pool. Your liquidity will migrate at the
current {isNotUniswap ? 'SushiSwap' : 'V2'} price.
</Trans>
</TYPE.body>
</ThemedText.Body>
<TYPE.body fontWeight={500} textAlign="center" fontSize={14} style={{ marginTop: '8px', opacity: 0.8 }}>
<ThemedText.Body
fontWeight={500}
textAlign="center"
fontSize={14}
style={{ marginTop: '8px', opacity: 0.8 }}
>
<Trans>Your transaction cost will be much higher as it includes the gas to create the pool.</Trans>
</TYPE.body>
</ThemedText.Body>
{v2SpotPrice && (
<AutoColumn gap="8px" style={{ marginTop: '12px' }}>
<RowBetween>
<TYPE.body fontWeight={500} fontSize={14}>
<ThemedText.Body fontWeight={500} fontSize={14}>
<Trans>
{isNotUniswap ? 'SushiSwap' : 'V2'} {invertPrice ? currency1.symbol : currency0.symbol} Price:
</Trans>{' '}
{invertPrice
? `${v2SpotPrice?.invert()?.toSignificant(6)} ${currency0.symbol}`
: `${v2SpotPrice?.toSignificant(6)} ${currency1.symbol}`}
</TYPE.body>
</ThemedText.Body>
</RowBetween>
</AutoColumn>
)}
......@@ -468,63 +477,63 @@ function V2PairMigration({
<YellowCard>
<AutoColumn gap="8px">
<RowBetween>
<TYPE.body fontSize={14}>
<ThemedText.Body fontSize={14}>
<Trans>
{isNotUniswap ? 'SushiSwap' : 'V2'} {invertPrice ? currency1.symbol : currency0.symbol} Price:
</Trans>
</TYPE.body>
<TYPE.black fontSize={14}>
</ThemedText.Body>
<ThemedText.Black fontSize={14}>
{invertPrice
? `${v2SpotPrice?.invert()?.toSignificant(6)} ${currency0.symbol}`
: `${v2SpotPrice?.toSignificant(6)} ${currency1.symbol}`}
</TYPE.black>
</ThemedText.Black>
</RowBetween>
<RowBetween>
<TYPE.body fontSize={14}>
<ThemedText.Body fontSize={14}>
<Trans>V3 {invertPrice ? currency1.symbol : currency0.symbol} Price:</Trans>
</TYPE.body>
<TYPE.black fontSize={14}>
</ThemedText.Body>
<ThemedText.Black fontSize={14}>
{invertPrice
? `${v3SpotPrice?.invert()?.toSignificant(6)} ${currency0.symbol}`
: `${v3SpotPrice?.toSignificant(6)} ${currency1.symbol}`}
</TYPE.black>
</ThemedText.Black>
</RowBetween>
<RowBetween>
<TYPE.body fontSize={14} color="inherit">
<ThemedText.Body fontSize={14} color="inherit">
<Trans>Price Difference:</Trans>
</TYPE.body>
<TYPE.black fontSize={14} color="inherit">
</ThemedText.Body>
<ThemedText.Black fontSize={14} color="inherit">
<Trans>{priceDifferenceFraction?.toSignificant(4)}%</Trans>
</TYPE.black>
</ThemedText.Black>
</RowBetween>
</AutoColumn>
<TYPE.body fontSize={14} style={{ marginTop: 8, fontWeight: 400 }}>
<ThemedText.Body fontSize={14} style={{ marginTop: 8, fontWeight: 400 }}>
<Trans>
You should only deposit liquidity into Uniswap V3 at a price you believe is correct. <br />
If the price seems incorrect, you can either make a swap to move the price or wait for someone else to
do so.
</Trans>
</TYPE.body>
</ThemedText.Body>
</YellowCard>
) : !noLiquidity && v3SpotPrice ? (
<RowBetween>
<TYPE.body fontSize={14}>
<ThemedText.Body fontSize={14}>
<Trans>V3 {invertPrice ? currency1.symbol : currency0.symbol} Price:</Trans>
</TYPE.body>
<TYPE.black fontSize={14}>
</ThemedText.Body>
<ThemedText.Black fontSize={14}>
{invertPrice
? `${v3SpotPrice?.invert()?.toSignificant(6)} ${currency0.symbol}`
: `${v3SpotPrice?.toSignificant(6)} ${currency1.symbol}`}
</TYPE.black>
</ThemedText.Black>
</RowBetween>
) : null}
<RowBetween>
<TYPE.label>
<ThemedText.Label>
<Trans>Set Price Range</Trans>
</TYPE.label>
</ThemedText.Label>
<RateToggle
currencyA={invertPrice ? currency1 : currency0}
currencyB={invertPrice ? currency0 : currency1}
......@@ -555,11 +564,11 @@ function V2PairMigration({
<YellowCard padding="8px 12px" $borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<ThemedText.Yellow ml="12px" fontSize="12px">
<Trans>
Your position will not earn fees or be used in trades until the market price moves into your range.
</Trans>
</TYPE.yellow>
</ThemedText.Yellow>
</RowBetween>
</YellowCard>
) : null}
......@@ -568,9 +577,9 @@ function V2PairMigration({
<YellowCard padding="8px 12px" $borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<ThemedText.Yellow ml="12px" fontSize="12px">
<Trans>Invalid range selected. The min price must be lower than the max price.</Trans>
</TYPE.yellow>
</ThemedText.Yellow>
</RowBetween>
</YellowCard>
) : null}
......@@ -580,7 +589,7 @@ function V2PairMigration({
<AutoColumn gap="md">
<LiquidityInfo token0Amount={position.amount0} token1Amount={position.amount1} />
{chainId && refund0 && refund1 ? (
<TYPE.black fontSize={12}>
<ThemedText.Black fontSize={12}>
<Trans>
At least {formatCurrencyAmount(refund0, 4)}{' '}
{token0.equals(WETH9_EXTENDED[chainId]) ? 'ETH' : token0.symbol} and{' '}
......@@ -588,7 +597,7 @@ function V2PairMigration({
{token1.equals(WETH9_EXTENDED[chainId]) ? 'ETH' : token1.symbol} will be refunded to your wallet
due to selected price range.
</Trans>
</TYPE.black>
</ThemedText.Black>
) : null}
</AutoColumn>
</DarkGreyCard>
......@@ -720,16 +729,16 @@ export default function MigrateV2Pair({
<AutoColumn gap="16px">
<AutoRow style={{ alignItems: 'center', justifyContent: 'space-between' }} gap="8px">
<BackArrow to="/migrate/v2" />
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Migrate V2 Liquidity</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<SettingsTab placeholderSlippage={DEFAULT_MIGRATE_SLIPPAGE_TOLERANCE} />
</AutoRow>
{!account ? (
<TYPE.largeHeader>
<ThemedText.LargeHeader>
<Trans>You must connect an account.</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
) : pairBalance && totalSupply && reserve0 && reserve1 && token0 && token1 ? (
<V2PairMigration
pair={pair}
......
......@@ -20,13 +20,13 @@ import { V2_FACTORY_ADDRESSES } from '../../constants/addresses'
import { useActiveWeb3React } from '../../hooks/web3'
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
import { useTokenBalancesWithLoadingIndicator } from '../../state/wallet/hooks'
import { BackArrow, StyledInternalLink, TYPE } from '../../theme'
import { BackArrow, StyledInternalLink, ThemedText } from '../../theme'
import { BodyWrapper } from '../AppBody'
function EmptyState({ message }: { message: ReactNode }) {
return (
<AutoColumn style={{ minHeight: 200, justifyContent: 'center', alignItems: 'center' }}>
<TYPE.body>{message}</TYPE.body>
<ThemedText.Body>{message}</ThemedText.Body>
</AutoColumn>
)
}
......@@ -117,34 +117,34 @@ export default function MigrateV2() {
<AutoColumn gap="16px">
<AutoRow style={{ alignItems: 'center', justifyContent: 'space-between' }} gap="8px">
<BackArrow to="/pool/v2" />
<TYPE.mediumHeader>
<ThemedText.MediumHeader>
<Trans>Migrate V2 Liquidity</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<div>
<QuestionHelper text={<Trans>Migrate your liquidity tokens from Uniswap V2 to Uniswap V3.</Trans>} />
</div>
</AutoRow>
<TYPE.body style={{ marginBottom: 8, fontWeight: 400 }}>
<ThemedText.Body style={{ marginBottom: 8, fontWeight: 400 }}>
<Trans>
For each pool shown below, click migrate to remove your liquidity from Uniswap V2 and deposit it into
Uniswap V3.
</Trans>
</TYPE.body>
</ThemedText.Body>
{!account ? (
<LightCard padding="40px">
<TYPE.body color={theme.text3} textAlign="center">
<ThemedText.Body color={theme.text3} textAlign="center">
<Trans>Connect to a wallet to view your V2 liquidity.</Trans>
</TYPE.body>
</ThemedText.Body>
</LightCard>
) : v2IsLoading ? (
<LightCard padding="40px">
<TYPE.body color={theme.text3} textAlign="center">
<ThemedText.Body color={theme.text3} textAlign="center">
<Dots>
<Trans>Loading</Trans>
</Dots>
</TYPE.body>
</ThemedText.Body>
</LightCard>
) : v2Pairs.filter(([, pair]) => !!pair).length > 0 ? (
<>
......
......@@ -3,7 +3,7 @@ import { AutoColumn } from 'components/Column'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import Texture from '../../assets/images/sandtexture.webp'
import { ExternalLink } from '../../theme'
......@@ -102,7 +102,7 @@ const CTA2 = styled(ExternalLink)`
}
`
const HeaderText = styled(TYPE.label)`
const HeaderText = styled(ThemedText.Label)`
align-items: center;
display: flex;
margin-bottom: 24px;
......@@ -133,9 +133,9 @@ export default function CTACards() {
<HeaderText>
<Trans>Learn about providing liquidity</Trans>
</HeaderText>
<TYPE.body fontWeight={300} style={{ alignItems: 'center', display: 'flex', maxWidth: '80%' }}>
<ThemedText.Body fontWeight={300} style={{ alignItems: 'center', display: 'flex', maxWidth: '80%' }}>
<Trans>Check out our v3 LP walkthrough and migration guides.</Trans>
</TYPE.body>
</ThemedText.Body>
</ResponsiveColumn>
</CTA1>
<CTA2 href={infoLink + 'pools'}>
......@@ -143,9 +143,9 @@ export default function CTACards() {
<HeaderText style={{ alignSelf: 'flex-start' }}>
<Trans>Top pools</Trans>
</HeaderText>
<TYPE.body fontWeight={300} style={{ alignSelf: 'flex-start' }}>
<ThemedText.Body fontWeight={300} style={{ alignSelf: 'flex-start' }}>
<Trans>Explore popular pools on Uniswap Analytics.</Trans>
</TYPE.body>
</ThemedText.Body>
</ResponsiveColumn>
</CTA2>
</CTASection>
......
......@@ -29,7 +29,7 @@ import { Bound } from 'state/mint/v3/actions'
import { useSingleCallResult } from 'state/multicall/hooks'
import { useIsTransactionPending, useTransactionAdder } from 'state/transactions/hooks'
import styled from 'styled-components/macro'
import { ExternalLink, HideExtraSmall, TYPE } from 'theme'
import { ExternalLink, HideExtraSmall, ThemedText } from 'theme'
import { currencyId } from 'utils/currencyId'
import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
import { formatTickPrice } from 'utils/formatTickPrice'
......@@ -79,7 +79,7 @@ const BadgeText = styled.div`
// responsive text
// disable the warning because we don't use the end prop, we just want to filter it out
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const Label = styled(({ end, ...props }) => <TYPE.label {...props} />)<{ end?: boolean }>`
const Label = styled(({ end, ...props }) => <ThemedText.Label {...props} />)<{ end?: boolean }>`
display: flex;
font-size: 16px;
justify-content: ${({ end }) => (end ? 'flex-end' : 'flex-start')};
......@@ -94,7 +94,7 @@ const ExtentsText = styled.span`
font-weight: 500;
`
const HoverText = styled(TYPE.main)`
const HoverText = styled(ThemedText.Main)`
text-decoration: none;
color: ${({ theme }) => theme.text3};
:hover {
......@@ -164,9 +164,9 @@ function CurrentPriceCard({
<ExtentsText>
<Trans>Current price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">
<ThemedText.MediumHeader textAlign="center">
{(inverted ? pool.token1Price : pool.token0Price).toSignificant(6)}{' '}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<ExtentsText>
<Trans>
{currencyQuote?.symbol} per {currencyBase?.symbol}
......@@ -185,7 +185,7 @@ function LinkedCurrency({ chainId, currency }: { chainId?: number; currency?: Cu
<ExternalLink href={getExplorerLink(chainId, address, ExplorerDataType.TOKEN)}>
<RowFixed>
<CurrencyLogo currency={currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{currency?.symbol}</TYPE.main>
<ThemedText.Main>{currency?.symbol}</ThemedText.Main>
</RowFixed>
</ExternalLink>
)
......@@ -194,7 +194,7 @@ function LinkedCurrency({ chainId, currency }: { chainId?: number; currency?: Cu
return (
<RowFixed>
<CurrencyLogo currency={currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{currency?.symbol}</TYPE.main>
<ThemedText.Main>{currency?.symbol}</ThemedText.Main>
</RowFixed>
)
}
......@@ -490,22 +490,22 @@ export function PositionPage({
<RowBetween>
<RowFixed>
<CurrencyLogo currency={feeValueUpper?.currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'}</TYPE.main>
<ThemedText.Main>{feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'}</ThemedText.Main>
</RowFixed>
<TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
<ThemedText.Main>{feeValueUpper?.currency?.symbol}</ThemedText.Main>
</RowBetween>
<RowBetween>
<RowFixed>
<CurrencyLogo currency={feeValueLower?.currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'}</TYPE.main>
<ThemedText.Main>{feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'}</ThemedText.Main>
</RowFixed>
<TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
<ThemedText.Main>{feeValueLower?.currency?.symbol}</ThemedText.Main>
</RowBetween>
</AutoColumn>
</LightCard>
<TYPE.italic>
<ThemedText.Italic>
<Trans>Collecting fees will withdraw currently available fees for you.</Trans>
</TYPE.italic>
</ThemedText.Italic>
<ButtonPrimary onClick={collect}>
<Trans>Collect</Trans>
</ButtonPrimary>
......@@ -564,9 +564,9 @@ export function PositionPage({
<ResponsiveRow>
<RowFixed>
<DoubleCurrencyLogo currency0={currencyBase} currency1={currencyQuote} size={24} margin={true} />
<TYPE.label fontSize={'24px'} mr="10px">
<ThemedText.Label fontSize={'24px'} mr="10px">
&nbsp;{currencyQuote?.symbol}&nbsp;/&nbsp;{currencyBase?.symbol}
</TYPE.label>
</ThemedText.Label>
<Badge style={{ marginRight: '8px' }}>
<BadgeText>
<Trans>{new Percent(feeAmount, 1_000_000).toSignificant()}%</Trans>
......@@ -646,13 +646,13 @@ export function PositionPage({
<Trans>Liquidity</Trans>
</Label>
{fiatValueOfLiquidity?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader fontSize="36px" fontWeight={500}>
<ThemedText.LargeHeader fontSize="36px" fontWeight={500}>
<Trans>${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })}</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<ThemedText.LargeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<Trans>$-</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
)}
</AutoColumn>
<LightCard padding="12px 16px">
......@@ -660,14 +660,14 @@ export function PositionPage({
<RowBetween>
<LinkedCurrency chainId={chainId} currency={currencyQuote} />
<RowFixed>
<TYPE.main>
<ThemedText.Main>
{inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)}
</TYPE.main>
</ThemedText.Main>
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main fontSize={11}>
<ThemedText.Main fontSize={11}>
<Trans>{inverted ? ratio : 100 - ratio}%</Trans>
</TYPE.main>
</ThemedText.Main>
</Badge>
) : null}
</RowFixed>
......@@ -675,14 +675,14 @@ export function PositionPage({
<RowBetween>
<LinkedCurrency chainId={chainId} currency={currencyBase} />
<RowFixed>
<TYPE.main>
<ThemedText.Main>
{inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)}
</TYPE.main>
</ThemedText.Main>
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main color={theme.text2} fontSize={11}>
<ThemedText.Main color={theme.text2} fontSize={11}>
<Trans>{inverted ? 100 - ratio : ratio}%</Trans>
</TYPE.main>
</ThemedText.Main>
</Badge>
) : null}
</RowFixed>
......@@ -700,13 +700,13 @@ export function PositionPage({
<Trans>Unclaimed fees</Trans>
</Label>
{fiatValueOfFees?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader color={theme.green1} fontSize="36px" fontWeight={500}>
<ThemedText.LargeHeader color={theme.green1} fontSize="36px" fontWeight={500}>
<Trans>${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })}</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<ThemedText.LargeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<Trans>$-</Trans>
</TYPE.largeHeader>
</ThemedText.LargeHeader>
)}
</AutoColumn>
{ownsNFT && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) || !!collectMigrationHash) ? (
......@@ -719,21 +719,21 @@ export function PositionPage({
onClick={() => setShowConfirm(true)}
>
{!!collectMigrationHash && !isCollectPending ? (
<TYPE.main color={theme.text1}>
<ThemedText.Main color={theme.text1}>
<Trans> Collected</Trans>
</TYPE.main>
</ThemedText.Main>
) : isCollectPending || collecting ? (
<TYPE.main color={theme.text1}>
<ThemedText.Main color={theme.text1}>
{' '}
<Dots>
<Trans>Collecting</Trans>
</Dots>
</TYPE.main>
</ThemedText.Main>
) : (
<>
<TYPE.main color={theme.white}>
<ThemedText.Main color={theme.white}>
<Trans>Collect fees</Trans>
</TYPE.main>
</ThemedText.Main>
</>
)}
</ButtonConfirmed>
......@@ -749,10 +749,12 @@ export function PositionPage({
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
<ThemedText.Main>{feeValueUpper?.currency?.symbol}</ThemedText.Main>
</RowFixed>
<RowFixed>
<TYPE.main>{feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'}</TYPE.main>
<ThemedText.Main>
{feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'}
</ThemedText.Main>
</RowFixed>
</RowBetween>
<RowBetween>
......@@ -762,10 +764,12 @@ export function PositionPage({
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
<ThemedText.Main>{feeValueLower?.currency?.symbol}</ThemedText.Main>
</RowFixed>
<RowFixed>
<TYPE.main>{feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'}</TYPE.main>
<ThemedText.Main>
{feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'}
</ThemedText.Main>
</RowFixed>
</RowBetween>
</AutoColumn>
......@@ -773,9 +777,9 @@ export function PositionPage({
{showCollectAsWeth && (
<AutoColumn gap="md">
<RowBetween>
<TYPE.main>
<ThemedText.Main>
<Trans>Collect as WETH</Trans>
</TYPE.main>
</ThemedText.Main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
......@@ -819,9 +823,9 @@ export function PositionPage({
<ExtentsText>
<Trans>Min price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">
<ThemedText.MediumHeader textAlign="center">
{formatTickPrice(priceLower, tickAtLimit, Bound.LOWER)}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<ExtentsText>
{' '}
<Trans>
......@@ -830,9 +834,9 @@ export function PositionPage({
</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
<ThemedText.Small color={theme.text3}>
<Trans>Your position will be 100% {currencyBase?.symbol} at this price.</Trans>
</TYPE.small>
</ThemedText.Small>
)}
</AutoColumn>
</LightCard>
......@@ -843,9 +847,9 @@ export function PositionPage({
<ExtentsText>
<Trans>Max price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">
<ThemedText.MediumHeader textAlign="center">
{formatTickPrice(priceUpper, tickAtLimit, Bound.UPPER)}
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<ExtentsText>
{' '}
<Trans>
......@@ -854,9 +858,9 @@ export function PositionPage({
</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
<ThemedText.Small color={theme.text3}>
<Trans>Your position will be 100% {currencyQuote?.symbol} at this price.</Trans>
</TYPE.small>
</ThemedText.Small>
)}
</AutoColumn>
</LightCard>
......
......@@ -17,7 +17,7 @@ import { Link } from 'react-router-dom'
import { useWalletModalToggle } from 'state/application/hooks'
import { useUserHideClosedPositions } from 'state/user/hooks'
import styled, { ThemeContext } from 'styled-components/macro'
import { HideSmall, TYPE } from 'theme'
import { HideSmall, ThemedText } from 'theme'
import { PositionDetails } from 'types/position'
import CTACards from './CTACards'
......@@ -199,9 +199,9 @@ export default function Pool() {
<AutoColumn gap="lg" justify="center">
<AutoColumn gap="lg" style={{ width: '100%' }}>
<TitleRow style={{ marginTop: '1rem' }} padding={'0'}>
<TYPE.body fontSize={'20px'}>
<ThemedText.Body fontSize={'20px'}>
<Trans>Pools Overview</Trans>
</TYPE.body>
</ThemedText.Body>
<ButtonRow>
{showV2Features && (
<Menu
......@@ -209,10 +209,10 @@ export default function Pool() {
flyoutAlignment={FlyoutAlignment.LEFT}
ToggleUI={(props: any) => (
<MoreOptionsButton {...props}>
<TYPE.body style={{ alignItems: 'center', display: 'flex' }}>
<ThemedText.Body style={{ alignItems: 'center', display: 'flex' }}>
<Trans>More</Trans>
<ChevronDown size={15} />
</TYPE.body>
</ThemedText.Body>
</MoreOptionsButton>
)}
/>
......@@ -249,12 +249,12 @@ export default function Pool() {
<PositionList positions={filteredPositions} />
) : (
<NoLiquidity>
<TYPE.body color={theme.text3} textAlign="center">
<ThemedText.Body color={theme.text3} textAlign="center">
<Inbox size={48} strokeWidth={1} style={{ marginBottom: '.5rem' }} />
<div>
<Trans>Your V3 liquidity positions will appear here.</Trans>
</div>
</TYPE.body>
</ThemedText.Body>
{showConnectAWallet && (
<ButtonPrimary style={{ marginTop: '2em', padding: '8px 16px' }} onClick={toggleWalletModal}>
<Trans>Connect a wallet</Trans>
......@@ -306,9 +306,9 @@ export default function Pool() {
{closedPositions.length > 0 ? (
<ShowInactiveToggle>
<label>
<TYPE.body onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}>
<ThemedText.Body onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}>
<Trans>Show closed positions</Trans>
</TYPE.body>
</ThemedText.Body>
</label>
<input
type="checkbox"
......
......@@ -23,7 +23,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { useStakingInfo } from '../../state/stake/hooks'
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
import { useTokenBalancesWithLoadingIndicator } from '../../state/wallet/hooks'
import { ExternalLink, HideSmall, TYPE } from '../../theme'
import { ExternalLink, HideSmall, ThemedText } from '../../theme'
const PageWrapper = styled(AutoColumn)`
max-width: 640px;
......@@ -144,26 +144,26 @@ export default function Pool() {
<CardSection>
<AutoColumn gap="md">
<RowBetween>
<TYPE.white fontWeight={600}>
<ThemedText.White fontWeight={600}>
<Trans>Liquidity provider rewards</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<RowBetween>
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>
Liquidity providers earn a 0.3% fee on all trades proportional to their share of the pool. Fees are
added to the pool, accrue in real time and can be claimed by withdrawing your liquidity.
</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<ExternalLink
style={{ color: 'white', textDecoration: 'underline' }}
target="_blank"
href="https://uniswap.org/docs/v2/core-concepts/pools/"
>
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>Read more about providing liquidity</Trans>
</TYPE.white>
</ThemedText.White>
</ExternalLink>
</AutoColumn>
</CardSection>
......@@ -175,9 +175,9 @@ export default function Pool() {
<AutoColumn gap="lg" justify="center">
<AutoColumn gap="md" style={{ width: '100%' }}>
<Layer2Prompt>
<TYPE.body color={theme.text3} textAlign="center">
<ThemedText.Body color={theme.text3} textAlign="center">
<Trans>V2 is not available on Layer 2. Switch to Layer 1 Ethereum.</Trans>
</TYPE.body>
</ThemedText.Body>
</Layer2Prompt>
</AutoColumn>
</AutoColumn>
......@@ -186,9 +186,9 @@ export default function Pool() {
<AutoColumn gap="md" style={{ width: '100%' }}>
<TitleRow style={{ marginTop: '1rem' }} padding={'0'}>
<HideSmall>
<TYPE.mediumHeader style={{ marginTop: '0.5rem', justifySelf: 'flex-start' }}>
<ThemedText.MediumHeader style={{ marginTop: '0.5rem', justifySelf: 'flex-start' }}>
<Trans>Your V2 liquidity</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
</HideSmall>
<ButtonRow>
<ResponsiveButtonSecondary as={Link} padding="6px 8px" to="/add/v2/ETH">
......@@ -209,17 +209,17 @@ export default function Pool() {
{!account ? (
<Card padding="40px">
<TYPE.body color={theme.text3} textAlign="center">
<ThemedText.Body color={theme.text3} textAlign="center">
<Trans>Connect to a wallet to view your liquidity.</Trans>
</TYPE.body>
</ThemedText.Body>
</Card>
) : v2IsLoading ? (
<EmptyProposals>
<TYPE.body color={theme.text3} textAlign="center">
<ThemedText.Body color={theme.text3} textAlign="center">
<Dots>
<Trans>Loading</Trans>
</Dots>
</TYPE.body>
</ThemedText.Body>
</EmptyProposals>
) : allV2PairsWithLiquidity?.length > 0 || stakingPairs?.length > 0 ? (
<>
......@@ -266,9 +266,9 @@ export default function Pool() {
</>
) : (
<EmptyProposals>
<TYPE.body color={theme.text3} textAlign="center">
<ThemedText.Body color={theme.text3} textAlign="center">
<Trans>No liquidity found.</Trans>
</TYPE.body>
</ThemedText.Body>
</EmptyProposals>
)}
</AutoColumn>
......
......@@ -22,7 +22,7 @@ import { useActiveWeb3React } from '../../hooks/web3'
import { usePairAdder } from '../../state/user/hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { StyledInternalLink } from '../../theme'
import { TYPE } from '../../theme'
import { ThemedText } from '../../theme'
import { currencyId } from '../../utils/currencyId'
import AppBody from '../AppBody'
import { Dots } from '../Pool/styleds'
......@@ -101,11 +101,11 @@ export default function PoolFinder() {
<AutoColumn style={{ padding: '1rem' }} gap="md">
<BlueCard>
<AutoColumn gap="10px">
<TYPE.link fontWeight={400} color={'primaryText1'}>
<ThemedText.Link fontWeight={400} color={'primaryText1'}>
<Trans>
<b>Tip:</b> Use this tool to find v2 pools that don&apos;t automatically appear in the interface.
</Trans>
</TYPE.link>
</ThemedText.Link>
</AutoColumn>
</BlueCard>
<ButtonDropdownLight
......
......@@ -29,7 +29,7 @@ import { Text } from 'rebass'
import { useBurnV3ActionHandlers, useBurnV3State, useDerivedV3BurnInfo } from 'state/burn/v3/hooks'
import { useTransactionAdder } from 'state/transactions/hooks'
import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
import { TYPE } from 'theme'
import { ThemedText } from 'theme'
import TransactionConfirmationModal, { ConfirmationModalContent } from '../../components/TransactionConfirmationModal'
import { WETH9_EXTENDED } from '../../constants/tokens'
......@@ -227,9 +227,9 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</RowBetween>
{feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? (
<>
<TYPE.italic fontSize={12} color={theme.text2} textAlign="left" padding={'8px 0 0 0'}>
<ThemedText.Italic fontSize={12} color={theme.text2} textAlign="left" padding={'8px 0 0 0'}>
<Trans>You will also collect fees earned from this position.</Trans>
</TYPE.italic>
</ThemedText.Italic>
<RowBetween>
<Text fontSize={16} fontWeight={500}>
<Trans>{feeValue0?.currency?.symbol} Fees Earned:</Trans>
......@@ -303,18 +303,18 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
size={20}
margin={true}
/>
<TYPE.label
<ThemedText.Label
ml="10px"
fontSize="20px"
>{`${feeValue0?.currency?.symbol}/${feeValue1?.currency?.symbol}`}</TYPE.label>
>{`${feeValue0?.currency?.symbol}/${feeValue1?.currency?.symbol}`}</ThemedText.Label>
</RowFixed>
<RangeBadge removed={removed} inRange={!outOfRange} />
</RowBetween>
<LightCard>
<AutoColumn gap="md">
<TYPE.main fontWeight={400}>
<ThemedText.Main fontWeight={400}>
<Trans>Amount</Trans>
</TYPE.main>
</ThemedText.Main>
<RowBetween>
<ResponsiveHeaderText>
<Trans>{percentForSlider}%</Trans>
......@@ -393,9 +393,9 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
{showCollectAsWeth && (
<RowBetween>
<TYPE.main>
<ThemedText.Main>
<Trans>Collect as WETH</Trans>
</TYPE.main>
</ThemedText.Main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
......
......@@ -36,7 +36,7 @@ import { useBurnActionHandlers, useBurnState, useDerivedBurnInfo } from '../../s
import { TransactionType } from '../../state/transactions/actions'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { StyledInternalLink, TYPE } from '../../theme'
import { StyledInternalLink, ThemedText } from '../../theme'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { calculateSlippageAmount } from '../../utils/calculateSlippageAmount'
import { currencyId } from '../../utils/currencyId'
......@@ -318,12 +318,12 @@ export default function RemoveLiquidity({
</RowFixed>
</RowBetween>
<TYPE.italic fontSize={12} color={theme.text2} textAlign="left" padding={'12px 0 0 0'}>
<ThemedText.Italic fontSize={12} color={theme.text2} textAlign="left" padding={'12px 0 0 0'}>
<Trans>
Output is estimated. If the price changes by more than {allowedSlippage.toSignificant(4)}% your transaction
will revert.
</Trans>
</TYPE.italic>
</ThemedText.Italic>
</AutoColumn>
)
}
......@@ -450,12 +450,12 @@ export default function RemoveLiquidity({
<AutoColumn gap="md">
<BlueCard>
<AutoColumn gap="10px">
<TYPE.link fontWeight={400} color={'primaryText1'}>
<ThemedText.Link fontWeight={400} color={'primaryText1'}>
<Trans>
<b>Tip:</b> Removing pool tokens converts your position back into underlying tokens at the current
rate, proportional to your share of the pool. Accrued fees are included in the amounts you receive.
</Trans>
</TYPE.link>
</ThemedText.Link>
</AutoColumn>
</BlueCard>
<LightCard>
......
......@@ -59,7 +59,7 @@ import {
useSwapState,
} from '../../state/swap/hooks'
import { useExpertModeManager } from '../../state/user/hooks'
import { LinkStyledButton, TYPE } from '../../theme'
import { LinkStyledButton, ThemedText } from '../../theme'
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
import { getTradeVersion } from '../../utils/getTradeVersion'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
......@@ -468,7 +468,7 @@ export default function Swap({ history }: RouteComponentProps) {
<AutoRouterLogo />
<LoadingOpacityContainer $loading={routeIsSyncing}>
{trade instanceof V3Trade && trade.swaps.length > 1 && (
<TYPE.blue fontSize={14}>{trade.swaps.length} routes</TYPE.blue>
<ThemedText.Blue fontSize={14}>{trade.swaps.length} routes</ThemedText.Blue>
)}
</LoadingOpacityContainer>
</AutoRow>
......@@ -506,9 +506,9 @@ export default function Swap({ history }: RouteComponentProps) {
<div>
{swapIsUnsupported ? (
<ButtonPrimary disabled={true}>
<TYPE.main mb="4px">
<ThemedText.Main mb="4px">
<Trans>Unsupported Asset</Trans>
</TYPE.main>
</ThemedText.Main>
</ButtonPrimary>
) : !account ? (
<ButtonLight onClick={toggleWalletModal}>
......@@ -525,17 +525,17 @@ export default function Swap({ history }: RouteComponentProps) {
</ButtonPrimary>
) : routeIsSyncing || routeIsLoading ? (
<GreyCard style={{ textAlign: 'center' }}>
<TYPE.main mb="4px">
<ThemedText.Main mb="4px">
<Dots>
<Trans>Loading</Trans>
</Dots>
</TYPE.main>
</ThemedText.Main>
</GreyCard>
) : routeNotFound && userHasSpecifiedInputOutput ? (
<GreyCard style={{ textAlign: 'center' }}>
<TYPE.main mb="4px">
<ThemedText.Main mb="4px">
<Trans>Insufficient liquidity for this trade.</Trans>
</TYPE.main>
</ThemedText.Main>
</GreyCard>
) : showApproveFlow ? (
<AutoRow style={{ flexWrap: 'nowrap', width: '100%' }}>
......
......@@ -20,7 +20,7 @@ import { ProposalData } from 'state/governance/hooks'
import { useAllProposalData, useUserDelegatee, useUserVotes } from 'state/governance/hooks'
import { useTokenBalance } from 'state/wallet/hooks'
import styled from 'styled-components/macro'
import { ExternalLink, TYPE } from 'theme'
import { ExternalLink, ThemedText } from 'theme'
import { shortenAddress } from 'utils'
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
......@@ -40,8 +40,8 @@ const Proposal = styled(Button)`
width: 100%;
margin-top: 1rem;
border-radius: 12px;
display: grid;
grid-template-columns: 48px 1fr 120px;
display: flex;
justify-content: space-between;
align-items: center;
text-align: left;
outline: none;
......@@ -59,10 +59,16 @@ const Proposal = styled(Button)`
const ProposalNumber = styled.span`
opacity: 0.6;
flex: 0 0 40px;
`
const ProposalTitle = styled.span`
font-weight: 600;
flex: 1;
max-width: 420px;
white-space: initial;
word-wrap: break-word;
padding-right: 10px;
`
const VoteCard = styled(DataCard)`
......@@ -77,7 +83,7 @@ const WrapSmall = styled(RowBetween)`
`};
`
const TextButton = styled(TYPE.main)`
const TextButton = styled(ThemedText.Main)`
color: ${({ theme }) => theme.primary1};
:hover {
cursor: pointer;
......@@ -135,26 +141,26 @@ export default function Landing() {
<CardSection>
<AutoColumn gap="md">
<RowBetween>
<TYPE.white fontWeight={600}>
<ThemedText.White fontWeight={600}>
<Trans>Uniswap Governance</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<RowBetween>
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>
UNI tokens represent voting shares in Uniswap governance. You can vote on each proposal yourself
or delegate your votes to a third party.
</Trans>
</TYPE.white>
</ThemedText.White>
</RowBetween>
<ExternalLink
style={{ color: 'white', textDecoration: 'underline' }}
href="https://uniswap.org/blog/uni"
target="_blank"
>
<TYPE.white fontSize={14}>
<ThemedText.White fontSize={14}>
<Trans>Read more about Uniswap governance</Trans>
</TYPE.white>
</ThemedText.White>
</ExternalLink>
</AutoColumn>
</CardSection>
......@@ -164,9 +170,9 @@ export default function Landing() {
</TopSection>
<TopSection gap="2px">
<WrapSmall>
<TYPE.mediumHeader style={{ margin: '0.5rem 0.5rem 0.5rem 0', flexShrink: 0 }}>
<ThemedText.MediumHeader style={{ margin: '0.5rem 0.5rem 0.5rem 0', flexShrink: 0 }}>
<Trans>Proposals</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<AutoRow gap="6px" justify="flex-end">
{loadingProposals || loadingAvailableVotes ? <Loader /> : null}
{showUnlockVoting ? (
......@@ -179,20 +185,20 @@ export default function Landing() {
<Trans>Unlock Voting</Trans>
</ButtonPrimary>
) : availableVotes && JSBI.notEqual(JSBI.BigInt(0), availableVotes?.quotient) ? (
<TYPE.body fontWeight={500} mr="6px">
<ThemedText.Body fontWeight={500} mr="6px">
<Trans>
<FormattedCurrencyAmount currencyAmount={availableVotes} /> Votes
</Trans>
</TYPE.body>
</ThemedText.Body>
) : uniBalance &&
userDelegatee &&
userDelegatee !== ZERO_ADDRESS &&
JSBI.notEqual(JSBI.BigInt(0), uniBalance?.quotient) ? (
<TYPE.body fontWeight={500} mr="6px">
<ThemedText.Body fontWeight={500} mr="6px">
<Trans>
<FormattedCurrencyAmount currencyAmount={uniBalance} /> Votes
</Trans>
</TYPE.body>
</ThemedText.Body>
) : (
''
)}
......@@ -211,9 +217,9 @@ export default function Landing() {
<div />
{userDelegatee && userDelegatee !== ZERO_ADDRESS ? (
<RowFixed>
<TYPE.body fontWeight={500} mr="4px">
<ThemedText.Body fontWeight={500} mr="4px">
<Trans>Delegated to:</Trans>
</TYPE.body>
</ThemedText.Body>
<AddressButton>
<StyledExternalLink
href={getExplorerLink(1, userDelegatee, ExplorerDataType.ADDRESS)}
......@@ -247,9 +253,9 @@ export default function Landing() {
)
})}
</TopSection>
<TYPE.subHeader color="text3">
<ThemedText.SubHeader color="text3">
<Trans>A minimum threshold of 0.25% of the total UNI supply is required to submit proposals</Trans>
</TYPE.subHeader>
</ThemedText.SubHeader>
</PageWrapper>
<SwitchLocaleLink />
</>
......
......@@ -38,7 +38,7 @@ import {
} from '../../state/governance/hooks'
import { VoteOption } from '../../state/governance/types'
import { useTokenBalance } from '../../state/wallet/hooks'
import { ExternalLink, StyledInternalLink, TYPE } from '../../theme'
import { ExternalLink, StyledInternalLink, ThemedText } from '../../theme'
import { isAddress } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { ProposalStatus } from './styled'
......@@ -249,27 +249,27 @@ export default function VotePage({
{proposalData && <ProposalStatus status={proposalData.status} />}
</RowBetween>
<AutoColumn gap="10px" style={{ width: '100%' }}>
<TYPE.largeHeader style={{ marginBottom: '.5rem' }}>{proposalData?.title}</TYPE.largeHeader>
<ThemedText.LargeHeader style={{ marginBottom: '.5rem' }}>{proposalData?.title}</ThemedText.LargeHeader>
<RowBetween>
<TYPE.main>
<ThemedText.Main>
{startDate && startDate > now ? (
<Trans>Voting starts approximately {startDate.toLocaleString(locale, dateFormat)}</Trans>
) : null}
</TYPE.main>
</ThemedText.Main>
</RowBetween>
<RowBetween>
<TYPE.main>
<ThemedText.Main>
{endDate &&
(endDate < now ? (
<Trans>Voting ended {endDate.toLocaleString(locale, dateFormat)}</Trans>
) : (
<Trans>Voting ends approximately {endDate.toLocaleString(locale, dateFormat)}</Trans>
))}
</TYPE.main>
</ThemedText.Main>
</RowBetween>
{proposalData && proposalData.status === ProposalState.ACTIVE && !showVotingButtons && (
<GreyCard>
<TYPE.black>
<ThemedText.Black>
<Trans>
Only UNI votes that were self delegated or delegated to another address before block{' '}
{proposalData.startBlock} are eligible for voting.{' '}
......@@ -282,7 +282,7 @@ export default function VotePage({
</Trans>
</span>
)}
</TYPE.black>
</ThemedText.Black>
</GreyCard>
)}
</AutoColumn>
......@@ -317,12 +317,12 @@ export default function VotePage({
<CardSection>
<AutoColumn gap="md">
<WrapSmall>
<TYPE.black fontWeight={600}>
<ThemedText.Black fontWeight={600}>
<Trans>For</Trans>
</TYPE.black>
<TYPE.black fontWeight={600}>
</ThemedText.Black>
<ThemedText.Black fontWeight={600}>
{proposalData?.forCount?.toLocaleString(undefined, { maximumFractionDigits: 0 })}
</TYPE.black>
</ThemedText.Black>
</WrapSmall>
</AutoColumn>
<ProgressWrapper>
......@@ -334,12 +334,12 @@ export default function VotePage({
<CardSection>
<AutoColumn gap="md">
<WrapSmall>
<TYPE.black fontWeight={600}>
<ThemedText.Black fontWeight={600}>
<Trans>Against</Trans>
</TYPE.black>
<TYPE.black fontWeight={600}>
</ThemedText.Black>
<ThemedText.Black fontWeight={600}>
{proposalData?.againstCount?.toLocaleString(undefined, { maximumFractionDigits: 0 })}
</TYPE.black>
</ThemedText.Black>
</WrapSmall>
</AutoColumn>
<ProgressWrapper>
......@@ -349,9 +349,9 @@ export default function VotePage({
</StyledDataCard>
</CardWrapper>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<ThemedText.MediumHeader fontWeight={600}>
<Trans>Details</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
{proposalData?.details?.map((d, i) => {
return (
<DetailText key={i}>
......@@ -370,17 +370,17 @@ export default function VotePage({
})}
</AutoColumn>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<ThemedText.MediumHeader fontWeight={600}>
<Trans>Description</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<MarkDownWrapper>
<ReactMarkdown source={proposalData?.description} />
</MarkDownWrapper>
</AutoColumn>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<ThemedText.MediumHeader fontWeight={600}>
<Trans>Proposer</Trans>
</TYPE.mediumHeader>
</ThemedText.MediumHeader>
<ProposerAddressLink
href={
proposalData?.proposer && chainId
......
......@@ -54,6 +54,8 @@ const StyledProposalContainer = styled.span<{ status: ProposalState }>`
width: fit-content;
justify-self: flex-end;
text-transform: uppercase;
flex: 0 0 100px;
text-align: center;
`
export function ProposalStatus({ status }: { status: ProposalState }) {
......
......@@ -16,7 +16,7 @@ describe('application reducer', () => {
beforeEach(() => {
store = createStore(reducer, {
blockNumber: {
[1]: 3,
1: 3,
},
chainId: null,
implements3085: false,
......@@ -83,8 +83,8 @@ describe('application reducer', () => {
it('works with non-set chains', () => {
store.dispatch(updateBlockNumber({ chainId: 3, blockNumber: 2 }))
expect(store.getState().blockNumber).toEqual({
[1]: 3,
[3]: 2,
1: 3,
3: 2,
})
})
})
......
......@@ -23,7 +23,7 @@ function useQueryCacheInvalidator() {
}
export default function Updater(): null {
const { account, chainId, library, connector } = useActiveWeb3React()
const { account, chainId, library } = useActiveWeb3React()
const dispatch = useAppDispatch()
const windowVisible = useIsWindowVisible()
......
......@@ -136,7 +136,7 @@ function useFormattedProposalCreatedLogs(
// Bravo and one bip proposals omit newlines
if (startBlock === BRAVO_START_BLOCK || startBlock === ONE_BIP_START_BLOCK) {
description = description.replace(/ /g, '\n').replace(/\d\. /g, '\n$&')
description = description.replace(/ {2}/g, '\n').replace(/\d\. /g, '\n$&')
}
return {
......
import { createStore, Store } from 'redux'
import { DEFAULT_LIST_OF_LISTS } from '../../constants/lists'
import { DEFAULT_ACTIVE_LIST_URLS } from '../../constants/lists'
import { updateVersion } from '../global/actions'
import { DEFAULT_ACTIVE_LIST_URLS } from './../../constants/lists'
import { acceptListUpdate, addList, enableList, fetchTokenList, removeList } from './actions'
import reducer, { ListsState } from './reducer'
......
......@@ -16,7 +16,7 @@ describe('hooks', () => {
expect(tryParsePrice(baseToken, quoteToken, '20.')).toEqual(undefined)
})
it('should return a price', () => {
it('should return a price when decimals are the same', () => {
const baseToken = new Token(1, '0x6b175474e89094c44da98b954eedeac495271d0f', 6)
const quoteToken = new Token(1, '0x1b175474e89094c44da98b954eedeac495271d0f', 6)
......@@ -36,5 +36,26 @@ describe('hooks', () => {
tryParsePrice(baseToken, quoteToken, /* ~2^-128 */ '0.000000000000000000000000000587747')?.toSignificant(6)
).toEqual('0.000000000000000000000000000587747')
})
it('should return a price when decimals are different', () => {
const baseToken = new Token(1, '0x6b175474e89094c44da98b954eedeac495271d0f', 2)
const quoteToken = new Token(1, '0x1b175474e89094c44da98b954eedeac495271d0f', 4)
expect(tryParsePrice(baseToken, quoteToken, '20')?.toSignificant(6)).toEqual('20')
expect(tryParsePrice(baseToken, quoteToken, '20.05')?.toSignificant(6)).toEqual('20.05')
expect(tryParsePrice(baseToken, quoteToken, '20.123456789')?.toSignificant(6)).toEqual('20.1235')
expect(tryParsePrice(baseToken, quoteToken, '0.123456789')?.toSignificant(6)).toEqual('0.123457')
expect(tryParsePrice(baseToken, quoteToken, '.123456789')?.toSignificant(6)).toEqual('0.123457')
expect(
tryParsePrice(
baseToken,
quoteToken,
(2 ** 128).toLocaleString('fullwide', { useGrouping: false })
)?.toSignificant(6)
).toEqual('340282000000000000000000000000000000000')
expect(
tryParsePrice(baseToken, quoteToken, /* ~2^-128 */ '0.000000000000000000000000000587747')?.toSignificant(6)
).toEqual('0.000000000000000000000000000587747')
})
})
})
......@@ -38,9 +38,9 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callListeners: {
[1]: {
1: {
[`${DAI_ADDRESS}-0x`]: {
[1]: 1,
1: 1,
},
},
},
......@@ -92,7 +92,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {},
callListeners: { [1]: { [`${DAI_ADDRESS}-0x`]: {} } },
callListeners: { 1: { [`${DAI_ADDRESS}-0x`]: {} } },
})
})
})
......@@ -110,7 +110,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
abc: {
blockNumber: 1,
data: '0x',
......@@ -140,7 +140,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
abc: {
blockNumber: 2,
data: '0x2',
......@@ -170,7 +170,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
abc: {
blockNumber: 2,
data: '0x2',
......@@ -191,7 +191,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
[`${DAI_ADDRESS}-0x0`]: { fetchingBlockNumber: 2 },
},
},
......@@ -215,7 +215,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
[`${DAI_ADDRESS}-0x0`]: { fetchingBlockNumber: 3 },
},
},
......@@ -239,7 +239,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
[`${DAI_ADDRESS}-0x0`]: { fetchingBlockNumber: 2 },
},
},
......@@ -258,7 +258,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {},
1: {},
},
})
})
......@@ -279,7 +279,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
[`${DAI_ADDRESS}-0x0`]: {
blockNumber: 2,
// null data indicates error
......@@ -306,7 +306,7 @@ describe('multicall reducer', () => {
)
expect(store.getState()).toEqual({
callResults: {
[1]: {
1: {
[`${DAI_ADDRESS}-0x0`]: { fetchingBlockNumber: 3 },
},
},
......
......@@ -6,8 +6,8 @@ describe('multicall updater', () => {
expect(
activeListeningKeys(
{
[1]: {
['abc']: {
1: {
abc: {
4: 2, // 2 listeners care about 4 block old data
1: 0, // 0 listeners care about 1 block old data
},
......@@ -23,8 +23,8 @@ describe('multicall updater', () => {
expect(
activeListeningKeys(
{
[1]: {
['abc']: {
1: {
abc: {
4: 2, // 2 listeners care about 4 block old data
3: 1, // 1 listener cares about 3 block old data
1: 0, // 0 listeners care about 1 block old data
......@@ -41,12 +41,12 @@ describe('multicall updater', () => {
expect(
activeListeningKeys(
{
[1]: {
['abc']: {
1: {
abc: {
4: 2, // 2 listeners care about 4 block old data
1: 0, // 0 listeners care about 1 block old data
},
['def']: {
def: {
Infinity: 2,
},
},
......@@ -62,12 +62,12 @@ describe('multicall updater', () => {
expect(
activeListeningKeys(
{
[1]: {
['abc']: {
1: {
abc: {
4: 2, // 2 listeners care about 4 block old data
1: 0, // 0 listeners care about 1 block old data
},
['def']: {
def: {
2: 1,
5: 2,
},
......@@ -84,8 +84,8 @@ describe('multicall updater', () => {
expect(
activeListeningKeys(
{
[1]: {
['abc']: {
1: {
abc: {
4: 2,
1: -1,
[-3]: 4,
......@@ -102,8 +102,8 @@ describe('multicall updater', () => {
expect(
activeListeningKeys(
{
[1]: {
['abc']: {
1: {
abc: {
Infinity: 2, // 2 listeners care about any data
4: 2, // 2 listeners care about 4 block old data
1: 0, // 0 listeners care about 1 block old data
......@@ -128,15 +128,15 @@ describe('multicall updater', () => {
expect(outdatedListeningKeys({}, { abc: 2, def: 3 }, 1, 1)).toEqual(['abc', 'def'])
})
it('returns only outdated keys', () => {
expect(outdatedListeningKeys({ [1]: { abc: { data: '0x', blockNumber: 2 } } }, { abc: 1, def: 1 }, 1, 2)).toEqual(
['def']
)
expect(outdatedListeningKeys({ 1: { abc: { data: '0x', blockNumber: 2 } } }, { abc: 1, def: 1 }, 1, 2)).toEqual([
'def',
])
})
it('returns only keys not being fetched', () => {
expect(
outdatedListeningKeys(
{
[1]: { abc: { data: '0x', blockNumber: 2 }, def: { fetchingBlockNumber: 2 } },
1: { abc: { data: '0x', blockNumber: 2 }, def: { fetchingBlockNumber: 2 } },
},
{ abc: 1, def: 1 },
1,
......@@ -147,7 +147,7 @@ describe('multicall updater', () => {
it('returns keys being fetched for old blocks', () => {
expect(
outdatedListeningKeys(
{ [1]: { abc: { data: '0x', blockNumber: 2 }, def: { fetchingBlockNumber: 1 } } },
{ 1: { abc: { data: '0x', blockNumber: 2 }, def: { fetchingBlockNumber: 1 } } },
{ abc: 1, def: 1 },
1,
2
......@@ -157,7 +157,7 @@ describe('multicall updater', () => {
it('respects blocks per fetch', () => {
expect(
outdatedListeningKeys(
{ [1]: { abc: { data: '0x', blockNumber: 2 }, def: { data: '0x', fetchingBlockNumber: 1 } } },
{ 1: { abc: { data: '0x', blockNumber: 2 }, def: { data: '0x', fetchingBlockNumber: 1 } } },
{ abc: 2, def: 2 },
1,
3
......
......@@ -24,7 +24,7 @@ export const STAKING_REWARDS_INFO: {
stakingRewardAddress: string
}[]
} = {
[1]: [
1: [
{
tokens: [WETH9_EXTENDED[1], DAI],
stakingRewardAddress: '0xa1484C3aa22a66C62b77E0AE78E15258bd0cB711',
......
......@@ -183,7 +183,7 @@ export function useDerivedSwapInfo(toggledVersion: Version | undefined): {
}
}, [toggledVersion, v2Trade, v3Trade.state, v3Trade.trade])
const bestTrade = isV2TradeBetter == undefined ? undefined : isV2TradeBetter ? v2Trade : v3Trade.trade
const bestTrade = isV2TradeBetter === undefined ? undefined : isV2TradeBetter ? v2Trade : v3Trade.trade
const currencyBalances = {
[Field.INPUT]: relevantTokenBalances[0],
......
......@@ -20,7 +20,7 @@ describe('transaction reducer', () => {
describe('updateVersion', () => {
it('clears old format transactions that do not have info', () => {
store = createStore(reducer, {
[1]: {
1: {
abc: {
hash: 'abc',
} as any,
......@@ -31,7 +31,7 @@ describe('transaction reducer', () => {
})
it('keeps old format transactions that do have info', () => {
store = createStore(reducer, {
[1]: {
1: {
abc: {
hash: 'abc',
info: {},
......
......@@ -153,53 +153,56 @@ const TextWrapper = styled(Text)<{ color: keyof Colors }>`
color: ${({ color, theme }) => (theme as any)[color]};
`
export const TYPE = {
main(props: TextProps) {
/**
* Preset styles of the Rebass Text component
*/
export const ThemedText = {
Main(props: TextProps) {
return <TextWrapper fontWeight={500} color={'text2'} {...props} />
},
link(props: TextProps) {
Link(props: TextProps) {
return <TextWrapper fontWeight={500} color={'primary1'} {...props} />
},
label(props: TextProps) {
Label(props: TextProps) {
return <TextWrapper fontWeight={600} color={'text1'} {...props} />
},
black(props: TextProps) {
Black(props: TextProps) {
return <TextWrapper fontWeight={500} color={'text1'} {...props} />
},
white(props: TextProps) {
White(props: TextProps) {
return <TextWrapper fontWeight={500} color={'white'} {...props} />
},
body(props: TextProps) {
Body(props: TextProps) {
return <TextWrapper fontWeight={400} fontSize={16} color={'text1'} {...props} />
},
largeHeader(props: TextProps) {
LargeHeader(props: TextProps) {
return <TextWrapper fontWeight={600} fontSize={24} {...props} />
},
mediumHeader(props: TextProps) {
MediumHeader(props: TextProps) {
return <TextWrapper fontWeight={500} fontSize={20} {...props} />
},
subHeader(props: TextProps) {
SubHeader(props: TextProps) {
return <TextWrapper fontWeight={400} fontSize={14} {...props} />
},
small(props: TextProps) {
Small(props: TextProps) {
return <TextWrapper fontWeight={500} fontSize={11} {...props} />
},
blue(props: TextProps) {
Blue(props: TextProps) {
return <TextWrapper fontWeight={500} color={'blue1'} {...props} />
},
yellow(props: TextProps) {
Yellow(props: TextProps) {
return <TextWrapper fontWeight={500} color={'yellow3'} {...props} />
},
darkGray(props: TextProps) {
DarkGray(props: TextProps) {
return <TextWrapper fontWeight={500} color={'text3'} {...props} />
},
gray(props: TextProps) {
Gray(props: TextProps) {
return <TextWrapper fontWeight={500} color={'bg3'} {...props} />
},
italic(props: TextProps) {
Italic(props: TextProps) {
return <TextWrapper fontWeight={500} fontSize={12} fontStyle={'italic'} color={'text2'} {...props} />
},
error({ error, ...props }: { error: boolean } & TextProps) {
Error({ error, ...props }: { error: boolean } & TextProps) {
return <TextWrapper fontWeight={500} color={error ? 'red1' : 'text2'} {...props} />
},
}
......
......@@ -18,7 +18,7 @@ export default function uriToHttp(uri: string): string[] {
const name = uri.match(/^ipns:(\/\/)?(.*)$/i)?.[2]
return [`https://cloudflare-ipfs.com/ipns/${name}/`, `https://ipfs.io/ipns/${name}/`]
case 'ar':
const tx = uri.match(/^ipns:(\/\/)?(.*)$/i)?.[2]
const tx = uri.match(/^ar:(\/\/)?(.*)$/i)?.[2]
return [`https://arweave.net/${tx}`]
default:
return []
......
......@@ -20372,9 +20372,9 @@ url-parse-lax@^3.0.0:
prepend-http "^2.0.0"
url-parse@^1.4.3, url-parse@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
version "1.5.3"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"
......@@ -21201,9 +21201,9 @@ ws@>=7.4.6:
integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==
ws@^5.1.1:
version "5.2.2"
resolved "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz"
integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==
version "5.2.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d"
integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==
dependencies:
async-limiter "~1.0.0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment