Commit 5c8b45c8 authored by Tina's avatar Tina Committed by GitHub

fix: Use non-subgraph fields for calculating USD prices on explore and token details pages (#6134)

* use non subgraph fields for querying usd prices

* undefined check

* remove unuecessary logoUrl field

* remove outdated test

* fix: switch recently fetched tokens to token project market & update missing chart message

---------
Co-authored-by: default avatarcartcrom <cartergcromer@gmail.com>
parent 2eb5ff3c
...@@ -49,10 +49,6 @@ describe('Token details', () => { ...@@ -49,10 +49,6 @@ describe('Token details', () => {
// Shiba predator token, low trading volume and also has warning modal // Shiba predator token, low trading volume and also has warning modal
cy.visit('/tokens/ethereum/0xa71d0588EAf47f12B13cF8eC750430d21DF04974') cy.visit('/tokens/ethereum/0xa71d0588EAf47f12B13cF8eC750430d21DF04974')
// Should have missing price chart when price unavailable (expected for this token)
if (cy.get('[data-cy="chart-header"]').contains('Price Unavailable')) {
cy.get('[data-cy="missing-chart"]').should('exist')
}
// Stats should have: TVL, 24H Volume, 52W low, 52W high // Stats should have: TVL, 24H Volume, 52W low, 52W high
cy.get(getTestSelector('token-details-stats')).should('exist') cy.get(getTestSelector('token-details-stats')).should('exist')
cy.get(getTestSelector('token-details-stats')).within(() => { cy.get(getTestSelector('token-details-stats')).within(() => {
......
...@@ -156,7 +156,7 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index, ...@@ -156,7 +156,7 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index,
} }
}, [toggleOpen, isHovered, token, navigate, handleClick, tokenDetailsPath]) }, [toggleOpen, isHovered, token, navigate, handleClick, tokenDetailsPath])
const arrow = getDeltaArrow(token.market?.pricePercentChange?.value, 18) const arrow = getDeltaArrow(token.project?.markets?.[0]?.pricePercentChange?.value, 18)
return ( return (
<Link <Link
...@@ -186,16 +186,16 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index, ...@@ -186,16 +186,16 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index,
</Row> </Row>
<Column className={styles.suggestionSecondaryContainer}> <Column className={styles.suggestionSecondaryContainer}>
{!!token.market?.price?.value && ( {!!token.project?.markets?.[0]?.price?.value && (
<> <>
<Row gap="4"> <Row gap="4">
<Box className={styles.primaryText}>{formatUSDPrice(token.market.price.value)}</Box> <Box className={styles.primaryText}>{formatUSDPrice(token.project.markets[0].price.value)}</Box>
</Row> </Row>
<PriceChangeContainer> <PriceChangeContainer>
<ArrowCell>{arrow}</ArrowCell> <ArrowCell>{arrow}</ArrowCell>
<ThemedText.BodySmall> <ThemedText.BodySmall>
<DeltaText delta={token.market?.pricePercentChange?.value}> <DeltaText delta={token.project.markets[0].pricePercentChange?.value}>
{Math.abs(token.market?.pricePercentChange?.value ?? 0).toFixed(2)}% {Math.abs(token.project.markets[0].pricePercentChange?.value ?? 0).toFixed(2)}%
</DeltaText> </DeltaText>
</ThemedText.BodySmall> </ThemedText.BodySmall>
</PriceChangeContainer> </PriceChangeContainer>
......
...@@ -13,7 +13,7 @@ import TimePeriodSelector from './TimeSelector' ...@@ -13,7 +13,7 @@ import TimePeriodSelector from './TimeSelector'
function usePriceHistory(tokenPriceData: TokenPriceQuery): PricePoint[] | undefined { function usePriceHistory(tokenPriceData: TokenPriceQuery): PricePoint[] | undefined {
// Appends the current price to the end of the priceHistory array // Appends the current price to the end of the priceHistory array
const priceHistory = useMemo(() => { const priceHistory = useMemo(() => {
const market = tokenPriceData.token?.market const market = tokenPriceData.token?.project?.markets?.[0]
const priceHistory = market?.priceHistory?.filter(isPricePoint) const priceHistory = market?.priceHistory?.filter(isPricePoint)
const currentPrice = market?.price?.value const currentPrice = market?.price?.value
if (Array.isArray(priceHistory) && currentPrice !== undefined) { if (Array.isArray(priceHistory) && currentPrice !== undefined) {
......
...@@ -138,15 +138,6 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod } ...@@ -138,15 +138,6 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
) )
const chartAvailable = !!prices && prices.length > 0 const chartAvailable = !!prices && prices.length > 0
const missingPricesMessage = !chartAvailable ? (
prices?.length === 0 ? (
<>
<Trans>Missing price data due to recently low trading volume on Uniswap v3</Trans>
</>
) : (
<Trans>Missing chart data</Trans>
)
) : null
// first price point on the x-axis of the current time period's chart // first price point on the x-axis of the current time period's chart
const startingPrice = originalPrices?.[0] ?? DATA_EMPTY const startingPrice = originalPrices?.[0] ?? DATA_EMPTY
...@@ -287,12 +278,18 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod } ...@@ -287,12 +278,18 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
) : ( ) : (
<> <>
<MissingPrice>Price Unavailable</MissingPrice> <MissingPrice>Price Unavailable</MissingPrice>
<ThemedText.Caption style={{ color: theme.textTertiary }}>{missingPricesMessage}</ThemedText.Caption> <ThemedText.Caption style={{ color: theme.textTertiary }}>
<Trans>Missing price data</Trans>
</ThemedText.Caption>
</> </>
)} )}
</ChartHeader> </ChartHeader>
{!chartAvailable ? ( {!chartAvailable ? (
<MissingPriceChart width={width} height={graphHeight} message={!!displayPrice.value && missingPricesMessage} /> <MissingPriceChart
width={width}
height={graphHeight}
message={!!displayPrice.value && <Trans>Price history unavailable</Trans>}
/>
) : ( ) : (
<svg data-cy="price-chart" width={width} height={graphHeight} style={{ minWidth: '100%' }}> <svg data-cy="price-chart" width={width} height={graphHeight} style={{ minWidth: '100%' }}>
<AnimatedInLineChart <AnimatedInLineChart
......
...@@ -200,8 +200,8 @@ export default function TokenDetails({ ...@@ -200,8 +200,8 @@ export default function TokenDetails({
<StatsSection <StatsSection
TVL={tokenQueryData?.market?.totalValueLocked?.value} TVL={tokenQueryData?.market?.totalValueLocked?.value}
volume24H={tokenQueryData?.market?.volume24H?.value} volume24H={tokenQueryData?.market?.volume24H?.value}
priceHigh52W={tokenQueryData?.market?.priceHigh52W?.value} priceHigh52W={tokenQueryData?.project?.markets?.[0]?.priceHigh52W?.value}
priceLow52W={tokenQueryData?.market?.priceLow52W?.value} priceLow52W={tokenQueryData?.project?.markets?.[0]?.priceLow52W?.value}
/> />
<Hr /> <Hr />
<AboutSection <AboutSection
......
...@@ -438,7 +438,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT ...@@ -438,7 +438,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
const filterNetwork = lowercaseChainName.toUpperCase() const filterNetwork = lowercaseChainName.toUpperCase()
const chainId = CHAIN_NAME_TO_CHAIN_ID[filterNetwork] const chainId = CHAIN_NAME_TO_CHAIN_ID[filterNetwork]
const timePeriod = useAtomValue(filterTimeAtom) const timePeriod = useAtomValue(filterTimeAtom)
const delta = token.market?.pricePercentChange?.value const delta = token.project?.markets?.[0]?.pricePercentChange?.value
const arrow = getDeltaArrow(delta) const arrow = getDeltaArrow(delta)
const smallArrow = getDeltaArrow(delta, 14) const smallArrow = getDeltaArrow(delta, 14)
const formattedDelta = formatDelta(delta) const formattedDelta = formatDelta(delta)
...@@ -478,7 +478,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT ...@@ -478,7 +478,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
price={ price={
<ClickableContent> <ClickableContent>
<PriceInfoCell> <PriceInfoCell>
{formatUSDPrice(token.market?.price?.value)} {formatUSDPrice(token.project?.markets?.[0]?.price?.value)}
<PercentChangeInfoCell> <PercentChangeInfoCell>
<ArrowCell>{smallArrow}</ArrowCell> <ArrowCell>{smallArrow}</ArrowCell>
<DeltaText delta={delta}>{formattedDelta}</DeltaText> <DeltaText delta={delta}>{formattedDelta}</DeltaText>
...@@ -509,7 +509,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT ...@@ -509,7 +509,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
width={width} width={width}
height={height} height={height}
tokenData={token} tokenData={token}
pricePercentChange={token.market?.pricePercentChange?.value} pricePercentChange={token.project?.markets?.[0]?.pricePercentChange?.value}
sparklineMap={props.sparklineMap} sparklineMap={props.sparklineMap}
/> />
) )
......
...@@ -34,15 +34,6 @@ gql` ...@@ -34,15 +34,6 @@ gql`
symbol symbol
market(currency: USD) { market(currency: USD) {
id id
price {
id
value
currency
}
pricePercentChange(duration: DAY) {
id
value
}
volume24H: volume(duration: DAY) { volume24H: volume(duration: DAY) {
id id
value value
...@@ -53,6 +44,17 @@ gql` ...@@ -53,6 +44,17 @@ gql`
id id
logoUrl logoUrl
safetyLevel safetyLevel
markets(currencies: [USD]) {
id
price {
id
value
}
pricePercentChange(duration: DAY) {
id
value
}
}
} }
} }
} }
......
...@@ -17,15 +17,6 @@ gql` ...@@ -17,15 +17,6 @@ gql`
symbol symbol
market(currency: USD) { market(currency: USD) {
id id
price {
id
value
currency
}
pricePercentChange(duration: DAY) {
id
value
}
volume24H: volume(duration: DAY) { volume24H: volume(duration: DAY) {
id id
value value
...@@ -36,6 +27,17 @@ gql` ...@@ -36,6 +27,17 @@ gql`
id id
logoUrl logoUrl
safetyLevel safetyLevel
markets(currencies: [USD]) {
id
price {
id
value
}
pricePercentChange(duration: DAY) {
id
value
}
}
} }
} }
} }
......
...@@ -30,24 +30,11 @@ gql` ...@@ -30,24 +30,11 @@ gql`
value value
currency currency
} }
price {
id
value
currency
}
volume24H: volume(duration: DAY) { volume24H: volume(duration: DAY) {
id id
value value
currency currency
} }
priceHigh52W: priceHighLow(duration: YEAR, highLow: HIGH) {
id
value
}
priceLow52W: priceHighLow(duration: YEAR, highLow: LOW) {
id
value
}
} }
project { project {
id id
...@@ -60,6 +47,22 @@ gql` ...@@ -60,6 +47,22 @@ gql`
chain chain
address address
} }
markets(currencies: [USD]) {
id
price {
id
value
currency
}
priceHigh52W: priceHighLow(duration: YEAR, highLow: HIGH) {
id
value
}
priceLow52W: priceHighLow(duration: YEAR, highLow: LOW) {
id
value
}
}
} }
} }
} }
......
...@@ -6,16 +6,19 @@ gql` ...@@ -6,16 +6,19 @@ gql`
id id
address address
chain chain
market(currency: USD) { project {
id id
price { markets(currencies: [USD]) {
id id
value price {
} id
priceHistory(duration: $duration) { value
id }
timestamp priceHistory(duration: $duration) {
value id
timestamp
value
}
} }
} }
} }
......
...@@ -36,22 +36,12 @@ gql` ...@@ -36,22 +36,12 @@ gql`
standard standard
market(currency: USD) { market(currency: USD) {
id id
totalValueLocked { volume(duration: $duration) {
id
value
currency
}
price {
id id
value value
currency currency
} }
pricePercentChange(duration: $duration) { totalValueLocked {
id
currency
value
}
volume(duration: $duration) {
id id
value value
currency currency
...@@ -60,6 +50,18 @@ gql` ...@@ -60,6 +50,18 @@ gql`
project { project {
id id
logoUrl logoUrl
markets(currencies: [USD]) {
id
price {
id
value
}
pricePercentChange(duration: $duration) {
id
currency
value
}
}
} }
} }
} }
...@@ -71,12 +73,14 @@ gql` ...@@ -71,12 +73,14 @@ gql`
id id
address address
chain chain
market(currency: USD) { project {
id markets(currencies: [USD]) {
priceHistory(duration: $duration) {
id id
timestamp priceHistory(duration: $duration) {
value id
timestamp
value
}
} }
} }
} }
...@@ -92,11 +96,15 @@ function useSortedTokens(tokens: TopTokens100Query['topTokens']) { ...@@ -92,11 +96,15 @@ function useSortedTokens(tokens: TopTokens100Query['topTokens']) {
let tokenArray = Array.from(tokens) let tokenArray = Array.from(tokens)
switch (sortMethod) { switch (sortMethod) {
case TokenSortMethod.PRICE: case TokenSortMethod.PRICE:
tokenArray = tokenArray.sort((a, b) => (b?.market?.price?.value ?? 0) - (a?.market?.price?.value ?? 0)) tokenArray = tokenArray.sort(
(a, b) => (b?.project?.markets?.[0]?.price?.value ?? 0) - (a?.project?.markets?.[0]?.price?.value ?? 0)
)
break break
case TokenSortMethod.PERCENT_CHANGE: case TokenSortMethod.PERCENT_CHANGE:
tokenArray = tokenArray.sort( tokenArray = tokenArray.sort(
(a, b) => (b?.market?.pricePercentChange?.value ?? 0) - (a?.market?.pricePercentChange?.value ?? 0) (a, b) =>
(b?.project?.markets?.[0]?.pricePercentChange?.value ?? 0) -
(a?.project?.markets?.[0]?.pricePercentChange?.value ?? 0)
) )
break break
case TokenSortMethod.TOTAL_VALUE_LOCKED: case TokenSortMethod.TOTAL_VALUE_LOCKED:
...@@ -160,7 +168,8 @@ export function useTopTokens(chain: Chain): UseTopTokensReturnValue { ...@@ -160,7 +168,8 @@ export function useTopTokens(chain: Chain): UseTopTokensReturnValue {
const unwrappedTokens = sparklineQuery?.topTokens?.map((topToken) => unwrapToken(chainId, topToken)) const unwrappedTokens = sparklineQuery?.topTokens?.map((topToken) => unwrapToken(chainId, topToken))
const map: SparklineMap = {} const map: SparklineMap = {}
unwrappedTokens?.forEach( unwrappedTokens?.forEach(
(current) => current?.address && (map[current.address] = current?.market?.priceHistory?.filter(isPricePoint)) (current) =>
current?.address && (map[current.address] = current?.project?.markets?.[0]?.priceHistory?.filter(isPricePoint))
) )
return map return map
}, [chainId, sparklineQuery?.topTokens]) }, [chainId, sparklineQuery?.topTokens])
......
...@@ -16,15 +16,6 @@ gql` ...@@ -16,15 +16,6 @@ gql`
symbol symbol
market(currency: USD) { market(currency: USD) {
id id
price {
id
value
currency
}
pricePercentChange(duration: DAY) {
id
value
}
volume24H: volume(duration: DAY) { volume24H: volume(duration: DAY) {
id id
value value
...@@ -35,6 +26,18 @@ gql` ...@@ -35,6 +26,18 @@ gql`
id id
logoUrl logoUrl
safetyLevel safetyLevel
markets(currencies: [USD]) {
id
price {
id
value
}
pricePercentChange(duration: DAY) {
id
currency
value
}
}
} }
} }
} }
......
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