Commit 4ba9d98e authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

fix(L2): polish (#1988)

* polish

move getINfoLinkByChainId to chain constants

pr review - translations

optimism token list, typo, text color for L1 switch

use <Trans /> instead of t

undo unintentional tokenlist order change

use {'Optimism'} instead of {name}

switch deadline implementation

remove unused TYPE import

switch to generalized CHAIN_INFO instead of L2_INFO so we don't have to check in components

add target chain id param to optimism bridge

fix a minor breakpoint issue

reduce sigfigs for header balance

update network card dropdown text for optimism

remove list code

refactor SupportedChainId

* SupportedL1ChainId | SupportedL2ChainId -> SupportedChainId
parent 52790ac9
...@@ -9,10 +9,10 @@ import { useModalOpen, useToggleModal } from 'state/application/hooks' ...@@ -9,10 +9,10 @@ import { useModalOpen, useToggleModal } from 'state/application/hooks'
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme' import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { switchToNetwork } from 'utils/switchToNetwork' import { switchToNetwork } from 'utils/switchToNetwork'
import { L2_CHAIN_IDS, L2_INFO, NETWORK_LABELS, SupportedChainId } from '../../constants/chains' import { CHAIN_INFO, L2_CHAIN_IDS, NETWORK_LABELS, SupportedChainId, SupportedL2ChainId } from '../../constants/chains'
const StopOverflowQuery = `@media screen and (min-width: ${MEDIA_WIDTHS.upToMedium}px) and (max-width: ${ const StopOverflowQuery = `@media screen and (min-width: ${MEDIA_WIDTHS.upToMedium + 1}px) and (max-width: ${
MEDIA_WIDTHS.upToMedium + 400 MEDIA_WIDTHS.upToMedium + 500
}px)` }px)`
const BaseWrapper = css` const BaseWrapper = css`
...@@ -81,7 +81,7 @@ const L1Tag = styled.div` ...@@ -81,7 +81,7 @@ const L1Tag = styled.div`
color: #c4d9f8; color: #c4d9f8;
opacity: 40%; opacity: 40%;
` `
const L2Tag = styled.div<{ chainId: SupportedChainId }>` const L2Tag = styled.div<{ chainId: SupportedL2ChainId }>`
background-color: ${({ chainId }) => (chainId === SupportedChainId.ARBITRUM_ONE ? '#28A0F0' : '#FF0420')}; background-color: ${({ chainId }) => (chainId === SupportedChainId.ARBITRUM_ONE ? '#28A0F0' : '#FF0420')};
border-radius: 6px; border-radius: 6px;
color: white; color: white;
...@@ -131,8 +131,10 @@ const MenuItem = styled(ExternalLink)` ...@@ -131,8 +131,10 @@ const MenuItem = styled(ExternalLink)`
const ButtonMenuItem = styled.button` const ButtonMenuItem = styled.button`
${BaseMenuItem} ${BaseMenuItem}
border: none; border: none;
outline: none;
box-shadow: none; box-shadow: none;
color: ${({ theme }) => theme.text2};
outline: none;
padding-left: 0;
` `
const NetworkInfo = styled.button` const NetworkInfo = styled.button`
align-items: center; align-items: center;
...@@ -143,11 +145,12 @@ const NetworkInfo = styled.button` ...@@ -143,11 +145,12 @@ const NetworkInfo = styled.button`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
font-weight: 500; font-weight: 500;
font-size: 12px;
height: 100%; height: 100%;
justify-content: space-between; justify-content: space-between;
margin: 0; margin: 0;
padding: 8px; padding: 8px;
width: 172px; width: 188px;
:hover, :hover,
:focus { :focus {
...@@ -156,6 +159,9 @@ const NetworkInfo = styled.button` ...@@ -156,6 +159,9 @@ const NetworkInfo = styled.button`
background-color: ${({ theme }) => theme.bg3}; background-color: ${({ theme }) => theme.bg3};
} }
` `
const NetworkLabel = styled.span`
flex: 1 1 auto;
`
export default function NetworkCard() { export default function NetworkCard() {
const { chainId, library } = useActiveWeb3React() const { chainId, library } = useActiveWeb3React()
...@@ -182,26 +188,23 @@ export default function NetworkCard() { ...@@ -182,26 +188,23 @@ export default function NetworkCard() {
} }
if (L2_CHAIN_IDS.includes(chainId)) { if (L2_CHAIN_IDS.includes(chainId)) {
const info = L2_INFO[chainId] const info = CHAIN_INFO[chainId as SupportedL2ChainId]
const isArbitrum = [SupportedChainId.ARBITRUM_ONE, SupportedChainId.ARBITRUM_RINKEBY].includes(chainId)
return ( return (
<L2Wrapper ref={node}> <L2Wrapper ref={node}>
<NetworkInfo onClick={toggle}> <NetworkInfo onClick={toggle}>
<Icon src={info.logoUrl} /> <Icon src={info.logoUrl} />
<span>{NETWORK_LABELS[chainId]}</span> <NetworkLabel>{info.label}</NetworkLabel>
<L2Tag chainId={chainId}>L2 Alpha</L2Tag> <L2Tag chainId={chainId}>L2</L2Tag>
</NetworkInfo> </NetworkInfo>
{open && ( {open && (
<MenuFlyout> <MenuFlyout>
<MenuItem href={info.bridge}> <MenuItem href={info.bridge}>
<div> <div>{isArbitrum ? <Trans>{info.label} Bridge</Trans> : <Trans>Optimism Gateway</Trans>}</div>
<Trans>{NETWORK_LABELS[chainId]} Bridge</Trans>
</div>
<LinkOutCircle /> <LinkOutCircle />
</MenuItem> </MenuItem>
<MenuItem href={info.explorer}> <MenuItem href={info.explorer}>
<div> {isArbitrum ? <Trans>{info.label} Explorer</Trans> : <Trans>Etherscan</Trans>}
<Trans>{NETWORK_LABELS[chainId]} Explorer</Trans>
</div>
<LinkOutCircle /> <LinkOutCircle />
</MenuItem> </MenuItem>
<MenuItem href={info.docs}> <MenuItem href={info.docs}>
......
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Token } from '@uniswap/sdk-core' import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { useMemo } from 'react' import { useMemo } from 'react'
import { X } from 'react-feather' import { X } from 'react-feather'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import tokenLogo from '../../assets/images/token-logo.png' import tokenLogo from '../../assets/images/token-logo.png'
import { UNI } from '../../constants/tokens' import { UNI } from '../../constants/tokens'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks/web3'
import { useMerkleDistributorContract } from '../../hooks/useContract' import { useMerkleDistributorContract } from '../../hooks/useContract'
import useCurrentBlockTimestamp from '../../hooks/useCurrentBlockTimestamp' import useCurrentBlockTimestamp from '../../hooks/useCurrentBlockTimestamp'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import useUSDCPrice from '../../hooks/useUSDCPrice'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTotalUniEarned } from '../../state/stake/hooks' import { useTotalUniEarned } from '../../state/stake/hooks'
import { useAggregateUniBalance, useTokenBalance } from '../../state/wallet/hooks' import { useAggregateUniBalance, useTokenBalance } from '../../state/wallet/hooks'
import { ExternalLink, StyledInternalLink, TYPE, UniTokenAnimated } from '../../theme' import { ExternalLink, StyledInternalLink, TYPE, UniTokenAnimated } from '../../theme'
import { computeUniCirculation } from '../../utils/computeUniCirculation' import { computeUniCirculation } from '../../utils/computeUniCirculation'
import useUSDCPrice from '../../hooks/useUSDCPrice'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
import { RowBetween } from '../Row'
import { Break, CardBGImage, CardNoise, CardSection, DataCard } from '../earn/styled' import { Break, CardBGImage, CardNoise, CardSection, DataCard } from '../earn/styled'
import { Trans } from '@lingui/macro' import { RowBetween } from '../Row'
const ContentWrapper = styled(AutoColumn)` const ContentWrapper = styled(AutoColumn)`
width: 100%; width: 100%;
...@@ -59,6 +60,8 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU ...@@ -59,6 +60,8 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
[blockTimestamp, chainId, totalSupply, unclaimedUni, uni] [blockTimestamp, chainId, totalSupply, unclaimedUni, uni]
) )
const { infoLink } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
return ( return (
<ContentWrapper gap="lg"> <ContentWrapper gap="lg">
<ModalUpper> <ModalUpper>
...@@ -128,7 +131,7 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU ...@@ -128,7 +131,7 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
<TYPE.white color="white">{totalSupply?.toFixed(0, { groupSeparator: ',' })}</TYPE.white> <TYPE.white color="white">{totalSupply?.toFixed(0, { groupSeparator: ',' })}</TYPE.white>
</RowBetween> </RowBetween>
{uni && uni.chainId === 1 ? ( {uni && uni.chainId === 1 ? (
<ExternalLink href={`https://info.uniswap.org/token/${uni.address}`}> <ExternalLink href={`${infoLink}/token/${uni.address}`}>
<Trans>View UNI Analytics</Trans> <Trans>View UNI Analytics</Trans>
</ExternalLink> </ExternalLink>
) : null} ) : null}
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import useScrollPosition from '@react-hook/window-scroll' import useScrollPosition from '@react-hook/window-scroll'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { darken } from 'polished' import { darken } from 'polished'
import { useState } from 'react' import { useState } from 'react'
import { Moon, Sun } from 'react-feather' import { Moon, Sun } from 'react-feather'
...@@ -285,7 +286,7 @@ const StyledMenuButton = styled.button` ...@@ -285,7 +286,7 @@ const StyledMenuButton = styled.button`
` `
export default function Header() { export default function Header() {
const { account } = useActiveWeb3React() const { account, chainId } = useActiveWeb3React()
const userEthBalance = useETHBalances(account ? [account] : [])?.[account ?? ''] const userEthBalance = useETHBalances(account ? [account] : [])?.[account ?? '']
// const [isDark] = useDarkModeManager() // const [isDark] = useDarkModeManager()
...@@ -302,6 +303,7 @@ export default function Header() { ...@@ -302,6 +303,7 @@ export default function Header() {
const scrollY = useScrollPosition() const scrollY = useScrollPosition()
const { infoLink } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
return ( return (
<HeaderFrame showBackground={scrollY > 45}> <HeaderFrame showBackground={scrollY > 45}>
<ClaimModal /> <ClaimModal />
...@@ -335,7 +337,7 @@ export default function Header() { ...@@ -335,7 +337,7 @@ export default function Header() {
<StyledNavLink id={`stake-nav-link`} to={'/vote'}> <StyledNavLink id={`stake-nav-link`} to={'/vote'}>
<Trans>Vote</Trans> <Trans>Vote</Trans>
</StyledNavLink> </StyledNavLink>
<StyledExternalLink id={`stake-nav-link`} href={'https://info.uniswap.org'}> <StyledExternalLink id={`stake-nav-link`} href={infoLink}>
<Trans>Charts</Trans> <Trans>Charts</Trans>
<sup></sup> <sup></sup>
</StyledExternalLink> </StyledExternalLink>
...@@ -364,7 +366,7 @@ export default function Header() { ...@@ -364,7 +366,7 @@ export default function Header() {
<AccountElement active={!!account} style={{ pointerEvents: 'auto' }}> <AccountElement active={!!account} style={{ pointerEvents: 'auto' }}>
{account && userEthBalance ? ( {account && userEthBalance ? (
<BalanceText style={{ flexShrink: 0 }} pl="0.75rem" pr="0.5rem" fontWeight={500}> <BalanceText style={{ flexShrink: 0 }} pl="0.75rem" pr="0.5rem" fontWeight={500}>
<Trans>{userEthBalance?.toSignificant(4)} ETH</Trans> <Trans>{userEthBalance?.toSignificant(3)} ETH</Trans>
</BalanceText> </BalanceText>
) : null} ) : null}
<Web3Status /> <Web3Status />
......
...@@ -10,7 +10,7 @@ import { useModalOpen, useToggleModal } from '../../state/application/hooks' ...@@ -10,7 +10,7 @@ import { useModalOpen, useToggleModal } from '../../state/application/hooks'
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { ExternalLink } from '../../theme' import { ExternalLink } from '../../theme'
import { ButtonPrimary } from '../Button' import { ButtonPrimary } from '../Button'
import { L2_CHAIN_IDS } from 'constants/chains' import { L2_CHAIN_IDS, CHAIN_INFO, SupportedChainId } from 'constants/chains'
export enum FlyoutAlignment { export enum FlyoutAlignment {
LEFT = 'LEFT', LEFT = 'LEFT',
...@@ -133,7 +133,7 @@ export default function Menu() { ...@@ -133,7 +133,7 @@ export default function Menu() {
useOnClickOutside(node, open ? toggle : undefined) useOnClickOutside(node, open ? toggle : undefined)
const openClaimModal = useToggleModal(ApplicationModal.ADDRESS_CLAIM) const openClaimModal = useToggleModal(ApplicationModal.ADDRESS_CLAIM)
const showUNIClaimOption = Boolean(!!account && !!chainId && !L2_CHAIN_IDS.includes(chainId)) const showUNIClaimOption = Boolean(!!account && !!chainId && !L2_CHAIN_IDS.includes(chainId))
const { infoLink } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
return ( return (
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30451 // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30451
<StyledMenu ref={node as any}> <StyledMenu ref={node as any}>
...@@ -167,7 +167,7 @@ export default function Menu() { ...@@ -167,7 +167,7 @@ export default function Menu() {
<Trans>Discord</Trans> <Trans>Discord</Trans>
</div> </div>
</MenuItem> </MenuItem>
<MenuItem href="https://info.uniswap.org/"> <MenuItem href={infoLink}>
<PieChart size={14} /> <PieChart size={14} />
<div> <div>
<Trans>Analytics</Trans> <Trans>Analytics</Trans>
......
...@@ -5,7 +5,7 @@ import { ...@@ -5,7 +5,7 @@ import {
OptimismWrapperBackgroundDarkMode, OptimismWrapperBackgroundDarkMode,
OptimismWrapperBackgroundLightMode, OptimismWrapperBackgroundLightMode,
} from 'components/NetworkAlert/NetworkAlert' } from 'components/NetworkAlert/NetworkAlert'
import { L2_CHAIN_IDS, L2_INFO, NETWORK_LABELS, SupportedChainId } from 'constants/chains' import { CHAIN_INFO, L2_CHAIN_IDS, NETWORK_LABELS, SupportedChainId, SupportedL2ChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3' import { useActiveWeb3React } from 'hooks/web3'
import { ArrowDownCircle } from 'react-feather' import { ArrowDownCircle } from 'react-feather'
import { useArbitrumAlphaAlert, useDarkModeManager } from 'state/user/hooks' import { useArbitrumAlphaAlert, useDarkModeManager } from 'state/user/hooks'
...@@ -27,9 +27,9 @@ const DesktopTextBreak = styled.div` ...@@ -27,9 +27,9 @@ const DesktopTextBreak = styled.div`
display: block; display: block;
} }
` `
const Wrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; logoUrl: string }>` const Wrapper = styled.div<{ chainId: SupportedL2ChainId; darkMode: boolean; logoUrl: string }>`
${({ chainId, darkMode }) => ${({ chainId, darkMode }) =>
chainId === SupportedChainId.OPTIMISM [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
? darkMode ? darkMode
? OptimismWrapperBackgroundDarkMode ? OptimismWrapperBackgroundDarkMode
: OptimismWrapperBackgroundLightMode : OptimismWrapperBackgroundLightMode
...@@ -62,18 +62,19 @@ const Wrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; logoU ...@@ -62,18 +62,19 @@ const Wrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; logoU
} }
` `
const Body = styled.div` const Body = styled.div`
font-size: 12px;
line-height: 143%; line-height: 143%;
margin: 12px; margin: 12px;
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) { @media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
margin: 16px 20px 31px;
flex: 1 1 auto; flex: 1 1 auto;
margin: 0; margin: auto 0;
} }
` `
const LinkOutCircle = styled(ArrowDownCircle)` const LinkOutCircle = styled(ArrowDownCircle)`
transform: rotate(230deg); transform: rotate(230deg);
width: 20px; width: 20px;
height: 20px; height: 20px;
margin-left: 12px;
` `
const LinkOutToBridge = styled.a` const LinkOutToBridge = styled.a`
align-items: center; align-items: center;
...@@ -81,10 +82,11 @@ const LinkOutToBridge = styled.a` ...@@ -81,10 +82,11 @@ const LinkOutToBridge = styled.a`
border-radius: 16px; border-radius: 16px;
color: white; color: white;
display: flex; display: flex;
font-size: 14px;
justify-content: space-between; justify-content: space-between;
margin: 0; margin: 0;
max-height: 47px; max-height: 47px;
padding: 14px; padding: 16px 8px;
text-decoration: none; text-decoration: none;
width: auto; width: auto;
:hover, :hover,
...@@ -106,15 +108,18 @@ export function MinimalNetworkAlert() { ...@@ -106,15 +108,18 @@ export function MinimalNetworkAlert() {
if (!chainId || !L2_CHAIN_IDS.includes(chainId) || arbitrumAlphaAcknowledged) { if (!chainId || !L2_CHAIN_IDS.includes(chainId) || arbitrumAlphaAcknowledged) {
return null return null
} }
const info = L2_INFO[chainId] const info = CHAIN_INFO[chainId as SupportedL2ChainId]
const depositUrl = [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
? `${info.bridge}?chainId=1`
: info.bridge
return ( return (
<Wrapper darkMode={darkMode} chainId={chainId} logoUrl={info.logoUrl}> <Wrapper darkMode={darkMode} chainId={chainId} logoUrl={info.logoUrl}>
<L2Icon src={info.logoUrl} /> <L2Icon src={info.logoUrl} />
<Body> <Body>
<Trans>This is an alpha release of Uniswap on the {NETWORK_LABELS[chainId]} network.</Trans> <Trans>This is an alpha release of Uniswap on the {NETWORK_LABELS[chainId]} network.</Trans>
<DesktopTextBreak /> <Trans>You must bridge L1 assets to the network to swap them.</Trans> <DesktopTextBreak /> <Trans>You must bridge L1 assets to the network to use them.</Trans>
</Body> </Body>
<LinkOutToBridge href={info.bridge} target="_blank" rel="noopener noreferrer"> <LinkOutToBridge href={depositUrl} target="_blank" rel="noopener noreferrer">
<Trans>Deposit to {NETWORK_LABELS[chainId]}</Trans> <Trans>Deposit to {NETWORK_LABELS[chainId]}</Trans>
<LinkOutCircle /> <LinkOutCircle />
</LinkOutToBridge> </LinkOutToBridge>
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { L2_CHAIN_IDS, NETWORK_LABELS, SupportedChainId } from 'constants/chains' import { L2_CHAIN_IDS, NETWORK_LABELS, SupportedChainId, SupportedL2ChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3' import { useActiveWeb3React } from 'hooks/web3'
import { useCallback, useState } from 'react' import { useCallback, useState } from 'react'
import { ArrowDownCircle, X } from 'react-feather' import { ArrowDownCircle, X } from 'react-feather'
import { useArbitrumAlphaAlert, useDarkModeManager } from 'state/user/hooks' import { useArbitrumAlphaAlert, useDarkModeManager } from 'state/user/hooks'
import { useETHBalances } from 'state/wallet/hooks' import { useETHBalances } from 'state/wallet/hooks'
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
import { MEDIA_WIDTHS, TYPE } from 'theme' import { MEDIA_WIDTHS } from 'theme'
import { L2_INFO } from '../../constants/chains' import { CHAIN_INFO } from '../../constants/chains'
const L2Icon = styled.img` const L2Icon = styled.img`
width: 40px; width: 40px;
...@@ -48,9 +48,9 @@ export const OptimismWrapperBackgroundLightMode = css` ...@@ -48,9 +48,9 @@ export const OptimismWrapperBackgroundLightMode = css`
background: radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%), background: radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),
radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.5); radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.5);
` `
const RootWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; logoUrl: string }>` const RootWrapper = styled.div<{ chainId: number; darkMode: boolean; logoUrl: string }>`
${({ chainId, darkMode }) => ${({ chainId, darkMode }) =>
chainId === SupportedChainId.OPTIMISM [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
? darkMode ? darkMode
? OptimismWrapperBackgroundDarkMode ? OptimismWrapperBackgroundDarkMode
: OptimismWrapperBackgroundLightMode : OptimismWrapperBackgroundLightMode
...@@ -61,7 +61,7 @@ const RootWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; l ...@@ -61,7 +61,7 @@ const RootWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; l
display: flex; display: flex;
flex-direction: column; flex-direction: column;
max-width: 480px; max-width: 480px;
min-height: 218px; min-height: 174px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
width: 100%; width: 100%;
...@@ -79,11 +79,14 @@ const RootWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; l ...@@ -79,11 +79,14 @@ const RootWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; l
z-index: -1; z-index: -1;
} }
` `
const Header = styled(TYPE.largeHeader)` const Header = styled.h2`
font-weight: 600;
font-size: 20px;
margin: 0; margin: 0;
padding-right: 30px; padding-right: 30px;
` `
const Body = styled.p` const Body = styled.p`
font-size: 12px;
grid-column: 1 / 3; grid-column: 1 / 3;
line-height: 143%; line-height: 143%;
margin: 0; margin: 0;
...@@ -102,9 +105,11 @@ const LinkOutToBridge = styled.a` ...@@ -102,9 +105,11 @@ const LinkOutToBridge = styled.a`
border-radius: 16px; border-radius: 16px;
color: white; color: white;
display: flex; display: flex;
font-size: 16px;
height: 44px;
justify-content: space-between; justify-content: space-between;
margin: 0 18px 18px 18px; margin: 0 20px 20px 20px;
padding: 14px 24px; padding: 12px 16px;
text-decoration: none; text-decoration: none;
width: auto; width: auto;
:hover, :hover,
...@@ -130,7 +135,10 @@ export function NetworkAlert() { ...@@ -130,7 +135,10 @@ export function NetworkAlert() {
if (!chainId || !L2_CHAIN_IDS.includes(chainId) || arbitrumAlphaAcknowledged || locallyDismissed) { if (!chainId || !L2_CHAIN_IDS.includes(chainId) || arbitrumAlphaAcknowledged || locallyDismissed) {
return null return null
} }
const info = L2_INFO[chainId] const info = CHAIN_INFO[chainId as SupportedL2ChainId]
const depositUrl = [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
? `${info.bridge}?chainId=1`
: info.bridge
return ( return (
<RootWrapper chainId={chainId} darkMode={darkMode} logoUrl={info.logoUrl}> <RootWrapper chainId={chainId} darkMode={darkMode} logoUrl={info.logoUrl}>
<CloseIcon onClick={dismiss} /> <CloseIcon onClick={dismiss} />
...@@ -146,7 +154,7 @@ export function NetworkAlert() { ...@@ -146,7 +154,7 @@ export function NetworkAlert() {
</Trans> </Trans>
</Body> </Body>
</ContentWrapper> </ContentWrapper>
<LinkOutToBridge href={info.bridge} target="_blank" rel="noopener noreferrer"> <LinkOutToBridge href={depositUrl} target="_blank" rel="noopener noreferrer">
<Trans>Deposit to {NETWORK_LABELS[chainId]}</Trans> <Trans>Deposit to {NETWORK_LABELS[chainId]}</Trans>
<LinkOutCircle /> <LinkOutCircle />
</LinkOutToBridge> </LinkOutToBridge>
......
import { Trans } from '@lingui/macro'
import { SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import { AlertOctagon } from 'react-feather'
import styled from 'styled-components/macro'
const Root = styled.div`
background-color: ${({ theme }) => theme.yellow3};
border-radius: 18px;
color: black;
margin-top: 16px;
max-width: 480px;
padding: 16px;
width: 100%;
`
const WarningIcon = styled(AlertOctagon)`
margin: 0 8px 0 0;
`
const TitleRow = styled.div`
align-items: center;
display: flex;
flex-direction: row;
justify-content: flex-start;
margin: 0;
font-size: 20px;
font-weight: 600;
line-height: 25px;
`
const Body = styled.div`
font-size: 12px;
line-height: 15px;
margin: 8px 0 0 0;
`
const LinkOutToNotion = styled.a`
color: black;
`
export default function OptimismDowntimeWarning() {
const { chainId } = useActiveWeb3React()
if (!chainId || ![SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)) {
return null
}
return (
<Root>
<TitleRow>
<WarningIcon />
<Trans>{'Optimism'} Scheduled Downtimes</Trans>
</TitleRow>
<Body>
<Trans>
{'Optimism'} expects some scheduled downtime in the near future.&nbsp;
<LinkOutToNotion
href={`https://www.notion.so/Optimism-Regenesis-Schedule-8d14a34902ca4f5a8910762b3ec4b8da`}
target="_blank"
rel="noopener noreferrer"
>
Read more.
</LinkOutToNotion>
</Trans>
</Body>
</Root>
)
}
import { Web3Provider } from '@ethersproject/providers' import { Web3Provider } from '@ethersproject/providers'
import { InjectedConnector } from '@web3-react/injected-connector' import { InjectedConnector } from '@web3-react/injected-connector'
import { PortisConnector } from '@web3-react/portis-connector'
import { WalletConnectConnector } from '@web3-react/walletconnect-connector' import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { WalletLinkConnector } from '@web3-react/walletlink-connector' import { WalletLinkConnector } from '@web3-react/walletlink-connector'
import { PortisConnector } from '@web3-react/portis-connector' import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
import { SupportedChainId } from '../constants/chains' import { SupportedChainId } from '../constants/chains'
import getLibrary from '../utils/getLibrary' import getLibrary from '../utils/getLibrary'
import { FortmaticConnector } from './Fortmatic' import { FortmaticConnector } from './Fortmatic'
import { NetworkConnector } from './NetworkConnector' import { NetworkConnector } from './NetworkConnector'
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
const INFURA_KEY = process.env.REACT_APP_INFURA_KEY const INFURA_KEY = process.env.REACT_APP_INFURA_KEY
const FORMATIC_KEY = process.env.REACT_APP_FORTMATIC_KEY const FORMATIC_KEY = process.env.REACT_APP_FORTMATIC_KEY
...@@ -19,9 +18,7 @@ if (typeof INFURA_KEY === 'undefined') { ...@@ -19,9 +18,7 @@ if (typeof INFURA_KEY === 'undefined') {
throw new Error(`REACT_APP_INFURA_KEY must be a defined environment variable`) throw new Error(`REACT_APP_INFURA_KEY must be a defined environment variable`)
} }
const NETWORK_URLS: { const NETWORK_URLS = {
[chainId in SupportedChainId]: string
} = {
[SupportedChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`, [SupportedChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`, [SupportedChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`, [SupportedChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
...@@ -33,7 +30,7 @@ const NETWORK_URLS: { ...@@ -33,7 +30,7 @@ const NETWORK_URLS: {
[SupportedChainId.ARBITRUM_RINKEBY]: `https://rinkeby.arbitrum.io/rpc`, [SupportedChainId.ARBITRUM_RINKEBY]: `https://rinkeby.arbitrum.io/rpc`,
} }
const SUPPORTED_CHAIN_IDS: SupportedChainId[] = [ const SUPPORTED_CHAIN_IDS = [
SupportedChainId.MAINNET, SupportedChainId.MAINNET,
SupportedChainId.KOVAN, SupportedChainId.KOVAN,
SupportedChainId.GOERLI, SupportedChainId.GOERLI,
...@@ -81,7 +78,7 @@ export const portis = new PortisConnector({ ...@@ -81,7 +78,7 @@ export const portis = new PortisConnector({
// mainnet only // mainnet only
export const walletlink = new WalletLinkConnector({ export const walletlink = new WalletLinkConnector({
url: NETWORK_URLS[1], url: NETWORK_URLS[SupportedChainId.MAINNET],
appName: 'Uniswap', appName: 'Uniswap',
appLogoUrl: UNISWAP_LOGO_URL, appLogoUrl: UNISWAP_LOGO_URL,
}) })
...@@ -7,28 +7,25 @@ export enum SupportedChainId { ...@@ -7,28 +7,25 @@ export enum SupportedChainId {
RINKEBY = 4, RINKEBY = 4,
GOERLI = 5, GOERLI = 5,
KOVAN = 42, KOVAN = 42,
ARBITRUM_ONE = 42161, ARBITRUM_ONE = 42161,
ARBITRUM_RINKEBY = 421611, ARBITRUM_RINKEBY = 421611,
OPTIMISM = 10, OPTIMISM = 10,
OPTIMISTIC_KOVAN = 69, OPTIMISTIC_KOVAN = 69,
} }
export const L2_CHAIN_IDS = [SupportedChainId.ARBITRUM_ONE, SupportedChainId.OPTIMISM] export type SupportedL2ChainId =
| SupportedChainId.ARBITRUM_ONE
| SupportedChainId.ARBITRUM_RINKEBY
| SupportedChainId.OPTIMISM
| SupportedChainId.OPTIMISTIC_KOVAN
export const L2_INFO: Record<number, { bridge: string; docs: string; explorer: string; logoUrl: string }> = { export type SupportedL1ChainId =
[SupportedChainId.OPTIMISM]: { | SupportedChainId.MAINNET
bridge: 'https://gateway.optimism.io/', | SupportedChainId.ROPSTEN
docs: 'https://optimism.io/', | SupportedChainId.RINKEBY
explorer: 'https://optimistic.etherscan.io/', | SupportedChainId.GOERLI
logoUrl: optimismLogoUrl, | SupportedChainId.KOVAN
},
[SupportedChainId.ARBITRUM_ONE]: {
bridge: 'https://bridge.arbitrum.io/',
explorer: 'https://explorer.arbitrum.io/',
docs: 'https://offchainlabs.com/',
logoUrl: arbitrumLogoUrl,
},
}
export const NETWORK_LABELS: { [chainId in SupportedChainId | number]: string } = { export const NETWORK_LABELS: { [chainId in SupportedChainId | number]: string } = {
[SupportedChainId.MAINNET]: 'Mainnet', [SupportedChainId.MAINNET]: 'Mainnet',
...@@ -37,7 +34,100 @@ export const NETWORK_LABELS: { [chainId in SupportedChainId | number]: string } ...@@ -37,7 +34,100 @@ export const NETWORK_LABELS: { [chainId in SupportedChainId | number]: string }
[SupportedChainId.GOERLI]: 'Görli', [SupportedChainId.GOERLI]: 'Görli',
[SupportedChainId.KOVAN]: 'Kovan', [SupportedChainId.KOVAN]: 'Kovan',
[SupportedChainId.ARBITRUM_ONE]: 'Arbitrum', [SupportedChainId.ARBITRUM_ONE]: 'Arbitrum',
[SupportedChainId.ARBITRUM_RINKEBY]: 'Arbitrum Testnet', [SupportedChainId.ARBITRUM_RINKEBY]: 'Arbitrum Rinkeby',
[SupportedChainId.OPTIMISM]: 'Optimism', [SupportedChainId.OPTIMISM]: 'Optimistic Ethereum',
[SupportedChainId.OPTIMISTIC_KOVAN]: 'Optimism Testnet', [SupportedChainId.OPTIMISTIC_KOVAN]: 'Optimistic Kovan',
} as const
export const L1_CHAIN_IDS = [
SupportedChainId.MAINNET,
SupportedChainId.ROPSTEN,
SupportedChainId.RINKEBY,
SupportedChainId.GOERLI,
SupportedChainId.KOVAN,
]
export const L2_CHAIN_IDS = [
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.OPTIMISM,
SupportedChainId.OPTIMISTIC_KOVAN,
]
interface L1ChainInfo {
docs: string
explorer: string
infoLink: string
label: string
}
interface L2ChainInfo extends L1ChainInfo {
bridge: string
logoUrl: string
}
type ChainInfo = { [chainId in SupportedL2ChainId]: L2ChainInfo } &
{ [chainId in SupportedL1ChainId]: L1ChainInfo } & { [chainId: number]: L1ChainInfo | L2ChainInfo }
export const CHAIN_INFO: ChainInfo = {
[SupportedChainId.ARBITRUM_ONE]: {
bridge: 'https://bridge.arbitrum.io/',
docs: 'https://offchainlabs.com/',
explorer: 'https://explorer.arbitrum.io/',
infoLink: 'https://info.uniswap.org/#/arbitrum',
label: NETWORK_LABELS[SupportedChainId.ARBITRUM_ONE],
logoUrl: arbitrumLogoUrl,
},
[SupportedChainId.ARBITRUM_RINKEBY]: {
bridge: 'https://bridge.arbitrum.io/',
docs: 'https://offchainlabs.com/',
explorer: 'https://explorer.arbitrum.io/',
infoLink: 'https://info.uniswap.org/#/arbitrum',
label: NETWORK_LABELS[SupportedChainId.ARBITRUM_RINKEBY],
logoUrl: arbitrumLogoUrl,
},
[SupportedChainId.MAINNET]: {
docs: 'https://docs.uniswap.org/',
explorer: 'https://etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: NETWORK_LABELS[SupportedChainId.MAINNET],
},
[SupportedChainId.RINKEBY]: {
docs: 'https://docs.uniswap.org/',
explorer: 'https://rinkeby.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: NETWORK_LABELS[SupportedChainId.RINKEBY],
},
[SupportedChainId.ROPSTEN]: {
docs: 'https://docs.uniswap.org/',
explorer: 'https://ropsten.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: NETWORK_LABELS[SupportedChainId.ROPSTEN],
},
[SupportedChainId.KOVAN]: {
docs: 'https://docs.uniswap.org/',
explorer: 'https://kovan.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: NETWORK_LABELS[SupportedChainId.KOVAN],
},
[SupportedChainId.GOERLI]: {
docs: 'https://docs.uniswap.org/',
explorer: 'https://goerli.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/',
label: NETWORK_LABELS[SupportedChainId.GOERLI],
},
[SupportedChainId.OPTIMISM]: {
bridge: 'https://gateway.optimism.io/',
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/optimism',
label: NETWORK_LABELS[SupportedChainId.OPTIMISM],
logoUrl: optimismLogoUrl,
},
[SupportedChainId.OPTIMISTIC_KOVAN]: {
bridge: 'https://gateway.optimism.io/',
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
infoLink: 'https://info.uniswap.org/#/optimism',
label: NETWORK_LABELS[SupportedChainId.OPTIMISTIC_KOVAN],
logoUrl: optimismLogoUrl,
},
} }
// used to mark unsupported tokens, these are hosted lists of unsupported tokens
const COMPOUND_LIST = 'https://raw.githubusercontent.com/compound-finance/token-list/master/compound.tokenlist.json'
const UMA_LIST = 'https://umaproject.org/uma.tokenlist.json'
const AAVE_LIST = 'tokenlist.aave.eth' const AAVE_LIST = 'tokenlist.aave.eth'
const WRAPPED_LIST = 'wrapped.tokensoft.eth' const BA_LIST = 'https://raw.githubusercontent.com/The-Blockchain-Association/sec-notice-list/master/ba-sec-list.json'
const SET_LIST = 'https://raw.githubusercontent.com/SetProtocol/uniswap-tokenlist/main/set.tokenlist.json'
const ROLL_LIST = 'https://app.tryroll.com/tokens.json'
const COINGECKO_LIST = 'https://tokens.coingecko.com/uniswap/all.json'
const CMC_ALL_LIST = 'defi.cmc.eth' const CMC_ALL_LIST = 'defi.cmc.eth'
const CMC_STABLECOIN = 'stablecoin.cmc.eth' const CMC_STABLECOIN = 'stablecoin.cmc.eth'
const KLEROS_LIST = 't2crtokens.eth' const COINGECKO_LIST = 'https://tokens.coingecko.com/uniswap/all.json'
const COMPOUND_LIST = 'https://raw.githubusercontent.com/compound-finance/token-list/master/compound.tokenlist.json'
const GEMINI_LIST = 'https://www.gemini.com/uniswap/manifest.json' const GEMINI_LIST = 'https://www.gemini.com/uniswap/manifest.json'
const BA_LIST = 'https://raw.githubusercontent.com/The-Blockchain-Association/sec-notice-list/master/ba-sec-list.json' const KLEROS_LIST = 't2crtokens.eth'
export const OPTIMISM_LIST = 'https://static.optimism.io/optimism.tokenlist.json'
const ROLL_LIST = 'https://app.tryroll.com/tokens.json'
const SET_LIST = 'https://raw.githubusercontent.com/SetProtocol/uniswap-tokenlist/main/set.tokenlist.json'
const UMA_LIST = 'https://umaproject.org/uma.tokenlist.json'
const WRAPPED_LIST = 'wrapped.tokensoft.eth'
// used to mark unsupported tokens, these are hosted lists of unsupported tokens
export const UNSUPPORTED_LIST_URLS: string[] = [BA_LIST] export const UNSUPPORTED_LIST_URLS: string[] = [BA_LIST]
// lower index == higher priority for token import // lower index == higher priority for token import
export const DEFAULT_LIST_OF_LISTS: string[] = [ export const DEFAULT_LIST_OF_LISTS: string[] = [
COMPOUND_LIST, COMPOUND_LIST,
AAVE_LIST, AAVE_LIST,
OPTIMISM_LIST,
UMA_LIST, UMA_LIST,
WRAPPED_LIST, WRAPPED_LIST,
SET_LIST, SET_LIST,
......
...@@ -7,6 +7,7 @@ export const NetworkContextName = 'NETWORK' ...@@ -7,6 +7,7 @@ export const NetworkContextName = 'NETWORK'
// 30 minutes, denominated in seconds // 30 minutes, denominated in seconds
export const DEFAULT_DEADLINE_FROM_NOW = 60 * 30 export const DEFAULT_DEADLINE_FROM_NOW = 60 * 30
export const L2_DEADLINE_FROM_NOW = 60 * 5
// used for rewards deadlines // used for rewards deadlines
export const BIG_INT_SECONDS_IN_WEEK = JSBI.BigInt(60 * 60 * 24 * 7) export const BIG_INT_SECONDS_IN_WEEK = JSBI.BigInt(60 * 60 * 24 * 7)
......
import { L2_CHAIN_IDS } from 'constants/chains'
import { L2_DEADLINE_FROM_NOW } from 'constants/misc'
import { BigNumber } from 'ethers' import { BigNumber } from 'ethers'
import { useMemo } from 'react' import { useMemo } from 'react'
import { useAppSelector } from 'state/hooks' import { useAppSelector } from 'state/hooks'
import useCurrentBlockTimestamp from './useCurrentBlockTimestamp' 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 // 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 { export default function useTransactionDeadline(): BigNumber | undefined {
const { chainId } = useActiveWeb3React()
const ttl = useAppSelector((state) => state.user.userDeadline) const ttl = useAppSelector((state) => state.user.userDeadline)
const blockTimestamp = useCurrentBlockTimestamp() const blockTimestamp = useCurrentBlockTimestamp()
return useMemo(() => { return useMemo(() => {
if (blockTimestamp && chainId && L2_CHAIN_IDS.includes(chainId)) return blockTimestamp.add(L2_DEADLINE_FROM_NOW)
if (blockTimestamp && ttl) return blockTimestamp.add(ttl) if (blockTimestamp && ttl) return blockTimestamp.add(ttl)
return undefined return undefined
}, [blockTimestamp, ttl]) }, [blockTimestamp, chainId, ttl])
} }
...@@ -71,6 +71,7 @@ import { SwitchLocaleLink } from 'components/SwitchLocaleLink' ...@@ -71,6 +71,7 @@ import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import PresetsButtons from 'components/RangeSelector/PresetsButtons' import PresetsButtons from 'components/RangeSelector/PresetsButtons'
import LiquidityChartRangeInput from 'components/LiquidityChartRangeInput' import LiquidityChartRangeInput from 'components/LiquidityChartRangeInput'
import { SupportedChainId } from 'constants/chains' import { SupportedChainId } from 'constants/chains'
import OptimismDowntimeWarning from 'components/OptimismDowntimeWarning'
const DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE = new Percent(50, 10_000) const DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
...@@ -541,6 +542,7 @@ export default function AddLiquidity({ ...@@ -541,6 +542,7 @@ export default function AddLiquidity({
<> <>
<ScrollablePage> <ScrollablePage>
<NetworkAlert /> <NetworkAlert />
<OptimismDowntimeWarning />
<TransactionConfirmationModal <TransactionConfirmationModal
isOpen={showConfirm} isOpen={showConfirm}
onDismiss={handleDismissConfirmation} onDismiss={handleDismissConfirmation}
......
...@@ -2,6 +2,8 @@ import { Trans } from '@lingui/macro' ...@@ -2,6 +2,8 @@ import { Trans } from '@lingui/macro'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import { MinimalNetworkAlert } from 'components/NetworkAlert/MinimalNetworkAlert' import { MinimalNetworkAlert } from 'components/NetworkAlert/MinimalNetworkAlert'
import { RowBetween } from 'components/Row' import { RowBetween } from 'components/Row'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { TYPE } from 'theme' import { TYPE } from 'theme'
import Texture from '../../assets/images/sandtexture.webp' import Texture from '../../assets/images/sandtexture.webp'
...@@ -119,6 +121,8 @@ const StyledImage = styled.img` ...@@ -119,6 +121,8 @@ const StyledImage = styled.img`
` `
export default function CTACards() { export default function CTACards() {
const { chainId } = useActiveWeb3React()
const { infoLink } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
return ( return (
<div> <div>
<MinimalNetworkAlert /> <MinimalNetworkAlert />
...@@ -137,7 +141,7 @@ export default function CTACards() { ...@@ -137,7 +141,7 @@ export default function CTACards() {
</RowBetween> </RowBetween>
</ResponsiveColumn> </ResponsiveColumn>
</CTA1> </CTA1>
<CTA2 href={'https://info.uniswap.org/#/pools'}> <CTA2 href={infoLink + '/pools'}>
<ResponsiveColumn> <ResponsiveColumn>
<HeaderText style={{ alignSelf: 'flex-start' }}> <HeaderText style={{ alignSelf: 'flex-start' }}>
<Trans>Top pools</Trans> <Trans>Top pools</Trans>
......
...@@ -44,6 +44,7 @@ import Toggle from 'components/Toggle' ...@@ -44,6 +44,7 @@ import Toggle from 'components/Toggle'
import { Bound } from 'state/mint/v3/actions' import { Bound } from 'state/mint/v3/actions'
import useIsTickAtLimit from 'hooks/useIsTickAtLimit' import useIsTickAtLimit from 'hooks/useIsTickAtLimit'
import { formatTickPrice } from 'utils/formatTickPrice' import { formatTickPrice } from 'utils/formatTickPrice'
import { SupportedChainId } from 'constants/chains'
const PageWrapper = styled.div` const PageWrapper = styled.div`
min-width: 800px; min-width: 800px;
...@@ -372,11 +373,6 @@ export function PositionPage({ ...@@ -372,11 +373,6 @@ export function PositionPage({
const currencyQuote = inverted ? currency0 : currency1 const currencyQuote = inverted ? currency0 : currency1
const currencyBase = inverted ? currency1 : currency0 const currencyBase = inverted ? currency1 : currency0
// check if price is within range
const below = pool && typeof tickLower === 'number' ? pool.tickCurrent < tickLower : undefined
const above = pool && typeof tickUpper === 'number' ? pool.tickCurrent >= tickUpper : undefined
const inRange: boolean = typeof below === 'boolean' && typeof above === 'boolean' ? !below && !above : false
const ratio = useMemo(() => { const ratio = useMemo(() => {
return priceLower && pool && priceUpper return priceLower && pool && priceUpper
? getRatio( ? getRatio(
...@@ -479,6 +475,11 @@ export function PositionPage({ ...@@ -479,6 +475,11 @@ export function PositionPage({
const feeValueUpper = inverted ? feeValue0 : feeValue1 const feeValueUpper = inverted ? feeValue0 : feeValue1
const feeValueLower = inverted ? feeValue1 : feeValue0 const feeValueLower = inverted ? feeValue1 : feeValue0
// check if price is within range
const below = pool && typeof tickLower === 'number' ? pool.tickCurrent < tickLower : undefined
const above = pool && typeof tickUpper === 'number' ? pool.tickCurrent >= tickUpper : undefined
const inRange: boolean = typeof below === 'boolean' && typeof above === 'boolean' ? !below && !above : false
function modalHeader() { function modalHeader() {
return ( return (
<AutoColumn gap={'md'} style={{ marginTop: '20px' }}> <AutoColumn gap={'md'} style={{ marginTop: '20px' }}>
...@@ -510,13 +511,15 @@ export function PositionPage({ ...@@ -510,13 +511,15 @@ export function PositionPage({
) )
} }
const onOptimisticChain = chainId && [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
const showCollectAsWeth = Boolean( const showCollectAsWeth = Boolean(
ownsNFT && ownsNFT &&
(feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) &&
currency0 && currency0 &&
currency1 && currency1 &&
(currency0.isNative || currency1.isNative) && (currency0.isNative || currency1.isNative) &&
!collectMigrationHash !collectMigrationHash &&
!onOptimisticChain
) )
return loading || poolState === PoolState.LOADING || !feeAmount ? ( return loading || poolState === PoolState.LOADING || !feeAmount ? (
......
...@@ -148,6 +148,16 @@ export default function Pool() { ...@@ -148,6 +148,16 @@ export default function Pool() {
link: '/migrate/v2', link: '/migrate/v2',
external: false, external: false,
}, },
{
content: (
<MenuItem>
<Layers size={16} style={{ marginRight: '12px' }} />
<Trans>V2 liquidity</Trans>
</MenuItem>
),
link: '/pool/v2',
external: false,
},
{ {
content: ( content: (
<MenuItem> <MenuItem>
...@@ -160,19 +170,6 @@ export default function Pool() { ...@@ -160,19 +170,6 @@ export default function Pool() {
}, },
] ]
if (showV2Features) {
menuItems.splice(2, 0, {
content: (
<MenuItem>
<Layers size={16} style={{ marginRight: '12px' }} />
<Trans>V2 liquidity</Trans>
</MenuItem>
),
link: '/pool/v2',
external: false,
})
}
return ( return (
<> <>
<PageWrapper> <PageWrapper>
...@@ -186,18 +183,20 @@ export default function Pool() { ...@@ -186,18 +183,20 @@ export default function Pool() {
</TYPE.mediumHeader> </TYPE.mediumHeader>
</HideSmall> </HideSmall>
<ButtonRow> <ButtonRow>
<Menu {showV2Features && (
menuItems={menuItems} <Menu
flyoutAlignment={FlyoutAlignment.LEFT} menuItems={menuItems}
ToggleUI={(props: any) => ( flyoutAlignment={FlyoutAlignment.LEFT}
<MoreOptionsButton {...props}> ToggleUI={(props: any) => (
<TYPE.body style={{ alignItems: 'center', display: 'flex' }}> <MoreOptionsButton {...props}>
<Trans>More</Trans> <TYPE.body style={{ alignItems: 'center', display: 'flex' }}>
<ChevronDown size={15} /> <Trans>More</Trans>
</TYPE.body> <ChevronDown size={15} />
</MoreOptionsButton> </TYPE.body>
)} </MoreOptionsButton>
/> )}
/>
)}
<ResponsiveButtonPrimary id="join-pool-button" as={Link} to="/add/ETH"> <ResponsiveButtonPrimary id="join-pool-button" as={Link} to="/add/ETH">
+ <Trans>New Position</Trans> + <Trans>New Position</Trans>
</ResponsiveButtonPrimary> </ResponsiveButtonPrimary>
......
...@@ -35,6 +35,7 @@ import { AddRemoveTabs } from 'components/NavigationTabs' ...@@ -35,6 +35,7 @@ import { AddRemoveTabs } from 'components/NavigationTabs'
import RangeBadge from 'components/Badge/RangeBadge' import RangeBadge from 'components/Badge/RangeBadge'
import Toggle from 'components/Toggle' import Toggle from 'components/Toggle'
import { t, Trans } from '@lingui/macro' import { t, Trans } from '@lingui/macro'
import { SupportedChainId } from 'constants/chains'
const DEFAULT_REMOVE_V3_LIQUIDITY_SLIPPAGE_TOLERANCE = new Percent(5, 100) const DEFAULT_REMOVE_V3_LIQUIDITY_SLIPPAGE_TOLERANCE = new Percent(5, 100)
...@@ -251,6 +252,16 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -251,6 +252,16 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
) )
} }
const onOptimisticChain = chainId && [SupportedChainId.OPTIMISM, SupportedChainId.OPTIMISTIC_KOVAN].includes(chainId)
const showCollectAsWeth = Boolean(
!onOptimisticChain &&
liquidityValue0?.currency &&
liquidityValue1?.currency &&
(liquidityValue0.currency.isNative ||
liquidityValue1.currency.isNative ||
liquidityValue0.currency.wrapped.equals(WETH9_EXTENDED[liquidityValue0.currency.chainId]) ||
liquidityValue1.currency.wrapped.equals(WETH9_EXTENDED[liquidityValue1.currency.chainId]))
)
return ( return (
<AutoColumn> <AutoColumn>
<TransactionConfirmationModal <TransactionConfirmationModal
...@@ -373,12 +384,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -373,12 +384,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
{liquidityValue0?.currency && {showCollectAsWeth && (
liquidityValue1?.currency &&
(liquidityValue0.currency.isNative ||
liquidityValue1.currency.isNative ||
liquidityValue0.currency.wrapped.equals(WETH9_EXTENDED[liquidityValue0.currency.chainId]) ||
liquidityValue1.currency.wrapped.equals(WETH9_EXTENDED[liquidityValue1.currency.chainId])) ? (
<RowBetween> <RowBetween>
<TYPE.main> <TYPE.main>
<Trans>Collect as WETH</Trans> <Trans>Collect as WETH</Trans>
...@@ -389,7 +395,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -389,7 +395,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)} toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
/> />
</RowBetween> </RowBetween>
) : null} )}
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<AutoColumn gap="12px" style={{ flex: '1' }}> <AutoColumn gap="12px" style={{ flex: '1' }}>
......
import { useEffect } from 'react' import { useEffect } from 'react'
import { useAppDispatch } from 'state/hooks' import { useAppDispatch } from 'state/hooks'
import { updateMatchesDarkMode } from './actions' import { updateMatchesDarkMode } from './actions'
export default function Updater(): null { export default function Updater(): null {
......
...@@ -34,12 +34,14 @@ export default function RadialGradientByChainUpdater(): null { ...@@ -34,12 +34,14 @@ export default function RadialGradientByChainUpdater(): null {
switch (chainId) { switch (chainId) {
case SupportedChainId.ARBITRUM_ONE: case SupportedChainId.ARBITRUM_ONE:
case SupportedChainId.ARBITRUM_RINKEBY:
setBackground(backgroundResetStyles) setBackground(backgroundResetStyles)
const arbitrumLightGradient = 'radial-gradient(150% 100% at 50% 0%, #CDE8FB 0%, #FCF3F9 50%, #FFFFFF 100%)' const arbitrumLightGradient = 'radial-gradient(150% 100% at 50% 0%, #CDE8FB 0%, #FCF3F9 50%, #FFFFFF 100%)'
const arbitrumDarkGradient = 'radial-gradient(150% 100% at 50% 0%, #0A294B 0%, #221E30 50%, #1F2128 100%)' const arbitrumDarkGradient = 'radial-gradient(150% 100% at 50% 0%, #0A294B 0%, #221E30 50%, #1F2128 100%)'
backgroundRadialGradientElement.style.background = darkMode ? arbitrumDarkGradient : arbitrumLightGradient backgroundRadialGradientElement.style.background = darkMode ? arbitrumDarkGradient : arbitrumLightGradient
break break
case SupportedChainId.OPTIMISM: case SupportedChainId.OPTIMISM:
case SupportedChainId.OPTIMISTIC_KOVAN:
setBackground(backgroundResetStyles) setBackground(backgroundResetStyles)
const optimismLightGradient = 'radial-gradient(150% 100% at 50% 0%, #FFFBF2 2%, #FFF4F9 53%, #FFFFFF 100%)' const optimismLightGradient = 'radial-gradient(150% 100% at 50% 0%, #FFFBF2 2%, #FFF4F9 53%, #FFFFFF 100%)'
const optimismDarkGradient = 'radial-gradient(150% 100% at 50% 0%, #3E2E38 2%, #2C1F2D 53%, #1F2128 100%)' const optimismDarkGradient = 'radial-gradient(150% 100% at 50% 0%, #3E2E38 2%, #2C1F2D 53%, #1F2128 100%)'
......
import { SupportedChainId } from '../constants/chains' import { L1_CHAIN_IDS, SupportedChainId } from '../constants/chains'
const MAINNET_AND_TESTNETS = [
SupportedChainId.MAINNET,
SupportedChainId.ROPSTEN,
SupportedChainId.RINKEBY,
SupportedChainId.GOERLI,
SupportedChainId.KOVAN,
]
export function constructSameAddressMap<T extends string>( export function constructSameAddressMap<T extends string>(
address: T, address: T,
additionalNetworks: SupportedChainId[] = [] additionalNetworks: SupportedChainId[] = []
): { [chainId: number]: T } { ): { [chainId: number]: T } {
return MAINNET_AND_TESTNETS.concat(additionalNetworks).reduce<{ [chainId: number]: T }>((memo, chainId) => { return L1_CHAIN_IDS.concat(additionalNetworks).reduce<{ [chainId: number]: T }>((memo, chainId) => {
memo[chainId] = address memo[chainId] = address
return memo return memo
}, {}) }, {})
......
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