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): migrate markets #1483

Merged
merged 5 commits into from
Jan 30, 2025
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: 5 additions & 3 deletions src/hooks/Orderbook/useDrawOrderbook.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCallback, useEffect, useRef, useState } from 'react';

import { BonsaiHelpers } from '@/bonsai/ontology';
import { shallowEqual } from 'react-redux';

import type { PerpetualMarketOrderbookLevel } from '@/constants/abacus';
Expand All @@ -19,9 +20,10 @@ import { OutputType, formatNumberOutput } from '@/components/Output';

import { useAppSelector } from '@/state/appTypes';
import { getSelectedLocale } from '@/state/localizationSelectors';
import { getCurrentMarketConfig, getCurrentMarketOrderbookMap } from '@/state/perpetualsSelectors';
import { getCurrentMarketOrderbookMap } from '@/state/perpetualsSelectors';

import { getConsistentAssetSizeString } from '@/lib/consistentAssetSize';
import { MaybeBigNumber } from '@/lib/numbers';
import {
getHistogramXValues,
getRektFromIdx,
Expand Down Expand Up @@ -66,10 +68,10 @@ export const useDrawOrderbook = ({
const { decimal: decimalSeparator, group: groupSeparator } = useLocaleSeparators();
const selectedLocale = useAppSelector(getSelectedLocale);

const marketConfig = orEmptyObj(useAppSelector(getCurrentMarketConfig));
const marketConfig = orEmptyObj(useAppSelector(BonsaiHelpers.currentMarket.stableMarketInfo));
const stepSizeDecimals = marketConfig.stepSizeDecimals ?? TOKEN_DECIMALS;
const tickSizeDecimals = marketConfig.tickSizeDecimals ?? SMALL_USD_DECIMALS;
const stepSize = marketConfig.stepSize ?? 10 ** (-1 * TOKEN_DECIMALS);
const stepSize = MaybeBigNumber(marketConfig.stepSize)?.toNumber() ?? 10 ** (-1 * TOKEN_DECIMALS);
const prevData = useRef<typeof data>(data);
const theme = useAppThemeAndColorModeContext();

Expand Down
4 changes: 2 additions & 2 deletions src/hooks/tradingView/useTradingView.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react';

import { BonsaiHelpers } from '@/bonsai/ontology';
import BigNumber from 'bignumber.js';
import isEmpty from 'lodash/isEmpty';
import {
Expand All @@ -22,7 +23,6 @@ import { useAppDispatch, useAppSelector } from '@/state/appTypes';
import { getAppColorMode, getAppTheme } from '@/state/appUiConfigsSelectors';
import { getCurrentMarketId } from '@/state/currentMarketSelectors';
import { getSelectedLocale } from '@/state/localizationSelectors';
import { getCurrentMarketConfig } from '@/state/perpetualsSelectors';
import { updateChartConfig } from '@/state/tradingView';
import { getTvChartConfig } from '@/state/tradingViewSelectors';

Expand Down Expand Up @@ -88,7 +88,7 @@ export const useTradingView = ({
[marketId: string]: number | undefined;
}>({});
const { tickSizeDecimals: tickSizeDecimalsAbacus } = orEmptyObj(
useAppSelector(getCurrentMarketConfig)
useAppSelector(BonsaiHelpers.currentMarket.stableMarketInfo)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a weird hook. It is expecting indexer tickSizeDecimals as well as Abacus ones. I understand replacing the tickSizeDecimalsAbacus but maybe we can deprecate needing a fallback here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yeah what is happening here. Why would it load the tick size manually from the indexer instead of waiting for abacus to load it????? huuuh

);
const tickSizeDecimals =
(marketId
Expand Down
8 changes: 3 additions & 5 deletions src/hooks/useClosePositionFormInputs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCallback, useEffect } from 'react';

import { BonsaiHelpers } from '@/bonsai/ontology';
import { NumberFormatValues } from 'react-number-format';
import { shallowEqual, useDispatch } from 'react-redux';

Expand All @@ -9,10 +10,7 @@ import { TOKEN_DECIMALS, USD_DECIMALS } from '@/constants/numbers';
import { useAppSelector } from '@/state/appTypes';
import { setClosePositionFormInputs } from '@/state/inputs';
import { getClosePositionFormInputs, getInputClosePositionData } from '@/state/inputsSelectors';
import {
getCurrentMarketConfig,
getCurrentMarketMidMarketPrice,
} from '@/state/perpetualsSelectors';
import { getCurrentMarketMidMarketPrice } from '@/state/perpetualsSelectors';

import abacusStateManager from '@/lib/abacus';
import { MustBigNumber } from '@/lib/numbers';
Expand All @@ -34,7 +32,7 @@ export const useClosePositionFormInputs = () => {
const { limitPrice } = price ?? {};

const { stepSizeDecimals, tickSizeDecimals } = orEmptyObj(
useAppSelector(getCurrentMarketConfig, shallowEqual)
useAppSelector(BonsaiHelpers.currentMarket.stableMarketInfo)
);

const midMarketPrice = useAppSelector(getCurrentMarketMidMarketPrice, shallowEqual);
Expand Down
13 changes: 7 additions & 6 deletions src/hooks/useCurrentMarketId.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useMemo } from 'react';

import { BonsaiHelpers } from '@/bonsai/ontology';
import { shallowEqual } from 'react-redux';
import { useMatch, useNavigate } from 'react-router-dom';

Expand All @@ -19,15 +20,12 @@ import { closeDialogInTradeBox, openDialog } from '@/state/dialogs';
import { getActiveTradeBoxDialog } from '@/state/dialogsSelectors';
import { getHasSeenPredictionMarketIntroDialog } from '@/state/dismissableSelectors';
import { setCurrentMarketId, setCurrentMarketIdIfTradeable } from '@/state/perpetuals';
import {
getLaunchedMarketIds,
getMarketIds,
getMarketOraclePrice,
} from '@/state/perpetualsSelectors';
import { getLaunchedMarketIds, getMarketIds } from '@/state/perpetualsSelectors';

import abacusStateManager from '@/lib/abacus';

import { useMarketsData } from './useMarketsData';
import { useParameterizedSelector } from './useParameterizedSelector';

export const useCurrentMarketId = () => {
const navigate = useNavigate();
Expand All @@ -38,7 +36,10 @@ export const useCurrentMarketId = () => {
const openPositions = useAppSelector(getOpenPositions, shallowEqual);
const marketIds = useAppSelector(getMarketIds, shallowEqual);
const hasMarketIds = marketIds.length > 0;
const currentMarketOraclePrice = useAppSelector((s) => getMarketOraclePrice(s, marketId ?? ''));
const currentMarketOraclePrice = useParameterizedSelector(
BonsaiHelpers.markets.createSelectMarketSummaryById,
marketId
)?.oraclePrice;
const hasMarketOraclePrice = currentMarketOraclePrice != null;
const launchableMarkets = useLaunchableMarkets();
const activeTradeBoxDialog = useAppSelector(getActiveTradeBoxDialog);
Expand Down
13 changes: 7 additions & 6 deletions src/hooks/usePageTitlePriceUpdates.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect } from 'react';

import { shallowEqual } from 'react-redux';
import { BonsaiHelpers } from '@/bonsai/ontology';

import { SMALL_USD_DECIMALS } from '@/constants/numbers';
import { DEFAULT_DOCUMENT_TITLE } from '@/constants/routes';
Expand All @@ -10,10 +10,9 @@ import { OutputType, formatNumberOutput } from '@/components/Output';
import { useAppSelector } from '@/state/appTypes';
import { getCurrentMarketId } from '@/state/currentMarketSelectors';
import { getSelectedLocale } from '@/state/localizationSelectors';
import {
getCurrentMarketConfig,
getCurrentMarketMidMarketPriceWithOraclePriceFallback,
} from '@/state/perpetualsSelectors';
import { getCurrentMarketMidMarketPriceWithOraclePriceFallback } from '@/state/perpetualsSelectors';

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

import { useBreakpoints } from './useBreakpoints';
import { useLocaleSeparators } from './useLocaleSeparators';
Expand All @@ -22,7 +21,9 @@ export const usePageTitlePriceUpdates = () => {
const { isNotTablet } = useBreakpoints();
const id = useAppSelector(getCurrentMarketId);
const selectedLocale = useAppSelector(getSelectedLocale);
const { tickSizeDecimals } = useAppSelector(getCurrentMarketConfig, shallowEqual) ?? {};
const { tickSizeDecimals } = orEmptyObj(
useAppSelector(BonsaiHelpers.currentMarket.stableMarketInfo)
);
const { decimal: decimalSeparator, group: groupSeparator } = useLocaleSeparators();

const orderbookMidMarketPrice = useAppSelector(
Expand Down
25 changes: 13 additions & 12 deletions src/hooks/usePerpetualMarketsStats.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
import { useMemo } from 'react';

import { shallowEqual } from 'react-redux';
import { BonsaiCore } from '@/bonsai/ontology';

import { useAppSelector } from '@/state/appTypes';
import { getPerpetualMarkets } from '@/state/perpetualsSelectors';

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

const FEE_ESTIMATION_MULTIPLIER = 0.0002 * 0.4; // 40% of 2bps because of vault and affiliate revshare

export const usePerpetualMarketsStats = () => {
const perpetualMarkets = orEmptyRecord(useAppSelector(getPerpetualMarkets, shallowEqual));
const perpetualMarkets = orEmptyRecord(useAppSelector(BonsaiCore.markets.markets.data));

const markets = useMemo(
() => Object.values(perpetualMarkets).filter(isPresent),
[perpetualMarkets]
);

const stats = useMemo(() => {
let volume24HUSDC = 0;
let openInterestUSDC = 0;
let volume24HUSDC = BIG_NUMBERS.ZERO;
let openInterestUSDC = BIG_NUMBERS.ZERO;

// eslint-disable-next-line no-restricted-syntax
for (const { oraclePrice, perpetual } of markets) {
const { volume24H, openInterest = 0 } = perpetual ?? {};
volume24HUSDC += volume24H ?? 0;
if (oraclePrice) openInterestUSDC += openInterest * oraclePrice;
for (const { oraclePrice, volume24H, openInterest } of markets) {
volume24HUSDC = volume24HUSDC.plus(volume24H);
if (oraclePrice) {
openInterestUSDC = openInterestUSDC.plus(MustBigNumber(openInterest).times(oraclePrice));
}
}

return {
volume24HUSDC,
openInterestUSDC,
feesEarned: volume24HUSDC * FEE_ESTIMATION_MULTIPLIER,
volume24HUSDC: volume24HUSDC.toNumber(),
openInterestUSDC: openInterestUSDC.toNumber(),
feesEarned: volume24HUSDC.times(FEE_ESTIMATION_MULTIPLIER).toNumber(),
};
}, [markets]);

Expand Down
12 changes: 9 additions & 3 deletions src/lib/tradingView/dydxfeed/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BonsaiHelpers } from '@/bonsai/ontology';
// eslint-disable-next-line no-restricted-imports
import { subscribeOnStream, unsubscribeFromStream } from '@/bonsai/websocket/candlesForTradingView';
import { groupBy } from 'lodash';
Expand Down Expand Up @@ -29,9 +30,9 @@ import { Themes } from '@/styles/themes';
import { type RootStore } from '@/state/_store';
import { getMarketFills } from '@/state/accountSelectors';
import { getAppColorMode, getAppTheme } from '@/state/appUiConfigsSelectors';
import { getMarketConfig, getMarketData } from '@/state/perpetualsSelectors';

import { objectKeys } from '@/lib/objectHelpers';
import { orEmptyObj } from '@/lib/typeUtils';

import { log } from '../../telemetry';
import { getSymbol, mapCandle } from '../utils';
Expand Down Expand Up @@ -84,7 +85,9 @@ export const getDydxDatafeed = (

resolveSymbol: async (symbolName: string, onSymbolResolvedCallback: ResolveCallback) => {
const symbolItem = getSymbol(symbolName || DEFAULT_MARKETID);
const { tickSizeDecimals } = getMarketConfig(store.getState(), symbolItem.symbol) ?? {};
const { tickSizeDecimals } = orEmptyObj(
BonsaiHelpers.markets.createSelectMarketSummaryById()(store.getState(), symbolItem.symbol)
);

const pricescale = tickSizeDecimals ? 10 ** tickSizeDecimals : initialPriceScale ?? 100;

Expand Down Expand Up @@ -123,7 +126,10 @@ export const getDydxDatafeed = (
const colorMode = getAppColorMode(store.getState());

const [fromMs, toMs] = [fromSeconds * 1000, toSeconds * 1000];
const market = getMarketData(store.getState(), symbolInfo.ticker!);
const market = BonsaiHelpers.markets.createSelectMarketSummaryById()(
store.getState(),
symbolInfo.ticker!
);
if (!market) return;

const fills = getMarketFills(store.getState())[symbolInfo.ticker!] ?? [];
Expand Down
12 changes: 6 additions & 6 deletions src/pages/trade/TradeHeaderMobile.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { BonsaiHelpers } from '@/bonsai/ontology';
import { shallowEqual } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';

Expand All @@ -15,10 +14,10 @@ import { Output, OutputType } from '@/components/Output';
import { MidMarketPrice } from '@/views/MidMarketPrice';

import { useAppSelector } from '@/state/appTypes';
import { getCurrentMarketData } from '@/state/perpetualsSelectors';

import { getDisplayableAssetFromBaseAsset } from '@/lib/assetUtils';
import { MustBigNumber } from '@/lib/numbers';
import { orEmptyObj } from '@/lib/typeUtils';

export const TradeHeaderMobile = ({ launchableMarketId }: { launchableMarketId?: string }) => {
const id = useAppSelector(BonsaiHelpers.currentMarket.assetId);
Expand All @@ -27,8 +26,9 @@ export const TradeHeaderMobile = ({ launchableMarketId }: { launchableMarketId?:

const navigate = useNavigate();

const { displayId, priceChange24H, priceChange24HPercent } =
useAppSelector(getCurrentMarketData, shallowEqual) ?? {};
const { displayableTicker, priceChange24H, percentChange24h } = orEmptyObj(
useAppSelector(BonsaiHelpers.currentMarket.marketInfo)
);

const launchableAsset = useMetadataServiceAssetFromId(launchableMarketId);

Expand All @@ -49,7 +49,7 @@ export const TradeHeaderMobile = ({ launchableMarketId }: { launchableMarketId?:
<AssetIcon logoUrl={imageUrl} symbol={id} tw="text-[2.5rem]" />
<$Name>
<h3>{name}</h3>
<span>{displayId}</span>
<span>{displayableTicker}</span>
</$Name>
</div>
);
Expand All @@ -64,7 +64,7 @@ export const TradeHeaderMobile = ({ launchableMarketId }: { launchableMarketId?:
<MidMarketPrice />
<$PriceChange
type={OutputType.Percent}
value={MustBigNumber(priceChange24HPercent).abs()}
value={MustBigNumber(percentChange24h).abs()}
isNegative={MustBigNumber(priceChange24H).isNegative()}
/>
</$Right>
Expand Down
4 changes: 2 additions & 2 deletions src/state/accountSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { ALL_MARKETS_STRING } from './accountUiMemory';
import { getSelectedNetwork } from './appSelectors';
import { createAppSelector } from './appTypes';
import { getCurrentMarketId } from './currentMarketSelectors';
import { getCurrentMarketOrderbook, getPerpetualMarkets } from './perpetualsSelectors';
import { getCurrentMarketOrderbook } from './perpetualsSelectors';

/**
* @param state
Expand Down Expand Up @@ -191,7 +191,7 @@ export const getSubaccountOpenOrders = createAppSelector([getSubaccountOrders],
);

export const getOpenIsolatedOrders = createAppSelector(
[getSubaccountOrders, getPerpetualMarkets],
[getSubaccountOrders, BonsaiCore.markets.markets.data],
(allOrders, allMarkets) =>
(allOrders ?? [])
.filter((o) => isOrderStatusOpen(o.status) && o.marginMode === AbacusMarginMode.Isolated)
Expand Down
Loading
Loading