Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add stats page #296

Merged
merged 7 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@invariant-labs/a0-sdk": "^0.2.19",
"@invariant-labs/a0-sdk": "^0.2.20",
"@mui/icons-material": "^5.15.15",
"@mui/material": "^5.15.15",
"@nightlylabs/wallet-selector-polkadot": "^0.2.5",
Expand Down
9 changes: 8 additions & 1 deletion src/components/Stats/PoolList/PoolList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useStyles } from './style'
import { Grid } from '@mui/material'
import { PaginationList } from '@components/PaginationList/PaginationList'
import { SortTypePoolList } from '@store/consts/static'
import { Network } from '@invariant-labs/a0-sdk'

interface PoolListInterface {
data: Array<{
Expand All @@ -15,16 +16,19 @@ interface PoolListInterface {
volume: number
TVL: number
fee: number
addressFrom: string
addressTo: string
// apy: number
// apyData: {
// fees: number
// accumulatedFarmsAvg: number
// accumulatedFarmsSingleTick: number
// }
}>
network: Network
}

const PoolList: React.FC<PoolListInterface> = ({ data }) => {
const PoolList: React.FC<PoolListInterface> = ({ data, network }) => {
const { classes } = useStyles()
const [page, setPage] = React.useState(1)
const [sortType, setSortType] = React.useState(SortTypePoolList.VOLUME_DESC)
Expand Down Expand Up @@ -92,6 +96,9 @@ const PoolList: React.FC<PoolListInterface> = ({ data }) => {
// apy={element.apy}
// apyData={element.apyData}
key={index}
addressFrom={element.addressFrom}
addressTo={element.addressTo}
network={network}
/>
))}
{pages > 1 ? (
Expand Down
8 changes: 6 additions & 2 deletions src/components/Stats/PoolList/Stats.PoolList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MemoryRouter } from 'react-router-dom'
import PoolList from './PoolList'
import { store } from '@store/index'
import { Provider } from 'react-redux'
import { Network } from '@invariant-labs/a0-sdk'

const meta = {
title: 'Stats/PoolList',
Expand Down Expand Up @@ -75,12 +76,15 @@ const poolsList = Array(40)
coingeckoId: 'usd-coin'
},
volume24: randomVolume24,
tvl: randomTvl24
tvl: randomTvl24,
addressFrom: '5Dvb5E8zKU4E9c7YxfNL5VC8YQj4VAFUTCGYY9ayFLnnY3UA',
addressTo: '5Dvb5E8zKU4E9c7YxfNL5VC8YQj4VAFUTCGYY9ayFLnnY3UA'
}
})

export const Primary: Story = {
args: {
data: poolsList
data: poolsList,
network: Network.Local
}
}
20 changes: 16 additions & 4 deletions src/components/Stats/PoolListItem/PoolListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import React from 'react'
import { theme } from '@static/theme'
import { useStyles } from './style'
import { Box, Grid, Typography, useMediaQuery } from '@mui/material'
import { formatNumbers, showPrefix } from '@utils/utils'
import { addressToTicker, formatNumbers, parseFeeToPathFee, showPrefix } from '@utils/utils'
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'
import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'
import { useNavigate } from 'react-router-dom'
import icons from '@static/icons'
import { SortTypePoolList } from '@store/consts/static'
import { Network } from '@invariant-labs/a0-sdk'
import { PERCENTAGE_SCALE } from '@invariant-labs/a0-sdk/target/consts'

