Compare commits

...
Author SHA1 Message Date
Matthew Russell 973a2759c0 chore: remove fetch policy 2023-05-19 14:57:27 -07:00
Matthew Russell b163eb6bfe chore: add fetch policy 2023-05-19 14:47:17 -07:00
Matthew Russell 8b69169021 chore: subscribe to all positions 2023-05-19 14:41:59 -07:00
Matthew Russell 79ac604009 chore: add second position view with multi key data 2023-05-18 14:12:23 -07:00
dexturr 162b167860 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-18 18:07:36 +00:00
11 changed files with 418 additions and 23 deletions
+31 -19
View File
@@ -38,7 +38,7 @@
"tranche_end": "2023-06-11T00:00:00.000Z",
"total_added": "15949",
"total_removed": "215.8495183664",
"locked_amount": "12086.6850242682186761",
"locked_amount": "11959.0406231332146841",
"deposits": [
{
"amount": "11447",
@@ -329,7 +329,7 @@
"tranche_end": "2023-05-20T00:00:00.000Z",
"total_added": "20967.125",
"total_removed": "4313.169927159795",
"locked_amount": "1043.349054639274308255",
"locked_amount": "869.949636622298931016875",
"deposits": [
{
"amount": "897",
@@ -2501,7 +2501,7 @@
"tranche_start": "2023-03-06T00:00:00.000Z",
"tranche_end": "2023-04-06T00:00:00.000Z",
"total_added": "14099",
"total_removed": "4403.49002352036",
"total_removed": "5107.49002352036",
"locked_amount": "0",
"deposits": [
{
@@ -3286,6 +3286,11 @@
"user": "0xd8489848Ee545DB18859B3e03dE01aD99a22a807",
"tx": "0xf8f66ba448c7711852effc4782d944f50061c1b077c9e9e6dfbc93a0ec45c297"
},
{
"amount": "704",
"user": "0x0b5739816AB0097C43F77479048a0A6093DD0441",
"tx": "0x0ed882c629ec1b0154e769f86e3ecd9f4680de6d3bcec67556225eaaaa1bddf2"
},
{
"amount": "30",
"user": "0xBe9F912Ad481C61B653463E8F1D2b2b310D49861",
@@ -4021,10 +4026,17 @@
"tx": "0x46d80a145d2f49ef3152cbfaa6d2bb054deabe21396ab43553a3f076e2db62e1"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "704",
"user": "0x0b5739816AB0097C43F77479048a0A6093DD0441",
"tranche_id": 53,
"tx": "0x0ed882c629ec1b0154e769f86e3ecd9f4680de6d3bcec67556225eaaaa1bddf2"
}
],
"total_tokens": "704",
"withdrawn_tokens": "0",
"remaining_tokens": "704"
"withdrawn_tokens": "704",
"remaining_tokens": "0"
},
{
"address": "0x981D29D939cAa4ADC04A5e44224dBB45539E8730",
@@ -5584,7 +5596,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "86666.297",
"total_removed": "0",
"locked_amount": "47605.4017552180739029016",
"locked_amount": "47546.4919777417822259639",
"deposits": [
{
"amount": "86666.297",
@@ -5650,7 +5662,7 @@
"tranche_end": "2023-06-01T00:00:00.000Z",
"total_added": "2500",
"total_removed": "0",
"locked_amount": "185.341149013024125",
"locked_amount": "181.933156542531675",
"deposits": [
{
"amount": "2500",
@@ -5683,7 +5695,7 @@
"tranche_end": "2023-11-01T00:00:00.000Z",
"total_added": "15000.000000000000015",
"total_removed": "0",
"locked_amount": "13572.785514794685013572785514794685",
"locked_amount": "13552.559820350241013552559820350241",
"deposits": [
{
"amount": "1.5e-14",
@@ -5791,7 +5803,7 @@
"tranche_end": "2023-09-01T00:00:00.000Z",
"total_added": "17500",
"total_removed": "0",
"locked_amount": "10033.28599914452525",
"locked_amount": "10009.68935562600725",
"deposits": [
{
"amount": "12500",
@@ -6058,7 +6070,7 @@
"tranche_end": "2023-08-01T00:00:00.000Z",
"total_added": "37500",
"total_removed": "18592.291570575",
"locked_amount": "15433.59854588704875",
"locked_amount": "15382.196228514426375",
"deposits": [
{
"amount": "7500",
@@ -6510,7 +6522,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "47561.9678160577578038775",
"locked_amount": "47503.1117863411078668825",
"deposits": [
{
"amount": "129999.45",
@@ -6543,7 +6555,7 @@
"tranche_end": "2024-04-01T00:00:00.000Z",
"total_added": "54144.7663",
"total_removed": "0",
"locked_amount": "47116.7217333150004818831",
"locked_amount": "47080.01840876004104699305",
"deposits": [
{
"amount": "54144.7663",
@@ -6576,7 +6588,7 @@
"tranche_end": "2023-09-03T00:00:00.000Z",
"total_added": "62600",
"total_removed": "0",
"locked_amount": "18435.7575659563655",
"locked_amount": "18393.206399036021604",
"deposits": [
{
"amount": "10000",
@@ -6769,7 +6781,7 @@
"tranche_end": "2023-09-17T00:00:00.000Z",
"total_added": "5000",
"total_removed": "0",
"locked_amount": "1664.285419837646",
"locked_amount": "1660.88676433282625",
"deposits": [
{
"amount": "5000",
@@ -7838,7 +7850,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "1709370.7872515768348",
"locked_amount": "77027.5703575844087789349",
"locked_amount": "75708.9407040557483188244",
"deposits": [
{
"amount": "1852091.69",
@@ -41915,7 +41927,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "747515.181114080043393",
"locked_amount": "142865.8822173107416572269134",
"locked_amount": "140839.6075379211948069455415",
"deposits": [
{
"amount": "1998.95815",
@@ -43319,7 +43331,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15870102.715470999700000001",
"total_removed": "889552.43313356066956852",
"locked_amount": "5806280.83111707407448955866311495377399295",
"locked_amount": "5799095.79120322791577005129823294316842385",
"deposits": [
{
"amount": "16249.93",
@@ -60271,7 +60283,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "45798.0743154683416",
"locked_amount": "22637.900715233350373427636631164",
"locked_amount": "22316.8408879026950634697130999496",
"deposits": [
{
"amount": "3000",
@@ -32,6 +32,7 @@ import {
import { TradingViews } from './trade-views';
import { MarketSelector } from './market-selector';
import { HeaderStats } from './header-stats';
import { PositionsMultiKey } from '@vegaprotocol/positions';
interface TradeGridProps {
market: Market | null;
@@ -130,6 +131,11 @@ const MarketBottomPanel = memo(
>
<TradeGridChild>
<Tabs storageKey="console-trade-grid-bottom-right">
<Tab id="positions-multi" name={t('Positions v2')}>
<VegaWalletContainer>
<PositionsMultiKey />
</VegaWalletContainer>
</Tab>
<Tab id="positions" name={t('Positions')}>
<VegaWalletContainer>
<TradingViews.positions.component
@@ -20,6 +20,7 @@ export const SettlementDateCell = ({
}: SettlementDataCellProps) => {
const linkCreator = useLinks(DApp.Explorer);
const date = closeTimestamp ? new Date(closeTimestamp) : metaDate;
console.log(metaDate);
let text = '';
if (!date) {
@@ -92,5 +92,8 @@ const cacheConfig: InMemoryCacheConfig = {
Fees: {
keyFields: false,
},
Position: {
keyFields: ['market', ['id'], 'party', ['id']],
},
},
};
+1 -1
View File
@@ -46,7 +46,7 @@ export const Navbar = ({
return (
<Navigation
appName="Console"
theme={theme}
theme={'dark'}
actions={
<>
<ProtocolUpgradeCountdown
+1
View File
@@ -1,6 +1,7 @@
export * from './lib/__generated__/Positions';
export * from './lib/positions-container';
export * from './lib/positions-data-providers';
export * from './lib/positions-multi-key';
export * from './lib/margin-data-provider';
export * from './lib/positions-table';
export * from './lib/use-market-margin';
+5
View File
@@ -9,6 +9,9 @@ fragment PositionFields on Position {
market {
id
}
party {
id
}
}
query Positions($partyId: ID!) {
@@ -34,6 +37,8 @@ subscription PositionsSubscription($partyId: ID!) {
marketId
lossSocializationAmount
positionStatus
partyId
marketId
}
}
@@ -0,0 +1,43 @@
fragment PositionMultiFields on Position {
realisedPNL
openVolume
unrealisedPNL
averageEntryPrice
updatedAt
positionStatus
lossSocializationAmount
market {
id
}
party {
id
}
}
query PositionsMulti($partyIds: [ID!]!) {
positions(filter: { partyIds: $partyIds }) {
edges {
node {
...PositionMultiFields
}
}
}
}
query MarketName($marketId: ID!) {
market(id: $marketId) {
id
tradableInstrument {
instrument {
code
}
}
}
}
query MarketDecimals($marketId: ID!) {
market(id: $marketId) {
id
decimalPlaces
}
}
+8 -3
View File
@@ -3,21 +3,21 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
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 PositionFieldsFragment = { __typename?: 'Position', realisedPNL: string, openVolume: string, unrealisedPNL: string, averageEntryPrice: string, updatedAt?: any | null, positionStatus: Types.PositionStatus, lossSocializationAmount: string, market: { __typename?: 'Market', id: string }, party: { __typename?: 'Party', id: string } };
export type PositionsQueryVariables = Types.Exact<{
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 };
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 }, party: { __typename?: 'Party', id: string } } }> | null } | null } | null };
export type PositionsSubscriptionSubscriptionVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type PositionsSubscriptionSubscription = { __typename?: 'Subscription', positions: Array<{ __typename?: 'PositionUpdate', realisedPNL: string, openVolume: string, unrealisedPNL: string, averageEntryPrice: string, updatedAt?: any | null, marketId: string, lossSocializationAmount: string, positionStatus: Types.PositionStatus }> };
export type PositionsSubscriptionSubscription = { __typename?: 'Subscription', positions: Array<{ __typename?: 'PositionUpdate', realisedPNL: string, openVolume: string, unrealisedPNL: string, averageEntryPrice: string, updatedAt?: any | null, marketId: string, lossSocializationAmount: string, positionStatus: Types.PositionStatus, partyId: string }> };
export type MarginFieldsFragment = { __typename?: 'MarginLevels', maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string, asset: { __typename?: 'Asset', id: string }, market: { __typename?: 'Market', id: string } };
@@ -57,6 +57,9 @@ export const PositionFieldsFragmentDoc = gql`
market {
id
}
party {
id
}
}
`;
export const MarginFieldsFragmentDoc = gql`
@@ -126,6 +129,8 @@ export const PositionsSubscriptionDocument = gql`
marketId
lossSocializationAmount
positionStatus
partyId
marketId
}
}
`;
+160
View File
@@ -0,0 +1,160 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type PositionMultiFieldsFragment = { __typename?: 'Position', realisedPNL: string, openVolume: string, unrealisedPNL: string, averageEntryPrice: string, updatedAt?: any | null, positionStatus: Types.PositionStatus, lossSocializationAmount: string, market: { __typename?: 'Market', id: string }, party: { __typename?: 'Party', id: string } };
export type PositionsMultiQueryVariables = Types.Exact<{
partyIds: Array<Types.Scalars['ID']> | Types.Scalars['ID'];
}>;
export type PositionsMultiQuery = { __typename?: 'Query', positions?: { __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 }, party: { __typename?: 'Party', id: string } } }> | null } | null };
export type MarketNameQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type MarketNameQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', code: string } } } | null };
export type MarketDecimalsQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type MarketDecimalsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number } | null };
export const PositionMultiFieldsFragmentDoc = gql`
fragment PositionMultiFields on Position {
realisedPNL
openVolume
unrealisedPNL
averageEntryPrice
updatedAt
positionStatus
lossSocializationAmount
market {
id
}
party {
id
}
}
`;
export const PositionsMultiDocument = gql`
query PositionsMulti($partyIds: [ID!]!) {
positions(filter: {partyIds: $partyIds}) {
edges {
node {
...PositionMultiFields
}
}
}
}
${PositionMultiFieldsFragmentDoc}`;
/**
* __usePositionsMultiQuery__
*
* To run a query within a React component, call `usePositionsMultiQuery` and pass it any options that fit your needs.
* When your component renders, `usePositionsMultiQuery` 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 } = usePositionsMultiQuery({
* variables: {
* partyIds: // value for 'partyIds'
* },
* });
*/
export function usePositionsMultiQuery(baseOptions: Apollo.QueryHookOptions<PositionsMultiQuery, PositionsMultiQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<PositionsMultiQuery, PositionsMultiQueryVariables>(PositionsMultiDocument, options);
}
export function usePositionsMultiLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PositionsMultiQuery, PositionsMultiQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<PositionsMultiQuery, PositionsMultiQueryVariables>(PositionsMultiDocument, options);
}
export type PositionsMultiQueryHookResult = ReturnType<typeof usePositionsMultiQuery>;
export type PositionsMultiLazyQueryHookResult = ReturnType<typeof usePositionsMultiLazyQuery>;
export type PositionsMultiQueryResult = Apollo.QueryResult<PositionsMultiQuery, PositionsMultiQueryVariables>;
export const MarketNameDocument = gql`
query MarketName($marketId: ID!) {
market(id: $marketId) {
id
tradableInstrument {
instrument {
code
}
}
}
}
`;
/**
* __useMarketNameQuery__
*
* To run a query within a React component, call `useMarketNameQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketNameQuery` 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 } = useMarketNameQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useMarketNameQuery(baseOptions: Apollo.QueryHookOptions<MarketNameQuery, MarketNameQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketNameQuery, MarketNameQueryVariables>(MarketNameDocument, options);
}
export function useMarketNameLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketNameQuery, MarketNameQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketNameQuery, MarketNameQueryVariables>(MarketNameDocument, options);
}
export type MarketNameQueryHookResult = ReturnType<typeof useMarketNameQuery>;
export type MarketNameLazyQueryHookResult = ReturnType<typeof useMarketNameLazyQuery>;
export type MarketNameQueryResult = Apollo.QueryResult<MarketNameQuery, MarketNameQueryVariables>;
export const MarketDecimalsDocument = gql`
query MarketDecimals($marketId: ID!) {
market(id: $marketId) {
id
decimalPlaces
}
}
`;
/**
* __useMarketDecimalsQuery__
*
* To run a query within a React component, call `useMarketDecimalsQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketDecimalsQuery` 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 } = useMarketDecimalsQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useMarketDecimalsQuery(baseOptions: Apollo.QueryHookOptions<MarketDecimalsQuery, MarketDecimalsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketDecimalsQuery, MarketDecimalsQueryVariables>(MarketDecimalsDocument, options);
}
export function useMarketDecimalsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketDecimalsQuery, MarketDecimalsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketDecimalsQuery, MarketDecimalsQueryVariables>(MarketDecimalsDocument, options);
}
export type MarketDecimalsQueryHookResult = ReturnType<typeof useMarketDecimalsQuery>;
export type MarketDecimalsLazyQueryHookResult = ReturnType<typeof useMarketDecimalsLazyQuery>;
export type MarketDecimalsQueryResult = Apollo.QueryResult<MarketDecimalsQuery, MarketDecimalsQueryVariables>;
@@ -0,0 +1,159 @@
import { useVegaWallet } from '@vegaprotocol/wallet';
import {
useMarketDecimalsQuery,
useMarketNameQuery,
usePositionsMultiQuery,
} from './__generated__/PositionsMulti';
import { AgGridLazy } from '@vegaprotocol/datagrid';
import { useEffect, useMemo } from 'react';
import type {
PositionsSubscriptionSubscription,
PositionsSubscriptionSubscriptionVariables,
} from './__generated__/Positions';
import { PositionsSubscriptionDocument } from './__generated__/Positions';
import { addDecimalsFormatNumber, truncateByChars } from '@vegaprotocol/utils';
import { useApolloClient } from '@apollo/client';
export const PositionsMultiKey = () => {
const { pubKeys } = useVegaWallet();
const { data } = usePositions();
const colDefs = useMemo(() => {
return [
{
field: 'party.id',
valueFormatter: ({ value }) => {
const truncated = truncateByChars(value);
const pk = pubKeys?.find((pk) => pk.publicKey === value);
return pk ? pk.name + ' ' + truncated : truncated;
},
},
{
headerName: 'Market',
field: 'market.id',
cellRenderer: ({ value }) => {
return <MarketCell id={value} />;
},
},
{
field: 'openVolume',
},
{
field: 'unrealisedPNL',
cellRenderer: ({ data }) => {
return (
<PNLCell marketId={data.market.id} value={data.unrealisedPNL} />
);
},
},
{
field: 'realisedPNL',
cellRenderer: ({ data }) => {
return <PNLCell marketId={data.market.id} value={data.realisedPNL} />;
},
},
{
field: 'updatedAt',
},
];
}, [pubKeys]);
const rowData = data?.positions?.edges?.length
? data.positions.edges.map((e) => e.node)
: [];
return (
<AgGridLazy
getRowId={({ data }) => `${data.party.id}:${data.market.id}`}
style={{ width: '100%', height: '100%' }}
columnDefs={colDefs}
rowData={rowData}
/>
);
};
const usePositions = () => {
const { pubKeys } = useVegaWallet();
const client = useApolloClient();
const { data, loading, error } = usePositionsMultiQuery({
variables: {
partyIds: pubKeys ? pubKeys.map((pk) => pk.publicKey) : [],
},
skip: !pubKeys || pubKeys.length === 0,
});
useEffect(() => {
if (!pubKeys?.length) return;
const subs = pubKeys.map((p) => {
return client
.subscribe<
PositionsSubscriptionSubscription,
PositionsSubscriptionSubscriptionVariables
>({
query: PositionsSubscriptionDocument,
variables: {
partyId: p.publicKey,
},
// no cache as we only want to store data in the root Position query,
// we modify this cache entry directly below
fetchPolicy: 'no-cache',
})
.subscribe(({ data }) => {
data?.positions.forEach((position) => {
const id = client.cache.identify({
__typename: 'Position',
party: { id: position.partyId },
market: { id: position.marketId },
});
client.cache.modify({
id,
fields: {
realisedPNL: () => position.realisedPNL,
unrealisedPNL: () => position.unrealisedPNL,
openVolume: () => position.openVolume,
averageEntryPrice: () => position.averageEntryPrice,
positionStatus: () => position.positionStatus,
lossSocializationAmount: () => position.lossSocializationAmount,
updatedAt: () => position.updatedAt,
},
});
});
});
});
return () => {
subs.forEach((sub) => {
sub.unsubscribe();
});
};
}, [pubKeys, client]);
return { data, loading, error };
};
const MarketCell = ({ id }: { id: string }) => {
const { data } = useMarketNameQuery({
variables: {
marketId: id,
},
// We should cache all static market data higher up the render tree so this
// can be cache only
// fetchPolicy: 'cache-only',
});
if (!data?.market) return <span>-</span>;
return <span>{data.market.tradableInstrument.instrument.code}</span>;
};
const PNLCell = ({ marketId, value }: { marketId: string; value: string }) => {
const { data } = useMarketDecimalsQuery({
variables: {
marketId,
},
// We should cache all static market data higher up the render tree so this
// can be cache only
// fetchPolicy: 'cache-only'
});
if (!data?.market) return <span>-</span>;
return (
<span>{addDecimalsFormatNumber(value, data.market.decimalPlaces)}</span>
);
};