Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
d69e65d
change port
Jul 19, 2023
75825f0
Merge pull request #1 from hyperliquid-dex/fix
Jul 19, 2023
7511e5f
wip
tradermohamed Jul 19, 2023
6238fb5
clean up
tradermohamed Jul 19, 2023
7edee18
also sort coins alphabetically and minor fixes
tradermohamed Jul 20, 2023
b67f40d
run prettify
tradermohamed Jul 20, 2023
38d2af5
more clean up
tradermohamed Jul 20, 2023
bc0d2ec
cu
tradermohamed Jul 20, 2023
30da274
Add ability to select coin to display on funding rate graph
tradermohamed Jul 21, 2023
526c9d2
fees
tradermohamed Jul 24, 2023
803c706
wip
tradermohamed Jul 24, 2023
cf46ffb
wip
tradermohamed Jul 25, 2023
1095f6b
fix fees
tradermohamed Jul 25, 2023
500327c
wip
tradermohamed Jul 25, 2023
c8b6937
wip
tradermohamed Jul 25, 2023
686a82e
wip
tradermohamed Jul 25, 2023
3b44ee1
naming
tradermohamed Jul 26, 2023
da25707
fixes
tradermohamed Jul 26, 2023
40ab55e
fixes
tradermohamed Jul 26, 2023
9400b5d
fixes
tradermohamed Jul 27, 2023
d4b097e
mobile
tradermohamed Jul 31, 2023
2b87451
fix
tradermohamed Jul 31, 2023
d6ee9fc
Merge pull request #3 from hyperliquid-dex/mohamed/charts
tradermohamed Jul 31, 2023
120d966
Updating hedged pnl
Jul 31, 2023
1650222
Merge pull request #4 from hyperliquid-dex/shwe/charts
trophies2015 Jul 31, 2023
fccc727
add explainer
Jul 31, 2023
9bf33b1
Changing slippage graph
Jul 31, 2023
e07cfd2
Updating Hedged HLP description
Jul 31, 2023
34116d5
Merge pull request #5 from hyperliquid-dex/shwe/liquidity
trophies2015 Jul 31, 2023
a3da425
Fix syncing
Jul 31, 2023
f5d0286
update sync naming
Jul 31, 2023
6468f7b
Merge pull request #6 from hyperliquid-dex/shwe/sync
trophies2015 Jul 31, 2023
3184ff1
Slippage and HLP graph
tradermohamed Aug 1, 2023
4257b4d
Fix isMobile bug
Aug 1, 2023
461a577
style
Aug 1, 2023
d4bf202
Merge pull request #8 from hyperliquid-dex/shwe/isMobile
trophies2015 Aug 1, 2023
8c7507f
Shwe/colors (#10)
trophies2015 Aug 2, 2023
e89f4d1
Merge mobile changes (#12)
tradermohamed Aug 2, 2023
0f1bf1a
Change data format and add github/telegram
Aug 2, 2023
9057031
small updates
Aug 2, 2023
4e99658
more fixes
Aug 2, 2023
d14d6be
prettify
Aug 2, 2023
5b60f56
apos fix
Aug 2, 2023
0ad9511
fixes
Aug 2, 2023
8be1e73
Revert "Merge mobile changes (#12)"
Aug 3, 2023
e8298b1
Merge pull request #16 from hyperliquid-dex/reverting
trophies2015 Aug 3, 2023
eef6ecc
Merge pull request #17 from hyperliquid-dex/shwe/allfixes
trophies2015 Aug 3, 2023
29de041
Misc clean up and fixes (#18)
tradermohamed Aug 3, 2023
b8d83a9
Fixing slippage chart and misc clean up (#19)
tradermohamed Aug 10, 2023
e76c2de
Add mixpanel event for loading stats page
traderben Aug 10, 2023
8493b25
Change desription and title
Aug 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
NEXT_PUBLIC_API_URL = http://localhost:8000
NEXT_PUBLIC_API_URL = https://stats-api.hyperliquid.xyz
NEXT_PUBLIC_GOOGLE_ANALYTICS_CONFIG = G-8GN39Z428L

10 changes: 5 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"typescript.enablePromptUseWorkspaceTsdk": true,
"editor.wordWrap": "wordWrapColumn",
"editor.wordWrapColumn": 140,
"typescript.tsdk": "node_modules/typescript/lib"
}
"typescript.enablePromptUseWorkspaceTsdk": true,
"editor.wordWrap": "wordWrapColumn",
"editor.wordWrapColumn": 140,
"typescript.tsdk": "node_modules/typescript/lib"
}
34 changes: 14 additions & 20 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import { ChakraProvider } from '@chakra-ui/react';
import theme from "../styles/theme";
import { Providers } from "./providers";
import theme from '../styles/theme';
import { Providers } from './providers';

export const metadata = {
title: 'Hyperliquid Stats',
description: 'Explore the Hyperliquid protocol’s statistics',
}

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
title: 'Hyperliquid stats',
description:
'Stats dashboard for Hyperliquid, a decentralized perpetual futures exchange on its own L1. Metrics include volume, users, open interest, funding rate, vault pnl, trader pnl, liquidations, inflows, outflows, and more.',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<html lang='en'>
<head>
<meta name="viewport" content="width=device-width" />
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png" />
<meta name='viewport' content='width=device-width' />
<link rel='apple-touch-icon' sizes='180x180' href='/img/apple-touch-icon.png' />
<link rel='icon' type='image/png' sizes='32x32' href='/img/favicon-32x32.png' />
<link rel='icon' type='image/png' sizes='16x16' href='/img/favicon-16x16.png' />
</head>
<body>
<Providers>
{children}
</Providers>
<Providers>{children}</Providers>
</body>
</html>
)
);
}
47 changes: 21 additions & 26 deletions app/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
'use client'
'use client';
import { useEffect } from 'react';
import { CacheProvider } from '@chakra-ui/next-js'
import { ChakraProvider } from '@chakra-ui/react'
import TagManager from 'react-gtm-module'
import { CacheProvider } from '@chakra-ui/next-js';
import { ChakraProvider } from '@chakra-ui/react';
import TagManager from 'react-gtm-module';
import { Global } from '@emotion/react';
import theme from "../styles/theme";
import theme from '../styles/theme';
import { GlobalStyles } from '@/styles/global';
import { DataContextProvider } from "../contexts/data";
import { DataContextProvider } from '../contexts/data';

