From 26026a0f248d65fd83583c6496c6d42f070daddf Mon Sep 17 00:00:00 2001 From: Boris Kubrik Date: Wed, 25 Oct 2023 08:41:57 +0100 Subject: [PATCH] feat(frontend): show all-time volume fix: pnpm fixup! feat(frontend): show all-time volume fix: make requests concurrently fixup! feat(frontend): show all-time volume fix: font size and layout shift fixup! feat(frontend): show all-time volume fix: reduce request frequency --- packages/frontend/package.json | 1 + packages/frontend/src/App.tsx | 2 + .../frontend/src/components/Stats/Stats.tsx | 23 +++++++++ .../frontend/src/hooks/useAllTimeStats.tsx | 48 +++++++++++++++++++ packages/frontend/src/subgraph.json | 9 ++++ packages/frontend/tsconfig.json | 2 +- pnpm-lock.yaml | 23 +++++++++ 7 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 packages/frontend/src/components/Stats/Stats.tsx create mode 100644 packages/frontend/src/hooks/useAllTimeStats.tsx create mode 100644 packages/frontend/src/subgraph.json diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 1e884049..001849cf 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -39,6 +39,7 @@ "bn.js": "5.2.1", "debounce": "^1.2.1", "ethers": "^5.6.1", + "graphql-request": "^6.1.0", "hash.js": "1.1.7", "js-sha3": "0.8.0", "react": "^18.2.0", diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 9181ee0a..1840658b 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -5,6 +5,7 @@ import { Header } from './components/Header/Header'; import { Hero } from './components/Hero/Hero'; import { Route, Routes } from 'react-router-dom'; import { SpaceTravelCanvas } from './space-travel/SpaceTravelCanvas'; +import { Stats } from './components/Stats/Stats'; const Layout: FunctionComponent<{ children: ReactNode }> = ({ children }) => { return ( @@ -12,6 +13,7 @@ const Layout: FunctionComponent<{ children: ReactNode }> = ({ children }) => {
+
{children}
diff --git a/packages/frontend/src/components/Stats/Stats.tsx b/packages/frontend/src/components/Stats/Stats.tsx new file mode 100644 index 00000000..bc0659fb --- /dev/null +++ b/packages/frontend/src/components/Stats/Stats.tsx @@ -0,0 +1,23 @@ +import { useAllTimeStats } from 'src/hooks/useAllTimeStats'; +import { numberWithCommas } from 'src/utils/numberWithCommas'; + +const Stats = () => { + const { error, data } = useAllTimeStats(); + + if (error) { + console.error('Failed to fetch all-time stats:', error); + } + + return ( +
+ {data ? ( + `All-time volume: $${numberWithCommas(data)}` + ) : ( + // To avoid layout shifts + Placehodler + )} +
+ ); +}; + +export { Stats }; diff --git a/packages/frontend/src/hooks/useAllTimeStats.tsx b/packages/frontend/src/hooks/useAllTimeStats.tsx new file mode 100644 index 00000000..cf63ce4b --- /dev/null +++ b/packages/frontend/src/hooks/useAllTimeStats.tsx @@ -0,0 +1,48 @@ +import { useQuery } from '@tanstack/react-query'; +import { request, gql } from 'graphql-request'; +import GRAPH_URLS from 'src/subgraph.json'; + +const ALL_TIME_STATS_QUERY = gql` + query { + allTimeStats(id: "current") { + volumeUsd + } + } +`; + +type AllTimeStatsResponse = { + allTimeStats: { + volumeUsd: string; + }; +}; + +const useAllTimeStats = () => { + return useQuery( + ['allTimeStats'], + async () => { + const responses = (await Promise.all( + Object.values(GRAPH_URLS).map(url => + request(url, ALL_TIME_STATS_QUERY).catch((error: any) => { + console.error(`Failed to fetch data from ${url}:`, error); + + return { allTimeStats: { volumeUsd: '0' } }; + }) + ) + )) as AllTimeStatsResponse[]; + + const totalVolumeUsd = responses.reduce( + (sum: number, response: AllTimeStatsResponse) => + sum + Number(response.allTimeStats?.volumeUsd ?? '0'), + 0 + ); + + return Math.round(totalVolumeUsd); + }, + { + staleTime: 1000 * 60 * 5, // 5 minutes + refetchOnWindowFocus: false, + } + ); +}; + +export { useAllTimeStats }; diff --git a/packages/frontend/src/subgraph.json b/packages/frontend/src/subgraph.json new file mode 100644 index 00000000..9ad12842 --- /dev/null +++ b/packages/frontend/src/subgraph.json @@ -0,0 +1,9 @@ +{ + "1": "https://gateway-arbitrum.network.thegraph.com/api/3e9d2f58d24bcd5d854ba4c4c8df5c3b/subgraphs/id/G316MkVLSw1ksstmonpSQ1UEBUWmRSZf4QkoRA5CN4TA", + "10": "https://api.thegraph.com/subgraphs/name/sifiorg/sifi-optimism", + "56": "https://api.thegraph.com/subgraphs/name/sifiorg/sifi-bsc", + "137": "https://gateway-arbitrum.network.thegraph.com/api/3e9d2f58d24bcd5d854ba4c4c8df5c3b/subgraphs/id/VJesTAc98ochTTwDQViVgnM4jWhyRC4pyWHBpDQkCjj", + "8453": "https://api.thegraph.com/subgraphs/name/sifiorg/sifi-base", + "42161": "https://gateway-arbitrum.network.thegraph.com/api/3e9d2f58d24bcd5d854ba4c4c8df5c3b/subgraphs/id/BVexPGe3pnB7Mw7ajFkEDQJ8XY8XdVKbAL37ydmorhSQ", + "43114": "https://gateway-arbitrum.network.thegraph.com/api/3e9d2f58d24bcd5d854ba4c4c8df5c3b/subgraphs/id/4cn8JGVKUJBWRJNt4n5KQNMKyMLjRATUBLQ9oSCbL9QA" +} diff --git a/packages/frontend/tsconfig.json b/packages/frontend/tsconfig.json index a2a0ee47..f5897ff6 100644 --- a/packages/frontend/tsconfig.json +++ b/packages/frontend/tsconfig.json @@ -18,6 +18,6 @@ "composite": true, "outDir": "dist" }, - "include": ["src/**/*", ".storybook/decorators/*", "src"], + "include": ["src/**/*", ".storybook/decorators/*", "src", "src/subgraph.json"], "exclude": ["node_modules", "dist"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 82aeef2b..b533bc75 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,6 +92,9 @@ importers: ethers: specifier: ^5.6.1 version: 5.7.1 + graphql-request: + specifier: ^6.1.0 + version: 6.1.0(graphql@16.6.0) hash.js: specifier: 1.1.7 version: 1.1.7 @@ -4473,6 +4476,14 @@ packages: assemblyscript: 0.19.10 dev: false + /@graphql-typed-document-node/core@3.2.0(graphql@16.6.0): + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + graphql: 16.6.0 + dev: false + /@hapi/hoek@9.3.0: resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} dev: true @@ -15948,6 +15959,18 @@ packages: graphql: 16.6.0 dev: false + /graphql-request@6.1.0(graphql@16.6.0): + resolution: {integrity: sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==} + peerDependencies: + graphql: 14 - 16 + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.6.0) + cross-fetch: 3.1.5 + graphql: 16.6.0 + transitivePeerDependencies: + - encoding + dev: false + /graphql@15.5.0: resolution: {integrity: sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==} engines: {node: '>= 10.x'}