Commit 85217452 authored by Moody Salem's avatar Moody Salem

improvement(ts): strict everywhere

parent f7a1a2ab
......@@ -40,11 +40,12 @@ export default function Transaction({ hash }: { hash: string }) {
const { chainId } = useActiveWeb3React()
const allTransactions = useAllTransactions()
const summary = allTransactions?.[hash]?.summary
const pending = !allTransactions?.[hash]?.receipt
const success =
!pending &&
(allTransactions[hash].receipt.status === 1 || typeof allTransactions[hash].receipt.status === 'undefined')
const tx = allTransactions?.[hash]
const summary = tx?.summary
const pending = !tx?.receipt
const success = !pending && tx && (tx.receipt?.status === 1 || typeof tx.receipt?.status === 'undefined')
if (!chainId) return null
return (
<TransactionWrapper>
......
......@@ -285,13 +285,9 @@ export default function AccountDetails({
return null
}
const clearAllTransactionsCallback = useCallback(
(event: React.MouseEvent) => {
event.preventDefault()
dispatch(clearAllTransactions({ chainId }))
},
[dispatch, chainId]
)
const clearAllTransactionsCallback = useCallback(() => {
if (chainId) dispatch(clearAllTransactions({ chainId }))
}, [dispatch, chainId])
return (
<>
......@@ -339,7 +335,7 @@ export default function AccountDetails({
<>
<div>
{getStatusIcon()}
<p> {shortenAddress(account)}</p>
<p> {account && shortenAddress(account)}</p>
</div>
</>
)}
......@@ -350,17 +346,21 @@ export default function AccountDetails({
<>
<AccountControl>
<div>
<Copy toCopy={account}>
<span style={{ marginLeft: '4px' }}>Copy Address</span>
</Copy>
<AddressLink
hasENS={!!ENSName}
isENS={true}
href={getEtherscanLink(chainId, ENSName, 'address')}
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>
</AddressLink>
{account && (
<Copy toCopy={account}>
<span style={{ marginLeft: '4px' }}>Copy Address</span>
</Copy>
)}
{chainId && account && (
<AddressLink
hasENS={!!ENSName}
isENS={true}
href={chainId && getEtherscanLink(chainId, ENSName, 'address')}
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>
</AddressLink>
)}
</div>
</AccountControl>
</>
......@@ -368,17 +368,21 @@ export default function AccountDetails({
<>
<AccountControl>
<div>
<Copy toCopy={account}>
<span style={{ marginLeft: '4px' }}>Copy Address</span>
</Copy>
<AddressLink
hasENS={!!ENSName}
isENS={false}
href={getEtherscanLink(chainId, account, 'address')}
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>
</AddressLink>
{account && (
<Copy toCopy={account}>
<span style={{ marginLeft: '4px' }}>Copy Address</span>
</Copy>
)}
{chainId && account && (
<AddressLink
hasENS={!!ENSName}
isENS={false}
href={getEtherscanLink(chainId, account, 'address')}
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>
</AddressLink>
)}
</div>
</AccountControl>
</>
......
......@@ -101,7 +101,7 @@ export default function AddressInputPanel({
<TYPE.black color={theme.text2} fontWeight={500} fontSize={14}>
Recipient
</TYPE.black>
{address && (
{address && chainId && (
<ExternalLink href={getEtherscanLink(chainId, name ?? address, 'address')} style={{ fontSize: '14px' }}>
(View on Etherscan)
</ExternalLink>
......
......@@ -137,13 +137,13 @@ export default function CurrencyInputPanel({
onMax,
showMaxButton,
label = 'Input',
onCurrencySelect = null,
currency = null,
onCurrencySelect,
currency,
disableCurrencySelect = false,
hideBalance = false,
pair = null, // used for double token logo
hideInput = false,
otherCurrency = null,
otherCurrency,
id,
showCommonBases
}: CurrencyInputPanelProps) {
......@@ -151,7 +151,7 @@ export default function CurrencyInputPanel({
const [modalOpen, setModalOpen] = useState(false)
const { account } = useActiveWeb3React()
const selectedCurrencyBalance = useCurrencyBalance(account, currency)
const selectedCurrencyBalance = useCurrencyBalance(account ?? undefined, currency ?? undefined)
const theme = useContext(ThemeContext)
const handleDismissSearch = useCallback(() => {
......@@ -231,7 +231,7 @@ export default function CurrencyInputPanel({
</CurrencySelect>
</InputRow>
</Container>
{!disableCurrencySelect && (
{!disableCurrencySelect && onCurrencySelect && (
<CurrencySearchModal
isOpen={modalOpen}
onDismiss={handleDismissSearch}
......
......@@ -137,7 +137,7 @@ const NETWORK_LABELS: { [chainId in ChainId]: string | null } = {
export default function Header() {
const { account, chainId } = useActiveWeb3React()
const userEthBalance = useETHBalances([account])[account]
const userEthBalance = useETHBalances(account ? [account] : [])?.[account ?? '']
const [isDark] = useDarkModeManager()
return (
......@@ -156,7 +156,7 @@ export default function Header() {
<HeaderControls>
<HeaderElement>
<TestnetWrapper>
{!isMobile && NETWORK_LABELS[chainId] && <NetworkCard>{NETWORK_LABELS[chainId]}</NetworkCard>}
{!isMobile && chainId && NETWORK_LABELS[chainId] && <NetworkCard>{NETWORK_LABELS[chainId]}</NetworkCard>}
</TestnetWrapper>
<AccountElement active={!!account} style={{ pointerEvents: 'auto' }}>
{account && userEthBalance ? (
......
......@@ -5,7 +5,7 @@ import styled from 'styled-components'
import { useActiveWeb3React } from '../../hooks'
import Jazzicon from 'jazzicon'
const StyledIdenticon = styled.div`
const StyledIdenticonContainer = styled.div`
height: 1rem;
width: 1rem;
border-radius: 1.125rem;
......@@ -24,5 +24,6 @@ export default function Identicon() {
}
}, [account])
return <StyledIdenticon ref={ref} />
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30451
return <StyledIdenticonContainer ref={ref as any} />
}
......@@ -24,7 +24,7 @@ const StyledSVG = styled.svg<{ size: string; stroke?: string }>`
* Takes in custom size and stroke for circle color, default to primary color as fill,
* need ...rest for layered styles on top
*/
export default function Loader({ size = '16px', stroke = null, ...rest }: { size?: string; stroke?: string }) {
export default function Loader({ size = '16px', stroke, ...rest }: { size?: string; stroke?: string }) {
return (
<StyledSVG viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" size={size} stroke={stroke} {...rest}>
<path
......
......@@ -87,7 +87,8 @@ export default function Menu() {
useOnClickOutside(node, open ? toggle : undefined)
return (
<StyledMenu ref={node}>
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30451
<StyledMenu ref={node as any}>
<StyledMenuButton onClick={toggle}>
<StyledMenuIcon />
</StyledMenuButton>
......
......@@ -86,7 +86,7 @@ export default function Modal({
onDismiss,
minHeight = false,
maxHeight = 50,
initialFocusRef = null,
initialFocusRef,
children
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
......
import { Placement } from '@popperjs/core'
import { transparentize } from 'polished'
import React, { useState } from 'react'
import React, { useCallback, useState } from 'react'
import { usePopper } from 'react-popper'
import styled from 'styled-components'
import useInterval from '../../hooks/useInterval'
......@@ -83,9 +83,9 @@ export interface PopoverProps {
}
export default function Popover({ content, show, children, placement = 'auto' }: PopoverProps) {
const [referenceElement, setReferenceElement] = useState<HTMLDivElement>(null)
const [popperElement, setPopperElement] = useState<HTMLDivElement>(null)
const [arrowElement, setArrowElement] = useState<HTMLDivElement>(null)
const [referenceElement, setReferenceElement] = useState<HTMLDivElement | null>(null)
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null)
const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null)
const { styles, update, attributes } = usePopper(referenceElement, popperElement, {
placement,
strategy: 'fixed',
......@@ -94,17 +94,20 @@ export default function Popover({ content, show, children, placement = 'auto' }:
{ name: 'arrow', options: { element: arrowElement } }
]
})
useInterval(update, show ? 100 : null)
const updateCallback = useCallback(() => {
update && update()
}, [update])
useInterval(updateCallback, show ? 100 : null)
return (
<>
<ReferenceElement ref={setReferenceElement}>{children}</ReferenceElement>
<ReferenceElement ref={setReferenceElement as any}>{children}</ReferenceElement>
<Portal>
<PopoverContainer show={show} ref={setPopperElement} style={styles.popper} {...attributes.popper}>
<PopoverContainer show={show} ref={setPopperElement as any} style={styles.popper} {...attributes.popper}>
{content}
<Arrow
className={`arrow-${attributes.popper?.['data-popper-placement'] ?? ''}`}
ref={setArrowElement}
ref={setArrowElement as any}
style={styles.arrow}
{...attributes.arrow}
/>
......
......@@ -81,7 +81,11 @@ export default function PopupItem({
popupContent = <ListUpdatePopup popKey={popKey} listUrl={listUrl} oldList={oldList} newList={newList} auto={auto} />
}
const faderStyle = useSpring({ from: { width: '100%' }, to: { width: '0%' }, config: { duration: removeAfterMs } })
const faderStyle = useSpring({
from: { width: '100%' },
to: { width: '0%' },
config: { duration: removeAfterMs ?? undefined }
})
return (
<Popup>
......
......@@ -32,7 +32,9 @@ export default function TransactionPopup({
</div>
<AutoColumn gap="8px">
<TYPE.body fontWeight={500}>{summary ?? 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.body>
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</ExternalLink>
{chainId && (
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</ExternalLink>
)}
</AutoColumn>
</RowNoFlex>
)
......
......@@ -28,7 +28,7 @@ function V1PositionCard({ token, V1LiquidityBalance }: PositionCardProps) {
<RowFixed>
<DoubleCurrencyLogo currency0={token} margin={true} size={20} />
<Text fontWeight={500} fontSize={20} style={{ marginLeft: '' }}>
{`${token.equals(WETH[chainId]) ? 'WETH' : token.symbol}/ETH`}
{`${chainId && token.equals(WETH[chainId]) ? 'WETH' : token.symbol}/ETH`}
</Text>
<Text
fontSize={12}
......
......@@ -46,7 +46,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
const [showMore, setShowMore] = useState(false)
const userPoolBalance = useTokenBalance(account, pair.liquidityToken)
const userPoolBalance = useTokenBalance(account ?? undefined, pair.liquidityToken)
const totalPoolTokens = useTotalSupply(pair.liquidityToken)
const [token0Deposited, token1Deposited] =
......@@ -131,7 +131,7 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
const [showMore, setShowMore] = useState(false)
const userPoolBalance = useTokenBalance(account, pair.liquidityToken)
const userPoolBalance = useTokenBalance(account ?? undefined, pair.liquidityToken)
const totalPoolTokens = useTotalSupply(pair.liquidityToken)
const poolTokenPercentage =
......
......@@ -31,7 +31,7 @@ export default function CommonBases({
selectedCurrency
}: {
chainId?: ChainId
selectedCurrency?: Currency
selectedCurrency?: Currency | null
onSelect: (currency: Currency) => void
}) {
return (
......
......@@ -163,9 +163,9 @@ export default function CurrencyList({
}: {
height: number
currencies: Currency[]
selectedCurrency: Currency | undefined
selectedCurrency?: Currency | null
onCurrencySelect: (currency: Currency) => void
otherCurrency: Currency | undefined
otherCurrency?: Currency | null
fixedListRef?: MutableRefObject<FixedSizeList | undefined>
showETH: boolean
}) {
......
......@@ -26,9 +26,9 @@ import AutoSizer from 'react-virtualized-auto-sizer'
interface CurrencySearchProps {
isOpen: boolean
onDismiss: () => void
selectedCurrency?: Currency
selectedCurrency?: Currency | null
onCurrencySelect: (currency: Currency) => void
otherSelectedCurrency?: Currency
otherSelectedCurrency?: Currency | null
showCommonBases?: boolean
onChangeList: () => void
}
......
......@@ -11,9 +11,9 @@ import { ListSelect } from './ListSelect'
interface CurrencySearchModalProps {
isOpen: boolean
onDismiss: () => void
selectedCurrency?: Currency
selectedCurrency?: Currency | null
onCurrencySelect: (currency: Currency) => void
otherSelectedCurrency?: Currency
otherSelectedCurrency?: Currency | null
showCommonBases?: boolean
}
......
......@@ -31,6 +31,6 @@ export function filterTokens(tokens: Token[], search: string): Token[] {
return tokens.filter(token => {
const { symbol, name } = token
return matchesSearch(symbol) || matchesSearch(name)
return (symbol && matchesSearch(symbol)) || (name && matchesSearch(name))
})
}
{
"extends": "../../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
......@@ -141,7 +141,8 @@ export default function SettingsTab() {
useOnClickOutside(node, open ? toggle : undefined)
return (
<StyledMenu ref={node}>
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30451
<StyledMenu ref={node as any}>
<Modal isOpen={showConfirmation} onDismiss={() => setShowConfirmation(false)} maxHeight={100}>
<ModalContentWrapper>
<AutoColumn gap="lg">
......
......@@ -53,7 +53,7 @@ function TokenWarningCard({ token }: TokenWarningCardProps) {
if (userToken.equals(token)) {
return false
}
return userToken.symbol.toLowerCase() === tokenSymbol || userToken.name.toLowerCase() === tokenName
return userToken.symbol?.toLowerCase() === tokenSymbol || userToken.name?.toLowerCase() === tokenName
})
}, [token, chainId, allTokens, tokenSymbol, tokenName])
......@@ -72,9 +72,11 @@ function TokenWarningCard({ token }: TokenWarningCardProps) {
? `${token.name} (${token.symbol})`
: token.name || token.symbol}{' '}
</TYPE.main>
<ExternalLink style={{ fontWeight: 400 }} href={getEtherscanLink(chainId, token.address, 'token')}>
<TYPE.blue title={token.address}>{shortenAddress(token.address)} (View on Etherscan)</TYPE.blue>
</ExternalLink>
{chainId && (
<ExternalLink style={{ fontWeight: 400 }} href={getEtherscanLink(chainId, token.address, 'token')}>
<TYPE.blue title={token.address}>{shortenAddress(token.address)} (View on Etherscan)</TYPE.blue>
</ExternalLink>
)}
</AutoColumn>
</AutoRow>
</Wrapper>
......
......@@ -91,11 +91,13 @@ function TransactionSubmittedContent({
Transaction Submitted
</Text>
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')}>
<Text fontWeight={500} fontSize={14} color={theme.primary1}>
View on Etherscan
</Text>
</ExternalLink>
{chainId && hash && (
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')}>
<Text fontWeight={500} fontSize={14} color={theme.primary1}>
View on Etherscan
</Text>
</ExternalLink>
)}
<ButtonPrimary onClick={onDismiss} style={{ margin: '20px 0 0 0' }}>
<Text fontWeight={500} fontSize={20}>
Close
......
{
"extends": "../../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
......@@ -104,48 +104,44 @@ export default function SlippageTabs({ rawSlippage, setRawSlippage, deadline, se
slippageInput === '' || (rawSlippage / 100).toFixed(2) === Number.parseFloat(slippageInput).toFixed(2)
const deadlineInputIsValid = deadlineInput === '' || (deadline / 60).toString() === deadlineInput
let slippageError: SlippageError
let slippageError: SlippageError | undefined
if (slippageInput !== '' && !slippageInputIsValid) {
slippageError = SlippageError.InvalidInput
} else if (slippageInputIsValid && rawSlippage < 50) {
slippageError = SlippageError.RiskyLow
} else if (slippageInputIsValid && rawSlippage > 500) {
slippageError = SlippageError.RiskyHigh
} else {
slippageError = undefined
}
let deadlineError: DeadlineError
let deadlineError: DeadlineError | undefined
if (deadlineInput !== '' && !deadlineInputIsValid) {
deadlineError = DeadlineError.InvalidInput
} else {
deadlineError = undefined
}
function parseCustomSlippage(value: string) {
setSlippageInput(value)
let valueAsIntFromRoundedFloat: number
try {
valueAsIntFromRoundedFloat = Number.parseInt((Number.parseFloat(value) * 100).toString())
const valueAsIntFromRoundedFloat = Number.parseInt((Number.parseFloat(value) * 100).toString())
if (!Number.isNaN(valueAsIntFromRoundedFloat) && valueAsIntFromRoundedFloat < 5000) {
setRawSlippage(valueAsIntFromRoundedFloat)
}
} catch {}
if (
typeof valueAsIntFromRoundedFloat === 'number' &&
!Number.isNaN(valueAsIntFromRoundedFloat) &&
valueAsIntFromRoundedFloat < 5000
) {
setRawSlippage(valueAsIntFromRoundedFloat)
}
}
function parseCustomDeadline(value: string) {
setDeadlineInput(value)
let valueAsInt: number
try {
valueAsInt = Number.parseInt(value) * 60
const valueAsInt: number = Number.parseInt(value) * 60
if (!Number.isNaN(valueAsInt) && valueAsInt > 0) {
setDeadline(valueAsInt)
}
} catch {}
if (typeof valueAsInt === 'number' && !Number.isNaN(valueAsInt) && valueAsInt > 0) {
setDeadline(valueAsInt)
}
}
return (
......@@ -195,8 +191,9 @@ export default function SlippageTabs({ rawSlippage, setRawSlippage, deadline, se
</span>
</SlippageEmojiContainer>
) : null}
{/* https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30451 */}
<Input
ref={inputRef}
ref={inputRef as any}
placeholder={(rawSlippage / 100).toFixed(2)}
value={slippageInput}
onBlur={() => {
......
......@@ -73,7 +73,7 @@ const SubHeader = styled.div`
font-size: 12px;
`
const IconWrapper = styled.div<{ size?: number }>`
const IconWrapper = styled.div<{ size?: number | null }>`
${({ theme }) => theme.flexColumnNoWrap};
align-items: center;
justify-content: center;
......@@ -90,7 +90,7 @@ const IconWrapper = styled.div<{ size?: number }>`
export default function Option({
link = null,
clickable = true,
size = null,
size,
onClick = null,
color,
header,
......
......@@ -86,7 +86,7 @@ export default function PendingView({
<ErrorButton
onClick={() => {
setPendingError(false)
tryActivation(connector)
connector && tryActivation(connector)
}}
>
Try Again
......
......@@ -184,13 +184,14 @@ export default function WalletModal({
connector.walletConnectProvider = undefined
}
activate(connector, undefined, true).catch(error => {
if (error instanceof UnsupportedChainIdError) {
activate(connector) // a little janky...can't use setError because the connector isn't set
} else {
setPendingError(true)
}
})
connector &&
activate(connector, undefined, true).catch(error => {
if (error instanceof UnsupportedChainIdError) {
activate(connector) // a little janky...can't use setError because the connector isn't set
} else {
setPendingError(true)
}
})
}
// close wallet modal if fortmatic modal is active
......@@ -359,7 +360,7 @@ export default function WalletModal({
}
return (
<Modal isOpen={walletModalOpen} onDismiss={toggleWalletModal} minHeight={null} maxHeight={90}>
<Modal isOpen={walletModalOpen} onDismiss={toggleWalletModal} minHeight={false} maxHeight={90}>
<Wrapper>{getModalContent()}</Wrapper>
</Modal>
)
......
......@@ -19,7 +19,7 @@ const Message = styled.h2`
color: ${({ theme }) => theme.secondary1};
`
export default function Web3ReactManager({ children }: { children: JSX.Element }): JSX.Element {
export default function Web3ReactManager({ children }: { children: JSX.Element }) {
const { t } = useTranslation()
const { active } = useWeb3React()
const { active: networkActive, error: networkError, activate: activateNetwork } = useWeb3React(NetworkContextName)
......
......@@ -169,7 +169,7 @@ function Web3StatusInner() {
const { t } = useTranslation()
const { account, connector, error } = useWeb3React()
const { ENSName } = useENSName(account)
const { ENSName } = useENSName(account ?? undefined)
const allTransactions = useAllTransactions()
......@@ -197,7 +197,7 @@ function Web3StatusInner() {
<Text>{ENSName || shortenAddress(account)}</Text>
</>
)}
{!hasPendingTransactions && <StatusIcon connector={connector} />}
{!hasPendingTransactions && connector && <StatusIcon connector={connector} />}
</Web3StatusConnected>
)
} else if (error) {
......@@ -220,7 +220,7 @@ export default function Web3Status() {
const { active, account } = useWeb3React()
const contextNetwork = useWeb3React(NetworkContextName)
const { ENSName } = useENSName(account)
const { ENSName } = useENSName(account ?? undefined)
const allTransactions = useAllTransactions()
......@@ -239,7 +239,7 @@ export default function Web3Status() {
return (
<>
<Web3StatusInner />
<WalletModal ENSName={ENSName} pendingTransactions={pending} confirmedTransactions={confirmed} />
<WalletModal ENSName={ENSName ?? undefined} pendingTransactions={pending} confirmedTransactions={confirmed} />
</>
)
}
{
"extends": "../../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../../tsconfig.strict.json",
"include": [
"**/*",
"../../../node_modules/eslint-plugin-react/lib/types.d.ts"
]
}
\ No newline at end of file
......@@ -67,14 +67,14 @@ export function V1LiquidityInfo({
<div style={{ marginLeft: '.75rem' }}>
<TYPE.mediumHeader>
{<FormattedPoolCurrencyAmount currencyAmount={liquidityTokenAmount} />}{' '}
{token.equals(WETH[chainId]) ? 'WETH' : token.symbol}/ETH
{chainId && token.equals(WETH[chainId]) ? 'WETH' : token.symbol}/ETH
</TYPE.mediumHeader>
</div>
</AutoRow>
<RowBetween my="1rem">
<Text fontSize={16} fontWeight={500}>
Pooled {token.equals(WETH[chainId]) ? 'WETH' : token.symbol}:
Pooled {chainId && token.equals(WETH[chainId]) ? 'WETH' : token.symbol}:
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
......@@ -107,7 +107,7 @@ function V1PairMigration({ liquidityTokenAmount, token }: { liquidityTokenAmount
const [v2PairState, v2Pair] = usePair(chainId ? WETH[chainId] : undefined, token)
const isFirstLiquidityProvider: boolean = v2PairState === PairState.NOT_EXISTS
const v2SpotPrice = v2Pair?.reserveOf(token)?.divide(v2Pair?.reserveOf(WETH[chainId]))
const v2SpotPrice = chainId && v2Pair ? v2Pair.reserveOf(token).divide(v2Pair.reserveOf(WETH[chainId])) : undefined
const [confirmingMigration, setConfirmingMigration] = useState<boolean>(false)
const [pendingMigrationHash, setPendingMigrationHash] = useState<string | null>(null)
......@@ -158,11 +158,11 @@ function V1PairMigration({ liquidityTokenAmount, token }: { liquidityTokenAmount
: tokenWorth?.numerator
const addTransaction = useTransactionAdder()
const isMigrationPending = useIsTransactionPending(pendingMigrationHash)
const isMigrationPending = useIsTransactionPending(pendingMigrationHash ?? undefined)
const migrator = useV2MigratorContract()
const migrate = useCallback(() => {
if (!minAmountToken || !minAmountETH) return
if (!minAmountToken || !minAmountETH || !migrator) return
setConfirmingMigration(true)
migrator
......@@ -194,16 +194,18 @@ function V1PairMigration({ liquidityTokenAmount, token }: { liquidityTokenAmount
const largePriceDifference = !!priceDifferenceAbs && !priceDifferenceAbs.lessThan(JSBI.BigInt(5))
const isSuccessfullyMigrated = !!pendingMigrationHash && !!noLiquidityTokens
const isSuccessfullyMigrated = !!pendingMigrationHash && noLiquidityTokens
return (
<AutoColumn gap="20px">
<TYPE.body my={9} style={{ fontWeight: 400 }}>
This tool will safely migrate your V1 liquidity to V2 with minimal price risk. The process is completely
trustless thanks to the{' '}
<ExternalLink href={getEtherscanLink(chainId, MIGRATOR_ADDRESS, 'address')}>
<TYPE.blue display="inline">Uniswap migration contract↗</TYPE.blue>
</ExternalLink>
{chainId && (
<ExternalLink href={getEtherscanLink(chainId, MIGRATOR_ADDRESS, 'address')}>
<TYPE.blue display="inline">Uniswap migration contract↗</TYPE.blue>
</ExternalLink>
)}
.
</TYPE.body>
......@@ -242,7 +244,7 @@ function V1PairMigration({ liquidityTokenAmount, token }: { liquidityTokenAmount
<RowBetween>
<TYPE.body color="inherit">Price Difference:</TYPE.body>
<TYPE.black color="inherit">{priceDifferenceAbs.toSignificant(4)}%</TYPE.black>
<TYPE.black color="inherit">{priceDifferenceAbs?.toSignificant(4)}%</TYPE.black>
</RowBetween>
</AutoColumn>
</YellowCard>
......@@ -336,12 +338,12 @@ export default function MigrateV1Exchange({
const liquidityToken: Token | undefined = useMemo(
() =>
validatedAddress && token
validatedAddress && chainId && token
? new Token(chainId, validatedAddress, 18, `UNI-V1-${token.symbol}`, 'Uniswap V1')
: undefined,
[chainId, validatedAddress, token]
)
const userLiquidityBalance = useTokenBalance(account, liquidityToken)
const userLiquidityBalance = useTokenBalance(account ?? undefined, liquidityToken)
// redirect for invalid url params
if (!validatedAddress || tokenAddress === AddressZero) {
......@@ -362,7 +364,7 @@ export default function MigrateV1Exchange({
{!account ? (
<TYPE.largeHeader>You must connect an account.</TYPE.largeHeader>
) : validatedAddress && token?.equals(WETH[chainId]) ? (
) : validatedAddress && chainId && token?.equals(WETH[chainId]) ? (
<>
<TYPE.body my={9} style={{ fontWeight: 400 }}>
Because Uniswap V2 uses WETH under the hood, your Uniswap V1 WETH/ETH liquidity cannot be migrated. You
......
......@@ -58,7 +58,7 @@ function V1PairRemoval({
: new TokenAmount(token, ZERO)
const addTransaction = useTransactionAdder()
const isRemovalPending = useIsTransactionPending(pendingRemovalHash)
const isRemovalPending = useIsTransactionPending(pendingRemovalHash ?? undefined)
const remove = useCallback(() => {
if (!liquidityTokenAmount) return
......@@ -79,7 +79,7 @@ function V1PairRemoval({
})
addTransaction(response, {
summary: `Remove ${token.equals(WETH[chainId]) ? 'WETH' : token.symbol}/ETH V1 liquidity`
summary: `Remove ${chainId && token.equals(WETH[chainId]) ? 'WETH' : token.symbol}/ETH V1 liquidity`
})
setPendingRemovalHash(response.hash)
})
......@@ -91,7 +91,7 @@ function V1PairRemoval({
const noLiquidityTokens = !!liquidityTokenAmount && liquidityTokenAmount.equalTo(ZERO)
const isSuccessfullyRemoved = !!pendingRemovalHash && !!noLiquidityTokens
const isSuccessfullyRemoved = !!pendingRemovalHash && noLiquidityTokens
return (
<AutoColumn gap="20px">
......@@ -119,7 +119,7 @@ function V1PairRemoval({
</LightCard>
<TYPE.darkGray style={{ textAlign: 'center' }}>
{`Your Uniswap V1 ${
token.equals(WETH[chainId]) ? 'WETH' : token.symbol
chainId && token.equals(WETH[chainId]) ? 'WETH' : token.symbol
}/ETH liquidity will be redeemed for underlying assets.`}
</TYPE.darkGray>
</AutoColumn>
......@@ -140,12 +140,12 @@ export default function RemoveV1Exchange({
const liquidityToken: Token | undefined = useMemo(
() =>
validatedAddress && token
validatedAddress && chainId && token
? new Token(chainId, validatedAddress, 18, `UNI-V1-${token.symbol}`, 'Uniswap V1')
: undefined,
[chainId, validatedAddress, token]
)
const userLiquidityBalance = useTokenBalance(account, liquidityToken)
const userLiquidityBalance = useTokenBalance(account ?? undefined, liquidityToken)
// redirect for invalid url params
if (!validatedAddress || tokenAddress === AddressZero) {
......@@ -166,7 +166,7 @@ export default function RemoveV1Exchange({
{!account ? (
<TYPE.largeHeader>You must connect an account.</TYPE.largeHeader>
) : userLiquidityBalance && token ? (
) : userLiquidityBalance && token && exchangeContract ? (
<V1PairRemoval
exchangeContract={exchangeContract}
liquidityTokenAmount={userLiquidityBalance}
......
......@@ -29,7 +29,7 @@ export default function MigrateV1() {
// automatically add the search token
const token = useToken(tokenSearch)
const selectedTokenListTokens = useSelectedTokenList()
const isOnSelectedList = isTokenOnList(selectedTokenListTokens, token)
const isOnSelectedList = isTokenOnList(selectedTokenListTokens, token ?? undefined)
const allTokens = useAllTokens()
const addToken = useAddUserToken()
useEffect(() => {
......@@ -41,27 +41,26 @@ export default function MigrateV1() {
// get V1 LP balances
const V1Exchanges = useAllTokenV1Exchanges()
const V1LiquidityTokens: Token[] = useMemo(() => {
return Object.keys(V1Exchanges).map(
exchangeAddress => new Token(chainId, exchangeAddress, 18, 'UNI-V1', 'Uniswap V1')
)
return chainId
? Object.keys(V1Exchanges).map(exchangeAddress => new Token(chainId, exchangeAddress, 18, 'UNI-V1', 'Uniswap V1'))
: []
}, [chainId, V1Exchanges])
const [V1LiquidityBalances, V1LiquidityBalancesLoading] = useTokenBalancesWithLoadingIndicator(
account,
account ?? undefined,
V1LiquidityTokens
)
const allV1PairsWithLiquidity = V1LiquidityTokens.filter(V1LiquidityToken => {
return (
V1LiquidityBalances?.[V1LiquidityToken.address] &&
JSBI.greaterThan(V1LiquidityBalances[V1LiquidityToken.address].raw, JSBI.BigInt(0))
)
const balance = V1LiquidityBalances?.[V1LiquidityToken.address]
return balance && JSBI.greaterThan(balance.raw, JSBI.BigInt(0))
}).map(V1LiquidityToken => {
return (
const balance = V1LiquidityBalances[V1LiquidityToken.address]
return balance ? (
<V1PositionCard
key={V1LiquidityToken.address}
token={V1Exchanges[V1LiquidityToken.address]}
V1LiquidityBalance={V1LiquidityBalances[V1LiquidityToken.address]}
V1LiquidityBalance={balance}
/>
)
) : null
})
// should never always be false, because a V1 exhchange exists for WETH on all testnets
......
{
"extends": "../../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../../tsconfig.strict.json",
"include": [
"**/*",
"../../../node_modules/eslint-plugin-react/lib/types.d.ts"
]
}
\ No newline at end of file
{
"extends": "../../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
{
"extends": "../../tsconfig.strict.json",
"include": ["**/*"]
}
\ No newline at end of file
......@@ -8,11 +8,13 @@
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"strict": true,
"alwaysStrict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
......
{
"extends": "./tsconfig.json",
"compilerOptions": {
"strict": true,
"alwaysStrict": true,
"strictNullChecks": true
}
}
\ No newline at end of file
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