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} + {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 ( - - - - - - - - - - {chains?.map((data, index) => { - return ( - handleChainNavigation(data.id)}> - - - - - - - ); - })} -
{t('HOME.DASHBOARD.chain')}{t('HOME.DASHBOARD.chainId')}{t('HOME.DASHBOARD.nativeToken')}{t('HOME.DASHBOARD.tvl')}{t('HOME.DASHBOARD.type')}
{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 = () => { </header> - {availableChains && <Table chains={filteredChains} />} + {availableChains && <DataTable chains={filteredChains} />} {!availableChains && <NotFound text={t('HOME.DASHBOARD.notFound')} />} </section> ); 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 ( <section> {ecosystemData && ( <> - <Title title={`${t('HOME.lockedAssets')}: ${formatDataNumber(ecosystemData.total, 0, true, true)}`} /> - <TotalValueLocked tvl={ecosystemData.tvl} /> + <Title title={`${t('HOME.lockedAssets')}: ${formatDataNumber(totalL1TVL, 0, true, true)}`} /> + <TotalValueLocked tvl={ecosystemData.l1Tvl} /> </> )} </section> 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<typeof getStaticProps>) => { 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 ( <> - <CustomHead title={chain?.name} /> + <CustomHead title={chain?.chainName} /> <ChainDetail /> </> ); @@ -33,11 +33,11 @@ const Chain = ({ chain }: InferGetStaticPropsType<typeof getStaticProps>) => { 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<ChainProps> = 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 ( <DataContext.Provider value={{ @@ -63,6 +69,7 @@ export const DataProvider = ({ children }: DataProps) => { 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 {