const tagManagerArgs = { gtmId: process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_CONFIG as string };

export function Providers({
children
}: {
children: React.ReactNode
}) {
export function Providers({ children }: { children: React.ReactNode }) {
useEffect(() => {
TagManager.initialize(tagManagerArgs);
}, []);

useEffect(() => {
TagManager.initialize(tagManagerArgs)
}, []);

return (
<DataContextProvider>
<CacheProvider>
<ChakraProvider theme={theme}>
<Global styles={GlobalStyles} />
{children}
</ChakraProvider>
</CacheProvider>
</DataContextProvider>
)
}
return (
<DataContextProvider>
<CacheProvider>
<ChakraProvider theme={theme}>
<Global styles={GlobalStyles} />
{children}
</ChakraProvider>
</CacheProvider>
</DataContextProvider>
);
}
210 changes: 151 additions & 59 deletions components/common/chartWrapper/index.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,159 @@
import { RiLoader5Fill } from 'react-icons/ri';
import { Box, Button, ButtonGroup, Text, Spinner } from '@chakra-ui/react';
import { useIsMobile } from '@/hooks/useIsMobile';
import { ChevronDownIcon } from '@chakra-ui/icons';
import {
Box,
Button,
ButtonGroup,
Text,
Spinner,
MenuButton,
Menu,
MenuList,
MenuItemOption,
MenuOptionGroup,
Grid,
} from '@chakra-ui/react';

interface Toggle {
text: string;
event: () => void;
active: boolean;
text: string;
event: () => void;
active: boolean;
}

const Loader = () => <Box w="100%" position="absolute" top="calc(50% - 10px)" display="flex" justifyContent="center"><Spinner display="flex" w="30px" h="30px" /></Box>
export interface CoinSelector {
name: string;
event: () => void;
isChecked: boolean;
}

const Loader = () => (
<Box w='100%' position='absolute' top='calc(50% - 10px)' display='flex' justifyContent='center'>
<Spinner display='flex' w='30px' h='30px' />
</Box>
);

type Props = {
title: string;
loading: boolean;
controls?: {
toggles: Toggle[];
};
zIndex?: number;
coinSelectors?: CoinSelector[];
children?: React.ReactNode;
};

