feat: 1537 LP view data provider subscriptions after 0.58 release (#1630)

* fix: #1537 add lp provider sub

* fix: change LP title & update party.id

* fix: #1537 fix obligation and supplied

* fix: #1537 add min width on accounts

* fix: #1537 consistent null check

* fix: #1537 update lp data providers

* fix:  add acounts data provider but requires party id

* feat: #1537 LP data provider -  marketID & query or subscribe for accounts - partyId

* fix: #1537 remove log and fix build

* fix: #1537 fix build console lite and lp dashboard

* fix: #1537 fix tsconfig lp dahsboard

* fix: #1537 use interval to poll LP data - sub not working yet
This commit is contained in:
m.ray 2022-10-24 20:42:53 +01:00 committed by GitHub
parent 630ef4a22d
commit 4d20151abd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 714 additions and 612 deletions

View File

@ -96,7 +96,7 @@ const OrdersManager = () => {
order={editOrder}
onSubmit={(fields) => {
setEditOrder(null);
orderEdit.edit({ price: fields.entryPrice });
orderEdit.edit({ price: fields.limitPrice });
}}
/>
)}

View File

@ -8,7 +8,7 @@
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noPropertyAccessFromIndexSignature": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},

View File

@ -1,19 +1,33 @@
import { LiquidityTable, useLiquidityProvision } from '@vegaprotocol/liquidity';
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
import { LiquidityProvisionStatus } from '@vegaprotocol/types';
import {
liquidityProvisionsDataProvider,
LiquidityTable,
lpAggregatedDataProvider,
marketLiquidityDataProvider,
} from '@vegaprotocol/liquidity';
import { tooltipMapping } from '@vegaprotocol/market-info';
import {
addDecimalsFormatNumber,
NetworkParams,
t,
useDataProvider,
useNetworkParam,
} from '@vegaprotocol/react-helpers';
import { Schema } from '@vegaprotocol/types';
import {
AsyncRenderer,
Link as UiToolkitLink,
Tab,
Tabs,
Link as UiToolkitLink,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import type { AgGridReact } from 'ag-grid-react';
import { Header, HeaderStat } from '../../components/header';
import { useRouter } from 'next/router';
import { useRef, useMemo } from 'react';
import { tooltipMapping } from '@vegaprotocol/market-info';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { Header, HeaderStat } from '../../components/header';
import type { AgGridReact } from 'ag-grid-react';
import type { LiquidityProvisionData } from '@vegaprotocol/liquidity';
const LiquidityPage = ({ id }: { id?: string }) => {
const { query } = useRouter();
@ -24,34 +38,81 @@ const LiquidityPage = ({ id }: { id?: string }) => {
const marketId =
id || (Array.isArray(query.marketId) ? query.marketId[0] : query.marketId);
const {
data: {
liquidityProviders,
suppliedStake,
targetStake,
name,
symbol,
assetDecimalPlaces,
const { data: marketProvision } = useDataProvider({
dataProvider: marketLiquidityDataProvider,
noUpdate: true,
variables: useMemo(() => ({ marketId }), [marketId]),
});
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
const { reload } = useDataProvider({
dataProvider: liquidityProvisionsDataProvider,
variables: useMemo(() => ({ marketId }), [marketId]),
});
const update = useCallback(
({ data }: { data: LiquidityProvisionData[] }) => {
if (!gridRef.current?.api) {
return false;
}
if (dataRef.current?.length) {
dataRef.current = data;
gridRef.current.api.refreshInfiniteCache();
return true;
}
return false;
},
[gridRef]
);
const {
data: liquidityProviders,
loading,
error,
} = useLiquidityProvision({ marketId });
} = useDataProvider({
dataProvider: lpAggregatedDataProvider,
update,
variables: useMemo(
() => ({ marketId, partyId: pubKey }),
[marketId, pubKey]
),
});
// To be removed when liquidityProvision subscriptions are working
useEffect(() => {
const interval = setInterval(reload, 10000);
return () => clearInterval(interval);
}, [reload]);
const targetStake = marketProvision?.market?.data?.targetStake;
const suppliedStake = marketProvision?.market?.data?.suppliedStake;
const assetDecimalPlaces =
marketProvision?.market?.tradableInstrument.instrument.product
.settlementAsset.decimals || 0;
const symbol =
marketProvision?.market?.tradableInstrument.instrument.product
.settlementAsset.symbol;
const { param: stakeToCcySiskas } = useNetworkParam(
NetworkParams.market_liquidity_stakeToCcySiskas
);
const stakeToCcySiska = stakeToCcySiskas && stakeToCcySiskas[0];
const myLpEdges = useMemo(
() => liquidityProviders.filter((e) => e.party === pubKey),
() => liquidityProviders?.filter((e) => e.party.id === pubKey),
[liquidityProviders, pubKey]
);
const activeEdges = useMemo(
() =>
liquidityProviders.filter(
(e) => e.status === LiquidityProvisionStatus.STATUS_ACTIVE
liquidityProviders?.filter(
(e) => e.status === Schema.LiquidityProvisionStatus.STATUS_ACTIVE
),
[liquidityProviders]
);
const inactiveEdges = useMemo(
() =>
liquidityProviders.filter(
(e) => e.status !== LiquidityProvisionStatus.STATUS_ACTIVE
liquidityProviders?.filter(
(e) => e.status !== Schema.LiquidityProvisionStatus.STATUS_ACTIVE
),
[liquidityProviders]
);
@ -63,9 +124,13 @@ const LiquidityPage = ({ id }: { id?: string }) => {
}
const getActiveDefaultId = () => {
if (myLpEdges?.length > 0) return LiquidityTabs.MyLiquidityProvision;
if (myLpEdges && myLpEdges.length > 0) {
return LiquidityTabs.MyLiquidityProvision;
}
if (activeEdges?.length) return LiquidityTabs.Active;
else if (inactiveEdges?.length > 0) return LiquidityTabs.Inactive;
else if (inactiveEdges && inactiveEdges.length > 0) {
return LiquidityTabs.Inactive;
}
return LiquidityTabs.Active;
};
@ -75,8 +140,10 @@ const LiquidityPage = ({ id }: { id?: string }) => {
<Header
title={
<Link href={`/markets/${marketId}`} passHref={true}>
<UiToolkitLink>
{`${name} ${t('liquidity provision')}`}
<UiToolkitLink className="sm:text-lg md:text-xl lg:text-2xl flex items-center gap-2 whitespace-nowrap hover:text-neutral-500 dark:hover:text-neutral-300">
{`${
marketProvision?.market?.tradableInstrument.instrument.name
} ${t('liquidity provision')}`}
</UiToolkitLink>
</Link>
}
@ -117,29 +184,40 @@ const LiquidityPage = ({ id }: { id?: string }) => {
name={t('My liquidity provision')}
hidden={!pubKey}
>
<LiquidityTable
ref={gridRef}
data={myLpEdges}
symbol={symbol}
assetDecimalPlaces={assetDecimalPlaces}
/>
{myLpEdges && (
<LiquidityTable
ref={gridRef}
data={myLpEdges}
symbol={symbol}
stakeToCcySiskas={stakeToCcySiska}
assetDecimalPlaces={assetDecimalPlaces}
/>
)}
</Tab>
<Tab id={LiquidityTabs.Active} name={t('Active')}>
<LiquidityTable
ref={gridRef}
data={activeEdges}
symbol={symbol}
assetDecimalPlaces={assetDecimalPlaces}
/>
</Tab>
<Tab id={LiquidityTabs.Inactive} name={t('Inactive')}>
<LiquidityTable
ref={gridRef}
data={inactiveEdges}
symbol={symbol}
assetDecimalPlaces={assetDecimalPlaces}
/>
{activeEdges && (
<LiquidityTable
ref={gridRef}
data={activeEdges}
symbol={symbol}
assetDecimalPlaces={assetDecimalPlaces}
stakeToCcySiskas={stakeToCcySiska}
/>
)}
</Tab>
{
<Tab id={LiquidityTabs.Inactive} name={t('Inactive')}>
{inactiveEdges && (
<LiquidityTable
ref={gridRef}
data={inactiveEdges}
symbol={symbol}
assetDecimalPlaces={assetDecimalPlaces}
stakeToCcySiskas={stakeToCcySiska}
/>
)}
</Tab>
}
</Tabs>
</div>
</AsyncRenderer>

View File

@ -1,23 +1,24 @@
import produce from 'immer';
import type { IterableElement } from 'type-fest';
import {
AccountsDocument,
AccountEventsDocument,
} from './__generated___/Accounts';
import type {
AccountFieldsFragment,
AccountsQuery,
AccountEventsSubscription,
} from './__generated___/Accounts';
import { assetsProvider } from '@vegaprotocol/assets';
import { marketsProvider } from '@vegaprotocol/market-list';
import {
makeDataProvider,
makeDerivedDataProvider,
} from '@vegaprotocol/react-helpers';
import { AccountType } from '@vegaprotocol/types';
import type { Market } from '@vegaprotocol/market-list';
import { marketsProvider } from '@vegaprotocol/market-list';
import produce from 'immer';
import { assetsProvider } from '@vegaprotocol/assets';
import {
AccountEventsDocument,
AccountsDocument,
} from './__generated___/Accounts';
import type { IterableElement } from 'type-fest';
import type {
AccountFieldsFragment,
AccountsQuery,
AccountEventsSubscription,
} from './__generated___/Accounts';
import type { Market } from '@vegaprotocol/market-list';
import type { Asset } from '@vegaprotocol/assets';
function isAccount(
@ -37,7 +38,7 @@ export const getId = (
| IterableElement<AccountEventsSubscription['accounts']>
) =>
isAccount(account)
? `${account.type}-${account.asset.id}-${account.market?.id ?? 'null'}`
? `${account.type}-${account.asset.id}-${account.market?.id || 'null'}`
: `${account.type}-${account.assetId}-${account.marketId || 'null'}`;
export type Account = Omit<AccountFieldsFragment, 'market' | 'asset'> & {
@ -76,7 +77,9 @@ const getData = (
const getDelta = (
subscriptionData: AccountEventsSubscription
): AccountEventsSubscription['accounts'] => subscriptionData.accounts;
): AccountEventsSubscription['accounts'] => {
return subscriptionData.accounts;
};
export const accountsOnlyDataProvider = makeDataProvider<
AccountsQuery,
@ -127,6 +130,7 @@ const getAssetAccountAggregation = (
accountList: Account[],
assetId: string
): AccountFields => {
console.log(accountList);
const accounts = accountList.filter((a) => a.asset.id === assetId);
const available = getTotalBalance(
accounts.filter((a) => a.type === AccountType.ACCOUNT_TYPE_GENERAL)

View File

@ -8,7 +8,7 @@
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noPropertyAccessFromIndexSignature": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},

View File

@ -44,7 +44,7 @@ export const compileGridData = (
);
grid.push({
label: isLiquidityMonitoringAuction
? t('Est auction end')
? t('Est. auction end')
: t('Auction end'),
value: isLiquidityMonitoringAuction ? `~${endDate}` : endDate,
});
@ -69,28 +69,31 @@ export const compileGridData = (
value: formatStake(market.data.suppliedStake),
});
}
if (market.data?.indicativePrice) {
grid.push({
label: t('Est uncrossing price'),
label: t('Est. uncrossing price'),
value:
'~' +
addDecimalsFormatNumber(
market.data.indicativePrice,
market.decimalPlaces
),
market.data.indicativePrice && market.data.indicativePrice !== '0'
? `~
${addDecimalsFormatNumber(
market.data.indicativePrice,
market.decimalPlaces
)}`
: '-',
});
}
if (market.data?.indicativeVolume) {
grid.push({
label: t('Est uncrossing vol'),
label: t('Est. uncrossing vol'),
value:
'~' +
addDecimalsFormatNumber(
market.data.indicativeVolume,
market.positionDecimalPlaces
),
market.data.indicativeVolume && market.data.indicativeVolume !== '0'
? '~' +
addDecimalsFormatNumber(
market.data.indicativeVolume,
market.positionDecimalPlaces
)
: '-',
});
}

View File

@ -1,31 +1,10 @@
query MarketLiquidity($marketId: ID!) {
# MarketLp
query MarketLp($marketId: ID!) {
market(id: $marketId) {
id
decimalPlaces
positionDecimalPlaces
liquidityProvisionsConnection {
edges {
node {
id
party {
id
accountsConnection(marketId: $marketId, type: ACCOUNT_TYPE_BOND) {
edges {
node {
type
balance
}
}
}
}
createdAt
updatedAt
commitmentAmount
fee
status
}
}
}
tradableInstrument {
instrument {
code
@ -49,13 +28,86 @@ query MarketLiquidity($marketId: ID!) {
openInterest
targetStake
marketValueProxy
liquidityProviderFeeShare {
party {
id
}
}
}
# Liquidity Provisions
fragment LiquidityProvisionFields on LiquidityProvision {
party {
id
accountsConnection(marketId: $marketId, type: ACCOUNT_TYPE_BOND) {
edges {
node {
type
balance
}
}
}
}
createdAt
updatedAt
commitmentAmount
fee
status
}
query LiquidityProvisions($marketId: ID!) {
market(id: $marketId) {
liquidityProvisionsConnection {
edges {
node {
...LiquidityProvisionFields
}
equityLikeShare
averageEntryValuation
}
}
}
}
subscription LiquidityProvisionsUpdate($partyId: ID, $marketId: ID) {
liquidityProvisions(partyId: $partyId, marketId: $marketId) {
id
partyID
createdAt
updatedAt
marketID
commitmentAmount
fee
status
}
}
# Liquidity Provider Share Fee
fragment LiquidityProviderFeeShareFields on LiquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
query LiquidityProviderFeeShare($marketId: ID!) {
market(id: $marketId) {
id
data {
market {
id
}
liquidityProviderFeeShare {
...LiquidityProviderFeeShareFields
}
}
}
}
subscription LiquidityProviderFeeShareUpdate($marketId: ID!) {
marketsData(marketIds: [$marketId]) {
liquidityProviderFeeShare {
partyId
equityLikeShare
averageEntryValuation
}
}
}

View File

@ -1,255 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
import { AccountType, LiquidityProvisionStatus } from "@vegaprotocol/types";
// ====================================================
// GraphQL query operation: MarketLiquidity
// ====================================================
export interface MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party_accountsConnection_edges_node {
__typename: "Account";
/**
* Account type (General, Margin, etc)
*/
type: AccountType;
/**
* Balance as string - current account balance (approx. as balances can be updated several times per second)
*/
balance: string;
}
export interface MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party_accountsConnection_edges {
__typename: "AccountEdge";
/**
* The account
*/
node: MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party_accountsConnection_edges_node;
}
export interface MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party_accountsConnection {
__typename: "AccountsConnection";
/**
* List of accounts available for the connection
*/
edges: (MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party_accountsConnection_edges | null)[] | null;
}
export interface MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party {
__typename: "Party";
/**
* Party identifier
*/
id: string;
/**
* Collateral accounts relating to a party
*/
accountsConnection: MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party_accountsConnection | null;
}
export interface MarketLiquidity_market_liquidityProvisionsConnection_edges_node {
__typename: "LiquidityProvision";
/**
* Unique identifier for the order (set by the system after consensus)
*/
id: string | null;
/**
* The party making this commitment
*/
party: MarketLiquidity_market_liquidityProvisionsConnection_edges_node_party;
/**
* When the liquidity provision was initially created (formatted RFC3339)
*/
createdAt: string;
/**
* RFC3339Nano time of when the liquidity provision was updated
*/
updatedAt: string | null;
/**
* Specified as a unit-less number that represents the amount of settlement asset of the market.
*/
commitmentAmount: string;
/**
* Nominated liquidity fee factor, which is an input to the calculation of liquidity fees on the market, as per setting fees and rewarding liquidity providers.
*/
fee: string;
/**
* The current status of this liquidity provision
*/
status: LiquidityProvisionStatus;
}
export interface MarketLiquidity_market_liquidityProvisionsConnection_edges {
__typename: "LiquidityProvisionsEdge";
node: MarketLiquidity_market_liquidityProvisionsConnection_edges_node;
}
export interface MarketLiquidity_market_liquidityProvisionsConnection {
__typename: "LiquidityProvisionsConnection";
edges: (MarketLiquidity_market_liquidityProvisionsConnection_edges | null)[] | null;
}
export interface MarketLiquidity_market_tradableInstrument_instrument_product_settlementAsset {
__typename: "Asset";
/**
* The ID of the asset
*/
id: string;
/**
* The symbol of the asset (e.g: GBP)
*/
symbol: string;
/**
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
*/
decimals: number;
}
export interface MarketLiquidity_market_tradableInstrument_instrument_product {
__typename: "Future";
/**
* The name of the asset (string)
*/
settlementAsset: MarketLiquidity_market_tradableInstrument_instrument_product_settlementAsset;
}
export interface MarketLiquidity_market_tradableInstrument_instrument {
__typename: "Instrument";
/**
* A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string)
*/
code: string;
/**
* Full and fairly descriptive name for the instrument
*/
name: string;
/**
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
*/
product: MarketLiquidity_market_tradableInstrument_instrument_product;
}
export interface MarketLiquidity_market_tradableInstrument {
__typename: "TradableInstrument";
/**
* An instance of, or reference to, a fully specified instrument.
*/
instrument: MarketLiquidity_market_tradableInstrument_instrument;
}
export interface MarketLiquidity_market_data_market {
__typename: "Market";
/**
* Market ID
*/
id: string;
}
export interface MarketLiquidity_market_data_liquidityProviderFeeShare_party {
__typename: "Party";
/**
* Party identifier
*/
id: string;
}
export interface MarketLiquidity_market_data_liquidityProviderFeeShare {
__typename: "LiquidityProviderFeeShare";
/**
* The liquidity provider party ID
*/
party: MarketLiquidity_market_data_liquidityProviderFeeShare_party;
/**
* The share owned by this liquidity provider (float)
*/
equityLikeShare: string;
/**
* The average entry valuation of the liquidity provider for the market
*/
averageEntryValuation: string;
}
export interface MarketLiquidity_market_data {
__typename: "MarketData";
/**
* Market of the associated mark price
*/
market: MarketLiquidity_market_data_market;
/**
* The supplied stake for the market
*/
suppliedStake: string | null;
/**
* The sum of the size of all positions greater than 0.
*/
openInterest: string;
/**
* The amount of stake targeted for this market
*/
targetStake: string | null;
/**
* The market value proxy
*/
marketValueProxy: string;
/**
* The equity like share of liquidity fee for each liquidity provider
*/
liquidityProviderFeeShare: MarketLiquidity_market_data_liquidityProviderFeeShare[] | null;
}
export interface MarketLiquidity_market {
__typename: "Market";
/**
* Market ID
*/
id: string;
/**
* The number of decimal places that an integer must be shifted by in order to get a correct
* number denominated in the currency of the market. (uint64)
*
* Examples:
* Currency Balance decimalPlaces Real Balance
* GBP 100 0 GBP 100
* GBP 100 2 GBP 1.00
* GBP 100 4 GBP 0.01
* GBP 1 4 GBP 0.0001 ( 0.01p )
*
* GBX (pence) 100 0 GBP 1.00 (100p )
* GBX (pence) 100 2 GBP 0.01 ( 1p )
* GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/
decimalPlaces: number;
/**
* The number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
* This sets how big the smallest order / position on the market can be.
*/
positionDecimalPlaces: number;
/**
* The list of the liquidity provision commitments for this market
*/
liquidityProvisionsConnection: MarketLiquidity_market_liquidityProvisionsConnection | null;
/**
* An instance of, or reference to, a tradable instrument.
*/
tradableInstrument: MarketLiquidity_market_tradableInstrument;
/**
* marketData for the given market
*/
data: MarketLiquidity_market_data | null;
}
export interface MarketLiquidity {
/**
* An instrument that is trading on the Vega network
*/
market: MarketLiquidity_market | null;
}
export interface MarketLiquidityVariables {
marketId: string;
}

View File

@ -1,2 +0,0 @@
export * from './MarketLiquidity';
export * from './LiquidityProvisionMarkets';

View File

@ -3,43 +3,81 @@ import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketLiquidityQueryVariables = Types.Exact<{
export type MarketLpQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type MarketLiquidityQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, liquidityProvisionsConnection?: { __typename?: 'LiquidityProvisionsConnection', edges?: Array<{ __typename?: 'LiquidityProvisionsEdge', node: { __typename?: 'LiquidityProvision', id?: string | null, createdAt: string, updatedAt?: string | null, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus, party: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'Account', type: Types.AccountType, balance: string } } | null> | null } | null } } } | null> | null } | null, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', code: string, name: string, product: { __typename?: 'Future', settlementAsset: { __typename?: 'Asset', id: string, symbol: string, decimals: number } } } }, data?: { __typename?: 'MarketData', suppliedStake?: string | null, openInterest: string, targetStake?: string | null, marketValueProxy: string, market: { __typename?: 'Market', id: string }, liquidityProviderFeeShare?: Array<{ __typename?: 'LiquidityProviderFeeShare', equityLikeShare: string, averageEntryValuation: string, party: { __typename?: 'Party', id: string } }> | null } | null } | null };
export type MarketLpQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', code: string, name: string, product: { __typename?: 'Future', settlementAsset: { __typename?: 'Asset', id: string, symbol: string, decimals: number } } } }, data?: { __typename?: 'MarketData', suppliedStake?: string | null, openInterest: string, targetStake?: string | null, marketValueProxy: string, market: { __typename?: 'Market', id: string } } | null } | null };
export type LiquidityProvisionFieldsFragment = { __typename?: 'LiquidityProvision', createdAt: string, updatedAt?: string | null, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus, party: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'Account', type: Types.AccountType, balance: string } } | null> | null } | null } };
export type LiquidityProvisionsQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export const MarketLiquidityDocument = gql`
query MarketLiquidity($marketId: ID!) {
export type LiquidityProvisionsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', liquidityProvisionsConnection?: { __typename?: 'LiquidityProvisionsConnection', edges?: Array<{ __typename?: 'LiquidityProvisionsEdge', node: { __typename?: 'LiquidityProvision', createdAt: string, updatedAt?: string | null, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus, party: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'Account', type: Types.AccountType, balance: string } } | null> | null } | null } } } | null> | null } | null } | null };
export type LiquidityProvisionsUpdateSubscriptionVariables = Types.Exact<{
partyId?: Types.InputMaybe<Types.Scalars['ID']>;
marketId?: Types.InputMaybe<Types.Scalars['ID']>;
}>;
export type LiquidityProvisionsUpdateSubscription = { __typename?: 'Subscription', liquidityProvisions?: Array<{ __typename?: 'LiquidityProvisionUpdate', id?: string | null, partyID: string, createdAt: string, updatedAt?: string | null, marketID: string, commitmentAmount: string, fee: string, status: Types.LiquidityProvisionStatus }> | null };
export type LiquidityProviderFeeShareFieldsFragment = { __typename?: 'LiquidityProviderFeeShare', equityLikeShare: string, averageEntryValuation: string, party: { __typename?: 'Party', id: string } };
export type LiquidityProviderFeeShareQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type LiquidityProviderFeeShareQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, data?: { __typename?: 'MarketData', market: { __typename?: 'Market', id: string }, liquidityProviderFeeShare?: Array<{ __typename?: 'LiquidityProviderFeeShare', equityLikeShare: string, averageEntryValuation: string, party: { __typename?: 'Party', id: string } }> | null } | null } | null };
export type LiquidityProviderFeeShareUpdateSubscriptionVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type LiquidityProviderFeeShareUpdateSubscription = { __typename?: 'Subscription', marketsData: Array<{ __typename?: 'ObservableMarketData', liquidityProviderFeeShare?: Array<{ __typename?: 'ObservableLiquidityProviderFeeShare', partyId: string, equityLikeShare: string, averageEntryValuation: string }> | null }> };
export const LiquidityProvisionFieldsFragmentDoc = gql`
fragment LiquidityProvisionFields on LiquidityProvision {
party {
id
accountsConnection(marketId: $marketId, type: ACCOUNT_TYPE_BOND) {
edges {
node {
type
balance
}
}
}
}
createdAt
updatedAt
commitmentAmount
fee
status
}
`;
export const LiquidityProviderFeeShareFieldsFragmentDoc = gql`
fragment LiquidityProviderFeeShareFields on LiquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
`;
export const MarketLpDocument = gql`
query MarketLp($marketId: ID!) {
market(id: $marketId) {
id
decimalPlaces
positionDecimalPlaces
liquidityProvisionsConnection {
edges {
node {
id
party {
id
accountsConnection(marketId: $marketId, type: ACCOUNT_TYPE_BOND) {
edges {
node {
type
balance
}
}
}
}
createdAt
updatedAt
commitmentAmount
fee
status
}
}
}
tradableInstrument {
instrument {
code
@ -63,42 +101,191 @@ export const MarketLiquidityDocument = gql`
openInterest
targetStake
marketValueProxy
liquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
}
}
}
`;
/**
* __useMarketLiquidityQuery__
* __useMarketLpQuery__
*
* To run a query within a React component, call `useMarketLiquidityQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketLiquidityQuery` returns an object from Apollo Client that contains loading, error, and data properties
* To run a query within a React component, call `useMarketLpQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketLpQuery` 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 } = useMarketLiquidityQuery({
* const { data, loading, error } = useMarketLpQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useMarketLiquidityQuery(baseOptions: Apollo.QueryHookOptions<MarketLiquidityQuery, MarketLiquidityQueryVariables>) {
export function useMarketLpQuery(baseOptions: Apollo.QueryHookOptions<MarketLpQuery, MarketLpQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketLiquidityQuery, MarketLiquidityQueryVariables>(MarketLiquidityDocument, options);
return Apollo.useQuery<MarketLpQuery, MarketLpQueryVariables>(MarketLpDocument, options);
}
export function useMarketLiquidityLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketLiquidityQuery, MarketLiquidityQueryVariables>) {
export function useMarketLpLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketLpQuery, MarketLpQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketLiquidityQuery, MarketLiquidityQueryVariables>(MarketLiquidityDocument, options);
return Apollo.useLazyQuery<MarketLpQuery, MarketLpQueryVariables>(MarketLpDocument, options);
}
export type MarketLiquidityQueryHookResult = ReturnType<typeof useMarketLiquidityQuery>;
export type MarketLiquidityLazyQueryHookResult = ReturnType<typeof useMarketLiquidityLazyQuery>;
export type MarketLiquidityQueryResult = Apollo.QueryResult<MarketLiquidityQuery, MarketLiquidityQueryVariables>;
export type MarketLpQueryHookResult = ReturnType<typeof useMarketLpQuery>;
export type MarketLpLazyQueryHookResult = ReturnType<typeof useMarketLpLazyQuery>;
export type MarketLpQueryResult = Apollo.QueryResult<MarketLpQuery, MarketLpQueryVariables>;
export const LiquidityProvisionsDocument = gql`
query LiquidityProvisions($marketId: ID!) {
market(id: $marketId) {
liquidityProvisionsConnection {
edges {
node {
...LiquidityProvisionFields
}
}
}
}
}
${LiquidityProvisionFieldsFragmentDoc}`;
/**
* __useLiquidityProvisionsQuery__
*
* To run a query within a React component, call `useLiquidityProvisionsQuery` and pass it any options that fit your needs.
* When your component renders, `useLiquidityProvisionsQuery` 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 } = useLiquidityProvisionsQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useLiquidityProvisionsQuery(baseOptions: Apollo.QueryHookOptions<LiquidityProvisionsQuery, LiquidityProvisionsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<LiquidityProvisionsQuery, LiquidityProvisionsQueryVariables>(LiquidityProvisionsDocument, options);
}
export function useLiquidityProvisionsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<LiquidityProvisionsQuery, LiquidityProvisionsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<LiquidityProvisionsQuery, LiquidityProvisionsQueryVariables>(LiquidityProvisionsDocument, options);
}
export type LiquidityProvisionsQueryHookResult = ReturnType<typeof useLiquidityProvisionsQuery>;
export type LiquidityProvisionsLazyQueryHookResult = ReturnType<typeof useLiquidityProvisionsLazyQuery>;
export type LiquidityProvisionsQueryResult = Apollo.QueryResult<LiquidityProvisionsQuery, LiquidityProvisionsQueryVariables>;
export const LiquidityProvisionsUpdateDocument = gql`
subscription LiquidityProvisionsUpdate($partyId: ID, $marketId: ID) {
liquidityProvisions(partyId: $partyId, marketId: $marketId) {
id
partyID
createdAt
updatedAt
marketID
commitmentAmount
fee
status
}
}
`;
/**
* __useLiquidityProvisionsUpdateSubscription__
*
* To run a query within a React component, call `useLiquidityProvisionsUpdateSubscription` and pass it any options that fit your needs.
* When your component renders, `useLiquidityProvisionsUpdateSubscription` 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 subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useLiquidityProvisionsUpdateSubscription({
* variables: {
* partyId: // value for 'partyId'
* marketId: // value for 'marketId'
* },
* });
*/
export function useLiquidityProvisionsUpdateSubscription(baseOptions?: Apollo.SubscriptionHookOptions<LiquidityProvisionsUpdateSubscription, LiquidityProvisionsUpdateSubscriptionVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useSubscription<LiquidityProvisionsUpdateSubscription, LiquidityProvisionsUpdateSubscriptionVariables>(LiquidityProvisionsUpdateDocument, options);
}
export type LiquidityProvisionsUpdateSubscriptionHookResult = ReturnType<typeof useLiquidityProvisionsUpdateSubscription>;
export type LiquidityProvisionsUpdateSubscriptionResult = Apollo.SubscriptionResult<LiquidityProvisionsUpdateSubscription>;
export const LiquidityProviderFeeShareDocument = gql`
query LiquidityProviderFeeShare($marketId: ID!) {
market(id: $marketId) {
id
data {
market {
id
}
liquidityProviderFeeShare {
...LiquidityProviderFeeShareFields
}
}
}
}
${LiquidityProviderFeeShareFieldsFragmentDoc}`;
/**
* __useLiquidityProviderFeeShareQuery__
*
* To run a query within a React component, call `useLiquidityProviderFeeShareQuery` and pass it any options that fit your needs.
* When your component renders, `useLiquidityProviderFeeShareQuery` 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 } = useLiquidityProviderFeeShareQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useLiquidityProviderFeeShareQuery(baseOptions: Apollo.QueryHookOptions<LiquidityProviderFeeShareQuery, LiquidityProviderFeeShareQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<LiquidityProviderFeeShareQuery, LiquidityProviderFeeShareQueryVariables>(LiquidityProviderFeeShareDocument, options);
}
export function useLiquidityProviderFeeShareLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<LiquidityProviderFeeShareQuery, LiquidityProviderFeeShareQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<LiquidityProviderFeeShareQuery, LiquidityProviderFeeShareQueryVariables>(LiquidityProviderFeeShareDocument, options);
}
export type LiquidityProviderFeeShareQueryHookResult = ReturnType<typeof useLiquidityProviderFeeShareQuery>;
export type LiquidityProviderFeeShareLazyQueryHookResult = ReturnType<typeof useLiquidityProviderFeeShareLazyQuery>;
export type LiquidityProviderFeeShareQueryResult = Apollo.QueryResult<LiquidityProviderFeeShareQuery, LiquidityProviderFeeShareQueryVariables>;
export const LiquidityProviderFeeShareUpdateDocument = gql`
subscription LiquidityProviderFeeShareUpdate($marketId: ID!) {
marketsData(marketIds: [$marketId]) {
liquidityProviderFeeShare {
partyId
equityLikeShare
averageEntryValuation
}
}
}
`;
/**
* __useLiquidityProviderFeeShareUpdateSubscription__
*
* To run a query within a React component, call `useLiquidityProviderFeeShareUpdateSubscription` and pass it any options that fit your needs.
* When your component renders, `useLiquidityProviderFeeShareUpdateSubscription` 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 subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useLiquidityProviderFeeShareUpdateSubscription({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useLiquidityProviderFeeShareUpdateSubscription(baseOptions: Apollo.SubscriptionHookOptions<LiquidityProviderFeeShareUpdateSubscription, LiquidityProviderFeeShareUpdateSubscriptionVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useSubscription<LiquidityProviderFeeShareUpdateSubscription, LiquidityProviderFeeShareUpdateSubscriptionVariables>(LiquidityProviderFeeShareUpdateDocument, options);
}
export type LiquidityProviderFeeShareUpdateSubscriptionHookResult = ReturnType<typeof useLiquidityProviderFeeShareUpdateSubscription>;
export type LiquidityProviderFeeShareUpdateSubscriptionResult = Apollo.SubscriptionResult<LiquidityProviderFeeShareUpdateSubscription>;

View File

@ -1,4 +1,4 @@
export * from './__generated__';
export * from './__generated___/MarketLiquidity';
export * from './liquidity-data-provider';
export * from './liquidity-table';
export * from './markets-liquidity-provider';

View File

@ -1,175 +1,194 @@
import { gql, useQuery } from '@apollo/client';
import type { LiquidityProvisionStatus } from '@vegaprotocol/types';
import { accountsDataProvider } from '@vegaprotocol/accounts';
import {
makeDataProvider,
makeDerivedDataProvider,
} from '@vegaprotocol/react-helpers';
import { AccountType } from '@vegaprotocol/types';
import { useNetworkParam, NetworkParams } from '@vegaprotocol/react-helpers';
import BigNumber from 'bignumber.js';
import produce from 'immer';
import {
LiquidityProviderFeeShareDocument,
LiquidityProviderFeeShareUpdateDocument,
LiquidityProvisionsDocument,
LiquidityProvisionsUpdateDocument,
MarketLpDocument,
} from './__generated___/MarketLiquidity';
import type {
MarketLiquidity,
MarketLiquidity_market_data_liquidityProviderFeeShare,
} from './__generated__';
const MARKET_LIQUIDITY_QUERY = gql`
query MarketLiquidity($marketId: ID!) {
market(id: $marketId) {
id
decimalPlaces
positionDecimalPlaces
liquidityProvisionsConnection {
edges {
node {
id
party {
id
accountsConnection(marketId: $marketId, type: ACCOUNT_TYPE_BOND) {
edges {
node {
type
balance
}
}
}
}
createdAt
updatedAt
commitmentAmount
fee
status
}
MarketLpQuery,
LiquidityProviderFeeShareFieldsFragment,
LiquidityProviderFeeShareQuery,
LiquidityProviderFeeShareUpdateSubscription,
LiquidityProvisionFieldsFragment,
LiquidityProvisionsQuery,
LiquidityProvisionsUpdateSubscription,
} from './__generated___/MarketLiquidity';
import type { Account } from '@vegaprotocol/accounts';
export const liquidityProvisionsDataProvider = makeDataProvider<
LiquidityProvisionsQuery,
LiquidityProvisionFieldsFragment[],
LiquidityProvisionsUpdateSubscription,
LiquidityProvisionsUpdateSubscription['liquidityProvisions']
>({
query: LiquidityProvisionsDocument,
subscriptionQuery: LiquidityProvisionsUpdateDocument,
update: (
data: LiquidityProvisionFieldsFragment[],
deltas: LiquidityProvisionsUpdateSubscription['liquidityProvisions']
) => {
return produce(data, (draft) => {
deltas?.forEach((delta) => {
const id = delta.partyID;
const index = draft.findIndex((a) => a.party.id === id);
if (index !== -1) {
draft[index].commitmentAmount = delta.commitmentAmount;
draft[index].fee = delta.fee;
draft[index].updatedAt = delta.updatedAt;
draft[index].status = delta.status;
} else {
draft.unshift({
commitmentAmount: delta.commitmentAmount,
fee: delta.fee,
status: delta.status,
updatedAt: delta.updatedAt,
createdAt: delta.createdAt,
party: {
id: delta.partyID,
},
// TODO add accounts connection to the subscription
});
}
}
tradableInstrument {
instrument {
code
name
product {
... on Future {
settlementAsset {
id
symbol
decimals
}
}
}
}
}
data {
market {
id
}
suppliedStake
openInterest
targetStake
marketValueProxy
liquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
}
}
}
`;
export interface LiquidityProvision {
party: string;
commitmentAmount: string | undefined;
fee: string | undefined;
equityLikeShare: string;
averageEntryValuation: string;
obligation: string | null;
supplied: string | null;
status?: LiquidityProvisionStatus;
createdAt: string | undefined;
updatedAt: string | null | undefined;
}
export interface LiquidityData {
liquidityProviders: LiquidityProvision[];
suppliedStake?: string | null;
targetStake?: string | null;
code?: string;
symbol?: string;
decimalPlaces?: number;
positionDecimalPlaces?: number;
assetDecimalPlaces?: number;
name?: string;
}
export const useLiquidityProvision = ({
marketId,
partyId,
}: {
partyId?: string;
marketId?: string;
}) => {
const { param: stakeToCcySiskas } = useNetworkParam(
NetworkParams.market_liquidity_stakeToCcySiskas
);
const stakeToCcySiska = stakeToCcySiskas && stakeToCcySiskas[0];
const { data, loading, error } = useQuery<MarketLiquidity>(
MARKET_LIQUIDITY_QUERY,
{
variables: { marketId },
}
);
const liquidityProviders = (
data?.market?.data?.liquidityProviderFeeShare || []
)
?.filter(
(p: MarketLiquidity_market_data_liquidityProviderFeeShare) =>
!partyId || p.party.id === partyId
) // if partyId is provided, filter out other parties
.map((provider: MarketLiquidity_market_data_liquidityProviderFeeShare) => {
const liquidityProvisionConnection =
data?.market?.liquidityProvisionsConnection?.edges?.find(
(e) => e?.node.party.id === provider.party.id
);
const balance =
liquidityProvisionConnection?.node?.party.accountsConnection?.edges?.reduce(
(acc, e) => {
return e?.node.type === AccountType.ACCOUNT_TYPE_BOND // just an extra check to make sure we only use bond accounts
? acc.plus(new BigNumber(e?.node.balance ?? 0))
: acc;
},
new BigNumber(0)
);
const obligation =
stakeToCcySiska &&
new BigNumber(stakeToCcySiska)
.times(liquidityProvisionConnection?.node?.commitmentAmount ?? 1)
.toString();
const supplied =
stakeToCcySiska &&
new BigNumber(stakeToCcySiska).times(balance ?? 1).toString();
return {
party: provider.party.id,
createdAt: liquidityProvisionConnection?.node?.createdAt,
updatedAt: liquidityProvisionConnection?.node?.updatedAt,
commitmentAmount: liquidityProvisionConnection?.node?.commitmentAmount,
fee: liquidityProvisionConnection?.node?.fee,
status: liquidityProvisionConnection?.node?.status,
equityLikeShare: provider.equityLikeShare,
averageEntryValuation: provider.averageEntryValuation,
obligation,
supplied,
};
});
});
const liquidityData: LiquidityData = {
liquidityProviders,
suppliedStake: data?.market?.data?.suppliedStake,
targetStake: data?.market?.data?.targetStake,
decimalPlaces: data?.market?.decimalPlaces,
positionDecimalPlaces: data?.market?.positionDecimalPlaces,
code: data?.market?.tradableInstrument.instrument.code,
name: data?.market?.tradableInstrument.instrument.name,
assetDecimalPlaces:
data?.market?.tradableInstrument.instrument.product.settlementAsset
.decimals,
symbol:
data?.market?.tradableInstrument.instrument.product.settlementAsset
.symbol,
};
return { data: liquidityData, loading, error };
},
getData: (responseData: LiquidityProvisionsQuery) => {
return (
responseData.market?.liquidityProvisionsConnection?.edges?.map(
(e) => e?.node
) ?? []
).filter((e) => !!e) as LiquidityProvisionFieldsFragment[];
},
getDelta: (
subscriptionData: LiquidityProvisionsUpdateSubscription
): LiquidityProvisionsUpdateSubscription['liquidityProvisions'] => {
return subscriptionData.liquidityProvisions;
},
});
export const marketLiquidityDataProvider = makeDataProvider<
MarketLpQuery,
MarketLpQuery,
never,
never
>({
query: MarketLpDocument,
getData: (responseData: MarketLpQuery) => {
return responseData;
},
});
export const liquidityFeeShareDataProvider = makeDataProvider<
LiquidityProviderFeeShareQuery,
LiquidityProviderFeeShareFieldsFragment[],
LiquidityProviderFeeShareUpdateSubscription,
LiquidityProviderFeeShareUpdateSubscription['marketsData'][0]['liquidityProviderFeeShare']
>({
query: LiquidityProviderFeeShareDocument,
subscriptionQuery: LiquidityProviderFeeShareUpdateDocument,
update: (
data: LiquidityProviderFeeShareFieldsFragment[],
deltas: LiquidityProviderFeeShareUpdateSubscription['marketsData'][0]['liquidityProviderFeeShare']
) => {
return produce(data, (draft) => {
deltas?.forEach((delta) => {
const id = delta.partyId;
const index = draft.findIndex((a) => a.party.id === id);
if (index !== -1) {
draft[index].equityLikeShare = delta.equityLikeShare;
draft[index].averageEntryValuation = delta.averageEntryValuation;
} else {
draft.unshift({
equityLikeShare: delta.equityLikeShare,
averageEntryValuation: delta.averageEntryValuation,
party: {
id: delta.partyId,
},
// TODO add accounts connection to the subscription
});
}
});
});
},
getData: (data) => {
return data.market?.data?.liquidityProviderFeeShare || [];
},
getDelta: (subscriptionData: LiquidityProviderFeeShareUpdateSubscription) => {
return subscriptionData.marketsData[0].liquidityProviderFeeShare;
},
});
export const lpAggregatedDataProvider = makeDerivedDataProvider(
[
(callback, client, variables) =>
liquidityProvisionsDataProvider(callback, client, {
marketId: variables?.marketId,
}),
(callback, client, variables) =>
accountsDataProvider(callback, client, {
partyId: variables?.partyId || '', // party Id can not be null
}),
marketLiquidityDataProvider,
liquidityFeeShareDataProvider,
],
([
liquidityProvisions,
accounts,
marketLiquidity,
liquidityFeeShare,
]): LiquidityProvisionData[] => {
return getLiquidityProvision(
liquidityProvisions,
accounts,
marketLiquidity,
liquidityFeeShare
);
}
);
export const getLiquidityProvision = (
liquidityProvisions: LiquidityProvisionFieldsFragment[],
accounts: Account[],
marketLiquidity: MarketLpQuery,
liquidityFeeShare: LiquidityProviderFeeShareFieldsFragment[]
): LiquidityProvisionData[] => {
return liquidityProvisions.map((lp) => {
const market = marketLiquidity?.market;
const feeShare = liquidityFeeShare.find((f) => f.party.id === lp.party.id);
if (!feeShare) return lp;
const lpData: LiquidityProvisionData = {
...lp,
averageEntryValuation: feeShare?.averageEntryValuation,
equityLikeShare: feeShare?.equityLikeShare,
assetDecimalPlaces:
market?.tradableInstrument.instrument.product.settlementAsset.decimals,
balance:
accounts
?.filter((a) => a?.type === AccountType.ACCOUNT_TYPE_BOND)
?.reduce(
(acc, a) => acc.plus(new BigNumber(a.balance ?? 0)),
new BigNumber(0)
)
.toString() ?? '0',
};
return lpData;
});
};
export interface LiquidityProvisionData
extends LiquidityProvisionFieldsFragment {
assetDecimalPlaces?: number;
balance?: string;
averageEntryValuation?: string;
equityLikeShare?: string;
}

View File

@ -1,34 +1,36 @@
import LiquidityTable from './liquidity-table';
import { act, render, screen } from '@testing-library/react';
import { LiquidityProvisionStatus } from '@vegaprotocol/types';
import type { LiquidityProvision } from './liquidity-data-provider';
import { Schema } from '@vegaprotocol/types';
import type { LiquidityProvisionData } from './liquidity-data-provider';
const singleRow: LiquidityProvision = {
const singleRow = {
party: 'a3f762f0a6e998e1d0c6e73017a13ec8a22386c30f7f64a1bdca47330bc592dd',
createdAt: '2022-08-19T17:18:36.257028Z',
updatedAt: '2022-08-19T17:18:36.257028Z',
commitmentAmount: '56298653179',
fee: '0.001',
status: LiquidityProvisionStatus.STATUS_ACTIVE,
status: Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
equityLikeShare: '0.5',
averageEntryValuation: '0.5',
supplied: '67895',
obligation: '56785',
};
} as unknown as LiquidityProvisionData;
const singleRowData = [singleRow];
describe('LiquidityTable', () => {
it('should render successfully', async () => {
await act(async () => {
const { baseElement } = render(<LiquidityTable data={[]} />);
const { baseElement } = render(
<LiquidityTable data={[]} stakeToCcySiskas={'1'} />
);
expect(baseElement).toBeTruthy();
});
});
it('should render correct columns', async () => {
await act(async () => {
render(<LiquidityTable data={singleRowData} />);
render(<LiquidityTable data={singleRowData} stakeToCcySiskas={'0.3'} />);
});
const headers = await screen.getAllByRole('columnheader');

View File

@ -11,11 +11,11 @@ import {
} from '@vegaprotocol/ui-toolkit';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridColumn } from 'ag-grid-react';
import type { LiquidityProvision } from './liquidity-data-provider';
import type { ValueFormatterParams } from 'ag-grid-community';
import BigNumber from 'bignumber.js';
import type { LiquidityProvisionStatus } from '@vegaprotocol/types';
import type { Schema } from '@vegaprotocol/types';
import { LiquidityProvisionStatusMapping } from '@vegaprotocol/types';
import type { LiquidityProvisionData } from './liquidity-data-provider';
const percentageFormatter = ({ value }: ValueFormatterParams) => {
if (!value) return '-';
@ -30,22 +30,32 @@ const dateValueFormatter = ({ value }: { value?: string | null }) => {
};
export interface LiquidityTableProps {
data: LiquidityProvision[];
data?: LiquidityProvisionData[];
symbol?: string;
assetDecimalPlaces?: number;
stakeToCcySiskas: string;
}
export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
({ data, symbol = '', assetDecimalPlaces }, ref) => {
({ data, symbol = '', assetDecimalPlaces, stakeToCcySiskas }, ref) => {
const assetDecimalsFormatter = ({ value }: ValueFormatterParams) => {
if (!value) return '-';
return `${addDecimalsFormatNumber(value, assetDecimalPlaces ?? 0, 5)}`;
};
const stakeToCcySiskasFormatter = ({ value }: ValueFormatterParams) => {
if (!value) return '-';
const newValue = new BigNumber(value)
.times(stakeToCcySiskas ?? 1)
.toString();
return `${addDecimalsFormatNumber(newValue, assetDecimalPlaces ?? 0, 5)}`;
};
if (!data) return null;
return (
<AgGrid
style={{ width: '100%', height: '100%' }}
overlayNoRowsTemplate={t('No liquidity provisions')}
getRowId={({ data }) => data.party}
getRowId={({ data }) => data.party.id}
rowHeight={34}
ref={ref}
tooltipShowDelay={500}
@ -60,7 +70,7 @@ export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
>
<AgGridColumn
headerName={t('Party')}
field="party"
field="party.id"
headerTooltip={t(
'The public key of the party making this commitment.'
)}
@ -104,27 +114,31 @@ export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
/>
<AgGridColumn
headerName={t('Obligation')}
field="obligation"
field="commitmentAmount"
type="rightAligned"
headerTooltip={t(
'The liquidity providers obligation to the market, calculated as the liquidity commitment amount multiplied by the value of the stake_to_ccy_siskas network parameter.'
)}
valueFormatter={assetDecimalsFormatter}
valueFormatter={stakeToCcySiskasFormatter}
/>
<AgGridColumn
headerName={t('Supplied')}
headerTooltip={t(
'The amount of the settlement asset supplied for liquidity by this provider, calculated as the bond account balance multiplied by the value of the stake_to_ccy_siskas network parameter.'
)}
field="supplied"
field="balance"
type="rightAligned"
valueFormatter={assetDecimalsFormatter}
valueFormatter={stakeToCcySiskasFormatter}
/>
<AgGridColumn
headerName={t('Status')}
headerTooltip={t('The current status of this liquidity provision.')}
field="status"
valueFormatter={({ value }: { value: LiquidityProvisionStatus }) => {
valueFormatter={({
value,
}: {
value: Schema.LiquidityProvisionStatus;
}) => {
if (!value) return value;
return LiquidityProvisionStatusMapping[value];
}}

View File

@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { Interval } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import {
makeDataProvider,
makeDerivedDataProvider,
@ -18,7 +18,7 @@ import {
marketListProvider,
} from '@vegaprotocol/market-list';
import type { LiquidityProvisionMarkets } from './__generated__';
import type { LiquidityProvisionMarkets } from './__generated__/LiquidityProvisionMarkets';
import { LiquidityProvisionMarketsDocument } from './__generated___/MarketsLiquidity';
import {
@ -97,7 +97,7 @@ const liquidityProvisionProvider = makeDerivedDataProvider<Markets, never>(
(callback, client, variables) =>
marketsCandlesProvider(callback, client, {
...variables,
interval: Interval.INTERVAL_I1D,
interval: Schema.Interval.INTERVAL_I1D,
}),
liquidityMarketsProvider,
],
@ -116,7 +116,7 @@ export const useMarketsLiquidity = () => {
const variables = useMemo(() => {
return {
since: new Date(yesterday).toISOString(),
interval: Interval.INTERVAL_I1H,
interval: Schema.Interval.INTERVAL_I1H,
};
}, [yesterday]);

View File

@ -1,7 +1,7 @@
import BigNumber from 'bignumber.js';
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
import type { LiquidityProvisionMarkets_marketsConnection_edges_node } from './../__generated__';
import type { LiquidityProvisionMarkets_marketsConnection_edges_node } from './../__generated__/LiquidityProvisionMarkets';
export type LiquidityProvisionMarket =
LiquidityProvisionMarkets_marketsConnection_edges_node;

View File

@ -26,7 +26,7 @@ interface OrderEditDialogProps {
}
interface FormFields {
entryPrice: string;
limitPrice: string;
}
export const OrderEditDialog = ({
@ -42,7 +42,7 @@ export const OrderEditDialog = ({
handleSubmit,
} = useForm<FormFields>({
defaultValues: {
entryPrice: addDecimalsFormatNumber(
limitPrice: addDecimalsFormatNumber(
order.price,
order.market?.decimalPlaces ?? 0
),
@ -99,21 +99,21 @@ export const OrderEditDialog = ({
data-testid="edit-order"
className="w-1/2 mt-4"
>
<FormGroup label={t('Price')} labelFor="entryPrice">
<FormGroup label={t('Price')} labelFor="limitPrice">
<Input
type="number"
step={step}
{...register('entryPrice', {
{...register('limitPrice', {
required: t('You need to provide a price'),
validate: {
min: (value) =>
Number(value) > 0 ? true : t('The price cannot be negative'),
},
})}
id="entryPrice"
id="limitPrice"
/>
{errors.entryPrice?.message && (
<InputError intent="danger">{errors.entryPrice.message}</InputError>
{errors.limitPrice?.message && (
<InputError intent="danger">{errors.limitPrice.message}</InputError>
)}
</FormGroup>
<Button variant="primary" size="md" type="submit">

View File

@ -91,7 +91,7 @@ export const OrderList = forwardRef<AgGridReact, OrderListProps>(
order={editOrder}
onSubmit={(fields) => {
setEditOrder(null);
orderEdit.edit({ price: fields.entryPrice });
orderEdit.edit({ price: fields.limitPrice });
}}
/>
)}