* feat(#2367): market liquidity supplied in trade market header * feat(#2467): calculate LP status * fix: add LP view link * fix: add LP view link * feat(#2367): show liquidity supplied percentage * feat(#2367): show liquidity supplied percentage * fix: liquidity-utils test needs big number * feat(#2456): liquidity status marker * feat(#2456): liquidity indicator * feat(#2367): update props lp * fix: use market data directly * feat(#2367): move data grid in react-helpers * feat(#2367): move data grid in react-helpers * fix: indicator commented * chore: remove unnecessary styles * test: update test name Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
a9c7c2bb46
commit
1e98ecbd21
@ -1,13 +1,12 @@
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type { FieldErrors } from 'react-hook-form';
|
import type { FieldErrors } from 'react-hook-form';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { t, toDecimal } from '@vegaprotocol/react-helpers';
|
import { DataGrid, t, toDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||||
import {
|
import {
|
||||||
MarketDataGrid,
|
|
||||||
compileGridData,
|
compileGridData,
|
||||||
MarginWarning,
|
MarginWarning,
|
||||||
isMarketInAuction,
|
isMarketInAuction,
|
||||||
@ -216,9 +215,7 @@ export const useOrderValidation = ({
|
|||||||
<span>
|
<span>
|
||||||
{t('This market is in auction until it reaches')}{' '}
|
{t('This market is in auction until it reaches')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={<DataGrid grid={compileGridData(market)} />}
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span>{t('sufficient liquidity')}</span>
|
<span>{t('sufficient liquidity')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -240,9 +237,7 @@ export const useOrderValidation = ({
|
|||||||
<span>
|
<span>
|
||||||
{t('This market is in auction due to')}{' '}
|
{t('This market is in auction due to')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={<DataGrid grid={compileGridData(market)} />}
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span>{t('high price volatility')}</span>
|
<span>{t('high price volatility')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -281,9 +276,7 @@ export const useOrderValidation = ({
|
|||||||
<span>
|
<span>
|
||||||
{t('This market is in auction until it reaches')}{' '}
|
{t('This market is in auction until it reaches')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={<DataGrid grid={compileGridData(market)} />}
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span>{t('sufficient liquidity')}</span>
|
<span>{t('sufficient liquidity')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -307,9 +300,7 @@ export const useOrderValidation = ({
|
|||||||
<span>
|
<span>
|
||||||
{t('This market is in auction due to')}{' '}
|
{t('This market is in auction due to')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={<DataGrid grid={compileGridData(market)} />}
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span>{t('high price volatility')}</span>
|
<span>{t('high price volatility')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -17,6 +17,7 @@ import { Last24hPriceChange } from '../../components/last-24h-price-change';
|
|||||||
import { Last24hVolume } from '../../components/last-24h-volume';
|
import { Last24hVolume } from '../../components/last-24h-volume';
|
||||||
import { MarketState } from '../../components/market-state';
|
import { MarketState } from '../../components/market-state';
|
||||||
import { MarketTradingMode } from '../../components/market-trading-mode';
|
import { MarketTradingMode } from '../../components/market-trading-mode';
|
||||||
|
import { MarketLiquiditySupplied } from '../../components/liquidity-supplied';
|
||||||
|
|
||||||
interface TradeMarketHeaderProps {
|
interface TradeMarketHeaderProps {
|
||||||
market: SingleMarketFieldsFragment | null;
|
market: SingleMarketFieldsFragment | null;
|
||||||
@ -96,6 +97,10 @@ export const TradeMarketHeader = ({
|
|||||||
</HeaderStat>
|
</HeaderStat>
|
||||||
) : null}
|
) : null}
|
||||||
<MarketProposalNotification marketId={market?.id} />
|
<MarketProposalNotification marketId={market?.id} />
|
||||||
|
<MarketLiquiditySupplied
|
||||||
|
marketId={market?.id}
|
||||||
|
assetDecimals={asset?.decimals || 0}
|
||||||
|
/>
|
||||||
</Header>
|
</Header>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
1
apps/trading/components/liquidity-supplied/index.ts
Normal file
1
apps/trading/components/liquidity-supplied/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './liquidity-supplied';
|
@ -0,0 +1,130 @@
|
|||||||
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
|
import {
|
||||||
|
addDecimalsFormatNumber,
|
||||||
|
formatNumberPercentage,
|
||||||
|
NetworkParams,
|
||||||
|
t,
|
||||||
|
useDataProvider,
|
||||||
|
useNetworkParams,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
|
import type {
|
||||||
|
MarketData,
|
||||||
|
MarketDataUpdateFieldsFragment,
|
||||||
|
SingleMarketFieldsFragment,
|
||||||
|
} from '@vegaprotocol/market-list';
|
||||||
|
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||||
|
import { HeaderStat } from '../header';
|
||||||
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
import { useCheckLiquidityStatus } from '@vegaprotocol/liquidity';
|
||||||
|
import { DataGrid } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
marketId?: string;
|
||||||
|
noUpdate?: boolean;
|
||||||
|
assetDecimals: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MarketLiquiditySupplied = ({
|
||||||
|
marketId,
|
||||||
|
assetDecimals,
|
||||||
|
noUpdate = false,
|
||||||
|
}: Props) => {
|
||||||
|
const [market, setMarket] = useState<MarketData>();
|
||||||
|
const { params } = useNetworkParams([
|
||||||
|
NetworkParams.market_liquidity_stakeToCcySiskas,
|
||||||
|
NetworkParams.market_liquidity_targetstake_triggering_ratio,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const stakeToCcyVolume = Number(params.market_liquidity_stakeToCcySiskas);
|
||||||
|
const triggeringRatio = Number(
|
||||||
|
params.market_liquidity_targetstake_triggering_ratio
|
||||||
|
);
|
||||||
|
|
||||||
|
const variables = useMemo(
|
||||||
|
() => ({
|
||||||
|
marketId: marketId,
|
||||||
|
}),
|
||||||
|
[marketId]
|
||||||
|
);
|
||||||
|
|
||||||
|
const { data } = useDataProvider<SingleMarketFieldsFragment, never>({
|
||||||
|
dataProvider: marketProvider,
|
||||||
|
variables,
|
||||||
|
skip: !marketId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const update = useCallback(
|
||||||
|
({ data: marketData }: { data: MarketData | null }) => {
|
||||||
|
if (!noUpdate && marketData) {
|
||||||
|
setMarket(marketData);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
[noUpdate]
|
||||||
|
);
|
||||||
|
|
||||||
|
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
||||||
|
dataProvider: marketDataProvider,
|
||||||
|
update,
|
||||||
|
variables,
|
||||||
|
skip: noUpdate || !marketId || !data,
|
||||||
|
});
|
||||||
|
|
||||||
|
const supplied = market?.suppliedStake
|
||||||
|
? addDecimalsFormatNumber(
|
||||||
|
new BigNumber(market?.suppliedStake)
|
||||||
|
.multipliedBy(stakeToCcyVolume || 1)
|
||||||
|
.toString(),
|
||||||
|
assetDecimals
|
||||||
|
)
|
||||||
|
: '-';
|
||||||
|
|
||||||
|
const { percentage } = useCheckLiquidityStatus({
|
||||||
|
suppliedStake: market?.suppliedStake || 0,
|
||||||
|
targetStake: market?.targetStake || 0,
|
||||||
|
triggeringRatio,
|
||||||
|
});
|
||||||
|
|
||||||
|
const compiledGrid = [
|
||||||
|
{
|
||||||
|
label: t('Supplied stake'),
|
||||||
|
value: market?.suppliedStake
|
||||||
|
? addDecimalsFormatNumber(
|
||||||
|
new BigNumber(market?.suppliedStake).toString(),
|
||||||
|
assetDecimals
|
||||||
|
)
|
||||||
|
: '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Target stake'),
|
||||||
|
value: market?.targetStake
|
||||||
|
? addDecimalsFormatNumber(
|
||||||
|
new BigNumber(market?.targetStake).toString(),
|
||||||
|
assetDecimals
|
||||||
|
)
|
||||||
|
: '-',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const description = (
|
||||||
|
<section>
|
||||||
|
{compiledGrid && <DataGrid grid={compiledGrid} />}
|
||||||
|
<br />
|
||||||
|
<Link href={`/#/liquidity/${marketId}`} data-testid="view-liquidity-link">
|
||||||
|
{t('View liquidity provision table')}
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HeaderStat
|
||||||
|
heading={t('Liquidity supplied')}
|
||||||
|
description={description}
|
||||||
|
testId="liquidity-supplied"
|
||||||
|
>
|
||||||
|
{/* <Indicator variant={status} /> */}
|
||||||
|
{supplied} ({formatNumberPercentage(percentage, 2)})
|
||||||
|
</HeaderStat>
|
||||||
|
);
|
||||||
|
};
|
@ -6,10 +6,10 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
||||||
import { timeInForceLabel } from '@vegaprotocol/orders';
|
import { timeInForceLabel } from '@vegaprotocol/orders';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||||
import { compileGridData, MarketDataGrid } from '../trading-mode-tooltip';
|
import { compileGridData } from '../trading-mode-tooltip';
|
||||||
import { MarketModeValidationType } from '../../constants';
|
import { MarketModeValidationType } from '../../constants';
|
||||||
|
|
||||||
interface TimeInForceSelectorProps {
|
interface TimeInForceSelectorProps {
|
||||||
@ -78,9 +78,7 @@ export const TimeInForceSelector = ({
|
|||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{t('This market is in auction until it reaches')}{' '}
|
{t('This market is in auction until it reaches')}{' '}
|
||||||
<Tooltip
|
<Tooltip description={<DataGrid grid={compileGridData(market)} />}>
|
||||||
description={<MarketDataGrid grid={compileGridData(market)} />}
|
|
||||||
>
|
|
||||||
<span>{t('sufficient liquidity')}</span>
|
<span>{t('sufficient liquidity')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{'. '}
|
{'. '}
|
||||||
@ -95,9 +93,7 @@ export const TimeInForceSelector = ({
|
|||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{t('This market is in auction due to')}{' '}
|
{t('This market is in auction due to')}{' '}
|
||||||
<Tooltip
|
<Tooltip description={<DataGrid grid={compileGridData(market)} />}>
|
||||||
description={<MarketDataGrid grid={compileGridData(market)} />}
|
|
||||||
>
|
|
||||||
<span>{t('high price volatility')}</span>
|
<span>{t('high price volatility')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{'. '}
|
{'. '}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { FormGroup, InputError, Tooltip } from '@vegaprotocol/ui-toolkit';
|
import { FormGroup, InputError, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||||
import { compileGridData, MarketDataGrid } from '../trading-mode-tooltip';
|
import { compileGridData } from '../trading-mode-tooltip';
|
||||||
import { MarketModeValidationType } from '../../constants';
|
import { MarketModeValidationType } from '../../constants';
|
||||||
|
|
||||||
interface TypeSelectorProps {
|
interface TypeSelectorProps {
|
||||||
@ -33,9 +33,7 @@ export const TypeSelector = ({
|
|||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{t('This market is in auction until it reaches')}{' '}
|
{t('This market is in auction until it reaches')}{' '}
|
||||||
<Tooltip
|
<Tooltip description={<DataGrid grid={compileGridData(market)} />}>
|
||||||
description={<MarketDataGrid grid={compileGridData(market)} />}
|
|
||||||
>
|
|
||||||
<span>{t('sufficient liquidity')}</span>
|
<span>{t('sufficient liquidity')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{'. '}
|
{'. '}
|
||||||
@ -48,9 +46,7 @@ export const TypeSelector = ({
|
|||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{t('This market is in auction due to')}{' '}
|
{t('This market is in auction due to')}{' '}
|
||||||
<Tooltip
|
<Tooltip description={<DataGrid grid={compileGridData(market)} />}>
|
||||||
description={<MarketDataGrid grid={compileGridData(market)} />}
|
|
||||||
>
|
|
||||||
<span>{t('high price volatility')}</span>
|
<span>{t('high price volatility')}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{'. '}
|
{'. '}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { DataGridProps } from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
t,
|
t,
|
||||||
getDateTimeFormat,
|
getDateTimeFormat,
|
||||||
@ -6,7 +7,6 @@ import {
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { Link as UILink } from '@vegaprotocol/ui-toolkit';
|
import { Link as UILink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type { MarketDataGridProps } from './market-data-grid';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ export const compileGridData = (
|
|||||||
market: MarketDealTicket,
|
market: MarketDealTicket,
|
||||||
onSelect?: (id: string) => void
|
onSelect?: (id: string) => void
|
||||||
): { label: ReactNode; value?: ReactNode }[] => {
|
): { label: ReactNode; value?: ReactNode }[] => {
|
||||||
const grid: MarketDataGridProps['grid'] = [];
|
const grid: DataGridProps['grid'] = [];
|
||||||
const isLiquidityMonitoringAuction =
|
const isLiquidityMonitoringAuction =
|
||||||
market.data.marketTradingMode ===
|
market.data.marketTradingMode ===
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
export * from './market-data-grid';
|
|
||||||
export * from './trading-mode-tooltip';
|
export * from './trading-mode-tooltip';
|
||||||
export * from './compile-grid-data';
|
export * from './compile-grid-data';
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useEnvironment } from '@vegaprotocol/environment';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import { createDocsLinks } from '@vegaprotocol/react-helpers';
|
import { createDocsLinks } from '@vegaprotocol/react-helpers';
|
||||||
import { MarketDataGrid } from './market-data-grid';
|
|
||||||
|
|
||||||
type TradingModeTooltipProps = {
|
type TradingModeTooltipProps = {
|
||||||
tradingMode: Schema.MarketTradingMode | null;
|
tradingMode: Schema.MarketTradingMode | null;
|
||||||
@ -46,7 +45,7 @@ export const TradingModeTooltip = ({
|
|||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
{compiledGrid && <MarketDataGrid grid={compiledGrid} />}
|
{compiledGrid && <DataGrid grid={compiledGrid} />}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -72,7 +71,7 @@ export const TradingModeTooltip = ({
|
|||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
{compiledGrid && <MarketDataGrid grid={compiledGrid} />}
|
{compiledGrid && <DataGrid grid={compiledGrid} />}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -94,7 +93,7 @@ export const TradingModeTooltip = ({
|
|||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
{compiledGrid && <MarketDataGrid grid={compiledGrid} />}
|
{compiledGrid && <DataGrid grid={compiledGrid} />}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { Intent } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
import {
|
import {
|
||||||
formatWithAsset,
|
formatWithAsset,
|
||||||
sumLiquidityCommitted,
|
sumLiquidityCommitted,
|
||||||
@ -6,6 +9,7 @@ import {
|
|||||||
getCandle24hAgo,
|
getCandle24hAgo,
|
||||||
getChange,
|
getChange,
|
||||||
EMPTY_VALUE,
|
EMPTY_VALUE,
|
||||||
|
useCheckLiquidityStatus,
|
||||||
} from './liquidity-utils';
|
} from './liquidity-utils';
|
||||||
|
|
||||||
const CANDLES_1 = [
|
const CANDLES_1 = [
|
||||||
@ -118,3 +122,50 @@ describe('getChange', () => {
|
|||||||
expect(result).toEqual(EMPTY_VALUE);
|
expect(result).toEqual(EMPTY_VALUE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('useCheckLiquidityStatus', () => {
|
||||||
|
it('should return amber if liquidity is enough', () => {
|
||||||
|
const { result } = renderHook(() =>
|
||||||
|
useCheckLiquidityStatus({
|
||||||
|
suppliedStake: '60',
|
||||||
|
targetStake: '100',
|
||||||
|
triggeringRatio: '0.5',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
status: Intent.Warning,
|
||||||
|
percentage: new BigNumber('60'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return red if liquidity is not enough', () => {
|
||||||
|
const { result } = renderHook(() =>
|
||||||
|
useCheckLiquidityStatus({
|
||||||
|
suppliedStake: '60',
|
||||||
|
targetStake: '100',
|
||||||
|
triggeringRatio: '1',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
status: Intent.Danger,
|
||||||
|
percentage: new BigNumber('60'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return green if liquidity is enough', () => {
|
||||||
|
const { result } = renderHook(() =>
|
||||||
|
useCheckLiquidityStatus({
|
||||||
|
suppliedStake: '101',
|
||||||
|
targetStake: '100',
|
||||||
|
triggeringRatio: '1',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).toEqual({
|
||||||
|
status: Intent.Success,
|
||||||
|
percentage: new BigNumber('101'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -2,6 +2,7 @@ import BigNumber from 'bignumber.js';
|
|||||||
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
import type { MarketNodeFragment } from './../__generated__/MarketsLiquidity';
|
import type { MarketNodeFragment } from './../__generated__/MarketsLiquidity';
|
||||||
|
import { Intent } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
export type LiquidityProvisionMarket = MarketNodeFragment;
|
export type LiquidityProvisionMarket = MarketNodeFragment;
|
||||||
|
|
||||||
@ -117,3 +118,46 @@ export const getTargetStake = (
|
|||||||
) => {
|
) => {
|
||||||
return markets.find((m) => m.id === marketId)?.data?.targetStake || '0';
|
return markets.find((m) => m.id === marketId)?.data?.targetStake || '0';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useCheckLiquidityStatus = ({
|
||||||
|
suppliedStake,
|
||||||
|
targetStake,
|
||||||
|
triggeringRatio,
|
||||||
|
}: {
|
||||||
|
suppliedStake: string | number;
|
||||||
|
targetStake: string | number;
|
||||||
|
triggeringRatio: string | number;
|
||||||
|
}): {
|
||||||
|
status: Intent;
|
||||||
|
percentage: BigNumber;
|
||||||
|
} => {
|
||||||
|
// percentage supplied
|
||||||
|
const percentage = new BigNumber(suppliedStake)
|
||||||
|
.dividedBy(targetStake)
|
||||||
|
.multipliedBy(100);
|
||||||
|
// IF supplied_stake >= target_stake THEN
|
||||||
|
if (new BigNumber(suppliedStake).gte(new BigNumber(targetStake))) {
|
||||||
|
// show a green status, e.g. "🟢 $13,666,999 liquidity supplied"
|
||||||
|
return {
|
||||||
|
status: Intent.Success,
|
||||||
|
percentage,
|
||||||
|
};
|
||||||
|
// ELSE IF supplied_stake > NETPARAM[market.liquidity.targetstake.triggering.ratio] * target_stake THEN
|
||||||
|
} else if (
|
||||||
|
new BigNumber(suppliedStake).gte(
|
||||||
|
new BigNumber(targetStake).multipliedBy(triggeringRatio)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// show an amber status, e.g. "🟠 $3,456,123 liquidity supplied"
|
||||||
|
return {
|
||||||
|
status: Intent.Warning,
|
||||||
|
percentage,
|
||||||
|
};
|
||||||
|
// ELSE show a red status, e.g. "🔴 $600,002 liquidity supplied"
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status: Intent.Danger,
|
||||||
|
percentage,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -3,14 +3,14 @@ import * as Types from '@vegaprotocol/types';
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import * as Apollo from '@apollo/client';
|
import * as Apollo from '@apollo/client';
|
||||||
const defaultOptions = {} as const;
|
const defaultOptions = {} as const;
|
||||||
export type MarketDataUpdateFieldsFragment = { __typename?: 'ObservableMarketData', marketId: string, bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketTradingMode: Types.MarketTradingMode, marketState: Types.MarketState, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string };
|
export type MarketDataUpdateFieldsFragment = { __typename?: 'ObservableMarketData', marketId: string, bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketTradingMode: Types.MarketTradingMode, marketState: Types.MarketState, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null };
|
||||||
|
|
||||||
export type MarketDataUpdateSubscriptionVariables = Types.Exact<{
|
export type MarketDataUpdateSubscriptionVariables = Types.Exact<{
|
||||||
marketId: Types.Scalars['ID'];
|
marketId: Types.Scalars['ID'];
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type MarketDataUpdateSubscription = { __typename?: 'Subscription', marketsData: Array<{ __typename?: 'ObservableMarketData', marketId: string, bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketTradingMode: Types.MarketTradingMode, marketState: Types.MarketState, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string }> };
|
export type MarketDataUpdateSubscription = { __typename?: 'Subscription', marketsData: Array<{ __typename?: 'ObservableMarketData', marketId: string, bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketTradingMode: Types.MarketTradingMode, marketState: Types.MarketState, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null }> };
|
||||||
|
|
||||||
export type MarketDataFieldsFragment = { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketTradingMode: Types.MarketTradingMode, marketState: Types.MarketState, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, market: { __typename?: 'Market', id: string } };
|
export type MarketDataFieldsFragment = { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketTradingMode: Types.MarketTradingMode, marketState: Types.MarketState, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, market: { __typename?: 'Market', id: string } };
|
||||||
|
|
||||||
@ -35,6 +35,8 @@ export const MarketDataUpdateFieldsFragmentDoc = gql`
|
|||||||
indicativePrice
|
indicativePrice
|
||||||
bestStaticBidPrice
|
bestStaticBidPrice
|
||||||
bestStaticOfferPrice
|
bestStaticOfferPrice
|
||||||
|
targetStake
|
||||||
|
suppliedStake
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
export const MarketDataFieldsFragmentDoc = gql`
|
export const MarketDataFieldsFragmentDoc = gql`
|
||||||
|
@ -11,6 +11,8 @@ fragment MarketDataUpdateFields on ObservableMarketData {
|
|||||||
indicativePrice
|
indicativePrice
|
||||||
bestStaticBidPrice
|
bestStaticBidPrice
|
||||||
bestStaticOfferPrice
|
bestStaticOfferPrice
|
||||||
|
targetStake
|
||||||
|
suppliedStake
|
||||||
}
|
}
|
||||||
|
|
||||||
subscription MarketDataUpdate($marketId: ID!) {
|
subscription MarketDataUpdate($marketId: ID!) {
|
||||||
|
@ -102,6 +102,9 @@ export const NetworkParams = {
|
|||||||
spam_protection_voting_min_tokens: 'spam_protection_voting_min_tokens',
|
spam_protection_voting_min_tokens: 'spam_protection_voting_min_tokens',
|
||||||
spam_protection_proposal_min_tokens: 'spam_protection_proposal_min_tokens',
|
spam_protection_proposal_min_tokens: 'spam_protection_proposal_min_tokens',
|
||||||
market_liquidity_stakeToCcySiskas: 'market_liquidity_stakeToCcySiskas',
|
market_liquidity_stakeToCcySiskas: 'market_liquidity_stakeToCcySiskas',
|
||||||
|
market_liquidity_stakeToCcyVolume: 'market_liquidity_stakeToCcyVolume',
|
||||||
|
market_liquidity_targetstake_triggering_ratio:
|
||||||
|
'market_liquidity_targetstake_triggering_ratio',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
type Params = typeof NetworkParams;
|
type Params = typeof NetworkParams;
|
||||||
|
@ -14,3 +14,4 @@ export * from './lib/links';
|
|||||||
export * from './lib/is-asset-erc20';
|
export * from './lib/is-asset-erc20';
|
||||||
export * from './lib/remove-pagination-wrapper';
|
export * from './lib/remove-pagination-wrapper';
|
||||||
export * from './lib/__generated__/ChainId';
|
export * from './lib/__generated__/ChainId';
|
||||||
|
export * from './lib/data-grid';
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
export type MarketDataGridProps = {
|
export type DataGridProps = {
|
||||||
grid: {
|
grid: {
|
||||||
label: string | ReactNode;
|
label: string | ReactNode;
|
||||||
value?: ReactNode;
|
value?: ReactNode;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MarketDataGrid = ({ grid }: MarketDataGridProps) => {
|
export const DataGrid = ({ grid }: DataGridProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{grid.map(
|
{grid.map(
|
1
libs/react-helpers/src/lib/data-grid/index.ts
Normal file
1
libs/react-helpers/src/lib/data-grid/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './data-grid';
|
@ -11,3 +11,4 @@ export * from './remove-0x';
|
|||||||
export * from './time';
|
export * from './time';
|
||||||
export * from './links';
|
export * from './links';
|
||||||
export * from './remove-pagination-wrapper';
|
export * from './remove-pagination-wrapper';
|
||||||
|
export * from './data-grid';
|
||||||
|
Loading…
Reference in New Issue
Block a user