From daca9d1a5ea285e34306cb1fd886f0e168720ef4 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Mon, 15 Jul 2024 15:46:41 +0700 Subject: [PATCH 1/5] refactor(utils): home page overview, separate request --- src/lib/pages/home/full.tsx | 6 ++-- src/lib/pages/home/sequencer.tsx | 6 ++-- src/lib/services/stats/sequencer.ts | 19 ++++++++++-- src/lib/services/types/stats.ts | 46 ++++++++++++++++------------- 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/lib/pages/home/full.tsx b/src/lib/pages/home/full.tsx index bdfd19992..3686e8967 100644 --- a/src/lib/pages/home/full.tsx +++ b/src/lib/pages/home/full.tsx @@ -86,21 +86,21 @@ export const HomeFull = () => { diff --git a/src/lib/pages/home/sequencer.tsx b/src/lib/pages/home/sequencer.tsx index 8659818ca..63e35e279 100644 --- a/src/lib/pages/home/sequencer.tsx +++ b/src/lib/pages/home/sequencer.tsx @@ -86,21 +86,21 @@ export const HomeSequencer = () => { diff --git a/src/lib/services/stats/sequencer.ts b/src/lib/services/stats/sequencer.ts index 011d099c3..5ba8996b7 100644 --- a/src/lib/services/stats/sequencer.ts +++ b/src/lib/services/stats/sequencer.ts @@ -1,5 +1,6 @@ import axios from "axios"; +import { getBlocksSequencer } from "../block/sequencer"; import type { OverviewsStats } from "../types"; import { zOverviewsStatsResponseSequencer } from "../types"; import { parseWithError } from "lib/utils"; @@ -8,13 +9,27 @@ export const getOverviewStatsSequencer = async ( endpoint: string, chainId: string ): Promise => - Promise.all([ + Promise.allSettled([ axios .get( `https://dashboard-api.initiation-1.initia.xyz/v1/chart-data/${chainId}` ) .then(({ data }) => data), + getBlocksSequencer(endpoint, undefined, 1), axios .get(`${endpoint}/indexer/block/v1/avg_blocktime`) .then(({ data }) => data), - ]).then((data) => parseWithError(zOverviewsStatsResponseSequencer, data)); + ]).then(([dashboardApi, blocksLcd, avgBlockTimeLcd]) => { + const data = parseWithError(zOverviewsStatsResponseSequencer, [ + dashboardApi.status === "fulfilled" ? dashboardApi.value : null, + avgBlockTimeLcd.status === "fulfilled" ? avgBlockTimeLcd.value : null, + ]); + + return { + ...data, + latestBlock: + blocksLcd.status === "fulfilled" + ? blocksLcd.value.blocks[0].height + : null, + }; + }); diff --git a/src/lib/services/types/stats.ts b/src/lib/services/types/stats.ts index d6aceea04..5b1f92a6d 100644 --- a/src/lib/services/types/stats.ts +++ b/src/lib/services/types/stats.ts @@ -2,9 +2,9 @@ import { z } from "zod"; export const zOverviewsStatsResponse = z .object({ - transaction_count: z.number().nonnegative(), - latest_block: z.number().nonnegative(), - block_time: z.number().nonnegative(), + transaction_count: z.number().nonnegative().nullable(), + latest_block: z.number().nonnegative().nullable(), + block_time: z.number().nonnegative().nullable(), }) .transform((val) => ({ txCount: val.transaction_count, @@ -16,23 +16,29 @@ export type OverviewsStats = z.infer; export const zOverviewsStatsResponseSequencer = z .tuple([ - z.object({ - last_block_height: z.number().nonnegative(), - data: z.array( - z.object({ - date: z.string(), - tvl: z.number().nonnegative(), - tx_count: z.number().nonnegative(), - active_accounts: z.number().nonnegative(), - }) - ), - }), - z.object({ - avg_block_time: z.number().nonnegative(), - }), + z + .object({ + last_block_height: z.number().nonnegative(), + data: z.array( + z.object({ + date: z.string(), + tvl: z.number().nonnegative(), + tx_count: z.number().nonnegative(), + active_accounts: z.number().nonnegative(), + }) + ), + }) + .nullable(), + z + .object({ + avg_block_time: z.number().nonnegative(), + }) + .nullable(), ]) .transform(([stat, avg]) => ({ - latestBlock: stat.last_block_height, - txCount: stat.data.sort((a, b) => b.date.localeCompare(a.date))[0].tx_count, - blockTime: avg.avg_block_time, + latestBlock: stat?.last_block_height ?? null, + txCount: + stat?.data.sort((a, b) => b.date.localeCompare(a.date))[0].tx_count ?? + null, + blockTime: avg?.avg_block_time ?? null, })); From baf07a2d63f979c10aff171f78e66864f85561c2 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Mon, 15 Jul 2024 15:50:07 +0700 Subject: [PATCH 2/5] docs: update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 930c7564d..1090d17c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Improvements +- [#1022](https://github.com/alleslabs/celatone-frontend/pull/1022) Separate API requests in home page overview component + ### Bug fixes ## v1.7.1 From dc01b284646def7ae00003db143c8d84d58a0ca9 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Tue, 16 Jul 2024 11:07:08 +0700 Subject: [PATCH 3/5] feat(utils): separate query --- src/lib/services/block/sequencer.ts | 6 +++++ src/lib/services/stats/index.ts | 37 ++++++++++++++++++++++++++- src/lib/services/stats/sequencer.ts | 36 +++++--------------------- src/lib/services/types/block.ts | 6 +++++ src/lib/services/types/stats.ts | 39 ++++++++++------------------- 5 files changed, 67 insertions(+), 57 deletions(-) diff --git a/src/lib/services/block/sequencer.ts b/src/lib/services/block/sequencer.ts index 30a3b086f..e0136e0c6 100644 --- a/src/lib/services/block/sequencer.ts +++ b/src/lib/services/block/sequencer.ts @@ -3,6 +3,7 @@ import axios from "axios"; import { zBlockDataResponseSequencer, zBlocksResponseSequencer, + zBlockTimeAverageSequencer, } from "../types"; import type { Option } from "lib/types"; import { parseWithError } from "lib/utils"; @@ -43,6 +44,11 @@ export const getBlocksSequencer = async ( }) .then(({ data }) => parseWithError(zBlocksResponseSequencer, data)); +export const getBlockTimeAverageSequencer = async (endpoint: string) => + axios + .get(`${endpoint}/indexer/block/v1/avg_blocktime`) + .then(({ data }) => parseWithError(zBlockTimeAverageSequencer, data)); + export const getBlockDataSequencer = async (endpoint: string, height: number) => axios .get(`${endpoint}/indexer/block/v1/blocks/${height}`) diff --git a/src/lib/services/stats/index.ts b/src/lib/services/stats/index.ts index 26a6b756e..cb276a43f 100644 --- a/src/lib/services/stats/index.ts +++ b/src/lib/services/stats/index.ts @@ -1,6 +1,10 @@ import { useQuery } from "@tanstack/react-query"; import type { UseQueryResult } from "@tanstack/react-query"; +import { + getBlocksSequencer, + getBlockTimeAverageSequencer, +} from "../block/sequencer"; import type { OverviewsStats } from "../types"; import { handleQueryByTier } from "../utils"; import { @@ -30,6 +34,37 @@ export const useOverviewsStats = ( const apiEndpoint = useBaseApiRoute("overviews"); const lcdEndpoint = useLcdEndpoint(); + const querySequencerFn = async () => { + let statsSequencer; + let blocksSequencer; + let blockTimeAverageSequencer; + + try { + statsSequencer = await getOverviewStatsSequencer(chainId); + } catch { + statsSequencer = null; + } + + try { + blocksSequencer = await getBlocksSequencer(lcdEndpoint, undefined, 1); + } catch { + blocksSequencer = null; + } + + try { + blockTimeAverageSequencer = + await getBlockTimeAverageSequencer(lcdEndpoint); + } catch { + blockTimeAverageSequencer = null; + } + + return { + txCount: statsSequencer?.data[0]?.txCount ?? null, + latestBlock: blocksSequencer?.blocks[0]?.height ?? null, + blockTime: blockTimeAverageSequencer?.avgBlockTime ?? null, + }; + }; + return useQuery( [ CELATONE_QUERY_KEYS.OVERVIEWS_STATS, @@ -42,7 +77,7 @@ export const useOverviewsStats = ( handleQueryByTier({ tier, threshold: "sequencer", - querySequencer: () => getOverviewStatsSequencer(lcdEndpoint, chainId), + querySequencer: querySequencerFn, queryFull: () => getOverviewsStats(apiEndpoint), }), { diff --git a/src/lib/services/stats/sequencer.ts b/src/lib/services/stats/sequencer.ts index 5ba8996b7..273a6a836 100644 --- a/src/lib/services/stats/sequencer.ts +++ b/src/lib/services/stats/sequencer.ts @@ -1,35 +1,11 @@ import axios from "axios"; -import { getBlocksSequencer } from "../block/sequencer"; -import type { OverviewsStats } from "../types"; import { zOverviewsStatsResponseSequencer } from "../types"; import { parseWithError } from "lib/utils"; -export const getOverviewStatsSequencer = async ( - endpoint: string, - chainId: string -): Promise => - Promise.allSettled([ - axios - .get( - `https://dashboard-api.initiation-1.initia.xyz/v1/chart-data/${chainId}` - ) - .then(({ data }) => data), - getBlocksSequencer(endpoint, undefined, 1), - axios - .get(`${endpoint}/indexer/block/v1/avg_blocktime`) - .then(({ data }) => data), - ]).then(([dashboardApi, blocksLcd, avgBlockTimeLcd]) => { - const data = parseWithError(zOverviewsStatsResponseSequencer, [ - dashboardApi.status === "fulfilled" ? dashboardApi.value : null, - avgBlockTimeLcd.status === "fulfilled" ? avgBlockTimeLcd.value : null, - ]); - - return { - ...data, - latestBlock: - blocksLcd.status === "fulfilled" - ? blocksLcd.value.blocks[0].height - : null, - }; - }); +export const getOverviewStatsSequencer = async (chainId: string) => + axios + .get( + `https://dashboard-api.initiation-1.initia.xyz/v1/chart-data/${chainId}` + ) + .then(({ data }) => parseWithError(zOverviewsStatsResponseSequencer, data)); diff --git a/src/lib/services/types/block.ts b/src/lib/services/types/block.ts index cc8d39b70..00bb09c25 100644 --- a/src/lib/services/types/block.ts +++ b/src/lib/services/types/block.ts @@ -191,6 +191,12 @@ export const zBlocksResponseSequencer = z.object({ pagination: zPagination, }); +export const zBlockTimeAverageSequencer = z + .object({ + avg_block_time: z.number().nonnegative(), + }) + .transform(snakeToCamel); + export const zBlockDataResponseSequencer = zBlockSequencer.transform( (val) => ({ hash: val.hash, diff --git a/src/lib/services/types/stats.ts b/src/lib/services/types/stats.ts index 5b1f92a6d..68643f4c7 100644 --- a/src/lib/services/types/stats.ts +++ b/src/lib/services/types/stats.ts @@ -1,5 +1,7 @@ import { z } from "zod"; +import { snakeToCamel } from "lib/utils"; + export const zOverviewsStatsResponse = z .object({ transaction_count: z.number().nonnegative().nullable(), @@ -15,30 +17,15 @@ export const zOverviewsStatsResponse = z export type OverviewsStats = z.infer; export const zOverviewsStatsResponseSequencer = z - .tuple([ - z - .object({ - last_block_height: z.number().nonnegative(), - data: z.array( - z.object({ - date: z.string(), - tvl: z.number().nonnegative(), - tx_count: z.number().nonnegative(), - active_accounts: z.number().nonnegative(), - }) - ), - }) - .nullable(), - z - .object({ - avg_block_time: z.number().nonnegative(), + .object({ + last_block_height: z.number().nonnegative(), + data: z.array( + z.object({ + date: z.string(), + tvl: z.number().nonnegative(), + tx_count: z.number().nonnegative(), + active_accounts: z.number().nonnegative(), }) - .nullable(), - ]) - .transform(([stat, avg]) => ({ - latestBlock: stat?.last_block_height ?? null, - txCount: - stat?.data.sort((a, b) => b.date.localeCompare(a.date))[0].tx_count ?? - null, - blockTime: avg?.avg_block_time ?? null, - })); + ), + }) + .transform(snakeToCamel); From bbd7bfc6ae5ae905c6a9c31f2d164040ff1c05aa Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Tue, 16 Jul 2024 12:26:40 +0700 Subject: [PATCH 4/5] feat(pages): separate api call --- src/lib/app-provider/env.ts | 1 + src/lib/pages/home/sequencer.tsx | 21 ++++++++++++------ src/lib/services/block/index.ts | 19 +++++++++++++++- src/lib/services/stats/index.ts | 37 +------------------------------- src/lib/services/types/stats.ts | 8 ++++--- 5 files changed, 40 insertions(+), 46 deletions(-) diff --git a/src/lib/app-provider/env.ts b/src/lib/app-provider/env.ts index 5b7b528c7..803157b47 100644 --- a/src/lib/app-provider/env.ts +++ b/src/lib/app-provider/env.ts @@ -24,6 +24,7 @@ export enum CELATONE_QUERY_KEYS { BLOCK_DATA_LCD = "CELATONE_QUERY_BLOCK_DATA_LCD", BLOCK_DATA_SEQUENCER = "CELATONE_QUERY_BLOCK_DATA_SEQUENCER", BLOCK_LATEST_HEIGHT_LCD = "CELATONE_QUERY_BLOCK_LATEST_HEIGHT_LCD", + BLOCK_TIME_AVERAGE_SEQUENCER = "CELATONE_QUERY_BLOCK_TIME_AVERAGE_SEQUENCER", BLOCKS_SEQUENCER = "CELATONE_QUERY_BLOCKS_SEQUENCER", // CODE GQL CODES = "CELATONE_QUERY_CODES", diff --git a/src/lib/pages/home/sequencer.tsx b/src/lib/pages/home/sequencer.tsx index 63e35e279..453cee4b2 100644 --- a/src/lib/pages/home/sequencer.tsx +++ b/src/lib/pages/home/sequencer.tsx @@ -11,6 +11,10 @@ import { ConnectWalletAlert } from "lib/components/ConnectWalletAlert"; import PageContainer from "lib/components/PageContainer"; import { ViewMore } from "lib/components/table"; import { UserDocsLink } from "lib/components/UserDocsLink"; +import { + useBlockTimeAverageSequencer, + useLatestBlockLcd, +} from "lib/services/block"; import { useOverviewsStats } from "lib/services/stats"; import { DevShortcut, TopDecorations } from "./components"; @@ -40,7 +44,12 @@ export const HomeSequencer = () => { theme, } = useCelatoneApp(); - const { data: overviewsStats, isLoading } = useOverviewsStats(); + const { data: overviewsStats, isLoading: isOverviewsStatesLoading } = + useOverviewsStats(); + const { data: latestBlock, isLoading: isLatestBlockLoading } = + useLatestBlockLcd(); + const { data: blockTimeAverage, isLoading: isBlockTimeAverageLoading } = + useBlockTimeAverageSequencer(); const toTxs = () => navigate({ @@ -87,21 +96,21 @@ export const HomeSequencer = () => { title={txInfo.title} tooltip={txInfo.tooltip} value={overviewsStats?.txCount?.toLocaleString()} - isLoading={isLoading} + isLoading={isOverviewsStatesLoading} navigate={toTxs} /> diff --git a/src/lib/services/block/index.ts b/src/lib/services/block/index.ts index 067066292..cda7cba37 100644 --- a/src/lib/services/block/index.ts +++ b/src/lib/services/block/index.ts @@ -16,7 +16,11 @@ import { import { getBlockData, getBlocks } from "./api"; import { getBlockDataLcd, getLatestBlockLcd } from "./lcd"; -import { getBlockDataSequencer, getBlocksSequencer } from "./sequencer"; +import { + getBlockDataSequencer, + getBlocksSequencer, + getBlockTimeAverageSequencer, +} from "./sequencer"; export const useBlocks = ( limit: number, @@ -112,6 +116,19 @@ export const useBlocksSequencer = (limit = 10) => { }; }; +export const useBlockTimeAverageSequencer = () => { + const endpoint = useLcdEndpoint(); + + return useQuery( + [CELATONE_QUERY_KEYS.BLOCK_TIME_AVERAGE_SEQUENCER, endpoint], + async () => getBlockTimeAverageSequencer(endpoint), + { + retry: false, + refetchOnWindowFocus: false, + } + ); +}; + export const useBlockDataSequencer = (height: number) => { const endpoint = useLcdEndpoint(); diff --git a/src/lib/services/stats/index.ts b/src/lib/services/stats/index.ts index cb276a43f..184ae6b68 100644 --- a/src/lib/services/stats/index.ts +++ b/src/lib/services/stats/index.ts @@ -1,10 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import type { UseQueryResult } from "@tanstack/react-query"; -import { - getBlocksSequencer, - getBlockTimeAverageSequencer, -} from "../block/sequencer"; import type { OverviewsStats } from "../types"; import { handleQueryByTier } from "../utils"; import { @@ -34,37 +30,6 @@ export const useOverviewsStats = ( const apiEndpoint = useBaseApiRoute("overviews"); const lcdEndpoint = useLcdEndpoint(); - const querySequencerFn = async () => { - let statsSequencer; - let blocksSequencer; - let blockTimeAverageSequencer; - - try { - statsSequencer = await getOverviewStatsSequencer(chainId); - } catch { - statsSequencer = null; - } - - try { - blocksSequencer = await getBlocksSequencer(lcdEndpoint, undefined, 1); - } catch { - blocksSequencer = null; - } - - try { - blockTimeAverageSequencer = - await getBlockTimeAverageSequencer(lcdEndpoint); - } catch { - blockTimeAverageSequencer = null; - } - - return { - txCount: statsSequencer?.data[0]?.txCount ?? null, - latestBlock: blocksSequencer?.blocks[0]?.height ?? null, - blockTime: blockTimeAverageSequencer?.avgBlockTime ?? null, - }; - }; - return useQuery( [ CELATONE_QUERY_KEYS.OVERVIEWS_STATS, @@ -77,7 +42,7 @@ export const useOverviewsStats = ( handleQueryByTier({ tier, threshold: "sequencer", - querySequencer: querySequencerFn, + querySequencer: () => getOverviewStatsSequencer(chainId), queryFull: () => getOverviewsStats(apiEndpoint), }), { diff --git a/src/lib/services/types/stats.ts b/src/lib/services/types/stats.ts index 68643f4c7..2f2b1a4ae 100644 --- a/src/lib/services/types/stats.ts +++ b/src/lib/services/types/stats.ts @@ -1,7 +1,5 @@ import { z } from "zod"; -import { snakeToCamel } from "lib/utils"; - export const zOverviewsStatsResponse = z .object({ transaction_count: z.number().nonnegative().nullable(), @@ -28,4 +26,8 @@ export const zOverviewsStatsResponseSequencer = z }) ), }) - .transform(snakeToCamel); + .transform((val) => ({ + txCount: val.data[val.data.length - 1].tx_count, + latestBlock: val.last_block_height, + blockTime: 0, + })); From 62b363664ac9d242bc49dd6eea62b07ddec0ed07 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Tue, 16 Jul 2024 15:54:46 +0700 Subject: [PATCH 5/5] fix: pr comments --- src/lib/pages/home/full.tsx | 2 +- src/lib/pages/home/sequencer.tsx | 2 +- src/lib/services/types/stats.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/pages/home/full.tsx b/src/lib/pages/home/full.tsx index 3686e8967..1a3b8b51c 100644 --- a/src/lib/pages/home/full.tsx +++ b/src/lib/pages/home/full.tsx @@ -86,7 +86,7 @@ export const HomeFull = () => { diff --git a/src/lib/pages/home/sequencer.tsx b/src/lib/pages/home/sequencer.tsx index 453cee4b2..7b5e98a57 100644 --- a/src/lib/pages/home/sequencer.tsx +++ b/src/lib/pages/home/sequencer.tsx @@ -95,7 +95,7 @@ export const HomeSequencer = () => { diff --git a/src/lib/services/types/stats.ts b/src/lib/services/types/stats.ts index 2f2b1a4ae..aa05320e0 100644 --- a/src/lib/services/types/stats.ts +++ b/src/lib/services/types/stats.ts @@ -29,5 +29,5 @@ export const zOverviewsStatsResponseSequencer = z .transform((val) => ({ txCount: val.data[val.data.length - 1].tx_count, latestBlock: val.last_block_height, - blockTime: 0, + blockTime: null, }));