Feature/fix token history request v2 (#403)

* fix large token stats request

* fix

* upgrade settings lib

* fix

* fix

* fix

* fix

* fix cd

* test

* fix build
This commit is contained in:
Adrian Brzeziński 2024-03-15 14:03:59 +01:00 committed by GitHub
parent 74c3ebc00c
commit dc10d611d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 83 additions and 102 deletions

View File

@ -1,11 +1,14 @@
import { Group, I64_MAX_BN } from '@blockworks-foundation/mango-v4'
import { Group } from '@blockworks-foundation/mango-v4'
import { PublicKey } from '@solana/web3.js'
import { MangoTokenStatsItem, TokenStatsItem } from 'types'
import { MANGO_DATA_API_URL } from 'utils/constants'
export const fetchTokenStatsData = async (group: Group) => {
const response = await fetch(
`${MANGO_DATA_API_URL}/token-historical-stats?mango-group=${group?.publicKey.toString()}`,
)
export const fetchTokenStatsData = async (group: Group, mint?: PublicKey) => {
let url = `${MANGO_DATA_API_URL}/token-historical-stats?mango-group=${group?.publicKey.toString()}`
if (mint) {
url = `${url}&mint=${mint.toBase58()}`
}
const response = await fetch(url)
if (!response.ok) {
throw new Error('Network response was not ok')
}
@ -52,7 +55,7 @@ export const processTokenStatsData = (
const previous = filtered.reduce((max, cur) =>
max.date_hour > cur.date_hour ? max : cur,
)
let tokenStatsItem: TokenStatsItem = {
const tokenStatsItem: TokenStatsItem = {
borrow_apr: previous.borrow_apr,
borrow_rate: bank.getBorrowRateUi() / 100,
collected_fees: previous.collected_fees,

View File

@ -573,7 +573,7 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
new BN(proposedPreset.depositLimit.toString()),
Number(proposedPreset.zeroUtilRate),
Number(proposedPreset.platformLiquidationFee),
false,
proposedPreset.disableAssetLiquidation,
Number(proposedPreset.collateralFeePerDay),
)
.accounts({

View File

@ -208,7 +208,9 @@ const DashboardSuggestedValues = ({
: null,
getNullOrVal(fieldsToChange.zeroUtilRate),
getNullOrVal(fieldsToChange.platformLiquidationFee),
null,
fieldsToChange.disableAssetLiquidation === undefined
? null
: fieldsToChange.disableAssetLiquidation,
getNullOrVal(fieldsToChange.collateralFeePerDay),
null,
)

View File

@ -1,34 +1,26 @@
import mangoStore from '@store/mangoStore'
import { useTranslation } from 'next-i18next'
import { useEffect, useState } from 'react'
import { useState } from 'react'
import { formatYAxis } from 'utils/formatting'
import DetailedAreaOrBarChart from '@components/shared/DetailedAreaOrBarChart'
import NetDepositsChart from './NetDepositsChart'
import { useTokenStats } from 'hooks/useTokenStats'
const DepositsAndBorrows = () => {
const { t } = useTranslation(['common', 'token', 'trade'])
const mangoStats = mangoStore((s) => s.tokenStats.mangoStats)
const loadingStats = mangoStore((s) => s.tokenStats.loading)
const { data: tokenStats, isLoading } = useTokenStats()
const [borrowDaysToShow, setBorrowDaysToShow] = useState('30')
const [depositDaysToShow, setDepositDaysToShow] = useState('30')
const tokenStatsInitialLoad = mangoStore((s) => s.tokenStats.initialLoad)
useEffect(() => {
if (!tokenStatsInitialLoad) {
const actions = mangoStore.getState().actions
actions.fetchTokenStats()
}
}, [tokenStatsInitialLoad])
return (
<>
<div className="col-span-2 border-b border-th-bkg-3 px-6 py-4 md:col-span-1 lg:py-6 ">
<DetailedAreaOrBarChart
changeAsPercent
data={mangoStats}
data={tokenStats?.mangoStats}
daysToShow={depositDaysToShow}
setDaysToShow={setDepositDaysToShow}
loading={loadingStats}
loading={isLoading}
heightClass="h-64"
loaderHeightClass="h-[350px]"
prefix="$"
@ -41,12 +33,12 @@ const DepositsAndBorrows = () => {
<div className="col-span-2 border-b border-th-bkg-3 px-6 py-4 md:col-span-1 md:pl-6 lg:py-6">
<DetailedAreaOrBarChart
changeAsPercent
data={mangoStats}
data={tokenStats?.mangoStats}
daysToShow={borrowDaysToShow}
setDaysToShow={setBorrowDaysToShow}
heightClass="h-64"
loaderHeightClass="h-[350px]"
loading={loadingStats}
loading={isLoading}
prefix="$"
tickFormat={(x) => `$${formatYAxis(x)}`}
title={t('total-borrow-value')}

View File

@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next'
import { MangoTokenStatsItem } from 'types'
import { formatYAxis } from 'utils/formatting'
import { groupPerpByHourlyInterval } from './Volume'
import { useTokenStats } from 'hooks/useTokenStats'
interface GroupedTokenDataItem extends MangoTokenStatsItem {
intervalStartMillis: number
@ -42,8 +43,8 @@ const groupTokenByHourlyInterval = (
const Fees = () => {
const { t } = useTranslation(['common', 'token', 'trade'])
const mangoStats = mangoStore((s) => s.tokenStats.mangoStats)
const loadingStats = mangoStore((s) => s.tokenStats.loading)
const { data: tokenStats, isLoading } = useTokenStats()
const mangoStats = tokenStats?.mangoStats
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
const [feesDaysToShow, setFeesDaysToShow] = useState('30')
const [showCumulativeFees, setShowCumulativeFees] = useState(true)
@ -52,7 +53,7 @@ const Fees = () => {
const { feeValues: perpFeeChartData } = usePerpStatsChartData()
const tokenFeesChartData = useMemo(() => {
if (!mangoStats.length) return []
if (!mangoStats?.length) return []
if (showCumulativeFees) {
return mangoStats
} else {
@ -115,7 +116,7 @@ const Fees = () => {
setDaysToShow={setFeesDaysToShow}
heightClass="h-64"
loaderHeightClass="h-[350px]"
loading={loadingStats}
loading={isLoading}
prefix="$"
tickFormat={(x) => `$${formatYAxis(x)}`}
title={t('token:token-fees-collected')}

View File

@ -1,13 +1,13 @@
import { Bank } from '@blockworks-foundation/mango-v4'
import TabButtons from '@components/shared/TabButtons'
import mangoStore from '@store/mangoStore'
import { useTranslation } from 'next-i18next'
import { useEffect, useMemo, useState } from 'react'
import { useMemo, useState } from 'react'
import { TokenStatsItem } from 'types'
import { formatYAxis } from 'utils/formatting'
import DetailedAreaOrBarChart from '@components/shared/DetailedAreaOrBarChart'
import TokenRatesChart from './TokenRatesChart'
import Switch from '@components/forms/Switch'
import { useTokenStats } from 'hooks/useTokenStats'
const SWITCH_WRAPPER_CLASSES =
'mt-4 flex justify-end space-x-4 border-t border-th-bkg-3 px-4 py-2 md:px-6'
@ -71,20 +71,11 @@ const ChartTabs = ({ bank }: { bank: Bank }) => {
const [borrowDaysToShow, setBorrowDaysToShow] = useState('30')
const [depositRateDaysToShow, setDepositRateDaysToShow] = useState('30')
const [borrowRateDaysToShow, setBorrowRateDaysToShow] = useState('30')
const tokenStats = mangoStore((s) => s.tokenStats.data)
const loadingTokenStats = mangoStore((s) => s.tokenStats.loading)
const tokenStatsInitialLoad = mangoStore((s) => s.tokenStats.initialLoad)
useEffect(() => {
if (!tokenStatsInitialLoad) {
const actions = mangoStore.getState().actions
actions.fetchTokenStats()
}
}, [tokenStatsInitialLoad])
const { data: tokenStats, isLoading } = useTokenStats(bank.mint)
console.log(tokenStats)
const formattedStats = useMemo(() => {
if (!tokenStats?.length) return []
return tokenStats
if (!tokenStats?.data?.length) return []
return tokenStats.data
.filter((c) => c.token_index === bank.tokenIndex)
.sort(
(a, b) =>
@ -192,7 +183,7 @@ const ChartTabs = ({ bank }: { bank: Bank }) => {
heightClass="h-64"
loaderHeightClass="h-[334px]"
domain={[0, 'dataMax']}
loading={loadingTokenStats}
loading={isLoading}
small
tickFormat={(x) => formatYAxis(x)}
title={`${t('token:deposits')}`}
@ -229,7 +220,7 @@ const ChartTabs = ({ bank }: { bank: Bank }) => {
data={formattedStats}
dataKey="deposit_apr"
daysToShow={depositRateDaysToShow}
loading={loadingTokenStats}
loading={isLoading}
setDaysToShow={setDepositRateDaysToShow}
title={`${t('token:average-deposit-rate')} (APR)`}
/>
@ -270,7 +261,7 @@ const ChartTabs = ({ bank }: { bank: Bank }) => {
heightClass="h-64"
loaderHeightClass="h-[334px]"
domain={[0, 'dataMax']}
loading={loadingTokenStats}
loading={isLoading}
small
tickFormat={(x) => formatYAxis(x)}
title={`${t('token:borrows')}`}
@ -307,7 +298,7 @@ const ChartTabs = ({ bank }: { bank: Bank }) => {
data={formattedStats}
dataKey="borrow_apr"
daysToShow={borrowRateDaysToShow}
loading={loadingTokenStats}
loading={isLoading}
setDaysToShow={setBorrowRateDaysToShow}
title={`${t('token:average-borrow-rate')} (APR)`}
/>

38
hooks/useTokenStats.ts Normal file
View File

@ -0,0 +1,38 @@
import { useQuery } from '@tanstack/react-query'
import { fetchTokenStatsData, processTokenStatsData } from 'apis/mngo'
import useMangoGroup from './useMangoGroup'
import { PublicKey } from '@solana/web3.js'
const refetchMs = 24 * 60 * 60 * 1000
export function useTokenStats(mint?: PublicKey) {
const { group } = useMangoGroup()
const criteria = mint
? [group?.publicKey.toBase58(), mint.toBase58()]
: [group?.publicKey.toBase58(), 'all']
return useQuery(
['tokenStats', criteria],
async () => {
try {
const rawData = await fetchTokenStatsData(group!, mint)
const [data, mangoStats] = processTokenStatsData(rawData, group!)
return {
data,
mangoStats,
}
} catch (error) {
return {
data: [],
mangoStats: [],
}
}
},
{
enabled: !!group && mint ? !!mint : !!'all',
staleTime: refetchMs,
retry: 1,
refetchInterval: refetchMs,
},
)
}

View File

@ -3,10 +3,9 @@
"version": "0.1.0",
"private": true,
"scripts": {
"setup": "yarn install --network-concurrency 1 && npx yarn-deduplicate && yarn allow-scripts && yarn bigint-fix",
"ci": "yarn install --frozen-lockfile --network-concurrency 1 --color=always && yarn allow-scripts && yarn bigint-fix",
"setup": "yarn install --network-concurrency 1 && npx yarn-deduplicate && yarn allow-scripts",
"ci": "yarn install --frozen-lockfile --network-concurrency 1 --color=always && yarn allow-scripts",
"ci-dupe-check": "npx yarn-deduplicate --list --fail",
"bigint-fix": "cd node_modules/bigint-buffer && yarn rebuild && cd ../../",
"dev": "rm -rf .next && next dev",
"test": "yarn jest",
"build": "next build",
@ -25,7 +24,7 @@
"@blockworks-foundation/mango-feeds": "0.1.7",
"@blockworks-foundation/mango-mints-redemption": "^0.0.10",
"@blockworks-foundation/mango-v4": "0.23.1",
"@blockworks-foundation/mango-v4-settings": "0.14.17",
"@blockworks-foundation/mango-v4-settings": "0.14.19",
"@blockworks-foundation/mangolana": "0.0.14",
"@headlessui/react": "1.6.6",
"@heroicons/react": "2.0.18",

View File

@ -59,10 +59,8 @@ import {
SpotTradeHistory,
SwapHistoryItem,
TradeForm,
TokenStatsItem,
NFT,
TourSettings,
MangoTokenStatsItem,
ThemeData,
PositionStat,
OrderbookTooltip,
@ -81,7 +79,6 @@ import {
IOrderLineAdapter,
} from '@public/charting_library/charting_library'
import { nftThemeMeta } from 'utils/theme'
import { fetchTokenStatsData, processTokenStatsData } from 'apis/mngo'
import { OrderTypes } from 'utils/tradeForm'
import { usePlausible } from 'next-plausible'
import { collectTxConfirmationData } from 'utils/transactionConfirmationData'
@ -276,12 +273,6 @@ export type MangoStore = {
}
set: (x: (x: MangoStore) => void) => void
themeData: ThemeData
tokenStats: {
initialLoad: boolean
loading: boolean
data: TokenStatsItem[] | null
mangoStats: MangoTokenStatsItem[]
}
tradeForm: TradeForm
tradingView: {
orderLines: Map<string | BN, IOrderLineAdapter>
@ -320,7 +311,6 @@ export type MangoStore = {
offset?: number,
limit?: number,
) => Promise<void>
fetchTokenStats: () => void
fetchTourSettings: (walletPk: string) => void
fetchWalletTokens: (walletPk: PublicKey) => Promise<void>
connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise<void>
@ -472,12 +462,6 @@ const mangoStore = create<MangoStore>()(
triggerPrice: '',
},
themeData: nftThemeMeta.default,
tokenStats: {
initialLoad: false,
loading: true,
data: [],
mangoStats: [],
},
tradeForm: DEFAULT_TRADE_FORM,
tradingView: {
orderLines: new Map(),
@ -956,36 +940,6 @@ const mangoStore = create<MangoStore>()(
}
}, timeout)
},
fetchTokenStats: async () => {
const set = get().set
const group = get().group
if (!group) return
set((state) => {
state.tokenStats.loading = true
})
try {
const rawData = await fetchTokenStatsData(group)
const [data, mangoStats] = processTokenStatsData(rawData, group)
set((state) => {
state.tokenStats.data = data
state.tokenStats.mangoStats = mangoStats
state.tokenStats.initialLoad = true
state.tokenStats.loading = false
})
} catch (error) {
set((state) => {
state.tokenStats.loading = false
})
console.log('Failed to fetch token stats data', error)
notify({
title: 'Failed to fetch token stats data',
type: 'error',
})
}
},
fetchWalletTokens: async (walletPk: PublicKey) => {
const set = get().set
const connection = get().connection

View File

@ -1,4 +1,4 @@
import { PublicKey } from '@metaplex-foundation/js'
import { PublicKey } from '@solana/web3.js'
export const LAST_ACCOUNT_KEY = 'mangoAccount-0.4'

View File

@ -106,6 +106,7 @@ function loadNft(
return Promise.race([
metaplex
.nfts()
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
.load({ metadata: nft })
.catch((e) => {

View File

@ -350,10 +350,10 @@
bn.js "^5.2.1"
eslint-config-prettier "^9.0.0"
"@blockworks-foundation/mango-v4-settings@0.14.17":
version "0.14.17"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.14.17.tgz#789d5c8b69f37881331acf30c855164b73892be5"
integrity sha512-Cu+85KSBm+G3ELNgnu8hd398swm4rinHrqMN4mSe9BHCwkMZBnxg8bynCYu2xpgbWTXEqdooyXQbBN0t3OZkHg==
"@blockworks-foundation/mango-v4-settings@0.14.19":
version "0.14.19"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.14.19.tgz#5f712a04cb34a7f12cbc742002cef1c5c3efb887"
integrity sha512-F01JfWnRHczrTidgHRyUwOacH1arC6pcLD9KGEvghdEE5YgetRBbrbAiFfrPQ4axym2ovX6HByVb1zAouDnoow==
dependencies:
bn.js "^5.2.1"
eslint-config-prettier "^9.0.0"