function ChartWrapper({ title, loading, controls, zIndex, coinSelectors, children }: Props) {
const isMobile = useIsMobile();
const controlButtons =
controls &&
controls.toggles &&
controls.toggles.length > 0 &&
controls.toggles.map((toggle: Toggle, index: number) => {
return (
<Button
key={`toggle-chart-${index}`}
onClick={() => toggle.event()}
variant={toggle.active ? 'primary' : 'faded'}
size='sm'
>
{toggle.text}
</Button>
);
});

const coinSelectorsMenu = coinSelectors && (
<Box>
<Menu closeOnSelect={false} preventOverflow={true}>
<MenuButton
as={Button}
rightIcon={<ChevronDownIcon />}
variant='primary'
fontSize={'14px'}
size='sm'
>
Select coins
</MenuButton>
<MenuList
minWidth='100px'
maxHeight='300px'
overflowY='auto'
css={{
'&::-webkit-scrollbar': {
width: '4px',
},
'&::-webkit-scrollbar-track': {
width: '6px',
},
'&::-webkit-scrollbar-thumb': {
background: '#FFF',
borderRadius: '24px',
},
}}
>
<MenuOptionGroup
type='checkbox'
value={coinSelectors
.filter((coinSelector: CoinSelector) => coinSelector.isChecked)
.map((coinSelector: CoinSelector) => coinSelector.name)}
>
{coinSelectors.map((coinSelector: CoinSelector, index: number) => {
return (
<MenuItemOption
value={coinSelector.name}
key={`toggle-chart-${index}`}
onClick={() => coinSelector.event()}
isChecked={coinSelector.isChecked}
>
{coinSelector.name}
</MenuItemOption>
);
})}
</MenuOptionGroup>
</MenuList>
</Menu>
</Box>
);

function ChartWrapper(props: any) {
const {
title,
loading,
csvFields,
data,
controls,
zIndex,
} = props;
const menu = (
<Box display='flex' padding='0'>
<Grid
mb='1rem'
templateColumns='1fr auto'
gap={controls ? '2' : '0'}
justifyContent='flex-start'
>
{isMobile && controls ? (
controlButtons
) : (
<ButtonGroup isAttached={true}>{controlButtons}</ButtonGroup>
)}
{coinSelectorsMenu}
</Grid>
</Box>
);

return (
<Box display="grid" width={{ xs: '100%', md: '100%' }} mt="3" p={{ xs: '0', md: '0 5 0 0' }}>
<Box position="relative"
p={{ xs: '2', md: '4' }}
bg="#0f2e29"
boxShadow="0px 0px 7px rgb(0 0 0 / 20%)"
borderRadius={{ xs: '0', md: '2xl' }}
zIndex={zIndex}
>
<Box w="100%" mb="2">
<Box w="100%" mb="2"
display="flex"
justifyContent="space-between"
flexDirection={{ xs: "column", md: "row" }}
>
<Text display="flex" w={{ xs: "100%", md: "100%" }} fontSize="1.2rem" fontWeight="600">
{title}
</Text>
<Box w={{ xs: "100%", md: "100%" }} display="flex" justifyContent={{ xs: "flex-start", md: "flex-end" }}
mt={controls && controls.toggles && controls.toggles.length && "2"}
mb="1rem">
<ButtonGroup isAttached={true}>
{controls && controls.toggles && controls.toggles.length > 0 && controls.toggles.map((toggle: Toggle, index: number) => {
return (
<Button
key={`toggle-chart-${index}`}
onClick={() => toggle.event()}
variant={toggle.active ? "primary" : "faded"}
size="sm"
>
{toggle.text}
</Button>
)
})}
</ButtonGroup>
</Box>
</Box>
</Box>
{loading && <Loader />}
{props.children}
</Box>
</Box>
);
return (
<Box display='grid' mt='3' p={{ xs: '0', md: '0 5 0 0' }}>
<Box
position='relative'
p={{ xs: '2', md: '4' }}
bg='#0f2e29'
boxShadow='0px 0px 7px rgb(0 0 0 / 20%)'
borderRadius={{ xs: '0', md: '2xl' }}
zIndex={zIndex}
>
<Grid gridTemplateColumns={{ xs: '1fr', xl: '1fr auto' }} gap={4}>
<Text fontSize='1.2rem' fontWeight='600' whiteSpace={'nowrap'}>
{title}
</Text>
{menu}
</Grid>
{loading && <Loader />}
{children}
</Box>
</Box>
);
}

export default ChartWrapper;
export default ChartWrapper;
Loading