From 7629e2442fde903c05641c52e637b1243a3d3792 Mon Sep 17 00:00:00 2001 From: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com> Date: Fri, 12 Jan 2024 12:10:26 +0100 Subject: [PATCH] add functional funding rate + selector (#729) * add functional funding rate + selector * Edit perps position (#728) --- .../Perps/PerpsInfo/FundingRate.tsx | 77 +++++++++++++++++++ .../Perps/PerpsInfo/InterestItem.tsx | 27 +++++++ .../{PerpsInfo.tsx => PerpsInfo/index.tsx} | 43 ++--------- src/hooks/perps/usePerpsMarket.ts | 11 ++- 4 files changed, 117 insertions(+), 41 deletions(-) create mode 100644 src/components/Perps/PerpsInfo/FundingRate.tsx create mode 100644 src/components/Perps/PerpsInfo/InterestItem.tsx rename src/components/Perps/{PerpsInfo.tsx => PerpsInfo/index.tsx} (60%) diff --git a/src/components/Perps/PerpsInfo/FundingRate.tsx b/src/components/Perps/PerpsInfo/FundingRate.tsx new file mode 100644 index 00000000..353e4ac9 --- /dev/null +++ b/src/components/Perps/PerpsInfo/FundingRate.tsx @@ -0,0 +1,77 @@ +import { useMemo, useState } from 'react' + +import { FormattedNumber } from 'components/FormattedNumber' +import { ChevronDown } from 'components/Icons' +import Loading from 'components/Loading' +import { Tooltip } from 'components/Tooltip' +import { BN_ZERO } from 'constants/math' +import usePerpsMarket from 'hooks/perps/usePerpsMarket' +import useToggle from 'hooks/useToggle' + +type Interval = '1H' | '1D' | '1W' | '1M' | '1Y' + +enum Intervals { + '1H' = 365 * 24, + '1D' = 365, + '1W' = 52, + '1M' = 12, + '1Y' = 1, +} + +export default function FundingRate() { + const { data: market, isLoading } = usePerpsMarket() + const [interval, setInterval] = useState('1H') + const [show, toggleShow] = useToggle(false) + + const fundingRate = useMemo(() => { + return market?.fundingRate.div(Intervals[interval]) ?? BN_ZERO + }, [interval, market?.fundingRate]) + + if (isLoading) return + if (!market) return '-' + + return ( +
+ + + {Object.keys(Intervals) + .filter((key) => isNaN(Number(key))) + .map((key) => ( + + ))} +
+ } + type='info' + placement='bottom' + contentClassName='!bg-white/10 border border-white/20 backdrop-blur-xl !p-0' + interactive + hideArrow + visible={show} + onClickOutside={() => toggleShow(false)} + > + + + + ) +} diff --git a/src/components/Perps/PerpsInfo/InterestItem.tsx b/src/components/Perps/PerpsInfo/InterestItem.tsx new file mode 100644 index 00000000..85af00da --- /dev/null +++ b/src/components/Perps/PerpsInfo/InterestItem.tsx @@ -0,0 +1,27 @@ +import React from 'react' + +import AssetSymbol from 'components/Asset/AssetSymbol' +import { FormattedNumber } from 'components/FormattedNumber' +import Loading from 'components/Loading' +import usePerpsMarket from 'hooks/perps/usePerpsMarket' + +interface InterestItemProps { + type: 'long' | 'short' +} +export default function InterestItem(props: InterestItemProps) { + const { data: market, isLoading } = usePerpsMarket() + + if (isLoading) return + if (!market) return null + + return ( +
+ + +
+ ) +} diff --git a/src/components/Perps/PerpsInfo.tsx b/src/components/Perps/PerpsInfo/index.tsx similarity index 60% rename from src/components/Perps/PerpsInfo.tsx rename to src/components/Perps/PerpsInfo/index.tsx index 05cb6e5b..41aefa83 100644 --- a/src/components/Perps/PerpsInfo.tsx +++ b/src/components/Perps/PerpsInfo/index.tsx @@ -1,11 +1,11 @@ import React, { useMemo } from 'react' -import AssetSymbol from 'components/Asset/AssetSymbol' import Card from 'components/Card' import DisplayCurrency from 'components/DisplayCurrency' import Divider from 'components/Divider' -import { FormattedNumber } from 'components/FormattedNumber' import Loading from 'components/Loading' +import FundingRate from 'components/Perps/PerpsInfo/FundingRate' +import InterestItem from 'components/Perps/PerpsInfo/InterestItem' import Text from 'components/Text' import usePerpsMarket from 'hooks/perps/usePerpsMarket' import usePrice from 'hooks/usePrice' @@ -25,28 +25,14 @@ export function PerpsInfo() { } + item={} />, } - />, - - ) : ( - - ) - } + item={} />, + } />, ] }, [assetPrice, market]) @@ -81,22 +67,3 @@ function InfoItem(props: InfoItemProps) { ) } - -interface InterestItemProps { - market: PerpsMarket | null - type: 'long' | 'short' -} -function InterestItem(props: InterestItemProps) { - if (!props.market) return - - return ( -
- - -
- ) -} diff --git a/src/hooks/perps/usePerpsMarket.ts b/src/hooks/perps/usePerpsMarket.ts index e0e98395..87f3cbf9 100644 --- a/src/hooks/perps/usePerpsMarket.ts +++ b/src/hooks/perps/usePerpsMarket.ts @@ -11,15 +11,20 @@ export default function usePerpsMarket() { const { perpsAsset } = usePerpsAsset() const clients = useClients() - return useSWR(clients && perpsAsset && `chains/${chainConfig.id}/perps/${perpsAsset.denom}`, () => - getPerpsMarket(clients!, perpsAsset!), + return useSWR( + clients && perpsAsset && `chains/${chainConfig.id}/perps/${perpsAsset.denom}`, + () => getPerpsMarket(clients!, perpsAsset!), + { + refreshInterval: 1000, + dedupingInterval: 1000, + }, ) } async function getPerpsMarket(clients: ContractClients, asset: Asset) { const denomState = await clients.perps.perpDenomState({ denom: asset.denom }) return { - fundingRate: BN(denomState.rate.abs), + fundingRate: BN(denomState.rate as any), asset: asset, openInterest: { long: BN_ZERO,