Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b29311af9 | ||
|
|
2725bef159 | ||
|
|
070f1905e2 | ||
|
|
6705eb4398 | ||
|
|
9d3fc04597 | ||
|
|
d3929b8d4a |
@@ -4,9 +4,8 @@ import {
|
||||
getMarketExpiryDateFormatted,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { MarketInfoNoCandlesQuery } from '@vegaprotocol/market-info';
|
||||
import type { MarketInfoWithData } from '@vegaprotocol/market-info';
|
||||
import { MarketInfoTable } from '@vegaprotocol/market-info';
|
||||
import pick from 'lodash/pick';
|
||||
import {
|
||||
MarketStateMapping,
|
||||
MarketTradingModeMapping,
|
||||
@@ -17,11 +16,7 @@ import BigNumber from 'bignumber.js';
|
||||
import { useMemo } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const MarketDetails = ({
|
||||
market,
|
||||
}: {
|
||||
market: MarketInfoNoCandlesQuery['market'];
|
||||
}) => {
|
||||
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
||||
const quoteUnit = market?.tradableInstrument.instrument.product.quoteName;
|
||||
const assetId = useMemo(
|
||||
() => market?.tradableInstrument.instrument.product?.settlementAsset.id,
|
||||
@@ -32,7 +27,9 @@ export const MarketDetails = ({
|
||||
if (!market) return null;
|
||||
|
||||
const keyDetails = {
|
||||
...pick(market, 'decimalPlaces', 'positionDecimalPlaces', 'tradingMode'),
|
||||
decimalPlaces: market.decimalPlaces,
|
||||
positionDecimalPlaces: market.positionDecimalPlaces,
|
||||
tradingMode: market.tradingMode,
|
||||
state: MarketStateMapping[market.state],
|
||||
};
|
||||
const assetDecimals =
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
interface CancelSummaryProps {
|
||||
orderId?: string;
|
||||
marketId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple component for rendering a reasonable string from an order cancellation
|
||||
*/
|
||||
export const CancelSummary = ({ orderId, marketId }: CancelSummaryProps) => {
|
||||
return <span className="font-bold">{getLabel(orderId, marketId)}</span>;
|
||||
};
|
||||
|
||||
export function getLabel(
|
||||
orderId: string | undefined,
|
||||
marketId: string | undefined
|
||||
): string {
|
||||
if (!orderId && !marketId) {
|
||||
return t('All orders');
|
||||
} else if (marketId && !orderId) {
|
||||
return t('All in market');
|
||||
}
|
||||
|
||||
return '-';
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import type { BatchCancellationInstruction } from '../../../../routes/types/bloc
|
||||
import { TxOrderType } from '../../tx-order-type';
|
||||
import { MarketLink } from '../../../links';
|
||||
import OrderSummary from '../../../order-summary/order-summary';
|
||||
import { CancelSummary } from '../../../order-summary/order-cancellation';
|
||||
|
||||
interface BatchCancelProps {
|
||||
index: number;
|
||||
@@ -19,7 +20,14 @@ export const BatchCancel = ({ index, submission }: BatchCancelProps) => {
|
||||
<TxOrderType orderType={'OrderCancellation'} />
|
||||
</td>
|
||||
<td>
|
||||
<OrderSummary id={submission.orderId} modifier="cancelled" />
|
||||
{submission.orderId ? (
|
||||
<OrderSummary id={submission.orderId} modifier="cancelled" />
|
||||
) : (
|
||||
<CancelSummary
|
||||
orderId={submission.orderId}
|
||||
marketId={submission.marketId}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
<td>
|
||||
<MarketLink id={submission.marketId} />
|
||||
|
||||
@@ -5,6 +5,8 @@ import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||
import DeterministicOrderDetails from '../../order-details/deterministic-order-details';
|
||||
import { CancelSummary } from '../../order-summary/order-cancellation';
|
||||
import Hash from '../../links/hash';
|
||||
|
||||
interface TxDetailsOrderCancelProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
@@ -24,8 +26,8 @@ export const TxDetailsOrderCancel = ({
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const marketId: string = txData.command.orderCancellation.marketId || '-';
|
||||
const orderId: string = txData.command.orderCancellation.orderId || '-';
|
||||
const marketId: string = txData.command.orderCancellation.marketId;
|
||||
const orderId: string = txData.command.orderCancellation.orderId;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -38,18 +40,24 @@ export const TxDetailsOrderCancel = ({
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Order')}</TableCell>
|
||||
<TableCell>
|
||||
<code>{orderId}</code>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Market')}</TableCell>
|
||||
<TableCell>
|
||||
<MarketLink id={marketId} />
|
||||
{orderId ? (
|
||||
<Hash text={orderId} />
|
||||
) : (
|
||||
<CancelSummary orderId={orderId} marketId={marketId} />
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{marketId ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Market')}</TableCell>
|
||||
<TableCell>
|
||||
<MarketLink id={marketId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
</TableWithTbody>
|
||||
|
||||
{orderId !== '-' ? <DeterministicOrderDetails id={orderId} /> : null}
|
||||
{orderId ? <DeterministicOrderDetails id={orderId} /> : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ export const Proposals = () => {
|
||||
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: proposalsDataProvider,
|
||||
variables: {},
|
||||
});
|
||||
|
||||
useDocumentTitle([t('Governance Proposals')]);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { AsyncRenderer, Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { MarketDetails } from '../../components/markets/market-details';
|
||||
import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||
import compact from 'lodash/compact';
|
||||
import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
|
||||
import { marketInfoNoCandlesDataProvider } from '@vegaprotocol/market-info';
|
||||
import { marketInfoProvider } from '@vegaprotocol/market-info';
|
||||
import { PageTitle } from '../../components/page-helpers/page-title';
|
||||
|
||||
export const MarketPage = () => {
|
||||
@@ -16,24 +16,17 @@ export const MarketPage = () => {
|
||||
|
||||
const { marketId } = useParams<{ marketId: string }>();
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId,
|
||||
}),
|
||||
[marketId]
|
||||
);
|
||||
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: marketInfoNoCandlesDataProvider,
|
||||
dataProvider: marketInfoProvider,
|
||||
skipUpdates: true,
|
||||
variables,
|
||||
variables: {
|
||||
marketId: marketId || '',
|
||||
skip: !marketId,
|
||||
},
|
||||
});
|
||||
|
||||
useDocumentTitle(
|
||||
compact([
|
||||
'Market details',
|
||||
data?.market?.tradableInstrument.instrument.name,
|
||||
])
|
||||
compact(['Market details', data?.tradableInstrument.instrument.name])
|
||||
);
|
||||
|
||||
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
|
||||
@@ -43,10 +36,10 @@ export const MarketPage = () => {
|
||||
<section className="relative">
|
||||
<PageTitle
|
||||
data-testid="markets-heading"
|
||||
title={data?.market?.tradableInstrument.instrument.name || ''}
|
||||
title={data?.tradableInstrument.instrument.name || ''}
|
||||
actions={
|
||||
<Button
|
||||
disabled={!data?.market}
|
||||
disabled={!data}
|
||||
size="xs"
|
||||
onClick={() => setDialogOpen(true)}
|
||||
>
|
||||
@@ -60,14 +53,14 @@ export const MarketPage = () => {
|
||||
loading={loading}
|
||||
error={error}
|
||||
>
|
||||
<MarketDetails market={data?.market} />
|
||||
{data && <MarketDetails market={data} />}
|
||||
</AsyncRenderer>
|
||||
</section>
|
||||
<JsonViewerDialog
|
||||
open={dialogOpen}
|
||||
onChange={(isOpen) => setDialogOpen(isOpen)}
|
||||
title={data?.market?.tradableInstrument.instrument.name || ''}
|
||||
content={data?.market}
|
||||
title={data?.tradableInstrument.instrument.name || ''}
|
||||
content={data}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@ export const MarketsPage = () => {
|
||||
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: marketsProvider,
|
||||
variables: undefined,
|
||||
skipUpdates: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useMemo } from 'react';
|
||||
import { makeDerivedDataProvider } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
@@ -43,7 +42,7 @@ const useMarketDetails = (marketId: string | undefined) => {
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: lpDataProvider,
|
||||
skipUpdates: true,
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
variables: { marketId: marketId || '' },
|
||||
});
|
||||
|
||||
const liquidityProviders = data?.liquidityProviders || [];
|
||||
|
||||
+7
-10
@@ -39,14 +39,11 @@ export const Last24hVolume = ({
|
||||
[marketId, yTimestamp]
|
||||
);
|
||||
|
||||
const variables24hAgo = useMemo(
|
||||
() => ({
|
||||
marketId: marketId,
|
||||
interval: Schema.Interval.INTERVAL_I1D,
|
||||
since: yTimestamp,
|
||||
}),
|
||||
[marketId, yTimestamp]
|
||||
);
|
||||
const variables24hAgo = {
|
||||
marketId: marketId,
|
||||
interval: Schema.Interval.INTERVAL_I1D,
|
||||
since: yTimestamp,
|
||||
};
|
||||
|
||||
const throttledSetCandles = useRef(
|
||||
throttle((data: Candle[]) => {
|
||||
@@ -64,7 +61,7 @@ export const Last24hVolume = ({
|
||||
[throttledSetCandles]
|
||||
);
|
||||
|
||||
const { data, error } = useDataProvider<Candle[], Candle>({
|
||||
const { data, error } = useDataProvider({
|
||||
dataProvider: marketCandlesProvider,
|
||||
variables: variables,
|
||||
update,
|
||||
@@ -88,7 +85,7 @@ export const Last24hVolume = ({
|
||||
[throttledSetVolumeChange]
|
||||
);
|
||||
|
||||
useDataProvider<Candle[], Candle>({
|
||||
useDataProvider({
|
||||
dataProvider: marketCandlesProvider,
|
||||
update: updateCandle24hAgo,
|
||||
variables: variables24hAgo,
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
"tranche_end": "2023-04-06T00:00:00.000Z",
|
||||
"total_added": "14099",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "12845.7134438470736744",
|
||||
"locked_amount": "12503.8505943847065215",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "30",
|
||||
@@ -2772,7 +2772,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "86666.297",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "64404.7768689454615673836",
|
||||
"locked_amount": "64226.2997002376996434844",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "86666.297",
|
||||
@@ -2838,7 +2838,7 @@
|
||||
"tranche_end": "2023-06-01T00:00:00.000Z",
|
||||
"total_added": "2500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "1157.2026353276355",
|
||||
"locked_amount": "1146.87754375254385",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "2500",
|
||||
@@ -2959,7 +2959,7 @@
|
||||
"tranche_end": "2023-09-01T00:00:00.000Z",
|
||||
"total_added": "17500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "16762.3704206924315",
|
||||
"locked_amount": "16690.880384460548",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "12500",
|
||||
@@ -3226,7 +3226,7 @@
|
||||
"tranche_end": "2023-08-01T00:00:00.000Z",
|
||||
"total_added": "37500",
|
||||
"total_removed": "3720.2151432",
|
||||
"locked_amount": "30092.06184775936125",
|
||||
"locked_amount": "29936.3298035604675",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -3436,7 +3436,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "129999.45",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "64346.015613772301177895",
|
||||
"locked_amount": "64167.701283024126646992",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129999.45",
|
||||
@@ -3502,7 +3502,7 @@
|
||||
"tranche_end": "2023-09-03T00:00:00.000Z",
|
||||
"total_added": "62600",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "30570.1271943176011",
|
||||
"locked_amount": "30441.211212582448",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10000",
|
||||
@@ -3695,7 +3695,7 @@
|
||||
"tranche_end": "2023-09-17T00:00:00.000Z",
|
||||
"total_added": "5000",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "2633.484271943176",
|
||||
"locked_amount": "2623.187468290208",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "5000",
|
||||
@@ -3906,7 +3906,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "97499.58",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "6339.6488375364585926712",
|
||||
"locked_amount": "6164.7390898037635677228",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "97499.58",
|
||||
@@ -3939,7 +3939,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "135173.4239508",
|
||||
"total_removed": "98230.390980249184455396",
|
||||
"locked_amount": "8665.205466200317294112311476",
|
||||
"locked_amount": "8426.134037957922291545186664",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "135173.4239508",
|
||||
@@ -3985,7 +3985,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "32499.86",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "2666.9807860720642474196",
|
||||
"locked_amount": "2593.399275730700033358",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "32499.86",
|
||||
@@ -4018,7 +4018,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "10833.29",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "868.0763660974942076085",
|
||||
"locked_amount": "844.126298499455427378",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10833.29",
|
||||
@@ -4051,7 +4051,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "22749.93",
|
||||
"total_removed": "4720.860935375",
|
||||
"locked_amount": "3245.0633378272258072119",
|
||||
"locked_amount": "3155.5326359947637016882",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "6500",
|
||||
@@ -4203,7 +4203,7 @@
|
||||
"tranche_end": "2023-05-01T00:00:00.000Z",
|
||||
"total_added": "22500",
|
||||
"total_removed": "5257.2509016",
|
||||
"locked_amount": "6618.773020257828",
|
||||
"locked_amount": "6525.3337937384904",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -4533,7 +4533,7 @@
|
||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||
"total_added": "1939928.38",
|
||||
"total_removed": "928642.9598472029154",
|
||||
"locked_amount": "453062.8421701724988668568",
|
||||
"locked_amount": "449067.829844236323584786",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1852091.69",
|
||||
@@ -7507,10 +7507,15 @@
|
||||
"tranche_id": 10,
|
||||
"tranche_start": "2021-07-15T23:37:11.000Z",
|
||||
"tranche_end": "2021-07-15T23:37:11.000Z",
|
||||
"total_added": "6259302.299000000000000001",
|
||||
"total_removed": "6213483.280000000000000001",
|
||||
"total_added": "6359302.299000000000000001",
|
||||
"total_removed": "6313483.280000000000000001",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tx": "0xf82d4ea9a92b8374c542a9cff94581e511ca54ee70eb0f65436727ac473aeb75"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -8038,6 +8043,11 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tx": "0xf82d4ea9a92b8374c542a9cff94581e511ca54ee70eb0f65436727ac473aeb75"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -8508,6 +8518,12 @@
|
||||
{
|
||||
"address": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tranche_id": 10,
|
||||
"tx": "0xf82d4ea9a92b8374c542a9cff94581e511ca54ee70eb0f65436727ac473aeb75"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -8696,6 +8712,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tranche_id": 10,
|
||||
"tx": "0xf82d4ea9a92b8374c542a9cff94581e511ca54ee70eb0f65436727ac473aeb75"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -8877,8 +8899,8 @@
|
||||
"tx": "0xac16a4ce688d40a482a59914d68c3a676592f8804ee8f0781b66a4ba5ccfbdfc"
|
||||
}
|
||||
],
|
||||
"total_tokens": "3056651",
|
||||
"withdrawn_tokens": "3056651",
|
||||
"total_tokens": "3156651",
|
||||
"withdrawn_tokens": "3156651",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
@@ -9943,7 +9965,7 @@
|
||||
"tranche_start": "2021-09-03T00:00:00.000Z",
|
||||
"tranche_end": "2022-09-03T00:00:00.000Z",
|
||||
"total_added": "55431.000000000000000003",
|
||||
"total_removed": "44298.21518131551",
|
||||
"total_removed": "44310.21518131551",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -20223,6 +20245,11 @@
|
||||
"user": "0x4043fD11285B4f98A0f7b383D973a17F03e23EC5",
|
||||
"tx": "0xa3689042534a1b09c39510c3a9da4f5838c77e88df0dd7dd76415b759d9ad377"
|
||||
},
|
||||
{
|
||||
"amount": "12",
|
||||
"user": "0xCeE1b5DF292f5EA23798271f8e1374D911Fb4DE0",
|
||||
"tx": "0xfc74f691ee45ff735fd4df873755059973385f62772d50a85d9cc1e5ba53e528"
|
||||
},
|
||||
{
|
||||
"amount": "12",
|
||||
"user": "0x1D92cb812FdeDF1a5aFE3c5080B2D3Ec102694c6",
|
||||
@@ -35729,10 +35756,17 @@
|
||||
"tx": "0xd03e666dd6a358145f291e4ceec193352614d00727ed8910a4cad16374fffa43"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "12",
|
||||
"user": "0xCeE1b5DF292f5EA23798271f8e1374D911Fb4DE0",
|
||||
"tranche_id": 11,
|
||||
"tx": "0xfc74f691ee45ff735fd4df873755059973385f62772d50a85d9cc1e5ba53e528"
|
||||
}
|
||||
],
|
||||
"total_tokens": "12",
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "12"
|
||||
"withdrawn_tokens": "12",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0x2dd204e9cC4D41C68f2bb7Aa3b8Ce49884e482f5",
|
||||
@@ -37269,8 +37303,8 @@
|
||||
"tranche_start": "2022-03-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "3732368.4671",
|
||||
"total_removed": "618385.665327542135993",
|
||||
"locked_amount": "720701.17341691302668589937",
|
||||
"total_removed": "700133.348465855088393",
|
||||
"locked_amount": "714562.23038751102092088275",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1998.95815",
|
||||
@@ -37444,6 +37478,16 @@
|
||||
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
|
||||
"tx": "0xcba878ae28c2c84219f8281dc2a57d0d9b6c99b7920900d5344c76aabe8f1e84"
|
||||
},
|
||||
{
|
||||
"amount": "52343.18016",
|
||||
"user": "0x93b478148FF792B00076B7EdC89Db1FdE7772079",
|
||||
"tx": "0x282e2c8a2d0f87b31d99e0be5d955c1c1a5b69ff43364630a130a1222fb6d06c"
|
||||
},
|
||||
{
|
||||
"amount": "29404.5029783129524",
|
||||
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
|
||||
"tx": "0x166702670ca700f8d8957a5264ec47f6bcf67609682512d11dabc14276add0fb"
|
||||
},
|
||||
{
|
||||
"amount": "16659.576193025747093",
|
||||
"user": "0xB523235B6c7C74DDB26b10E78bFb2d0Cb63Ae289",
|
||||
@@ -38122,6 +38166,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "29404.5029783129524",
|
||||
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
|
||||
"tranche_id": 1,
|
||||
"tx": "0x166702670ca700f8d8957a5264ec47f6bcf67609682512d11dabc14276add0fb"
|
||||
},
|
||||
{
|
||||
"amount": "20348.9930984908397",
|
||||
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
|
||||
@@ -38148,8 +38198,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "112323.67",
|
||||
"withdrawn_tokens": "61339.357996063048",
|
||||
"remaining_tokens": "50984.312003936952"
|
||||
"withdrawn_tokens": "90743.8609743760004",
|
||||
"remaining_tokens": "21579.8090256239996"
|
||||
},
|
||||
{
|
||||
"address": "0x3D7944C81794Bc621076958cA0dC0F0b31BDc3e2",
|
||||
@@ -38526,6 +38576,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "52343.18016",
|
||||
"user": "0x93b478148FF792B00076B7EdC89Db1FdE7772079",
|
||||
"tranche_id": 1,
|
||||
"tx": "0x282e2c8a2d0f87b31d99e0be5d955c1c1a5b69ff43364630a130a1222fb6d06c"
|
||||
},
|
||||
{
|
||||
"amount": "34960.394886",
|
||||
"user": "0x93b478148FF792B00076B7EdC89Db1FdE7772079",
|
||||
@@ -38552,8 +38608,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200000",
|
||||
"withdrawn_tokens": "109216.685914",
|
||||
"remaining_tokens": "90783.314086"
|
||||
"withdrawn_tokens": "161559.866074",
|
||||
"remaining_tokens": "38440.133926"
|
||||
},
|
||||
{
|
||||
"address": "0xB523235B6c7C74DDB26b10E78bFb2d0Cb63Ae289",
|
||||
@@ -38629,8 +38685,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "15870102.715470999700000001",
|
||||
"total_removed": "589571.49512571875997952",
|
||||
"locked_amount": "7855247.6731391336068375002475321149851311",
|
||||
"total_removed": "793252.53458217063817452",
|
||||
"locked_amount": "7833479.37531468897572201750618542248391456",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "16249.93",
|
||||
@@ -39234,6 +39290,41 @@
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x16288057d0947efbbbc6ca61d6864ecfd4eb7949ddc1a934a05474ddbe453d4b"
|
||||
},
|
||||
{
|
||||
"amount": "536.260884812357375",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x18cda39375506d544e7a7b9fa9137aa3887b2abac598b151502a2c4eb1835f37"
|
||||
},
|
||||
{
|
||||
"amount": "19140.8654581272429",
|
||||
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
|
||||
"tx": "0xcfc7eefc60479d3e8470ea1c5d673a12e2417c9b9b3ebf4bf4137e8260fe07c8"
|
||||
},
|
||||
{
|
||||
"amount": "43338.199512",
|
||||
"user": "0x29f1856E73262fc4372BBF442EbB550919459308",
|
||||
"tx": "0x666f2848ebb8b2f7c6d7829fbab733bce6aeb750b6c70a51753ad86321f87247"
|
||||
},
|
||||
{
|
||||
"amount": "43325.172344",
|
||||
"user": "0x21ff84851BdF79de9AA357E47856d58b2d825392",
|
||||
"tx": "0xa13fae0c67f07b9eeaa65833f61e559672ba72a8c5b788ca83de99d95d1b2543"
|
||||
},
|
||||
{
|
||||
"amount": "43329.582318",
|
||||
"user": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
|
||||
"tx": "0x5eb1aba5b222162fbdec7d3e70bada62541fdef3914d25ba81e4fcb04a9d776b"
|
||||
},
|
||||
{
|
||||
"amount": "43329.683698",
|
||||
"user": "0x74b521F96c641FD59631Dc6a24c558ed39D64352",
|
||||
"tx": "0x9050c6348f5ef78b2a6d6b0947dcf004a8b608434319e9e30d8d6495fa19dc42"
|
||||
},
|
||||
{
|
||||
"amount": "10681.27524151227792",
|
||||
"user": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
|
||||
"tx": "0x1bb20a86b93d4f463dfab637d48333322efa4562109547456c547a1f7141e324"
|
||||
},
|
||||
{
|
||||
"amount": "535.4042378778335",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -41081,6 +41172,12 @@
|
||||
"tranche_id": 2,
|
||||
"tx": "0x16288057d0947efbbbc6ca61d6864ecfd4eb7949ddc1a934a05474ddbe453d4b"
|
||||
},
|
||||
{
|
||||
"amount": "536.260884812357375",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x18cda39375506d544e7a7b9fa9137aa3887b2abac598b151502a2c4eb1835f37"
|
||||
},
|
||||
{
|
||||
"amount": "535.4042378778335",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -42295,8 +42392,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "259998.8875",
|
||||
"withdrawn_tokens": "130887.978656279565875",
|
||||
"remaining_tokens": "129110.908843720434125"
|
||||
"withdrawn_tokens": "131424.23954109192325",
|
||||
"remaining_tokens": "128574.64795890807675"
|
||||
},
|
||||
{
|
||||
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
||||
@@ -42414,6 +42511,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "43325.172344",
|
||||
"user": "0x21ff84851BdF79de9AA357E47856d58b2d825392",
|
||||
"tranche_id": 2,
|
||||
"tx": "0xa13fae0c67f07b9eeaa65833f61e559672ba72a8c5b788ca83de99d95d1b2543"
|
||||
},
|
||||
{
|
||||
"amount": "30379.050924",
|
||||
"user": "0x21ff84851BdF79de9AA357E47856d58b2d825392",
|
||||
@@ -42428,8 +42531,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200000",
|
||||
"withdrawn_tokens": "57857.45725",
|
||||
"remaining_tokens": "142142.54275"
|
||||
"withdrawn_tokens": "101182.629594",
|
||||
"remaining_tokens": "98817.370406"
|
||||
},
|
||||
{
|
||||
"address": "0x8DA3586FF7526E122093EE6dD86DFBf067ad8704",
|
||||
@@ -42791,6 +42894,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "10681.27524151227792",
|
||||
"user": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x1bb20a86b93d4f463dfab637d48333322efa4562109547456c547a1f7141e324"
|
||||
},
|
||||
{
|
||||
"amount": "10964.26423788708204",
|
||||
"user": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
|
||||
@@ -42805,8 +42914,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "49294.676",
|
||||
"withdrawn_tokens": "14258.87379151869992",
|
||||
"remaining_tokens": "35035.80220848130008"
|
||||
"withdrawn_tokens": "24940.14903303097784",
|
||||
"remaining_tokens": "24354.52696696902216"
|
||||
},
|
||||
{
|
||||
"address": "0x4092E429B149b5495265b608FD6Fae69fa5bfBe6",
|
||||
@@ -42834,6 +42943,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "43329.683698",
|
||||
"user": "0x74b521F96c641FD59631Dc6a24c558ed39D64352",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x9050c6348f5ef78b2a6d6b0947dcf004a8b608434319e9e30d8d6495fa19dc42"
|
||||
},
|
||||
{
|
||||
"amount": "30570.627196",
|
||||
"user": "0x74b521F96c641FD59631Dc6a24c558ed39D64352",
|
||||
@@ -42854,8 +42969,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200000",
|
||||
"withdrawn_tokens": "57856.544842",
|
||||
"remaining_tokens": "142143.455158"
|
||||
"withdrawn_tokens": "101186.22854",
|
||||
"remaining_tokens": "98813.77146"
|
||||
},
|
||||
{
|
||||
"address": "0x834b777E3aB758C84FeBbfb9d6BB675bc4B16915",
|
||||
@@ -43218,6 +43333,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "43329.582318",
|
||||
"user": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x5eb1aba5b222162fbdec7d3e70bada62541fdef3914d25ba81e4fcb04a9d776b"
|
||||
},
|
||||
{
|
||||
"amount": "30374.150954",
|
||||
"user": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
|
||||
@@ -43238,8 +43359,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200000",
|
||||
"withdrawn_tokens": "57854.669336",
|
||||
"remaining_tokens": "142145.330664"
|
||||
"withdrawn_tokens": "101184.251654",
|
||||
"remaining_tokens": "98815.748346"
|
||||
},
|
||||
{
|
||||
"address": "0xA5d8726fFaD226e65D136ef9C2185750863b4850",
|
||||
@@ -43372,6 +43493,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "19140.8654581272429",
|
||||
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
|
||||
"tranche_id": 2,
|
||||
"tx": "0xcfc7eefc60479d3e8470ea1c5d673a12e2417c9b9b3ebf4bf4137e8260fe07c8"
|
||||
},
|
||||
{
|
||||
"amount": "13246.0770207423553",
|
||||
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
|
||||
@@ -43392,8 +43519,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "87676.33",
|
||||
"withdrawn_tokens": "25209.4762502180206",
|
||||
"remaining_tokens": "62466.8537497819794"
|
||||
"withdrawn_tokens": "44350.3417083452635",
|
||||
"remaining_tokens": "43325.9882916547365"
|
||||
},
|
||||
{
|
||||
"address": "0x9cF9B305601154C85ff86014d10a8762C802db0B",
|
||||
@@ -43601,6 +43728,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "43338.199512",
|
||||
"user": "0x29f1856E73262fc4372BBF442EbB550919459308",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x666f2848ebb8b2f7c6d7829fbab733bce6aeb750b6c70a51753ad86321f87247"
|
||||
},
|
||||
{
|
||||
"amount": "30360.0931",
|
||||
"user": "0x29f1856E73262fc4372BBF442EbB550919459308",
|
||||
@@ -43621,8 +43754,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200000",
|
||||
"withdrawn_tokens": "57841.692856",
|
||||
"remaining_tokens": "142158.307144"
|
||||
"withdrawn_tokens": "101179.892368",
|
||||
"remaining_tokens": "98820.107632"
|
||||
},
|
||||
{
|
||||
"address": "0x87D71adAbC11c35aF566eD51421eDA0c82828a3A",
|
||||
@@ -44569,8 +44702,8 @@
|
||||
"tranche_start": "2021-11-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||
"total_added": "14597706.0446472999",
|
||||
"total_removed": "5581993.656033465744205406",
|
||||
"locked_amount": "1530469.269321785094773221183308807",
|
||||
"total_removed": "5732288.868131620050778506",
|
||||
"locked_amount": "1510372.915762151115519682772533698",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129284.449",
|
||||
@@ -44849,6 +44982,51 @@
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0xb499e0514e04e8acb67e4e8cc68ceaf57a018bbf844b006f7e77d1a3373ddfec"
|
||||
},
|
||||
{
|
||||
"amount": "743.788992596092989",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0xe6310e8b181b7de346b3dacbdda2dfb8191938c1326eb3ccab3c390a1da3fc5d"
|
||||
},
|
||||
{
|
||||
"amount": "8987.626998403452",
|
||||
"user": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
|
||||
"tx": "0xa9c90284c90345a2895e81e8ef23db30f051ec6c6ef5183ca255fcaf22de4327"
|
||||
},
|
||||
{
|
||||
"amount": "6912.633608920802",
|
||||
"user": "0x97E5985117F47c8d110Be1c422DdCB9bE9b46e62",
|
||||
"tx": "0xc1f747d9dbff23e28d6de87a8dbec2c56d46197429056310ea86a58c6d496951"
|
||||
},
|
||||
{
|
||||
"amount": "11752.132634029515",
|
||||
"user": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
|
||||
"tx": "0x00d7d3b263bb030d6185e25b7f193be30c5393215377a9254b326438d7646e75"
|
||||
},
|
||||
{
|
||||
"amount": "14517.473476800768",
|
||||
"user": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
|
||||
"tx": "0xd9b50ce86b31b3f056eb0d3468968af34bc2baa1cea80abd23bb52f4fee3bbba"
|
||||
},
|
||||
{
|
||||
"amount": "9677.727038032512",
|
||||
"user": "0xd4632B682228Db5f38E2283869AEe8c29ee6Eec8",
|
||||
"tx": "0x90d931bf82513dea5199db4e453ff157388063079569c50910df85790b16bb3b"
|
||||
},
|
||||
{
|
||||
"amount": "10369.208041666186",
|
||||
"user": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
|
||||
"tx": "0xfe06b188901c295532cd3e8701fcccee385405585f295b1e8fbdef1644803bef"
|
||||
},
|
||||
{
|
||||
"amount": "6913.0876496568166456",
|
||||
"user": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
|
||||
"tx": "0x455a8038de44fe4c2308c74f9512ce861c1153da4fc3deb4626ff5820757e92b"
|
||||
},
|
||||
{
|
||||
"amount": "80421.5336580481619385",
|
||||
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
|
||||
"tx": "0x69930da3ef2f654a71946c49cacdd77c151bdf8f8ee18812eede5e3da511a901"
|
||||
},
|
||||
{
|
||||
"amount": "800.792718381487871",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
@@ -47888,6 +48066,12 @@
|
||||
"tranche_id": 3,
|
||||
"tx": "0xb499e0514e04e8acb67e4e8cc68ceaf57a018bbf844b006f7e77d1a3373ddfec"
|
||||
},
|
||||
{
|
||||
"amount": "743.788992596092989",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tranche_id": 3,
|
||||
"tx": "0xe6310e8b181b7de346b3dacbdda2dfb8191938c1326eb3ccab3c390a1da3fc5d"
|
||||
},
|
||||
{
|
||||
"amount": "800.792718381487871",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
@@ -50404,8 +50588,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "359123.469575",
|
||||
"withdrawn_tokens": "320890.679702958869192",
|
||||
"remaining_tokens": "38232.789872041130808"
|
||||
"withdrawn_tokens": "321634.468695554962181",
|
||||
"remaining_tokens": "37489.000879445037819"
|
||||
},
|
||||
{
|
||||
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
|
||||
@@ -50635,6 +50819,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "80421.5336580481619385",
|
||||
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x69930da3ef2f654a71946c49cacdd77c151bdf8f8ee18812eede5e3da511a901"
|
||||
},
|
||||
{
|
||||
"amount": "21866.26138234560055572",
|
||||
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
|
||||
@@ -50961,8 +51151,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "1266324.603486",
|
||||
"withdrawn_tokens": "1054715.46046774287416502",
|
||||
"remaining_tokens": "211609.14301825712583498"
|
||||
"withdrawn_tokens": "1135136.99412579103610352",
|
||||
"remaining_tokens": "131187.60936020896389648"
|
||||
},
|
||||
{
|
||||
"address": "0xC5d9221EB9c28A69859264c0A2Fe0d3272228296",
|
||||
@@ -51427,6 +51617,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "6912.633608920802",
|
||||
"user": "0x97E5985117F47c8d110Be1c422DdCB9bE9b46e62",
|
||||
"tranche_id": 3,
|
||||
"tx": "0xc1f747d9dbff23e28d6de87a8dbec2c56d46197429056310ea86a58c6d496951"
|
||||
},
|
||||
{
|
||||
"amount": "7096.654181850842",
|
||||
"user": "0x97E5985117F47c8d110Be1c422DdCB9bE9b46e62",
|
||||
@@ -51453,8 +51649,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "31784.9",
|
||||
"withdrawn_tokens": "21570.353734449044",
|
||||
"remaining_tokens": "10214.546265550956"
|
||||
"withdrawn_tokens": "28482.987343369846",
|
||||
"remaining_tokens": "3301.912656630154"
|
||||
},
|
||||
{
|
||||
"address": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
|
||||
@@ -51467,6 +51663,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "6913.0876496568166456",
|
||||
"user": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x455a8038de44fe4c2308c74f9512ce861c1153da4fc3deb4626ff5820757e92b"
|
||||
},
|
||||
{
|
||||
"amount": "7096.9655595642880472",
|
||||
"user": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
|
||||
@@ -51493,8 +51695,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "31786.09544",
|
||||
"withdrawn_tokens": "21572.0382463216479552",
|
||||
"remaining_tokens": "10214.0571936783520448"
|
||||
"withdrawn_tokens": "28485.1258959784646008",
|
||||
"remaining_tokens": "3300.9695440215353992"
|
||||
},
|
||||
{
|
||||
"address": "0xbEb7f1B85626Fd9BdA69765d7abb3832C542A62E",
|
||||
@@ -51522,6 +51724,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "9677.727038032512",
|
||||
"user": "0xd4632B682228Db5f38E2283869AEe8c29ee6Eec8",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x90d931bf82513dea5199db4e453ff157388063079569c50910df85790b16bb3b"
|
||||
},
|
||||
{
|
||||
"amount": "9935.44459047968",
|
||||
"user": "0xd4632B682228Db5f38E2283869AEe8c29ee6Eec8",
|
||||
@@ -51560,8 +51768,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "44499.2",
|
||||
"withdrawn_tokens": "30199.64284308704",
|
||||
"remaining_tokens": "14299.55715691296"
|
||||
"withdrawn_tokens": "39877.369881119552",
|
||||
"remaining_tokens": "4621.830118880448"
|
||||
},
|
||||
{
|
||||
"address": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
|
||||
@@ -51574,6 +51782,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "14517.473476800768",
|
||||
"user": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
|
||||
"tranche_id": 3,
|
||||
"tx": "0xd9b50ce86b31b3f056eb0d3468968af34bc2baa1cea80abd23bb52f4fee3bbba"
|
||||
},
|
||||
{
|
||||
"amount": "14902.31933949408",
|
||||
"user": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
|
||||
@@ -51606,8 +51820,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "66748.8",
|
||||
"withdrawn_tokens": "45298.309676595072",
|
||||
"remaining_tokens": "21450.490323404928"
|
||||
"withdrawn_tokens": "59815.78315339584",
|
||||
"remaining_tokens": "6933.01684660416"
|
||||
},
|
||||
{
|
||||
"address": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
|
||||
@@ -51620,6 +51834,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "10369.208041666186",
|
||||
"user": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
|
||||
"tranche_id": 3,
|
||||
"tx": "0xfe06b188901c295532cd3e8701fcccee385405585f295b1e8fbdef1644803bef"
|
||||
},
|
||||
{
|
||||
"amount": "10645.268077994374",
|
||||
"user": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
|
||||
@@ -51652,8 +51872,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "47678.2",
|
||||
"withdrawn_tokens": "32357.271744238356",
|
||||
"remaining_tokens": "15320.928255761644"
|
||||
"withdrawn_tokens": "42726.479785904542",
|
||||
"remaining_tokens": "4951.720214095458"
|
||||
},
|
||||
{
|
||||
"address": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
|
||||
@@ -51666,6 +51886,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "8987.626998403452",
|
||||
"user": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
|
||||
"tranche_id": 3,
|
||||
"tx": "0xa9c90284c90345a2895e81e8ef23db30f051ec6c6ef5183ca255fcaf22de4327"
|
||||
},
|
||||
{
|
||||
"amount": "9224.162860659198",
|
||||
"user": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
|
||||
@@ -51692,8 +51918,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "41320.2",
|
||||
"withdrawn_tokens": "28039.82041559223",
|
||||
"remaining_tokens": "13280.37958440777"
|
||||
"withdrawn_tokens": "37027.447413995682",
|
||||
"remaining_tokens": "4292.752586004318"
|
||||
},
|
||||
{
|
||||
"address": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
|
||||
@@ -51706,6 +51932,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "11752.132634029515",
|
||||
"user": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x00d7d3b263bb030d6185e25b7f193be30c5393215377a9254b326438d7646e75"
|
||||
},
|
||||
{
|
||||
"amount": "12063.855243783915",
|
||||
"user": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
|
||||
@@ -51738,8 +51970,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "54034.5",
|
||||
"withdrawn_tokens": "36669.48305084571",
|
||||
"remaining_tokens": "17365.01694915429"
|
||||
"withdrawn_tokens": "48421.615684875225",
|
||||
"remaining_tokens": "5612.884315124775"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -51749,7 +51981,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "5778205.3912159303",
|
||||
"total_removed": "3353757.81738108986999524",
|
||||
"locked_amount": "287794.260969934471042521754104188",
|
||||
"locked_amount": "279854.0701367884731113185910330208",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "552496.6455",
|
||||
@@ -53844,7 +54076,7 @@
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "472355.6199999996",
|
||||
"total_removed": "35983.6942986130685",
|
||||
"locked_amount": "114199.22063145092350782298427196",
|
||||
"locked_amount": "113226.470016747764500428676509372",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "3000",
|
||||
@@ -83002,7 +83234,7 @@
|
||||
"tranche_start": "2021-12-05T00:00:00.000Z",
|
||||
"tranche_end": "2022-06-05T00:00:00.000Z",
|
||||
"total_added": "171288.42",
|
||||
"total_removed": "66601.1049690697989",
|
||||
"total_removed": "66803.5995794947989",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -87227,6 +87459,11 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "202.494610425",
|
||||
"user": "0x76bC9a132e27E9007c2adBfc92E65Bf0C5082B51",
|
||||
"tx": "0x8ca9ede6297f539eafe855fe5f55aef4cb8ca66630779c385285a56e995e9997"
|
||||
},
|
||||
{
|
||||
"amount": "225",
|
||||
"user": "0x18CB827d620aF4Eb847C32737d60e36489d7ECb2",
|
||||
@@ -90564,6 +90801,12 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "202.494610425",
|
||||
"user": "0x76bC9a132e27E9007c2adBfc92E65Bf0C5082B51",
|
||||
"tranche_id": 6,
|
||||
"tx": "0x8ca9ede6297f539eafe855fe5f55aef4cb8ca66630779c385285a56e995e9997"
|
||||
},
|
||||
{
|
||||
"amount": "47.505389575",
|
||||
"user": "0x76bC9a132e27E9007c2adBfc92E65Bf0C5082B51",
|
||||
@@ -90572,8 +90815,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "250",
|
||||
"withdrawn_tokens": "47.505389575",
|
||||
"remaining_tokens": "202.494610425"
|
||||
"withdrawn_tokens": "250",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0xb147d8B6804970f6fCb9EAc7f7Ec5A0aFCcFe5c2",
|
||||
|
||||
@@ -26,20 +26,20 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
|
||||
it('market price', () => {
|
||||
cy.getByTestId(marketTitle).contains('Market price').click();
|
||||
validateMarketDataRow(0, 'Mark Price', '0.05749');
|
||||
validateMarketDataRow(1, 'Best Bid Price', '6.81765 ');
|
||||
validateMarketDataRow(2, 'Best Offer Price', '6.81769 ');
|
||||
validateMarketDataRow(0, 'Mark Price', '46,126.90058');
|
||||
validateMarketDataRow(1, 'Best Bid Price', '44,126.90058 ');
|
||||
validateMarketDataRow(2, 'Best Offer Price', '48,126.90058 ');
|
||||
validateMarketDataRow(3, 'Quote Unit', 'BTC');
|
||||
});
|
||||
|
||||
it('market volume displayed', () => {
|
||||
cy.getByTestId(marketTitle).contains('Market volume').click();
|
||||
validateMarketDataRow(0, '24 Hour Volume', '-');
|
||||
validateMarketDataRow(0, '24 Hour Volume', '1');
|
||||
validateMarketDataRow(1, 'Open Interest', '0');
|
||||
validateMarketDataRow(2, 'Best Bid Volume', '5');
|
||||
validateMarketDataRow(3, 'Best Offer Volume', '1');
|
||||
validateMarketDataRow(4, 'Best Static Bid Volume', '5');
|
||||
validateMarketDataRow(5, 'Best Static Offer Volume', '1');
|
||||
validateMarketDataRow(2, 'Best Bid Volume', '1');
|
||||
validateMarketDataRow(3, 'Best Offer Volume', '3');
|
||||
validateMarketDataRow(4, 'Best Static Bid Volume', '2');
|
||||
validateMarketDataRow(5, 'Best Static Offer Volume', '4');
|
||||
});
|
||||
|
||||
it('insurance pool displayed', () => {
|
||||
@@ -149,9 +149,9 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
.contains(/Liquidity(?! m)/)
|
||||
.click();
|
||||
|
||||
validateMarketDataRow(0, 'Target Stake', '0.56789 tBTC');
|
||||
validateMarketDataRow(1, 'Supplied Stake', '0.56767 tBTC');
|
||||
validateMarketDataRow(2, 'Market Value Proxy', '6.77678 tBTC');
|
||||
validateMarketDataRow(0, 'Target Stake', '10.00 tBTC');
|
||||
validateMarketDataRow(1, 'Supplied Stake', '0.01 tBTC');
|
||||
validateMarketDataRow(2, 'Market Value Proxy', '20.00 tBTC');
|
||||
|
||||
cy.getByTestId('view-liquidity-link').should(
|
||||
'have.text',
|
||||
@@ -163,8 +163,8 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId(marketTitle).contains('Liquidity price range').click();
|
||||
|
||||
validateMarketDataRow(0, 'Liquidity Price Range', '2.00% of mid price');
|
||||
validateMarketDataRow(1, 'Lowest Price', '0.05634 BTC');
|
||||
validateMarketDataRow(2, 'Highest Price', '0.05864 BTC');
|
||||
validateMarketDataRow(1, 'Lowest Price', '45,204.362 BTC');
|
||||
validateMarketDataRow(2, 'Highest Price', '47,049.438 BTC');
|
||||
});
|
||||
|
||||
it('oracle displayed', () => {
|
||||
|
||||
@@ -38,7 +38,7 @@ describe('accounts', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId('tab-accounts')
|
||||
.get(tradingAccountRowId)
|
||||
.find('[col-id="deposited"]')
|
||||
.should('have.text', '1,001.00');
|
||||
.should('have.text', '100,001.01');
|
||||
});
|
||||
describe('sorting by ag-grid columns should work well', () => {
|
||||
it('sorting by asset', () => {
|
||||
@@ -58,24 +58,24 @@ describe('accounts', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId('Collateral').click();
|
||||
const marketsSortedDefault = [
|
||||
'1,000.00002',
|
||||
'1,001.00',
|
||||
'1,000.01',
|
||||
'100,001.01',
|
||||
'1,000.01',
|
||||
'1,000.00',
|
||||
'1,000.00001',
|
||||
];
|
||||
const marketsSortedAsc = [
|
||||
'1,000.00',
|
||||
'1,000.00001',
|
||||
'1,000.00002',
|
||||
'1,000.01',
|
||||
'1,000.01',
|
||||
'1,001.00',
|
||||
'100,001.01',
|
||||
];
|
||||
const marketsSortedDesc = [
|
||||
'1,001.00',
|
||||
'1,000.01',
|
||||
'100,001.01',
|
||||
'1,000.01',
|
||||
'1,000.00002',
|
||||
'1,000.00001',
|
||||
'1,000.00',
|
||||
];
|
||||
checkSorting(
|
||||
'deposited',
|
||||
@@ -87,9 +87,9 @@ describe('accounts', { tags: '@smoke' }, () => {
|
||||
|
||||
it('sorting by used', () => {
|
||||
cy.getByTestId('Collateral').click();
|
||||
const marketsSortedDefault = ['0.00', '1.00', '0.01', '0.01', '0.00'];
|
||||
const marketsSortedAsc = ['0.00', '0.00', '0.01', '0.01', '1.00'];
|
||||
const marketsSortedDesc = ['1.00', '0.01', '0.01', '0.00', '0.00'];
|
||||
const marketsSortedDefault = ['0.00', '1.01', '0.01', '0.00', '0.00'];
|
||||
const marketsSortedAsc = ['0.00', '0.00', '0.00', '0.01', '1.01'];
|
||||
const marketsSortedDesc = ['1.01', '0.01', '0.00', '0.00', '0.00'];
|
||||
checkSorting(
|
||||
'used',
|
||||
marketsSortedDefault,
|
||||
@@ -102,24 +102,24 @@ describe('accounts', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId('Collateral').click();
|
||||
const marketsSortedDefault = [
|
||||
'1,000.00002',
|
||||
'1,000.00',
|
||||
'100,000.00',
|
||||
'1,000.00',
|
||||
'1,000.00',
|
||||
'1,000.00001',
|
||||
];
|
||||
const marketsSortedAsc = [
|
||||
'1,000.00',
|
||||
'1,000.00',
|
||||
'1,000.00',
|
||||
'1,000.00001',
|
||||
'1,000.00002',
|
||||
'100,000.00',
|
||||
];
|
||||
const marketsSortedDesc = [
|
||||
'100,000.00',
|
||||
'1,000.00002',
|
||||
'1,000.00001',
|
||||
'1,000.00',
|
||||
'1,000.00',
|
||||
'1,000.00',
|
||||
];
|
||||
|
||||
checkSorting(
|
||||
|
||||
@@ -2,7 +2,11 @@ import * as Schema from '@vegaprotocol/types';
|
||||
import { aliasGQLQuery, mockConnectWallet } from '@vegaprotocol/cypress';
|
||||
import { testOrderSubmission } from '../support/order-validation';
|
||||
import type { OrderSubmission } from '@vegaprotocol/wallet';
|
||||
import { accountsQuery, estimateOrderQuery } from '@vegaprotocol/mock';
|
||||
import {
|
||||
accountsQuery,
|
||||
estimateOrderQuery,
|
||||
amendGeneralAccountBalance,
|
||||
} from '@vegaprotocol/mock';
|
||||
import { createOrder } from '../support/create-order';
|
||||
|
||||
const orderSizeField = 'order-size';
|
||||
@@ -583,6 +587,10 @@ describe('suspended market validation', { tags: '@regression' }, () => {
|
||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
||||
);
|
||||
const accounts = accountsQuery();
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'Accounts', accounts);
|
||||
});
|
||||
cy.mockSubscription();
|
||||
cy.visit('/#/markets/market-0');
|
||||
cy.wait('@Markets');
|
||||
@@ -632,30 +640,10 @@ describe('account validation', { tags: '@regression' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.setVegaWallet();
|
||||
cy.mockTradingPage();
|
||||
const accounts = accountsQuery();
|
||||
amendGeneralAccountBalance(accounts, 'market-0', '0');
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
'Accounts',
|
||||
accountsQuery({
|
||||
party: {
|
||||
accountsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '0',
|
||||
market: null,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-0',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
aliasGQLQuery(req, 'Accounts', accounts);
|
||||
});
|
||||
cy.mockSubscription();
|
||||
cy.visit('/#/markets/market-0');
|
||||
@@ -679,19 +667,13 @@ describe('account validation', { tags: '@regression' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.setVegaWallet();
|
||||
cy.mockTradingPage();
|
||||
const accounts = accountsQuery();
|
||||
amendGeneralAccountBalance(accounts, 'market-0', '100000000');
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
'EstimateOrder',
|
||||
estimateOrderQuery({
|
||||
estimateOrder: {
|
||||
marginLevels: {
|
||||
__typename: 'MarginLevels',
|
||||
initialLevel: '1000000000',
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
aliasGQLQuery(req, 'Accounts', accounts);
|
||||
});
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'EstimateOrder', estimateOrderQuery());
|
||||
});
|
||||
cy.mockSubscription();
|
||||
cy.visit('/#/markets/market-0');
|
||||
@@ -707,7 +689,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
||||
);
|
||||
cy.getByTestId('dealticket-warning-margin').should(
|
||||
'contain.text',
|
||||
'9,999.99 tDAI is currently required. You have only 1,000.00 tDAI available.Deposit tDAI'
|
||||
'You may not have enough margin available to open this position. 2,354.72283 tDAI is currently required. You have only 1,000.01 tDAI available.'
|
||||
);
|
||||
cy.getByTestId('deal-ticket-deposit-dialog-button').click();
|
||||
cy.getByTestId('dialog-content')
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('orders list', { tags: '@smoke' }, () => {
|
||||
cy.visit('/#/markets/market-0');
|
||||
cy.getByTestId('Orders').click();
|
||||
cy.wait('@Orders').then(() => {
|
||||
expect(subscriptionMocks.OrdersUpdate).to.be.calledTwice;
|
||||
expect(subscriptionMocks.OrdersUpdate).to.be.calledThrice;
|
||||
});
|
||||
cy.wait('@Markets');
|
||||
});
|
||||
@@ -136,7 +136,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
|
||||
cy.visit('/#/markets/market-0');
|
||||
cy.getByTestId('Orders').click();
|
||||
cy.wait('@Orders').then(() => {
|
||||
expect(subscriptionMocks.OrdersUpdate).to.be.calledTwice;
|
||||
expect(subscriptionMocks.OrdersUpdate).to.be.calledThrice;
|
||||
});
|
||||
});
|
||||
const orderId = '1234567890';
|
||||
@@ -354,7 +354,7 @@ describe('amend and cancel order', { tags: '@smoke' }, () => {
|
||||
cy.visit('/#/markets/market-0');
|
||||
cy.getByTestId('Orders').click();
|
||||
cy.wait('@Orders').then(() => {
|
||||
expect(subscriptionMocks.OrdersUpdate).to.be.calledTwice;
|
||||
expect(subscriptionMocks.OrdersUpdate).to.be.calledThrice;
|
||||
});
|
||||
cy.mockVegaWalletTransaction();
|
||||
});
|
||||
|
||||
@@ -164,10 +164,10 @@ describe('positions', { tags: '@smoke' }, () => {
|
||||
|
||||
cy.get('[col-id="liquidationPrice"]').should('contain.text', '0'); // liquidation price
|
||||
|
||||
cy.get('[col-id="currentLeverage"]').should('contain.text', '138.446.1');
|
||||
cy.get('[col-id="currentLeverage"]').should('contain.text', '2.846.1');
|
||||
|
||||
cy.get('[col-id="marginAccountBalance"]') // margin allocated
|
||||
.should('contain.text', '1,000');
|
||||
.should('contain.text', '0.01');
|
||||
|
||||
cy.get('[col-id="unrealisedPNL"]').each(($unrealisedPnl) => {
|
||||
cy.wrap($unrealisedPnl).invoke('text').should('not.be.empty');
|
||||
|
||||
@@ -17,6 +17,13 @@ describe('connect hosted wallet', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('can connect', () => {
|
||||
// 0002-WCON-002
|
||||
// 0002-WCON-003
|
||||
// 0002-WCON-039
|
||||
// 0002-WCON-017
|
||||
// 0002-WCON-018
|
||||
// 0002-WCON-019
|
||||
|
||||
// Mock authentication
|
||||
cy.intercept('POST', 'https://wallet.testnet.vega.xyz/api/v1/auth/token', {
|
||||
body: {
|
||||
@@ -41,6 +48,9 @@ describe('connect hosted wallet', { tags: '@smoke' }, () => {
|
||||
},
|
||||
});
|
||||
cy.getByTestId(connectVegaBtn).click();
|
||||
cy.contains(
|
||||
'Choose wallet app to connect, or to change port or server URL enter a custom wallet location first'
|
||||
);
|
||||
cy.contains('Connect Vega wallet');
|
||||
cy.contains('Hosted Fairground wallet');
|
||||
|
||||
@@ -51,9 +61,13 @@ describe('connect hosted wallet', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId(form).find('#passphrase').click().type('pass');
|
||||
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
|
||||
cy.getByTestId(manageVegaBtn).should('exist');
|
||||
cy.getByTestId('manage-vega-wallet').click();
|
||||
cy.getByTestId('keypair-list').should('exist');
|
||||
});
|
||||
|
||||
it('doesnt connect with invalid credentials', () => {
|
||||
// 0002-WCON-020
|
||||
|
||||
// Mock incorrect username/password
|
||||
cy.intercept('POST', 'https://wallet.testnet.vega.xyz/api/v1/auth/token', {
|
||||
body: {
|
||||
@@ -99,6 +113,10 @@ describe('connect vega wallet', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('can connect', () => {
|
||||
// 0002-WCON-002
|
||||
// 0002-WCON-005
|
||||
// 0002-WCON-007
|
||||
|
||||
mockConnectWallet();
|
||||
cy.getByTestId(connectVegaBtn).click();
|
||||
cy.getByTestId('connectors-list')
|
||||
@@ -110,16 +128,40 @@ describe('connect vega wallet', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('can change selected public key and disconnect', () => {
|
||||
// 0002-WCON-022
|
||||
// 0002-WCON-023
|
||||
// 0002-WCON-025
|
||||
// 0002-WCON-026
|
||||
// 0002-WCON-021
|
||||
// 0002-WCON-027
|
||||
// 0002-WCON-030
|
||||
// 0002-WCON-029
|
||||
// 0002-WCON-008
|
||||
// 0002-WCON-035
|
||||
// 0002-WCON-014
|
||||
// 0002-WCON-010
|
||||
|
||||
mockConnectWallet();
|
||||
const key2 = Cypress.env('VEGA_PUBLIC_KEY2');
|
||||
const truncatedKey2 = Cypress.env('TRUNCATED_VEGA_PUBLIC_KEY2');
|
||||
cy.connectVegaWallet();
|
||||
cy.getByTestId('manage-vega-wallet').click();
|
||||
cy.getByTestId('keypair-list').should('exist');
|
||||
cy.getByTestId(`key-${key2}`).should('contain.text', truncatedKey2);
|
||||
cy.getByTestId(`key-${key2}`)
|
||||
.find('[data-testid="copy-vega-public-key"]')
|
||||
.should('be.visible');
|
||||
cy.get(`[data-testid="key-${key2}"] > .mr-2`).click();
|
||||
cy.getByTestId('keypair-list')
|
||||
.find('[data-state="checked"]')
|
||||
.should('be.visible');
|
||||
cy.getByTestId('disconnect').click();
|
||||
cy.getByTestId('connect-vega-wallet').should('exist');
|
||||
cy.getByTestId('manage-vega-wallet').should('not.exist');
|
||||
cy.getByTestId('connect-vega-wallet').click();
|
||||
cy.contains(
|
||||
'Choose wallet app to connect, or to change port or server URL enter a custom wallet location first'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ import type { onMessage } from '@vegaprotocol/cypress';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import { orderUpdateSubscription } from '@vegaprotocol/mock';
|
||||
|
||||
let sendOrderUpdate: (data: OrdersUpdateSubscription) => void;
|
||||
const sendOrderUpdate: ((data: OrdersUpdateSubscription) => void)[] = [];
|
||||
const getOnOrderUpdate = () => {
|
||||
const onOrderUpdate: onMessage<
|
||||
OrdersUpdateSubscription,
|
||||
OrdersUpdateSubscriptionVariables
|
||||
> = (send) => {
|
||||
sendOrderUpdate = send;
|
||||
sendOrderUpdate.push(send);
|
||||
};
|
||||
return onOrderUpdate;
|
||||
};
|
||||
@@ -31,5 +31,5 @@ export function updateOrder(
|
||||
if (!sendOrderUpdate) {
|
||||
throw new Error('OrderSub not called');
|
||||
}
|
||||
sendOrderUpdate(update);
|
||||
sendOrderUpdate.forEach((send) => send(update));
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
} from '@vegaprotocol/mock';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type { MarketDataQuery, MarketsQuery } from '@vegaprotocol/market-list';
|
||||
import type { MarketInfoQuery } from '@vegaprotocol/market-info';
|
||||
|
||||
type MarketPageMockData = {
|
||||
state: Schema.MarketState;
|
||||
@@ -69,18 +68,6 @@ const marketsDataOverride = (
|
||||
},
|
||||
});
|
||||
|
||||
const marketInfoOverride = (
|
||||
data: MarketPageMockData
|
||||
): PartialDeep<MarketInfoQuery> => ({
|
||||
market: {
|
||||
state: data.state,
|
||||
tradingMode: data.tradingMode,
|
||||
data: {
|
||||
trigger: data.trigger,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const mockTradingPage = (
|
||||
req: CyHttpMessages.IncomingHttpRequest,
|
||||
state: Schema.MarketState = Schema.MarketState.STATE_ACTIVE,
|
||||
@@ -109,11 +96,7 @@ const mockTradingPage = (
|
||||
aliasGQLQuery(req, 'Margins', marginsQuery());
|
||||
aliasGQLQuery(req, 'Assets', assetsQuery());
|
||||
aliasGQLQuery(req, 'Asset', assetQuery());
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
'MarketInfo',
|
||||
marketInfoQuery(marketInfoOverride({ state, tradingMode, trigger }))
|
||||
);
|
||||
aliasGQLQuery(req, 'MarketInfo', marketInfoQuery());
|
||||
aliasGQLQuery(req, 'Trades', tradesQuery());
|
||||
aliasGQLQuery(req, 'Chart', chartQuery());
|
||||
aliasGQLQuery(req, 'Candles', candlesQuery());
|
||||
|
||||
@@ -12,6 +12,7 @@ export const Home = () => {
|
||||
// should be the oldest market that is currently trading in us mode(i.e. not in auction).
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider: marketsWithDataProvider,
|
||||
variables: undefined,
|
||||
});
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
const marketId = useGlobalStore((store) => store.marketId);
|
||||
|
||||
@@ -47,7 +47,8 @@ export const Liquidity = () => {
|
||||
const useReloadLiquidityData = (marketId: string | undefined) => {
|
||||
const { reload } = useDataProvider({
|
||||
dataProvider: liquidityProvisionsDataProvider,
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
variables: { marketId: marketId || '' },
|
||||
skip: !marketId,
|
||||
});
|
||||
useEffect(() => {
|
||||
const interval = setInterval(reload, 10000);
|
||||
@@ -77,7 +78,8 @@ export const LiquidityContainer = ({
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: lpAggregatedDataProvider,
|
||||
update,
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
variables: { marketId: marketId || '' },
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
const assetDecimalPlaces =
|
||||
@@ -161,7 +163,8 @@ export const LiquidityViewContainer = ({
|
||||
} = useDataProvider({
|
||||
dataProvider: lpAggregatedDataProvider,
|
||||
update,
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
variables: { marketId: marketId || '' },
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
const targetStake = marketData?.targetStake;
|
||||
|
||||
@@ -7,10 +7,6 @@ import {
|
||||
useThrottledDataProvider,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { AsyncRenderer, ExternalLink, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import type {
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment,
|
||||
} from '@vegaprotocol/market-list';
|
||||
|
||||
import { marketProvider, marketDataProvider } from '@vegaprotocol/market-list';
|
||||
import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||
@@ -35,13 +31,10 @@ const TitleUpdater = ({
|
||||
}) => {
|
||||
const pageTitle = usePageTitleStore((store) => store.pageTitle);
|
||||
const updateTitle = usePageTitleStore((store) => store.updateTitle);
|
||||
const { data: marketData } = useThrottledDataProvider<
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment
|
||||
>(
|
||||
const { data: marketData } = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketDataProvider,
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
variables: { marketId: marketId || '' },
|
||||
skip: !marketId,
|
||||
},
|
||||
1000
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { RefObject } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
import { isNumeric } from '@vegaprotocol/utils';
|
||||
import {
|
||||
@@ -9,7 +8,6 @@ import {
|
||||
import { PriceChangeCell } from '@vegaprotocol/datagrid';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { CandleClose } from '@vegaprotocol/types';
|
||||
import type { Candle } from '@vegaprotocol/market-list';
|
||||
import { marketCandlesProvider } from '@vegaprotocol/market-list';
|
||||
import { THROTTLE_UPDATE_TIME } from '../constants';
|
||||
|
||||
@@ -30,19 +28,14 @@ export const Last24hPriceChange = ({
|
||||
}: Props) => {
|
||||
const [ref, inView] = useInView({ root: inViewRoot?.current });
|
||||
const yesterday = useYesterday();
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId: marketId,
|
||||
interval: Schema.Interval.INTERVAL_I1H,
|
||||
since: new Date(yesterday).toISOString(),
|
||||
}),
|
||||
[marketId, yesterday]
|
||||
);
|
||||
|
||||
const { data, error } = useThrottledDataProvider<Candle[], Candle>(
|
||||
const { data, error } = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketCandlesProvider,
|
||||
variables,
|
||||
variables: {
|
||||
marketId: marketId || '',
|
||||
interval: Schema.Interval.INTERVAL_I1H,
|
||||
since: new Date(yesterday).toISOString(),
|
||||
},
|
||||
skip: !marketId || !inView,
|
||||
},
|
||||
THROTTLE_UPDATE_TIME
|
||||
|
||||
@@ -10,8 +10,6 @@ import {
|
||||
useYesterday,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { useMemo } from 'react';
|
||||
import type { Candle } from '@vegaprotocol/market-list';
|
||||
import { THROTTLE_UPDATE_TIME } from '../constants';
|
||||
|
||||
interface Props {
|
||||
@@ -32,19 +30,14 @@ export const Last24hVolume = ({
|
||||
const yesterday = useYesterday();
|
||||
const [ref, inView] = useInView({ root: inViewRoot?.current });
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId: marketId,
|
||||
interval: Schema.Interval.INTERVAL_I1H,
|
||||
since: new Date(yesterday).toISOString(),
|
||||
}),
|
||||
[marketId, yesterday]
|
||||
);
|
||||
|
||||
const { data } = useThrottledDataProvider<Candle[], Candle>(
|
||||
const { data } = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketCandlesProvider,
|
||||
variables,
|
||||
variables: {
|
||||
marketId: marketId || '',
|
||||
interval: Schema.Interval.INTERVAL_I1H,
|
||||
since: new Date(yesterday).toISOString(),
|
||||
},
|
||||
skip: !(inView && marketId),
|
||||
},
|
||||
THROTTLE_UPDATE_TIME
|
||||
|
||||
@@ -4,10 +4,7 @@ import {
|
||||
useDataProvider,
|
||||
useNetworkParams,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||
import { HeaderStat } from '../header';
|
||||
import {
|
||||
@@ -70,7 +67,7 @@ export const MarketLiquiditySupplied = ({
|
||||
[noUpdate]
|
||||
);
|
||||
|
||||
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
||||
useDataProvider({
|
||||
dataProvider: marketDataProvider,
|
||||
update,
|
||||
variables,
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import type { RefObject } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
import { addDecimalsFormatNumber, isNumeric } from '@vegaprotocol/utils';
|
||||
import { useThrottledDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { PriceCell } from '@vegaprotocol/datagrid';
|
||||
import type {
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { marketDataProvider } from '@vegaprotocol/market-list';
|
||||
import { THROTTLE_UPDATE_TIME } from '../constants';
|
||||
|
||||
@@ -27,15 +22,10 @@ export const MarketMarkPrice = ({
|
||||
asPriceCell,
|
||||
}: Props) => {
|
||||
const [ref, inView] = useInView({ root: inViewRoot?.current });
|
||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||
|
||||
const { data } = useThrottledDataProvider<
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment
|
||||
>(
|
||||
const { data } = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketDataProvider,
|
||||
variables,
|
||||
variables: { marketId: marketId || '' },
|
||||
skip: !inView,
|
||||
},
|
||||
THROTTLE_UPDATE_TIME
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import throttle from 'lodash/throttle';
|
||||
import type {
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment,
|
||||
Market,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import type { MarketData, Market } from '@vegaprotocol/market-list';
|
||||
import { marketDataProvider } from '@vegaprotocol/market-list';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { HeaderStat } from '../header';
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import * as constants from '../constants';
|
||||
|
||||
export const MarketState = ({ market }: { market: Market | null }) => {
|
||||
@@ -33,14 +29,10 @@ export const MarketState = ({ market }: { market: Market | null }) => {
|
||||
[throttledSetMarketState]
|
||||
);
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({ marketId: market?.id || '' }),
|
||||
[market?.id]
|
||||
);
|
||||
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
||||
useDataProvider({
|
||||
dataProvider: marketDataProvider,
|
||||
update,
|
||||
variables,
|
||||
variables: { marketId: market?.id || '' },
|
||||
skip: !market?.id,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||
import { HeaderStat } from '../header';
|
||||
import * as constants from '../constants';
|
||||
|
||||
export const MarketVolume = ({ marketId }: { marketId: string }) => {
|
||||
const [marketVolume, setMarketVolume] = useState<string>('-');
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId: marketId,
|
||||
}),
|
||||
[marketId]
|
||||
);
|
||||
const variables = { marketId };
|
||||
const { data } = useDataProvider({
|
||||
dataProvider: marketProvider,
|
||||
variables,
|
||||
@@ -46,7 +38,7 @@ export const MarketVolume = ({ marketId }: { marketId: string }) => {
|
||||
[data?.positionDecimalPlaces, throttledSetMarketVolume]
|
||||
);
|
||||
|
||||
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
||||
useDataProvider({
|
||||
dataProvider: marketDataProvider,
|
||||
update,
|
||||
variables,
|
||||
|
||||
@@ -106,14 +106,13 @@ export const SelectMarketPopover = ({
|
||||
loading: marketsLoading,
|
||||
reload: marketListReload,
|
||||
} = useMarketList();
|
||||
const variables = useMemo(() => ({ partyId: pubKey }), [pubKey]);
|
||||
const {
|
||||
data: positions,
|
||||
loading: positionsLoading,
|
||||
reload,
|
||||
} = useDataProvider({
|
||||
dataProvider: positionsDataProvider,
|
||||
variables,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
const onSelectMarket = useCallback(
|
||||
|
||||
@@ -20,6 +20,7 @@ export const WelcomeDialog = () => {
|
||||
const [riskAccepted] = useLocalStorage(constants.RISK_ACCEPTED_KEY);
|
||||
const { data } = useDataProvider({
|
||||
dataProvider: activeMarketsProvider,
|
||||
variables: undefined,
|
||||
});
|
||||
|
||||
const { update, shouldDisplayWelcomeDialog } = useGlobalStore((store) => ({
|
||||
|
||||
@@ -18,6 +18,7 @@ import type {
|
||||
AccountFieldsFragment,
|
||||
AccountsQuery,
|
||||
AccountEventsSubscription,
|
||||
AccountsQueryVariables,
|
||||
} from './__generated__/Accounts';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import type { Asset } from '@vegaprotocol/assets';
|
||||
@@ -85,7 +86,8 @@ export const accountsOnlyDataProvider = makeDataProvider<
|
||||
AccountsQuery,
|
||||
AccountFieldsFragment[],
|
||||
AccountEventsSubscription,
|
||||
AccountEventsSubscription['accounts']
|
||||
AccountEventsSubscription['accounts'],
|
||||
AccountsQueryVariables
|
||||
>({
|
||||
query: AccountsDocument,
|
||||
subscriptionQuery: AccountEventsDocument,
|
||||
@@ -159,8 +161,16 @@ const getAssetAccountAggregation = (
|
||||
return { ...balanceAccount, breakdown };
|
||||
};
|
||||
|
||||
export const accountsDataProvider = makeDerivedDataProvider<Account[], never>(
|
||||
[accountsOnlyDataProvider, marketsProvider, assetsProvider],
|
||||
export const accountsDataProvider = makeDerivedDataProvider<
|
||||
Account[],
|
||||
never,
|
||||
AccountsQueryVariables
|
||||
>(
|
||||
[
|
||||
accountsOnlyDataProvider,
|
||||
(callback, client) => marketsProvider(callback, client, undefined),
|
||||
(callback, client) => assetsProvider(callback, client, undefined),
|
||||
],
|
||||
([accounts, markets, assets]): Account[] | null => {
|
||||
return accounts
|
||||
? accounts
|
||||
@@ -194,7 +204,8 @@ export const accountsDataProvider = makeDerivedDataProvider<Account[], never>(
|
||||
|
||||
export const aggregatedAccountsDataProvider = makeDerivedDataProvider<
|
||||
AccountFields[],
|
||||
never
|
||||
never,
|
||||
AccountsQueryVariables
|
||||
>(
|
||||
[accountsDataProvider],
|
||||
(parts) => parts[0] && getAccountData(parts[0] as Account[])
|
||||
|
||||
@@ -31,10 +31,7 @@ export const AccountManager = ({
|
||||
}: AccountManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
const { data, loading, error, reload } = useDataProvider<
|
||||
AccountFields[],
|
||||
never
|
||||
>({
|
||||
const { data, loading, error, reload } = useDataProvider({
|
||||
dataProvider: aggregatedAccountsDataProvider,
|
||||
variables,
|
||||
});
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { forwardRef, useMemo, useState } from 'react';
|
||||
import { addDecimalsFormatNumber, isNumeric } from '@vegaprotocol/utils';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
isNumeric,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type {
|
||||
VegaICellRendererParams,
|
||||
VegaValueFormatterParams,
|
||||
VegaValueGetterParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { Button, ButtonLink, Dialog } from '@vegaprotocol/ui-toolkit';
|
||||
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
|
||||
@@ -117,17 +122,23 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
headerTooltip={t(
|
||||
'This is the total amount of collateral used plus the amount available in your general account.'
|
||||
)}
|
||||
valueGetter={({
|
||||
data,
|
||||
}: VegaValueGetterParams<AccountFields, 'deposited'>) => {
|
||||
return !data?.deposited
|
||||
? undefined
|
||||
: toBigNum(data.deposited, data.asset.decimals).toNumber();
|
||||
}}
|
||||
maxWidth={300}
|
||||
cellRenderer={({
|
||||
data,
|
||||
value,
|
||||
node,
|
||||
}: VegaICellRendererParams<AccountFields, 'deposited'>) => {
|
||||
const valueFormatted =
|
||||
data &&
|
||||
data.asset &&
|
||||
isNumeric(value) &&
|
||||
addDecimalsFormatNumber(value, data.asset.decimals);
|
||||
isNumeric(data.deposited) &&
|
||||
addDecimalsFormatNumber(data.deposited, data.asset.decimals);
|
||||
return node.rowPinned ? (
|
||||
<CenteredGridCellWrapper className="h-[30px] justify-end">
|
||||
{valueFormatted}
|
||||
@@ -144,17 +155,23 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
headerTooltip={t(
|
||||
'This is the amount of collateral used from your general account.'
|
||||
)}
|
||||
valueGetter={({
|
||||
data,
|
||||
}: VegaValueGetterParams<AccountFields, 'used'>) => {
|
||||
return !data?.used
|
||||
? undefined
|
||||
: toBigNum(data.used, data.asset.decimals).toNumber();
|
||||
}}
|
||||
maxWidth={300}
|
||||
cellRenderer={({
|
||||
data,
|
||||
value,
|
||||
node,
|
||||
}: VegaICellRendererParams<AccountFields, 'used'>) => {
|
||||
const valueFormatted =
|
||||
data &&
|
||||
data.asset &&
|
||||
isNumeric(value) &&
|
||||
addDecimalsFormatNumber(value, data.asset.decimals);
|
||||
isNumeric(data.used) &&
|
||||
addDecimalsFormatNumber(data.used, data.asset.decimals);
|
||||
return node.rowPinned ? (
|
||||
<CenteredGridCellWrapper className="h-[30px] justify-end">
|
||||
{valueFormatted}
|
||||
@@ -171,26 +188,31 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
headerTooltip={t(
|
||||
'This is the amount of collateral available in your general account.'
|
||||
)}
|
||||
valueGetter={({
|
||||
data,
|
||||
}: VegaValueGetterParams<AccountFields, 'available'>) => {
|
||||
return !data?.available
|
||||
? undefined
|
||||
: toBigNum(data.available, data.asset.decimals).toNumber();
|
||||
}}
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: VegaValueFormatterParams<AccountFields, 'available'>) =>
|
||||
data &&
|
||||
data.asset &&
|
||||
isNumeric(value) &&
|
||||
addDecimalsFormatNumber(value, data.asset.decimals)
|
||||
isNumeric(data.available) &&
|
||||
addDecimalsFormatNumber(data.available, data.asset.decimals)
|
||||
}
|
||||
maxWidth={300}
|
||||
cellRenderer={({
|
||||
data,
|
||||
value,
|
||||
node,
|
||||
}: VegaICellRendererParams<AccountFields, 'available'>) => {
|
||||
const valueFormatted =
|
||||
data &&
|
||||
data.asset &&
|
||||
isNumeric(value) &&
|
||||
addDecimalsFormatNumber(value, data.asset.decimals);
|
||||
isNumeric(data.available) &&
|
||||
addDecimalsFormatNumber(data.available, data.asset.decimals);
|
||||
return node.rowPinned ? (
|
||||
<CenteredGridCellWrapper className="h-[30px] justify-end">
|
||||
{valueFormatted}
|
||||
|
||||
@@ -43,10 +43,6 @@ export const accountFields: AccountFieldsFragment[] = [
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
market: {
|
||||
id: 'market-0',
|
||||
__typename: 'Market',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id-2',
|
||||
@@ -75,7 +71,7 @@ export const accountFields: AccountFieldsFragment[] = [
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id-2',
|
||||
id: 'asset-0',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -94,7 +90,7 @@ export const accountFields: AccountFieldsFragment[] = [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
balance: '10000000000',
|
||||
market: null,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
@@ -141,3 +137,25 @@ export const accountEventsSubscription = (
|
||||
};
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
export const amendGeneralAccountBalance = (
|
||||
accounts: AccountsQuery,
|
||||
marketId: string,
|
||||
balance: string
|
||||
) => {
|
||||
if (accounts.party?.accountsConnection?.edges) {
|
||||
const marginAccount = accounts.party.accountsConnection.edges.find(
|
||||
(edge) => edge?.node.market?.id === marketId
|
||||
);
|
||||
if (marginAccount) {
|
||||
const generalAccount = accounts.party.accountsConnection.edges.find(
|
||||
(edge) =>
|
||||
edge?.node.asset.id === marginAccount.node.asset.id &&
|
||||
!edge?.node.market
|
||||
);
|
||||
if (generalAccount) {
|
||||
generalAccount.node.balance = balance;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ export const TransferContainer = () => {
|
||||
const { param } = useNetworkParam(NetworkParams.transfer_fee_factor);
|
||||
const { data } = useDataProvider({
|
||||
dataProvider: accountsDataProvider,
|
||||
variables: { partyId: pubKey },
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
const create = useVegaTransactionStore((store) => store.create);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { makeDataProvider } from '@vegaprotocol/utils';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import type { AssetQuery, AssetFieldsFragment } from './__generated__/Asset';
|
||||
import type {
|
||||
AssetQuery,
|
||||
AssetFieldsFragment,
|
||||
AssetQueryVariables,
|
||||
} from './__generated__/Asset';
|
||||
import { AssetDocument } from './__generated__/Asset';
|
||||
|
||||
export type Asset = AssetFieldsFragment;
|
||||
@@ -15,21 +18,21 @@ export const getData = (responseData: AssetQuery | null | undefined) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const assetProvider = makeDataProvider<AssetQuery, Asset, never, never>({
|
||||
export const assetProvider = makeDataProvider<
|
||||
AssetQuery,
|
||||
Asset,
|
||||
never,
|
||||
never,
|
||||
AssetQueryVariables
|
||||
>({
|
||||
query: AssetDocument,
|
||||
getData,
|
||||
});
|
||||
|
||||
export const useAssetDataProvider = (assetId: string) => {
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
assetId,
|
||||
}),
|
||||
[assetId]
|
||||
);
|
||||
return useDataProvider({
|
||||
dataProvider: assetProvider,
|
||||
variables,
|
||||
variables: { assetId: assetId || '' },
|
||||
skip: !assetId,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -40,4 +40,5 @@ export const enabledAssetsProvider = makeDerivedDataProvider<
|
||||
export const useAssetsDataProvider = () =>
|
||||
useDataProvider({
|
||||
dataProvider: assetsProvider,
|
||||
variables: undefined,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { formatNumber } from '@vegaprotocol/utils';
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Notification, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { useDepositDialog } from '@vegaprotocol/deposits';
|
||||
@@ -19,14 +19,14 @@ export const MarginWarning = ({ margin, balance, asset }: Props) => {
|
||||
<Notification
|
||||
intent={Intent.Warning}
|
||||
testId="dealticket-warning-margin"
|
||||
message={`You may not have enough margin available to open this position. ${formatNumber(
|
||||
message={`You may not have enough margin available to open this position. ${addDecimalsFormatNumber(
|
||||
margin,
|
||||
asset.decimals
|
||||
)} ${asset.symbol} ${t(
|
||||
'is currently required. You have only'
|
||||
)} ${formatNumber(balance, asset.decimals)} ${asset.symbol} ${t(
|
||||
'available.'
|
||||
)}`}
|
||||
)} ${addDecimalsFormatNumber(balance, asset.decimals)} ${
|
||||
asset.symbol
|
||||
} ${t('available.')}`}
|
||||
buttonProps={{
|
||||
text: t(`Deposit ${asset.symbol}`),
|
||||
action: () => openDepositDialog(asset.id),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useMemo } from 'react';
|
||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useThrottledDataProvider } from '@vegaprotocol/react-helpers';
|
||||
@@ -29,7 +28,7 @@ export const DealTicketContainer = ({
|
||||
} = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketDataProvider,
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
variables: { marketId },
|
||||
},
|
||||
1000
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||
import {
|
||||
@@ -12,22 +11,51 @@ interface DealTicketFeeDetailsProps {
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
market: Market;
|
||||
marketData: MarketData;
|
||||
margin: string;
|
||||
totalMargin: string;
|
||||
balance: string;
|
||||
}
|
||||
|
||||
export interface DealTicketFeeDetails {
|
||||
export interface DealTicketFeeDetailProps {
|
||||
label: string;
|
||||
value?: string | number | null;
|
||||
labelDescription?: string | ReactNode;
|
||||
symbol?: string;
|
||||
}
|
||||
|
||||
export const DealTicketFeeDetail = ({
|
||||
label,
|
||||
value,
|
||||
labelDescription,
|
||||
symbol,
|
||||
}: DealTicketFeeDetailProps) => (
|
||||
<div className="text-xs mt-2 flex justify-between items-center gap-4 flex-wrap">
|
||||
<div>
|
||||
<Tooltip description={labelDescription}>
|
||||
<div>{label}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="text-neutral-500 dark:text-neutral-300">{`${value ?? '-'} ${
|
||||
symbol || ''
|
||||
}`}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const DealTicketFeeDetails = ({
|
||||
order,
|
||||
market,
|
||||
marketData,
|
||||
margin,
|
||||
totalMargin,
|
||||
balance,
|
||||
}: DealTicketFeeDetailsProps) => {
|
||||
const feeDetails = useFeeDealTicketDetails(order, market, marketData);
|
||||
const details = useMemo(() => getFeeDetailsValues(feeDetails), [feeDetails]);
|
||||
const details = getFeeDetailsValues({
|
||||
...feeDetails,
|
||||
margin,
|
||||
totalMargin,
|
||||
balance,
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
{details.map(({ label, value, labelDescription, symbol }) => (
|
||||
|
||||
@@ -21,8 +21,7 @@ import {
|
||||
Intent,
|
||||
Notification,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useOrderMarginValidation } from '../../hooks/use-order-margin-validation';
|
||||
import { MarginWarning } from '../deal-ticket-validation/margin-warning';
|
||||
|
||||
import {
|
||||
validateExpiration,
|
||||
validateMarketState,
|
||||
@@ -32,11 +31,16 @@ import {
|
||||
} from '../../utils';
|
||||
import { ZeroBalanceError } from '../deal-ticket-validation/zero-balance-error';
|
||||
import { SummaryValidationType } from '../../constants';
|
||||
import { useHasNoBalance } from '../../hooks/use-has-no-balance';
|
||||
import { useInitialMargin } from '../../hooks/use-initial-margin';
|
||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||
import { MarginWarning } from '../deal-ticket-validation/margin-warning';
|
||||
import {
|
||||
useMarketAccountBalance,
|
||||
useAccountBalance,
|
||||
} from '@vegaprotocol/accounts';
|
||||
|
||||
import { OrderTimeInForce, OrderType } from '@vegaprotocol/types';
|
||||
import { useOrderForm } from '../../hooks/use-order-form';
|
||||
import type { OrderObj } from '@vegaprotocol/orders';
|
||||
|
||||
export interface DealTicketProps {
|
||||
market: Market;
|
||||
@@ -67,17 +71,41 @@ export const DealTicket = ({
|
||||
update,
|
||||
handleSubmit,
|
||||
} = useOrderForm(market.id);
|
||||
const marketStateError = validateMarketState(marketData.marketState);
|
||||
const hasNoBalance = useHasNoBalance(
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id
|
||||
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
||||
const { accountBalance: marginAccountBalance } = useMarketAccountBalance(
|
||||
market.id
|
||||
);
|
||||
const { accountBalance: generalAccountBalance } = useAccountBalance(asset.id);
|
||||
const balance = (
|
||||
BigInt(marginAccountBalance) + BigInt(generalAccountBalance)
|
||||
).toString();
|
||||
|
||||
const marketStateError = validateMarketState(marketData.marketState);
|
||||
const hasNoBalance = generalAccountBalance === '0';
|
||||
const marketTradingModeError = validateMarketTradingMode(
|
||||
marketData.marketTradingMode
|
||||
);
|
||||
|
||||
const normalizedOrder =
|
||||
order &&
|
||||
normalizeOrderSubmission(
|
||||
order,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces
|
||||
);
|
||||
|
||||
const { margin, totalMargin } = useInitialMargin(
|
||||
market.id,
|
||||
normalizedOrder?.size,
|
||||
order?.side
|
||||
);
|
||||
|
||||
const checkForErrors = useCallback(() => {
|
||||
if (!pubKey) {
|
||||
setError('summary', { message: t('No public key selected') });
|
||||
setError('summary', {
|
||||
message: t('No public key selected'),
|
||||
type: SummaryValidationType.NoPubKey,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -114,6 +142,7 @@ export const DealTicket = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
(pubKey && errors.summary?.type === SummaryValidationType.NoPubKey) ||
|
||||
(!hasNoBalance &&
|
||||
errors.summary?.type === SummaryValidationType.NoCollateral) ||
|
||||
(marketStateError === true &&
|
||||
@@ -125,6 +154,7 @@ export const DealTicket = ({
|
||||
}
|
||||
checkForErrors();
|
||||
}, [
|
||||
pubKey,
|
||||
hasNoBalance,
|
||||
marketStateError,
|
||||
marketTradingModeError,
|
||||
@@ -254,9 +284,10 @@ export const DealTicket = ({
|
||||
)}
|
||||
<SummaryMessage
|
||||
errorMessage={errors.summary?.message}
|
||||
market={market}
|
||||
marketData={marketData}
|
||||
order={order}
|
||||
asset={asset}
|
||||
marketTradingMode={marketData.marketTradingMode}
|
||||
balance={balance}
|
||||
margin={totalMargin}
|
||||
isReadOnly={isReadOnly}
|
||||
pubKey={pubKey}
|
||||
onClickCollateral={onClickCollateral}
|
||||
@@ -266,9 +297,16 @@ export const DealTicket = ({
|
||||
variant={order.side === Schema.Side.SIDE_BUY ? 'ternary' : 'secondary'}
|
||||
/>
|
||||
<DealTicketFeeDetails
|
||||
order={order}
|
||||
order={normalizeOrderSubmission(
|
||||
order,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces
|
||||
)}
|
||||
market={market}
|
||||
marketData={marketData}
|
||||
margin={margin}
|
||||
totalMargin={totalMargin}
|
||||
balance={marginAccountBalance}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
@@ -280,9 +318,10 @@ export const DealTicket = ({
|
||||
*/
|
||||
interface SummaryMessageProps {
|
||||
errorMessage?: string;
|
||||
market: Market;
|
||||
marketData: MarketData;
|
||||
order: OrderObj;
|
||||
asset: { id: string; symbol: string; name: string; decimals: number };
|
||||
marketTradingMode: MarketData['marketTradingMode'];
|
||||
balance: string;
|
||||
margin: string;
|
||||
isReadOnly: boolean;
|
||||
pubKey: string | null;
|
||||
onClickCollateral?: () => void;
|
||||
@@ -290,22 +329,17 @@ interface SummaryMessageProps {
|
||||
const SummaryMessage = memo(
|
||||
({
|
||||
errorMessage,
|
||||
market,
|
||||
marketData,
|
||||
order,
|
||||
asset,
|
||||
marketTradingMode,
|
||||
balance,
|
||||
margin,
|
||||
isReadOnly,
|
||||
pubKey,
|
||||
onClickCollateral,
|
||||
}: SummaryMessageProps) => {
|
||||
// Specific error UI for if balance is so we can
|
||||
// render a deposit dialog
|
||||
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
||||
const assetSymbol = asset.symbol;
|
||||
const { balanceError, balance, margin } = useOrderMarginValidation({
|
||||
market,
|
||||
marketData,
|
||||
order,
|
||||
});
|
||||
const openVegaWalletDialog = useVegaWalletDialogStore(
|
||||
(store) => store.openVegaWalletDialog
|
||||
);
|
||||
@@ -349,7 +383,7 @@ const SummaryMessage = memo(
|
||||
return (
|
||||
<div className="mb-2">
|
||||
<ZeroBalanceError
|
||||
asset={market.tradableInstrument.instrument.product.settlementAsset}
|
||||
asset={asset}
|
||||
onClickCollateral={onClickCollateral}
|
||||
/>
|
||||
</div>
|
||||
@@ -370,21 +404,16 @@ const SummaryMessage = memo(
|
||||
|
||||
// If there is no blocking error but user doesn't have enough
|
||||
// balance render the margin warning, but still allow submission
|
||||
if (balanceError) {
|
||||
return (
|
||||
<div className="mb-2">
|
||||
<MarginWarning balance={balance} margin={margin} asset={asset} />
|
||||
</div>
|
||||
);
|
||||
if (BigInt(balance) < BigInt(margin)) {
|
||||
return <MarginWarning balance={balance} margin={margin} asset={asset} />;
|
||||
}
|
||||
|
||||
// Show auction mode warning
|
||||
if (
|
||||
[
|
||||
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||
].includes(marketData.marketTradingMode)
|
||||
].includes(marketTradingMode)
|
||||
) {
|
||||
return (
|
||||
<div className="mb-2">
|
||||
|
||||
@@ -55,6 +55,7 @@ export const MarketSelector = ({ market, setMarket, ItemRenderer }: Props) => {
|
||||
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: marketsProvider,
|
||||
variables: undefined,
|
||||
skipUpdates: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -7,6 +7,15 @@ export const EST_MARGIN_TOOLTIP_TEXT = (settlementAsset: string) =>
|
||||
For example, for a notional size of $500, if the margin requirement is 10%, then the estimated margin would be approximately $50.`,
|
||||
[settlementAsset]
|
||||
);
|
||||
export const EST_TOTAL_MARGIN_TOOLTIP_TEXT = t(
|
||||
'Estimated total margin that will cover open position, active orders and this order.'
|
||||
);
|
||||
export const MARGIN_ACCOUNT_TOOLTIP_TEXT = t('Margin account balance');
|
||||
export const MARGIN_DIFF_TOOLTIP_TEXT = (settlementAsset: string) =>
|
||||
t(
|
||||
"The additional margin required for your new position (taking into account volume and open orders), compared to your current margin. Measured in the market's settlement asset ($s).",
|
||||
[settlementAsset]
|
||||
);
|
||||
export const CONTRACTS_MARGIN_TOOLTIP_TEXT = t(
|
||||
'The number of contracts determines how many units of the futures contract to buy or sell. For example, this is similar to buying one share of a listed company. The value of 1 contract is equivalent to the price of the contract. For example, if the current price is $50, then one contract is worth $50.'
|
||||
);
|
||||
@@ -41,6 +50,7 @@ export enum MarketModeValidationType {
|
||||
}
|
||||
|
||||
export enum SummaryValidationType {
|
||||
NoPubKey = 'NoPubKey',
|
||||
NoCollateral = 'NoCollateral',
|
||||
TradingMode = 'MarketTradingMode',
|
||||
MarketState = 'MarketState',
|
||||
|
||||
@@ -4,5 +4,3 @@ export * from './use-fee-deal-ticket-details';
|
||||
export * from './use-market-positions';
|
||||
export * from './use-maximum-position-size';
|
||||
export * from './use-order-closeout';
|
||||
export * from './use-order-margin';
|
||||
export * from './use-order-margin-validation';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useMemo } from 'react';
|
||||
import { marketDepthProvider } from '@vegaprotocol/market-depth';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
@@ -13,11 +12,10 @@ interface Props {
|
||||
}
|
||||
|
||||
export const useCalculateSlippage = ({ market, order }: Props) => {
|
||||
const variables = useMemo(() => ({ marketId: market.id }), [market.id]);
|
||||
const { data } = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketDepthProvider,
|
||||
variables,
|
||||
variables: { marketId: market.id },
|
||||
},
|
||||
1000
|
||||
);
|
||||
|
||||
@@ -3,24 +3,26 @@ import {
|
||||
addDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
formatNumber,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { useMemo } from 'react';
|
||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
EST_CLOSEOUT_TOOLTIP_TEXT,
|
||||
EST_MARGIN_TOOLTIP_TEXT,
|
||||
// EST_MARGIN_TOOLTIP_TEXT,
|
||||
EST_TOTAL_MARGIN_TOOLTIP_TEXT,
|
||||
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||
MARGIN_ACCOUNT_TOOLTIP_TEXT,
|
||||
MARGIN_DIFF_TOOLTIP_TEXT,
|
||||
} from '../constants';
|
||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
||||
import { useOrderCloseOut } from './use-order-closeout';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
import type { OrderMargin } from './use-order-margin';
|
||||
import { useMarketAccountBalance } from '@vegaprotocol/accounts';
|
||||
import { getDerivedPrice } from '../utils/get-price';
|
||||
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||
import type { EstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||
|
||||
export const useFeeDealTicketDetails = (
|
||||
order: OrderSubmissionBody['orderSubmission'],
|
||||
@@ -28,33 +30,23 @@ export const useFeeDealTicketDetails = (
|
||||
marketData: MarketData
|
||||
) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const slippage = useCalculateSlippage({ market, order });
|
||||
const { accountBalance } = useMarketAccountBalance(market.id);
|
||||
|
||||
const derivedPrice = useMemo(() => {
|
||||
return getDerivedPrice(order, market, marketData);
|
||||
}, [order, market, marketData]);
|
||||
const price = useMemo(() => {
|
||||
return getDerivedPrice(order, marketData);
|
||||
}, [order, marketData]);
|
||||
|
||||
// Note this isn't currently used anywhere
|
||||
const slippageAdjustedPrice = useMemo(() => {
|
||||
if (derivedPrice) {
|
||||
if (slippage && parseFloat(slippage) !== 0) {
|
||||
const isLong = order.side === Schema.Side.SIDE_BUY;
|
||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
||||
parseFloat(slippage) / 100
|
||||
);
|
||||
return new BigNumber(derivedPrice).multipliedBy(multiplier).toNumber();
|
||||
}
|
||||
return derivedPrice;
|
||||
}
|
||||
return null;
|
||||
}, [derivedPrice, order.side, slippage]);
|
||||
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
marketData,
|
||||
partyId: pubKey || '',
|
||||
derivedPrice,
|
||||
const { data: estMargin } = useEstimateOrderQuery({
|
||||
variables: {
|
||||
marketId: market.id,
|
||||
partyId: pubKey || '',
|
||||
price,
|
||||
size: order.size,
|
||||
side: order.side,
|
||||
timeInForce: order.timeInForce,
|
||||
type: order.type,
|
||||
},
|
||||
skip: !pubKey || !market || !order.size || !price,
|
||||
});
|
||||
|
||||
const estCloseOut = useOrderCloseOut({
|
||||
@@ -64,13 +56,13 @@ export const useFeeDealTicketDetails = (
|
||||
});
|
||||
|
||||
const notionalSize = useMemo(() => {
|
||||
if (derivedPrice && order.size) {
|
||||
return new BigNumber(order.size)
|
||||
.multipliedBy(addDecimal(derivedPrice, market.decimalPlaces))
|
||||
if (price && order.size) {
|
||||
return toBigNum(order.size, market.positionDecimalPlaces)
|
||||
.multipliedBy(addDecimal(price, market.decimalPlaces))
|
||||
.toString();
|
||||
}
|
||||
return null;
|
||||
}, [derivedPrice, order.size, market.decimalPlaces]);
|
||||
}, [price, order.size, market.decimalPlaces, market.positionDecimalPlaces]);
|
||||
|
||||
const assetSymbol =
|
||||
market.tradableInstrument.instrument.product.settlementAsset.symbol;
|
||||
@@ -80,37 +72,40 @@ export const useFeeDealTicketDetails = (
|
||||
market,
|
||||
assetSymbol,
|
||||
notionalSize,
|
||||
estMargin,
|
||||
accountBalance,
|
||||
estimateOrder: estMargin?.estimateOrder,
|
||||
estCloseOut,
|
||||
slippage,
|
||||
slippageAdjustedPrice,
|
||||
};
|
||||
}, [
|
||||
market,
|
||||
assetSymbol,
|
||||
notionalSize,
|
||||
accountBalance,
|
||||
estMargin,
|
||||
estCloseOut,
|
||||
slippage,
|
||||
slippageAdjustedPrice,
|
||||
]);
|
||||
};
|
||||
|
||||
export interface FeeDetails {
|
||||
balance: string;
|
||||
market: Market;
|
||||
assetSymbol: string;
|
||||
notionalSize: string | null;
|
||||
estMargin: OrderMargin | null;
|
||||
estCloseOut: string | null;
|
||||
slippage: string | null;
|
||||
estimateOrder: EstimateOrderQuery['estimateOrder'] | undefined;
|
||||
margin: string;
|
||||
totalMargin: string;
|
||||
}
|
||||
|
||||
export const getFeeDetailsValues = ({
|
||||
balance,
|
||||
assetSymbol,
|
||||
notionalSize,
|
||||
estMargin,
|
||||
estCloseOut,
|
||||
estimateOrder,
|
||||
margin,
|
||||
market,
|
||||
notionalSize,
|
||||
totalMargin,
|
||||
}: FeeDetails) => {
|
||||
const assetDecimals =
|
||||
market.tradableInstrument.instrument.product.settlementAsset.decimals;
|
||||
@@ -129,7 +124,12 @@ export const getFeeDetailsValues = ({
|
||||
? addDecimalsFormatNumber(value, assetDecimals)
|
||||
: '-';
|
||||
};
|
||||
return [
|
||||
const details: {
|
||||
label: string;
|
||||
value?: string | null;
|
||||
symbol: string;
|
||||
labelDescription: React.ReactNode;
|
||||
}[] = [
|
||||
{
|
||||
label: t('Notional'),
|
||||
value: formatValueWithMarketDp(notionalSize),
|
||||
@@ -139,8 +139,8 @@ export const getFeeDetailsValues = ({
|
||||
{
|
||||
label: t('Fees'),
|
||||
value:
|
||||
estMargin?.totalFees &&
|
||||
`~${formatValueWithAssetDp(estMargin?.totalFees)}`,
|
||||
estimateOrder?.totalFeeAmount &&
|
||||
`~${formatValueWithAssetDp(estimateOrder?.totalFeeAmount)}`,
|
||||
labelDescription: (
|
||||
<>
|
||||
<span>
|
||||
@@ -149,7 +149,7 @@ export const getFeeDetailsValues = ({
|
||||
)}
|
||||
</span>
|
||||
<FeesBreakdown
|
||||
fees={estMargin?.fees}
|
||||
fees={estimateOrder?.fee}
|
||||
feeFactors={market.fees.factors}
|
||||
symbol={assetSymbol}
|
||||
decimals={assetDecimals}
|
||||
@@ -158,18 +158,46 @@ export const getFeeDetailsValues = ({
|
||||
),
|
||||
symbol: assetSymbol,
|
||||
},
|
||||
/*
|
||||
{
|
||||
label: t('Margin'),
|
||||
value:
|
||||
estMargin?.margin && `~${formatValueWithAssetDp(estMargin?.margin)}`,
|
||||
label: t('Initial margin'),
|
||||
value: margin && `~${formatValueWithAssetDp(margin)}`,
|
||||
symbol: assetSymbol,
|
||||
labelDescription: EST_MARGIN_TOOLTIP_TEXT(assetSymbol),
|
||||
},
|
||||
*/
|
||||
{
|
||||
label: t('Liquidation'),
|
||||
value: estCloseOut && `~${formatValueWithMarketDp(estCloseOut)}`,
|
||||
symbol: market.tradableInstrument.instrument.product.quoteName,
|
||||
labelDescription: EST_CLOSEOUT_TOOLTIP_TEXT(quoteName),
|
||||
label: t('Margin required'),
|
||||
value: `~${formatValueWithAssetDp(
|
||||
balance
|
||||
? (BigInt(totalMargin) - BigInt(balance)).toString()
|
||||
: totalMargin
|
||||
)}`,
|
||||
symbol: assetSymbol,
|
||||
labelDescription: MARGIN_DIFF_TOOLTIP_TEXT(assetSymbol),
|
||||
},
|
||||
];
|
||||
if (balance) {
|
||||
details.push({
|
||||
label: t('Projected margin'),
|
||||
value: `~${formatValueWithAssetDp(totalMargin)}`,
|
||||
symbol: assetSymbol,
|
||||
labelDescription: EST_TOTAL_MARGIN_TOOLTIP_TEXT,
|
||||
});
|
||||
}
|
||||
details.push({
|
||||
label: t('Current margin allocation'),
|
||||
value: balance
|
||||
? `~${formatValueWithAssetDp(balance)}`
|
||||
: `${formatValueWithAssetDp(balance)}`,
|
||||
symbol: assetSymbol,
|
||||
labelDescription: MARGIN_ACCOUNT_TOOLTIP_TEXT,
|
||||
});
|
||||
details.push({
|
||||
label: t('Liquidation'),
|
||||
value: estCloseOut && `~${formatValueWithMarketDp(estCloseOut)}`,
|
||||
symbol: market.tradableInstrument.instrument.product.quoteName,
|
||||
labelDescription: EST_CLOSEOUT_TOOLTIP_TEXT(quoteName),
|
||||
});
|
||||
return details;
|
||||
};
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
import { toBigNum } from '@vegaprotocol/utils';
|
||||
|
||||
export const useHasNoBalance = (assetId: string) => {
|
||||
const { accountBalance, accountDecimals } = useAccountBalance(assetId);
|
||||
const balance =
|
||||
accountBalance && accountDecimals !== null
|
||||
? toBigNum(accountBalance, accountDecimals)
|
||||
: toBigNum('0', 0);
|
||||
return balance.isZero();
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { marketDataProvider } from '@vegaprotocol/market-list';
|
||||
import {
|
||||
calculateMargins,
|
||||
// getDerivedPrice,
|
||||
volumeAndMarginProvider,
|
||||
} from '@vegaprotocol/positions';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { marketInfoProvider } from '@vegaprotocol/market-info';
|
||||
|
||||
export const useInitialMargin = (
|
||||
marketId: OrderSubmissionBody['orderSubmission']['marketId'],
|
||||
size?: OrderSubmissionBody['orderSubmission']['size'],
|
||||
side?: OrderSubmissionBody['orderSubmission']['side']
|
||||
) => {
|
||||
const { pubKey: partyId } = useVegaWallet();
|
||||
const commonVariables = { marketId, partyId: partyId || '' };
|
||||
const { data: marketData } = useDataProvider({
|
||||
dataProvider: marketDataProvider,
|
||||
variables: { marketId },
|
||||
});
|
||||
const { data: activeVolumeAndMargin } = useDataProvider({
|
||||
dataProvider: volumeAndMarginProvider,
|
||||
variables: commonVariables,
|
||||
skip: !partyId,
|
||||
});
|
||||
const { data: marketInfo } = useDataProvider({
|
||||
dataProvider: marketInfoProvider,
|
||||
variables: commonVariables,
|
||||
});
|
||||
let totalMargin = '0';
|
||||
let margin = '0';
|
||||
if (marketInfo?.riskFactors && marketData && size && side) {
|
||||
const {
|
||||
positionDecimalPlaces,
|
||||
decimalPlaces,
|
||||
tradableInstrument,
|
||||
riskFactors,
|
||||
} = marketInfo;
|
||||
const { marginCalculator, instrument } = tradableInstrument;
|
||||
const { decimals } = instrument.product.settlementAsset;
|
||||
margin = totalMargin = calculateMargins({
|
||||
side,
|
||||
size,
|
||||
price: marketData.markPrice, // getDerivedPrice(order, marketData), same in positions-data-providers
|
||||
positionDecimalPlaces,
|
||||
decimalPlaces,
|
||||
decimals,
|
||||
scalingFactors: marginCalculator?.scalingFactors,
|
||||
riskFactors,
|
||||
}).initialMargin;
|
||||
}
|
||||
|
||||
if (activeVolumeAndMargin) {
|
||||
let sellMargin = BigInt(activeVolumeAndMargin.sellInitialMargin);
|
||||
let buyMargin = BigInt(activeVolumeAndMargin.buyInitialMargin);
|
||||
if (side === Side.SIDE_SELL) {
|
||||
sellMargin += BigInt(totalMargin);
|
||||
} else {
|
||||
buyMargin += BigInt(totalMargin);
|
||||
}
|
||||
totalMargin =
|
||||
sellMargin > buyMargin ? sellMargin.toString() : buyMargin.toString();
|
||||
}
|
||||
|
||||
return useMemo(() => ({ totalMargin, margin }), [totalMargin, margin]);
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { toBigNum } from '@vegaprotocol/utils';
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||
|
||||
interface Props {
|
||||
market: Market;
|
||||
marketData: MarketData;
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
}
|
||||
|
||||
export const useOrderMarginValidation = ({
|
||||
market,
|
||||
marketData,
|
||||
order,
|
||||
}: Props) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
marketData,
|
||||
partyId: pubKey || '',
|
||||
});
|
||||
const { id: assetId, decimals: assetDecimals } =
|
||||
market.tradableInstrument.instrument.product.settlementAsset;
|
||||
|
||||
const { accountBalance, accountDecimals } = useAccountBalance(assetId);
|
||||
const balance =
|
||||
accountBalance && accountDecimals !== null
|
||||
? toBigNum(accountBalance, accountDecimals)
|
||||
: toBigNum('0', assetDecimals);
|
||||
const margin = toBigNum(estMargin?.margin || 0, assetDecimals);
|
||||
|
||||
// return only simple types (bool, string) for make memo sensible
|
||||
const balanceError = balance.isGreaterThan(0) && balance.isLessThan(margin);
|
||||
const balanceAsString = balance.toString();
|
||||
const marginAsString = margin.toString();
|
||||
return useMemo(() => {
|
||||
return {
|
||||
balance: balanceAsString,
|
||||
margin: marginAsString,
|
||||
balanceError,
|
||||
};
|
||||
}, [balanceAsString, marginAsString, balanceError]);
|
||||
};
|
||||
@@ -1,116 +0,0 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { PositionMargin } from './use-market-positions';
|
||||
import type { Props } from './use-order-margin';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||
|
||||
let mockEstimateData = {
|
||||
estimateOrder: {
|
||||
fee: {
|
||||
makerFee: '100000.000',
|
||||
infrastructureFee: '100000.000',
|
||||
liquidityFee: '100000.000',
|
||||
},
|
||||
marginLevels: {
|
||||
initialLevel: '200000',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
jest.mock('@apollo/client', () => ({
|
||||
...jest.requireActual('@apollo/client'),
|
||||
useQuery: jest.fn(() => ({ data: mockEstimateData })),
|
||||
}));
|
||||
|
||||
let mockMarketPositions: PositionMargin = {
|
||||
openVolume: '1',
|
||||
balance: '100000',
|
||||
};
|
||||
|
||||
jest.mock('./use-market-positions', () => ({
|
||||
useMarketPositions: ({
|
||||
marketId,
|
||||
partyId,
|
||||
}: {
|
||||
marketId: string;
|
||||
partyId: string;
|
||||
}) => mockMarketPositions,
|
||||
}));
|
||||
|
||||
describe('useOrderMargin', () => {
|
||||
const marketId = 'marketId';
|
||||
const args: Props = {
|
||||
order: {
|
||||
marketId,
|
||||
size: '2',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_IOC,
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
},
|
||||
market: {
|
||||
id: marketId,
|
||||
decimalPlaces: 2,
|
||||
positionDecimalPlaces: 0,
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
} as unknown as Market,
|
||||
marketData: {
|
||||
indicativePrice: '100',
|
||||
markPrice: '200',
|
||||
} as unknown as MarketData,
|
||||
partyId: 'partyId',
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should calculate margin correctly', () => {
|
||||
const { result } = renderHook(() => useOrderMargin(args));
|
||||
expect(result.current?.margin).toEqual('100000');
|
||||
expect((useQuery as jest.Mock).mock.calls[0][1].variables.size).toEqual(
|
||||
args.order.size
|
||||
);
|
||||
});
|
||||
|
||||
it('should calculate fees correctly', () => {
|
||||
const { result } = renderHook(() => useOrderMargin(args));
|
||||
expect(result.current?.totalFees).toEqual('300000');
|
||||
});
|
||||
|
||||
it('should not subtract initialMargin if there is no position', () => {
|
||||
mockMarketPositions = null;
|
||||
const { result } = renderHook(() => useOrderMargin(args));
|
||||
expect(result.current?.margin).toEqual('200000');
|
||||
|
||||
expect((useQuery as jest.Mock).mock.calls[0][1].variables.size).toEqual(
|
||||
args.order.size
|
||||
);
|
||||
});
|
||||
|
||||
it('should return empty value if API fails', () => {
|
||||
mockEstimateData = {
|
||||
estimateOrder: {
|
||||
fee: {
|
||||
makerFee: '100000.000',
|
||||
infrastructureFee: '100000.000',
|
||||
liquidityFee: '100000.000',
|
||||
},
|
||||
marginLevels: {
|
||||
initialLevel: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
const { result } = renderHook(() => useOrderMargin(args));
|
||||
expect(result.current).toEqual(null);
|
||||
|
||||
const calledSize = new BigNumber(mockMarketPositions?.openVolume || 0)
|
||||
.plus(args.order.size)
|
||||
.toString();
|
||||
expect((useQuery as jest.Mock).mock.calls[0][1].variables.size).toEqual(
|
||||
calledSize
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,76 +0,0 @@
|
||||
import { useMemo } from 'react';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { removeDecimal } from '@vegaprotocol/utils';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||
import { getDerivedPrice } from '../utils/get-price';
|
||||
|
||||
export interface Props {
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
market: Market;
|
||||
marketData: MarketData;
|
||||
partyId: string;
|
||||
derivedPrice?: string;
|
||||
}
|
||||
|
||||
export interface OrderMargin {
|
||||
margin: string;
|
||||
totalFees: string | null;
|
||||
fees: {
|
||||
makerFee: string;
|
||||
liquidityFee: string;
|
||||
infrastructureFee: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const useOrderMargin = ({
|
||||
order,
|
||||
market,
|
||||
marketData,
|
||||
partyId,
|
||||
derivedPrice,
|
||||
}: Props): OrderMargin | null => {
|
||||
const { balance } = useMarketPositions({ marketId: market.id }) || {};
|
||||
const priceForEstimate =
|
||||
derivedPrice || getDerivedPrice(order, market, marketData);
|
||||
|
||||
const { data } = useEstimateOrderQuery({
|
||||
variables: {
|
||||
marketId: market.id,
|
||||
partyId,
|
||||
price: priceForEstimate,
|
||||
size: removeDecimal(order.size, market.positionDecimalPlaces),
|
||||
side: order.side,
|
||||
timeInForce: order.timeInForce,
|
||||
type: order.type,
|
||||
},
|
||||
skip: !partyId || !market.id || !order.size || !priceForEstimate,
|
||||
});
|
||||
const { makerFee, liquidityFee, infrastructureFee } = data?.estimateOrder
|
||||
.fee || { makerFee: '', liquidityFee: '', infrastructureFee: '' };
|
||||
const { initialLevel } = data?.estimateOrder.marginLevels ?? {};
|
||||
return useMemo(() => {
|
||||
if (initialLevel) {
|
||||
const margin = BigNumber.maximum(
|
||||
0,
|
||||
new BigNumber(initialLevel).minus(balance || 0)
|
||||
).toString();
|
||||
const fees = new BigNumber(makerFee)
|
||||
.plus(liquidityFee)
|
||||
.plus(infrastructureFee)
|
||||
.toString();
|
||||
return {
|
||||
margin,
|
||||
totalFees: fees,
|
||||
fees: {
|
||||
makerFee,
|
||||
liquidityFee,
|
||||
infrastructureFee,
|
||||
},
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}, [initialLevel, makerFee, liquidityFee, infrastructureFee, balance]);
|
||||
};
|
||||
@@ -64,20 +64,27 @@ export function generateMarketData(
|
||||
id: 'market-id',
|
||||
__typename: 'Market',
|
||||
},
|
||||
auctionStart: '2022-06-21T17:18:43.484055236Z',
|
||||
auctionEnd: '2022-06-21T17:18:43.484055236Z',
|
||||
targetStake: '1000000',
|
||||
suppliedStake: '1000',
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
staticMidPrice: '0',
|
||||
indicativePrice: '100',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '10',
|
||||
auctionStart: '2022-06-21T17:18:43.484055236Z',
|
||||
bestBidPrice: '0',
|
||||
bestBidVolume: '0',
|
||||
bestOfferPrice: '0',
|
||||
bestOfferVolume: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticBidVolume: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
bestStaticOfferVolume: '0',
|
||||
indicativePrice: '100',
|
||||
indicativeVolume: '10',
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketValueProxy: '',
|
||||
markPrice: '200',
|
||||
midPrice: '0',
|
||||
openInterest: '',
|
||||
staticMidPrice: '0',
|
||||
suppliedStake: '1000',
|
||||
targetStake: '1000000',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_BATCH,
|
||||
};
|
||||
return merge(defaultMarketData, override);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { removeDecimal } from '@vegaprotocol/utils';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { isMarketInAuction } from './is-market-in-auction';
|
||||
import type { MarketData, Market } from '@vegaprotocol/market-list';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
|
||||
/**
|
||||
* Get the market price based on market mode (auction or not auction)
|
||||
@@ -34,7 +33,6 @@ export const getDerivedPrice = (
|
||||
type: Schema.OrderType;
|
||||
price?: string | undefined;
|
||||
},
|
||||
market: Market,
|
||||
marketData: MarketData
|
||||
) => {
|
||||
// If order type is market we should use either the mark price
|
||||
@@ -44,7 +42,7 @@ export const getDerivedPrice = (
|
||||
// Use the market price if order is a market order
|
||||
let price;
|
||||
if (order.type === Schema.OrderType.TYPE_LIMIT && order.price) {
|
||||
price = removeDecimal(order.price, market.decimalPlaces);
|
||||
price = order.price;
|
||||
} else {
|
||||
price = getMarketPrice(marketData);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ export const DepositContainer = ({ assetId }: { assetId?: string }) => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: enabledAssetsProvider,
|
||||
variables: undefined,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -13,6 +13,7 @@ import type { PageInfo, Edge } from '@vegaprotocol/utils';
|
||||
import { FillsDocument, FillsEventDocument } from './__generated__/Fills';
|
||||
import type {
|
||||
FillsQuery,
|
||||
FillsQueryVariables,
|
||||
FillFieldsFragment,
|
||||
FillEdgeFragment,
|
||||
FillsEventSubscription,
|
||||
@@ -62,13 +63,19 @@ export type TradeEdge = Edge<Trade>;
|
||||
const getData = (responseData: FillsQuery | null): FillEdgeFragment[] =>
|
||||
responseData?.party?.tradesConnection?.edges || [];
|
||||
|
||||
const getPageInfo = (responseData: FillsQuery): PageInfo | null =>
|
||||
responseData.party?.tradesConnection?.pageInfo || null;
|
||||
const getPageInfo = (responseData: FillsQuery | null): PageInfo | null =>
|
||||
responseData?.party?.tradesConnection?.pageInfo || null;
|
||||
|
||||
const getDelta = (subscriptionData: FillsEventSubscription) =>
|
||||
subscriptionData.trades || [];
|
||||
|
||||
export const fillsProvider = makeDataProvider({
|
||||
export const fillsProvider = makeDataProvider<
|
||||
Parameters<typeof getData>['0'],
|
||||
ReturnType<typeof getData>,
|
||||
Parameters<typeof getDelta>['0'],
|
||||
ReturnType<typeof getDelta>,
|
||||
FillsQueryVariables
|
||||
>({
|
||||
query: FillsDocument,
|
||||
subscriptionQuery: FillsEventDocument,
|
||||
update,
|
||||
@@ -83,9 +90,13 @@ export const fillsProvider = makeDataProvider({
|
||||
|
||||
export const fillsWithMarketProvider = makeDerivedDataProvider<
|
||||
(TradeEdge | null)[],
|
||||
Trade[]
|
||||
Trade[],
|
||||
FillsQueryVariables
|
||||
>(
|
||||
[fillsProvider, marketsProvider],
|
||||
[
|
||||
fillsProvider,
|
||||
(callback, client) => marketsProvider(callback, client, undefined),
|
||||
],
|
||||
(partsData): (TradeEdge | null)[] =>
|
||||
(partsData[0] as ReturnType<typeof getData>)?.map(
|
||||
(edge) =>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { RefObject } from 'react';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { useCallback, useMemo, useRef } from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { makeInfiniteScrollGetRows } from '@vegaprotocol/utils';
|
||||
import { useDataProvider, updateGridData } from '@vegaprotocol/react-helpers';
|
||||
import type { Trade, TradeEdge } from './fills-data-provider';
|
||||
@@ -73,16 +73,11 @@ export const useFillsList = ({
|
||||
[gridRef]
|
||||
);
|
||||
|
||||
const variables = useMemo(() => ({ partyId, marketId }), [partyId, marketId]);
|
||||
|
||||
const { data, error, loading, load, totalCount, reload } = useDataProvider<
|
||||
(TradeEdge | null)[],
|
||||
Trade[]
|
||||
>({
|
||||
const { data, error, loading, load, totalCount, reload } = useDataProvider({
|
||||
dataProvider: fillsWithMarketProvider,
|
||||
update,
|
||||
insert,
|
||||
variables,
|
||||
variables: { partyId, marketId: marketId || '' },
|
||||
});
|
||||
totalCountRef.current = totalCount;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ export const update = (
|
||||
data: ReturnType<typeof getData> | null,
|
||||
delta: ReturnType<typeof getData>,
|
||||
reload: () => void,
|
||||
variables?: LedgerEntriesQueryVariables
|
||||
variables: LedgerEntriesQueryVariables
|
||||
) => {
|
||||
if (!data) {
|
||||
return data;
|
||||
@@ -110,8 +110,8 @@ export const ledgerEntriesProvider = makeDerivedDataProvider<
|
||||
>(
|
||||
[
|
||||
ledgerEntriesOnlyProvider,
|
||||
(callback, client) => assetsProvider(callback, client),
|
||||
marketsProvider,
|
||||
(callback, client) => assetsProvider(callback, client, undefined),
|
||||
(callback, client) => marketsProvider(callback, client, undefined),
|
||||
],
|
||||
([entries, assets, markets]) => {
|
||||
return entries.map((edge: AggregatedLedgerEntriesEdge) => {
|
||||
|
||||
@@ -14,11 +14,14 @@ import {
|
||||
|
||||
import type {
|
||||
MarketLpQuery,
|
||||
MarketLpQueryVariables,
|
||||
LiquidityProviderFeeShareFieldsFragment,
|
||||
LiquidityProviderFeeShareQuery,
|
||||
LiquidityProviderFeeShareQueryVariables,
|
||||
LiquidityProviderFeeShareUpdateSubscription,
|
||||
LiquidityProvisionFieldsFragment,
|
||||
LiquidityProvisionsQuery,
|
||||
LiquidityProvisionsQueryVariables,
|
||||
LiquidityProvisionsUpdateSubscription,
|
||||
} from './__generated__/MarketLiquidity';
|
||||
import type { IterableElement } from 'type-fest';
|
||||
@@ -27,7 +30,8 @@ export const liquidityProvisionsDataProvider = makeDataProvider<
|
||||
LiquidityProvisionsQuery,
|
||||
LiquidityProvisionFieldsFragment[],
|
||||
LiquidityProvisionsUpdateSubscription,
|
||||
LiquidityProvisionsUpdateSubscription['liquidityProvisions']
|
||||
LiquidityProvisionsUpdateSubscription['liquidityProvisions'],
|
||||
LiquidityProvisionsQueryVariables
|
||||
>({
|
||||
query: LiquidityProvisionsDocument,
|
||||
subscriptionQuery: LiquidityProvisionsUpdateDocument,
|
||||
@@ -99,7 +103,8 @@ export const marketLiquidityDataProvider = makeDataProvider<
|
||||
MarketLpQuery,
|
||||
MarketLpQuery,
|
||||
never,
|
||||
never
|
||||
never,
|
||||
MarketLpQueryVariables
|
||||
>({
|
||||
query: MarketLpDocument,
|
||||
getData: (responseData: MarketLpQuery | null) => {
|
||||
@@ -111,7 +116,8 @@ export const liquidityFeeShareDataProvider = makeDataProvider<
|
||||
LiquidityProviderFeeShareQuery,
|
||||
LiquidityProviderFeeShareFieldsFragment[],
|
||||
LiquidityProviderFeeShareUpdateSubscription,
|
||||
LiquidityProviderFeeShareUpdateSubscription['marketsData'][0]['liquidityProviderFeeShare']
|
||||
LiquidityProviderFeeShareUpdateSubscription['marketsData'][0]['liquidityProviderFeeShare'],
|
||||
LiquidityProviderFeeShareQueryVariables
|
||||
>({
|
||||
query: LiquidityProviderFeeShareDocument,
|
||||
subscriptionQuery: LiquidityProviderFeeShareUpdateDocument,
|
||||
@@ -147,7 +153,11 @@ export const liquidityFeeShareDataProvider = makeDataProvider<
|
||||
},
|
||||
});
|
||||
|
||||
export const lpAggregatedDataProvider = makeDerivedDataProvider(
|
||||
export const lpAggregatedDataProvider = makeDerivedDataProvider<
|
||||
ReturnType<typeof getLiquidityProvision>,
|
||||
never,
|
||||
MarketLpQueryVariables
|
||||
>(
|
||||
[
|
||||
liquidityProvisionsDataProvider,
|
||||
marketLiquidityDataProvider,
|
||||
|
||||
@@ -5,12 +5,10 @@ import { useDataProvider, useYesterday } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
MarketCandles,
|
||||
MarketMaybeWithDataAndCandles,
|
||||
MarketsCandlesQueryVariables,
|
||||
} from '@vegaprotocol/market-list';
|
||||
|
||||
import {
|
||||
marketsCandlesProvider,
|
||||
marketListProvider,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { marketListProvider } from '@vegaprotocol/market-list';
|
||||
|
||||
import type { LiquidityProvisionMarketsQuery } from './__generated__/MarketsLiquidity';
|
||||
import { LiquidityProvisionMarketsDocument } from './__generated__/MarketsLiquidity';
|
||||
@@ -97,15 +95,18 @@ export const liquidityMarketsProvider = makeDataProvider<
|
||||
getData,
|
||||
});
|
||||
|
||||
const liquidityProvisionProvider = makeDerivedDataProvider<Market[], never>(
|
||||
const liquidityProvisionProvider = makeDerivedDataProvider<
|
||||
Market[],
|
||||
never,
|
||||
Exclude<MarketsCandlesQueryVariables, 'interval'>
|
||||
>(
|
||||
[
|
||||
marketListProvider,
|
||||
(callback, client, variables) =>
|
||||
marketsCandlesProvider(callback, client, {
|
||||
...variables,
|
||||
marketListProvider(callback, client, {
|
||||
since: variables.since,
|
||||
interval: Schema.Interval.INTERVAL_I1D,
|
||||
}),
|
||||
liquidityMarketsProvider,
|
||||
(callback, client) => liquidityMarketsProvider(callback, client, undefined),
|
||||
],
|
||||
(parts) => {
|
||||
return addData(
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('market depth provider update', () => {
|
||||
sequenceNumber: '',
|
||||
previousSequenceNumber: '',
|
||||
};
|
||||
const updatedData = update(data, [delta], reload);
|
||||
const updatedData = update(data, [delta], reload, { marketId: '1' });
|
||||
expect(updatedData).toBe(data);
|
||||
});
|
||||
|
||||
@@ -54,8 +54,12 @@ describe('market depth provider update', () => {
|
||||
previousSequenceNumber: '',
|
||||
},
|
||||
];
|
||||
expect(update(data, delta.slice(0, 1), reload)).toBe(data);
|
||||
expect(update(data, delta.slice(1, 2), reload)).toBe(data);
|
||||
expect(update(data, delta.slice(0, 1), reload, { marketId: '1' })).toBe(
|
||||
data
|
||||
);
|
||||
expect(update(data, delta.slice(1, 2), reload, { marketId: '1' })).toBe(
|
||||
data
|
||||
);
|
||||
});
|
||||
|
||||
it('restarts and captureException when there is gap in updates', () => {
|
||||
@@ -72,7 +76,7 @@ describe('market depth provider update', () => {
|
||||
previousSequenceNumber: '12',
|
||||
},
|
||||
];
|
||||
const updatedData = update(data, delta, reload);
|
||||
const updatedData = update(data, delta, reload, { marketId: '1' });
|
||||
expect(updatedData).toBe(data);
|
||||
expect(reload).toBeCalled();
|
||||
expect(mockCaptureException).toBeCalled();
|
||||
|
||||
@@ -9,12 +9,14 @@ import {
|
||||
} from './__generated__/MarketDepth';
|
||||
import type {
|
||||
MarketDepthQuery,
|
||||
MarketDepthQueryVariables,
|
||||
MarketDepthUpdateSubscription,
|
||||
} from './__generated__/MarketDepth';
|
||||
|
||||
export const update: Update<
|
||||
ReturnType<typeof getData>,
|
||||
ReturnType<typeof getDelta>
|
||||
ReturnType<typeof getDelta>,
|
||||
MarketDepthQueryVariables
|
||||
> = (data, deltas, reload) => {
|
||||
if (!data) {
|
||||
return data;
|
||||
@@ -61,12 +63,19 @@ export const update: Update<
|
||||
return data;
|
||||
};
|
||||
|
||||
const getData = (responseData: MarketDepthQuery | null) => responseData?.market;
|
||||
const getData = (responseData: MarketDepthQuery | null) =>
|
||||
responseData?.market || null;
|
||||
|
||||
const getDelta = (subscriptionData: MarketDepthUpdateSubscription) =>
|
||||
subscriptionData.marketsDepthUpdate;
|
||||
|
||||
export const marketDepthProvider = makeDataProvider({
|
||||
export const marketDepthProvider = makeDataProvider<
|
||||
MarketDepthQuery,
|
||||
ReturnType<typeof getData>,
|
||||
MarketDepthUpdateSubscription,
|
||||
ReturnType<typeof getDelta>,
|
||||
MarketDepthQueryVariables
|
||||
>({
|
||||
query: MarketDepthDocument,
|
||||
subscriptionQuery: MarketDepthUpdateDocument,
|
||||
update,
|
||||
|
||||
@@ -7,12 +7,13 @@ import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { marketDepthProvider } from './market-depth-provider';
|
||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import type {
|
||||
MarketDepthUpdateSubscription,
|
||||
MarketDepthQuery,
|
||||
PriceLevelFieldsFragment,
|
||||
MarketDepthQueryVariables,
|
||||
} from './__generated__/MarketDepth';
|
||||
import type { PriceLevelFieldsFragment } from './__generated__/MarketDepth';
|
||||
import {
|
||||
compactRows,
|
||||
updateCompactedRows,
|
||||
@@ -28,7 +29,7 @@ interface OrderbookManagerProps {
|
||||
|
||||
export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
||||
const [resolution, setResolution] = useState(1);
|
||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||
const variables = { marketId };
|
||||
const resolutionRef = useRef(resolution);
|
||||
const [orderbookData, setOrderbookData] = useState<OrderbookData>({
|
||||
rows: null,
|
||||
@@ -79,8 +80,8 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
||||
delta: deltas,
|
||||
data: rawData,
|
||||
}: {
|
||||
delta?: MarketDepthUpdateSubscription['marketsDepthUpdate'];
|
||||
data?: MarketDepthQuery['market'];
|
||||
delta?: MarketDepthUpdateSubscription['marketsDepthUpdate'] | null;
|
||||
data: NonNullable<MarketDepthQuery['market']> | null | undefined;
|
||||
}) => {
|
||||
if (!dataRef.current.rows) {
|
||||
return false;
|
||||
@@ -103,7 +104,11 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
||||
[marketId, updateOrderbookData]
|
||||
);
|
||||
|
||||
const { data, error, loading, flush, reload } = useDataProvider({
|
||||
const { data, error, loading, flush, reload } = useDataProvider<
|
||||
MarketDepthQuery['market'] | undefined,
|
||||
MarketDepthUpdateSubscription['marketsDepthUpdate'] | null,
|
||||
MarketDepthQueryVariables
|
||||
>({
|
||||
dataProvider: marketDepthProvider,
|
||||
update,
|
||||
variables,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { totalFeesPercentage } from '@vegaprotocol/market-list';
|
||||
import type { TradeFee, FeeFactors } from '@vegaprotocol/types';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
formatNumberPercentage,
|
||||
@@ -7,12 +8,7 @@ import { t } from '@vegaprotocol/i18n';
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
export const FeesCell = ({
|
||||
feeFactors,
|
||||
}: {
|
||||
feeFactors: Market['fees']['factors'];
|
||||
}) => (
|
||||
export const FeesCell = ({ feeFactors }: { feeFactors: FeeFactors }) => (
|
||||
<Tooltip description={<FeesBreakdownPercentage feeFactors={feeFactors} />}>
|
||||
<span>{totalFeesPercentage(feeFactors) ?? '-'}</span>
|
||||
</Tooltip>
|
||||
@@ -21,7 +17,7 @@ export const FeesCell = ({
|
||||
export const FeesBreakdownPercentage = ({
|
||||
feeFactors,
|
||||
}: {
|
||||
feeFactors?: Market['fees']['factors'];
|
||||
feeFactors?: FeeFactors;
|
||||
}) => {
|
||||
if (!feeFactors) return null;
|
||||
return (
|
||||
@@ -54,12 +50,8 @@ export const FeesBreakdown = ({
|
||||
symbol,
|
||||
decimals,
|
||||
}: {
|
||||
fees?: {
|
||||
infrastructureFee: string;
|
||||
liquidityFee: string;
|
||||
makerFee: string;
|
||||
};
|
||||
feeFactors?: Market['fees']['factors'];
|
||||
fees?: TradeFee;
|
||||
feeFactors?: FeeFactors;
|
||||
symbol?: string;
|
||||
decimals: number;
|
||||
}) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
query MarketInfo($marketId: ID!, $interval: Interval!, $since: String!) {
|
||||
query MarketInfo($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
id
|
||||
decimalPlaces
|
||||
@@ -32,7 +32,6 @@ query MarketInfo($marketId: ID!, $interval: Interval!, $since: String!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
tradingMode
|
||||
fees {
|
||||
factors {
|
||||
makerFee
|
||||
@@ -54,35 +53,6 @@ query MarketInfo($marketId: ID!, $interval: Interval!, $since: String!) {
|
||||
short
|
||||
long
|
||||
}
|
||||
data {
|
||||
market {
|
||||
id
|
||||
}
|
||||
markPrice
|
||||
midPrice
|
||||
bestBidVolume
|
||||
bestOfferVolume
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferVolume
|
||||
bestBidPrice
|
||||
bestOfferPrice
|
||||
trigger
|
||||
openInterest
|
||||
suppliedStake
|
||||
openInterest
|
||||
targetStake
|
||||
marketValueProxy
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
}
|
||||
liquidityMonitoringParameters {
|
||||
triggeringRatio
|
||||
targetStakeParameters {
|
||||
@@ -90,13 +60,6 @@ query MarketInfo($marketId: ID!, $interval: Interval!, $since: String!) {
|
||||
scalingFactor
|
||||
}
|
||||
}
|
||||
candlesConnection(interval: $interval, since: $since) {
|
||||
edges {
|
||||
node {
|
||||
volume
|
||||
}
|
||||
}
|
||||
}
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
id
|
||||
@@ -144,10 +107,12 @@ query MarketInfo($marketId: ID!, $interval: Interval!, $since: String!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
depth {
|
||||
lastTrade {
|
||||
price
|
||||
marginCalculator {
|
||||
scalingFactors {
|
||||
searchLevel
|
||||
initialMargin
|
||||
collateralRelease
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
query MarketInfoNoCandles($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
id
|
||||
decimalPlaces
|
||||
positionDecimalPlaces
|
||||
state
|
||||
tradingMode
|
||||
lpPriceRange
|
||||
proposal {
|
||||
id
|
||||
rationale {
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
marketTimestamps {
|
||||
open
|
||||
close
|
||||
}
|
||||
openingAuction {
|
||||
durationSecs
|
||||
volume
|
||||
}
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
asset {
|
||||
id
|
||||
}
|
||||
balance
|
||||
}
|
||||
}
|
||||
}
|
||||
tradingMode
|
||||
fees {
|
||||
factors {
|
||||
makerFee
|
||||
infrastructureFee
|
||||
liquidityFee
|
||||
}
|
||||
}
|
||||
priceMonitoringSettings {
|
||||
parameters {
|
||||
triggers {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
}
|
||||
}
|
||||
riskFactors {
|
||||
market
|
||||
short
|
||||
long
|
||||
}
|
||||
data {
|
||||
market {
|
||||
id
|
||||
}
|
||||
markPrice
|
||||
midPrice
|
||||
bestBidVolume
|
||||
bestOfferVolume
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferVolume
|
||||
bestBidPrice
|
||||
bestOfferPrice
|
||||
trigger
|
||||
openInterest
|
||||
suppliedStake
|
||||
openInterest
|
||||
targetStake
|
||||
marketValueProxy
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
}
|
||||
liquidityMonitoringParameters {
|
||||
triggeringRatio
|
||||
targetStakeParameters {
|
||||
timeWindow
|
||||
scalingFactor
|
||||
}
|
||||
}
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
id
|
||||
name
|
||||
code
|
||||
metadata {
|
||||
tags
|
||||
}
|
||||
product {
|
||||
... on Future {
|
||||
quoteName
|
||||
settlementAsset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
dataSourceSpecForSettlementData {
|
||||
id
|
||||
}
|
||||
dataSourceSpecForTradingTermination {
|
||||
id
|
||||
}
|
||||
dataSourceSpecBinding {
|
||||
settlementDataProperty
|
||||
tradingTerminationProperty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
riskModel {
|
||||
... on LogNormalRiskModel {
|
||||
tau
|
||||
riskAversionParameter
|
||||
params {
|
||||
r
|
||||
sigma
|
||||
mu
|
||||
}
|
||||
}
|
||||
... on SimpleRiskModel {
|
||||
params {
|
||||
factorLong
|
||||
factorShort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
depth {
|
||||
lastTrade {
|
||||
price
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,14 @@ import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type MarketInfoQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
interval: Types.Interval;
|
||||
since: Types.Scalars['String'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketInfoQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, lpPriceRange: string, proposal?: { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any }, openingAuction: { __typename?: 'AuctionDuration', durationSecs: number, volume: number }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string } } } | null> | null } | null, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, priceMonitoringSettings: { __typename?: 'PriceMonitoringSettings', parameters?: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null } | null }, riskFactors?: { __typename?: 'RiskFactor', market: string, short: string, long: string } | null, data?: { __typename?: 'MarketData', markPrice: string, midPrice: string, bestBidVolume: string, bestOfferVolume: string, bestStaticBidVolume: string, bestStaticOfferVolume: string, bestBidPrice: string, bestOfferPrice: string, trigger: Types.AuctionTrigger, openInterest: string, suppliedStake?: string | null, targetStake?: string | null, marketValueProxy: string, market: { __typename?: 'Market', id: string }, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null } | null, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: string, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, candlesConnection?: { __typename?: 'CandleDataConnection', edges?: Array<{ __typename?: 'CandleEdge', node: { __typename?: 'Candle', volume: string } } | null> | null } | null, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } }, riskModel: { __typename?: 'LogNormalRiskModel', tau: number, riskAversionParameter: number, params: { __typename?: 'LogNormalModelParams', r: number, sigma: number, mu: number } } | { __typename?: 'SimpleRiskModel', params: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } } }, depth: { __typename?: 'MarketDepth', lastTrade?: { __typename?: 'Trade', price: string } | null } } | null };
|
||||
export type MarketInfoQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, lpPriceRange: string, proposal?: { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any }, openingAuction: { __typename?: 'AuctionDuration', durationSecs: number, volume: number }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string } } } | null> | null } | null, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, priceMonitoringSettings: { __typename?: 'PriceMonitoringSettings', parameters?: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null } | null }, riskFactors?: { __typename?: 'RiskFactor', market: string, short: string, long: string } | null, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: string, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } }, riskModel: { __typename?: 'LogNormalRiskModel', tau: number, riskAversionParameter: number, params: { __typename?: 'LogNormalModelParams', r: number, sigma: number, mu: number } } | { __typename?: 'SimpleRiskModel', params: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } }, marginCalculator?: { __typename?: 'MarginCalculator', scalingFactors: { __typename?: 'ScalingFactors', searchLevel: number, initialMargin: number, collateralRelease: number } } | null } } | null };
|
||||
|
||||
|
||||
export const MarketInfoDocument = gql`
|
||||
query MarketInfo($marketId: ID!, $interval: Interval!, $since: String!) {
|
||||
query MarketInfo($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
id
|
||||
decimalPlaces
|
||||
@@ -48,7 +46,6 @@ export const MarketInfoDocument = gql`
|
||||
}
|
||||
}
|
||||
}
|
||||
tradingMode
|
||||
fees {
|
||||
factors {
|
||||
makerFee
|
||||
@@ -70,35 +67,6 @@ export const MarketInfoDocument = gql`
|
||||
short
|
||||
long
|
||||
}
|
||||
data {
|
||||
market {
|
||||
id
|
||||
}
|
||||
markPrice
|
||||
midPrice
|
||||
bestBidVolume
|
||||
bestOfferVolume
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferVolume
|
||||
bestBidPrice
|
||||
bestOfferPrice
|
||||
trigger
|
||||
openInterest
|
||||
suppliedStake
|
||||
openInterest
|
||||
targetStake
|
||||
marketValueProxy
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
}
|
||||
liquidityMonitoringParameters {
|
||||
triggeringRatio
|
||||
targetStakeParameters {
|
||||
@@ -106,13 +74,6 @@ export const MarketInfoDocument = gql`
|
||||
scalingFactor
|
||||
}
|
||||
}
|
||||
candlesConnection(interval: $interval, since: $since) {
|
||||
edges {
|
||||
node {
|
||||
volume
|
||||
}
|
||||
}
|
||||
}
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
id
|
||||
@@ -160,10 +121,12 @@ export const MarketInfoDocument = gql`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
depth {
|
||||
lastTrade {
|
||||
price
|
||||
marginCalculator {
|
||||
scalingFactors {
|
||||
searchLevel
|
||||
initialMargin
|
||||
collateralRelease
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,8 +146,6 @@ export const MarketInfoDocument = gql`
|
||||
* const { data, loading, error } = useMarketInfoQuery({
|
||||
* variables: {
|
||||
* marketId: // value for 'marketId'
|
||||
* interval: // value for 'interval'
|
||||
* since: // value for 'since'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type MarketInfoNoCandlesQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketInfoNoCandlesQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, lpPriceRange: string, proposal?: { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any }, openingAuction: { __typename?: 'AuctionDuration', durationSecs: number, volume: number }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string } } } | null> | null } | null, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, priceMonitoringSettings: { __typename?: 'PriceMonitoringSettings', parameters?: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null } | null }, riskFactors?: { __typename?: 'RiskFactor', market: string, short: string, long: string } | null, data?: { __typename?: 'MarketData', markPrice: string, midPrice: string, bestBidVolume: string, bestOfferVolume: string, bestStaticBidVolume: string, bestStaticOfferVolume: string, bestBidPrice: string, bestOfferPrice: string, trigger: Types.AuctionTrigger, openInterest: string, suppliedStake?: string | null, targetStake?: string | null, marketValueProxy: string, market: { __typename?: 'Market', id: string }, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null } | null, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: string, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } }, riskModel: { __typename?: 'LogNormalRiskModel', tau: number, riskAversionParameter: number, params: { __typename?: 'LogNormalModelParams', r: number, sigma: number, mu: number } } | { __typename?: 'SimpleRiskModel', params: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } } }, depth: { __typename?: 'MarketDepth', lastTrade?: { __typename?: 'Trade', price: string } | null } } | null };
|
||||
|
||||
|
||||
export const MarketInfoNoCandlesDocument = gql`
|
||||
query MarketInfoNoCandles($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
id
|
||||
decimalPlaces
|
||||
positionDecimalPlaces
|
||||
state
|
||||
tradingMode
|
||||
lpPriceRange
|
||||
proposal {
|
||||
id
|
||||
rationale {
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
marketTimestamps {
|
||||
open
|
||||
close
|
||||
}
|
||||
openingAuction {
|
||||
durationSecs
|
||||
volume
|
||||
}
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
asset {
|
||||
id
|
||||
}
|
||||
balance
|
||||
}
|
||||
}
|
||||
}
|
||||
tradingMode
|
||||
fees {
|
||||
factors {
|
||||
makerFee
|
||||
infrastructureFee
|
||||
liquidityFee
|
||||
}
|
||||
}
|
||||
priceMonitoringSettings {
|
||||
parameters {
|
||||
triggers {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
}
|
||||
}
|
||||
riskFactors {
|
||||
market
|
||||
short
|
||||
long
|
||||
}
|
||||
data {
|
||||
market {
|
||||
id
|
||||
}
|
||||
markPrice
|
||||
midPrice
|
||||
bestBidVolume
|
||||
bestOfferVolume
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferVolume
|
||||
bestBidPrice
|
||||
bestOfferPrice
|
||||
trigger
|
||||
openInterest
|
||||
suppliedStake
|
||||
openInterest
|
||||
targetStake
|
||||
marketValueProxy
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
}
|
||||
liquidityMonitoringParameters {
|
||||
triggeringRatio
|
||||
targetStakeParameters {
|
||||
timeWindow
|
||||
scalingFactor
|
||||
}
|
||||
}
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
id
|
||||
name
|
||||
code
|
||||
metadata {
|
||||
tags
|
||||
}
|
||||
product {
|
||||
... on Future {
|
||||
quoteName
|
||||
settlementAsset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
dataSourceSpecForSettlementData {
|
||||
id
|
||||
}
|
||||
dataSourceSpecForTradingTermination {
|
||||
id
|
||||
}
|
||||
dataSourceSpecBinding {
|
||||
settlementDataProperty
|
||||
tradingTerminationProperty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
riskModel {
|
||||
... on LogNormalRiskModel {
|
||||
tau
|
||||
riskAversionParameter
|
||||
params {
|
||||
r
|
||||
sigma
|
||||
mu
|
||||
}
|
||||
}
|
||||
... on SimpleRiskModel {
|
||||
params {
|
||||
factorLong
|
||||
factorShort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
depth {
|
||||
lastTrade {
|
||||
price
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useMarketInfoNoCandlesQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useMarketInfoNoCandlesQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useMarketInfoNoCandlesQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useMarketInfoNoCandlesQuery({
|
||||
* variables: {
|
||||
* marketId: // value for 'marketId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useMarketInfoNoCandlesQuery(baseOptions: Apollo.QueryHookOptions<MarketInfoNoCandlesQuery, MarketInfoNoCandlesQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<MarketInfoNoCandlesQuery, MarketInfoNoCandlesQueryVariables>(MarketInfoNoCandlesDocument, options);
|
||||
}
|
||||
export function useMarketInfoNoCandlesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketInfoNoCandlesQuery, MarketInfoNoCandlesQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<MarketInfoNoCandlesQuery, MarketInfoNoCandlesQueryVariables>(MarketInfoNoCandlesDocument, options);
|
||||
}
|
||||
export type MarketInfoNoCandlesQueryHookResult = ReturnType<typeof useMarketInfoNoCandlesQuery>;
|
||||
export type MarketInfoNoCandlesLazyQueryHookResult = ReturnType<typeof useMarketInfoNoCandlesLazyQuery>;
|
||||
export type MarketInfoNoCandlesQueryResult = Apollo.QueryResult<MarketInfoNoCandlesQuery, MarketInfoNoCandlesQueryVariables>;
|
||||
@@ -2,5 +2,4 @@ export * from './info-key-value-table';
|
||||
export * from './info-market';
|
||||
export * from './tooltip-mapping';
|
||||
export * from './__generated__/MarketInfo';
|
||||
export * from './__generated__/MarketInfoNoCandles';
|
||||
export * from './market-info-data-provider';
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { AssetDetailsTable, useAssetDataProvider } from '@vegaprotocol/assets';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { totalFeesPercentage } from '@vegaprotocol/market-list';
|
||||
import {
|
||||
totalFeesPercentage,
|
||||
calcCandleVolume,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
formatNumber,
|
||||
@@ -20,31 +23,20 @@ import {
|
||||
Splash,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import pick from 'lodash/pick';
|
||||
import { useMemo } from 'react';
|
||||
import { generatePath, Link } from 'react-router-dom';
|
||||
|
||||
import { MarketInfoTable } from './info-key-value-table';
|
||||
import { marketInfoDataProvider } from './market-info-data-provider';
|
||||
import { marketInfoWithDataAndCandlesProvider } from './market-info-data-provider';
|
||||
|
||||
import type { MarketInfoQuery } from './__generated__/MarketInfo';
|
||||
import type { MarketInfoWithDataAndCandles } from './market-info-data-provider';
|
||||
import { MarketProposalNotification } from '@vegaprotocol/proposals';
|
||||
|
||||
export interface InfoProps {
|
||||
market: MarketInfoQuery['market'];
|
||||
market: MarketInfoWithDataAndCandles;
|
||||
onSelect: (id: string) => void;
|
||||
}
|
||||
|
||||
export const calcCandleVolume = (
|
||||
m: MarketInfoQuery['market']
|
||||
): string | undefined => {
|
||||
return m?.candlesConnection?.edges
|
||||
?.reduce((acc: BigNumber, c) => {
|
||||
return acc.plus(new BigNumber(c?.node?.volume ?? 0));
|
||||
}, new BigNumber(m?.candlesConnection?.edges[0]?.node.volume ?? 0))
|
||||
?.toString();
|
||||
};
|
||||
|
||||
export interface MarketInfoContainerProps {
|
||||
marketId: string;
|
||||
onSelect?: (id: string) => void;
|
||||
@@ -67,15 +59,15 @@ export const MarketInfoContainer = ({
|
||||
);
|
||||
|
||||
const { data, loading, error, reload } = useDataProvider({
|
||||
dataProvider: marketInfoDataProvider,
|
||||
dataProvider: marketInfoWithDataAndCandlesProvider,
|
||||
skipUpdates: true,
|
||||
variables,
|
||||
});
|
||||
|
||||
return (
|
||||
<AsyncRenderer data={data} loading={loading} error={error} reload={reload}>
|
||||
{data && data.market ? (
|
||||
<Info market={data.market} onSelect={(id) => onSelect?.(id)} />
|
||||
{data ? (
|
||||
<Info market={data} onSelect={(id) => onSelect?.(id)} />
|
||||
) : (
|
||||
<Splash>
|
||||
<p>{t('Could not load market')}</p>
|
||||
@@ -88,7 +80,6 @@ export const MarketInfoContainer = ({
|
||||
export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
const { VEGA_TOKEN_URL, VEGA_EXPLORER_URL } = useEnvironment();
|
||||
const headerClassName = 'uppercase text-lg';
|
||||
const dayVolume = calcCandleVolume(market);
|
||||
const assetSymbol =
|
||||
market?.tradableInstrument.instrument.product?.settlementAsset.symbol || '';
|
||||
const quoteUnit =
|
||||
@@ -105,6 +96,8 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
market.accountsConnection?.edges
|
||||
);
|
||||
|
||||
const last24hourVolume = market.candles && calcCandleVolume(market.candles);
|
||||
|
||||
const marketDataPanels = [
|
||||
{
|
||||
title: t('Current fees'),
|
||||
@@ -131,13 +124,9 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
<>
|
||||
<MarketInfoTable
|
||||
data={{
|
||||
...pick(
|
||||
market.data,
|
||||
'name',
|
||||
'markPrice',
|
||||
'bestBidPrice',
|
||||
'bestOfferPrice'
|
||||
),
|
||||
markPrice: market.data?.markPrice,
|
||||
bestBidPrice: market.data?.bestBidPrice,
|
||||
bestOfferPrice: market.data?.bestOfferPrice,
|
||||
quoteUnit: market.tradableInstrument.instrument.product.quoteName,
|
||||
}}
|
||||
decimalPlaces={market.decimalPlaces}
|
||||
@@ -157,16 +146,17 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
<MarketInfoTable
|
||||
data={{
|
||||
'24hourVolume':
|
||||
dayVolume && dayVolume !== '0' ? formatNumber(dayVolume) : '-',
|
||||
...pick(
|
||||
market.data,
|
||||
'openInterest',
|
||||
'name',
|
||||
'bestBidVolume',
|
||||
'bestOfferVolume',
|
||||
'bestStaticBidVolume',
|
||||
'bestStaticOfferVolume'
|
||||
),
|
||||
last24hourVolume && last24hourVolume !== '0'
|
||||
? addDecimalsFormatNumber(
|
||||
last24hourVolume,
|
||||
market.positionDecimalPlaces
|
||||
)
|
||||
: '-',
|
||||
openInterest: market.data?.openInterest,
|
||||
bestBidVolume: market.data?.bestBidVolume,
|
||||
bestOfferVolume: market.data?.bestOfferVolume,
|
||||
bestStaticBidVolume: market.data?.bestStaticBidVolume,
|
||||
bestStaticOfferVolume: market.data?.bestStaticOfferVolume,
|
||||
}}
|
||||
decimalPlaces={market.positionDecimalPlaces}
|
||||
/>
|
||||
@@ -192,7 +182,9 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
];
|
||||
|
||||
const keyDetails = {
|
||||
...pick(market, 'decimalPlaces', 'positionDecimalPlaces', 'tradingMode'),
|
||||
decimalPlaces: market.decimalPlaces,
|
||||
positionDecimalPlaces: market.positionDecimalPlaces,
|
||||
tradingMode: market.tradingMode,
|
||||
state: Schema.MarketStateMapping[market.state],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,25 +1,68 @@
|
||||
import { makeDataProvider } from '@vegaprotocol/utils';
|
||||
import type { MarketInfoQuery } from './__generated__/MarketInfo';
|
||||
import { makeDataProvider, makeDerivedDataProvider } from '@vegaprotocol/utils';
|
||||
import type {
|
||||
MarketInfoQuery,
|
||||
MarketInfoQueryVariables,
|
||||
} from './__generated__/MarketInfo';
|
||||
import {
|
||||
marketDataProvider,
|
||||
marketCandlesProvider,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
MarketData,
|
||||
Candle,
|
||||
MarketCandlesQueryVariables,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { MarketInfoDocument } from './__generated__/MarketInfo';
|
||||
import type { MarketInfoNoCandlesQuery } from './__generated__/MarketInfoNoCandles';
|
||||
import { MarketInfoNoCandlesDocument } from './__generated__/MarketInfoNoCandles';
|
||||
|
||||
export const marketInfoDataProvider = makeDataProvider<
|
||||
MarketInfoQuery,
|
||||
export type MarketInfo = NonNullable<MarketInfoQuery['market']>;
|
||||
export type MarketInfoWithData = MarketInfo & { data?: MarketData };
|
||||
|
||||
export type MarketInfoWithDataAndCandles = MarketInfoWithData & {
|
||||
candles?: Candle[];
|
||||
};
|
||||
|
||||
const getData = (responseData: MarketInfoQuery | null) =>
|
||||
responseData?.market || null;
|
||||
|
||||
export const marketInfoProvider = makeDataProvider<
|
||||
MarketInfoQuery,
|
||||
MarketInfoQuery['market'],
|
||||
never,
|
||||
never
|
||||
never,
|
||||
MarketInfoQueryVariables
|
||||
>({
|
||||
query: MarketInfoDocument,
|
||||
getData: (responseData: MarketInfoQuery | null) => responseData,
|
||||
getData,
|
||||
});
|
||||
|
||||
export const marketInfoNoCandlesDataProvider = makeDataProvider<
|
||||
MarketInfoNoCandlesQuery,
|
||||
MarketInfoNoCandlesQuery,
|
||||
export const marketInfoWithDataProvider = makeDerivedDataProvider<
|
||||
MarketInfoWithData,
|
||||
never,
|
||||
never
|
||||
>({
|
||||
query: MarketInfoNoCandlesDocument,
|
||||
getData: (responseData: MarketInfoNoCandlesQuery | null) => responseData,
|
||||
MarketInfoQueryVariables
|
||||
>([marketInfoProvider, marketDataProvider], (parts) => {
|
||||
const market: MarketInfo | null = parts[0];
|
||||
const marketData: MarketData | null = parts[1];
|
||||
return (
|
||||
market && {
|
||||
...market,
|
||||
data: marketData || undefined,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
export const marketInfoWithDataAndCandlesProvider = makeDerivedDataProvider<
|
||||
MarketInfoWithDataAndCandles,
|
||||
never,
|
||||
MarketCandlesQueryVariables
|
||||
>([marketInfoProvider, marketDataProvider, marketCandlesProvider], (parts) => {
|
||||
const market: MarketInfo | null = parts[0];
|
||||
const marketData: MarketData | null = parts[1];
|
||||
const candles: Candle[] | null = parts[2];
|
||||
return (
|
||||
market && {
|
||||
...market,
|
||||
data: marketData || undefined,
|
||||
candles: candles || undefined,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -93,40 +93,6 @@ export const marketInfoQuery = (
|
||||
long: '0.008508132993273576',
|
||||
},
|
||||
lpPriceRange: '0.02',
|
||||
data: {
|
||||
__typename: 'MarketData',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '54b78c1b877e106842ae156332ccec740ad98d6bad43143ac6a029501dd7c6e0',
|
||||
},
|
||||
midPrice: '5749',
|
||||
markPrice: '5749',
|
||||
suppliedStake: '56767',
|
||||
marketValueProxy: '677678',
|
||||
targetStake: '56789',
|
||||
bestBidVolume: '5',
|
||||
bestOfferVolume: '1',
|
||||
bestStaticBidVolume: '5',
|
||||
bestStaticOfferVolume: '1',
|
||||
openInterest: '0',
|
||||
bestBidPrice: '681765',
|
||||
bestOfferPrice: '681769',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
priceMonitoringBounds: [
|
||||
{
|
||||
minValidPrice: '654701',
|
||||
maxValidPrice: '797323',
|
||||
trigger: {
|
||||
horizonSecs: 43200,
|
||||
probability: 0.9999999,
|
||||
auctionExtensionSecs: 600,
|
||||
__typename: 'PriceMonitoringTrigger',
|
||||
},
|
||||
referencePrice: '722625',
|
||||
__typename: 'PriceMonitoringBounds',
|
||||
},
|
||||
],
|
||||
},
|
||||
liquidityMonitoringParameters: {
|
||||
triggeringRatio: '0',
|
||||
targetStakeParameters: {
|
||||
@@ -136,7 +102,6 @@ export const marketInfoQuery = (
|
||||
},
|
||||
__typename: 'LiquidityMonitoringParameters',
|
||||
},
|
||||
candlesConnection: null,
|
||||
tradableInstrument: {
|
||||
__typename: 'TradableInstrument',
|
||||
instrument: {
|
||||
@@ -192,13 +157,6 @@ export const marketInfoQuery = (
|
||||
},
|
||||
},
|
||||
},
|
||||
depth: {
|
||||
__typename: 'MarketDepth',
|
||||
lastTrade: {
|
||||
__typename: 'Trade',
|
||||
price: '100',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+62
-26
@@ -3,40 +3,59 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
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, targetStake?: string | null, suppliedStake?: string | null };
|
||||
export type MarketDataUpdateFieldsFragment = { __typename?: 'ObservableMarketData', marketId: string, auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null };
|
||||
|
||||
export type MarketDataUpdateSubscriptionVariables = Types.Exact<{
|
||||
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, targetStake?: string | null, suppliedStake?: string | null }> };
|
||||
export type MarketDataUpdateSubscription = { __typename?: 'Subscription', marketsData: Array<{ __typename?: 'ObservableMarketData', marketId: string, auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | 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', auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, market: { __typename?: 'Market', id: string }, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null };
|
||||
|
||||
export type MarketDataQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __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 } } | null } }> } | null };
|
||||
export type MarketDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __typename?: 'MarketData', auctionEnd?: string | null, auctionStart?: string | null, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, indicativePrice: string, indicativeVolume: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, marketValueProxy: string, markPrice: string, midPrice: string, openInterest: string, staticMidPrice: string, suppliedStake?: string | null, targetStake?: string | null, trigger: Types.AuctionTrigger, market: { __typename?: 'Market', id: string }, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number } }> | null } | null } }> } | null };
|
||||
|
||||
export const MarketDataUpdateFieldsFragmentDoc = gql`
|
||||
fragment MarketDataUpdateFields on ObservableMarketData {
|
||||
marketId
|
||||
auctionEnd
|
||||
auctionStart
|
||||
bestBidPrice
|
||||
bestBidVolume
|
||||
bestOfferPrice
|
||||
markPrice
|
||||
trigger
|
||||
staticMidPrice
|
||||
marketTradingMode
|
||||
marketState
|
||||
indicativeVolume
|
||||
indicativePrice
|
||||
bestOfferVolume
|
||||
bestStaticBidPrice
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferPrice
|
||||
targetStake
|
||||
bestStaticOfferVolume
|
||||
indicativePrice
|
||||
indicativeVolume
|
||||
marketState
|
||||
marketTradingMode
|
||||
marketValueProxy
|
||||
markPrice
|
||||
midPrice
|
||||
openInterest
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
staticMidPrice
|
||||
suppliedStake
|
||||
targetStake
|
||||
trigger
|
||||
}
|
||||
`;
|
||||
export const MarketDataFieldsFragmentDoc = gql`
|
||||
@@ -44,21 +63,38 @@ export const MarketDataFieldsFragmentDoc = gql`
|
||||
market {
|
||||
id
|
||||
}
|
||||
bestBidPrice
|
||||
bestOfferPrice
|
||||
markPrice
|
||||
trigger
|
||||
staticMidPrice
|
||||
marketTradingMode
|
||||
marketState
|
||||
indicativeVolume
|
||||
indicativePrice
|
||||
bestStaticBidPrice
|
||||
bestStaticOfferPrice
|
||||
targetStake
|
||||
suppliedStake
|
||||
auctionStart
|
||||
auctionEnd
|
||||
auctionStart
|
||||
bestBidPrice
|
||||
bestBidVolume
|
||||
bestOfferPrice
|
||||
bestOfferVolume
|
||||
bestStaticBidPrice
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferPrice
|
||||
bestStaticOfferVolume
|
||||
indicativePrice
|
||||
indicativeVolume
|
||||
marketState
|
||||
marketTradingMode
|
||||
marketValueProxy
|
||||
markPrice
|
||||
midPrice
|
||||
openInterest
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
staticMidPrice
|
||||
suppliedStake
|
||||
targetStake
|
||||
trigger
|
||||
}
|
||||
`;
|
||||
export const MarketDataUpdateDocument = gql`
|
||||
|
||||
@@ -13,13 +13,14 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||
const { data, error, loading, reload } = useDataProvider({
|
||||
dataProvider,
|
||||
skipUpdates: true,
|
||||
variables: undefined,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="h-full relative">
|
||||
<MarketListTable
|
||||
rowData={error ? [] : data}
|
||||
noRowsOverlayComponent={() => null}
|
||||
suppressLoadingOverlay
|
||||
suppressNoRowsOverlay
|
||||
onRowClicked={(rowEvent: RowClickedEvent) => {
|
||||
const { data, event } = rowEvent;
|
||||
// filters out clicks on the symbol column because it should display asset details
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { makeDataProvider } from '@vegaprotocol/utils';
|
||||
import type {
|
||||
MarketCandlesQuery,
|
||||
MarketCandlesQueryVariables,
|
||||
MarketCandlesUpdateSubscription,
|
||||
MarketCandlesFieldsFragment,
|
||||
} from './__generated__/market-candles';
|
||||
@@ -36,7 +37,8 @@ export const marketCandlesProvider = makeDataProvider<
|
||||
MarketCandlesQuery,
|
||||
Candle[],
|
||||
MarketCandlesUpdateSubscription,
|
||||
Candle
|
||||
Candle,
|
||||
MarketCandlesQueryVariables
|
||||
>({
|
||||
query: MarketCandlesDocument,
|
||||
subscriptionQuery: MarketCandlesUpdateDocument,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import produce from 'immer';
|
||||
import { useMemo } from 'react';
|
||||
import { makeDataProvider, makeDerivedDataProvider } from '@vegaprotocol/utils';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
@@ -11,6 +10,7 @@ import type {
|
||||
MarketDataFieldsFragment,
|
||||
MarketDataUpdateSubscription,
|
||||
MarketDataUpdateFieldsFragment,
|
||||
MarketDataQueryVariables,
|
||||
} from './__generated__/market-data';
|
||||
|
||||
export type MarketData = MarketDataFieldsFragment;
|
||||
@@ -29,7 +29,7 @@ const update = (
|
||||
};
|
||||
|
||||
const getData = (responseData: MarketDataQuery | null): MarketData | null =>
|
||||
responseData?.marketsConnection?.edges[0].node.data || null;
|
||||
responseData?.marketsConnection?.edges[0]?.node?.data || null;
|
||||
|
||||
const getDelta = (
|
||||
subscriptionData: MarketDataUpdateSubscription
|
||||
@@ -39,7 +39,8 @@ export const marketDataProvider = makeDataProvider<
|
||||
MarketDataQuery,
|
||||
MarketData,
|
||||
MarketDataUpdateSubscription,
|
||||
MarketDataUpdateFieldsFragment
|
||||
MarketDataUpdateFieldsFragment,
|
||||
MarketDataQueryVariables
|
||||
>({
|
||||
query: MarketDataDocument,
|
||||
subscriptionQuery: MarketDataUpdateDocument,
|
||||
@@ -48,6 +49,12 @@ export const marketDataProvider = makeDataProvider<
|
||||
getDelta,
|
||||
});
|
||||
|
||||
export const markPriceProvider = makeDerivedDataProvider<
|
||||
string,
|
||||
never,
|
||||
MarketDataQueryVariables
|
||||
>([marketDataProvider], ([marketData]) => (marketData as MarketData).markPrice);
|
||||
|
||||
export type StaticMarketData = Pick<
|
||||
MarketData,
|
||||
| 'marketTradingMode'
|
||||
@@ -63,7 +70,8 @@ export type StaticMarketData = Pick<
|
||||
|
||||
export const staticMarketDataProvider = makeDerivedDataProvider<
|
||||
StaticMarketData,
|
||||
never
|
||||
never,
|
||||
MarketDataQueryVariables
|
||||
>([marketDataProvider], (parts, variables, prevData) => {
|
||||
const marketData = parts[0] as ReturnType<typeof getData>;
|
||||
if (!marketData) {
|
||||
@@ -89,10 +97,9 @@ export const staticMarketDataProvider = makeDerivedDataProvider<
|
||||
});
|
||||
|
||||
export const useStaticMarketData = (marketId?: string, skip?: boolean) => {
|
||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||
return useDataProvider({
|
||||
dataProvider: staticMarketDataProvider,
|
||||
variables,
|
||||
variables: { marketId: marketId || '' },
|
||||
skip: skip || !marketId,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,18 +1,37 @@
|
||||
fragment MarketDataUpdateFields on ObservableMarketData {
|
||||
marketId
|
||||
auctionEnd
|
||||
auctionStart
|
||||
bestBidPrice
|
||||
bestBidVolume
|
||||
bestOfferPrice
|
||||
markPrice
|
||||
trigger
|
||||
staticMidPrice
|
||||
marketTradingMode
|
||||
marketState
|
||||
indicativeVolume
|
||||
indicativePrice
|
||||
bestOfferVolume
|
||||
bestStaticBidPrice
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferPrice
|
||||
targetStake
|
||||
bestStaticOfferVolume
|
||||
indicativePrice
|
||||
indicativeVolume
|
||||
marketState
|
||||
marketTradingMode
|
||||
marketValueProxy
|
||||
markPrice
|
||||
midPrice
|
||||
openInterest
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
staticMidPrice
|
||||
suppliedStake
|
||||
targetStake
|
||||
trigger
|
||||
}
|
||||
|
||||
subscription MarketDataUpdate($marketId: ID!) {
|
||||
@@ -25,21 +44,38 @@ fragment MarketDataFields on MarketData {
|
||||
market {
|
||||
id
|
||||
}
|
||||
bestBidPrice
|
||||
bestOfferPrice
|
||||
markPrice
|
||||
trigger
|
||||
staticMidPrice
|
||||
marketTradingMode
|
||||
marketState
|
||||
indicativeVolume
|
||||
indicativePrice
|
||||
bestStaticBidPrice
|
||||
bestStaticOfferPrice
|
||||
targetStake
|
||||
suppliedStake
|
||||
auctionStart
|
||||
auctionEnd
|
||||
auctionStart
|
||||
bestBidPrice
|
||||
bestBidVolume
|
||||
bestOfferPrice
|
||||
bestOfferVolume
|
||||
bestStaticBidPrice
|
||||
bestStaticBidVolume
|
||||
bestStaticOfferPrice
|
||||
bestStaticOfferVolume
|
||||
indicativePrice
|
||||
indicativeVolume
|
||||
marketState
|
||||
marketTradingMode
|
||||
marketValueProxy
|
||||
markPrice
|
||||
midPrice
|
||||
openInterest
|
||||
priceMonitoringBounds {
|
||||
minValidPrice
|
||||
maxValidPrice
|
||||
trigger {
|
||||
horizonSecs
|
||||
probability
|
||||
auctionExtensionSecs
|
||||
}
|
||||
referencePrice
|
||||
}
|
||||
staticMidPrice
|
||||
suppliedStake
|
||||
targetStake
|
||||
trigger
|
||||
}
|
||||
|
||||
query MarketData($marketId: ID!) {
|
||||
|
||||
@@ -44,34 +44,62 @@ const marketDataFields: MarketDataFieldsFragment = {
|
||||
id: 'market-0',
|
||||
__typename: 'Market',
|
||||
},
|
||||
auctionStart: '2022-06-21T17:18:43.484055236Z',
|
||||
auctionEnd: '2022-06-21T17:18:43.484055236Z',
|
||||
targetStake: '1000000',
|
||||
suppliedStake: '1000',
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
staticMidPrice: '0',
|
||||
auctionStart: '2022-06-21T17:18:43.484055236Z',
|
||||
bestBidPrice: '4412690058',
|
||||
bestBidVolume: '1',
|
||||
bestOfferPrice: '4812690058',
|
||||
bestOfferVolume: '3',
|
||||
bestStaticBidPrice: '4512690058',
|
||||
bestStaticBidVolume: '2',
|
||||
bestStaticOfferPrice: '4712690058',
|
||||
bestStaticOfferVolume: '4',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '0',
|
||||
bestBidPrice: '0',
|
||||
bestOfferPrice: '0',
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketValueProxy: '2000000',
|
||||
markPrice: '4612690058',
|
||||
midPrice: '4612690000',
|
||||
openInterest: '0',
|
||||
priceMonitoringBounds: [
|
||||
{
|
||||
minValidPrice: '654701',
|
||||
maxValidPrice: '797323',
|
||||
trigger: {
|
||||
horizonSecs: 43200,
|
||||
probability: 0.9999999,
|
||||
auctionExtensionSecs: 600,
|
||||
__typename: 'PriceMonitoringTrigger',
|
||||
},
|
||||
referencePrice: '722625',
|
||||
__typename: 'PriceMonitoringBounds',
|
||||
},
|
||||
],
|
||||
staticMidPrice: '4612690001',
|
||||
suppliedStake: '1000',
|
||||
targetStake: '1000000',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
};
|
||||
|
||||
const marketDataUpdateFields: MarketDataUpdateFieldsFragment = {
|
||||
marketId: 'market-0',
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
staticMidPrice: '0',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '0',
|
||||
bestBidPrice: '0',
|
||||
bestBidVolume: '0',
|
||||
bestOfferPrice: '0',
|
||||
bestOfferVolume: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticBidVolume: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
bestStaticOfferVolume: '0',
|
||||
indicativePrice: '0',
|
||||
indicativeVolume: '0',
|
||||
marketId: 'market-0',
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketValueProxy: '',
|
||||
markPrice: '4612690058',
|
||||
midPrice: '0',
|
||||
openInterest: '0',
|
||||
staticMidPrice: '0',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { makeDataProvider } from '@vegaprotocol/utils';
|
||||
import { MarketsCandlesDocument } from './__generated__/markets-candles';
|
||||
import type { MarketsCandlesQuery } from './__generated__/markets-candles';
|
||||
import type {
|
||||
MarketsCandlesQuery,
|
||||
MarketsCandlesQueryVariables,
|
||||
} from './__generated__/markets-candles';
|
||||
import type { Candle } from './market-candles-provider';
|
||||
|
||||
export interface MarketCandles {
|
||||
@@ -22,7 +25,8 @@ export const marketsCandlesProvider = makeDataProvider<
|
||||
MarketsCandlesQuery,
|
||||
MarketCandles[],
|
||||
never,
|
||||
never
|
||||
never,
|
||||
MarketsCandlesQueryVariables
|
||||
>({
|
||||
query: MarketsCandlesDocument,
|
||||
getData,
|
||||
|
||||
@@ -4,6 +4,8 @@ import type {
|
||||
MarketsQuery,
|
||||
MarketFieldsFragment,
|
||||
} from './__generated__/markets';
|
||||
import type { MarketsCandlesQueryVariables } from './__generated__/markets-candles';
|
||||
|
||||
import { marketsDataProvider } from './markets-data-provider';
|
||||
import { marketDataProvider } from './market-data-provider';
|
||||
import { marketsCandlesProvider } from './markets-candles-provider';
|
||||
@@ -37,7 +39,7 @@ export const marketProvider = makeDerivedDataProvider<
|
||||
never,
|
||||
{ marketId: string }
|
||||
>(
|
||||
[marketsProvider],
|
||||
[(callback, client) => marketsProvider(callback, client, undefined)],
|
||||
([markets], variables) =>
|
||||
((markets as ReturnType<typeof getData>) || []).find(
|
||||
(market) => market.id === variables?.marketId
|
||||
@@ -84,10 +86,11 @@ const addCandles = <T extends Market>(
|
||||
|
||||
export const marketsWithCandlesProvider = makeDerivedDataProvider<
|
||||
MarketMaybeWithCandles[],
|
||||
never
|
||||
never,
|
||||
MarketsCandlesQueryVariables
|
||||
>(
|
||||
[
|
||||
(callback, client) => activeMarketsProvider(callback, client),
|
||||
(callback, client) => activeMarketsProvider(callback, client, undefined),
|
||||
marketsCandlesProvider,
|
||||
],
|
||||
(parts) => addCandles(parts[0] as Market[], parts[1] as MarketCandles[])
|
||||
@@ -113,10 +116,11 @@ export type MarketMaybeWithDataAndCandles = MarketMaybeWithData &
|
||||
|
||||
export const marketListProvider = makeDerivedDataProvider<
|
||||
MarketMaybeWithDataAndCandles[],
|
||||
never
|
||||
never,
|
||||
MarketsCandlesQueryVariables
|
||||
>(
|
||||
[
|
||||
(callback, client) => marketsWithDataProvider(callback, client),
|
||||
(callback, client) => marketsWithDataProvider(callback, client, undefined),
|
||||
marketsCandlesProvider,
|
||||
],
|
||||
(parts) =>
|
||||
|
||||
@@ -76,7 +76,9 @@ const orderMatchFilters = (
|
||||
return true;
|
||||
};
|
||||
|
||||
const getData = (responseData: OrdersQuery | null) =>
|
||||
const getData = (
|
||||
responseData: OrdersQuery | null
|
||||
): Edge<OrderFieldsFragment>[] =>
|
||||
responseData?.party?.ordersConnection?.edges || [];
|
||||
|
||||
const getDelta = (subscriptionData: OrdersUpdateSubscription) =>
|
||||
@@ -142,14 +144,19 @@ export const update = (
|
||||
__typename: 'Order',
|
||||
},
|
||||
cursor: '',
|
||||
__typename: 'OrderEdge',
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const ordersProvider = makeDataProvider({
|
||||
export const ordersProvider = makeDataProvider<
|
||||
OrdersQuery,
|
||||
ReturnType<typeof getData>,
|
||||
OrdersUpdateSubscription,
|
||||
ReturnType<typeof getDelta>,
|
||||
OrdersQueryVariables
|
||||
>({
|
||||
query: OrdersDocument,
|
||||
subscriptionQuery: OrdersUpdateDocument,
|
||||
update,
|
||||
@@ -168,7 +175,10 @@ export const ordersWithMarketProvider = makeDerivedDataProvider<
|
||||
Order[],
|
||||
OrdersQueryVariables
|
||||
>(
|
||||
[ordersProvider, marketsProvider],
|
||||
[
|
||||
ordersProvider,
|
||||
(callback, client) => marketsProvider(callback, client, undefined),
|
||||
],
|
||||
(partsData): OrderEdge[] =>
|
||||
((partsData[0] as ReturnType<typeof getData>) || []).map((edge) => ({
|
||||
cursor: edge.cursor,
|
||||
@@ -183,7 +193,13 @@ export const ordersWithMarketProvider = makeDerivedDataProvider<
|
||||
combineInsertionData<Order>
|
||||
);
|
||||
|
||||
const hasActiveOrderProviderInternal = makeDataProvider({
|
||||
const hasActiveOrderProviderInternal = makeDataProvider<
|
||||
OrdersQuery,
|
||||
boolean,
|
||||
OrdersUpdateSubscription,
|
||||
ReturnType<typeof getDelta>,
|
||||
OrdersQueryVariables
|
||||
>({
|
||||
query: OrdersDocument,
|
||||
subscriptionQuery: OrdersUpdateDocument,
|
||||
update: (
|
||||
|
||||
@@ -9,6 +9,8 @@ import type {
|
||||
} from 'ag-grid-community';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import type { GridReadyEvent } from 'ag-grid-community';
|
||||
|
||||
import { OrderListTable } from '../order-list/order-list';
|
||||
import { useOrderListData } from './use-order-list-data';
|
||||
import { useHasActiveOrder } from '../../order-hooks/use-has-active-order';
|
||||
@@ -156,6 +158,16 @@ export const OrderListManager = ({
|
||||
},
|
||||
[create]
|
||||
);
|
||||
|
||||
const onGridReady = useCallback(
|
||||
(event: GridReadyEvent) => {
|
||||
event.api.setDatasource({
|
||||
getRows,
|
||||
});
|
||||
},
|
||||
[getRows]
|
||||
);
|
||||
|
||||
const cancelAll = useCallback(
|
||||
(marketId?: string) => {
|
||||
create({
|
||||
@@ -177,7 +189,7 @@ export const OrderListManager = ({
|
||||
<OrderListTable
|
||||
ref={gridRef}
|
||||
rowModelType="infinite"
|
||||
datasource={{ getRows }}
|
||||
onGridReady={onGridReady}
|
||||
onBodyScrollEnd={onBodyScrollEnd}
|
||||
onBodyScroll={onBodyScroll}
|
||||
onFilterChanged={onFilterChanged}
|
||||
|
||||
@@ -139,18 +139,15 @@ export const useOrderListData = ({
|
||||
});
|
||||
totalCountRef.current = totalCount;
|
||||
|
||||
const getRows = makeInfiniteScrollGetRows<OrderEdge>(
|
||||
dataRef,
|
||||
totalCountRef,
|
||||
load,
|
||||
newRows
|
||||
const getRows = useRef(
|
||||
makeInfiniteScrollGetRows<OrderEdge>(dataRef, totalCountRef, load, newRows)
|
||||
);
|
||||
return {
|
||||
loading,
|
||||
error,
|
||||
data,
|
||||
addNewRows,
|
||||
getRows,
|
||||
getRows: getRows.current,
|
||||
reload,
|
||||
makeBottomPlaceholders,
|
||||
};
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
export * from './__generated__/OrdersSubscription';
|
||||
export * from './use-has-active-order';
|
||||
export * from './use-order-cancel';
|
||||
export * from './use-order-submit';
|
||||
export * from './use-order-edit';
|
||||
export * from './use-order-submit';
|
||||
export * from './use-order-update';
|
||||
export * from './use-pending-orders-volume';
|
||||
export * from './use-order-store';
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { OrderStatus, Side } from '@vegaprotocol/types';
|
||||
import { ordersProvider } from '../components/order-data-provider/order-data-provider';
|
||||
import type { OrderFieldsFragment } from '../components/order-data-provider/__generated__/Orders';
|
||||
import type { Edge } from '@vegaprotocol/utils';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const sumVolume = (orders: (Edge<OrderFieldsFragment> | null)[], side: Side) =>
|
||||
orders
|
||||
.reduce(
|
||||
(sum, order) =>
|
||||
order?.node.side === side
|
||||
? sum +
|
||||
BigInt(
|
||||
order?.node.status === OrderStatus.STATUS_PARTIALLY_FILLED
|
||||
? order?.node.remaining
|
||||
: order?.node.size
|
||||
)
|
||||
: sum,
|
||||
BigInt(0)
|
||||
)
|
||||
.toString();
|
||||
|
||||
export const useActiveOrdersVolumeAndMargin = (
|
||||
partyId: string | null | undefined,
|
||||
marketId: string
|
||||
) => {
|
||||
const [buyVolume, setBuyVolume] = useState<string | undefined>();
|
||||
const [sellVolume, setSellVolume] = useState<string | undefined>();
|
||||
const [buyInitialMargin, setBuyInitialMargin] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
const [sellInitialMargin, setSellInitialMargin] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
const update = useCallback(
|
||||
({ data }: { data: (Edge<OrderFieldsFragment> | null)[] | null }) => {
|
||||
if (!data) {
|
||||
setBuyVolume(undefined);
|
||||
setSellVolume(undefined);
|
||||
setBuyInitialMargin(undefined);
|
||||
setSellInitialMargin(undefined);
|
||||
} else {
|
||||
setBuyVolume(sumVolume(data, Side.SIDE_BUY));
|
||||
setSellVolume(sumVolume(data, Side.SIDE_SELL));
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[]
|
||||
);
|
||||
useDataProvider({
|
||||
dataProvider: ordersProvider,
|
||||
update,
|
||||
variables: {
|
||||
partyId: partyId || '',
|
||||
marketId,
|
||||
filter: {
|
||||
status: [
|
||||
OrderStatus.STATUS_ACTIVE,
|
||||
OrderStatus.STATUS_PARTIALLY_FILLED,
|
||||
],
|
||||
},
|
||||
},
|
||||
skip: !partyId,
|
||||
});
|
||||
return buyVolume || sellVolume
|
||||
? {
|
||||
buyVolume,
|
||||
sellVolume,
|
||||
buyInitialMargin,
|
||||
sellInitialMargin,
|
||||
}
|
||||
: undefined;
|
||||
};
|
||||
@@ -1,8 +1,11 @@
|
||||
export * from './lib/__generated__/Positions';
|
||||
export * from './lib/positions-container';
|
||||
export * from './lib/positions-data-providers';
|
||||
export * from './lib/margin-data-provider';
|
||||
export * from './lib/margin-calculator';
|
||||
export * from './lib/positions-table';
|
||||
export * from './lib/use-close-position';
|
||||
export * from './lib/use-positions-data';
|
||||
export * from './lib/use-market-position-open-volume';
|
||||
export * from './lib/use-market-margin';
|
||||
export * from './lib/use-market-position-open-volume';
|
||||
export * from './lib/use-open-volume';
|
||||
export * from './lib/use-positions-data';
|
||||
|
||||
+2
-2
@@ -5,9 +5,9 @@ import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type PositionFieldsFragment = { __typename?: 'Position', realisedPNL: string, openVolume: string, unrealisedPNL: string, averageEntryPrice: string, updatedAt?: any | null, positionStatus: Types.PositionStatus, lossSocializationAmount: string, market: { __typename?: 'Market', id: string } };
|
||||
|
||||
export type PositionsQueryVariables = Types.Exact<{
|
||||
export type PositionsQueryVariables = {
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
};
|
||||
|
||||
|
||||
export type PositionsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, positionsConnection?: { __typename?: 'PositionConnection', edges?: Array<{ __typename?: 'PositionEdge', node: { __typename?: 'Position', realisedPNL: string, openVolume: string, unrealisedPNL: string, averageEntryPrice: string, updatedAt?: any | null, positionStatus: Types.PositionStatus, lossSocializationAmount: string, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import { toBigNum } from '@vegaprotocol/utils';
|
||||
import { Side, MarketTradingMode, OrderType } from '@vegaprotocol/types';
|
||||
import type { ScalingFactors, RiskFactor } from '@vegaprotocol/types';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
|
||||
export const isMarketInAuction = (marketTradingMode: MarketTradingMode) => {
|
||||
return [
|
||||
MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||
MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||
].includes(marketTradingMode);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the market price based on market mode (auction or not auction)
|
||||
*/
|
||||
export const getMarketPrice = ({
|
||||
marketTradingMode,
|
||||
indicativePrice,
|
||||
markPrice,
|
||||
}: Pick<MarketData, 'marketTradingMode' | 'indicativePrice' | 'markPrice'>) => {
|
||||
if (isMarketInAuction(marketTradingMode)) {
|
||||
// 0 can never be a valid uncrossing price
|
||||
// as it would require there being orders on the book at that price.
|
||||
if (
|
||||
indicativePrice &&
|
||||
indicativePrice !== '0' &&
|
||||
BigInt(indicativePrice) !== BigInt(0)
|
||||
) {
|
||||
return indicativePrice;
|
||||
}
|
||||
}
|
||||
return markPrice;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the price for an order, order limit this is the user
|
||||
* entered value, for market this will be the mark price or
|
||||
* if in auction the indicative uncrossing price
|
||||
*/
|
||||
export const getDerivedPrice = (
|
||||
order: {
|
||||
type?: OrderType | null;
|
||||
price?: string;
|
||||
},
|
||||
marketData: Pick<
|
||||
MarketData,
|
||||
'marketTradingMode' | 'indicativePrice' | 'markPrice'
|
||||
>
|
||||
) => {
|
||||
// If order type is market we should use either the mark price
|
||||
// or the uncrossing price. If order type is limit use the price
|
||||
// the user has input
|
||||
|
||||
// Use the market price if order is a market order
|
||||
if (order.type === OrderType.TYPE_LIMIT && order.price) {
|
||||
return order.price;
|
||||
}
|
||||
return getMarketPrice(marketData);
|
||||
};
|
||||
|
||||
export const calculateMargins = ({
|
||||
size,
|
||||
side,
|
||||
price,
|
||||
decimals,
|
||||
positionDecimalPlaces,
|
||||
decimalPlaces,
|
||||
scalingFactors,
|
||||
riskFactors,
|
||||
}: {
|
||||
size: string;
|
||||
side: Side;
|
||||
positionDecimalPlaces: number;
|
||||
decimalPlaces: number;
|
||||
decimals: number;
|
||||
price: string;
|
||||
scalingFactors?: ScalingFactors;
|
||||
riskFactors: RiskFactor;
|
||||
}) => {
|
||||
const maintenanceMargin = toBigNum(size, positionDecimalPlaces)
|
||||
.multipliedBy(
|
||||
side === Side.SIDE_SELL ? riskFactors.short : riskFactors.long
|
||||
)
|
||||
.multipliedBy(toBigNum(price, decimalPlaces));
|
||||
return {
|
||||
maintenanceMargin: maintenanceMargin
|
||||
.multipliedBy(Math.pow(10, decimals))
|
||||
.toFixed(0),
|
||||
initialMargin: maintenanceMargin
|
||||
.multipliedBy(scalingFactors?.initialMargin ?? 1)
|
||||
.multipliedBy(Math.pow(10, decimals))
|
||||
.toFixed(0),
|
||||
};
|
||||
};
|
||||
@@ -1,5 +1,9 @@
|
||||
import produce from 'immer';
|
||||
import { makeDataProvider, removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
import {
|
||||
makeDataProvider,
|
||||
makeDerivedDataProvider,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/utils';
|
||||
import {
|
||||
MarginsSubscriptionDocument,
|
||||
MarginsDocument,
|
||||
@@ -8,6 +12,7 @@ import type {
|
||||
MarginsQuery,
|
||||
MarginFieldsFragment,
|
||||
MarginsSubscriptionSubscription,
|
||||
MarginsQueryVariables,
|
||||
} from './__generated__/Positions';
|
||||
|
||||
const update = (
|
||||
@@ -56,7 +61,8 @@ export const marginsDataProvider = makeDataProvider<
|
||||
MarginsQuery,
|
||||
MarginFieldsFragment[],
|
||||
MarginsSubscriptionSubscription,
|
||||
MarginsSubscriptionSubscription['margins']
|
||||
MarginsSubscriptionSubscription['margins'],
|
||||
MarginsQueryVariables
|
||||
>({
|
||||
query: MarginsDocument,
|
||||
subscriptionQuery: MarginsSubscriptionDocument,
|
||||
@@ -64,3 +70,15 @@ export const marginsDataProvider = makeDataProvider<
|
||||
getData,
|
||||
getDelta,
|
||||
});
|
||||
|
||||
export const marketMarginDataProvider = makeDerivedDataProvider<
|
||||
MarginFieldsFragment,
|
||||
never,
|
||||
MarginsQueryVariables & { marketId: string }
|
||||
>(
|
||||
[marginsDataProvider],
|
||||
(data, { marketId }) =>
|
||||
(data[0] as MarginFieldsFragment[]).find(
|
||||
(margin) => margin.market.id === marketId
|
||||
) || null
|
||||
);
|
||||
|
||||
@@ -11,19 +11,32 @@ import {
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/utils';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { MarketMaybeWithData } from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
MarketMaybeWithData,
|
||||
MarketDataQueryVariables,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { marketsWithDataProvider } from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
PositionsQuery,
|
||||
PositionFieldsFragment,
|
||||
PositionsSubscriptionSubscription,
|
||||
MarginFieldsFragment,
|
||||
PositionsQueryVariables,
|
||||
} from './__generated__/Positions';
|
||||
import {
|
||||
PositionsDocument,
|
||||
PositionsSubscriptionDocument,
|
||||
} from './__generated__/Positions';
|
||||
import { marginsDataProvider } from './margin-data-provider';
|
||||
import { calculateMargins } from './margin-calculator';
|
||||
import type { Edge } from '@vegaprotocol/utils';
|
||||
import { OrderStatus, Side } from '@vegaprotocol/types';
|
||||
import { marketInfoProvider } from '@vegaprotocol/market-info';
|
||||
import type { MarketInfoQuery } from '@vegaprotocol/market-info';
|
||||
import { marketDataProvider } from '@vegaprotocol/market-list';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
import { ordersProvider } from '@vegaprotocol/orders';
|
||||
import type { OrderFieldsFragment } from '@vegaprotocol/orders';
|
||||
import type { PositionStatus } from '@vegaprotocol/types';
|
||||
|
||||
type PositionMarginLevel = Pick<
|
||||
@@ -229,7 +242,8 @@ export const positionsDataProvider = makeDataProvider<
|
||||
PositionsQuery,
|
||||
PositionFieldsFragment[],
|
||||
PositionsSubscriptionSubscription,
|
||||
PositionsSubscriptionSubscription['positions']
|
||||
PositionsSubscriptionSubscription['positions'],
|
||||
PositionsQueryVariables
|
||||
>({
|
||||
query: PositionsDocument,
|
||||
subscriptionQuery: PositionsSubscriptionDocument,
|
||||
@@ -260,6 +274,32 @@ const upgradeMarginsConnection = (
|
||||
return null;
|
||||
};
|
||||
|
||||
export const positionDataProvider = makeDerivedDataProvider<
|
||||
PositionFieldsFragment,
|
||||
never,
|
||||
PositionsQueryVariables & MarketDataQueryVariables
|
||||
>(
|
||||
[
|
||||
(callback, client, variables) =>
|
||||
positionsDataProvider(callback, client, {
|
||||
partyId: variables?.partyId || '',
|
||||
}),
|
||||
],
|
||||
(data, variables) =>
|
||||
(data[0] as PositionFieldsFragment[] | null)?.find(
|
||||
(p) => p.market.id === variables?.marketId
|
||||
) || null
|
||||
);
|
||||
|
||||
export const openVolumeDataProvider = makeDerivedDataProvider<
|
||||
string,
|
||||
never,
|
||||
PositionsQueryVariables & MarketDataQueryVariables
|
||||
>(
|
||||
[positionDataProvider],
|
||||
(data) => (data[0] as PositionFieldsFragment | null)?.openVolume || null
|
||||
);
|
||||
|
||||
export const rejoinPositionData = (
|
||||
positions: PositionFieldsFragment[] | null,
|
||||
marketsData: MarketMaybeWithData[] | null,
|
||||
@@ -284,19 +324,15 @@ export const rejoinPositionData = (
|
||||
return null;
|
||||
};
|
||||
|
||||
export interface PositionsMetricsProviderVariables {
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
export const positionsMetricsProvider = makeDerivedDataProvider<
|
||||
Position[],
|
||||
Position[],
|
||||
PositionsMetricsProviderVariables
|
||||
PositionsQueryVariables
|
||||
>(
|
||||
[
|
||||
positionsDataProvider,
|
||||
accountsDataProvider,
|
||||
marketsWithDataProvider,
|
||||
(callback, client) => marketsWithDataProvider(callback, client, undefined),
|
||||
marginsDataProvider,
|
||||
],
|
||||
([positions, accounts, marketsData, margins], variables) => {
|
||||
@@ -317,3 +353,103 @@ export const positionsMetricsProvider = makeDerivedDataProvider<
|
||||
return !(previousRow && isEqual(previousRow, row));
|
||||
})
|
||||
);
|
||||
|
||||
export const volumeAndMarginProvider = makeDerivedDataProvider<
|
||||
{
|
||||
buyVolume: string;
|
||||
sellVolume: string;
|
||||
buyInitialMargin: string;
|
||||
sellInitialMargin: string;
|
||||
},
|
||||
never,
|
||||
PositionsQueryVariables & MarketDataQueryVariables
|
||||
>(
|
||||
[
|
||||
(callback, client, variables) =>
|
||||
ordersProvider(callback, client, {
|
||||
...variables,
|
||||
filter: {
|
||||
status: [
|
||||
OrderStatus.STATUS_ACTIVE,
|
||||
OrderStatus.STATUS_PARTIALLY_FILLED,
|
||||
],
|
||||
},
|
||||
}),
|
||||
(callback, client, variables) =>
|
||||
marketDataProvider(callback, client, { marketId: variables.marketId }),
|
||||
(callback, client, variables) =>
|
||||
marketInfoProvider(callback, client, { marketId: variables.marketId }),
|
||||
openVolumeDataProvider,
|
||||
],
|
||||
(data) => {
|
||||
const orders = data[0] as (Edge<OrderFieldsFragment> | null)[] | null;
|
||||
const marketData = data[1] as MarketData | null;
|
||||
const marketInfo = data[2] as MarketInfoQuery['market'];
|
||||
let openVolume = (data[3] as string | null) || '0';
|
||||
const shortPosition = openVolume?.startsWith('-');
|
||||
if (shortPosition) {
|
||||
openVolume = openVolume.substring(1);
|
||||
}
|
||||
let buyVolume = BigInt(shortPosition ? 0 : openVolume);
|
||||
let sellVolume = BigInt(shortPosition ? openVolume : 0);
|
||||
let buyInitialMargin = BigInt(0);
|
||||
let sellInitialMargin = BigInt(0);
|
||||
if (marketInfo?.riskFactors && marketData) {
|
||||
const {
|
||||
positionDecimalPlaces,
|
||||
decimalPlaces,
|
||||
tradableInstrument,
|
||||
riskFactors,
|
||||
} = marketInfo;
|
||||
const { marginCalculator, instrument } = tradableInstrument;
|
||||
const { decimals } = instrument.product.settlementAsset;
|
||||
const calculatorParams = {
|
||||
positionDecimalPlaces,
|
||||
decimalPlaces,
|
||||
decimals,
|
||||
scalingFactors: marginCalculator?.scalingFactors,
|
||||
riskFactors,
|
||||
};
|
||||
if (openVolume !== '0') {
|
||||
const { initialMargin } = calculateMargins({
|
||||
side: shortPosition ? Side.SIDE_SELL : Side.SIDE_BUY,
|
||||
size: openVolume,
|
||||
price: marketData.markPrice,
|
||||
...calculatorParams,
|
||||
});
|
||||
if (shortPosition) {
|
||||
sellInitialMargin += BigInt(initialMargin);
|
||||
} else {
|
||||
buyInitialMargin += BigInt(initialMargin);
|
||||
}
|
||||
}
|
||||
orders?.forEach((order) => {
|
||||
if (!order) {
|
||||
return;
|
||||
}
|
||||
const { side, remaining: size } = order.node;
|
||||
const initialMargin = BigInt(
|
||||
calculateMargins({
|
||||
side,
|
||||
size,
|
||||
price: marketData.markPrice, //getDerivedPrice(order.node, marketData), same use-initial-margin
|
||||
...calculatorParams,
|
||||
}).initialMargin
|
||||
);
|
||||
if (order.node.side === Side.SIDE_BUY) {
|
||||
buyVolume += BigInt(size);
|
||||
buyInitialMargin += initialMargin;
|
||||
} else {
|
||||
sellVolume += BigInt(size);
|
||||
sellInitialMargin += initialMargin;
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
buyVolume: buyVolume.toString(),
|
||||
sellVolume: sellVolume.toString(),
|
||||
buyInitialMargin: buyInitialMargin.toString(),
|
||||
sellInitialMargin: sellInitialMargin.toString(),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { openVolumeDataProvider } from './positions-data-providers';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export const useOpenVolume = (
|
||||
partyId: string | null | undefined,
|
||||
marketId: string
|
||||
) => {
|
||||
const [openVolume, setOpenVolume] = useState<string | undefined>(undefined);
|
||||
const update = useCallback(({ data }: { data: string | null }) => {
|
||||
setOpenVolume(data ?? undefined);
|
||||
return true;
|
||||
}, []);
|
||||
useDataProvider({
|
||||
dataProvider: openVolumeDataProvider,
|
||||
update,
|
||||
variables: { partyId: partyId || '', marketId },
|
||||
skip: !partyId,
|
||||
});
|
||||
return openVolume;
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import type { RefObject } from 'react';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import type { Position } from './positions-data-providers';
|
||||
import { positionsMetricsProvider } from './positions-data-providers';
|
||||
import type { PositionsMetricsProviderVariables } from './positions-data-providers';
|
||||
import type { PositionsQueryVariables } from './__generated__/Positions';
|
||||
import { useDataProvider, updateGridData } from '@vegaprotocol/react-helpers';
|
||||
import type { GetRowsParams } from '@vegaprotocol/datagrid';
|
||||
|
||||
@@ -14,7 +14,7 @@ export const usePositionsData = (
|
||||
gridRef: RefObject<AgGridReact>,
|
||||
clientSideModel?: boolean
|
||||
) => {
|
||||
const variables = useMemo<PositionsMetricsProviderVariables>(
|
||||
const variables = useMemo<PositionsQueryVariables>(
|
||||
() => ({ partyId }),
|
||||
[partyId]
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { makeDataProvider } from '@vegaprotocol/utils';
|
||||
import type {
|
||||
ProposalsListQuery,
|
||||
ProposalsListQueryVariables,
|
||||
ProposalListFieldsFragment,
|
||||
} from './__generated__/Proposals';
|
||||
import { ProposalsListDocument } from './__generated__/Proposals';
|
||||
@@ -14,5 +15,6 @@ export const proposalsDataProvider = makeDataProvider<
|
||||
ProposalsListQuery,
|
||||
ProposalListFieldsFragment[],
|
||||
never,
|
||||
never
|
||||
never,
|
||||
ProposalsListQueryVariables
|
||||
>({ query: ProposalsListDocument, getData });
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
import { proposalsDataProvider } from '../proposals-data-provider';
|
||||
import { useCallback, useMemo, useRef } from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { useColumnDefs } from './use-column-defs';
|
||||
import type { ProposalListFieldsFragment } from '../proposals-data-provider/__generated__/Proposals';
|
||||
@@ -22,14 +22,11 @@ export const ProposalsList = () => {
|
||||
const handleOnGridReady = useCallback(() => {
|
||||
gridRef.current?.api?.sizeColumnsToFit();
|
||||
}, [gridRef]);
|
||||
const variables = useMemo(() => {
|
||||
return {
|
||||
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
|
||||
};
|
||||
}, []);
|
||||
const { data, loading, error, reload } = useDataProvider({
|
||||
dataProvider: proposalsDataProvider,
|
||||
variables,
|
||||
variables: {
|
||||
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
|
||||
},
|
||||
});
|
||||
const filteredData = getNewMarketProposals(data || []);
|
||||
const { columnDefs, defaultColDef } = useColumnDefs();
|
||||
|
||||
@@ -6,6 +6,7 @@ import { MockedProvider } from '@apollo/client/testing';
|
||||
|
||||
type Data = number;
|
||||
type Delta = number;
|
||||
type Variables = { partyId: string };
|
||||
|
||||
const unsubscribe = jest.fn();
|
||||
const reload = jest.fn();
|
||||
@@ -23,8 +24,8 @@ const updateCallbackPayload: Parameters<UpdateCallback<Data, Delta>>['0'] = {
|
||||
};
|
||||
|
||||
const dataProvider = jest.fn<
|
||||
ReturnType<Subscribe<Data, Delta>>,
|
||||
Parameters<Subscribe<Data, Delta>>
|
||||
ReturnType<Subscribe<Data, Delta, Variables>>,
|
||||
Parameters<Subscribe<Data, Delta, Variables>>
|
||||
>();
|
||||
|
||||
dataProvider.mockReturnValue({
|
||||
@@ -37,10 +38,12 @@ dataProvider.mockReturnValue({
|
||||
jest.useFakeTimers();
|
||||
|
||||
describe('useDataProvider hook', () => {
|
||||
const render = (initialProps?: useDataProviderParams<Data, Delta>) =>
|
||||
const render = (
|
||||
initialProps?: useDataProviderParams<Data, Delta, Variables>
|
||||
) =>
|
||||
renderHook<
|
||||
ReturnType<typeof useDataProvider>,
|
||||
useDataProviderParams<Data, Delta>
|
||||
useDataProviderParams<Data, Delta, Variables>
|
||||
>((props) => useDataProvider(props), {
|
||||
wrapper: MockedProvider,
|
||||
initialProps,
|
||||
@@ -224,6 +227,7 @@ describe('useThrottledDataProvider hook', () => {
|
||||
useThrottledDataProvider(
|
||||
{
|
||||
dataProvider,
|
||||
variables,
|
||||
},
|
||||
wait
|
||||
),
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { Subscribe, Load, UpdateCallback } from '@vegaprotocol/utils';
|
||||
export interface useDataProviderParams<
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> {
|
||||
dataProvider: Subscribe<Data, Delta, Variables>;
|
||||
update?: ({
|
||||
@@ -30,7 +30,7 @@ export interface useDataProviderParams<
|
||||
data: Data | null;
|
||||
totalCount?: number;
|
||||
}) => boolean;
|
||||
variables?: Variables;
|
||||
variables: Variables;
|
||||
skipUpdates?: boolean;
|
||||
skip?: boolean;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ export interface useDataProviderParams<
|
||||
export const useDataProvider = <
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
>({
|
||||
dataProvider,
|
||||
update,
|
||||
@@ -163,8 +163,12 @@ export const useDataProvider = <
|
||||
};
|
||||
};
|
||||
|
||||
export const useThrottledDataProvider = <Data, Delta>(
|
||||
params: Omit<useDataProviderParams<Data, Delta>, 'update'>,
|
||||
export const useThrottledDataProvider = <
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
>(
|
||||
params: Omit<useDataProviderParams<Data, Delta, Variables>, 'update'>,
|
||||
wait?: number
|
||||
) => {
|
||||
const [data, setData] = useState<Data | null>(null);
|
||||
|
||||
@@ -2,12 +2,11 @@ import { makeInfiniteScrollGetRows } from '@vegaprotocol/utils';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { useCallback, useMemo, useRef } from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import type { BodyScrollEvent, BodyScrollEndEvent } from 'ag-grid-community';
|
||||
import { MAX_TRADES, tradesWithMarketProvider } from './trades-data-provider';
|
||||
import { tradesWithMarketProvider } from './trades-data-provider';
|
||||
import { TradesTable } from './trades-table';
|
||||
import type { Trade, TradeEdge } from './trades-data-provider';
|
||||
import type { TradesQueryVariables } from './__generated__/Trades';
|
||||
import { useOrderStore } from '@vegaprotocol/orders';
|
||||
|
||||
interface TradesContainerProps {
|
||||
@@ -22,11 +21,6 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
||||
const scrolledToTop = useRef(true);
|
||||
const updateOrder = useOrderStore((store) => store.update);
|
||||
|
||||
const variables = useMemo<TradesQueryVariables>(
|
||||
() => ({ marketId, maxTrades: MAX_TRADES }),
|
||||
[marketId]
|
||||
);
|
||||
|
||||
const addNewRows = useCallback(() => {
|
||||
if (newRows.current === 0) {
|
||||
return;
|
||||
@@ -84,7 +78,7 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
||||
dataProvider: tradesWithMarketProvider,
|
||||
update,
|
||||
insert,
|
||||
variables,
|
||||
variables: { marketId },
|
||||
});
|
||||
totalCountRef.current = totalCount;
|
||||
const getRows = makeInfiniteScrollGetRows<TradeEdge>(
|
||||
|
||||
@@ -10,6 +10,7 @@ import type { Market } from '@vegaprotocol/market-list';
|
||||
import { marketsProvider } from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
TradesQuery,
|
||||
TradesQueryVariables,
|
||||
TradeFieldsFragment,
|
||||
TradesUpdateSubscription,
|
||||
} from './__generated__/Trades';
|
||||
@@ -67,10 +68,16 @@ const update = (
|
||||
export type Trade = Omit<TradeFieldsFragment, 'market'> & { market?: Market };
|
||||
export type TradeEdge = Edge<Trade>;
|
||||
|
||||
const getPageInfo = (responseData: TradesQuery): PageInfo | null =>
|
||||
responseData.market?.tradesConnection?.pageInfo || null;
|
||||
const getPageInfo = (responseData: TradesQuery | null): PageInfo | null =>
|
||||
responseData?.market?.tradesConnection?.pageInfo || null;
|
||||
|
||||
export const tradesProvider = makeDataProvider({
|
||||
export const tradesProvider = makeDataProvider<
|
||||
Parameters<typeof getData>['0'],
|
||||
ReturnType<typeof getData>,
|
||||
Parameters<typeof getDelta>['0'],
|
||||
ReturnType<typeof getDelta>,
|
||||
TradesQueryVariables
|
||||
>({
|
||||
query: TradesDocument,
|
||||
subscriptionQuery: TradesUpdateDocument,
|
||||
update,
|
||||
@@ -85,9 +92,13 @@ export const tradesProvider = makeDataProvider({
|
||||
|
||||
export const tradesWithMarketProvider = makeDerivedDataProvider<
|
||||
(TradeEdge | null)[],
|
||||
Trade[]
|
||||
Trade[],
|
||||
TradesQueryVariables
|
||||
>(
|
||||
[tradesProvider, marketsProvider],
|
||||
[
|
||||
tradesProvider,
|
||||
(callback, client) => marketsProvider(callback, client, undefined),
|
||||
],
|
||||
(partsData): (TradeEdge | null)[] | null => {
|
||||
const edges = partsData[0] as ReturnType<typeof getData>;
|
||||
return edges.map((edge) => {
|
||||
|
||||
@@ -45,10 +45,11 @@ type CombinedData = {
|
||||
|
||||
type SubscriptionData = QueryData;
|
||||
type Delta = Data;
|
||||
type Variables = { var: string };
|
||||
|
||||
const update = jest.fn<
|
||||
ReturnType<Update<Data, Delta>>,
|
||||
Parameters<Update<Data, Delta>>
|
||||
ReturnType<Update<Data, Delta, Variables>>,
|
||||
Parameters<Update<Data, Delta, Variables>>
|
||||
>();
|
||||
|
||||
const callback = jest.fn<
|
||||
@@ -66,7 +67,13 @@ const getData = jest.fn((r: QueryData | null) => r?.data || null);
|
||||
|
||||
const getDelta = jest.fn((r: SubscriptionData) => r.data);
|
||||
|
||||
const subscribe = makeDataProvider<QueryData, Data, SubscriptionData, Delta>({
|
||||
const subscribe = makeDataProvider<
|
||||
QueryData,
|
||||
Data,
|
||||
SubscriptionData,
|
||||
Delta,
|
||||
Variables
|
||||
>({
|
||||
query,
|
||||
subscriptionQuery,
|
||||
update,
|
||||
@@ -75,18 +82,18 @@ const subscribe = makeDataProvider<QueryData, Data, SubscriptionData, Delta>({
|
||||
});
|
||||
|
||||
const combineData = jest.fn<
|
||||
ReturnType<CombineDerivedData<CombinedData>>,
|
||||
Parameters<CombineDerivedData<CombinedData>>
|
||||
ReturnType<CombineDerivedData<CombinedData, Variables>>,
|
||||
Parameters<CombineDerivedData<CombinedData, Variables>>
|
||||
>();
|
||||
|
||||
const combineDelta = jest.fn<
|
||||
ReturnType<CombineDerivedDelta<CombinedData, CombinedData>>,
|
||||
Parameters<CombineDerivedDelta<CombinedData, CombinedData>>
|
||||
ReturnType<CombineDerivedDelta<CombinedData, CombinedData, Variables>>,
|
||||
Parameters<CombineDerivedDelta<CombinedData, CombinedData, Variables>>
|
||||
>();
|
||||
|
||||
const combineInsertionData = jest.fn<
|
||||
ReturnType<CombineInsertionData<CombinedData>>,
|
||||
Parameters<CombineInsertionData<CombinedData>>
|
||||
ReturnType<CombineInsertionData<CombinedData, Variables>>,
|
||||
Parameters<CombineInsertionData<CombinedData, Variables>>
|
||||
>();
|
||||
|
||||
const first = 100;
|
||||
@@ -94,7 +101,8 @@ const paginatedSubscribe = makeDataProvider<
|
||||
QueryData,
|
||||
Data,
|
||||
SubscriptionData,
|
||||
Delta
|
||||
Delta,
|
||||
Variables
|
||||
>({
|
||||
query,
|
||||
subscriptionQuery,
|
||||
@@ -116,7 +124,8 @@ const errorGuardedSubscribe = makeDataProvider<
|
||||
QueryData,
|
||||
Data,
|
||||
SubscriptionData,
|
||||
Delta
|
||||
Delta,
|
||||
Variables
|
||||
>({
|
||||
query,
|
||||
subscriptionQuery,
|
||||
@@ -210,6 +219,8 @@ const clearPendingQueries = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const variables = { var: 'val' };
|
||||
|
||||
describe('data provider', () => {
|
||||
beforeEach(() => {
|
||||
clearPendingQueries();
|
||||
@@ -220,7 +231,6 @@ describe('data provider', () => {
|
||||
clientSubscribeSubscribe.mockClear();
|
||||
});
|
||||
it('memoize instance and unsubscribe if no subscribers', () => {
|
||||
const variables = { var: 'val' };
|
||||
const subscription1 = subscribe(jest.fn(), client, variables);
|
||||
const subscription2 = subscribe(jest.fn(), client, { ...variables });
|
||||
// const subscription1 = subscribe(jest.fn(), client);
|
||||
@@ -234,7 +244,7 @@ describe('data provider', () => {
|
||||
|
||||
it('calls callback before and after initial fetch', async () => {
|
||||
const data: Item[] = [];
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
expect(callback.mock.calls.length).toBe(1);
|
||||
expect(callback.mock.calls[0][0].data).toBe(null);
|
||||
expect(callback.mock.calls[0][0].loading).toBe(true);
|
||||
@@ -246,7 +256,7 @@ describe('data provider', () => {
|
||||
});
|
||||
|
||||
it('calls callback on error', async () => {
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
expect(callback.mock.calls.length).toBe(1);
|
||||
expect(callback.mock.calls[0][0].data).toBe(null);
|
||||
expect(callback.mock.calls[0][0].loading).toBe(true);
|
||||
@@ -260,7 +270,7 @@ describe('data provider', () => {
|
||||
});
|
||||
|
||||
it('calls successful callback on NotFound error on party path', async () => {
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
expect(callback.mock.calls.length).toBe(1);
|
||||
expect(callback.mock.calls[0][0].data).toBe(null);
|
||||
expect(callback.mock.calls[0][0].loading).toBe(true);
|
||||
@@ -280,7 +290,7 @@ describe('data provider', () => {
|
||||
const data: Data = [];
|
||||
getData.mockReturnValueOnce(data);
|
||||
await rejectQuery(error);
|
||||
expect(getData).toHaveBeenCalledWith(null, undefined);
|
||||
expect(getData).toHaveBeenCalledWith(null, variables);
|
||||
expect(callback.mock.calls.length).toBe(2);
|
||||
expect(callback.mock.calls[1][0].data).toEqual(data);
|
||||
expect(callback.mock.calls[1][0].error).toEqual(undefined);
|
||||
@@ -290,7 +300,7 @@ describe('data provider', () => {
|
||||
|
||||
it('calls update and callback on each update', async () => {
|
||||
const data: Item[] = [];
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
await resolveQuery({ data });
|
||||
const delta: Item[] = [];
|
||||
update.mockImplementationOnce((data, delta) => [...(data || []), ...delta]);
|
||||
@@ -308,7 +318,7 @@ describe('data provider', () => {
|
||||
|
||||
it("don't calls callback on update if data doesn't change", async () => {
|
||||
const data: Item[] = [];
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
await resolveQuery({ data });
|
||||
const delta: Item[] = [];
|
||||
update.mockImplementationOnce((data) => data || []);
|
||||
@@ -325,7 +335,7 @@ describe('data provider', () => {
|
||||
|
||||
it('refetch data on reload', async () => {
|
||||
const data: Item[] = [];
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
await resolveQuery({ data });
|
||||
subscription.reload();
|
||||
await resolveQuery({ data });
|
||||
@@ -337,7 +347,7 @@ describe('data provider', () => {
|
||||
|
||||
it('refetch data and restart subscription on reload with force', async () => {
|
||||
const data: Item[] = [];
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
await resolveQuery({ data });
|
||||
subscription.reload(true);
|
||||
await resolveQuery({ data });
|
||||
@@ -349,7 +359,7 @@ describe('data provider', () => {
|
||||
|
||||
it('calls callback on flush', async () => {
|
||||
const data: Item[] = [];
|
||||
const subscription = subscribe(callback, client);
|
||||
const subscription = subscribe(callback, client, variables);
|
||||
await resolveQuery({ data });
|
||||
const callbackCallsLength = callback.mock.calls.length;
|
||||
subscription.flush();
|
||||
@@ -365,7 +375,7 @@ describe('data provider', () => {
|
||||
id: i.toString(),
|
||||
},
|
||||
}));
|
||||
const subscription = paginatedSubscribe(callback, client);
|
||||
const subscription = paginatedSubscribe(callback, client, variables);
|
||||
await resolveQuery({
|
||||
data,
|
||||
totalCount,
|
||||
@@ -379,7 +389,7 @@ describe('data provider', () => {
|
||||
|
||||
it('loads requested data blocks and inserts data with total count', async () => {
|
||||
const totalCount = 1000;
|
||||
const subscription = paginatedSubscribe(callback, client);
|
||||
const subscription = paginatedSubscribe(callback, client, variables);
|
||||
await resolveQuery({
|
||||
data: generateData(),
|
||||
totalCount,
|
||||
@@ -503,7 +513,7 @@ describe('data provider', () => {
|
||||
|
||||
it('loads requested data blocks and inserts data without totalCount', async () => {
|
||||
const totalCount = undefined;
|
||||
const subscription = paginatedSubscribe(callback, client);
|
||||
const subscription = paginatedSubscribe(callback, client, variables);
|
||||
await resolveQuery({
|
||||
data: generateData(),
|
||||
totalCount,
|
||||
@@ -542,7 +552,7 @@ describe('data provider', () => {
|
||||
});
|
||||
|
||||
it('sets total count when first page has no next page', async () => {
|
||||
const subscription = paginatedSubscribe(callback, client);
|
||||
const subscription = paginatedSubscribe(callback, client, variables);
|
||||
await resolveQuery({
|
||||
data: generateData(),
|
||||
pageInfo: {
|
||||
@@ -556,8 +566,8 @@ describe('data provider', () => {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
|
||||
it('errorPolicyGuard should work properly', async () => {
|
||||
const subscription = errorGuardedSubscribe(callback, client);
|
||||
it('should retry with ignore error policy if errorPolicyGuard returns true', async () => {
|
||||
const subscription = errorGuardedSubscribe(callback, client, variables);
|
||||
const graphQLError = new GraphQLError(
|
||||
'',
|
||||
undefined,
|
||||
@@ -579,7 +589,7 @@ describe('data provider', () => {
|
||||
});
|
||||
expect(mockErrorPolicyGuard).toHaveBeenNthCalledWith(1, graphQLErrors);
|
||||
await waitFor(() =>
|
||||
expect(getData).toHaveBeenCalledWith({ data }, undefined)
|
||||
expect(getData).toHaveBeenCalledWith({ data }, variables)
|
||||
);
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
@@ -589,7 +599,6 @@ describe('derived data provider', () => {
|
||||
it('memoize instance and unsubscribe if no subscribers', () => {
|
||||
clientSubscribeSubscribe.mockClear();
|
||||
clientSubscribeUnsubscribe.mockClear();
|
||||
const variables = {};
|
||||
const subscription1 = derivedSubscribe(jest.fn(), client, variables);
|
||||
const subscription2 = derivedSubscribe(jest.fn(), client, variables);
|
||||
expect(clientSubscribeSubscribe.mock.calls.length).toEqual(2);
|
||||
@@ -615,7 +624,7 @@ describe('derived data provider', () => {
|
||||
ReturnType<UpdateCallback<CombinedData, CombinedData>>,
|
||||
Parameters<UpdateCallback<CombinedData, CombinedData>>
|
||||
>();
|
||||
const subscription = derivedSubscribe(callback, client);
|
||||
const subscription = derivedSubscribe(callback, client, variables);
|
||||
const data = { totalCount: 0 };
|
||||
combineData.mockReturnValueOnce(data);
|
||||
expect(callback.mock.calls.length).toBe(0);
|
||||
@@ -642,7 +651,7 @@ describe('derived data provider', () => {
|
||||
Parameters<UpdateCallback<CombinedData, CombinedData>>
|
||||
>();
|
||||
expect(callback.mock.calls.length).toBe(0);
|
||||
const subscription = derivedSubscribe(callback, client);
|
||||
const subscription = derivedSubscribe(callback, client, variables);
|
||||
const data = { totalCount: 0 };
|
||||
combineData.mockReturnValueOnce(data);
|
||||
expect(callback.mock.calls.length).toBe(0);
|
||||
@@ -677,7 +686,7 @@ describe('derived data provider', () => {
|
||||
ReturnType<UpdateCallback<CombinedData, CombinedData>>,
|
||||
Parameters<UpdateCallback<CombinedData, CombinedData>>
|
||||
>();
|
||||
const subscription = derivedSubscribe(callback, client);
|
||||
const subscription = derivedSubscribe(callback, client, variables);
|
||||
const data = { totalCount: 0 };
|
||||
combineData.mockReturnValueOnce(data);
|
||||
await resolveQuery({ data: part1 });
|
||||
@@ -709,7 +718,7 @@ describe('derived data provider', () => {
|
||||
ReturnType<UpdateCallback<CombinedData, CombinedData>>,
|
||||
Parameters<UpdateCallback<CombinedData, CombinedData>>
|
||||
>();
|
||||
const subscription = derivedSubscribe(callback, client);
|
||||
const subscription = derivedSubscribe(callback, client, variables);
|
||||
const data = { totalCount: 0 };
|
||||
combineData.mockReturnValueOnce(data);
|
||||
await resolveQuery({
|
||||
|
||||
@@ -53,12 +53,12 @@ export interface PageInfo {
|
||||
export interface Subscribe<
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> {
|
||||
(
|
||||
callback: UpdateCallback<Data, Delta>,
|
||||
client: ApolloClient<object>,
|
||||
variables?: Variables
|
||||
variables: Variables
|
||||
): {
|
||||
unsubscribe: () => void;
|
||||
reload: Reload;
|
||||
@@ -73,14 +73,9 @@ export type Query<Result> = DocumentNode | TypedDocumentNode<Result, any>;
|
||||
export interface Update<
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> {
|
||||
(
|
||||
data: Data | null,
|
||||
delta: Delta,
|
||||
reload: Reload,
|
||||
variables?: Variables
|
||||
): Data;
|
||||
(data: Data | null, delta: Delta, reload: Reload, variables: Variables): Data;
|
||||
}
|
||||
|
||||
export interface Append<Data> {
|
||||
@@ -165,7 +160,7 @@ interface DataProviderParams<
|
||||
Data,
|
||||
SubscriptionData,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> {
|
||||
query: Query<QueryData>;
|
||||
subscriptionQuery?: Query<SubscriptionData>;
|
||||
@@ -200,7 +195,7 @@ function makeDataProviderInternal<
|
||||
Data,
|
||||
SubscriptionData,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
>({
|
||||
query,
|
||||
subscriptionQuery,
|
||||
@@ -225,7 +220,7 @@ function makeDataProviderInternal<
|
||||
const updateQueue: Delta[] = [];
|
||||
|
||||
let resetTimer: ReturnType<typeof setTimeout>;
|
||||
let variables: Variables | undefined;
|
||||
let variables: Variables;
|
||||
let data: Data | null = null;
|
||||
let error: Error | undefined;
|
||||
let loading = true;
|
||||
@@ -492,7 +487,9 @@ function makeDataProviderInternal<
|
||||
callbacks.push(callback);
|
||||
if (callbacks.length === 1) {
|
||||
client = c;
|
||||
variables = v;
|
||||
if (v) {
|
||||
variables = v;
|
||||
}
|
||||
initialize();
|
||||
} else {
|
||||
notify(callback);
|
||||
@@ -515,7 +512,7 @@ function makeDataProviderInternal<
|
||||
const memoize = <
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
>(
|
||||
fn: () => Subscribe<Data, Delta, Variables>
|
||||
) => {
|
||||
@@ -563,7 +560,7 @@ export function makeDataProvider<
|
||||
Data,
|
||||
SubscriptionData,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
>(
|
||||
params: DataProviderParams<
|
||||
QueryData,
|
||||
@@ -585,27 +582,27 @@ export function makeDataProvider<
|
||||
* This effects in parts in combine function has any[] type
|
||||
*/
|
||||
type DependencySubscribe<
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> = Subscribe<any, any, Variables>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
type DependencyUpdateCallback<
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> = Parameters<DependencySubscribe<Variables>>['0'];
|
||||
export type DerivedPart<
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> = Parameters<DependencyUpdateCallback<Variables>>['0'];
|
||||
export type CombineDerivedData<
|
||||
Data,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> = (
|
||||
data: DerivedPart<Variables>['data'][],
|
||||
variables: Variables | undefined,
|
||||
variables: Variables,
|
||||
prevData: Data | null
|
||||
) => Data | null;
|
||||
|
||||
export type CombineDerivedDelta<
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> = (
|
||||
data: Data,
|
||||
parts: DerivedPart<Variables>[],
|
||||
@@ -615,7 +612,7 @@ export type CombineDerivedDelta<
|
||||
|
||||
export type CombineInsertionData<
|
||||
Data,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
> = (
|
||||
data: Data,
|
||||
parts: DerivedPart<Variables>[],
|
||||
@@ -625,7 +622,7 @@ export type CombineInsertionData<
|
||||
function makeDerivedDataProviderInternal<
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
>(
|
||||
dependencies: DependencySubscribe<Variables>[],
|
||||
combineData: CombineDerivedData<Data, Variables>,
|
||||
@@ -635,7 +632,7 @@ function makeDerivedDataProviderInternal<
|
||||
let subscriptions: ReturnType<DependencySubscribe>[] | undefined;
|
||||
let client: ApolloClient<object>;
|
||||
const callbacks: UpdateCallback<Data, Delta>[] = [];
|
||||
let variables: Variables | undefined;
|
||||
let variables: Variables;
|
||||
const parts: DerivedPart<Variables>[] = [];
|
||||
let data: Data | null = null;
|
||||
let error: Error | undefined;
|
||||
@@ -756,7 +753,9 @@ function makeDerivedDataProviderInternal<
|
||||
callbacks.push(callback);
|
||||
if (callbacks.length === 1) {
|
||||
client = c;
|
||||
variables = v;
|
||||
if (v) {
|
||||
variables = v;
|
||||
}
|
||||
initialize();
|
||||
} else {
|
||||
notify(callback);
|
||||
@@ -777,7 +776,7 @@ function makeDerivedDataProviderInternal<
|
||||
export function makeDerivedDataProvider<
|
||||
Data,
|
||||
Delta,
|
||||
Variables extends OperationVariables = OperationVariables
|
||||
Variables extends OperationVariables | undefined = undefined
|
||||
>(
|
||||
dependencies: DependencySubscribe<Variables>[],
|
||||
combineData: CombineDerivedData<Data, Variables>,
|
||||
|
||||
@@ -29,12 +29,16 @@ export const encodeTransaction = (tx: Transaction): string => {
|
||||
);
|
||||
};
|
||||
|
||||
export const normalizeOrderSubmission = <T extends Exact<OrderSubmission, T>>(
|
||||
order: T,
|
||||
export const normalizeOrderSubmission = (
|
||||
order: OrderSubmission,
|
||||
decimalPlaces: number,
|
||||
positionDecimalPlaces: number
|
||||
): OrderSubmission => ({
|
||||
...order,
|
||||
marketId: order.marketId,
|
||||
reference: order.reference,
|
||||
type: order.type,
|
||||
side: order.side,
|
||||
timeInForce: order.timeInForce,
|
||||
price:
|
||||
order.type === OrderType.TYPE_LIMIT && order.price
|
||||
? removeDecimal(order.price, decimalPlaces)
|
||||
|
||||
@@ -19,10 +19,9 @@ export const WithdrawFormContainer = ({
|
||||
partyId,
|
||||
submit,
|
||||
}: WithdrawFormContainerProps) => {
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: accountsDataProvider,
|
||||
variables,
|
||||
variables: { partyId: partyId || '' },
|
||||
});
|
||||
|
||||
const filteredAsset = useMemo(
|
||||
|
||||
Reference in New Issue
Block a user