interface IProps {
TVL?: number
Expand All @@ -22,6 +24,9 @@ interface IProps {
sortType?: SortTypePoolList
onSort?: (type: SortTypePoolList) => void
hideBottomLine?: boolean
addressFrom?: string
addressTo?: string
network?: Network
// apy?: number
// apyData?: {
// fees: number
Expand All @@ -42,7 +47,10 @@ const PoolListItem: React.FC<IProps> = ({
tokenIndex,
sortType,
onSort,
hideBottomLine = false
hideBottomLine = false,
addressFrom,
addressTo,
network
// apy = 0,
// apyData = {
// fees: 0,
Expand All @@ -56,11 +64,15 @@ const PoolListItem: React.FC<IProps> = ({
const isXs = useMediaQuery(theme.breakpoints.down('xs'))

const handleOpenPosition = () => {
navigate(`/newPosition/${symbolFrom}/${symbolTo}/0_01`)
navigate(
`/newPosition/${addressToTicker(network ?? Network.Testnet, addressFrom ?? '')}/${addressToTicker(network ?? Network.Testnet, addressTo ?? '')}/${parseFeeToPathFee(BigInt(Math.round(fee * 10 ** Number(PERCENTAGE_SCALE - 2n))))}`
)
}

const handleOpenSwap = () => {
navigate(`/exchange/${symbolFrom}/${symbolTo}`)
navigate(
`/exchange/${addressToTicker(network ?? Network.Testnet, addressFrom ?? '')}/${addressToTicker(network ?? Network.Testnet, addressTo ?? '')}`
)
}
return (
<Grid maxWidth='100%'>
Expand Down
75 changes: 32 additions & 43 deletions src/containers/WrappedStats/WrappedStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,38 @@ import { useDispatch, useSelector } from 'react-redux'
import loader from '@static/gif/loader.gif'
import useStyles from './styles'
import { Grid, Typography } from '@mui/material'
import { Network } from '@invariant-labs/a0-sdk'
import { EmptyPlaceholder } from '@components/EmptyPlaceholder/EmptyPlaceholder'
// import {
// fees24,
// isLoading,
// liquidityPlot,
// poolsStatsWithTokensDetails,
// tokensStatsWithTokensDetails,
// tvl24,
// volume24,
// volumePlot
// } from '@store/selectors/stats'
import {
fees24,
isLoading,
liquidityPlot,
poolsStatsWithTokensDetails,
tokensStatsWithTokensDetails,
tvl24,
volume24,
volumePlot
} from '@store/selectors/stats'
import { networkType } from '@store/selectors/connection'
import { actions } from '@store/reducers/stats'
import Volume from '@components/Stats/Volume/Volume'
import Liquidity from '@components/Stats/Liquidity/Liquidity'
import VolumeBar from '@components/Stats/volumeBar/VolumeBar'
import TokensList from '@components/Stats/TokensList/TokensList'
import PoolList from '@components/Stats/PoolList/PoolList'
import {
isLoadingStats,
liquidityPlotData,
fees24h,
poolsList,
tokensList,
tvl24h,
volume24h,
volumePlotData
} from './mockStats'

export const WrappedStats: React.FC = () => {
const { classes } = useStyles()

const dispatch = useDispatch()

// const poolsList = useSelector(poolsStatsWithTokensDetails)
// const tokensList = useSelector(tokensStatsWithTokensDetails)
// const volume24h = useSelector(volume24)
// const tvl24h = useSelector(tvl24)
// const fees24h = useSelector(fees24)
// const volumePlotData = useSelector(volumePlot)
// const liquidityPlotData = useSelector(liquidityPlot)
// const isLoadingStats = useSelector(isLoading)
const poolsList = useSelector(poolsStatsWithTokensDetails)
const tokensList = useSelector(tokensStatsWithTokensDetails)
const volume24h = useSelector(volume24)
const tvl24h = useSelector(tvl24)
const fees24h = useSelector(fees24)
const volumePlotData = useSelector(volumePlot)
const liquidityPlotData = useSelector(liquidityPlot)
const isLoadingStats = useSelector(isLoading)
const currentNetwork = useSelector(networkType)

useEffect(() => {
Expand All @@ -54,11 +43,7 @@ export const WrappedStats: React.FC = () => {

return (
<Grid container className={classes.wrapper} direction='column'>
{currentNetwork !== Network.Testnet ? (
<Grid container direction='column' alignItems='center'>
<EmptyPlaceholder desc={'We have not started collecting statistics yet'} />
</Grid>
) : isLoadingStats ? (
{isLoadingStats ? (
<img src={loader} className={classes.loading} alt='Loading' />
) : liquidityPlotData.length === 0 ? (
<Grid container direction='column' alignItems='center'>
Expand Down Expand Up @@ -95,11 +80,12 @@ export const WrappedStats: React.FC = () => {
<Grid container className={classes.row}>
<TokensList
data={tokensList.map(tokenData => ({
icon: tokenData.tokenDetails.logoURI,
name: tokenData.tokenDetails.name,
symbol: tokenData.tokenDetails.symbol,
icon: tokenData.tokenDetails?.logoURI,
name: tokenData.tokenDetails?.name,
symbol: tokenData.tokenDetails?.symbol,
price: tokenData.price,
priceChange: tokenData.priceChange,
// priceChange: tokenData.priceChange,
priceChange: 0,
volume: tokenData.volume24,
TVL: tokenData.tvl
}))}
Expand All @@ -108,13 +94,15 @@ export const WrappedStats: React.FC = () => {
<Typography className={classes.subheader}>Top pools</Typography>
<PoolList
data={poolsList.map(poolData => ({
symbolFrom: poolData.tokenXDetails.symbol,
symbolTo: poolData.tokenYDetails.symbol,
iconFrom: poolData.tokenXDetails.logoURI,
iconTo: poolData.tokenYDetails.logoURI,
symbolFrom: poolData.tokenXDetails?.symbol,
symbolTo: poolData.tokenYDetails?.symbol,
iconFrom: poolData.tokenXDetails?.logoURI,
iconTo: poolData.tokenYDetails?.logoURI,
volume: poolData.volume24,
TVL: poolData.tvl,
fee: poolData.fee
fee: poolData.fee,
addressFrom: poolData.tokenX,
addressTo: poolData.tokenY
// apy: poolData.apy,
// apyData: {
// fees: poolData.apy,
Expand All @@ -130,6 +118,7 @@ export const WrappedStats: React.FC = () => {
// accumulatedFarmsAvg: accumulatedAverageAPY?.[poolData.poolAddress.toString()] ?? 0
// }
}))}
network={currentNetwork}
/>
</>
)}
Expand Down
6 changes: 2 additions & 4 deletions src/pages/StatsPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { Grid } from '@mui/material'
import { useStyles } from './styles'
import comingSoon from '../../static/png/coming-soon.png'
// import WrappedStats from '@containers/WrappedStats/WrappedStats'
import WrappedStats from '@containers/WrappedStats/WrappedStats'

export const StatsPage: React.FC = () => {
const { classes } = useStyles()

return (
<Grid container className={classes.container}>
<img src={comingSoon} alt='Coming soon' />
{/* <WrappedStats /> */}
<WrappedStats />
</Grid>
)
}
Expand Down
56 changes: 56 additions & 0 deletions src/store/consts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,59 @@ export enum Chain {
AlephZero = 'Aleph Zero',
Eclipse = 'Eclipse'
}

export interface SnapshotValueData {
tokenBNFromBeginning: string
usdValue24: number
}

export interface PoolSnapshot {
timestamp: number
volumeX: SnapshotValueData
volumeY: SnapshotValueData
liquidityX: SnapshotValueData
liquidityY: SnapshotValueData
feeX: SnapshotValueData
feeY: SnapshotValueData
}

export interface FullSnap {
volume24: {
value: number
change: number
}
tvl24: {
value: number
change: number
}
fees24: {
value: number
change: number
}
tokensData: TokenStatsDataWithString[]
poolsData: PoolStatsDataWithString[]
volumePlot: TimeData[]
liquidityPlot: TimeData[]
}

export interface TokenStatsDataWithString {
address: string
price: number
volume24: number
tvl: number
}

export interface TimeData {
timestamp: number
value: number
}

export interface PoolStatsDataWithString {
poolAddress: string
tokenX: string
tokenY: string
fee: number
volume24: number
tvl: number
apy: number
}
2 changes: 0 additions & 2 deletions src/store/reducers/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ export interface Value24H {
export interface TokenStatsData {
address: string
price: number
priceChange: number
volume24: number
tvl: number
}

export interface PoolStatsData {
poolAddress: string
tokenX: string
tokenY: string
fee: number
Expand Down
5 changes: 4 additions & 1 deletion src/store/sagas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import { poolsSaga } from './pools'
import { positionsSaga } from './positions'
import { swapSaga } from './swap'
import { walletSaga } from './wallet'
import { statsHandler } from './stats'

function* rootSaga(): Generator {
yield all([connectionSaga, walletSaga, poolsSaga, positionsSaga, swapSaga].map(spawn))
yield all(
[connectionSaga, walletSaga, poolsSaga, positionsSaga, swapSaga, statsHandler].map(spawn)
)
}
export default rootSaga
Loading
Loading