chore(2415): get rid of polling queries on deal ticket (#2427)
* chore: get rid of polling queries on dael ticket * chore: get rid of polling queries on dael ticket - fix tests * chore: get rid of polling queries on deal ticket - fix linter * chore: get rid of polling queries on deal ticket - fix linter * chore: get rid of polling queries on deal ticket - adjust int test * chore: get rid of polling queries on deal ticket - adjust int test in console-lite * chore: get rid of polling queries on deal ticket - adjust unit some test * chore: get rid of polling queries on deal ticket - adjust unit some test * chore: get rid of polling queries on deal ticket - clean up some redundant types * chore: get rid of polling queries on deal ticket - clean up some redundant files
This commit is contained in:
parent
07b766e4d2
commit
b9ff2388db
@ -7,11 +7,7 @@ import {
|
||||
generateSimpleMarkets,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
||||
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
|
||||
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
||||
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
||||
import { generateMarketNames } from '../support/mocks/generate-market-names';
|
||||
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
||||
import type { Market, MarketsQuery } from '@vegaprotocol/market-list';
|
||||
@ -30,11 +26,7 @@ describe('market selector', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'MarketData', generateMarketData());
|
||||
aliasQuery(req, 'Market', generateMarket());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||
aliasQuery(req, 'MarketNames', generateMarketNames());
|
||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||
});
|
||||
|
@ -7,15 +7,14 @@ import {
|
||||
generateMarketData,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
||||
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
|
||||
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
||||
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
||||
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
||||
import type { MarketsQuery, Market } from '@vegaprotocol/market-list';
|
||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
||||
import { generateAccounts } from '../support/mocks/generate-accounts';
|
||||
import { generateAssets } from '../support/mocks/generate-assets';
|
||||
import { generatePositions } from '../support/mocks/generate-positions';
|
||||
|
||||
describe('Market trade', { tags: '@smoke' }, () => {
|
||||
let markets: Market[];
|
||||
@ -28,14 +27,13 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||
aliasQuery(req, 'Accounts', generateAccounts());
|
||||
aliasQuery(req, 'Assets', generateAssets());
|
||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||
aliasQuery(req, 'Market', generateMarket());
|
||||
aliasQuery(req, 'MarketData', generateMarketData());
|
||||
aliasQuery(req, 'Positions', generatePositions());
|
||||
});
|
||||
cy.visit('/markets');
|
||||
cy.wait('@Markets').then((response) => {
|
||||
@ -112,6 +110,24 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
|
||||
it('size slider should work well', () => {
|
||||
if (markets?.length) {
|
||||
const marketId = markets[1].id;
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(
|
||||
req,
|
||||
'Market',
|
||||
generateMarket({
|
||||
market: {
|
||||
id: marketId,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: { settlementAsset: { id: 'asset-id-2' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
@ -134,7 +150,24 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
|
||||
it('percentage selection should work well', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
const marketId = markets[1].id;
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(
|
||||
req,
|
||||
'Market',
|
||||
generateMarket({
|
||||
market: {
|
||||
id: marketId,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: { settlementAsset: { id: 'asset-id-2' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
@ -145,7 +178,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
.find('button')
|
||||
.should('have.text', '1');
|
||||
|
||||
cy.getByTestId('max-label').should('have.text', '21');
|
||||
cy.getByTestId('max-label').should('have.text', '11');
|
||||
|
||||
cy.getByTestId('percentage-selector')
|
||||
.find('button')
|
||||
@ -155,7 +188,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
.find('dd')
|
||||
.eq(0)
|
||||
.find('button')
|
||||
.should('have.text', '21');
|
||||
.should('have.text', '11');
|
||||
}
|
||||
});
|
||||
|
||||
@ -189,7 +222,24 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
|
||||
it('slippage value should be displayed', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
const marketId = markets[1].id;
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(
|
||||
req,
|
||||
'Market',
|
||||
generateMarket({
|
||||
market: {
|
||||
id: marketId,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: { settlementAsset: { id: 'asset-id-2' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
@ -205,7 +255,24 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
|
||||
it('allow slippage value to be adjusted', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
const marketId = markets[1].id;
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(
|
||||
req,
|
||||
'Market',
|
||||
generateMarket({
|
||||
market: {
|
||||
id: marketId,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: { settlementAsset: { id: 'asset-id-2' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
cy.visit(`/trading/${marketId}`);
|
||||
cy.connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
|
@ -108,7 +108,7 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('data should be properly rendered', () => {
|
||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 2);
|
||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -74,6 +74,21 @@ export const generateAccounts = (
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id-2',
|
||||
},
|
||||
balance: '265329',
|
||||
market: {
|
||||
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
|
||||
__typename: 'Market',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
|
@ -110,91 +110,91 @@ export const generateMarketDepth = (
|
||||
],
|
||||
buy: [
|
||||
{
|
||||
price: '9893005',
|
||||
price: '9891005',
|
||||
volume: '4',
|
||||
numberOfOrders: '3',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893003',
|
||||
price: '9890003',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9893001',
|
||||
price: '9889001',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9892006',
|
||||
price: '9888006',
|
||||
volume: '3',
|
||||
numberOfOrders: '2',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9891006',
|
||||
price: '9887006',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9891001',
|
||||
price: '9886001',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890101',
|
||||
price: '9885101',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890091',
|
||||
price: '9884091',
|
||||
volume: '5',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890081',
|
||||
price: '9883081',
|
||||
volume: '4',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890050',
|
||||
price: '9882050',
|
||||
volume: '2',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890040',
|
||||
price: '9881040',
|
||||
volume: '6',
|
||||
numberOfOrders: '3',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890030',
|
||||
price: '9880030',
|
||||
volume: '6',
|
||||
numberOfOrders: '2',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890021',
|
||||
price: '9879021',
|
||||
volume: '3',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890011',
|
||||
price: '9878011',
|
||||
volume: '1',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
},
|
||||
{
|
||||
price: '9890001',
|
||||
price: '9877001',
|
||||
volume: '11',
|
||||
numberOfOrders: '1',
|
||||
__typename: 'PriceLevel',
|
||||
|
@ -1,9 +0,0 @@
|
||||
export const generateMarketMarkPrice = () => {
|
||||
return {
|
||||
market: {
|
||||
decimalPlaces: 5,
|
||||
data: { markPrice: '692748', __typename: 'MarketData' },
|
||||
__typename: 'Market',
|
||||
},
|
||||
};
|
||||
};
|
@ -1,72 +0,0 @@
|
||||
import type { MarketPositionsQuery } from '@vegaprotocol/deal-ticket';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
export const generateMarketPositions = (): MarketPositionsQuery => {
|
||||
return {
|
||||
party: {
|
||||
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
balance: '400000000000000000000',
|
||||
market: {
|
||||
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
|
||||
__typename: 'Market',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
balance: '265329',
|
||||
market: {
|
||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
||||
__typename: 'Market',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
positionsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
openVolume: '3',
|
||||
market: {
|
||||
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
|
||||
__typename: 'Market',
|
||||
},
|
||||
__typename: 'Position',
|
||||
},
|
||||
__typename: 'PositionEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
openVolume: '12',
|
||||
market: {
|
||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
||||
__typename: 'Market',
|
||||
},
|
||||
__typename: 'Position',
|
||||
},
|
||||
__typename: 'PositionEdge',
|
||||
},
|
||||
],
|
||||
__typename: 'PositionConnection',
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
@ -1392,12 +1392,15 @@ export const generatePositionsMarkets = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const generateMarket = (): MarketQuery => {
|
||||
return {
|
||||
export const generateMarket = (
|
||||
override?: PartialDeep<MarketQuery>
|
||||
): MarketQuery => {
|
||||
const defaultResult = {
|
||||
market: {
|
||||
...singleMarket,
|
||||
},
|
||||
};
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
export const generateMarketData = (): MarketDataQuery => {
|
||||
|
@ -1,81 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartyBalanceQuery } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
export const generatePartyBalance = (
|
||||
override?: PartialDeep<PartyBalanceQuery>
|
||||
): PartyBalanceQuery => {
|
||||
const defaultResult: PartyBalanceQuery = {
|
||||
party: {
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '88474051',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '100000000',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
|
||||
symbol: 'tEURO',
|
||||
name: 'tEURO TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '3412867',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
balance: '70007',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
import type { PartyMarketDataQuery } from '@vegaprotocol/deal-ticket';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
export const generatePartyMarketData = (): PartyMarketDataQuery => {
|
||||
return {
|
||||
party: {
|
||||
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1200000',
|
||||
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
|
||||
market: null,
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '0.000000001',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
decimals: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
marginsConnection: { edges: null, __typename: 'MarginConnection' },
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
@ -41,7 +41,7 @@ export const generatePositions = (
|
||||
averageEntryPrice: '84400088',
|
||||
updatedAt: '2022-07-28T14:53:54.725477Z',
|
||||
market: {
|
||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
||||
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
|
||||
__typename: 'Market',
|
||||
},
|
||||
__typename: 'Position',
|
||||
|
@ -1,18 +0,0 @@
|
||||
query PartyBalanceQuery($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,61 +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 PartyBalanceQueryQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } } } | null> | null } | null } | null };
|
||||
|
||||
|
||||
export const PartyBalanceQueryDocument = gql`
|
||||
query PartyBalanceQuery($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __usePartyBalanceQueryQuery__
|
||||
*
|
||||
* To run a query within a React component, call `usePartyBalanceQueryQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `usePartyBalanceQueryQuery` 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 } = usePartyBalanceQueryQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function usePartyBalanceQueryQuery(baseOptions: Apollo.QueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
|
||||
}
|
||||
export function usePartyBalanceQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
|
||||
}
|
||||
export type PartyBalanceQueryQueryHookResult = ReturnType<typeof usePartyBalanceQueryQuery>;
|
||||
export type PartyBalanceQueryLazyQueryHookResult = ReturnType<typeof usePartyBalanceQueryLazyQuery>;
|
||||
export type PartyBalanceQueryQueryResult = Apollo.QueryResult<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>;
|
@ -1,9 +1,13 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { MarketDealTicketAsset } from '@vegaprotocol/market-list';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
...jest.requireActual('@vegaprotocol/wallet'),
|
||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||
}));
|
||||
|
||||
const tDAI: MarketDealTicketAsset = {
|
||||
__typename: 'Asset',
|
||||
@ -13,23 +17,20 @@ const tDAI: MarketDealTicketAsset = {
|
||||
decimals: 2,
|
||||
};
|
||||
|
||||
const accounts: AccountFragment[] = [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1000000',
|
||||
asset: tDAI,
|
||||
},
|
||||
];
|
||||
let mockAccountBalance: {
|
||||
accountBalance: string;
|
||||
accountDecimals: number | null;
|
||||
} = { accountBalance: '1000000', accountDecimals: 2 };
|
||||
jest.mock('@vegaprotocol/accounts', () => ({
|
||||
...jest.requireActual('@vegaprotocol/accounts'),
|
||||
useAccountBalance: jest.fn(() => mockAccountBalance),
|
||||
}));
|
||||
|
||||
describe('DealTicketBalance', function () {
|
||||
it('should render the balance', () => {
|
||||
const { getByText, getByRole } = render(
|
||||
<DealTicketBalance
|
||||
settlementAsset={tDAI}
|
||||
accounts={accounts}
|
||||
isWalletConnected
|
||||
/>
|
||||
<DealTicketBalance settlementAsset={tDAI} isWalletConnected />,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
|
||||
expect(getByRole('complementary')).toHaveAccessibleName('tDAI Balance');
|
||||
@ -39,11 +40,8 @@ describe('DealTicketBalance', function () {
|
||||
|
||||
it('should prompt to connect wallet', () => {
|
||||
const { getByText } = render(
|
||||
<DealTicketBalance
|
||||
settlementAsset={tDAI}
|
||||
accounts={accounts}
|
||||
isWalletConnected={false}
|
||||
/>
|
||||
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={false} />,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
|
||||
expect(
|
||||
@ -52,12 +50,10 @@ describe('DealTicketBalance', function () {
|
||||
});
|
||||
|
||||
it('should display zero balance', () => {
|
||||
mockAccountBalance = { accountBalance: '', accountDecimals: null };
|
||||
const { getByText } = render(
|
||||
<DealTicketBalance
|
||||
settlementAsset={tDAI}
|
||||
accounts={[]}
|
||||
isWalletConnected={true}
|
||||
/>
|
||||
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={true} />,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
|
||||
expect(getByText('No tDAI left to trade')).toBeInTheDocument();
|
||||
|
@ -1,41 +1,38 @@
|
||||
import classNames from 'classnames';
|
||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
t,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
|
||||
interface DealTicketBalanceProps {
|
||||
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
accounts: AccountFragment[];
|
||||
isWalletConnected: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const DealTicketBalance = ({
|
||||
settlementAsset,
|
||||
accounts,
|
||||
isWalletConnected,
|
||||
className = '',
|
||||
}: DealTicketBalanceProps) => {
|
||||
const settlementAssetId = settlementAsset?.id;
|
||||
const settlementAssetSymbol = settlementAsset?.symbol;
|
||||
const settlementAccount = useSettlementAccount(
|
||||
settlementAssetId,
|
||||
accounts,
|
||||
Schema.AccountType.ACCOUNT_TYPE_GENERAL
|
||||
);
|
||||
|
||||
const { accountBalance, accountDecimals } =
|
||||
useAccountBalance(settlementAssetId) || {};
|
||||
const settlementBalance = toBigNum(accountBalance || 0, accountDecimals || 0);
|
||||
|
||||
const formattedNumber =
|
||||
settlementAccount?.balance &&
|
||||
settlementAccount.asset.decimals &&
|
||||
addDecimalsFormatNumber(
|
||||
settlementAccount.balance,
|
||||
settlementAccount.asset.decimals
|
||||
);
|
||||
accountBalance &&
|
||||
accountDecimals &&
|
||||
addDecimalsFormatNumber(accountBalance, accountDecimals);
|
||||
|
||||
const balance = (
|
||||
<p className="text-blue text-lg font-semibold">
|
||||
{settlementAccount
|
||||
{!settlementBalance.isZero()
|
||||
? t(`${formattedNumber}`)
|
||||
: `No ${settlementAssetSymbol} left to trade`}
|
||||
</p>
|
||||
|
@ -1,14 +1,7 @@
|
||||
import { useParams } from 'react-router-dom';
|
||||
import {
|
||||
DealTicketManager,
|
||||
usePartyBalanceQuery,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketManager } from '@vegaprotocol/deal-ticket';
|
||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
t,
|
||||
useDataProvider,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { DealTicketSteps } from './deal-ticket-steps';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
@ -29,11 +22,6 @@ export const DealTicketContainer = () => {
|
||||
const { marketId } = useParams<{ marketId: string }>();
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
const { data: partyData } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId: marketId || '',
|
||||
@ -49,10 +37,6 @@ export const DealTicketContainer = () => {
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
const accounts = removePaginationWrapper(
|
||||
partyData?.party?.accountsConnection?.edges
|
||||
);
|
||||
|
||||
const loader = <Loader />;
|
||||
if (marketId && data) {
|
||||
const balance = (
|
||||
@ -61,7 +45,6 @@ export const DealTicketContainer = () => {
|
||||
settlementAsset={
|
||||
data.tradableInstrument.instrument.product?.settlementAsset
|
||||
}
|
||||
accounts={accounts || []}
|
||||
isWalletConnected={!!pubKey}
|
||||
/>
|
||||
);
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
getDefaultOrder,
|
||||
useOrderCloseOut,
|
||||
useOrderMargin,
|
||||
usePartyBalanceQuery,
|
||||
useMaximumPositionSize,
|
||||
useCalculateSlippage,
|
||||
validateAmount,
|
||||
@ -24,7 +23,6 @@ import {
|
||||
addDecimalsFormatNumber,
|
||||
addDecimal,
|
||||
formatNumber,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
useOrderSubmit,
|
||||
@ -77,17 +75,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
});
|
||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
||||
|
||||
const { data: partyBalance } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const accounts = removePaginationWrapper(
|
||||
partyBalance?.party?.accountsConnection?.edges
|
||||
);
|
||||
const maxTrade = useMaximumPositionSize({
|
||||
partyId: pubKey || '',
|
||||
accounts: accounts,
|
||||
marketId: market.id,
|
||||
settlementAssetId:
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
||||
@ -98,7 +86,6 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
const estCloseOut = useOrderCloseOut({
|
||||
order,
|
||||
market,
|
||||
partyData: partyBalance,
|
||||
});
|
||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
||||
const [slippageValue, setSlippageValue] = useState(
|
||||
|
@ -697,7 +697,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
||||
);
|
||||
cy.getByTestId('dealticket-warning-margin').should(
|
||||
'contain.text',
|
||||
'10,000.00 tBTC currently required, 1,000.00 tBTC available'
|
||||
'9,999.99 tBTC currently required, 1,000.00 tBTC available'
|
||||
);
|
||||
cy.getByTestId('deal-ticket-deposit-dialog-button').click();
|
||||
cy.getByTestId('dialog-content')
|
||||
|
@ -1,12 +1,6 @@
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import merge from 'lodash/merge';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
import type {
|
||||
EstimateOrderQuery,
|
||||
MarketMarkPriceQuery,
|
||||
PartyBalanceQuery,
|
||||
PartyMarketDataQuery,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import type { EstimateOrderQuery } from '@vegaprotocol/deal-ticket';
|
||||
|
||||
const estimateOrderMock: EstimateOrderQuery = {
|
||||
estimateOrder: {
|
||||
@ -27,87 +21,3 @@ export const generateEstimateOrder = (
|
||||
) => {
|
||||
return merge(estimateOrderMock, override);
|
||||
};
|
||||
|
||||
const marketMarkPriceMock: MarketMarkPriceQuery = {
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
decimalPlaces: 5,
|
||||
data: {
|
||||
__typename: 'MarketData',
|
||||
markPrice: '100',
|
||||
market: { __typename: 'Market', id: 'market-0' },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const generateMarkPrice = () => {
|
||||
return marketMarkPriceMock;
|
||||
};
|
||||
|
||||
const partyBalanceMock: PartyBalanceQuery = {
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
name: 'BTC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const generatePartyBalance = () => {
|
||||
return partyBalanceMock;
|
||||
};
|
||||
|
||||
export const generatePartyMarketData = (): PartyMarketDataQuery => {
|
||||
return {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
accountsConnection: {
|
||||
__typename: 'AccountsConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1200000',
|
||||
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
|
||||
market: null,
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountEdge',
|
||||
node: {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
marginsConnection: { edges: null, __typename: 'MarginConnection' },
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -18,12 +18,7 @@ import { generateOrders } from './mocks/generate-orders';
|
||||
import { generateMargins, generatePositions } from './mocks/generate-positions';
|
||||
import { generateTrades } from './mocks/generate-trades';
|
||||
import { generateWithdrawals } from './mocks/generate-withdrawals';
|
||||
import {
|
||||
generateEstimateOrder,
|
||||
generateMarkPrice,
|
||||
generatePartyBalance,
|
||||
generatePartyMarketData,
|
||||
} from './mocks/generate-fees';
|
||||
import { generateEstimateOrder } from './mocks/generate-fees';
|
||||
import { generateMarketProposals } from './mocks/generate-proposals';
|
||||
import { generateStatistics } from './mocks/generate-statistics';
|
||||
import { generateChainId } from './mocks/generate-chain-id';
|
||||
@ -94,10 +89,7 @@ const mockTradingPage = (
|
||||
aliasQuery(req, 'Withdrawals', generateWithdrawals());
|
||||
aliasQuery(req, 'NetworkParams', generateNetworkParameters());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarkPrice());
|
||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
||||
aliasQuery(req, 'MarketPositions', generatePositions());
|
||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||
aliasQuery(req, 'ProposalsList', generateMarketProposals());
|
||||
aliasQuery(req, 'Deposits', generateDeposits());
|
||||
};
|
||||
|
15
libs/accounts/src/lib/get-market-account.ts
Normal file
15
libs/accounts/src/lib/get-market-account.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import type { Account } from './accounts-data-provider';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
interface Props {
|
||||
accounts: Account[] | null;
|
||||
marketId: string;
|
||||
}
|
||||
|
||||
export const getMarketAccount = ({ accounts, marketId }: Props) =>
|
||||
accounts?.find((account) => {
|
||||
return (
|
||||
account.market?.id === marketId &&
|
||||
account.type === Schema.AccountType.ACCOUNT_TYPE_MARGIN
|
||||
);
|
||||
}) || null;
|
@ -6,3 +6,4 @@ export * from './accounts-manager';
|
||||
export * from './breakdown-table';
|
||||
export * from './use-account-balance';
|
||||
export * from './get-settlement-account';
|
||||
export * from './use-market-account-balance';
|
||||
|
43
libs/accounts/src/lib/use-market-account-balance.tsx
Normal file
43
libs/accounts/src/lib/use-market-account-balance.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { accountsDataProvider } from './accounts-data-provider';
|
||||
import type { Account } from './accounts-data-provider';
|
||||
import { getMarketAccount } from './get-market-account';
|
||||
|
||||
export const useMarketAccountBalance = (marketId: string) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const [accountBalance, setAccountBalance] = useState<string>('');
|
||||
const [accountDecimals, setAccountDecimals] = useState<number | null>(null);
|
||||
const variables = useMemo(() => {
|
||||
return { partyId: pubKey || '' };
|
||||
}, [pubKey]);
|
||||
const update = useCallback(
|
||||
({ data }: { data: Account[] | null }) => {
|
||||
const account = getMarketAccount({ accounts: data, marketId });
|
||||
if (accountBalance !== account?.balance) {
|
||||
setAccountBalance(account?.balance || '');
|
||||
}
|
||||
if (accountDecimals !== account?.asset.decimals) {
|
||||
setAccountDecimals(account?.asset.decimals || null);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[accountBalance, accountDecimals, marketId]
|
||||
);
|
||||
|
||||
useDataProvider({
|
||||
dataProvider: accountsDataProvider,
|
||||
variables,
|
||||
skip: !pubKey || !marketId,
|
||||
update,
|
||||
});
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
accountBalance,
|
||||
accountDecimals,
|
||||
}),
|
||||
[accountBalance, accountDecimals]
|
||||
);
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
query MarketMarkPrice($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
decimalPlaces
|
||||
data {
|
||||
markPrice
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
query MarketPositions($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
id
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
decimals
|
||||
}
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
positionsConnection {
|
||||
edges {
|
||||
node {
|
||||
openVolume
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
query PartyBalance($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
...Account
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment Account on AccountBalance {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
query PartyMarketData($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
id
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
decimals
|
||||
}
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
marginsConnection {
|
||||
edges {
|
||||
node {
|
||||
market {
|
||||
id
|
||||
}
|
||||
initialLevel
|
||||
maintenanceLevel
|
||||
searchLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +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 MarketMarkPriceQueryVariables = Types.Exact<{
|
||||
marketId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketMarkPriceQuery = { __typename?: 'Query', market?: { __typename?: 'Market', decimalPlaces: number, data?: { __typename?: 'MarketData', markPrice: string, market: { __typename?: 'Market', id: string } } | null } | null };
|
||||
|
||||
|
||||
export const MarketMarkPriceDocument = gql`
|
||||
query MarketMarkPrice($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
decimalPlaces
|
||||
data {
|
||||
markPrice
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useMarketMarkPriceQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useMarketMarkPriceQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useMarketMarkPriceQuery` 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 } = useMarketMarkPriceQuery({
|
||||
* variables: {
|
||||
* marketId: // value for 'marketId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useMarketMarkPriceQuery(baseOptions: Apollo.QueryHookOptions<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>(MarketMarkPriceDocument, options);
|
||||
}
|
||||
export function useMarketMarkPriceLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>(MarketMarkPriceDocument, options);
|
||||
}
|
||||
export type MarketMarkPriceQueryHookResult = ReturnType<typeof useMarketMarkPriceQuery>;
|
||||
export type MarketMarkPriceLazyQueryHookResult = ReturnType<typeof useMarketMarkPriceLazyQuery>;
|
||||
export type MarketMarkPriceQueryResult = Apollo.QueryResult<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>;
|
@ -1,72 +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 MarketPositionsQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketPositionsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', decimals: number }, market?: { __typename?: 'Market', id: string } | null } } | null> | null } | null, positionsConnection?: { __typename?: 'PositionConnection', edges?: Array<{ __typename?: 'PositionEdge', node: { __typename?: 'Position', openVolume: string, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
|
||||
|
||||
|
||||
export const MarketPositionsDocument = gql`
|
||||
query MarketPositions($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
id
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
decimals
|
||||
}
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
positionsConnection {
|
||||
edges {
|
||||
node {
|
||||
openVolume
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useMarketPositionsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useMarketPositionsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useMarketPositionsQuery` 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 } = useMarketPositionsQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useMarketPositionsQuery(baseOptions: Apollo.QueryHookOptions<MarketPositionsQuery, MarketPositionsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<MarketPositionsQuery, MarketPositionsQueryVariables>(MarketPositionsDocument, options);
|
||||
}
|
||||
export function useMarketPositionsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketPositionsQuery, MarketPositionsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<MarketPositionsQuery, MarketPositionsQueryVariables>(MarketPositionsDocument, options);
|
||||
}
|
||||
export type MarketPositionsQueryHookResult = ReturnType<typeof useMarketPositionsQuery>;
|
||||
export type MarketPositionsLazyQueryHookResult = ReturnType<typeof useMarketPositionsLazyQuery>;
|
||||
export type MarketPositionsQueryResult = Apollo.QueryResult<MarketPositionsQuery, MarketPositionsQueryVariables>;
|
@ -1,67 +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 PartyBalanceQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type PartyBalanceQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } } } | null> | null } | null } | null };
|
||||
|
||||
export type AccountFragment = { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } };
|
||||
|
||||
export const AccountFragmentDoc = gql`
|
||||
fragment Account on AccountBalance {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const PartyBalanceDocument = gql`
|
||||
query PartyBalance($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
...Account
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${AccountFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __usePartyBalanceQuery__
|
||||
*
|
||||
* To run a query within a React component, call `usePartyBalanceQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `usePartyBalanceQuery` 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 } = usePartyBalanceQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function usePartyBalanceQuery(baseOptions: Apollo.QueryHookOptions<PartyBalanceQuery, PartyBalanceQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<PartyBalanceQuery, PartyBalanceQueryVariables>(PartyBalanceDocument, options);
|
||||
}
|
||||
export function usePartyBalanceLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyBalanceQuery, PartyBalanceQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<PartyBalanceQuery, PartyBalanceQueryVariables>(PartyBalanceDocument, options);
|
||||
}
|
||||
export type PartyBalanceQueryHookResult = ReturnType<typeof usePartyBalanceQuery>;
|
||||
export type PartyBalanceLazyQueryHookResult = ReturnType<typeof usePartyBalanceLazyQuery>;
|
||||
export type PartyBalanceQueryResult = Apollo.QueryResult<PartyBalanceQuery, PartyBalanceQueryVariables>;
|
@ -1,75 +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 PartyMarketDataQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type PartyMarketDataQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, decimals: number }, market?: { __typename?: 'Market', id: string } | null } } | null> | null } | null, marginsConnection?: { __typename?: 'MarginConnection', edges?: Array<{ __typename?: 'MarginEdge', node: { __typename?: 'MarginLevels', initialLevel: string, maintenanceLevel: string, searchLevel: string, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
|
||||
|
||||
|
||||
export const PartyMarketDataDocument = gql`
|
||||
query PartyMarketData($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
id
|
||||
accountsConnection {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
decimals
|
||||
}
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
marginsConnection {
|
||||
edges {
|
||||
node {
|
||||
market {
|
||||
id
|
||||
}
|
||||
initialLevel
|
||||
maintenanceLevel
|
||||
searchLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __usePartyMarketDataQuery__
|
||||
*
|
||||
* To run a query within a React component, call `usePartyMarketDataQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `usePartyMarketDataQuery` 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 } = usePartyMarketDataQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function usePartyMarketDataQuery(baseOptions: Apollo.QueryHookOptions<PartyMarketDataQuery, PartyMarketDataQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<PartyMarketDataQuery, PartyMarketDataQueryVariables>(PartyMarketDataDocument, options);
|
||||
}
|
||||
export function usePartyMarketDataLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyMarketDataQuery, PartyMarketDataQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<PartyMarketDataQuery, PartyMarketDataQueryVariables>(PartyMarketDataDocument, options);
|
||||
}
|
||||
export type PartyMarketDataQueryHookResult = ReturnType<typeof usePartyMarketDataQuery>;
|
||||
export type PartyMarketDataLazyQueryHookResult = ReturnType<typeof usePartyMarketDataLazyQuery>;
|
||||
export type PartyMarketDataQueryResult = Apollo.QueryResult<PartyMarketDataQuery, PartyMarketDataQueryVariables>;
|
@ -1,14 +1,8 @@
|
||||
export * from './__generated__/EstimateOrder';
|
||||
export * from './__generated__/MarketMarkPrice';
|
||||
export * from './__generated__/MarketPositions';
|
||||
export * from './__generated__/PartyBalance';
|
||||
export * from './__generated__/PartyMarketData';
|
||||
export * from './use-calculate-slippage';
|
||||
export * from './use-fee-deal-ticket-details';
|
||||
export * from './use-market-data-mark-price';
|
||||
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';
|
||||
export * from './use-settlement-account';
|
||||
|
@ -16,7 +16,6 @@ import {
|
||||
EST_MARGIN_TOOLTIP_TEXT,
|
||||
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||
} from '../constants';
|
||||
import { usePartyBalanceQuery } from './__generated__/PartyBalance';
|
||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
||||
import { useOrderCloseOut } from './use-order-closeout';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
@ -49,22 +48,16 @@ export const useFeeDealTicketDetails = (
|
||||
return null;
|
||||
}, [derivedPrice, order.side, slippage]);
|
||||
|
||||
const estMargin: OrderMargin | null = useOrderMargin({
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: pubKey || '',
|
||||
derivedPrice,
|
||||
});
|
||||
|
||||
const { data: partyBalance } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const estCloseOut = useOrderCloseOut({
|
||||
order,
|
||||
market,
|
||||
partyData: partyBalance,
|
||||
});
|
||||
|
||||
const notionalSize = useMemo(() => {
|
||||
@ -87,7 +80,6 @@ export const useFeeDealTicketDetails = (
|
||||
estCloseOut,
|
||||
slippage,
|
||||
slippageAdjustedPrice,
|
||||
partyData: partyBalance,
|
||||
};
|
||||
}, [
|
||||
market,
|
||||
@ -97,7 +89,6 @@ export const useFeeDealTicketDetails = (
|
||||
estCloseOut,
|
||||
slippage,
|
||||
slippageAdjustedPrice,
|
||||
partyBalance,
|
||||
]);
|
||||
};
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
import { useMemo, useRef } from 'react';
|
||||
import type { MarketMarkPriceQuery } from './__generated__/MarketMarkPrice';
|
||||
import { useMarketMarkPriceQuery } from './__generated__/MarketMarkPrice';
|
||||
|
||||
export const useMarketDataMarkPrice = (marketId: string) => {
|
||||
const memoRef = useRef<MarketMarkPriceQuery | null>(null);
|
||||
const { data } = useMarketMarkPriceQuery({
|
||||
pollInterval: 5000,
|
||||
variables: { marketId },
|
||||
skip: !marketId,
|
||||
});
|
||||
return useMemo(() => {
|
||||
if (
|
||||
data &&
|
||||
data.market?.data?.markPrice !== memoRef.current?.market?.data?.markPrice
|
||||
) {
|
||||
memoRef.current = data;
|
||||
}
|
||||
return memoRef.current;
|
||||
}, [data, memoRef]);
|
||||
};
|
@ -1,60 +1,23 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
|
||||
let mockNotEmptyData = {
|
||||
party: {
|
||||
accountsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
balance: '50001000000',
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
market: {
|
||||
id: 'marketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
balance: '700000000000000000000000000000',
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
market: {
|
||||
id: 'someOtherMarketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
positionsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
openVolume: '100002',
|
||||
market: {
|
||||
id: 'marketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
openVolume: '3',
|
||||
market: {
|
||||
id: 'someOtherMarketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
...jest.requireActual('@vegaprotocol/wallet'),
|
||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||
}));
|
||||
let mockMarketAccountBalance: {
|
||||
accountBalance: string;
|
||||
accountDecimals: number | null;
|
||||
} = { accountBalance: '50001000000', accountDecimals: 5 };
|
||||
jest.mock('@vegaprotocol/accounts', () => ({
|
||||
...jest.requireActual('@vegaprotocol/accounts'),
|
||||
useMarketAccountBalance: jest.fn(() => mockMarketAccountBalance),
|
||||
}));
|
||||
|
||||
jest.mock('@apollo/client', () => ({
|
||||
...jest.requireActual('@apollo/client'),
|
||||
useQuery: jest.fn(() => ({ data: mockNotEmptyData })),
|
||||
jest.mock('@vegaprotocol/positions', () => ({
|
||||
...jest.requireActual('@vegaprotocol/positions'),
|
||||
useMarketPositionOpenVolume: jest.fn(() => '100002'),
|
||||
}));
|
||||
|
||||
describe('useOrderPosition Hook', () => {
|
||||
@ -62,85 +25,28 @@ describe('useOrderPosition Hook', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
it('should return proper positive value', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useMarketPositions({ marketId: 'marketId', partyId: 'partyId' })
|
||||
const { result } = renderHook(
|
||||
() => useMarketPositions({ marketId: 'marketId' }),
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
expect(result.current?.openVolume.toNumber()).toEqual(100002);
|
||||
expect(result.current?.balance.toString()).toEqual('50001000000');
|
||||
expect(result.current?.openVolume).toEqual('100002');
|
||||
expect(result.current?.balance).toEqual('50001000000');
|
||||
});
|
||||
|
||||
it('if balance equal 0 return null', () => {
|
||||
mockNotEmptyData = {
|
||||
party: {
|
||||
accountsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
balance: '0',
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
market: {
|
||||
id: 'marketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
positionsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
openVolume: '2',
|
||||
market: {
|
||||
id: 'marketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
const { result } = renderHook(() =>
|
||||
useMarketPositions({ marketId: 'marketId', partyId: 'partyId' })
|
||||
mockMarketAccountBalance = { accountBalance: '0', accountDecimals: 5 };
|
||||
const { result } = renderHook(
|
||||
() => useMarketPositions({ marketId: 'marketId' }),
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
expect(result.current).toBeNull();
|
||||
});
|
||||
|
||||
it('if no markets return null', () => {
|
||||
mockNotEmptyData = {
|
||||
party: {
|
||||
accountsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
balance: '33330',
|
||||
asset: {
|
||||
decimals: 5,
|
||||
},
|
||||
market: {
|
||||
id: 'otherMarketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
positionsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
openVolume: '2',
|
||||
market: {
|
||||
id: 'otherMarketId',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
const { result } = renderHook(() =>
|
||||
useMarketPositions({ marketId: 'marketId', partyId: 'partyId' })
|
||||
mockMarketAccountBalance = { accountBalance: '', accountDecimals: null };
|
||||
const { result } = renderHook(
|
||||
() => useMarketPositions({ marketId: 'marketId' }),
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
expect(result.current).toBeNull();
|
||||
});
|
||||
|
@ -1,48 +1,34 @@
|
||||
import { useMemo } from 'react';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { useMarketPositionsQuery } from './__generated__/MarketPositions';
|
||||
import { removePaginationWrapper } from '@vegaprotocol/react-helpers';
|
||||
import { useMarketAccountBalance } from '@vegaprotocol/accounts';
|
||||
import { useMarketPositionOpenVolume } from '@vegaprotocol/positions';
|
||||
|
||||
interface Props {
|
||||
marketId: string;
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
export type PositionMargin = {
|
||||
openVolume: BigNumber;
|
||||
balance: BigNumber;
|
||||
openVolume: string;
|
||||
balance: string;
|
||||
balanceDecimals?: number;
|
||||
} | null;
|
||||
|
||||
export const useMarketPositions = ({
|
||||
marketId,
|
||||
partyId,
|
||||
}: Props): PositionMargin => {
|
||||
const { data } = useMarketPositionsQuery({
|
||||
pollInterval: 5000,
|
||||
variables: { partyId },
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
export const useMarketPositions = ({ marketId }: Props): PositionMargin => {
|
||||
const { accountBalance, accountDecimals } = useMarketAccountBalance(marketId);
|
||||
const openVolume = useMarketPositionOpenVolume(marketId);
|
||||
|
||||
const accounts = removePaginationWrapper(
|
||||
data?.party?.accountsConnection?.edges
|
||||
);
|
||||
const account = accounts.find((nodes) => nodes.market?.id === marketId);
|
||||
|
||||
if (account) {
|
||||
const positionConnectionNode =
|
||||
data?.party?.positionsConnection?.edges?.find(
|
||||
(nodes) => nodes.node.market.id === marketId
|
||||
);
|
||||
const balance = new BigNumber(account.balance || 0);
|
||||
const openVolume = new BigNumber(
|
||||
positionConnectionNode?.node.openVolume || 0
|
||||
);
|
||||
if (!balance.isZero() && !openVolume.isZero()) {
|
||||
return {
|
||||
balance,
|
||||
balanceDecimals: account?.asset.decimals,
|
||||
openVolume,
|
||||
};
|
||||
return useMemo(() => {
|
||||
if (accountBalance && accountDecimals) {
|
||||
const balance = new BigNumber(accountBalance);
|
||||
const volume = new BigNumber(openVolume);
|
||||
if (!balance.isZero() && !volume.isZero()) {
|
||||
return {
|
||||
balance: accountBalance,
|
||||
balanceDecimals: accountDecimals,
|
||||
openVolume,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
}, [accountBalance, accountDecimals, openVolume]);
|
||||
};
|
||||
|
@ -1,31 +1,31 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { PositionMargin } from './use-market-positions';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { useMaximumPositionSize } from './use-maximum-position-size';
|
||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import type { PositionMargin } from './use-market-positions';
|
||||
import { useMaximumPositionSize } from './use-maximum-position-size';
|
||||
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
...jest.requireActual('@vegaprotocol/wallet'),
|
||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||
}));
|
||||
|
||||
let mockAccountBalance: {
|
||||
accountBalance: string;
|
||||
accountDecimals: number | null;
|
||||
} = { accountBalance: '200000', accountDecimals: 5 };
|
||||
jest.mock('@vegaprotocol/accounts', () => ({
|
||||
...jest.requireActual('@vegaprotocol/accounts'),
|
||||
useAccountBalance: jest.fn(() => mockAccountBalance),
|
||||
}));
|
||||
|
||||
const defaultMockMarketPositions = {
|
||||
openVolume: new BigNumber(1),
|
||||
balance: new BigNumber(100000),
|
||||
openVolume: '1',
|
||||
balance: '100000',
|
||||
};
|
||||
|
||||
let mockMarketPositions: PositionMargin | null = defaultMockMarketPositions;
|
||||
|
||||
const mockAccount: Account = {
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '200000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
name: 'tBTC TEST',
|
||||
decimals: 5,
|
||||
},
|
||||
};
|
||||
|
||||
const mockOrder: OrderSubmissionBody['orderSubmission'] = {
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
size: '1',
|
||||
@ -34,12 +34,6 @@ const mockOrder: OrderSubmissionBody['orderSubmission'] = {
|
||||
marketId: 'market-id',
|
||||
};
|
||||
|
||||
jest.mock('./use-settlement-account', () => {
|
||||
return {
|
||||
useSettlementAccount: jest.fn(() => mockAccount),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('./use-market-positions', () => ({
|
||||
useMarketPositions: ({
|
||||
marketId,
|
||||
@ -55,15 +49,15 @@ describe('useMaximumPositionSize', () => {
|
||||
mockMarketPositions = null;
|
||||
const price = '50';
|
||||
const expected = 4000;
|
||||
const { result } = renderHook(() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
partyId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
accounts: [mockAccount],
|
||||
})
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
}),
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
expect(result.current).toBe(expected);
|
||||
});
|
||||
@ -72,15 +66,15 @@ describe('useMaximumPositionSize', () => {
|
||||
const price = '50';
|
||||
mockMarketPositions = defaultMockMarketPositions;
|
||||
const expected = 3999;
|
||||
const { result } = renderHook(() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
partyId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
accounts: [mockAccount],
|
||||
})
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
}),
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
expect(result.current).toBe(expected);
|
||||
});
|
||||
@ -90,33 +84,36 @@ describe('useMaximumPositionSize', () => {
|
||||
mockOrder.side = Schema.Side.SIDE_SELL;
|
||||
mockMarketPositions = defaultMockMarketPositions;
|
||||
const expected = 4001;
|
||||
const { result } = renderHook(() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
partyId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
accounts: [mockAccount],
|
||||
})
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
}),
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
expect(result.current).toBe(expected);
|
||||
});
|
||||
|
||||
it('should return zero if no account balance', () => {
|
||||
mockAccount.balance = '0';
|
||||
mockAccountBalance = {
|
||||
accountBalance: '0',
|
||||
accountDecimals: 5,
|
||||
};
|
||||
const price = '50';
|
||||
mockMarketPositions = defaultMockMarketPositions;
|
||||
const expected = 0;
|
||||
const { result } = renderHook(() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
partyId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
accounts: [],
|
||||
})
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useMaximumPositionSize({
|
||||
marketId: '',
|
||||
price,
|
||||
settlementAssetId: '',
|
||||
order: mockOrder,
|
||||
}),
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
expect(result.current).toBe(expected);
|
||||
});
|
||||
|
@ -1,13 +1,10 @@
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
accounts: Account[];
|
||||
marketId: string;
|
||||
price?: string;
|
||||
settlementAssetId: string;
|
||||
@ -19,37 +16,26 @@ const getSize = (balance: string, price: string) =>
|
||||
|
||||
export const useMaximumPositionSize = ({
|
||||
marketId,
|
||||
accounts,
|
||||
partyId,
|
||||
price,
|
||||
settlementAssetId,
|
||||
order,
|
||||
}: Props): number => {
|
||||
const settlementAccount = useSettlementAccount(
|
||||
settlementAssetId,
|
||||
accounts,
|
||||
Schema.AccountType.ACCOUNT_TYPE_GENERAL
|
||||
);
|
||||
|
||||
const marketPositions = useMarketPositions({ marketId: marketId, partyId });
|
||||
|
||||
if (
|
||||
!settlementAccount?.balance ||
|
||||
new BigNumber(settlementAccount?.balance || 0).isZero()
|
||||
) {
|
||||
const { accountBalance } = useAccountBalance(settlementAssetId) || {};
|
||||
const marketPositions = useMarketPositions({ marketId: marketId });
|
||||
if (!accountBalance || new BigNumber(accountBalance || 0).isZero()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const size = getSize(settlementAccount.balance, price || '');
|
||||
const size = getSize(accountBalance, price || '');
|
||||
|
||||
if (!marketPositions) {
|
||||
return size.toNumber() || 0;
|
||||
}
|
||||
|
||||
const isSameSide =
|
||||
(marketPositions.openVolume.isPositive() &&
|
||||
(new BigNumber(marketPositions.openVolume).isPositive() &&
|
||||
order.side === Schema.Side.SIDE_BUY) ||
|
||||
(marketPositions.openVolume.isNegative() &&
|
||||
(new BigNumber(marketPositions.openVolume).isNegative() &&
|
||||
order.side === Schema.Side.SIDE_SELL);
|
||||
|
||||
const adjustedForVolume = new BigNumber(size)[isSameSide ? 'minus' : 'plus'](
|
||||
|
@ -1,15 +1,18 @@
|
||||
import * as React from 'react';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import type { PartyBalanceQuery } from './__generated__/PartyBalance';
|
||||
import { useOrderCloseOut } from './use-order-closeout';
|
||||
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
...jest.requireActual('@vegaprotocol/wallet'),
|
||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||
}));
|
||||
let mockMarketMargin: string | undefined = undefined;
|
||||
jest.mock('@vegaprotocol/positions', () => ({
|
||||
...jest.requireActual('@vegaprotocol/positions'),
|
||||
useMarketMargin: () => mockMarketMargin,
|
||||
}));
|
||||
|
||||
describe('useOrderCloseOut', () => {
|
||||
const order = { size: '2', side: 'SIDE_BUY' };
|
||||
@ -29,43 +32,32 @@ describe('useOrderCloseOut', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const partyData = {
|
||||
party: {
|
||||
accountsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
balance: '200000',
|
||||
asset: {
|
||||
id: 'assetId',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
data: {
|
||||
markPrice: 100000,
|
||||
},
|
||||
};
|
||||
} as unknown as MarketDealTicket;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should return proper null value', () => {
|
||||
mockMarketMargin = '-1';
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
order: order as OrderSubmissionBody['orderSubmission'],
|
||||
market: market as MarketDealTicket,
|
||||
partyData: partyData as PartyBalanceQuery,
|
||||
market: { ...market, data: { ...market.data, markPrice: '0' } },
|
||||
}),
|
||||
{
|
||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
||||
),
|
||||
wrapper: MockedProvider,
|
||||
}
|
||||
);
|
||||
expect(result.current).toEqual(null);
|
||||
});
|
||||
|
||||
it('should return proper sell value', () => {
|
||||
mockMarketMargin = '0';
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
@ -73,13 +65,10 @@ describe('useOrderCloseOut', () => {
|
||||
...order,
|
||||
side: 'SIDE_SELL',
|
||||
} as OrderSubmissionBody['orderSubmission'],
|
||||
market: market as MarketDealTicket,
|
||||
partyData: partyData as PartyBalanceQuery,
|
||||
market: market,
|
||||
}),
|
||||
{
|
||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
||||
),
|
||||
wrapper: MockedProvider,
|
||||
}
|
||||
);
|
||||
expect(result.current).toEqual('1.00');
|
||||
@ -93,12 +82,10 @@ describe('useOrderCloseOut', () => {
|
||||
...order,
|
||||
side: 'SIDE_SELL',
|
||||
} as OrderSubmissionBody['orderSubmission'],
|
||||
market: market as MarketDealTicket,
|
||||
market: { ...market, data: { ...market.data, markPrice: '0' } },
|
||||
}),
|
||||
{
|
||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
||||
),
|
||||
wrapper: MockedProvider,
|
||||
}
|
||||
);
|
||||
expect(result.current).toEqual('0.00');
|
||||
|
@ -1,85 +1,47 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
addDecimal,
|
||||
formatNumber,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import { useMarketDataMarkPrice } from './use-market-data-mark-price';
|
||||
import { usePartyMarketDataQuery } from './__generated__/PartyMarketData';
|
||||
import { addDecimal, formatNumber } from '@vegaprotocol/react-helpers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { PartyBalanceQuery } from './__generated__/PartyBalance';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import {
|
||||
useAccountBalance,
|
||||
useMarketAccountBalance,
|
||||
} from '@vegaprotocol/accounts';
|
||||
import { useMarketMargin } from '@vegaprotocol/positions';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
|
||||
interface Props {
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
market: MarketDealTicket;
|
||||
partyData?: PartyBalanceQuery;
|
||||
}
|
||||
|
||||
export const useOrderCloseOut = ({
|
||||
order,
|
||||
market,
|
||||
partyData,
|
||||
}: Props): string | null => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const accounts = removePaginationWrapper(
|
||||
partyData?.party?.accountsConnection?.edges
|
||||
export const useOrderCloseOut = ({ order, market }: Props): string | null => {
|
||||
const { accountBalance, accountDecimals } = useAccountBalance(
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id
|
||||
);
|
||||
const account = useSettlementAccount(
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
||||
accounts
|
||||
);
|
||||
const { data } = usePartyMarketDataQuery({
|
||||
pollInterval: 5000,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const markPriceData = useMarketDataMarkPrice(market.id);
|
||||
const marketPositions = useMarketPositions({
|
||||
marketId: market.id,
|
||||
partyId: pubKey || '',
|
||||
});
|
||||
const { accountBalance: positionBalance, accountDecimals: positionDecimals } =
|
||||
useMarketAccountBalance(market.id);
|
||||
const maintenanceLevel = useMarketMargin(market.id);
|
||||
|
||||
const marginMaintenanceLevel = new BigNumber(
|
||||
addDecimal(
|
||||
data?.party?.marginsConnection?.edges?.find(
|
||||
(nodes) => nodes.node.market.id === market.id
|
||||
)?.node.maintenanceLevel || 0,
|
||||
market.decimalPlaces
|
||||
)
|
||||
);
|
||||
|
||||
const dataAccounts = removePaginationWrapper(
|
||||
data?.party?.accountsConnection?.edges
|
||||
);
|
||||
const positionAccount = dataAccounts.find(
|
||||
(account) => account.market?.id === market.id
|
||||
addDecimal(maintenanceLevel || 0, market.decimalPlaces)
|
||||
);
|
||||
const positionAccountBalance = new BigNumber(
|
||||
addDecimal(
|
||||
positionAccount?.balance || 0,
|
||||
positionAccount?.asset?.decimals || 0
|
||||
)
|
||||
addDecimal(positionBalance || 0, positionDecimals || 0)
|
||||
);
|
||||
const generalAccountBalance = new BigNumber(
|
||||
addDecimal(account?.balance || 0, account?.asset.decimals || 0)
|
||||
addDecimal(accountBalance || 0, accountDecimals || 0)
|
||||
);
|
||||
const { openVolume } =
|
||||
useMarketPositions({
|
||||
marketId: market.id,
|
||||
}) || {};
|
||||
|
||||
const volume = new BigNumber(
|
||||
addDecimal(
|
||||
marketPositions?.openVolume.toString() || '0',
|
||||
market.positionDecimalPlaces
|
||||
)
|
||||
addDecimal(openVolume || '0', market.positionDecimalPlaces)
|
||||
)[order.side === Schema.Side.SIDE_BUY ? 'plus' : 'minus'](order.size);
|
||||
const markPrice = new BigNumber(
|
||||
addDecimal(
|
||||
markPriceData?.market?.data?.markPrice || 0,
|
||||
markPriceData?.market?.decimalPlaces || 0
|
||||
)
|
||||
addDecimal(market.data.markPrice || 0, market.decimalPlaces || 0)
|
||||
);
|
||||
// regarding formula (marginMaintenanceLevel - positionAccountBalance - generalAccountBalance) / volume + markPrice
|
||||
const marginDifference = marginMaintenanceLevel
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { toBigNum } from '@vegaprotocol/react-helpers';
|
||||
import type { OrderMargin } from './use-order-margin';
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
@ -14,7 +13,7 @@ interface Props {
|
||||
|
||||
export const useOrderMarginValidation = ({ market, order }: Props) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const estMargin: OrderMargin | null = useOrderMargin({
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: pubKey || '',
|
||||
|
@ -26,8 +26,8 @@ jest.mock('@apollo/client', () => ({
|
||||
}));
|
||||
|
||||
let mockMarketPositions: PositionMargin = {
|
||||
openVolume: new BigNumber(1),
|
||||
balance: new BigNumber(100000),
|
||||
openVolume: '1',
|
||||
balance: '100000',
|
||||
};
|
||||
|
||||
jest.mock('./use-market-positions', () => ({
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { useMemo } from 'react';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import type { EstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import { getDerivedPrice } from '../utils/get-price';
|
||||
@ -14,12 +14,6 @@ export interface Props {
|
||||
derivedPrice?: string;
|
||||
}
|
||||
|
||||
const addFees = (feeObj: EstimateOrderQuery['estimateOrder']['fee']) => {
|
||||
return new BigNumber(feeObj.makerFee)
|
||||
.plus(feeObj.liquidityFee)
|
||||
.plus(feeObj.infrastructureFee);
|
||||
};
|
||||
|
||||
export interface OrderMargin {
|
||||
margin: string;
|
||||
totalFees: string | null;
|
||||
@ -36,7 +30,7 @@ export const useOrderMargin = ({
|
||||
partyId,
|
||||
derivedPrice,
|
||||
}: Props): OrderMargin | null => {
|
||||
const marketPositions = useMarketPositions({ marketId: market.id, partyId });
|
||||
const { balance } = useMarketPositions({ marketId: market.id }) || {};
|
||||
const priceForEstimate = derivedPrice || getDerivedPrice(order, market);
|
||||
|
||||
const { data } = useEstimateOrderQuery({
|
||||
@ -51,29 +45,29 @@ export const useOrderMargin = ({
|
||||
},
|
||||
skip: !partyId || !market.id || !order.size || !priceForEstimate,
|
||||
});
|
||||
|
||||
if (data?.estimateOrder.marginLevels.initialLevel) {
|
||||
const fees =
|
||||
data?.estimateOrder?.fee && addFees(data.estimateOrder.fee).toString();
|
||||
const margin = BigNumber.maximum(
|
||||
0,
|
||||
new BigNumber(data.estimateOrder.marginLevels.initialLevel).minus(
|
||||
marketPositions?.balance || 0
|
||||
)
|
||||
).toString();
|
||||
|
||||
const { makerFee, liquidityFee, infrastructureFee } =
|
||||
data.estimateOrder.fee;
|
||||
|
||||
return {
|
||||
margin,
|
||||
totalFees: fees,
|
||||
fees: {
|
||||
makerFee,
|
||||
liquidityFee,
|
||||
infrastructureFee,
|
||||
},
|
||||
};
|
||||
}
|
||||
return null;
|
||||
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]);
|
||||
};
|
||||
|
@ -1,90 +0,0 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
||||
|
||||
describe('useSettlementAccount Hook', () => {
|
||||
it('should filter accounts by settlementAssetId', () => {
|
||||
const accounts: Account[] = [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '2000000000000000000000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
name: 'tBTC TEST',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1000000000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '5000000000000000000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55',
|
||||
symbol: 'VEGA',
|
||||
name: 'Vega (testnet)',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
type: Schema.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
balance: '5000000000000000000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55',
|
||||
symbol: 'VEGA',
|
||||
name: 'Vega (testnet)',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
];
|
||||
const tDAI =
|
||||
'6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61';
|
||||
const vega =
|
||||
'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55';
|
||||
|
||||
const { result: resultDai } = renderHook(() =>
|
||||
useSettlementAccount(tDAI, accounts)
|
||||
);
|
||||
expect(resultDai.current?.balance).toBe(accounts[1].balance);
|
||||
expect(resultDai.current?.asset).toEqual(accounts[1].asset);
|
||||
|
||||
const { result: resultVega } = renderHook(() =>
|
||||
useSettlementAccount(
|
||||
vega,
|
||||
accounts,
|
||||
Schema.AccountType.ACCOUNT_TYPE_MARGIN
|
||||
)
|
||||
);
|
||||
|
||||
expect(resultVega.current?.balance).toBe(accounts[3].balance);
|
||||
expect(resultVega.current?.asset).toEqual(accounts[3].asset);
|
||||
});
|
||||
|
||||
it('should return null if no accounts', () => {
|
||||
const accounts: Account[] = [];
|
||||
const settlementAssetId =
|
||||
'6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61';
|
||||
const { result } = renderHook(() =>
|
||||
useSettlementAccount(settlementAssetId, accounts)
|
||||
);
|
||||
expect(result.current).toBe(null);
|
||||
});
|
||||
});
|
@ -1,20 +0,0 @@
|
||||
import type * as Schema from '@vegaprotocol/types';
|
||||
import { useMemo } from 'react';
|
||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
||||
|
||||
export const useSettlementAccount = (
|
||||
settlementAssetId: string,
|
||||
accounts: Account[],
|
||||
type?: Schema.AccountType
|
||||
): Account | null => {
|
||||
const callback = () =>
|
||||
accounts.find((account) => {
|
||||
if (type) {
|
||||
return account.asset.id === settlementAssetId && account.type === type;
|
||||
}
|
||||
|
||||
return account.asset.id === settlementAssetId;
|
||||
});
|
||||
const account = useMemo(callback, [accounts, settlementAssetId, type]);
|
||||
return account || null;
|
||||
};
|
@ -4,3 +4,5 @@ export * from './lib/positions-data-providers';
|
||||
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';
|
||||
|
51
libs/positions/src/lib/use-market-margin.tsx
Normal file
51
libs/positions/src/lib/use-market-margin.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { marginsDataProvider } from './margin-data-provider';
|
||||
import type {
|
||||
MarginsQuery,
|
||||
MarginsSubscriptionSubscription,
|
||||
} from './__generated__/Positions';
|
||||
|
||||
const getMarketMarginPosition = ({
|
||||
data,
|
||||
marketId,
|
||||
}: {
|
||||
data: MarginsQuery['party'] | null;
|
||||
marketId: string;
|
||||
}) => {
|
||||
const positions =
|
||||
data?.marginsConnection?.edges?.map((item) => item.node) ?? [];
|
||||
return positions.find((item) => item.market.id === marketId);
|
||||
};
|
||||
|
||||
export const useMarketMargin = (marketId: string) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const [marginLevel, setMarginLevel] = useState<string>('');
|
||||
const variables = useMemo(() => {
|
||||
return { partyId: pubKey || '' };
|
||||
}, [pubKey]);
|
||||
|
||||
const update = useCallback(
|
||||
({ data }: { data: MarginsQuery['party'] | null }) => {
|
||||
const marginMarketPosition = getMarketMarginPosition({ data, marketId });
|
||||
if (marginLevel !== marginMarketPosition?.maintenanceLevel) {
|
||||
setMarginLevel(marginMarketPosition?.maintenanceLevel || '');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[marginLevel, setMarginLevel, marketId]
|
||||
);
|
||||
|
||||
useDataProvider<
|
||||
MarginsQuery['party'],
|
||||
MarginsSubscriptionSubscription['margins']
|
||||
>({
|
||||
dataProvider: marginsDataProvider,
|
||||
variables,
|
||||
skip: !pubKey || !marketId,
|
||||
update,
|
||||
});
|
||||
|
||||
return marginLevel;
|
||||
};
|
50
libs/positions/src/lib/use-market-position-open-volume.tsx
Normal file
50
libs/positions/src/lib/use-market-position-open-volume.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { positionsDataProvider } from './positions-data-providers';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
PositionsQuery,
|
||||
PositionsSubscriptionSubscription,
|
||||
} from './__generated__/Positions';
|
||||
|
||||
const getMarketPosition = ({
|
||||
data,
|
||||
marketId,
|
||||
}: {
|
||||
data: PositionsQuery['party'];
|
||||
marketId: string;
|
||||
}) => {
|
||||
const positions =
|
||||
data?.positionsConnection?.edges?.map((item) => item.node) ?? [];
|
||||
return positions.find((item) => item.market.id === marketId);
|
||||
};
|
||||
|
||||
export const useMarketPositionOpenVolume = (marketId: string) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const [openVolume, setOpenVolume] = useState<string>('');
|
||||
const variables = useMemo(() => {
|
||||
return { partyId: pubKey || '' };
|
||||
}, [pubKey]);
|
||||
const update = useCallback(
|
||||
({ data }: { data: PositionsQuery['party'] | undefined }) => {
|
||||
const position = getMarketPosition({ data, marketId });
|
||||
if (openVolume !== position?.openVolume) {
|
||||
setOpenVolume(position?.openVolume || '');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[openVolume, setOpenVolume, marketId]
|
||||
);
|
||||
|
||||
useDataProvider<
|
||||
PositionsQuery['party'],
|
||||
PositionsSubscriptionSubscription['positions']
|
||||
>({
|
||||
dataProvider: positionsDataProvider,
|
||||
variables,
|
||||
skip: !pubKey || !marketId,
|
||||
update,
|
||||
});
|
||||
|
||||
return openVolume;
|
||||
};
|
Loading…
Reference in New Issue
Block a user