Compare commits

...

5 Commits

Author SHA1 Message Date
Ian Lapham
7fd4005154 Fix(UNI page): hide inactive pools (#1213)
* Hide rewards

* remove config changes

* move active detection to hook, small changes

* replace string math
2020-11-18 13:43:17 -05:00
Moody Salem
48eab0d0ac bump token lists 2020-11-11 09:40:53 -06:00
Ian Lapham
c9ee1b3b32 Fix(pool page): show deposited liquidity on pool page (#1195)
* Show staked liquidity on pool page

* update button, cleanup

* Show combined balance for staking cards

* hide buttons on position card if no balance
2020-11-09 12:11:58 -05:00
Grzegorz Kućmierz
eb4c305eff fix(ens): support ens names with dashes in them
* fix: parseENSAddress #1200

* fix: lint error #1200

* fix: parseENSAddress - allow to match domains with twice characters; disallow more than once dash next to each other
2020-11-07 08:19:01 -08:00
Anxo Rodriguez
d9825622f1 Allow absolute imports (#1185) 2020-11-03 09:16:38 -06:00
15 changed files with 225 additions and 74 deletions

View File

@@ -31,7 +31,7 @@
"@uniswap/liquidity-staker": "^1.0.2",
"@uniswap/merkle-distributor": "1.0.1",
"@uniswap/sdk": "3.0.3",
"@uniswap/token-lists": "^1.0.0-beta.17",
"@uniswap/token-lists": "^1.0.0-beta.18",
"@uniswap/v2-core": "1.0.0",
"@uniswap/v2-periphery": "^1.1.0-beta.0",
"@web3-react/core": "^6.0.9",

View File

@@ -159,6 +159,26 @@ export const ButtonPink = styled(Base)`
}
`
export const ButtonUNIGradient = styled(ButtonPrimary)`
color: white;
padding: 4px 8px;
height: 36px;
font-weight: 500;
background-color: ${({ theme }) => theme.bg3};
background: radial-gradient(174.47% 188.91% at 1.84% 0%, #ff007a 0%, #2172e5 100%), #edeef2;
width: fit-content;
position: relative;
cursor: pointer;
border: none;
white-space: no-wrap;
:hover {
opacity: 0.8;
}
:active {
opacity: 0.9;
}
`
export const ButtonOutlined = styled(Base)`
border: 1px solid ${({ theme }) => theme.bg2};
background-color: transparent;

View File

@@ -123,9 +123,6 @@ const AccountElement = styled.div<{ active: boolean }>`
:focus {
border: 1px solid blue;
}
/* :hover {
background-color: ${({ theme, active }) => (!active ? theme.bg2 : theme.bg4)};
} */
`
const UNIAmount = styled(AccountElement)`

View File

@@ -1,4 +1,4 @@
import { JSBI, Pair, Percent } from '@uniswap/sdk'
import { JSBI, Pair, Percent, TokenAmount } from '@uniswap/sdk'
import { darken } from 'polished'
import React, { useState } from 'react'
import { ChevronDown, ChevronUp } from 'react-feather'
@@ -9,10 +9,10 @@ import { useTotalSupply } from '../../data/TotalSupply'
import { useActiveWeb3React } from '../../hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { ExternalLink, TYPE } from '../../theme'
import { ExternalLink, TYPE, HideExtraSmall, ExtraSmallOnly } from '../../theme'
import { currencyId } from '../../utils/currencyId'
import { unwrappedToken } from '../../utils/wrappedCurrency'
import { ButtonPrimary, ButtonSecondary, ButtonEmpty } from '../Button'
import { ButtonPrimary, ButtonSecondary, ButtonEmpty, ButtonUNIGradient } from '../Button'
import { transparentize } from 'polished'
import { CardNoise } from '../earn/styled'
@@ -22,8 +22,9 @@ import Card, { GreyCard, LightCard } from '../Card'
import { AutoColumn } from '../Column'
import CurrencyLogo from '../CurrencyLogo'
import DoubleCurrencyLogo from '../DoubleLogo'
import { RowBetween, RowFixed } from '../Row'
import { RowBetween, RowFixed, AutoRow } from '../Row'
import { Dots } from '../swap/styleds'
import { BIG_INT_ZERO } from '../../constants'
export const FixedHeightRow = styled(RowBetween)`
height: 24px;
@@ -47,6 +48,7 @@ interface PositionCardProps {
pair: Pair
showUnwrapped?: boolean
border?: string
stakedBalance?: TokenAmount // optional balance to indicate that liquidity is deposited in mining pool
}
export function MinimalPositionCard({ pair, showUnwrapped = false, border }: PositionCardProps) {
@@ -157,7 +159,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
)
}
export default function FullPositionCard({ pair, border }: PositionCardProps) {
export default function FullPositionCard({ pair, border, stakedBalance }: PositionCardProps) {
const { account } = useActiveWeb3React()
const currency0 = unwrappedToken(pair.token0)
@@ -165,9 +167,12 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
const [showMore, setShowMore] = useState(false)
const userPoolBalance = useTokenBalance(account ?? undefined, pair.liquidityToken)
const userDefaultPoolBalance = useTokenBalance(account ?? undefined, pair.liquidityToken)
const totalPoolTokens = useTotalSupply(pair.liquidityToken)
// if staked balance balance provided, add to standard liquidity amount
const userPoolBalance = stakedBalance ? userDefaultPoolBalance?.add(stakedBalance) : userDefaultPoolBalance
const poolTokenPercentage =
!!userPoolBalance && !!totalPoolTokens && JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
? new Percent(userPoolBalance.raw, totalPoolTokens.raw)
@@ -192,12 +197,22 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
<CardNoise />
<AutoColumn gap="12px">
<FixedHeightRow>
<RowFixed>
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} margin={true} size={20} />
<AutoRow gap="8px">
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} size={20} />
<Text fontWeight={500} fontSize={20}>
{!currency0 || !currency1 ? <Dots>Loading</Dots> : `${currency0.symbol}/${currency1.symbol}`}
</Text>
</RowFixed>
{!!stakedBalance && (
<ButtonUNIGradient as={Link} to={`/uni/${currencyId(currency0)}/${currencyId(currency1)}`}>
<HideExtraSmall>Earning UNI</HideExtraSmall>
<ExtraSmallOnly>
<span role="img" aria-label="bolt">
</span>
</ExtraSmallOnly>
</ButtonUNIGradient>
)}
</AutoRow>
<RowFixed gap="8px">
<ButtonEmpty
@@ -208,7 +223,6 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
>
{showMore ? (
<>
{' '}
Manage
<ChevronUp size="20" style={{ marginLeft: '10px' }} />
</>
@@ -226,12 +240,22 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
<AutoColumn gap="8px">
<FixedHeightRow>
<Text fontSize={16} fontWeight={500}>
Your pool tokens:
Your total pool tokens:
</Text>
<Text fontSize={16} fontWeight={500}>
{userPoolBalance ? userPoolBalance.toSignificant(4) : '-'}
</Text>
</FixedHeightRow>
{stakedBalance && (
<FixedHeightRow>
<Text fontSize={16} fontWeight={500}>
Pool tokens in rewards pool:
</Text>
<Text fontSize={16} fontWeight={500}>
{stakedBalance.toSignificant(4)}
</Text>
</FixedHeightRow>
)}
<FixedHeightRow>
<RowFixed>
<Text fontSize={16} fontWeight={500}>
@@ -273,7 +297,9 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
Your pool share:
</Text>
<Text fontSize={16} fontWeight={500}>
{poolTokenPercentage ? poolTokenPercentage.toFixed(2) + '%' : '-'}
{poolTokenPercentage
? (poolTokenPercentage.toFixed(2) === '0.00' ? '<0.01' : poolTokenPercentage.toFixed(2)) + '%'
: '-'}
</Text>
</FixedHeightRow>
@@ -285,26 +311,39 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
View accrued fees and analytics<span style={{ fontSize: '11px' }}></span>
</ExternalLink>
</ButtonSecondary>
<RowBetween marginTop="10px">
{userDefaultPoolBalance && JSBI.greaterThan(userDefaultPoolBalance.raw, BIG_INT_ZERO) && (
<RowBetween marginTop="10px">
<ButtonPrimary
padding="8px"
borderRadius="8px"
as={Link}
to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}
width="48%"
>
Add
</ButtonPrimary>
<ButtonPrimary
padding="8px"
borderRadius="8px"
as={Link}
width="48%"
to={`/remove/${currencyId(currency0)}/${currencyId(currency1)}`}
>
Remove
</ButtonPrimary>
</RowBetween>
)}
{stakedBalance && JSBI.greaterThan(stakedBalance.raw, BIG_INT_ZERO) && (
<ButtonPrimary
padding="8px"
borderRadius="8px"
as={Link}
to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}
width="48%"
to={`/uni/${currencyId(currency0)}/${currencyId(currency1)}`}
width="100%"
>
Add
Manage Liquidity in Rewards Pool
</ButtonPrimary>
<ButtonPrimary
padding="8px"
borderRadius="8px"
as={Link}
width="48%"
to={`/remove/${currencyId(currency0)}/${currencyId(currency1)}`}
>
Remove
</ButtonPrimary>
</RowBetween>
)}
</AutoColumn>
)}
</AutoColumn>

View File

@@ -14,6 +14,7 @@ import { unwrappedToken } from '../../utils/wrappedCurrency'
import { useTotalSupply } from '../../data/TotalSupply'
import { usePair } from '../../data/Reserves'
import useUSDCPrice from '../../utils/useUSDCPrice'
import { BIG_INT_SECONDS_IN_WEEK } from '../../constants'
const StatContainer = styled.div`
display: flex;
@@ -56,11 +57,6 @@ const TopSection = styled.div`
`};
`
// const APR = styled.div`
// display: flex;
// justify-content: flex-end;
// `
const BottomSection = styled.div<{ showBackground: boolean }>`
padding: 12px 16px;
opacity: ${({ showBackground }) => (showBackground ? '1' : '0.4')};
@@ -139,9 +135,15 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
</RowBetween>
<RowBetween>
<TYPE.white> Pool rate </TYPE.white>
<TYPE.white>{`${stakingInfo.totalRewardRate
?.multiply(`${60 * 60 * 24 * 7}`)
?.toFixed(0, { groupSeparator: ',' })} UNI / week`}</TYPE.white>
<TYPE.white>
{stakingInfo
? stakingInfo.active
? `${stakingInfo.totalRewardRate
?.multiply(BIG_INT_SECONDS_IN_WEEK)
?.toFixed(0, { groupSeparator: ',' })} UNI / week`
: '0 UNI / week'
: '-'}
</TYPE.white>
</RowBetween>
</StatContainer>
@@ -157,9 +159,13 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
<span role="img" aria-label="wizard-icon" style={{ marginRight: '0.5rem' }}>
</span>
{`${stakingInfo.rewardRate
?.multiply(`${60 * 60 * 24 * 7}`)
?.toSignificant(4, { groupSeparator: ',' })} UNI / week`}
{stakingInfo
? stakingInfo.active
? `${stakingInfo.rewardRate
?.multiply(BIG_INT_SECONDS_IN_WEEK)
?.toSignificant(4, { groupSeparator: ',' })} UNI / week`
: '0 UNI / week'
: '-'}
</TYPE.black>
</BottomSection>
</>

View File

@@ -179,6 +179,9 @@ export const INITIAL_ALLOWED_SLIPPAGE = 50
// 20 minutes, denominated in seconds
export const DEFAULT_DEADLINE_FROM_NOW = 60 * 20
// used for rewards deadlines
export const BIG_INT_SECONDS_IN_WEEK = JSBI.BigInt(60 * 60 * 24 * 7)
export const BIG_INT_ZERO = JSBI.BigInt(0)
// one basis point

View File

@@ -28,7 +28,7 @@ import { useTotalSupply } from '../../data/TotalSupply'
import { usePair } from '../../data/Reserves'
import usePrevious from '../../hooks/usePrevious'
import useUSDCPrice from '../../utils/useUSDCPrice'
import { BIG_INT_ZERO } from '../../constants'
import { BIG_INT_ZERO, BIG_INT_SECONDS_IN_WEEK } from '../../constants'
const PageWrapper = styled(AutoColumn)`
max-width: 640px;
@@ -177,9 +177,11 @@ export default function Manage({
<AutoColumn gap="sm">
<TYPE.body style={{ margin: 0 }}>Pool Rate</TYPE.body>
<TYPE.body fontSize={24} fontWeight={500}>
{stakingInfo?.totalRewardRate
?.multiply((60 * 60 * 24 * 7).toString())
?.toFixed(0, { groupSeparator: ',' }) ?? '-'}
{stakingInfo?.active
? stakingInfo?.totalRewardRate
?.multiply(BIG_INT_SECONDS_IN_WEEK)
?.toFixed(0, { groupSeparator: ',' }) ?? '-'
: '0'}
{' UNI / week'}
</TYPE.body>
</AutoColumn>
@@ -293,9 +295,11 @@ export default function Manage({
<span role="img" aria-label="wizard-icon" style={{ marginRight: '8px ' }}>
</span>
{stakingInfo?.rewardRate
?.multiply((60 * 60 * 24 * 7).toString())
?.toSignificant(4, { groupSeparator: ',' }) ?? '-'}
{stakingInfo?.active
? stakingInfo?.rewardRate
?.multiply(BIG_INT_SECONDS_IN_WEEK)
?.toSignificant(4, { groupSeparator: ',' }) ?? '-'
: '0'}
{' UNI / week'}
</TYPE.black>
</RowBetween>
@@ -311,9 +315,11 @@ export default function Manage({
{!showAddLiquidityButton && (
<DataRow style={{ marginBottom: '1rem' }}>
<ButtonPrimary padding="8px" borderRadius="8px" width="160px" onClick={handleDepositClick}>
{stakingInfo?.stakedAmount?.greaterThan(JSBI.BigInt(0)) ? 'Deposit' : 'Deposit UNI-V2 LP Tokens'}
</ButtonPrimary>
{stakingInfo && stakingInfo.active && (
<ButtonPrimary padding="8px" borderRadius="8px" width="160px" onClick={handleDepositClick}>
{stakingInfo?.stakedAmount?.greaterThan(JSBI.BigInt(0)) ? 'Deposit' : 'Deposit UNI-V2 LP Tokens'}
</ButtonPrimary>
)}
{stakingInfo?.stakedAmount?.greaterThan(JSBI.BigInt(0)) && (
<>
@@ -329,7 +335,7 @@ export default function Manage({
)}
</DataRow>
)}
{!userLiquidityUnstaked ? null : userLiquidityUnstaked.equalTo('0') ? null : (
{!userLiquidityUnstaked ? null : userLiquidityUnstaked.equalTo('0') ? null : !stakingInfo?.active ? null : (
<TYPE.main>{userLiquidityUnstaked.toSignificant(6)} UNI-V2 LP tokens available</TYPE.main>
)}
</PositionInfo>

View File

@@ -9,6 +9,9 @@ import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/
import { Countdown } from './Countdown'
import Loader from '../../components/Loader'
import { useActiveWeb3React } from '../../hooks'
import { JSBI } from '@uniswap/sdk'
import { BIG_INT_ZERO } from '../../constants'
import { OutlineCard } from '../../components/Card'
const PageWrapper = styled(AutoColumn)`
max-width: 640px;
@@ -29,16 +32,25 @@ const PoolSection = styled.div`
justify-self: center;
`
const DataRow = styled(RowBetween)`
${({ theme }) => theme.mediaWidth.upToSmall`
flex-direction: column;
`};
`
export default function Earn() {
const { chainId } = useActiveWeb3React()
// staking info for connected account
const stakingInfos = useStakingInfo()
const DataRow = styled(RowBetween)`
${({ theme }) => theme.mediaWidth.upToSmall`
flex-direction: column;
`};
`
/**
* only show staking cards with balance
* @todo only account for this if rewards are inactive
*/
const stakingInfosWithBalance = stakingInfos?.filter(s => JSBI.greaterThan(s.stakedAmount.raw, BIG_INT_ZERO))
// toggle copy if rewards are inactive
const stakingRewardsExist = Boolean(typeof chainId === 'number' && (STAKING_REWARDS_INFO[chainId]?.length ?? 0) > 0)
return (
@@ -81,9 +93,11 @@ export default function Earn() {
{stakingRewardsExist && stakingInfos?.length === 0 ? (
<Loader style={{ margin: 'auto' }} />
) : !stakingRewardsExist ? (
'No active rewards'
<OutlineCard>No active pools</OutlineCard>
) : stakingInfos?.length !== 0 && stakingInfosWithBalance.length === 0 ? (
<OutlineCard>No active pools</OutlineCard>
) : (
stakingInfos?.map(stakingInfo => {
stakingInfosWithBalance?.map(stakingInfo => {
// need to sort by added liquidity here
return <PoolCard key={stakingInfo.stakingRewardAddress} stakingInfo={stakingInfo} />
})

View File

@@ -1,6 +1,6 @@
import React, { useContext, useMemo } from 'react'
import styled, { ThemeContext } from 'styled-components'
import { Pair } from '@uniswap/sdk'
import { Pair, JSBI } from '@uniswap/sdk'
import { Link } from 'react-router-dom'
import { SwapPoolTabs } from '../../components/NavigationTabs'
@@ -19,6 +19,8 @@ import { usePairs } from '../../data/Reserves'
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
import { Dots } from '../../components/swap/styleds'
import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/earn/styled'
import { useStakingInfo } from '../../state/stake/hooks'
import { BIG_INT_ZERO } from '../../constants'
const PageWrapper = styled(AutoColumn)`
max-width: 640px;
@@ -107,11 +109,24 @@ export default function Pool() {
const hasV1Liquidity = useUserHasLiquidityInAllTokens()
// show liquidity even if its deposited in rewards contract
const stakingInfo = useStakingInfo()
const stakingInfosWithBalance = stakingInfo?.filter(pool => JSBI.greaterThan(pool.stakedAmount.raw, BIG_INT_ZERO))
const stakingPairs = usePairs(stakingInfosWithBalance?.map(stakingInfo => stakingInfo.tokens))
// remove any pairs that also are included in pairs with stake in mining pool
const v2PairsWithoutStakedAmount = allV2PairsWithLiquidity.filter(v2Pair => {
return (
stakingPairs
?.map(stakingPair => stakingPair[1])
.filter(stakingPair => stakingPair?.liquidityToken.address === v2Pair.liquidityToken.address).length === 0
)
})
return (
<>
<PageWrapper>
<SwapPoolTabs active={'pool'} />
<VoteCard>
<CardBGImage />
<CardNoise />
@@ -170,7 +185,7 @@ export default function Pool() {
<Dots>Loading</Dots>
</TYPE.body>
</EmptyProposals>
) : allV2PairsWithLiquidity?.length > 0 ? (
) : allV2PairsWithLiquidity?.length > 0 || stakingPairs?.length > 0 ? (
<>
<ButtonSecondary>
<RowBetween>
@@ -180,10 +195,19 @@ export default function Pool() {
<span> </span>
</RowBetween>
</ButtonSecondary>
{allV2PairsWithLiquidity.map(v2Pair => (
{v2PairsWithoutStakedAmount.map(v2Pair => (
<FullPositionCard key={v2Pair.liquidityToken.address} pair={v2Pair} />
))}
{stakingPairs.map(
(stakingPair, i) =>
stakingPair[1] && ( // skip pairs that arent loaded
<FullPositionCard
key={stakingInfosWithBalance[i].stakingRewardAddress}
pair={stakingPair[1]}
stakedBalance={stakingInfosWithBalance[i].stakedAmount}
/>
)
)}
</>
) : (
<EmptyProposals>

View File

@@ -5,6 +5,7 @@ import { STAKING_REWARDS_INTERFACE } from '../../constants/abis/staking-rewards'
import { useActiveWeb3React } from '../../hooks'
import { NEVER_RELOAD, useMultipleContractSingleData } from '../multicall/hooks'
import { tryParseAmount } from '../swap/hooks'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
export const STAKING_GENESIS = 1600387200
@@ -55,6 +56,8 @@ export interface StakingInfo {
rewardRate: TokenAmount
// when the period ends
periodFinish: Date | undefined
// if pool is active
active: boolean
// calculates a hypothetical amount of token distributed to the active account per second.
getHypotheticalRewardRate: (
stakedAmount: TokenAmount,
@@ -67,6 +70,9 @@ export interface StakingInfo {
export function useStakingInfo(pairToFilterBy?: Pair | null): StakingInfo[] {
const { chainId, account } = useActiveWeb3React()
// detect if staking is ended
const currentBlockTimestamp = useCurrentBlockTimestamp()
const info = useMemo(
() =>
chainId
@@ -170,7 +176,12 @@ export function useStakingInfo(pairToFilterBy?: Pair | null): StakingInfo[] {
const individualRewardRate = getHypotheticalRewardRate(stakedAmount, totalStakedAmount, totalRewardRate)
const periodFinishMs = periodFinishState.result?.[0]?.mul(1000)?.toNumber()
const periodFinishSeconds = periodFinishState.result?.[0]?.toNumber()
const periodFinishMs = periodFinishSeconds * 1000
// compare period end timestamp vs current block timestamp (in seconds)
const active =
periodFinishSeconds && currentBlockTimestamp ? periodFinishSeconds > currentBlockTimestamp.toNumber() : true
memo.push({
stakingRewardAddress: rewardsAddress,
@@ -181,12 +192,24 @@ export function useStakingInfo(pairToFilterBy?: Pair | null): StakingInfo[] {
totalRewardRate: totalRewardRate,
stakedAmount: stakedAmount,
totalStakedAmount: totalStakedAmount,
getHypotheticalRewardRate
getHypotheticalRewardRate,
active
})
}
return memo
}, [])
}, [balances, chainId, earnedAmounts, info, periodFinishes, rewardRates, rewardsAddresses, totalSupplies, uni])
}, [
balances,
chainId,
currentBlockTimestamp,
earnedAmounts,
info,
periodFinishes,
rewardRates,
rewardsAddresses,
totalSupplies,
uni
])
}
export function useTotalUniEarned(): TokenAmount | undefined {

View File

@@ -185,3 +185,16 @@ export const HideSmall = styled.span`
display: none;
`};
`
export const HideExtraSmall = styled.span`
${({ theme }) => theme.mediaWidth.upToExtraSmall`
display: none;
`};
`
export const ExtraSmallOnly = styled.span`
display: none;
${({ theme }) => theme.mediaWidth.upToExtraSmall`
display: block;
`};
`

View File

@@ -10,5 +10,10 @@ describe('parseENSAddress', () => {
expect(parseENSAddress('abso.lutely.eth')).toEqual({ ensName: 'abso.lutely.eth', ensPath: undefined })
expect(parseENSAddress('eth')).toEqual(undefined)
expect(parseENSAddress('eth/hello-world')).toEqual(undefined)
expect(parseENSAddress('hello-world.eth')).toEqual({ ensName: 'hello-world.eth', ensPath: undefined })
expect(parseENSAddress('-prefix-dash.eth')).toEqual(undefined)
expect(parseENSAddress('suffix-dash-.eth')).toEqual(undefined)
expect(parseENSAddress('it.eth')).toEqual({ ensName: 'it.eth', ensPath: undefined })
expect(parseENSAddress('only-single--dash.eth')).toEqual(undefined)
})
})

View File

@@ -1,7 +1,7 @@
const ENS_NAME_REGEX = /^(([a-zA-Z0-9]+\.)+)eth(\/.*)?$/
const ENS_NAME_REGEX = /^(([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+)eth(\/.*)?$/
export function parseENSAddress(ensAddress: string): { ensName: string; ensPath: string | undefined } | undefined {
const match = ensAddress.match(ENS_NAME_REGEX)
if (!match) return undefined
return { ensName: `${match[1].toLowerCase()}eth`, ensPath: match[3] }
return { ensName: `${match[1].toLowerCase()}eth`, ensPath: match[4] }
}

View File

@@ -22,7 +22,8 @@
"jsx": "preserve",
"downlevelIteration": true,
"allowSyntheticDefaultImports": true,
"types": ["react-spring", "jest"]
"types": ["react-spring", "jest"],
"baseUrl": "src"
},
"exclude": ["node_modules", "cypress"],
"include": ["./src/**/*.ts", "./src/**/*.tsx", "src/components/Confetti/index.js"]

View File

@@ -2726,10 +2726,10 @@
tiny-warning "^1.0.3"
toformat "^2.0.0"
"@uniswap/token-lists@^1.0.0-beta.17":
version "1.0.0-beta.17"
resolved "https://registry.yarnpkg.com/@uniswap/token-lists/-/token-lists-1.0.0-beta.17.tgz#a861fe96a0f3de91b01eae05dec05a6a2018b38e"
integrity sha512-UVRmSsP/ghJ7Dg8BHYjAZmZL96jHlZKrFoIEuKD3g1E4FbahfwS2j2KAaf6iQuLx6RWo8PQmDZ99rfK6T2xi8w==
"@uniswap/token-lists@^1.0.0-beta.18":
version "1.0.0-beta.18"
resolved "https://registry.yarnpkg.com/@uniswap/token-lists/-/token-lists-1.0.0-beta.18.tgz#b6c70b67fa9ee142e6df088e40490ec3a545e7ba"
integrity sha512-RuDY36JUc2+Id2Dlpnt+coFfUEf9WkfvR0a3LKvwVgzAfcrd5KvjZg+PhAr4bczFU1aq7rs3/QLgwpsnFYaiPw==
"@uniswap/v2-core@1.0.0":
version "1.0.0"