From 8caa5ff9570507bbd7fbecb0b813539ea4b1ccb4 Mon Sep 17 00:00:00 2001
From: TITI <162849030+0xtiti@users.noreply.github.com>
Date: Fri, 2 Aug 2024 17:24:26 -0300
Subject: [PATCH] feat: chain table (#12)
---
public/locales/en/common.json | 8 +-
public/locales/es/common.json | 8 +-
src/assets/icons/github.svg | 3 +
src/assets/icons/infoDark.svg | 5 +
src/assets/icons/infoLight.svg | 5 +
src/components/InfoTag.tsx | 44 +++++
src/components/Table.tsx | 162 ++++++++++++++++---
src/components/Theme/theme.ts | 100 +++++++++++-
src/components/TotalValueLocked.tsx | 23 +--
src/containers/ChainDetail/ChainMetadata.tsx | 6 +-
src/containers/Dashboard/index.tsx | 10 +-
src/containers/LockedAssets/index.tsx | 6 +-
src/data/ecosystemMockData.json | 137 ++++++++--------
src/pages/[chain]/index.tsx | 14 +-
src/providers/DataProvider.tsx | 9 +-
src/types/Data.ts | 26 ++-
src/types/Theme.ts | 10 ++
17 files changed, 432 insertions(+), 144 deletions(-)
create mode 100644 src/assets/icons/github.svg
create mode 100644 src/assets/icons/infoDark.svg
create mode 100644 src/assets/icons/infoLight.svg
create mode 100644 src/components/InfoTag.tsx
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index e95bd49..677ced4 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -10,10 +10,12 @@
"chain": "Chain",
"chainId": "Chain ID",
"nativeToken": "Native token",
- "tvl": "TVL - L1",
+ "tvl": "TVL (L1)",
"type": "Type",
- "search": "Search",
- "notFound": "Chain not found"
+ "search": "Search (Chain)",
+ "notFound": "Chain not found",
+ "noRPC": "No RPC",
+ "noMetadata": "No Metadata"
}
},
"CHAIN": {
diff --git a/public/locales/es/common.json b/public/locales/es/common.json
index 2b7daa8..6537f38 100644
--- a/public/locales/es/common.json
+++ b/public/locales/es/common.json
@@ -10,10 +10,12 @@
"chain": "Cadena",
"chainId": "ID de cadena",
"nativeToken": "Token nativo",
- "tvl": "TVL - L1",
+ "tvl": "TVL (L1)",
"type": "Tipo",
- "search": "Buscar",
- "notFound": "Cadena no encontrada"
+ "search": "Buscar (Cadena)",
+ "notFound": "Cadena no encontrada",
+ "noRPC": "Sin RPC",
+ "noMetadata": "Sin Metadata"
}
},
"CHAIN": {
diff --git a/src/assets/icons/github.svg b/src/assets/icons/github.svg
new file mode 100644
index 0000000..2bccb51
--- /dev/null
+++ b/src/assets/icons/github.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/icons/infoDark.svg b/src/assets/icons/infoDark.svg
new file mode 100644
index 0000000..93d0755
--- /dev/null
+++ b/src/assets/icons/infoDark.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/icons/infoLight.svg b/src/assets/icons/infoLight.svg
new file mode 100644
index 0000000..aa0e9fe
--- /dev/null
+++ b/src/assets/icons/infoLight.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/components/InfoTag.tsx b/src/components/InfoTag.tsx
new file mode 100644
index 0000000..1d81fd3
--- /dev/null
+++ b/src/components/InfoTag.tsx
@@ -0,0 +1,44 @@
+import { styled, Box, Typography } from '@mui/material';
+import Image from 'next/image';
+
+import { useCustomTheme } from '~/hooks';
+import informationIconDark from '~/assets/icons/infoDark.svg';
+import informationIconLight from '~/assets/icons/infoLight.svg';
+
+interface InfoTagProps {
+ information: string;
+}
+
+export const InfoTag = ({ information }: InfoTagProps) => {
+ const { theme } = useCustomTheme();
+ return (
+
+
+ {information}
+
+ );
+};
+
+const InfoTagContainer = styled(Box)(() => {
+ const { currentTheme } = useCustomTheme();
+
+ return {
+ display: 'flex',
+ alignItems: 'center',
+ fontSize: '0.7rem',
+ gap: currentTheme.gap,
+ backgroundColor: currentTheme.warningBackground,
+ borderRadius: currentTheme.borderRadius,
+ padding: '0.1rem 0.5rem 0.1rem 0.1rem',
+ border: currentTheme.warningBorder,
+ };
+});
+
+const InfoText = styled(Typography)(() => {
+ const { currentTheme } = useCustomTheme();
+
+ return {
+ fontSize: '0.7rem',
+ color: currentTheme.warningText,
+ };
+});
diff --git a/src/components/Table.tsx b/src/components/Table.tsx
index 11560e4..9eb7371 100644
--- a/src/components/Table.tsx
+++ b/src/components/Table.tsx
@@ -1,14 +1,27 @@
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/router';
+import {
+ styled,
+ TableContainer,
+ Table,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableBody,
+ Typography,
+ Avatar,
+} from '@mui/material';
import { EcosystemChainData } from '~/types';
import { formatDataNumber } from '~/utils';
+import { useCustomTheme } from '~/hooks';
+import { InfoTag } from './InfoTag';
interface TableProps {
chains: EcosystemChainData[];
}
-export const Table = ({ chains }: TableProps) => {
+export const DataTable = ({ chains }: TableProps) => {
const { t } = useTranslation();
const router = useRouter();
@@ -17,26 +30,131 @@ export const Table = ({ chains }: TableProps) => {
};
return (
-
-
- {t('HOME.DASHBOARD.chain')} |
- {t('HOME.DASHBOARD.chainId')} |
- {t('HOME.DASHBOARD.nativeToken')} |
- {t('HOME.DASHBOARD.tvl')} |
- {t('HOME.DASHBOARD.type')} |
-
-
- {chains?.map((data, index) => {
- return (
- handleChainNavigation(data.id)}>
- {data.name} |
- {data.id} |
- {data.nativeToken} |
- {formatDataNumber(data.tvl, 0, true)} |
- {data.type} |
-
- );
- })}
-
+
+
+ {/* Table titles */}
+
+
+ {t('HOME.DASHBOARD.chain')}
+ {t('HOME.DASHBOARD.chainId')}
+ {t('HOME.DASHBOARD.nativeToken')}
+ {t('HOME.DASHBOARD.tvl')}
+ {t('HOME.DASHBOARD.type')}
+
+
+
+ {/* Table data */}
+
+ {chains?.map((data, index) => {
+ return (
+ handleChainNavigation(data.chainId)}>
+ {/* Chain Name with Logo and Tags */}
+
+
+ {data.chainName}
+ {!data.rpc && }
+ {!data.metadata && }
+
+
+ {data.chainId}
+
+
+
+ {data.nativeToken}
+
+
+ {formatDataNumber(data.tvl, 0, true)}
+
+ {data.chainType}
+
+ );
+ })}
+
+
+
);
};
+
+const STableContainer = styled(TableContainer)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ width: '75rem',
+ borderRadius: currentTheme.borderRadius,
+ border: currentTheme.border,
+ overflow: 'hidden',
+ };
+});
+
+const STableHead = styled(TableHead)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ backgroundColor: currentTheme.backgroundTertiary,
+ color: currentTheme.textSecondary,
+ '&:not(:last-child)': {
+ borderBottom: currentTheme.border,
+ },
+ };
+});
+
+const STableBody = styled(TableBody)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ backgroundColor: currentTheme.backgroundSecondary,
+ border: currentTheme.border,
+ };
+});
+
+const STableRow = styled(TableRow)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ '&:not(:last-child)': {
+ border: currentTheme.border,
+ },
+ cursor: 'pointer',
+ transition: currentTheme.transition,
+ };
+});
+
+const STableCellHead = styled(TableCell)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ color: currentTheme.textSecondary,
+ textAlign: 'left',
+ };
+});
+
+const STableCell = styled(TableCell)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ color: currentTheme.textPrimary,
+ textAlign: 'left',
+ };
+});
+
+const LogoCell = styled(TableCell)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ color: currentTheme.textPrimary,
+ display: 'flex',
+ alignItems: 'center',
+ gap: currentTheme.gap,
+ border: 'none',
+ textAlign: 'left',
+ };
+});
+
+const ChainAvatar = styled(Avatar)(() => {
+ return {
+ width: '2rem',
+ height: '2rem',
+ };
+});
+
+const TokenAvatar = styled(Avatar)(() => {
+ const { currentTheme } = useCustomTheme();
+ return {
+ width: '1.5rem',
+ height: '1.5rem',
+ backgroundColor: currentTheme.emptyBackground,
+ };
+});
diff --git a/src/components/Theme/theme.ts b/src/components/Theme/theme.ts
index adbf0c1..793565b 100644
--- a/src/components/Theme/theme.ts
+++ b/src/components/Theme/theme.ts
@@ -1,10 +1,80 @@
import { Theme } from '~/types';
+const neutral: { [key: number]: string } = {
+ 50: '#F7F9FC',
+ 100: '#E8ECF2',
+ 200: '#DADDE5',
+ 300: '#BEC2CC',
+ 400: '#A1A7B3',
+ 500: '#858C99',
+ 600: '#6C7380',
+ 700: '#555A66',
+ 800: '#3D424D',
+ 900: '#262B33',
+ 950: '#11141A',
+};
+
+const primary: { [key: number]: string } = {
+ 50: '#D9E3FF',
+ 100: '#A6BFFF',
+ 200: '#739AFF',
+ 300: '#4075FF',
+ 400: '#1755F4',
+ 500: '#1650E5',
+ 600: '#2663FF',
+ 700: '#1347CC',
+ 800: '#113EB2',
+ 900: '#0C2C80',
+ 950: '#071B4D',
+};
+
+const warning: { [key: number]: string } = {
+ 50: '#FFF9E5',
+ 100: '#FFECB2',
+ 200: '#FFE080',
+ 300: '#FFD44D',
+ 400: '#FFC81A',
+ 500: '#FFC200',
+ 600: '#E5AF00',
+ 700: '#CC9B00',
+ 800: '#997500',
+ 900: '#664E00',
+ 950: '#4D3A00',
+};
+
+const error: { [key: number]: string } = {
+ 50: '#FFCCCC',
+ 100: '#FFB2B2',
+ 200: '#FF8C8C',
+ 300: '#FF6666',
+ 400: '#FF6666',
+ 500: '#FF0000',
+ 600: '#CC0000',
+ 700: '#A60000',
+ 800: '#800000',
+ 900: '#590000',
+ 950: '#330000',
+};
+
+const success: { [key: number]: string } = {
+ 50: '#CCFFE5',
+ 100: '#B2FFD9',
+ 200: '#8CFFC6',
+ 300: '#66FFB2',
+ 400: '#33FF99',
+ 500: '#00FF80',
+ 600: '#00CC66',
+ 700: '#00A653',
+ 800: '#008040',
+ 900: '#00592D',
+ 950: '#00331A',
+};
+
export const darkTheme: Theme = {
type: 'dark',
titleColor: '#000000',
textPrimary: '#ffffff',
- textSecondary: '#99A4B8',
+ textSecondary: '#A1A7B3',
backgroundPrimary: '#000000',
backgroundSecondary: '#262B33',
backgroundTertiary: '#11141A',
@@ -12,9 +82,19 @@ export const darkTheme: Theme = {
textFontFamily: 'Inter-Variable',
borderRadius: '1.5rem',
secondaryBorderRadius: '0.4rem',
- border: '0.1rem solid rgba(153, 164, 184, 0.1)',
+ transition: 'all 180ms ease-in-out',
+ border: '0.1rem solid rgba(255, 255, 255, 0.05)',
gap: '0.25rem',
padding: '1rem',
+ warningText: warning[400],
+ warningBackground: 'rgba(255, 200, 26, 0.1)',
+ warningBorder: '1px solid rgba(255, 200, 26, 0.051)',
+ emptyBackground: 'rgba(133, 140, 153, 0.3)',
+ neutral,
+ primary,
+ warning,
+ error,
+ success,
};
export const lightTheme: Theme = {
@@ -24,13 +104,23 @@ export const lightTheme: Theme = {
textPrimary: '#000000',
textSecondary: '#717171',
backgroundPrimary: '#ffffff',
- backgroundSecondary: '#E8ECF2',
- backgroundTertiary: '#f8f8f8',
+ backgroundSecondary: 'rgba(232, 236, 242, 1)',
+ backgroundTertiary: ' rgba(218, 221, 229, 1)',
titleFontFamily: 'Inter-Variable',
textFontFamily: 'Inter-Variable',
borderRadius: '1.5rem',
secondaryBorderRadius: '0.4rem',
- border: '0.1rem solid rgba(183, 183, 183, 0.3)',
+ transition: 'all 180ms ease-in-out',
+ border: '0.1rem solid rgba(0, 0, 0, 0.05)',
gap: '0.25rem',
+ warningText: warning[800],
padding: '1rem',
+ warningBackground: 'rgba(153, 117, 0, 0.051)',
+ warningBorder: '1px solid rgba(153, 117, 0, 0.01)',
+ emptyBackground: 'rgba(61, 66, 77, 1)',
+ neutral,
+ primary,
+ warning,
+ error,
+ success,
};
diff --git a/src/components/TotalValueLocked.tsx b/src/components/TotalValueLocked.tsx
index bc502c9..36c21a7 100644
--- a/src/components/TotalValueLocked.tsx
+++ b/src/components/TotalValueLocked.tsx
@@ -1,23 +1,10 @@
-import { formatDataNumber } from '~/utils';
-
-export interface TokenValueLocked {
- token: string;
- value: number;
-}
-
+import { TvlData } from '~/types';
+import { Box } from '@mui/material';
interface TotalValueLockedProps {
- tvl: { [token: string]: number }[];
+ tvl: TvlData[];
}
export const TotalValueLocked = ({ tvl }: TotalValueLockedProps) => {
- return (
-
- {tvl.map((data, index) => (
-
- {data.token}
- {formatDataNumber(data.value, 0, true)}
-
- ))}
-
- );
+ console.log(tvl);
+ return {/* Token graph tvl */};
};
diff --git a/src/containers/ChainDetail/ChainMetadata.tsx b/src/containers/ChainDetail/ChainMetadata.tsx
index 35f1f91..b90cdbe 100644
--- a/src/containers/ChainDetail/ChainMetadata.tsx
+++ b/src/containers/ChainDetail/ChainMetadata.tsx
@@ -25,9 +25,9 @@ export const ChainMetadata = () => {
{/*
*/}
diff --git a/src/containers/Dashboard/index.tsx b/src/containers/Dashboard/index.tsx
index fb425bc..a84cddb 100644
--- a/src/containers/Dashboard/index.tsx
+++ b/src/containers/Dashboard/index.tsx
@@ -1,6 +1,6 @@
import { useTranslation } from 'next-i18next';
-import { NotFound, Table, Title } from '~/components';
+import { NotFound, DataTable, Title } from '~/components';
import { useData, useStateContext } from '~/hooks';
export const Dashboard = () => {
@@ -8,12 +8,12 @@ export const Dashboard = () => {
const { ecosystemData } = useData();
const { searchTerm } = useStateContext();
- const filteredChains = ecosystemData?.chains.filter((chain) => {
- const chainIdStr = String(chain.id);
+ const filteredChains = ecosystemData?.zkChains.filter((chain) => {
+ const chainIdStr = String(chain.chainId);
const formattedSearchTerm = String(searchTerm).toLowerCase();
// Check if either chain name or chain ID matches the search term
- const matchesName = chain.name.toLowerCase().includes(formattedSearchTerm);
+ const matchesName = chain.chainName.toLowerCase().includes(formattedSearchTerm);
const matchesId = chainIdStr.includes(formattedSearchTerm);
return matchesName || matchesId;
@@ -27,7 +27,7 @@ export const Dashboard = () => {
- {availableChains &&
}
+ {availableChains &&
}
{!availableChains &&
}
);
diff --git a/src/containers/LockedAssets/index.tsx b/src/containers/LockedAssets/index.tsx
index 3d0212d..f86c22d 100644
--- a/src/containers/LockedAssets/index.tsx
+++ b/src/containers/LockedAssets/index.tsx
@@ -6,14 +6,14 @@ import { formatDataNumber } from '~/utils';
export const LockedAssets = () => {
const { t } = useTranslation();
- const { ecosystemData } = useData();
+ const { ecosystemData, totalL1TVL } = useData();
return (
{ecosystemData && (
<>
-
-
+
+
>
)}
diff --git a/src/data/ecosystemMockData.json b/src/data/ecosystemMockData.json
index acb7d40..fe39716 100644
--- a/src/data/ecosystemMockData.json
+++ b/src/data/ecosystemMockData.json
@@ -1,92 +1,95 @@
{
- "chains": [
+ "l1Tvl": [
{
- "name": "zkSync Era",
- "id": 324,
- "nativeToken": "ETH",
- "tvl": 1000000,
- "type": "ZKRollup"
- },
- {
- "name": "Teva Chain",
- "id": 100,
- "nativeToken": "ETH",
- "tvl": 1000000,
- "type": "ZKRollup"
- },
- {
- "name": "Cronos zkEVM",
- "id": 101,
- "nativeToken": "ETH",
- "tvl": 1000000,
- "type": "Validium"
- },
- {
- "name": "GRVT",
- "id": 102,
- "nativeToken": "ETH",
- "tvl": 1000000,
- "type": "Validium"
- },
- {
- "name": "Lens",
- "id": 103,
- "nativeToken": "ETH",
- "tvl": 1000000,
- "type": "Validium"
- },
- {
- "name": "ZKChain 104",
- "id": 104,
- "nativeToken": "ETH",
- "tvl": 1000000,
- "type": "ZKRollup"
+ "token": "ETH",
+ "total": 557596566000,
+ "imageUrl": "https://coin-images.coingecko.com/coins/images/279/large/ethereum.png?1696501628"
},
{
- "name": "ZKChain 105",
- "id": 105,
- "nativeToken": "ETH",
- "tvl": 1000000,
- "type": "Validium"
- }
- ],
- "total": 700000000,
- "tvl": [
- {
- "token": "ETH",
- "value": 557596566
+ "token": "USDT",
+ "total": 114493849618,
+ "imageUrl": "https://coin-images.coingecko.com/coins/images/325/large/tether.png"
},
{
"token": "USDC",
- "value": 90091851
+ "total": 34115209093,
+ "imageUrl": "https://coin-images.coingecko.com/coins/images/6319/large/usd-coin.png"
},
{
"token": "KOI",
- "value": 32757850
+ "total": 24115209093,
+ "imageUrl": "https://assets.coingecko.com/coins/images/35766/standard/Koi_logo.png?1709782399"
},
{
- "token": "USDT",
- "value": 18021853
+ "token": "WBTC",
+ "total": 12620248,
+ "imageUrl": "https://coin-images.coingecko.com/coins/images/5757/large/wrapped-bitcoin.png"
},
{
- "token": "WBTC",
- "value": 12620248
+ "token": "wsETH",
+ "total": 3552439,
+ "imageUrl": "https://coin-images.coingecko.com/coins/images/11320/large/staked-ether.png"
+ },
+ {
+ "token": "cbETH",
+ "total": 2552439,
+ "imageUrl": "https://assets.coingecko.com/coins/images/27008/standard/cbeth.png?1709186989"
},
{
- "token": "wstETH",
- "value": 3552439
+ "token": "BAL",
+ "total": 1552439,
+ "imageUrl": "https://coin-images.coingecko.com/coins/images/671/large/balancer.png"
+ }
+ ],
+ "ethGasInfo": {
+ "gasPrice": 50,
+ "ethTransfer": 21000,
+ "erc20Transfer": 65000
+ },
+ "zkChains": [
+ {
+ "chainId": 0,
+ "chainName": "ZKsyncERA",
+ "iconUrl": "https://s2.coinmarketcap.com/static/img/coins/64x64/24091.png",
+ "chainType": "Rollup",
+ "nativeToken": "ETH",
+ "tokenImgUrl": "https://coin-images.coingecko.com/coins/images/279/large/ethereum.png?1696501628",
+ "tvl": 1000000,
+ "metadata": true,
+ "rpc": true
},
{
- "token": "MUTE",
- "value": 2071481
+ "chainId": 1,
+ "chainName": "ZKsyncERA",
+ "iconUrl": "https://s2.coinmarketcap.com/static/img/coins/64x64/24091.png",
+ "chainType": "Validium",
+ "nativeToken": "ETH",
+ "tokenImgUrl": "https://coin-images.coingecko.com/coins/images/279/large/ethereum.png?1696501628",
+ "tvl": 500000,
+ "metadata": true,
+ "rpc": false
},
{
- "token": "rETH",
- "value": 1404096
+ "chainId": 2,
+ "chainName": "ZKsyncERA",
+ "iconUrl": "https://s2.coinmarketcap.com/static/img/coins/64x64/24091.png",
+ "chainType": "Rollup",
+ "nativeToken": "ETH",
+ "tokenImgUrl": "https://coin-images.coingecko.com/coins/images/279/large/ethereum.png?1696501628",
+ "tvl": 300000,
+ "metadata": false,
+ "rpc": true
},
{
- "token": "DAI",
- "value": 1080375
+ "chainId": 3,
+ "chainName": "ZKsyncERA",
+ "iconUrl": "https://s2.coinmarketcap.com/static/img/coins/64x64/24091.png",
+ "chainType": "Rollup",
+ "nativeToken": "ETH",
+ "tokenImgUrl": "https://coin-images.coingecko.com/coins/images/279/large/ethereum.png?1696501628",
+ "tvl": 10000,
+ "metadata": false,
+ "rpc": false
}
]
}
diff --git a/src/pages/[chain]/index.tsx b/src/pages/[chain]/index.tsx
index c5b142c..1dcbc6e 100644
--- a/src/pages/[chain]/index.tsx
+++ b/src/pages/[chain]/index.tsx
@@ -19,13 +19,13 @@ const Chain = ({ chain }: InferGetStaticPropsType
) => {
const { setSelectedChainId, refetchChainData } = useData();
useEffect(() => {
- setSelectedChainId(chain?.id);
+ setSelectedChainId(chain?.chainId);
refetchChainData({ throwOnError: true, cancelRefetch: false });
- }, [chain?.id, setSelectedChainId, refetchChainData]);
+ }, [chain?.chainId, setSelectedChainId, refetchChainData]);
return (
<>
-
+
>
);
@@ -33,11 +33,11 @@ const Chain = ({ chain }: InferGetStaticPropsType) => {
export const getStaticPaths: GetStaticPaths = async () => {
const ecosystemData = await fetchEcosystemData();
- const chains = ecosystemData.chains;
+ const chains = ecosystemData.zkChains;
const paths = SUPPORTED_LANGUAGES.flatMap((locale) =>
chains.map((chain: EcosystemChainData) => ({
- params: { chain: chain.id.toString() },
+ params: { chain: chain.chainId.toString() },
locale,
})),
);
@@ -47,9 +47,9 @@ export const getStaticPaths: GetStaticPaths = async () => {
export const getStaticProps: GetStaticProps = async ({ params, locale }: GetStaticPropsContext) => {
const ecosystemData = await fetchEcosystemData();
- const chains = ecosystemData.chains;
+ const chains = ecosystemData.zkChains;
const chainId = parseInt(params?.chain as string);
- const chain = chains.find((chain: EcosystemChainData) => chain.id === chainId);
+ const chain = chains.find((chain: EcosystemChainData) => chain.chainId === chainId);
if (!chain) {
return { notFound: true };
diff --git a/src/providers/DataProvider.tsx b/src/providers/DataProvider.tsx
index 5dc964e..6fd831e 100644
--- a/src/providers/DataProvider.tsx
+++ b/src/providers/DataProvider.tsx
@@ -2,7 +2,7 @@ import { createContext, useState, useEffect, ReactNode } from 'react';
import { useQuery, UseQueryResult } from '@tanstack/react-query';
import { useRouter } from 'next/router';
-import { ChainData, EcosystemData } from '~/types';
+import { ChainData, EcosystemData, TvlData } from '~/types';
import { fetchEcosystemData, fetchChainData } from '~/utils';
type ContextType = {
@@ -15,6 +15,8 @@ type ContextType = {
ecosystemData: EcosystemData;
chainData: ChainData;
+
+ totalL1TVL: number;
};
interface DataProps {
@@ -53,6 +55,10 @@ export const DataProvider = ({ children }: DataProps) => {
}
}, [isEcosystemError, isChainError, router]);
+ const totalL1TVL = (ecosystemData?.l1Tvl || []).reduce((accumulator: number, token: TvlData) => {
+ return accumulator + (token.total || 0);
+ }, 0);
+
return (
{
ecosystemData,
chainData,
refetchChainData,
+ totalL1TVL,
}}
>
{children}
diff --git a/src/types/Data.ts b/src/types/Data.ts
index 21121c0..30bb671 100644
--- a/src/types/Data.ts
+++ b/src/types/Data.ts
@@ -38,17 +38,29 @@ export interface ChainData {
}
export interface EcosystemChainData {
- name: string;
- id: number;
+ chainName: string;
+ chainId: number;
+ iconUrl: string;
nativeToken: string;
+ tokenImgUrl: string;
tvl: number;
- type: string;
+ chainType: string;
+ metadata: boolean;
+ rpc: boolean;
}
export interface EcosystemData {
- chains: EcosystemChainData[];
+ l1Tvl: TvlData[];
+ ethGasInfo: {
+ gasPrice: number;
+ ethTransfer: number;
+ erc20Transfer: number;
+ };
+ zkChains: EcosystemChainData[];
+}
+
+export interface TvlData {
+ token: string;
total: number;
- tvl: {
- [token: string]: number;
- }[];
+ imageUrl: string;
}
diff --git a/src/types/Theme.ts b/src/types/Theme.ts
index 050dee9..dcc5dbe 100644
--- a/src/types/Theme.ts
+++ b/src/types/Theme.ts
@@ -12,9 +12,19 @@ export interface Theme {
textFontFamily: string;
borderRadius: string;
secondaryBorderRadius: string;
+ transition: string;
border: string;
gap: string;
+ warningText: string;
+ warningBackground: string;
+ warningBorder: string;
+ emptyBackground: string;
padding: string;
+ neutral: { [key: number]: string };
+ primary: { [key: number]: string };
+ warning: { [key: number]: string };
+ error: { [key: number]: string };
+ success: { [key: number]: string };
}
export interface PropTheme {