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

feat(bonsai-ui): market header and launchable market details #1400

Merged
merged 15 commits into from
Jan 22, 2025
4 changes: 4 additions & 0 deletions src/abacus-ts/ontology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
selectParentSubaccountSummaryLoading,
} from './selectors/account';
import {
createSelectAssetInfo,
selectAllAssetsInfo,
selectAllAssetsInfoLoading,
selectCurrentMarketAssetInfo,
Expand Down Expand Up @@ -95,4 +96,7 @@ export const BonsaiHelpers = {
fills: getCurrentMarketAccountFills,
},
},
assets: {
paramaterizedAssetInfo: createSelectAssetInfo,
},
} as const satisfies NestedSelectors;
10 changes: 8 additions & 2 deletions src/views/LaunchableMarketStatsDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReactNode } from 'react';

import { BonsaiHelpers } from '@/abacus-ts/ontology';
import styled, { css } from 'styled-components';

import { Nullable } from '@/constants/abacus';
Expand All @@ -8,7 +9,7 @@ import { USD_DECIMALS } from '@/constants/numbers';
import { TooltipStringKeys } from '@/constants/tooltips';

import { useBreakpoints } from '@/hooks/useBreakpoints';
import { useMetadataServiceAssetFromId } from '@/hooks/useMetadataService';
import { useParameterizedSelector } from '@/hooks/useParameterizedSelector';
import { useStringGetter } from '@/hooks/useStringGetter';

import breakpoints from '@/styles/breakpoints';
Expand All @@ -19,6 +20,7 @@ import { Icon, IconName } from '@/components/Icon';
import { Output, OutputType } from '@/components/Output';
import { VerticalSeparator } from '@/components/Separator';

import { getAssetFromMarketId } from '@/lib/assetUtils';
import { orEmptyObj } from '@/lib/typeUtils';

