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:
parent
74c3ebc00c
commit
dc10d611d0
|
@ -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,
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -208,7 +208,9 @@ const DashboardSuggestedValues = ({
|
|||
: null,
|
||||
getNullOrVal(fieldsToChange.zeroUtilRate),
|
||||
getNullOrVal(fieldsToChange.platformLiquidationFee),
|
||||
null,
|
||||
fieldsToChange.disableAssetLiquidation === undefined
|
||||
? null
|
||||
: fieldsToChange.disableAssetLiquidation,
|
||||
getNullOrVal(fieldsToChange.collateralFeePerDay),
|
||||
null,
|
||||
)
|
||||
|
|
|
@ -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')}
|
||||
|
|
|
@ -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')}
|
||||
|
|
|
@ -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)`}
|
||||
/>
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
)
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PublicKey } from '@metaplex-foundation/js'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
|
||||
export const LAST_ACCOUNT_KEY = 'mangoAccount-0.4'
|
||||
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue