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,
|
generateSimpleMarkets,
|
||||||
} from '../support/mocks/generate-markets';
|
} from '../support/mocks/generate-markets';
|
||||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
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 { 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 { generateMarketNames } from '../support/mocks/generate-market-names';
|
||||||
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
||||||
import type { Market, MarketsQuery } from '@vegaprotocol/market-list';
|
import type { Market, MarketsQuery } from '@vegaprotocol/market-list';
|
||||||
@ -30,11 +26,7 @@ describe('market selector', { tags: '@smoke' }, () => {
|
|||||||
aliasQuery(req, 'MarketData', generateMarketData());
|
aliasQuery(req, 'MarketData', generateMarketData());
|
||||||
aliasQuery(req, 'Market', generateMarket());
|
aliasQuery(req, 'Market', generateMarket());
|
||||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
|
||||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
|
||||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
|
||||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
|
||||||
aliasQuery(req, 'MarketNames', generateMarketNames());
|
aliasQuery(req, 'MarketNames', generateMarketNames());
|
||||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||||
});
|
});
|
||||||
|
@ -7,15 +7,14 @@ import {
|
|||||||
generateMarketData,
|
generateMarketData,
|
||||||
} from '../support/mocks/generate-markets';
|
} from '../support/mocks/generate-markets';
|
||||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
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 { 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 { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
||||||
import type { MarketsQuery, Market } from '@vegaprotocol/market-list';
|
import type { MarketsQuery, Market } from '@vegaprotocol/market-list';
|
||||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
import { generateChainId } from '../support/mocks/generate-chain-id';
|
||||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
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' }, () => {
|
describe('Market trade', { tags: '@smoke' }, () => {
|
||||||
let markets: Market[];
|
let markets: Market[];
|
||||||
@ -28,14 +27,13 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
|||||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
|
||||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
aliasQuery(req, 'Accounts', generateAccounts());
|
||||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
aliasQuery(req, 'Assets', generateAssets());
|
||||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
|
||||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||||
aliasQuery(req, 'Market', generateMarket());
|
aliasQuery(req, 'Market', generateMarket());
|
||||||
aliasQuery(req, 'MarketData', generateMarketData());
|
aliasQuery(req, 'MarketData', generateMarketData());
|
||||||
|
aliasQuery(req, 'Positions', generatePositions());
|
||||||
});
|
});
|
||||||
cy.visit('/markets');
|
cy.visit('/markets');
|
||||||
cy.wait('@Markets').then((response) => {
|
cy.wait('@Markets').then((response) => {
|
||||||
@ -112,6 +110,24 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
|||||||
|
|
||||||
it('size slider should work well', () => {
|
it('size slider should work well', () => {
|
||||||
if (markets?.length) {
|
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.visit(`/trading/${markets[1].id}`);
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
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', () => {
|
it('percentage selection should work well', () => {
|
||||||
if (markets?.length) {
|
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.connectVegaWallet();
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
cy.get('button[aria-label="Open short position"]').click();
|
||||||
@ -145,7 +178,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
|||||||
.find('button')
|
.find('button')
|
||||||
.should('have.text', '1');
|
.should('have.text', '1');
|
||||||
|
|
||||||
cy.getByTestId('max-label').should('have.text', '21');
|
cy.getByTestId('max-label').should('have.text', '11');
|
||||||
|
|
||||||
cy.getByTestId('percentage-selector')
|
cy.getByTestId('percentage-selector')
|
||||||
.find('button')
|
.find('button')
|
||||||
@ -155,7 +188,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
|||||||
.find('dd')
|
.find('dd')
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.find('button')
|
.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', () => {
|
it('slippage value should be displayed', () => {
|
||||||
if (markets?.length) {
|
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.connectVegaWallet();
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||||
cy.get('button[aria-label="Open short position"]').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', () => {
|
it('allow slippage value to be adjusted', () => {
|
||||||
if (markets?.length) {
|
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.connectVegaWallet();
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||||
cy.get('button[aria-label="Open short position"]').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', () => {
|
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',
|
__typename: 'AccountEdge',
|
||||||
node: {
|
node: {
|
||||||
|
@ -110,91 +110,91 @@ export const generateMarketDepth = (
|
|||||||
],
|
],
|
||||||
buy: [
|
buy: [
|
||||||
{
|
{
|
||||||
price: '9893005',
|
price: '9891005',
|
||||||
volume: '4',
|
volume: '4',
|
||||||
numberOfOrders: '3',
|
numberOfOrders: '3',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9893003',
|
price: '9890003',
|
||||||
volume: '2',
|
volume: '2',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9893001',
|
price: '9889001',
|
||||||
volume: '1',
|
volume: '1',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9892006',
|
price: '9888006',
|
||||||
volume: '3',
|
volume: '3',
|
||||||
numberOfOrders: '2',
|
numberOfOrders: '2',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9891006',
|
price: '9887006',
|
||||||
volume: '2',
|
volume: '2',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9891001',
|
price: '9886001',
|
||||||
volume: '1',
|
volume: '1',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890101',
|
price: '9885101',
|
||||||
volume: '2',
|
volume: '2',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890091',
|
price: '9884091',
|
||||||
volume: '5',
|
volume: '5',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890081',
|
price: '9883081',
|
||||||
volume: '4',
|
volume: '4',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890050',
|
price: '9882050',
|
||||||
volume: '2',
|
volume: '2',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890040',
|
price: '9881040',
|
||||||
volume: '6',
|
volume: '6',
|
||||||
numberOfOrders: '3',
|
numberOfOrders: '3',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890030',
|
price: '9880030',
|
||||||
volume: '6',
|
volume: '6',
|
||||||
numberOfOrders: '2',
|
numberOfOrders: '2',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890021',
|
price: '9879021',
|
||||||
volume: '3',
|
volume: '3',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890011',
|
price: '9878011',
|
||||||
volume: '1',
|
volume: '1',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__typename: 'PriceLevel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
price: '9890001',
|
price: '9877001',
|
||||||
volume: '11',
|
volume: '11',
|
||||||
numberOfOrders: '1',
|
numberOfOrders: '1',
|
||||||
__typename: 'PriceLevel',
|
__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 => {
|
export const generateMarket = (
|
||||||
return {
|
override?: PartialDeep<MarketQuery>
|
||||||
|
): MarketQuery => {
|
||||||
|
const defaultResult = {
|
||||||
market: {
|
market: {
|
||||||
...singleMarket,
|
...singleMarket,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
return merge(defaultResult, override);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const generateMarketData = (): MarketDataQuery => {
|
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',
|
averageEntryPrice: '84400088',
|
||||||
updatedAt: '2022-07-28T14:53:54.725477Z',
|
updatedAt: '2022-07-28T14:53:54.725477Z',
|
||||||
market: {
|
market: {
|
||||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
},
|
},
|
||||||
__typename: 'Position',
|
__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 React from 'react';
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import { DealTicketBalance } from './deal-ticket-balance';
|
|
||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { MarketDealTicketAsset } from '@vegaprotocol/market-list';
|
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 = {
|
const tDAI: MarketDealTicketAsset = {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
@ -13,23 +17,20 @@ const tDAI: MarketDealTicketAsset = {
|
|||||||
decimals: 2,
|
decimals: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const accounts: AccountFragment[] = [
|
let mockAccountBalance: {
|
||||||
{
|
accountBalance: string;
|
||||||
__typename: 'AccountBalance',
|
accountDecimals: number | null;
|
||||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
} = { accountBalance: '1000000', accountDecimals: 2 };
|
||||||
balance: '1000000',
|
jest.mock('@vegaprotocol/accounts', () => ({
|
||||||
asset: tDAI,
|
...jest.requireActual('@vegaprotocol/accounts'),
|
||||||
},
|
useAccountBalance: jest.fn(() => mockAccountBalance),
|
||||||
];
|
}));
|
||||||
|
|
||||||
describe('DealTicketBalance', function () {
|
describe('DealTicketBalance', function () {
|
||||||
it('should render the balance', () => {
|
it('should render the balance', () => {
|
||||||
const { getByText, getByRole } = render(
|
const { getByText, getByRole } = render(
|
||||||
<DealTicketBalance
|
<DealTicketBalance settlementAsset={tDAI} isWalletConnected />,
|
||||||
settlementAsset={tDAI}
|
{ wrapper: MockedProvider }
|
||||||
accounts={accounts}
|
|
||||||
isWalletConnected
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(getByRole('complementary')).toHaveAccessibleName('tDAI Balance');
|
expect(getByRole('complementary')).toHaveAccessibleName('tDAI Balance');
|
||||||
@ -39,11 +40,8 @@ describe('DealTicketBalance', function () {
|
|||||||
|
|
||||||
it('should prompt to connect wallet', () => {
|
it('should prompt to connect wallet', () => {
|
||||||
const { getByText } = render(
|
const { getByText } = render(
|
||||||
<DealTicketBalance
|
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={false} />,
|
||||||
settlementAsset={tDAI}
|
{ wrapper: MockedProvider }
|
||||||
accounts={accounts}
|
|
||||||
isWalletConnected={false}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
@ -52,12 +50,10 @@ describe('DealTicketBalance', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display zero balance', () => {
|
it('should display zero balance', () => {
|
||||||
|
mockAccountBalance = { accountBalance: '', accountDecimals: null };
|
||||||
const { getByText } = render(
|
const { getByText } = render(
|
||||||
<DealTicketBalance
|
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={true} />,
|
||||||
settlementAsset={tDAI}
|
{ wrapper: MockedProvider }
|
||||||
accounts={[]}
|
|
||||||
isWalletConnected={true}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(getByText('No tDAI left to trade')).toBeInTheDocument();
|
expect(getByText('No tDAI left to trade')).toBeInTheDocument();
|
||||||
|
@ -1,41 +1,38 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
import {
|
||||||
import * as Schema from '@vegaprotocol/types';
|
addDecimalsFormatNumber,
|
||||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
t,
|
||||||
|
toBigNum,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||||
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
|
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||||
|
|
||||||
interface DealTicketBalanceProps {
|
interface DealTicketBalanceProps {
|
||||||
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||||
accounts: AccountFragment[];
|
|
||||||
isWalletConnected: boolean;
|
isWalletConnected: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DealTicketBalance = ({
|
export const DealTicketBalance = ({
|
||||||
settlementAsset,
|
settlementAsset,
|
||||||
accounts,
|
|
||||||
isWalletConnected,
|
isWalletConnected,
|
||||||
className = '',
|
className = '',
|
||||||
}: DealTicketBalanceProps) => {
|
}: DealTicketBalanceProps) => {
|
||||||
const settlementAssetId = settlementAsset?.id;
|
const settlementAssetId = settlementAsset?.id;
|
||||||
const settlementAssetSymbol = settlementAsset?.symbol;
|
const settlementAssetSymbol = settlementAsset?.symbol;
|
||||||
const settlementAccount = useSettlementAccount(
|
|
||||||
settlementAssetId,
|
const { accountBalance, accountDecimals } =
|
||||||
accounts,
|
useAccountBalance(settlementAssetId) || {};
|
||||||
Schema.AccountType.ACCOUNT_TYPE_GENERAL
|
const settlementBalance = toBigNum(accountBalance || 0, accountDecimals || 0);
|
||||||
);
|
|
||||||
const formattedNumber =
|
const formattedNumber =
|
||||||
settlementAccount?.balance &&
|
accountBalance &&
|
||||||
settlementAccount.asset.decimals &&
|
accountDecimals &&
|
||||||
addDecimalsFormatNumber(
|
addDecimalsFormatNumber(accountBalance, accountDecimals);
|
||||||
settlementAccount.balance,
|
|
||||||
settlementAccount.asset.decimals
|
|
||||||
);
|
|
||||||
|
|
||||||
const balance = (
|
const balance = (
|
||||||
<p className="text-blue text-lg font-semibold">
|
<p className="text-blue text-lg font-semibold">
|
||||||
{settlementAccount
|
{!settlementBalance.isZero()
|
||||||
? t(`${formattedNumber}`)
|
? t(`${formattedNumber}`)
|
||||||
: `No ${settlementAssetSymbol} left to trade`}
|
: `No ${settlementAssetSymbol} left to trade`}
|
||||||
</p>
|
</p>
|
||||||
|
@ -1,14 +1,7 @@
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import {
|
import { DealTicketManager } from '@vegaprotocol/deal-ticket';
|
||||||
DealTicketManager,
|
|
||||||
usePartyBalanceQuery,
|
|
||||||
} from '@vegaprotocol/deal-ticket';
|
|
||||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import {
|
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
t,
|
|
||||||
useDataProvider,
|
|
||||||
removePaginationWrapper,
|
|
||||||
} from '@vegaprotocol/react-helpers';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import { DealTicketSteps } from './deal-ticket-steps';
|
import { DealTicketSteps } from './deal-ticket-steps';
|
||||||
import { DealTicketBalance } from './deal-ticket-balance';
|
import { DealTicketBalance } from './deal-ticket-balance';
|
||||||
@ -29,11 +22,6 @@ export const DealTicketContainer = () => {
|
|||||||
const { marketId } = useParams<{ marketId: string }>();
|
const { marketId } = useParams<{ marketId: string }>();
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
|
|
||||||
const { data: partyData } = usePartyBalanceQuery({
|
|
||||||
variables: { partyId: pubKey || '' },
|
|
||||||
skip: !pubKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
const variables = useMemo(
|
const variables = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
marketId: marketId || '',
|
marketId: marketId || '',
|
||||||
@ -49,10 +37,6 @@ export const DealTicketContainer = () => {
|
|||||||
skip: !marketId,
|
skip: !marketId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const accounts = removePaginationWrapper(
|
|
||||||
partyData?.party?.accountsConnection?.edges
|
|
||||||
);
|
|
||||||
|
|
||||||
const loader = <Loader />;
|
const loader = <Loader />;
|
||||||
if (marketId && data) {
|
if (marketId && data) {
|
||||||
const balance = (
|
const balance = (
|
||||||
@ -61,7 +45,6 @@ export const DealTicketContainer = () => {
|
|||||||
settlementAsset={
|
settlementAsset={
|
||||||
data.tradableInstrument.instrument.product?.settlementAsset
|
data.tradableInstrument.instrument.product?.settlementAsset
|
||||||
}
|
}
|
||||||
accounts={accounts || []}
|
|
||||||
isWalletConnected={!!pubKey}
|
isWalletConnected={!!pubKey}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,6 @@ import {
|
|||||||
getDefaultOrder,
|
getDefaultOrder,
|
||||||
useOrderCloseOut,
|
useOrderCloseOut,
|
||||||
useOrderMargin,
|
useOrderMargin,
|
||||||
usePartyBalanceQuery,
|
|
||||||
useMaximumPositionSize,
|
useMaximumPositionSize,
|
||||||
useCalculateSlippage,
|
useCalculateSlippage,
|
||||||
validateAmount,
|
validateAmount,
|
||||||
@ -24,7 +23,6 @@ import {
|
|||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
addDecimal,
|
addDecimal,
|
||||||
formatNumber,
|
formatNumber,
|
||||||
removePaginationWrapper,
|
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
useOrderSubmit,
|
useOrderSubmit,
|
||||||
@ -77,17 +75,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
|||||||
});
|
});
|
||||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
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({
|
const maxTrade = useMaximumPositionSize({
|
||||||
partyId: pubKey || '',
|
|
||||||
accounts: accounts,
|
|
||||||
marketId: market.id,
|
marketId: market.id,
|
||||||
settlementAssetId:
|
settlementAssetId:
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
market.tradableInstrument.instrument.product.settlementAsset.id,
|
||||||
@ -98,7 +86,6 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
|||||||
const estCloseOut = useOrderCloseOut({
|
const estCloseOut = useOrderCloseOut({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
partyData: partyBalance,
|
|
||||||
});
|
});
|
||||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
||||||
const [slippageValue, setSlippageValue] = useState(
|
const [slippageValue, setSlippageValue] = useState(
|
||||||
|
@ -697,7 +697,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
|||||||
);
|
);
|
||||||
cy.getByTestId('dealticket-warning-margin').should(
|
cy.getByTestId('dealticket-warning-margin').should(
|
||||||
'contain.text',
|
'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('deal-ticket-deposit-dialog-button').click();
|
||||||
cy.getByTestId('dialog-content')
|
cy.getByTestId('dialog-content')
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import * as Types from '@vegaprotocol/types';
|
import type { EstimateOrderQuery } from '@vegaprotocol/deal-ticket';
|
||||||
import type {
|
|
||||||
EstimateOrderQuery,
|
|
||||||
MarketMarkPriceQuery,
|
|
||||||
PartyBalanceQuery,
|
|
||||||
PartyMarketDataQuery,
|
|
||||||
} from '@vegaprotocol/deal-ticket';
|
|
||||||
|
|
||||||
const estimateOrderMock: EstimateOrderQuery = {
|
const estimateOrderMock: EstimateOrderQuery = {
|
||||||
estimateOrder: {
|
estimateOrder: {
|
||||||
@ -27,87 +21,3 @@ export const generateEstimateOrder = (
|
|||||||
) => {
|
) => {
|
||||||
return merge(estimateOrderMock, override);
|
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 { generateMargins, generatePositions } from './mocks/generate-positions';
|
||||||
import { generateTrades } from './mocks/generate-trades';
|
import { generateTrades } from './mocks/generate-trades';
|
||||||
import { generateWithdrawals } from './mocks/generate-withdrawals';
|
import { generateWithdrawals } from './mocks/generate-withdrawals';
|
||||||
import {
|
import { generateEstimateOrder } from './mocks/generate-fees';
|
||||||
generateEstimateOrder,
|
|
||||||
generateMarkPrice,
|
|
||||||
generatePartyBalance,
|
|
||||||
generatePartyMarketData,
|
|
||||||
} from './mocks/generate-fees';
|
|
||||||
import { generateMarketProposals } from './mocks/generate-proposals';
|
import { generateMarketProposals } from './mocks/generate-proposals';
|
||||||
import { generateStatistics } from './mocks/generate-statistics';
|
import { generateStatistics } from './mocks/generate-statistics';
|
||||||
import { generateChainId } from './mocks/generate-chain-id';
|
import { generateChainId } from './mocks/generate-chain-id';
|
||||||
@ -94,10 +89,7 @@ const mockTradingPage = (
|
|||||||
aliasQuery(req, 'Withdrawals', generateWithdrawals());
|
aliasQuery(req, 'Withdrawals', generateWithdrawals());
|
||||||
aliasQuery(req, 'NetworkParams', generateNetworkParameters());
|
aliasQuery(req, 'NetworkParams', generateNetworkParameters());
|
||||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||||
aliasQuery(req, 'MarketMarkPrice', generateMarkPrice());
|
|
||||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
|
||||||
aliasQuery(req, 'MarketPositions', generatePositions());
|
aliasQuery(req, 'MarketPositions', generatePositions());
|
||||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
|
||||||
aliasQuery(req, 'ProposalsList', generateMarketProposals());
|
aliasQuery(req, 'ProposalsList', generateMarketProposals());
|
||||||
aliasQuery(req, 'Deposits', generateDeposits());
|
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 './breakdown-table';
|
||||||
export * from './use-account-balance';
|
export * from './use-account-balance';
|
||||||
export * from './get-settlement-account';
|
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__/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-calculate-slippage';
|
||||||
export * from './use-fee-deal-ticket-details';
|
export * from './use-fee-deal-ticket-details';
|
||||||
export * from './use-market-data-mark-price';
|
|
||||||
export * from './use-market-positions';
|
export * from './use-market-positions';
|
||||||
export * from './use-maximum-position-size';
|
export * from './use-maximum-position-size';
|
||||||
export * from './use-order-closeout';
|
export * from './use-order-closeout';
|
||||||
export * from './use-order-margin';
|
export * from './use-order-margin';
|
||||||
export * from './use-order-margin-validation';
|
export * from './use-order-margin-validation';
|
||||||
export * from './use-settlement-account';
|
|
||||||
|
@ -16,7 +16,6 @@ import {
|
|||||||
EST_MARGIN_TOOLTIP_TEXT,
|
EST_MARGIN_TOOLTIP_TEXT,
|
||||||
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { usePartyBalanceQuery } from './__generated__/PartyBalance';
|
|
||||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
import { useCalculateSlippage } from './use-calculate-slippage';
|
||||||
import { useOrderCloseOut } from './use-order-closeout';
|
import { useOrderCloseOut } from './use-order-closeout';
|
||||||
import { useOrderMargin } from './use-order-margin';
|
import { useOrderMargin } from './use-order-margin';
|
||||||
@ -49,22 +48,16 @@ export const useFeeDealTicketDetails = (
|
|||||||
return null;
|
return null;
|
||||||
}, [derivedPrice, order.side, slippage]);
|
}, [derivedPrice, order.side, slippage]);
|
||||||
|
|
||||||
const estMargin: OrderMargin | null = useOrderMargin({
|
const estMargin = useOrderMargin({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
partyId: pubKey || '',
|
partyId: pubKey || '',
|
||||||
derivedPrice,
|
derivedPrice,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: partyBalance } = usePartyBalanceQuery({
|
|
||||||
variables: { partyId: pubKey || '' },
|
|
||||||
skip: !pubKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
const estCloseOut = useOrderCloseOut({
|
const estCloseOut = useOrderCloseOut({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
partyData: partyBalance,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const notionalSize = useMemo(() => {
|
const notionalSize = useMemo(() => {
|
||||||
@ -87,7 +80,6 @@ export const useFeeDealTicketDetails = (
|
|||||||
estCloseOut,
|
estCloseOut,
|
||||||
slippage,
|
slippage,
|
||||||
slippageAdjustedPrice,
|
slippageAdjustedPrice,
|
||||||
partyData: partyBalance,
|
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
market,
|
market,
|
||||||
@ -97,7 +89,6 @@ export const useFeeDealTicketDetails = (
|
|||||||
estCloseOut,
|
estCloseOut,
|
||||||
slippage,
|
slippage,
|
||||||
slippageAdjustedPrice,
|
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 { renderHook } from '@testing-library/react';
|
||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import { useMarketPositions } from './use-market-positions';
|
import { useMarketPositions } from './use-market-positions';
|
||||||
|
|
||||||
let mockNotEmptyData = {
|
jest.mock('@vegaprotocol/wallet', () => ({
|
||||||
party: {
|
...jest.requireActual('@vegaprotocol/wallet'),
|
||||||
accountsConnection: {
|
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||||
edges: [
|
}));
|
||||||
{
|
let mockMarketAccountBalance: {
|
||||||
node: {
|
accountBalance: string;
|
||||||
balance: '50001000000',
|
accountDecimals: number | null;
|
||||||
asset: {
|
} = { accountBalance: '50001000000', accountDecimals: 5 };
|
||||||
decimals: 5,
|
jest.mock('@vegaprotocol/accounts', () => ({
|
||||||
},
|
...jest.requireActual('@vegaprotocol/accounts'),
|
||||||
market: {
|
useMarketAccountBalance: jest.fn(() => mockMarketAccountBalance),
|
||||||
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('@apollo/client', () => ({
|
jest.mock('@vegaprotocol/positions', () => ({
|
||||||
...jest.requireActual('@apollo/client'),
|
...jest.requireActual('@vegaprotocol/positions'),
|
||||||
useQuery: jest.fn(() => ({ data: mockNotEmptyData })),
|
useMarketPositionOpenVolume: jest.fn(() => '100002'),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('useOrderPosition Hook', () => {
|
describe('useOrderPosition Hook', () => {
|
||||||
@ -62,85 +25,28 @@ describe('useOrderPosition Hook', () => {
|
|||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
it('should return proper positive value', () => {
|
it('should return proper positive value', () => {
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(
|
||||||
useMarketPositions({ marketId: 'marketId', partyId: 'partyId' })
|
() => useMarketPositions({ marketId: 'marketId' }),
|
||||||
|
{ wrapper: MockedProvider }
|
||||||
);
|
);
|
||||||
expect(result.current?.openVolume.toNumber()).toEqual(100002);
|
expect(result.current?.openVolume).toEqual('100002');
|
||||||
expect(result.current?.balance.toString()).toEqual('50001000000');
|
expect(result.current?.balance).toEqual('50001000000');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if balance equal 0 return null', () => {
|
it('if balance equal 0 return null', () => {
|
||||||
mockNotEmptyData = {
|
mockMarketAccountBalance = { accountBalance: '0', accountDecimals: 5 };
|
||||||
party: {
|
const { result } = renderHook(
|
||||||
accountsConnection: {
|
() => useMarketPositions({ marketId: 'marketId' }),
|
||||||
edges: [
|
{ wrapper: MockedProvider }
|
||||||
{
|
|
||||||
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' })
|
|
||||||
);
|
);
|
||||||
expect(result.current).toBeNull();
|
expect(result.current).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if no markets return null', () => {
|
it('if no markets return null', () => {
|
||||||
mockNotEmptyData = {
|
mockMarketAccountBalance = { accountBalance: '', accountDecimals: null };
|
||||||
party: {
|
const { result } = renderHook(
|
||||||
accountsConnection: {
|
() => useMarketPositions({ marketId: 'marketId' }),
|
||||||
edges: [
|
{ wrapper: MockedProvider }
|
||||||
{
|
|
||||||
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' })
|
|
||||||
);
|
);
|
||||||
expect(result.current).toBeNull();
|
expect(result.current).toBeNull();
|
||||||
});
|
});
|
||||||
|
@ -1,48 +1,34 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
import { useMarketPositionsQuery } from './__generated__/MarketPositions';
|
import { useMarketAccountBalance } from '@vegaprotocol/accounts';
|
||||||
import { removePaginationWrapper } from '@vegaprotocol/react-helpers';
|
import { useMarketPositionOpenVolume } from '@vegaprotocol/positions';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
marketId: string;
|
marketId: string;
|
||||||
partyId: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PositionMargin = {
|
export type PositionMargin = {
|
||||||
openVolume: BigNumber;
|
openVolume: string;
|
||||||
balance: BigNumber;
|
balance: string;
|
||||||
balanceDecimals?: number;
|
balanceDecimals?: number;
|
||||||
} | null;
|
} | null;
|
||||||
|
|
||||||
export const useMarketPositions = ({
|
export const useMarketPositions = ({ marketId }: Props): PositionMargin => {
|
||||||
marketId,
|
const { accountBalance, accountDecimals } = useMarketAccountBalance(marketId);
|
||||||
partyId,
|
const openVolume = useMarketPositionOpenVolume(marketId);
|
||||||
}: Props): PositionMargin => {
|
|
||||||
const { data } = useMarketPositionsQuery({
|
|
||||||
pollInterval: 5000,
|
|
||||||
variables: { partyId },
|
|
||||||
fetchPolicy: 'no-cache',
|
|
||||||
});
|
|
||||||
|
|
||||||
const accounts = removePaginationWrapper(
|
return useMemo(() => {
|
||||||
data?.party?.accountsConnection?.edges
|
if (accountBalance && accountDecimals) {
|
||||||
);
|
const balance = new BigNumber(accountBalance);
|
||||||
const account = accounts.find((nodes) => nodes.market?.id === marketId);
|
const volume = new BigNumber(openVolume);
|
||||||
|
if (!balance.isZero() && !volume.isZero()) {
|
||||||
if (account) {
|
return {
|
||||||
const positionConnectionNode =
|
balance: accountBalance,
|
||||||
data?.party?.positionsConnection?.edges?.find(
|
balanceDecimals: accountDecimals,
|
||||||
(nodes) => nodes.node.market.id === marketId
|
openVolume,
|
||||||
);
|
};
|
||||||
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 null;
|
||||||
return null;
|
}, [accountBalance, accountDecimals, openVolume]);
|
||||||
};
|
};
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
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 { 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 = {
|
const defaultMockMarketPositions = {
|
||||||
openVolume: new BigNumber(1),
|
openVolume: '1',
|
||||||
balance: new BigNumber(100000),
|
balance: '100000',
|
||||||
};
|
};
|
||||||
|
|
||||||
let mockMarketPositions: PositionMargin | null = defaultMockMarketPositions;
|
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'] = {
|
const mockOrder: OrderSubmissionBody['orderSubmission'] = {
|
||||||
type: Schema.OrderType.TYPE_MARKET,
|
type: Schema.OrderType.TYPE_MARKET,
|
||||||
size: '1',
|
size: '1',
|
||||||
@ -34,12 +34,6 @@ const mockOrder: OrderSubmissionBody['orderSubmission'] = {
|
|||||||
marketId: 'market-id',
|
marketId: 'market-id',
|
||||||
};
|
};
|
||||||
|
|
||||||
jest.mock('./use-settlement-account', () => {
|
|
||||||
return {
|
|
||||||
useSettlementAccount: jest.fn(() => mockAccount),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('./use-market-positions', () => ({
|
jest.mock('./use-market-positions', () => ({
|
||||||
useMarketPositions: ({
|
useMarketPositions: ({
|
||||||
marketId,
|
marketId,
|
||||||
@ -55,15 +49,15 @@ describe('useMaximumPositionSize', () => {
|
|||||||
mockMarketPositions = null;
|
mockMarketPositions = null;
|
||||||
const price = '50';
|
const price = '50';
|
||||||
const expected = 4000;
|
const expected = 4000;
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(
|
||||||
useMaximumPositionSize({
|
() =>
|
||||||
marketId: '',
|
useMaximumPositionSize({
|
||||||
partyId: '',
|
marketId: '',
|
||||||
price,
|
price,
|
||||||
settlementAssetId: '',
|
settlementAssetId: '',
|
||||||
order: mockOrder,
|
order: mockOrder,
|
||||||
accounts: [mockAccount],
|
}),
|
||||||
})
|
{ wrapper: MockedProvider }
|
||||||
);
|
);
|
||||||
expect(result.current).toBe(expected);
|
expect(result.current).toBe(expected);
|
||||||
});
|
});
|
||||||
@ -72,15 +66,15 @@ describe('useMaximumPositionSize', () => {
|
|||||||
const price = '50';
|
const price = '50';
|
||||||
mockMarketPositions = defaultMockMarketPositions;
|
mockMarketPositions = defaultMockMarketPositions;
|
||||||
const expected = 3999;
|
const expected = 3999;
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(
|
||||||
useMaximumPositionSize({
|
() =>
|
||||||
marketId: '',
|
useMaximumPositionSize({
|
||||||
partyId: '',
|
marketId: '',
|
||||||
price,
|
price,
|
||||||
settlementAssetId: '',
|
settlementAssetId: '',
|
||||||
order: mockOrder,
|
order: mockOrder,
|
||||||
accounts: [mockAccount],
|
}),
|
||||||
})
|
{ wrapper: MockedProvider }
|
||||||
);
|
);
|
||||||
expect(result.current).toBe(expected);
|
expect(result.current).toBe(expected);
|
||||||
});
|
});
|
||||||
@ -90,33 +84,36 @@ describe('useMaximumPositionSize', () => {
|
|||||||
mockOrder.side = Schema.Side.SIDE_SELL;
|
mockOrder.side = Schema.Side.SIDE_SELL;
|
||||||
mockMarketPositions = defaultMockMarketPositions;
|
mockMarketPositions = defaultMockMarketPositions;
|
||||||
const expected = 4001;
|
const expected = 4001;
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(
|
||||||
useMaximumPositionSize({
|
() =>
|
||||||
marketId: '',
|
useMaximumPositionSize({
|
||||||
partyId: '',
|
marketId: '',
|
||||||
price,
|
price,
|
||||||
settlementAssetId: '',
|
settlementAssetId: '',
|
||||||
order: mockOrder,
|
order: mockOrder,
|
||||||
accounts: [mockAccount],
|
}),
|
||||||
})
|
{ wrapper: MockedProvider }
|
||||||
);
|
);
|
||||||
expect(result.current).toBe(expected);
|
expect(result.current).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return zero if no account balance', () => {
|
it('should return zero if no account balance', () => {
|
||||||
mockAccount.balance = '0';
|
mockAccountBalance = {
|
||||||
|
accountBalance: '0',
|
||||||
|
accountDecimals: 5,
|
||||||
|
};
|
||||||
const price = '50';
|
const price = '50';
|
||||||
mockMarketPositions = defaultMockMarketPositions;
|
mockMarketPositions = defaultMockMarketPositions;
|
||||||
const expected = 0;
|
const expected = 0;
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(
|
||||||
useMaximumPositionSize({
|
() =>
|
||||||
marketId: '',
|
useMaximumPositionSize({
|
||||||
partyId: '',
|
marketId: '',
|
||||||
price,
|
price,
|
||||||
settlementAssetId: '',
|
settlementAssetId: '',
|
||||||
order: mockOrder,
|
order: mockOrder,
|
||||||
accounts: [],
|
}),
|
||||||
})
|
{ wrapper: MockedProvider }
|
||||||
);
|
);
|
||||||
expect(result.current).toBe(expected);
|
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 * as Schema from '@vegaprotocol/types';
|
||||||
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
|
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
import { useMarketPositions } from './use-market-positions';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
partyId: string;
|
|
||||||
accounts: Account[];
|
|
||||||
marketId: string;
|
marketId: string;
|
||||||
price?: string;
|
price?: string;
|
||||||
settlementAssetId: string;
|
settlementAssetId: string;
|
||||||
@ -19,37 +16,26 @@ const getSize = (balance: string, price: string) =>
|
|||||||
|
|
||||||
export const useMaximumPositionSize = ({
|
export const useMaximumPositionSize = ({
|
||||||
marketId,
|
marketId,
|
||||||
accounts,
|
|
||||||
partyId,
|
|
||||||
price,
|
price,
|
||||||
settlementAssetId,
|
settlementAssetId,
|
||||||
order,
|
order,
|
||||||
}: Props): number => {
|
}: Props): number => {
|
||||||
const settlementAccount = useSettlementAccount(
|
const { accountBalance } = useAccountBalance(settlementAssetId) || {};
|
||||||
settlementAssetId,
|
const marketPositions = useMarketPositions({ marketId: marketId });
|
||||||
accounts,
|
if (!accountBalance || new BigNumber(accountBalance || 0).isZero()) {
|
||||||
Schema.AccountType.ACCOUNT_TYPE_GENERAL
|
|
||||||
);
|
|
||||||
|
|
||||||
const marketPositions = useMarketPositions({ marketId: marketId, partyId });
|
|
||||||
|
|
||||||
if (
|
|
||||||
!settlementAccount?.balance ||
|
|
||||||
new BigNumber(settlementAccount?.balance || 0).isZero()
|
|
||||||
) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size = getSize(settlementAccount.balance, price || '');
|
const size = getSize(accountBalance, price || '');
|
||||||
|
|
||||||
if (!marketPositions) {
|
if (!marketPositions) {
|
||||||
return size.toNumber() || 0;
|
return size.toNumber() || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isSameSide =
|
const isSameSide =
|
||||||
(marketPositions.openVolume.isPositive() &&
|
(new BigNumber(marketPositions.openVolume).isPositive() &&
|
||||||
order.side === Schema.Side.SIDE_BUY) ||
|
order.side === Schema.Side.SIDE_BUY) ||
|
||||||
(marketPositions.openVolume.isNegative() &&
|
(new BigNumber(marketPositions.openVolume).isNegative() &&
|
||||||
order.side === Schema.Side.SIDE_SELL);
|
order.side === Schema.Side.SIDE_SELL);
|
||||||
|
|
||||||
const adjustedForVolume = new BigNumber(size)[isSameSide ? 'minus' : 'plus'](
|
const adjustedForVolume = new BigNumber(size)[isSameSide ? 'minus' : 'plus'](
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||||
import type { PartyBalanceQuery } from './__generated__/PartyBalance';
|
|
||||||
import { useOrderCloseOut } from './use-order-closeout';
|
import { useOrderCloseOut } from './use-order-closeout';
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/wallet', () => ({
|
jest.mock('@vegaprotocol/wallet', () => ({
|
||||||
...jest.requireActual('@vegaprotocol/wallet'),
|
...jest.requireActual('@vegaprotocol/wallet'),
|
||||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||||
}));
|
}));
|
||||||
|
let mockMarketMargin: string | undefined = undefined;
|
||||||
|
jest.mock('@vegaprotocol/positions', () => ({
|
||||||
|
...jest.requireActual('@vegaprotocol/positions'),
|
||||||
|
useMarketMargin: () => mockMarketMargin,
|
||||||
|
}));
|
||||||
|
|
||||||
describe('useOrderCloseOut', () => {
|
describe('useOrderCloseOut', () => {
|
||||||
const order = { size: '2', side: 'SIDE_BUY' };
|
const order = { size: '2', side: 'SIDE_BUY' };
|
||||||
@ -29,43 +32,32 @@ describe('useOrderCloseOut', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
data: {
|
||||||
const partyData = {
|
markPrice: 100000,
|
||||||
party: {
|
|
||||||
accountsConnection: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
balance: '200000',
|
|
||||||
asset: {
|
|
||||||
id: 'assetId',
|
|
||||||
decimals: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
} as unknown as MarketDealTicket;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
it('should return proper null value', () => {
|
it('should return proper null value', () => {
|
||||||
|
mockMarketMargin = '-1';
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() =>
|
() =>
|
||||||
useOrderCloseOut({
|
useOrderCloseOut({
|
||||||
order: order as OrderSubmissionBody['orderSubmission'],
|
order: order as OrderSubmissionBody['orderSubmission'],
|
||||||
market: market as MarketDealTicket,
|
market: { ...market, data: { ...market.data, markPrice: '0' } },
|
||||||
partyData: partyData as PartyBalanceQuery,
|
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
wrapper: MockedProvider,
|
||||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
expect(result.current).toEqual(null);
|
expect(result.current).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return proper sell value', () => {
|
it('should return proper sell value', () => {
|
||||||
|
mockMarketMargin = '0';
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() =>
|
() =>
|
||||||
useOrderCloseOut({
|
useOrderCloseOut({
|
||||||
@ -73,13 +65,10 @@ describe('useOrderCloseOut', () => {
|
|||||||
...order,
|
...order,
|
||||||
side: 'SIDE_SELL',
|
side: 'SIDE_SELL',
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
} as OrderSubmissionBody['orderSubmission'],
|
||||||
market: market as MarketDealTicket,
|
market: market,
|
||||||
partyData: partyData as PartyBalanceQuery,
|
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
wrapper: MockedProvider,
|
||||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
expect(result.current).toEqual('1.00');
|
expect(result.current).toEqual('1.00');
|
||||||
@ -93,12 +82,10 @@ describe('useOrderCloseOut', () => {
|
|||||||
...order,
|
...order,
|
||||||
side: 'SIDE_SELL',
|
side: 'SIDE_SELL',
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
} as OrderSubmissionBody['orderSubmission'],
|
||||||
market: market as MarketDealTicket,
|
market: { ...market, data: { ...market.data, markPrice: '0' } },
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
wrapper: MockedProvider,
|
||||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
expect(result.current).toEqual('0.00');
|
expect(result.current).toEqual('0.00');
|
||||||
|
@ -1,85 +1,47 @@
|
|||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { addDecimal, formatNumber } from '@vegaprotocol/react-helpers';
|
||||||
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 * as Schema from '@vegaprotocol/types';
|
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 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 {
|
interface Props {
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
order: OrderSubmissionBody['orderSubmission'];
|
||||||
market: MarketDealTicket;
|
market: MarketDealTicket;
|
||||||
partyData?: PartyBalanceQuery;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useOrderCloseOut = ({
|
export const useOrderCloseOut = ({ order, market }: Props): string | null => {
|
||||||
order,
|
const { accountBalance, accountDecimals } = useAccountBalance(
|
||||||
market,
|
market.tradableInstrument.instrument.product.settlementAsset.id
|
||||||
partyData,
|
|
||||||
}: Props): string | null => {
|
|
||||||
const { pubKey } = useVegaWallet();
|
|
||||||
const accounts = removePaginationWrapper(
|
|
||||||
partyData?.party?.accountsConnection?.edges
|
|
||||||
);
|
);
|
||||||
const account = useSettlementAccount(
|
const { accountBalance: positionBalance, accountDecimals: positionDecimals } =
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
useMarketAccountBalance(market.id);
|
||||||
accounts
|
const maintenanceLevel = useMarketMargin(market.id);
|
||||||
);
|
|
||||||
const { data } = usePartyMarketDataQuery({
|
|
||||||
pollInterval: 5000,
|
|
||||||
variables: { partyId: pubKey || '' },
|
|
||||||
skip: !pubKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
const markPriceData = useMarketDataMarkPrice(market.id);
|
|
||||||
const marketPositions = useMarketPositions({
|
|
||||||
marketId: market.id,
|
|
||||||
partyId: pubKey || '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const marginMaintenanceLevel = new BigNumber(
|
const marginMaintenanceLevel = new BigNumber(
|
||||||
addDecimal(
|
addDecimal(maintenanceLevel || 0, market.decimalPlaces)
|
||||||
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
|
|
||||||
);
|
);
|
||||||
const positionAccountBalance = new BigNumber(
|
const positionAccountBalance = new BigNumber(
|
||||||
addDecimal(
|
addDecimal(positionBalance || 0, positionDecimals || 0)
|
||||||
positionAccount?.balance || 0,
|
|
||||||
positionAccount?.asset?.decimals || 0
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
const generalAccountBalance = new BigNumber(
|
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(
|
const volume = new BigNumber(
|
||||||
addDecimal(
|
addDecimal(openVolume || '0', market.positionDecimalPlaces)
|
||||||
marketPositions?.openVolume.toString() || '0',
|
|
||||||
market.positionDecimalPlaces
|
|
||||||
)
|
|
||||||
)[order.side === Schema.Side.SIDE_BUY ? 'plus' : 'minus'](order.size);
|
)[order.side === Schema.Side.SIDE_BUY ? 'plus' : 'minus'](order.size);
|
||||||
const markPrice = new BigNumber(
|
const markPrice = new BigNumber(
|
||||||
addDecimal(
|
addDecimal(market.data.markPrice || 0, market.decimalPlaces || 0)
|
||||||
markPriceData?.market?.data?.markPrice || 0,
|
|
||||||
markPriceData?.market?.decimalPlaces || 0
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
// regarding formula (marginMaintenanceLevel - positionAccountBalance - generalAccountBalance) / volume + markPrice
|
// regarding formula (marginMaintenanceLevel - positionAccountBalance - generalAccountBalance) / volume + markPrice
|
||||||
const marginDifference = marginMaintenanceLevel
|
const marginDifference = marginMaintenanceLevel
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import { toBigNum } from '@vegaprotocol/react-helpers';
|
import { toBigNum } from '@vegaprotocol/react-helpers';
|
||||||
import type { OrderMargin } from './use-order-margin';
|
|
||||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { useOrderMargin } from './use-order-margin';
|
import { useOrderMargin } from './use-order-margin';
|
||||||
@ -14,7 +13,7 @@ interface Props {
|
|||||||
|
|
||||||
export const useOrderMarginValidation = ({ market, order }: Props) => {
|
export const useOrderMarginValidation = ({ market, order }: Props) => {
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const estMargin: OrderMargin | null = useOrderMargin({
|
const estMargin = useOrderMargin({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
partyId: pubKey || '',
|
partyId: pubKey || '',
|
||||||
|
@ -26,8 +26,8 @@ jest.mock('@apollo/client', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let mockMarketPositions: PositionMargin = {
|
let mockMarketPositions: PositionMargin = {
|
||||||
openVolume: new BigNumber(1),
|
openVolume: '1',
|
||||||
balance: new BigNumber(100000),
|
balance: '100000',
|
||||||
};
|
};
|
||||||
|
|
||||||
jest.mock('./use-market-positions', () => ({
|
jest.mock('./use-market-positions', () => ({
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import { useMarketPositions } from './use-market-positions';
|
import { useMarketPositions } from './use-market-positions';
|
||||||
import type { EstimateOrderQuery } from './__generated__/EstimateOrder';
|
|
||||||
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||||
import { getDerivedPrice } from '../utils/get-price';
|
import { getDerivedPrice } from '../utils/get-price';
|
||||||
@ -14,12 +14,6 @@ export interface Props {
|
|||||||
derivedPrice?: string;
|
derivedPrice?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const addFees = (feeObj: EstimateOrderQuery['estimateOrder']['fee']) => {
|
|
||||||
return new BigNumber(feeObj.makerFee)
|
|
||||||
.plus(feeObj.liquidityFee)
|
|
||||||
.plus(feeObj.infrastructureFee);
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface OrderMargin {
|
export interface OrderMargin {
|
||||||
margin: string;
|
margin: string;
|
||||||
totalFees: string | null;
|
totalFees: string | null;
|
||||||
@ -36,7 +30,7 @@ export const useOrderMargin = ({
|
|||||||
partyId,
|
partyId,
|
||||||
derivedPrice,
|
derivedPrice,
|
||||||
}: Props): OrderMargin | null => {
|
}: Props): OrderMargin | null => {
|
||||||
const marketPositions = useMarketPositions({ marketId: market.id, partyId });
|
const { balance } = useMarketPositions({ marketId: market.id }) || {};
|
||||||
const priceForEstimate = derivedPrice || getDerivedPrice(order, market);
|
const priceForEstimate = derivedPrice || getDerivedPrice(order, market);
|
||||||
|
|
||||||
const { data } = useEstimateOrderQuery({
|
const { data } = useEstimateOrderQuery({
|
||||||
@ -51,29 +45,29 @@ export const useOrderMargin = ({
|
|||||||
},
|
},
|
||||||
skip: !partyId || !market.id || !order.size || !priceForEstimate,
|
skip: !partyId || !market.id || !order.size || !priceForEstimate,
|
||||||
});
|
});
|
||||||
|
const { makerFee, liquidityFee, infrastructureFee } = data?.estimateOrder
|
||||||
if (data?.estimateOrder.marginLevels.initialLevel) {
|
.fee || { makerFee: '', liquidityFee: '', infrastructureFee: '' };
|
||||||
const fees =
|
const { initialLevel } = data?.estimateOrder.marginLevels ?? {};
|
||||||
data?.estimateOrder?.fee && addFees(data.estimateOrder.fee).toString();
|
return useMemo(() => {
|
||||||
const margin = BigNumber.maximum(
|
if (initialLevel) {
|
||||||
0,
|
const margin = BigNumber.maximum(
|
||||||
new BigNumber(data.estimateOrder.marginLevels.initialLevel).minus(
|
0,
|
||||||
marketPositions?.balance || 0
|
new BigNumber(initialLevel).minus(balance || 0)
|
||||||
)
|
).toString();
|
||||||
).toString();
|
const fees = new BigNumber(makerFee)
|
||||||
|
.plus(liquidityFee)
|
||||||
const { makerFee, liquidityFee, infrastructureFee } =
|
.plus(infrastructureFee)
|
||||||
data.estimateOrder.fee;
|
.toString();
|
||||||
|
return {
|
||||||
return {
|
margin,
|
||||||
margin,
|
totalFees: fees,
|
||||||
totalFees: fees,
|
fees: {
|
||||||
fees: {
|
makerFee,
|
||||||
makerFee,
|
liquidityFee,
|
||||||
liquidityFee,
|
infrastructureFee,
|
||||||
infrastructureFee,
|
},
|
||||||
},
|
};
|
||||||
};
|
}
|
||||||
}
|
return null;
|
||||||
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/positions-table';
|
||||||
export * from './lib/use-close-position';
|
export * from './lib/use-close-position';
|
||||||
export * from './lib/use-positions-data';
|
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