type ElementProps = {
Expand Down Expand Up @@ -53,7 +55,11 @@ export const LaunchableMarketStatsDetails = ({
}: ElementProps) => {
const stringGetter = useStringGetter();
const { isTablet } = useBreakpoints();
const launchableAsset = useMetadataServiceAssetFromId(launchableMarketId);
const assetId = getAssetFromMarketId(launchableMarketId);
const launchableAsset = useParameterizedSelector(
BonsaiHelpers.assets.paramaterizedAssetInfo,
assetId
);

const {
marketCap,
Expand Down
16 changes: 11 additions & 5 deletions src/views/MarketDetails/LaunchableMarketDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { BonsaiHelpers } from '@/abacus-ts/ontology';

import { STRING_KEYS } from '@/constants/localization';
import { ISOLATED_LIQUIDITY_TIER_INFO } from '@/constants/markets';
import { TooltipStringKeys } from '@/constants/tooltips';

import { useMetadataServiceAssetFromId } from '@/hooks/useMetadataService';
import { useParameterizedSelector } from '@/hooks/useParameterizedSelector';
import { useStringGetter } from '@/hooks/useStringGetter';

import { DetailsItem } from '@/components/Details';
import { Icon, IconName } from '@/components/Icon';
import { Output, OutputType } from '@/components/Output';

import { getDisplayableTickerFromMarket } from '@/lib/assetUtils';
import { getAssetFromMarketId, getDisplayableTickerFromMarket } from '@/lib/assetUtils';
import { BIG_NUMBERS } from '@/lib/numbers';

import { MarketDetails } from './MarketDetails';

export const LaunchableMarketDetails = ({ launchableMarketId }: { launchableMarketId: string }) => {
const stringGetter = useStringGetter();
const launchableAsset = useMetadataServiceAssetFromId(launchableMarketId);
const assetId = getAssetFromMarketId(launchableMarketId);
const launchableAsset = useParameterizedSelector(
BonsaiHelpers.assets.paramaterizedAssetInfo,
assetId
);

if (!launchableAsset) return null;

const { name, id, logo, urls, marketCap, reportedMarketCap, volume24h } = launchableAsset;
const { name, logo, urls, marketCap, reportedMarketCap, volume24h } = launchableAsset;
const { website, technicalDoc, cmc } = urls;
const showSelfReportedMarketCap = marketCap ? false : !!reportedMarketCap;

Expand Down Expand Up @@ -54,7 +60,7 @@ export const LaunchableMarketDetails = ({ launchableMarketId }: { launchableMark
{
key: 'ticker',
label: stringGetter({ key: STRING_KEYS.TICKER }),
value: getDisplayableTickerFromMarket(`${id}-USD`),
value: getDisplayableTickerFromMarket(`${assetId}-USD`),
},
{
key: 'market-type',
Expand Down
49 changes: 28 additions & 21 deletions src/views/MarketStatsDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useRef } from 'react';

import { shallowEqual } from 'react-redux';
import { BonsaiCore, BonsaiHelpers } from '@/abacus-ts/ontology';
import BigNumber from 'bignumber.js';
import styled, { css } from 'styled-components';

import { STRING_KEYS } from '@/constants/localization';
Expand All @@ -25,13 +26,10 @@ import { NextFundingTimer } from '@/views/NextFundingTimer';

import { useAppSelector } from '@/state/appTypes';
import { getSelectedDisplayUnit } from '@/state/appUiConfigsSelectors';
import {
getCurrentMarketConfig,
getCurrentMarketData,
getCurrentMarketMidMarketPrice,
} from '@/state/perpetualsSelectors';
import { getCurrentMarketMidMarketPrice } from '@/state/perpetualsSelectors';

import { BIG_NUMBERS, MustBigNumber } from '@/lib/numbers';
import { orEmptyObj } from '@/lib/typeUtils';

import { MidMarketPrice } from './MidMarketPrice';

Expand All @@ -54,24 +52,33 @@ export const MarketStatsDetails = ({ showMidMarketPrice = true }: ElementProps)
const stringGetter = useStringGetter();
const { isTablet } = useBreakpoints();

const { tickSizeDecimals, initialMarginFraction, effectiveInitialMarginFraction } =
useAppSelector(getCurrentMarketConfig, shallowEqual) ?? {};
const marketData = useAppSelector(BonsaiHelpers.currentMarket.marketInfo);
const isLoading = useAppSelector(BonsaiCore.markets.markets.loading) === 'pending';

const {
displayableAsset,
effectiveInitialMarginFraction,
initialMarginFraction,
nextFundingRate,
openInterest,
openInterestUSDC,
oraclePrice,
percentChange24h,
priceChange24H,
tickSizeDecimals,
trades24H,
volume24H,
} = orEmptyObj(marketData);

const midMarketPrice = useAppSelector(getCurrentMarketMidMarketPrice);
const lastMidMarketPrice = useRef(midMarketPrice);
const currentMarketData = useAppSelector(getCurrentMarketData, shallowEqual);
const isLoading = currentMarketData === undefined;

const { oraclePrice, perpetual, priceChange24H, priceChange24HPercent, assetId } =
currentMarketData ?? {};

useEffect(() => {
lastMidMarketPrice.current = midMarketPrice;
}, [midMarketPrice]);

const displayUnit = useAppSelector(getSelectedDisplayUnit);

const { nextFundingRate, openInterest, openInterestUSDC, trades24H, volume24H } = perpetual ?? {};

const valueMap = {
[MarketStats.OraclePrice]: oraclePrice,
[MarketStats.NextFunding]: undefined, // hardcoded
Expand Down Expand Up @@ -117,9 +124,9 @@ export const MarketStatsDetails = ({ showMidMarketPrice = true }: ElementProps)
value={valueMap[stat]}
stat={stat}
tickSizeDecimals={tickSizeDecimals}
assetId={assetId ?? ''}
assetId={displayableAsset ?? ''}
isLoading={isLoading}
priceChange24HPercent={priceChange24HPercent}
priceChange24HPercent={percentChange24h}
initialMarginFraction={initialMarginFraction}
effectiveInitialMarginFraction={effectiveInitialMarginFraction}
useFiatDisplayUnit={displayUnit === DisplayUnit.Fiat}
Expand Down Expand Up @@ -210,14 +217,14 @@ const DetailsItem = ({
effectiveInitialMarginFraction,
useFiatDisplayUnit,
}: {
value: number | null | undefined;
value: string | number | null | undefined;
stat: MarketStats;
tickSizeDecimals: number | null | undefined;
assetId: string;
isLoading: boolean;
priceChange24HPercent: number | null | undefined;
initialMarginFraction: number | null | undefined;
effectiveInitialMarginFraction: number | null | undefined;
initialMarginFraction: string | null | undefined;
effectiveInitialMarginFraction: BigNumber | null | undefined;
jaredvu marked this conversation as resolved.
Show resolved Hide resolved
useFiatDisplayUnit: boolean;
}) => {
const valueBN = MustBigNumber(value);
Expand Down Expand Up @@ -313,7 +320,7 @@ const DetailsItem = ({
? BIG_NUMBERS.ONE.div(effectiveInitialMarginFraction)
: null
}
withDiff={initialMarginFraction !== effectiveInitialMarginFraction}
withDiff={initialMarginFraction !== effectiveInitialMarginFraction?.toString()}
jaredvu marked this conversation as resolved.
Show resolved Hide resolved
type={OutputType.Multiple}
/>
);
Expand Down
Loading