From d7e36de10cd968e12ae917009e6b84b27d62519e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=88=AB=C3=B8ba?= <106074508+EchoDex@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:28:24 +0400 Subject: [PATCH] Added volume to header (#64) * feat: added volume * fix: remove index price * fix: add interval --- .../screens/TradeScreen/MarketStatistics.tsx | 9 +++-- .../src/services/SpotMarketService.ts | 35 +++++++++++++++++++ spark-frontend/src/stores/TradeStore.ts | 30 +++++++++++++--- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/spark-frontend/src/screens/TradeScreen/MarketStatistics.tsx b/spark-frontend/src/screens/TradeScreen/MarketStatistics.tsx index ca3320e3..d4950f70 100644 --- a/spark-frontend/src/screens/TradeScreen/MarketStatistics.tsx +++ b/spark-frontend/src/screens/TradeScreen/MarketStatistics.tsx @@ -11,18 +11,17 @@ import { useMedia } from "@src/hooks/useMedia"; import { useStores } from "@src/stores"; import { media } from "@src/themes/breakpoints"; import BN from "@src/utils/BN"; +import { toCurrency } from "@src/utils/toCurrency"; const MarketStatistics: React.FC = observer(() => { const { tradeStore } = useStores(); const theme = useTheme(); const media = useMedia(); - //todo исправить значения const spotStatsArr = [ - { title: "Index price", value: tradeStore.market?.priceUnits.toFormat(2) }, - { title: "24h volume", value: "$ 0.00" }, - { title: "24h High", value: "$ 0.00" }, - { title: "24h Low", value: "$ 0.00" }, + { title: "24h volume", value: toCurrency(BN.formatUnits(tradeStore.marketInfo.volume, 6).toSignificant(2)) }, + { title: "24h High", value: toCurrency(BN.formatUnits(tradeStore.marketInfo.high, 9).toSignificant(2)) }, + { title: "24h Low", value: toCurrency(BN.formatUnits(tradeStore.marketInfo.low, 9).toSignificant(2)) }, ]; const renderMobile = () => { diff --git a/spark-frontend/src/services/SpotMarketService.ts b/spark-frontend/src/services/SpotMarketService.ts index 08c4faed..f6a88eb1 100644 --- a/spark-frontend/src/services/SpotMarketService.ts +++ b/spark-frontend/src/services/SpotMarketService.ts @@ -138,6 +138,41 @@ export async function fetchTrades(baseToken: string, limit: number): Promise { + const now = Date.now(); + const startTime = Math.floor((now - 24 * 60 * 60 * 1000) / 1000); + const filter = `where: {blockTimestamp_gte: ${startTime}}`; + + const query = ` + query { + tradeEvents(${filter}) { + tradeAmount + price + } + }`; + + try { + const response = await fetchIndexer(query); + const data = response.data.data.tradeEvents as { tradeAmount: string; price: string }[]; + + const volume = data.reduce((acc: number, curr) => acc + parseFloat(curr.tradeAmount), 0); + const high = data.reduce((max, trade) => (trade.price > max ? trade.price : max), data[0].price); + const low = data.reduce((min, trade) => (trade.price < min ? trade.price : min), data[0].price); + + return { volume: new BN(volume), high: new BN(high), low: new BN(low) }; + } catch (error) { + console.error("Error during Trades request:", error); + + return { volume: BN.ZERO, high: BN.ZERO, low: BN.ZERO }; + } +} + const fetchIndexer = async (query: string) => { for (const i in INDEXER_URLS) { const indexer = INDEXER_URLS[i]; diff --git a/spark-frontend/src/stores/TradeStore.ts b/spark-frontend/src/stores/TradeStore.ts index bbc45abb..c6aec199 100644 --- a/spark-frontend/src/stores/TradeStore.ts +++ b/spark-frontend/src/stores/TradeStore.ts @@ -2,13 +2,17 @@ import { makeAutoObservable } from "mobx"; import { TOKENS_BY_ASSET_ID, TOKENS_BY_SYMBOL } from "@src/constants"; import { SpotMarket } from "@src/entity"; -import { fetchMarketCreateEvents } from "@src/services/SpotMarketService"; +import { fetchMarketCreateEvents, fetchVolumeData, SpotMarketVolume } from "@src/services/SpotMarketService"; +import BN from "@src/utils/BN"; +import { IntervalUpdater } from "@src/utils/IntervalUpdater"; import RootStore from "@stores/RootStore"; export interface ISerializedTradeStore { favMarkets: string | null; } +const MARKET_INFO_UPDATE_INTERVAL = 5 * 60 * 1000; // 5 min + class TradeStore { rootStore: RootStore; initialized: boolean = false; @@ -19,6 +23,14 @@ class TradeStore { marketSymbol: string | null = null; readonly defaultMarketSymbol = "BTC-USDC"; + marketInfo: SpotMarketVolume = { + volume: BN.ZERO, + high: BN.ZERO, + low: BN.ZERO, + }; + + private marketInfoUpdater: IntervalUpdater; + constructor(rootStore: RootStore, initState?: ISerializedTradeStore) { this.rootStore = rootStore; makeAutoObservable(this); @@ -29,6 +41,10 @@ class TradeStore { } this.init(); + + this.marketInfoUpdater = new IntervalUpdater(this.updateMarketInfo, MARKET_INFO_UPDATE_INTERVAL); + + this.marketInfoUpdater.run(true); } get market() { @@ -71,17 +87,21 @@ class TradeStore { }); }; + updateMarketInfo = async () => { + this.marketInfo = await fetchVolumeData(); + }; + private setFavMarkets = (v: string[]) => (this.favMarkets = v); private setSpotMarkets = (v: SpotMarket[]) => (this.spotMarkets = v); - serialize = (): ISerializedTradeStore => ({ - favMarkets: this.favMarkets.join(","), - }); - private setInitialized = (l: boolean) => (this.initialized = l); private _setLoading = (l: boolean) => (this.loading = l); + + serialize = (): ISerializedTradeStore => ({ + favMarkets: this.favMarkets.join(","), + }); } export default TradeStore;