diff --git a/src/helpers/environment/Environment/Environment.ts b/src/helpers/environment/Environment/Environment.ts index 11614775e..b4070d34d 100644 --- a/src/helpers/environment/Environment/Environment.ts +++ b/src/helpers/environment/Environment/Environment.ts @@ -43,6 +43,11 @@ export class Environment { key: "VITE_WG_PUBLIC_NODE_URL", }); + public static getSubgraphApiKey = (): string | undefined => + this._get({ + first: true, + key: "VITE_SUBGRAPH_API_KEY", + }); /** * a feature flag for denoting when we are on the staging server * @returns {string} true or false diff --git a/src/views/Range/RangeChart.tsx b/src/views/Range/RangeChart.tsx index 40fe4fdd0..c6fa88e83 100644 --- a/src/views/Range/RangeChart.tsx +++ b/src/views/Range/RangeChart.tsx @@ -15,7 +15,7 @@ import { YAxis, } from "recharts"; import { NameType } from "recharts/types/component/DefaultTooltipContent"; -import { formatCurrency, parseBigNumber, trim } from "src/helpers"; +import { formatCurrency, parseBigNumber } from "src/helpers"; import { RANGEv2 as OlympusRange } from "src/typechain/Range"; import { OperatorMovingAverage, OperatorTargetPrice, PriceHistory } from "src/views/Range/hooks"; @@ -54,38 +54,18 @@ const RangeChart = (props: { const { data: targetPrice } = OperatorTargetPrice(); const { data: movingAverage } = OperatorMovingAverage(); - const formattedWallHigh = trim(parseBigNumber(rangeData.high.wall.price, 18), 2); - const formattedWallLow = trim(parseBigNumber(rangeData.low.wall.price, 18), 2); - const formattedCushionHigh = trim(parseBigNumber(rangeData.high.cushion.price, 18), 2); - const formattedCushionLow = trim(parseBigNumber(rangeData.low.cushion.price, 18), 2); - const chartData = priceData.map((item: any) => { + const chartData = priceData.map((item, index) => { + const isFirstItem = index === 0; + return { - ...item, - timestamp: item.timestamp, - uv: [formattedWallHigh, formattedCushionHigh], - lv: [formattedWallLow, formattedCushionLow], - ma: targetPrice, + price: parseFloat(item.snapshot.ohmPrice), + timestamp: isFirstItem ? "now" : item.snapshot.timestamp, + uv: [item.snapshot.highWallPrice, item.snapshot.highCushionPrice], + lv: [item.snapshot.lowWallPrice, item.snapshot.lowCushionPrice], + ma: parseFloat(item.snapshot.ohmMovingAveragePrice), }; }); - /* We load an object at the front of the chartData array - * with no price data to shift the chart line left and add an extra element with current market price - */ - chartData.unshift( - { - uv: [formattedWallHigh, formattedCushionHigh], - lv: [formattedWallLow, formattedCushionLow], - ma: targetPrice, - }, - { - price: currentPrice, - timestamp: "now", - uv: [formattedWallHigh, formattedCushionHigh], - lv: [formattedWallLow, formattedCushionLow], - ma: targetPrice, - }, - ); - const CustomReferenceDot = (props: { cx: string | number | undefined; cy: string | number | undefined; @@ -121,47 +101,43 @@ const RangeChart = (props: { const TooltipContent = ({ payload, label }: TooltipProps) => { const price = payload && payload.length > 4 ? payload[4].value : currentPrice; const timestamp = payload && payload.length > 4 ? payload[4].payload.timestamp : ""; + const lowerCushion = payload && payload.length > 4 ? payload[4].payload.lv[1] : ""; + const lowerWall = payload && payload.length > 4 ? payload[4].payload.lv[0] : ""; + const upperCushion = payload && payload.length > 4 ? payload[4].payload.uv[1] : ""; + const upperWall = payload && payload.length > 4 ? payload[4].payload.uv[0] : ""; + return ( - + Price + + Lower Range + + + + + + Upper Range + + + + {label === "now" && ( <> - - Lower Range - - - - - - Upper Range - - - - )} @@ -172,7 +148,7 @@ const RangeChart = (props: { return isFetched ? ( - + @@ -249,7 +225,7 @@ const RangeChart = (props: { 1 && chartData[1].price} + y={chartData.length > 1 ? chartData[0].price : 0} shape={CustomReferenceDot} fill={theme.colors.gray[10]} > @@ -257,7 +233,7 @@ const RangeChart = (props: { className={classes.currentPrice} position={(isSquishyBid && bidPriceDelta < 0) || (isSquishyAsk && askPriceDelta < 0) ? "bottom" : "top"} > - {formatCurrency(chartData.length > 1 && chartData[1].price, 2, reserveSymbol)} + {formatCurrency(chartData.length > 1 ? chartData[0].price : 0, 2, reserveSymbol)} diff --git a/src/views/Range/hooks.tsx b/src/views/Range/hooks.tsx index 6199771f8..3b9b51a00 100644 --- a/src/views/Range/hooks.tsx +++ b/src/views/Range/hooks.tsx @@ -1,6 +1,6 @@ import { useMutation, useQuery } from "@tanstack/react-query"; import { BigNumber, ContractReceipt, ethers } from "ethers"; -import { formatEther } from "ethers/lib/utils.js"; +import request, { gql } from "graphql-request"; import toast from "react-hot-toast"; import { DAO_TREASURY_ADDRESSES, OHM_ADDRESSES } from "src/constants/addresses"; import { @@ -12,6 +12,7 @@ import { import { parseBigNumber } from "src/helpers"; import { trackGAEvent, trackGtagEvent } from "src/helpers/analytics/trackGAEvent"; import { DecimalBigNumber } from "src/helpers/DecimalBigNumber/DecimalBigNumber"; +import { Environment } from "src/helpers/environment/Environment/Environment"; import { isValidAddress } from "src/helpers/misc/isValidAddress"; import { Providers } from "src/helpers/providers/Providers/Providers"; import { queryAssertion } from "src/helpers/react-query/queryAssertion"; @@ -24,35 +25,51 @@ import { useSigner } from "wagmi"; /**Chainlink Price Feed. Retrieves OHMETH and ETH/{RESERVE} feed **/ export const PriceHistory = () => { - const networks = useTestableNetworks(); const { data = [], isFetched, isLoading, } = useQuery(["getPriceHistory"], async () => { - const contract = RANGE_PRICE_CONTRACT.getEthersContract(networks.MAINNET); - const lastObservationIndex = await contract.nextObsIndex(); - const secondsToSubtract = await contract.observationFrequency(); - let currentDate = new Date(); // Start with the current date - const resultsArray: { - price: number; - timestamp: string; - }[] = []; - - for (let i = 1; i < 10; i++) { - const observation = (lastObservationIndex - i + 90) % 90; - if (i > 0) { - currentDate = new Date(currentDate.getTime() - secondsToSubtract * 1000); + const query = gql` + query { + newObservations(first: 150, orderBy: block, orderDirection: desc) { + snapshot { + block + date + highCushionPrice + highWallPrice + lowCushionPrice + lowWallPrice + ohmPrice + timestamp + ohmMovingAveragePrice + } + } } - const datapoint = await contract.observations(observation); - const resultObject = { - price: parseFloat(formatEther(datapoint)), - timestamp: currentDate.toLocaleString(), - }; - resultsArray.push(resultObject); - } - - return resultsArray; + `; + + type snapshot = { + newObservations: { + snapshot: { + block: number; + date: string; + highCushionPrice: string; + highWallPrice: string; + lowCushionPrice: string; + lowWallPrice: string; + ohmPrice: string; + timestamp: string; + ohmMovingAveragePrice: string; + }; + }[]; + }; + const subgraphApiKey = Environment.getSubgraphApiKey(); + const response = await request( + `https://gateway.thegraph.com/api/${subgraphApiKey}/subgraphs/id/8L8ZJ5hqCZguKk2QyBRWWdsp2thmzHF2Egyj4TqC9NHc`, + query, + ); + + return response.newObservations; }); return { data, isFetched, isLoading };