Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c325becce1 | ||
|
|
4bd905d083 | ||
|
|
9816f2cf0e | ||
|
|
7cd53cb1f9 | ||
|
|
5672725754 | ||
|
|
a59fab616f | ||
|
|
479c7e5664 | ||
|
|
29ba732986 | ||
|
|
2fb8c9d36b |
@@ -32,14 +32,14 @@ runs:
|
||||
- name: Import fairground network
|
||||
shell: bash
|
||||
if: ${{ inputs.capsule==false }}
|
||||
run: vegawallet network import --from-url="https://raw.githubusercontent.com/vegaprotocol/networks-internal/master/stagnet3/stagnet3.toml" --force --home ~/.vegacapsule/testnet/wallet
|
||||
run: vegawallet network import --from-url="https://raw.githubusercontent.com/vegaprotocol/networks/master/fairground/fairground.toml" --force --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Start service using fairground network
|
||||
shell: bash
|
||||
if: ${{ inputs.capsule==false }}
|
||||
run: vegawallet service run --network stagnet3 --automatic-consent --no-version-check --home ~/.vegacapsule/testnet/wallet &
|
||||
run: vegawallet service run --network fairground --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
- name: Start service using capsule network
|
||||
shell: bash
|
||||
if: ${{ inputs.capsule==true }}
|
||||
if: ${{ inputs.capsule }}
|
||||
run: vegawallet service run --network DV --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
env:
|
||||
GO111MODULE: 'on'
|
||||
GOBIN: /home/runner/go/bin
|
||||
VEGA_VERSION: 'v0.58.0'
|
||||
VEGA_VERSION: 'v0.57.0'
|
||||
steps:
|
||||
#######
|
||||
## Setup flags
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
|
||||
# See if we capsule is needed for this project
|
||||
- name: Set capsule flag
|
||||
if: ${{ github.event.inputs.project == 'explorer-e2e' || github.event.inputs.project == 'token-e2e'}}
|
||||
if: ${{ github.event.inputs.project == 'explorer-e2e' || github.event.inputs.project == 'token-e2e' }}
|
||||
run: echo RUN_CAPSULE=true >> $GITHUB_ENV
|
||||
|
||||
#######
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: false
|
||||
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: true
|
||||
|
||||
######
|
||||
## Upload logs
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
env:
|
||||
GO111MODULE: 'on'
|
||||
GOBIN: /home/runner/go/bin
|
||||
VEGA_VERSION: 'v0.58.0'
|
||||
VEGA_VERSION: 'v0.57.0'
|
||||
RUN_CAPSULE: true
|
||||
steps:
|
||||
#######
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: yarn nx run-many --skip-nx-cache --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome --parallel=1
|
||||
run: yarn nx run-many --skip-nx-cache --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
||||
working-directory: frontend-monorepo
|
||||
env:
|
||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
env:
|
||||
GO111MODULE: 'on'
|
||||
GOBIN: /home/runner/go/bin
|
||||
VEGA_VERSION: 'v0.58.0'
|
||||
VEGA_VERSION: 'v0.57.0'
|
||||
steps:
|
||||
#######
|
||||
## Setup langs
|
||||
|
||||
@@ -3,7 +3,7 @@ name: Generate queries
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
|
||||
jobs:
|
||||
master:
|
||||
|
||||
@@ -42,5 +42,3 @@ jobs:
|
||||
run: yarn nx affected:test
|
||||
- name: Build affected
|
||||
run: yarn nx affected:build
|
||||
- name: Build affected spec
|
||||
run: yarn nx affected --target=build-spec
|
||||
|
||||
Vendored
-20
@@ -1,20 +0,0 @@
|
||||
@Library('vega-shared-library') _
|
||||
|
||||
def commitHash = 'UNKNOWN'
|
||||
|
||||
pipeline {
|
||||
agent any
|
||||
options {
|
||||
skipDefaultCheckout true
|
||||
parallelsAlwaysFailFast()
|
||||
}
|
||||
stages {
|
||||
stage('approbation') {
|
||||
steps {
|
||||
sh 'printenv'
|
||||
checkout scm
|
||||
runApprobation ignoreFailure: false, frontendBranch: env.BRANCH_NAME, type: 'frontend'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,26 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
# React Environment Variables
|
||||
|
||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
||||
|
||||
# Netlify Environment Variables
|
||||
|
||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
||||
|
||||
NX_VERSION=$npm_package_version
|
||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
||||
NX_BRANCH=$BRANCH
|
||||
NX_PULL_REQUEST=$PULL_REQUEST
|
||||
NX_HEAD=$HEAD
|
||||
NX_COMMIT_REF=$COMMIT_REF
|
||||
NX_CONTEXT=$CONTEXT
|
||||
NX_REVIEW_ID=$REVIEW_ID
|
||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
||||
NX_URL=$URL
|
||||
NX_DEPLOY_URL=$DEPLOY_URL
|
||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
||||
|
||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
declare module '*.scss';
|
||||
@@ -27,7 +27,7 @@ describe('market selector', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyBalanceQuery', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||
aliasQuery(req, 'MarketNames', generateMarketNames());
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
generateSimpleMarkets,
|
||||
generateMarketsCandles,
|
||||
generateMarketsData,
|
||||
generateMarket,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
|
||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||
@@ -28,11 +27,10 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyBalanceQuery', generatePartyBalance());
|
||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||
aliasQuery(req, 'Market', generateMarket());
|
||||
});
|
||||
cy.visit('/markets');
|
||||
cy.wait('@Markets').then((response) => {
|
||||
@@ -298,7 +296,11 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
|
||||
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
|
||||
|
||||
cy.getByTestId('place-order').should('be.enabled').click();
|
||||
cy.getByTestId('place-order').click();
|
||||
cy.getByTestId('dialog-title').should(
|
||||
'have.text',
|
||||
'Awaiting network confirmation'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@ import {
|
||||
emptyPositions,
|
||||
generateMargins,
|
||||
} from '../support/mocks/generate-positions';
|
||||
import { generateAccounts } from '../support/mocks/generate-accounts';
|
||||
import { generateAssets } from '../support/mocks/generate-assets';
|
||||
import {
|
||||
generateAccounts,
|
||||
generateAssets,
|
||||
} from '../support/mocks/generate-accounts';
|
||||
import { generateOrders } from '../support/mocks/generate-orders';
|
||||
import { generateFills } from '../support/mocks/generate-fills';
|
||||
import {
|
||||
|
||||
@@ -21,14 +21,11 @@ import registerCypressGrep from 'cypress-grep';
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
registerCypressGrep();
|
||||
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
// Mock chainId fetch which happens on every page for wallet connection
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'ChainId', {
|
||||
statistics: {
|
||||
__typename: 'Statistics',
|
||||
chainId: 'vega-fairground-202210041151',
|
||||
},
|
||||
statistics: { __typename: 'Statistics', chainId: 'test-chain-id' },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
||||
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
|
||||
|
||||
export const protoCandles = [
|
||||
{ open: '9556163', close: '9587028', __typename: 'Candle' },
|
||||
@@ -124,24 +123,3 @@ export const protoMarket: Market = {
|
||||
},
|
||||
__typename: 'Market',
|
||||
};
|
||||
|
||||
export const singleMarket: SingleMarketFieldsFragment = {
|
||||
...protoMarket,
|
||||
tradableInstrument: {
|
||||
...protoMarket.tradableInstrument,
|
||||
instrument: {
|
||||
...protoMarket.tradableInstrument.instrument,
|
||||
product: {
|
||||
...protoMarket.tradableInstrument.instrument.product,
|
||||
settlementAsset: {
|
||||
...protoMarket.tradableInstrument.instrument.product.settlementAsset,
|
||||
id: 'dai-id',
|
||||
name: 'DAI Name',
|
||||
},
|
||||
oracleSpecForTradingTermination: {
|
||||
id: 'oid',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { AccountsQuery } from '@vegaprotocol/accounts';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
import type { AccountsQuery, AssetsQuery } from '@vegaprotocol/accounts';
|
||||
import { AccountType, Schema as Types } from '@vegaprotocol/types';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateAccounts = (
|
||||
@@ -12,7 +12,7 @@ export const generateAccounts = (
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
accounts: [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
market: null,
|
||||
@@ -22,7 +22,7 @@ export const generateAccounts = (
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
market: {
|
||||
@@ -35,7 +35,7 @@ export const generateAccounts = (
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
balance: '1000',
|
||||
market: {
|
||||
@@ -48,7 +48,7 @@ export const generateAccounts = (
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
balance: '1000',
|
||||
market: {
|
||||
@@ -61,7 +61,7 @@ export const generateAccounts = (
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '100000000',
|
||||
market: null,
|
||||
@@ -75,3 +75,43 @@ export const generateAccounts = (
|
||||
};
|
||||
return merge(defaultAccounts, override);
|
||||
};
|
||||
|
||||
export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
const defaultAssets: AssetsQuery = {
|
||||
assetsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: 'asset-id',
|
||||
symbol: 'tEURO',
|
||||
decimals: 5,
|
||||
name: 'Euro',
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'asset-id-2',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
name: 'DAI',
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'asset-0',
|
||||
symbol: 'AST0',
|
||||
decimals: 5,
|
||||
name: 'Asto',
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
return merge(defaultAssets, override);
|
||||
};
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { AssetsQuery } from '@vegaprotocol/assets';
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
const defaultAssets: AssetsQuery = {
|
||||
assetsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: 'asset-id',
|
||||
symbol: 'tEURO',
|
||||
decimals: 5,
|
||||
name: 'Euro',
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '1',
|
||||
withdrawThreshold: '2',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'asset-id-2',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
name: 'DAI',
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '1',
|
||||
withdrawThreshold: '2',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'asset-0',
|
||||
symbol: 'AST0',
|
||||
decimals: 5,
|
||||
name: 'Asto',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
maxFaucetAmountMint: '3',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '0',
|
||||
__typename: 'AccountBalance',
|
||||
},
|
||||
globalRewardPoolAccount: null,
|
||||
takerFeeRewardAccount: null,
|
||||
makerFeeRewardAccount: null,
|
||||
lpFeeRewardAccount: null,
|
||||
marketProposerRewardAccount: null,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
return merge(defaultAssets, override);
|
||||
};
|
||||
@@ -1,21 +1,13 @@
|
||||
import type { DealTicketQuery } from '@vegaprotocol/deal-ticket';
|
||||
import { MarketTradingMode, MarketState } from '@vegaprotocol/types';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateDealTicket = (
|
||||
override?: PartialDeep<DealTicketQuery>
|
||||
): DealTicketQuery => {
|
||||
const defaultResult: DealTicketQuery = {
|
||||
export const generateDealTicket = () => {
|
||||
return {
|
||||
market: {
|
||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
||||
decimalPlaces: 5,
|
||||
positionDecimalPlaces: 0,
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
state: 'STATE_ACTIVE',
|
||||
tradingMode: 'Continuous',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||
product: {
|
||||
quoteName: 'DAI',
|
||||
@@ -23,7 +15,6 @@ export const generateDealTicket = (
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'Future',
|
||||
@@ -36,17 +27,7 @@ export const generateDealTicket = (
|
||||
lastTrade: { price: '9893006', __typename: 'Trade' },
|
||||
__typename: 'MarketDepth',
|
||||
},
|
||||
fees: {
|
||||
factors: {
|
||||
makerFee: '0.0002',
|
||||
infrastructureFee: '0.0005',
|
||||
liquidityFee: '0.001',
|
||||
__typename: 'FeeFactors',
|
||||
},
|
||||
__typename: 'Fees',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
};
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { FillsQuery, FillFieldsFragment } from '@vegaprotocol/fills';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const generateFills = (
|
||||
seller: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
},
|
||||
aggressor: Schema.Side.SIDE_SELL,
|
||||
aggressor: Side.SIDE_SELL,
|
||||
buyerFee: {
|
||||
infrastructureFee: '5000',
|
||||
},
|
||||
@@ -30,11 +30,11 @@ export const generateFills = (
|
||||
seller: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
},
|
||||
aggressor: Schema.Side.SIDE_BUY,
|
||||
aggressor: Side.SIDE_BUY,
|
||||
}),
|
||||
generateFill({
|
||||
id: '3',
|
||||
aggressor: Schema.Side.SIDE_SELL,
|
||||
aggressor: Side.SIDE_SELL,
|
||||
market: {
|
||||
id: 'market-2',
|
||||
},
|
||||
@@ -80,7 +80,7 @@ export const generateFill = (override?: PartialDeep<FillFieldsFragment>) => {
|
||||
size: '50000',
|
||||
buyOrder: 'buy-order',
|
||||
sellOrder: 'sell-order',
|
||||
aggressor: Schema.Side.SIDE_BUY,
|
||||
aggressor: Side.SIDE_BUY,
|
||||
buyer: {
|
||||
__typename: 'Party',
|
||||
id: 'buyer-id',
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||
import type { MarketDepthQuery } from '../../../../../libs/market-depth/src/lib/__generated___/MarketDepth';
|
||||
import type { MarketDepth } from '../../../../../libs/market-depth/src/lib/__generated__/MarketDepth';
|
||||
|
||||
export const generateMarketDepth = (
|
||||
override?: PartialDeep<MarketDepthQuery>
|
||||
): MarketDepthQuery => {
|
||||
const defaultResult: MarketDepthQuery = {
|
||||
override?: PartialDeep<MarketDepth>
|
||||
): MarketDepth => {
|
||||
const defaultResult: MarketDepth = {
|
||||
market: {
|
||||
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
|
||||
depth: {
|
||||
|
||||
@@ -12,9 +12,8 @@ import type {
|
||||
MarketsDataQuery,
|
||||
MarketDataFieldsFragment,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { protoMarket, protoCandles, singleMarket } from './commons';
|
||||
import { protoMarket, protoCandles } from './commons';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type { MarketQuery } from '@vegaprotocol/market-list';
|
||||
|
||||
export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
const markets: Market[] = [
|
||||
@@ -1378,11 +1377,3 @@ export const generatePositionsMarkets = () => {
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const generateMarket = (): MarketQuery => {
|
||||
return {
|
||||
market: {
|
||||
...singleMarket,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type { OrdersQuery, OrderFieldsFragment } from '@vegaprotocol/orders';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type {
|
||||
Orders,
|
||||
Orders_party_ordersConnection_edges_node,
|
||||
} from '@vegaprotocol/orders';
|
||||
import {
|
||||
OrderStatus,
|
||||
OrderTimeInForce,
|
||||
OrderType,
|
||||
Side,
|
||||
} from '@vegaprotocol/types';
|
||||
|
||||
export const generateOrders = (
|
||||
override?: PartialDeep<OrdersQuery>
|
||||
): OrdersQuery => {
|
||||
const orders: OrderFieldsFragment[] = [
|
||||
export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
|
||||
const orders: Orders_party_ordersConnection_edges_node[] = [
|
||||
{
|
||||
__typename: 'Order',
|
||||
id: '066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
|
||||
@@ -15,12 +21,12 @@ export const generateOrders = (
|
||||
id: 'market-0',
|
||||
},
|
||||
size: '10',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_FILLED,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
status: OrderStatus.STATUS_FILLED,
|
||||
side: Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '20000000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 30).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
@@ -36,12 +42,12 @@ export const generateOrders = (
|
||||
id: 'market-1',
|
||||
},
|
||||
size: '1',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_FILLED,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
status: OrderStatus.STATUS_FILLED,
|
||||
side: Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '100',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 29).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
@@ -57,12 +63,12 @@ export const generateOrders = (
|
||||
id: 'market-2',
|
||||
},
|
||||
size: '1',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_FILLED,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
status: OrderStatus.STATUS_FILLED,
|
||||
side: Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '20000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 28).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
@@ -78,12 +84,12 @@ export const generateOrders = (
|
||||
id: 'market-3',
|
||||
},
|
||||
size: '1',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_ACTIVE,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
status: OrderStatus.STATUS_ACTIVE,
|
||||
side: Side.SIDE_BUY,
|
||||
remaining: '0',
|
||||
price: '100000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 27).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
@@ -99,12 +105,12 @@ export const generateOrders = (
|
||||
id: 'market-3',
|
||||
},
|
||||
size: '10',
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status: Schema.OrderStatus.STATUS_PARTIALLY_FILLED,
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
status: OrderStatus.STATUS_PARTIALLY_FILLED,
|
||||
side: Side.SIDE_SELL,
|
||||
remaining: '3',
|
||||
price: '100000',
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
createdAt: new Date(2020, 1, 27).toISOString(),
|
||||
updatedAt: null,
|
||||
expiresAt: null,
|
||||
@@ -114,7 +120,7 @@ export const generateOrders = (
|
||||
},
|
||||
];
|
||||
|
||||
const defaultResult: OrdersQuery = {
|
||||
const defaultResult: Orders = {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
ordersConnection: {
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartyBalanceQuery } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
|
||||
export const generatePartyBalance = (
|
||||
override?: PartialDeep<PartyBalanceQuery>
|
||||
): PartyBalanceQuery => {
|
||||
const defaultResult: PartyBalanceQuery = {
|
||||
export const generatePartyBalance = () => {
|
||||
return {
|
||||
party: {
|
||||
accounts: [
|
||||
{
|
||||
balance: '88474051',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
type: 'ACCOUNT_TYPE_GENERAL',
|
||||
asset: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
symbol: 'tDAI',
|
||||
@@ -19,11 +12,11 @@ export const generatePartyBalance = (
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
},
|
||||
{
|
||||
balance: '100000000',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
type: 'ACCOUNT_TYPE_GENERAL',
|
||||
asset: {
|
||||
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
|
||||
symbol: 'tEURO',
|
||||
@@ -31,11 +24,11 @@ export const generatePartyBalance = (
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
},
|
||||
{
|
||||
balance: '3412867',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
type: 'ACCOUNT_TYPE_GENERAL',
|
||||
asset: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
symbol: 'tDAI',
|
||||
@@ -43,11 +36,11 @@ export const generatePartyBalance = (
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
},
|
||||
{
|
||||
balance: '70007',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
type: 'ACCOUNT_TYPE_GENERAL',
|
||||
asset: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
symbol: 'tDAI',
|
||||
@@ -55,12 +48,10 @@ export const generatePartyBalance = (
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
},
|
||||
],
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ export const generatePartyMarketData = () => {
|
||||
balance: '1200000',
|
||||
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
|
||||
market: null,
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
},
|
||||
],
|
||||
marginsConnection: { edges: null, __typename: 'MarginConnection' },
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type {
|
||||
PositionsQuery,
|
||||
PositionFieldsFragment,
|
||||
MarginsQuery,
|
||||
Positions,
|
||||
Positions_party_positionsConnection_edges_node,
|
||||
} from '@vegaprotocol/positions';
|
||||
|
||||
export const generatePositions = (
|
||||
override?: PartialDeep<PositionsQuery>
|
||||
): PositionsQuery => {
|
||||
const nodes: PositionFieldsFragment[] = [
|
||||
override?: PartialDeep<Positions>
|
||||
): Positions => {
|
||||
const nodes: Positions_party_positionsConnection_edges_node[] = [
|
||||
{
|
||||
__typename: 'Position',
|
||||
realisedPNL: '0',
|
||||
@@ -48,7 +47,7 @@ export const generatePositions = (
|
||||
},
|
||||
];
|
||||
|
||||
const defaultResult: PositionsQuery = {
|
||||
const defaultResult: Positions = {
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
@@ -67,7 +66,7 @@ export const generatePositions = (
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
export const emptyPositions = (): PositionsQuery => {
|
||||
export const emptyPositions = () => {
|
||||
return {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
@@ -77,7 +76,7 @@ export const emptyPositions = (): PositionsQuery => {
|
||||
};
|
||||
};
|
||||
|
||||
export const generateMargins = (): MarginsQuery => {
|
||||
export const generateMargins = () => {
|
||||
return {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
@@ -120,7 +119,7 @@ export const generateMargins = (): MarginsQuery => {
|
||||
},
|
||||
{
|
||||
node: {
|
||||
__typename: 'MarginLevels',
|
||||
m_typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"allowJs": true,
|
||||
"types": ["cypress", "node", "cypress-real-events", "cypress-grep"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.js", "./declaration.d.ts"]
|
||||
"include": ["src/**/*.ts", "src/**/*.js"]
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
|
||||
NX_VEGA_URL=https://api.sandbox.vega.xyz/graphql
|
||||
NX_VEGA_ENV=SANDBOX
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","STAGNET1":"https://stagnet1.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
|
||||
NX_VEGA_EXPLORER_URL=https://sandbox.explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/docs/testnet
|
||||
@@ -1,10 +0,0 @@
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet1-network.json
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
|
||||
NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
@@ -4,4 +4,4 @@ NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://staging2.explorer.vega.xyz
|
||||
|
||||
@@ -77,13 +77,6 @@
|
||||
"nx build console-lite"
|
||||
]
|
||||
}
|
||||
},
|
||||
"build-spec": {
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"outputs": [],
|
||||
"options": {
|
||||
"command": "yarn tsc --project ./apps/console-lite/tsconfig.spec.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
|
||||
@@ -40,7 +40,11 @@ function App() {
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||
<Header />
|
||||
<Main />
|
||||
<VegaConnectDialog connectors={Connectors} />
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWalletDialog.connect}
|
||||
setDialogOpen={vegaWalletDialog.setConnect}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWalletDialog.manage}
|
||||
setDialogOpen={vegaWalletDialog.setManage}
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { AccountType } from "@vegaprotocol/types";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: PartyBalanceQuery
|
||||
// ====================================================
|
||||
|
||||
export interface PartyBalanceQuery_party_accounts_asset {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The ID of the asset
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
*/
|
||||
symbol: string;
|
||||
/**
|
||||
* The full name of the asset (e.g: Great British Pound)
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
|
||||
*/
|
||||
decimals: number;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQuery_party_accounts {
|
||||
__typename: "Account";
|
||||
/**
|
||||
* Account type (General, Margin, etc)
|
||||
*/
|
||||
type: AccountType;
|
||||
/**
|
||||
* Balance as string - current account balance (approx. as balances can be updated several times per second)
|
||||
*/
|
||||
balance: string;
|
||||
/**
|
||||
* Asset, the 'currency'
|
||||
*/
|
||||
asset: PartyBalanceQuery_party_accounts_asset;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQuery_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Collateral accounts relating to a party
|
||||
*/
|
||||
accounts: PartyBalanceQuery_party_accounts[] | null;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQuery {
|
||||
/**
|
||||
* An entity that is trading on the Vega network
|
||||
*/
|
||||
party: PartyBalanceQuery_party | null;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQueryVariables {
|
||||
partyId: string;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ export type PartyBalanceQueryQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accounts?: Array<{ __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } }> | null } | null };
|
||||
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accounts?: Array<{ __typename?: 'Account', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } }> | null } | null };
|
||||
|
||||
|
||||
export const PartyBalanceQueryDocument = gql`
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import type {
|
||||
AccountFragment,
|
||||
DealTicketMarketFragment,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
PartyBalanceQuery_party_accounts,
|
||||
PartyBalanceQuery_party_accounts_asset,
|
||||
} from './__generated__/PartyBalanceQuery';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
|
||||
const tDAI: DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'] =
|
||||
{
|
||||
__typename: 'Asset',
|
||||
id: '1',
|
||||
symbol: 'tDAI',
|
||||
name: 'TDAI',
|
||||
decimals: 2,
|
||||
};
|
||||
const tDAI: PartyBalanceQuery_party_accounts_asset = {
|
||||
__typename: 'Asset',
|
||||
id: '1',
|
||||
symbol: 'tDAI',
|
||||
name: 'TDAI',
|
||||
decimals: 2,
|
||||
};
|
||||
|
||||
const accounts: AccountFragment[] = [
|
||||
const accounts: PartyBalanceQuery_party_accounts[] = [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1000000',
|
||||
asset: tDAI,
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartyBalanceQuery_party_accounts } from './__generated__/PartyBalanceQuery';
|
||||
import { useSettlementAccount } from '../../hooks/use-settlement-account';
|
||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
import type {
|
||||
AccountFragment,
|
||||
DealTicketMarketFragment,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
|
||||
|
||||
interface DealTicketBalanceProps {
|
||||
settlementAsset: DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
accounts: AccountFragment[];
|
||||
accounts: PartyBalanceQuery_party_accounts[];
|
||||
isWalletConnected: boolean;
|
||||
className?: string;
|
||||
}
|
||||
@@ -27,7 +26,7 @@ export const DealTicketBalance = ({
|
||||
accounts,
|
||||
AccountType.ACCOUNT_TYPE_GENERAL
|
||||
);
|
||||
const formattedNumber =
|
||||
const formatedNumber =
|
||||
settlementAccount?.balance &&
|
||||
settlementAccount.asset.decimals &&
|
||||
addDecimalsFormatNumber(
|
||||
@@ -38,7 +37,7 @@ export const DealTicketBalance = ({
|
||||
const balance = (
|
||||
<p className="text-blue text-lg font-semibold">
|
||||
{settlementAccount
|
||||
? t(`${formattedNumber}`)
|
||||
? t(`${formatedNumber}`)
|
||||
: `No ${settlementAssetSymbol} left to trade`}
|
||||
</p>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import {
|
||||
DealTicketManager,
|
||||
DealTicketContainer as Container,
|
||||
usePartyBalanceQuery,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
@@ -10,20 +11,41 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { DealTicketSteps } from './deal-ticket-steps';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
import Baubles from './baubles-decor';
|
||||
import type { PartyBalanceQuery } from './__generated__/PartyBalanceQuery';
|
||||
import ConnectWallet from '../wallet-connector';
|
||||
|
||||
const tempEmptyText = (
|
||||
<p>{t('Please select a market from the markets page')}</p>
|
||||
);
|
||||
|
||||
const PARTY_BALANCE_QUERY = gql`
|
||||
query PartyBalanceQuery($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accounts {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const DealTicketContainer = () => {
|
||||
const { marketId } = useParams<{ marketId: string }>();
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
const { data: partyData, loading } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
const { data: partyData, loading } = useQuery<PartyBalanceQuery>(
|
||||
PARTY_BALANCE_QUERY,
|
||||
{
|
||||
variables: { partyId: pubKey },
|
||||
skip: !pubKey,
|
||||
}
|
||||
);
|
||||
|
||||
const loader = <Loader />;
|
||||
|
||||
@@ -48,7 +70,7 @@ export const DealTicketContainer = () => {
|
||||
return (
|
||||
<DealTicketManager market={data.market}>
|
||||
{loading ? loader : balance}
|
||||
<DealTicketSteps market={data.market} />
|
||||
<DealTicketSteps market={data.market} partyData={partyData} />
|
||||
</DealTicketManager>
|
||||
);
|
||||
}}
|
||||
|
||||
+41
-40
@@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Icon, Tooltip, TrafficLight } from '@vegaprotocol/ui-toolkit';
|
||||
import { Icon, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import * as constants from './constants';
|
||||
import { TrafficLight } from '../traffic-light';
|
||||
|
||||
interface DealTicketEstimatesProps {
|
||||
quoteName?: string;
|
||||
@@ -16,6 +17,45 @@ interface DealTicketEstimatesProps {
|
||||
slippage?: string;
|
||||
}
|
||||
|
||||
interface DataTitleProps {
|
||||
children: ReactNode;
|
||||
quoteName?: string;
|
||||
}
|
||||
|
||||
export const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
|
||||
<dt>
|
||||
{children}
|
||||
{quoteName && <small> ({quoteName})</small>}
|
||||
</dt>
|
||||
);
|
||||
|
||||
interface ValueTooltipProps {
|
||||
value?: string;
|
||||
children?: ReactNode;
|
||||
description: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export const ValueTooltipRow = ({
|
||||
value,
|
||||
children,
|
||||
description,
|
||||
id,
|
||||
}: ValueTooltipProps) => (
|
||||
<dd className="flex gap-x-2 items-center">
|
||||
{value || children}
|
||||
<Tooltip align="center" description={description}>
|
||||
<div className="cursor-help" id={id || ''} tabIndex={-1}>
|
||||
<Icon
|
||||
name={IconNames.ISSUE}
|
||||
className="block rotate-180"
|
||||
ariaLabel={description}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</dd>
|
||||
);
|
||||
|
||||
export const DealTicketEstimates = ({
|
||||
price,
|
||||
quoteName,
|
||||
@@ -91,42 +131,3 @@ export const DealTicketEstimates = ({
|
||||
)}
|
||||
</dl>
|
||||
);
|
||||
|
||||
interface DataTitleProps {
|
||||
children: ReactNode;
|
||||
quoteName?: string;
|
||||
}
|
||||
|
||||
export const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
|
||||
<dt>
|
||||
{children}
|
||||
{quoteName && <small> ({quoteName})</small>}
|
||||
</dt>
|
||||
);
|
||||
|
||||
interface ValueTooltipProps {
|
||||
value?: string;
|
||||
children?: ReactNode;
|
||||
description: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export const ValueTooltipRow = ({
|
||||
value,
|
||||
children,
|
||||
description,
|
||||
id,
|
||||
}: ValueTooltipProps) => (
|
||||
<dd className="flex gap-x-2 items-center">
|
||||
{value || children}
|
||||
<Tooltip align="center" description={description}>
|
||||
<div className="cursor-help" id={id || ''} tabIndex={-1}>
|
||||
<Icon
|
||||
name={IconNames.ISSUE}
|
||||
className="block rotate-180"
|
||||
ariaLabel={description}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</dd>
|
||||
);
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DealTicketEstimates } from '@vegaprotocol/deal-ticket';
|
||||
import React from 'react';
|
||||
import { DealTicketEstimates } from './deal-ticket-estimates';
|
||||
import { DealTicketSizeInput } from './deal-ticket-size-input';
|
||||
|
||||
interface DealTicketSizeProps {
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
Dialog,
|
||||
Icon,
|
||||
Intent,
|
||||
Tooltip,
|
||||
TrafficLight,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import * as constants from './constants';
|
||||
import { TrafficLight } from '../traffic-light';
|
||||
import { Dialog, Icon, Intent, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { InputSetter } from '../../components/input-setter';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import {
|
||||
DataTitle,
|
||||
EST_SLIPPAGE,
|
||||
ValueTooltipRow,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { DataTitle, ValueTooltipRow } from './deal-ticket-estimates';
|
||||
|
||||
interface DealTicketSlippageProps {
|
||||
step?: number;
|
||||
@@ -48,12 +40,12 @@ export const DealTicketSlippage = ({
|
||||
const formLabel = (
|
||||
<label className="flex items-center mb-1">
|
||||
<span className="mr-1">{t('Adjust slippage tolerance')}</span>
|
||||
<Tooltip align="center" description={EST_SLIPPAGE}>
|
||||
<Tooltip align="center" description={constants.EST_SLIPPAGE}>
|
||||
<div className="cursor-help" tabIndex={-1}>
|
||||
<Icon
|
||||
name={IconNames.ISSUE}
|
||||
className="block rotate-180"
|
||||
ariaLabel={EST_SLIPPAGE}
|
||||
ariaLabel={constants.EST_SLIPPAGE}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -91,7 +83,7 @@ export const DealTicketSlippage = ({
|
||||
<DataTitle>{t('Est. Price Impact / Slippage')}</DataTitle>
|
||||
<div className="flex">
|
||||
<div className="mr-1">
|
||||
<ValueTooltipRow description={EST_SLIPPAGE}>
|
||||
<ValueTooltipRow description={constants.EST_SLIPPAGE}>
|
||||
<TrafficLight value={value} q1={1} q2={5}>
|
||||
{value}%
|
||||
</TrafficLight>
|
||||
|
||||
@@ -3,13 +3,6 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { Stepper } from '../stepper';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
useOrderCloseOut,
|
||||
useOrderMargin,
|
||||
usePartyBalanceQuery,
|
||||
useMaximumPositionSize,
|
||||
useCalculateSlippage,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
getDefaultOrder,
|
||||
useOrderValidation,
|
||||
@@ -19,13 +12,12 @@ import { InputError } from '@vegaprotocol/ui-toolkit';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { MarketSelector } from '@vegaprotocol/deal-ticket';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { VegaTxStatus } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet, VegaTxStatus } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
t,
|
||||
addDecimalsFormatNumber,
|
||||
toDecimal,
|
||||
removeDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
useOrderSubmit,
|
||||
@@ -38,14 +30,23 @@ import { DealTicketSize } from './deal-ticket-size';
|
||||
import MarketNameRenderer from '../simple-market-list/simple-market-renderer';
|
||||
import SideSelector, { SIDE_NAMES } from './side-selector';
|
||||
import ReviewTrade from './review-trade';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type { PartyBalanceQuery } from './__generated__/PartyBalanceQuery';
|
||||
import useOrderCloseOut from '../../hooks/use-order-closeout';
|
||||
import useOrderMargin from '../../hooks/use-order-margin';
|
||||
import useMaximumPositionSize from '../../hooks/use-maximum-position-size';
|
||||
import useCalculateSlippage from '../../hooks/use-calculate-slippage';
|
||||
import { Side, OrderType } from '@vegaprotocol/types';
|
||||
import { DealTicketSlippage } from './deal-ticket-slippage';
|
||||
|
||||
interface DealTicketMarketProps {
|
||||
market: DealTicketMarketFragment;
|
||||
partyData?: PartyBalanceQuery;
|
||||
}
|
||||
|
||||
export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
export const DealTicketSteps = ({
|
||||
market,
|
||||
partyData,
|
||||
}: DealTicketMarketProps) => {
|
||||
const navigate = useNavigate();
|
||||
const setMarket = useCallback(
|
||||
(marketId: string) => {
|
||||
@@ -67,11 +68,15 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
|
||||
const emptyString = ' - ';
|
||||
const step = toDecimal(market.positionDecimalPlaces);
|
||||
const orderType = watch('type');
|
||||
const orderTimeInForce = watch('timeInForce');
|
||||
const orderSide = watch('side');
|
||||
const orderSize = watch('size');
|
||||
const order = watch();
|
||||
const { message: invalidText, isDisabled } = useOrderValidation({
|
||||
market,
|
||||
orderType: order.type,
|
||||
orderTimeInForce: order.timeInForce,
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
fieldErrors: errors,
|
||||
});
|
||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
||||
@@ -82,14 +87,9 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
partyId: pubKey || '',
|
||||
});
|
||||
|
||||
const { data: partyBalance } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const maxTrade = useMaximumPositionSize({
|
||||
partyId: pubKey || '',
|
||||
accounts: partyBalance?.party?.accounts || [],
|
||||
accounts: partyData?.party?.accounts || [],
|
||||
marketId: market.id,
|
||||
settlementAssetId:
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
||||
@@ -97,11 +97,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
order,
|
||||
});
|
||||
|
||||
const estCloseOut = useOrderCloseOut({
|
||||
order,
|
||||
market,
|
||||
partyData: partyBalance,
|
||||
});
|
||||
const estCloseOut = useOrderCloseOut({ order, market, partyData });
|
||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
||||
const [slippageValue, setSlippageValue] = useState(
|
||||
slippage ? parseFloat(slippage) : 0
|
||||
@@ -118,7 +114,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
|
||||
const price = useMemo(() => {
|
||||
if (slippage && market?.depth?.lastTrade?.price) {
|
||||
const isLong = order.side === Schema.Side.SIDE_BUY;
|
||||
const isLong = order.side === Side.SIDE_BUY;
|
||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
||||
parseFloat(slippage) / 100
|
||||
);
|
||||
@@ -134,26 +130,26 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
|
||||
const notionalSize = useMemo(() => {
|
||||
if (price) {
|
||||
const size = new BigNumber(price).multipliedBy(order.size).toNumber();
|
||||
const size = new BigNumber(price).multipliedBy(orderSize).toNumber();
|
||||
|
||||
return addDecimalsFormatNumber(size, market.decimalPlaces);
|
||||
}
|
||||
return null;
|
||||
}, [market.decimalPlaces, order.size, price]);
|
||||
}, [market.decimalPlaces, orderSize, price]);
|
||||
|
||||
const fees = useMemo(() => {
|
||||
if (estMargin?.totalFees && notionalSize) {
|
||||
const percentage = new BigNumber(estMargin?.totalFees)
|
||||
if (estMargin?.fees && notionalSize) {
|
||||
const percentage = new BigNumber(estMargin?.fees)
|
||||
.dividedBy(notionalSize)
|
||||
.multipliedBy(100)
|
||||
.decimalPlaces(2)
|
||||
.toString();
|
||||
|
||||
return `${estMargin.totalFees} (${percentage}%)`;
|
||||
return `${estMargin.fees} (${percentage}%)`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [estMargin?.totalFees, notionalSize]);
|
||||
}, [estMargin?.fees, notionalSize]);
|
||||
|
||||
const max = useMemo(() => {
|
||||
return new BigNumber(maxTrade)
|
||||
@@ -161,10 +157,6 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
.toNumber();
|
||||
}, [market.positionDecimalPlaces, maxTrade]);
|
||||
|
||||
useEffect(() => {
|
||||
setSlippageValue(slippage ? parseFloat(slippage) : 0);
|
||||
}, [slippage]);
|
||||
|
||||
const onSizeChange = useCallback(
|
||||
(value: number) => {
|
||||
const newVal = new BigNumber(value)
|
||||
@@ -182,7 +174,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
(value: number) => {
|
||||
if (market?.depth?.lastTrade?.price) {
|
||||
if (value) {
|
||||
const isLong = order.side === Schema.Side.SIDE_BUY;
|
||||
const isLong = order.side === Side.SIDE_BUY;
|
||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
||||
value / 100
|
||||
);
|
||||
@@ -193,11 +185,11 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
|
||||
setValue('price', bestAskPrice);
|
||||
|
||||
if (order.type === Schema.OrderType.TYPE_MARKET) {
|
||||
setValue('type', Schema.OrderType.TYPE_LIMIT);
|
||||
if (orderType === OrderType.TYPE_MARKET) {
|
||||
setValue('type', OrderType.TYPE_LIMIT);
|
||||
}
|
||||
} else {
|
||||
setValue('type', Schema.OrderType.TYPE_MARKET);
|
||||
setValue('type', OrderType.TYPE_MARKET);
|
||||
setValue('price', market?.depth?.lastTrade?.price);
|
||||
}
|
||||
}
|
||||
@@ -207,8 +199,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
market.decimalPlaces,
|
||||
market?.depth?.lastTrade?.price,
|
||||
order.side,
|
||||
order.type,
|
||||
setSlippageValue,
|
||||
orderType,
|
||||
setValue,
|
||||
]
|
||||
);
|
||||
@@ -255,7 +246,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
)}
|
||||
/>
|
||||
),
|
||||
value: SIDE_NAMES[order.side] || '',
|
||||
value: SIDE_NAMES[orderSide] || '',
|
||||
},
|
||||
{
|
||||
label: t('Choose Position Size'),
|
||||
@@ -267,7 +258,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
min={step}
|
||||
max={max}
|
||||
onSizeChange={onSizeChange}
|
||||
size={new BigNumber(order.size).toNumber()}
|
||||
size={new BigNumber(orderSize).toNumber()}
|
||||
name="size"
|
||||
price={formattedPrice || emptyString}
|
||||
positionDecimalPlaces={market.positionDecimalPlaces}
|
||||
@@ -276,7 +267,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
.symbol
|
||||
}
|
||||
notionalSize={notionalSize || emptyString}
|
||||
estCloseOut={estCloseOut || emptyString}
|
||||
estCloseOut={estCloseOut}
|
||||
fees={fees || emptyString}
|
||||
estMargin={estMargin?.margin || emptyString}
|
||||
/>
|
||||
@@ -286,9 +277,9 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
t('Loading...')
|
||||
'loading...'
|
||||
),
|
||||
value: order.size,
|
||||
value: orderSize,
|
||||
},
|
||||
{
|
||||
label: t('Review Trade'),
|
||||
@@ -306,7 +297,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
isDisabled={isDisabled}
|
||||
transactionStatus={transactionStatus}
|
||||
order={order}
|
||||
estCloseOut={estCloseOut || emptyString}
|
||||
estCloseOut={estCloseOut}
|
||||
estMargin={estMargin?.margin || emptyString}
|
||||
price={formattedPrice || emptyString}
|
||||
quoteName={
|
||||
@@ -321,15 +312,9 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
title={getOrderDialogTitle(finalizedOrder?.status)}
|
||||
intent={getOrderDialogIntent(finalizedOrder?.status)}
|
||||
icon={getOrderDialogIcon(finalizedOrder?.status)}
|
||||
content={{
|
||||
Complete: (
|
||||
<OrderFeedback
|
||||
transaction={transaction}
|
||||
order={finalizedOrder}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<OrderFeedback transaction={transaction} order={finalizedOrder} />
|
||||
</Dialog>
|
||||
</div>
|
||||
),
|
||||
disabled: true,
|
||||
|
||||
@@ -4,18 +4,19 @@ import {
|
||||
KeyValueTable,
|
||||
KeyValueTableRow,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketEstimates } from '@vegaprotocol/deal-ticket';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { SIDE_NAMES } from './side-selector';
|
||||
import SimpleMarketExpires from '../simple-market-list/simple-market-expires';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import type {
|
||||
MarketTags,
|
||||
MarketTagsVariables,
|
||||
} from './__generated__/MarketTags';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { MarketExpires } from '@vegaprotocol/market-info';
|
||||
import { DealTicketEstimates } from './deal-ticket-estimates';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
|
||||
export const MARKET_TAGS_QUERY = gql`
|
||||
query MarketTags($marketId: ID!) {
|
||||
@@ -72,10 +73,9 @@ export default ({
|
||||
<div
|
||||
className={classNames(
|
||||
{
|
||||
'buyButton dark:buyButtonDark':
|
||||
order.side === Schema.Side.SIDE_BUY,
|
||||
'buyButton dark:buyButtonDark': order.side === Side.SIDE_BUY,
|
||||
'sellButton dark:sellButtonDark':
|
||||
order.side === Schema.Side.SIDE_SELL,
|
||||
order.side === Side.SIDE_SELL,
|
||||
},
|
||||
'px-2 py-1 inline text-ui-small'
|
||||
)}
|
||||
@@ -86,7 +86,7 @@ export default ({
|
||||
<div>
|
||||
{tagsData?.market?.tradableInstrument.instrument.metadata
|
||||
.tags && (
|
||||
<MarketExpires
|
||||
<SimpleMarketExpires
|
||||
tags={
|
||||
tagsData?.market.tradableInstrument.instrument.metadata.tags
|
||||
}
|
||||
|
||||
@@ -2,16 +2,16 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
|
||||
interface SideSelectorProps {
|
||||
value: Schema.Side;
|
||||
onSelect: (side: Schema.Side) => void;
|
||||
value: Side;
|
||||
onSelect: (side: Side) => void;
|
||||
}
|
||||
|
||||
export const SIDE_NAMES: Record<Schema.Side, string> = {
|
||||
[Schema.Side.SIDE_BUY]: t('Long'),
|
||||
[Schema.Side.SIDE_SELL]: t('Short'),
|
||||
export const SIDE_NAMES: Record<Side, string> = {
|
||||
[Side.SIDE_BUY]: t('Long'),
|
||||
[Side.SIDE_SELL]: t('Short'),
|
||||
};
|
||||
|
||||
export default ({ value, onSelect }: SideSelectorProps) => {
|
||||
@@ -31,9 +31,9 @@ export default ({ value, onSelect }: SideSelectorProps) => {
|
||||
className={classNames(
|
||||
'px-8 py-2',
|
||||
'buyButton hover:buyButton dark:buyButtonDark dark:hover:buyButtonDark',
|
||||
{ selected: value === Schema.Side.SIDE_BUY }
|
||||
{ selected: value === Side.SIDE_BUY }
|
||||
)}
|
||||
onClick={() => onSelect(Schema.Side.SIDE_BUY)}
|
||||
onClick={() => onSelect(Side.SIDE_BUY)}
|
||||
>
|
||||
{t('Long')}
|
||||
</button>
|
||||
@@ -43,9 +43,9 @@ export default ({ value, onSelect }: SideSelectorProps) => {
|
||||
className={classNames(
|
||||
'px-8 py-2',
|
||||
'sellButton hover:sellButton dark:sellButtonDark dark:hover:sellButtonDark',
|
||||
{ selected: value === Schema.Side.SIDE_SELL }
|
||||
{ selected: value === Side.SIDE_SELL }
|
||||
)}
|
||||
onClick={() => onSelect(Schema.Side.SIDE_SELL)}
|
||||
onClick={() => onSelect(Side.SIDE_SELL)}
|
||||
>
|
||||
{t('Short')}
|
||||
</button>
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
import { useMemo } from 'react';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { DepositManager } from '@vegaprotocol/deposits';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { enabledAssetsProvider } from '@vegaprotocol/assets';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { getEnabledAssets, t } from '@vegaprotocol/react-helpers';
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { Web3Container } from '@vegaprotocol/web3';
|
||||
import type { DepositAssets } from './__generated__/DepositAssets';
|
||||
|
||||
const DEPOSITS_QUERY = gql`
|
||||
query DepositAssets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
status
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* Fetches data required for the Deposit page
|
||||
@@ -14,19 +34,20 @@ import { Web3Container } from '@vegaprotocol/web3';
|
||||
export const DepositContainer = () => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const { pubKey } = useVegaWallet();
|
||||
const variables = useMemo(() => ({ partyId: pubKey }), [pubKey]);
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: enabledAssetsProvider,
|
||||
variables,
|
||||
|
||||
const { data, loading, error } = useQuery<DepositAssets>(DEPOSITS_QUERY, {
|
||||
variables: { partyId: pubKey },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const assets = getEnabledAssets(data);
|
||||
|
||||
return (
|
||||
<AsyncRenderer data={data} loading={loading} error={error}>
|
||||
{data && data.length ? (
|
||||
<AsyncRenderer<DepositAssets> data={data} loading={loading} error={error}>
|
||||
{assets.length ? (
|
||||
<Web3Container>
|
||||
<DepositManager
|
||||
assets={data}
|
||||
assets={assets}
|
||||
isFaucetable={VEGA_ENV !== Networks.MAINNET}
|
||||
/>
|
||||
</Web3Container>
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import Logo from './logo';
|
||||
import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
|
||||
import LocalContext from '../../context/local-context';
|
||||
|
||||
const Header = () => {
|
||||
const { updateVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
updateVegaWalletDialog: store.updateVegaWalletDialog,
|
||||
}));
|
||||
const {
|
||||
vegaWalletDialog: { setManage },
|
||||
vegaWalletDialog: { setConnect, setManage },
|
||||
theme,
|
||||
toggleTheme,
|
||||
} = useContext(LocalContext);
|
||||
@@ -22,7 +18,7 @@ const Header = () => {
|
||||
<Logo />
|
||||
<div className="flex items-center gap-2 ml-auto relative z-10">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={updateVegaWalletDialog}
|
||||
setConnectDialog={setConnect}
|
||||
setManageDialog={setManage}
|
||||
/>
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
|
||||
|
||||
@@ -22,9 +22,15 @@ const AccountsManager = () => {
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
const update = useCallback(
|
||||
({ data }: { data: AccountFields[] | null }) => {
|
||||
dataRef.current = data;
|
||||
gridRef.current?.api?.refreshInfiniteCache();
|
||||
return true;
|
||||
if (!gridRef.current?.api) {
|
||||
return false;
|
||||
}
|
||||
if (dataRef.current?.length) {
|
||||
dataRef.current = data;
|
||||
gridRef.current.api.refreshInfiniteCache();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[gridRef]
|
||||
);
|
||||
@@ -33,9 +39,7 @@ const AccountsManager = () => {
|
||||
update,
|
||||
variables,
|
||||
});
|
||||
if (!dataRef.current && data) {
|
||||
dataRef.current = data;
|
||||
}
|
||||
dataRef.current = data;
|
||||
const getRows = async ({
|
||||
successCallback,
|
||||
startRow,
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
t,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
@@ -118,13 +118,13 @@ const useColumnDefinitions = ({ partyId }: Props) => {
|
||||
const taker = t('Taker');
|
||||
const maker = t('Maker');
|
||||
if (data?.buyer.id === partyId) {
|
||||
if (value === Schema.Side.SIDE_BUY) {
|
||||
if (value === Side.SIDE_BUY) {
|
||||
return taker;
|
||||
} else {
|
||||
return maker;
|
||||
}
|
||||
} else if (data?.seller.id === partyId) {
|
||||
if (value === Schema.Side.SIDE_SELL) {
|
||||
if (value === Side.SIDE_SELL) {
|
||||
return taker;
|
||||
} else {
|
||||
return maker;
|
||||
|
||||
@@ -67,26 +67,20 @@ const OrdersManager = () => {
|
||||
<orderCancel.Dialog
|
||||
title={getCancelDialogTitle(orderCancel.cancelledOrder?.status)}
|
||||
intent={getCancelDialogIntent(orderCancel.cancelledOrder?.status)}
|
||||
content={{
|
||||
Complete: (
|
||||
<OrderFeedback
|
||||
transaction={orderCancel.transaction}
|
||||
order={orderCancel.cancelledOrder}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<OrderFeedback
|
||||
transaction={orderCancel.transaction}
|
||||
order={orderCancel.cancelledOrder}
|
||||
/>
|
||||
</orderCancel.Dialog>
|
||||
<orderEdit.Dialog
|
||||
title={getEditDialogTitle(orderEdit.updatedOrder?.status)}
|
||||
content={{
|
||||
Complete: (
|
||||
<OrderFeedback
|
||||
transaction={orderEdit.transaction}
|
||||
order={orderEdit.updatedOrder}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<OrderFeedback
|
||||
transaction={orderEdit.transaction}
|
||||
order={orderEdit.updatedOrder}
|
||||
/>
|
||||
</orderEdit.Dialog>
|
||||
{editOrder && (
|
||||
<OrderEditDialog
|
||||
isOpen={Boolean(editOrder)}
|
||||
@@ -96,7 +90,7 @@ const OrdersManager = () => {
|
||||
order={editOrder}
|
||||
onSubmit={(fields) => {
|
||||
setEditOrder(null);
|
||||
orderEdit.edit({ price: fields.limitPrice });
|
||||
orderEdit.edit({ price: fields.entryPrice });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -12,16 +12,19 @@ import {
|
||||
t,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
OrderFieldsFragment,
|
||||
Orders_party_ordersConnection_edges_node,
|
||||
Order,
|
||||
CancelOrderArgs,
|
||||
} from '@vegaprotocol/orders';
|
||||
import { isOrderActive } from '@vegaprotocol/orders';
|
||||
import {
|
||||
OrderRejectionReasonMapping,
|
||||
OrderStatus,
|
||||
OrderType,
|
||||
OrderStatusMapping,
|
||||
OrderTypeMapping,
|
||||
Schema,
|
||||
Side,
|
||||
OrderTimeInForce,
|
||||
OrderTimeInForceMapping,
|
||||
} from '@vegaprotocol/types';
|
||||
|
||||
@@ -57,15 +60,21 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
cellClass: 'font-mono !flex h-full items-center',
|
||||
width: 80,
|
||||
cellClassRules: {
|
||||
[positiveClassNames]: ({ data }: { data: OrderFieldsFragment }) =>
|
||||
data?.side === Schema.Side.SIDE_BUY,
|
||||
[negativeClassNames]: ({ data }: { data: OrderFieldsFragment }) =>
|
||||
data?.side === Schema.Side.SIDE_SELL,
|
||||
[positiveClassNames]: ({
|
||||
data,
|
||||
}: {
|
||||
data: Orders_party_ordersConnection_edges_node;
|
||||
}) => data?.side === Side.SIDE_BUY,
|
||||
[negativeClassNames]: ({
|
||||
data,
|
||||
}: {
|
||||
data: Orders_party_ordersConnection_edges_node;
|
||||
}) => data?.side === Side.SIDE_SELL,
|
||||
},
|
||||
valueFormatter: ({ value, data }: ValueFormatterParams) => {
|
||||
if (value && data && data.market) {
|
||||
const prefix = data
|
||||
? data.side === Schema.Side.SIDE_BUY
|
||||
? data.side === Side.SIDE_BUY
|
||||
? '+'
|
||||
: '-'
|
||||
: '';
|
||||
@@ -83,8 +92,8 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
}: ValueFormatterParams & {
|
||||
value?: OrderFieldsFragment['type'];
|
||||
}) => OrderTypeMapping[value as Schema.OrderType],
|
||||
value?: Orders_party_ordersConnection_edges_node['type'];
|
||||
}) => OrderTypeMapping[value as OrderType],
|
||||
},
|
||||
{
|
||||
colId: 'status',
|
||||
@@ -97,7 +106,7 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
value?: StatusKey;
|
||||
}) => {
|
||||
if (value && data && data.market) {
|
||||
if (value === Schema.OrderStatus.STATUS_REJECTED) {
|
||||
if (value === OrderStatus.STATUS_REJECTED) {
|
||||
return `${OrderStatusMapping[value as StatusKey]}: ${
|
||||
data.rejectionReason &&
|
||||
OrderRejectionReasonMapping[
|
||||
@@ -121,7 +130,7 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
data,
|
||||
value,
|
||||
}: ValueFormatterParams & {
|
||||
value?: OrderFieldsFragment['remaining'];
|
||||
value?: Orders_party_ordersConnection_edges_node['remaining'];
|
||||
}) => {
|
||||
if (value && data && data.market) {
|
||||
const dps = data.market.positionDecimalPlaces;
|
||||
@@ -147,13 +156,13 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
value,
|
||||
data,
|
||||
}: ValueFormatterParams & {
|
||||
value?: OrderFieldsFragment['price'];
|
||||
value?: Orders_party_ordersConnection_edges_node['price'];
|
||||
}) => {
|
||||
if (
|
||||
value === undefined ||
|
||||
!data ||
|
||||
!data.market ||
|
||||
data.type === Schema.OrderType.TYPE_MARKET
|
||||
data.type === OrderType.TYPE_MARKET
|
||||
) {
|
||||
return '-';
|
||||
}
|
||||
@@ -172,7 +181,7 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
}) => {
|
||||
if (value && data?.market) {
|
||||
if (
|
||||
value === Schema.OrderTimeInForce.TIME_IN_FORCE_GTT &&
|
||||
value === OrderTimeInForce.TIME_IN_FORCE_GTT &&
|
||||
data.expiresAt
|
||||
) {
|
||||
const expiry = getDateTimeFormat().format(
|
||||
@@ -194,7 +203,7 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
}: ValueFormatterParams & {
|
||||
value?: OrderFieldsFragment['createdAt'];
|
||||
value?: Orders_party_ordersConnection_edges_node['createdAt'];
|
||||
}) => {
|
||||
return value ? getDateTimeFormat().format(new Date(value)) : value;
|
||||
},
|
||||
@@ -206,7 +215,7 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
}: ValueFormatterParams & {
|
||||
value?: OrderFieldsFragment['updatedAt'];
|
||||
value?: Orders_party_ordersConnection_edges_node['updatedAt'];
|
||||
}) => {
|
||||
return value ? getDateTimeFormat().format(new Date(value)) : '-';
|
||||
},
|
||||
|
||||
+24
-11
@@ -7,7 +7,10 @@ import {
|
||||
signedNumberCssClassRules,
|
||||
t,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type { Position } from '@vegaprotocol/positions';
|
||||
import type {
|
||||
PositionsTableValueFormatterParams,
|
||||
Position,
|
||||
} from '@vegaprotocol/positions';
|
||||
import { AmountCell } from '@vegaprotocol/positions';
|
||||
import type {
|
||||
CellRendererSelectorResult,
|
||||
@@ -17,7 +20,6 @@ import type {
|
||||
ColDef,
|
||||
} from 'ag-grid-community';
|
||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
|
||||
import { Intent, ProgressBarCell } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
const EmptyCell = () => '';
|
||||
@@ -75,7 +77,9 @@ const useColumnDefinitions = () => {
|
||||
value,
|
||||
data,
|
||||
node,
|
||||
}: VegaValueFormatterParams<Position, 'openVolume'>) => {
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['openVolume'];
|
||||
}) => {
|
||||
let ret;
|
||||
if (value && data) {
|
||||
ret = node?.rowPinned
|
||||
@@ -103,7 +107,9 @@ const useColumnDefinitions = () => {
|
||||
value,
|
||||
data,
|
||||
node,
|
||||
}: VegaValueFormatterParams<Position, 'markPrice'>) => {
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['markPrice'];
|
||||
}) => {
|
||||
if (
|
||||
data &&
|
||||
value &&
|
||||
@@ -180,8 +186,9 @@ const useColumnDefinitions = () => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
node,
|
||||
}: VegaValueFormatterParams<Position, 'currentLeverage'>) =>
|
||||
value === undefined ? '' : formatNumber(value.toString(), 1),
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['currentLeverage'];
|
||||
}) => (value === undefined ? '' : formatNumber(value.toString(), 1)),
|
||||
},
|
||||
{
|
||||
colId: 'marginallocated',
|
||||
@@ -222,8 +229,10 @@ const useColumnDefinitions = () => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
data,
|
||||
}: VegaValueFormatterParams<Position, 'realisedPNL'>) =>
|
||||
value === undefined || data === undefined
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['realisedPNL'];
|
||||
}) =>
|
||||
value === undefined
|
||||
? ''
|
||||
: addDecimalsFormatNumber(value.toString(), data.decimals),
|
||||
cellRenderer: 'PriceFlashCell',
|
||||
@@ -240,8 +249,10 @@ const useColumnDefinitions = () => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
data,
|
||||
}: VegaValueFormatterParams<Position, 'unrealisedPNL'>) =>
|
||||
value === undefined || data === undefined
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['unrealisedPNL'];
|
||||
}) =>
|
||||
value === undefined
|
||||
? ''
|
||||
: addDecimalsFormatNumber(value.toString(), data.decimals),
|
||||
cellRenderer: 'PriceFlashCell',
|
||||
@@ -255,7 +266,9 @@ const useColumnDefinitions = () => {
|
||||
type: 'rightAligned',
|
||||
valueFormatter: ({
|
||||
value,
|
||||
}: VegaValueFormatterParams<Position, 'updatedAt'>) => {
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['updatedAt'];
|
||||
}) => {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { MarketExpires } from './market-expires';
|
||||
import SimpleMarketExpires from './simple-market-expires';
|
||||
|
||||
describe('MarketExpires', () => {
|
||||
describe('SimpleMarketExpires', () => {
|
||||
describe('should properly parse different tags', () => {
|
||||
it('settlement:date', () => {
|
||||
const tags = [
|
||||
@@ -12,7 +12,7 @@ describe('MarketExpires', () => {
|
||||
'settlement:notadate',
|
||||
'settlement:20220525T1200',
|
||||
];
|
||||
render(<MarketExpires tags={tags} />);
|
||||
render(<SimpleMarketExpires tags={tags} />);
|
||||
expect(screen.getByText('May 25')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('MarketExpires', () => {
|
||||
'settlement:20220525T1200',
|
||||
'settlement-date:2022-04-25T1200',
|
||||
];
|
||||
render(<MarketExpires tags={tags} />);
|
||||
render(<SimpleMarketExpires tags={tags} />);
|
||||
expect(screen.getByText('Apr 25')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -32,7 +32,7 @@ describe('MarketExpires', () => {
|
||||
'settlement-date:20220525T1200',
|
||||
'settlement-expiry-date:2022-03-25T12:00:00',
|
||||
];
|
||||
render(<MarketExpires tags={tags} />);
|
||||
render(<SimpleMarketExpires tags={tags} />);
|
||||
expect(screen.getByText('Mar 25')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ describe('MarketExpires', () => {
|
||||
'settlemenz:20220525T1200',
|
||||
'settlemenx-date:20220425T1200',
|
||||
];
|
||||
const { container } = render(<MarketExpires tags={tags} />);
|
||||
const { container } = render(<SimpleMarketExpires tags={tags} />);
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import { format, isValid, parseISO } from 'date-fns';
|
||||
import { EXPIRE_DATE_FORMAT } from '../../constants';
|
||||
|
||||
const SimpleMarketExpires = ({
|
||||
tags,
|
||||
}: {
|
||||
tags?: ReadonlyArray<string> | null;
|
||||
}) => {
|
||||
if (tags) {
|
||||
const dateFound = tags.reduce<Date | null>((agg, tag) => {
|
||||
const parsed = parseISO(
|
||||
(tag.match(/^settlement.*:/) &&
|
||||
tag
|
||||
.split(':')
|
||||
.filter((item, i) => i)
|
||||
.join(':')) as string
|
||||
);
|
||||
if (isValid(parsed)) {
|
||||
agg = parsed;
|
||||
}
|
||||
return agg;
|
||||
}, null);
|
||||
return dateFound ? (
|
||||
<div className="p-2 text-ui-small border border-pink text-pink inline-block">{`${format(
|
||||
dateFound as Date,
|
||||
EXPIRE_DATE_FORMAT
|
||||
)}`}</div>
|
||||
) : null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default SimpleMarketExpires;
|
||||
@@ -4,7 +4,6 @@ import type { AgGridReact } from 'ag-grid-react';
|
||||
import {
|
||||
useScreenDimensions,
|
||||
useDataProvider,
|
||||
useYesterday,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import type { MarketState } from '@vegaprotocol/types';
|
||||
@@ -34,13 +33,13 @@ const SimpleMarketList = () => {
|
||||
const statusesRef = useRef<Record<string, MarketState | ''>>({});
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
|
||||
const yesterday = useYesterday();
|
||||
const variables = useMemo(() => {
|
||||
const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
|
||||
return {
|
||||
since: new Date(yesterday).toISOString(),
|
||||
since: new Date(yesterday * 1000).toISOString(),
|
||||
interval: Interval.INTERVAL_I1H,
|
||||
};
|
||||
}, [yesterday]);
|
||||
}, []);
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider: marketsWithCandlesProvider,
|
||||
variables,
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { InView } from 'react-intersection-observer';
|
||||
import { useDataProvider, useYesterday } from '@vegaprotocol/react-helpers';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import type { Candle } from '@vegaprotocol/market-list';
|
||||
import { marketCandlesProvider } from '@vegaprotocol/market-list';
|
||||
import { Interval } from '@vegaprotocol/types';
|
||||
@@ -68,13 +68,13 @@ const SimpleMarketPercentChangeWrapper = (props: Props) => {
|
||||
};
|
||||
|
||||
const SimpleMarketPercentChange = ({ candles, marketId, setValue }: Props) => {
|
||||
const yesterday = useYesterday();
|
||||
const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
|
||||
const { data } = useDataProvider({
|
||||
dataProvider: marketCandlesProvider,
|
||||
variables: {
|
||||
marketId,
|
||||
interval: Interval.INTERVAL_I1D,
|
||||
since: new Date(yesterday).toISOString(),
|
||||
since: new Date(yesterday * 1000).toISOString(),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import classNames from 'classnames';
|
||||
import SimpleMarketExpires from './simple-market-expires';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { MarketExpires } from '@vegaprotocol/market-info';
|
||||
|
||||
interface Props {
|
||||
market: Market;
|
||||
@@ -19,7 +19,7 @@ const MarketNameRenderer = ({ market, isMobile }: Props) => {
|
||||
{isMobile
|
||||
? market.tradableInstrument.instrument.code
|
||||
: market.tradableInstrument.instrument.name}{' '}
|
||||
<MarketExpires
|
||||
<SimpleMarketExpires
|
||||
tags={market.tradableInstrument.instrument.metadata.tags}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+23
-9
@@ -15,8 +15,8 @@ import {
|
||||
} from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/react-testing';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import SimpleMarketToolbar from './simple-market-toolbar';
|
||||
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
|
||||
import { markets as filterData } from './mocks/market-filters.json';
|
||||
|
||||
const mockedNavigate = jest.fn();
|
||||
@@ -35,23 +35,35 @@ describe('SimpleMarketToolbar', () => {
|
||||
const routes = useRoutes([
|
||||
{
|
||||
path: '/',
|
||||
element: <SimpleMarketToolbar data={filterData as Market[]} />,
|
||||
element: (
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'markets',
|
||||
children: [
|
||||
{
|
||||
path: `:state`,
|
||||
element: <SimpleMarketToolbar data={filterData as Market[]} />,
|
||||
element: (
|
||||
<SimpleMarketToolbar
|
||||
data={filterData as SimpleMarkets_markets[]}
|
||||
/>
|
||||
),
|
||||
children: [
|
||||
{
|
||||
path: `:product`,
|
||||
element: <SimpleMarketToolbar data={filterData as Market[]} />,
|
||||
element: (
|
||||
<SimpleMarketToolbar
|
||||
data={filterData as SimpleMarkets_markets[]}
|
||||
/>
|
||||
),
|
||||
children: [
|
||||
{
|
||||
path: `:asset`,
|
||||
element: (
|
||||
<SimpleMarketToolbar data={filterData as Market[]} />
|
||||
<SimpleMarketToolbar
|
||||
data={filterData as SimpleMarkets_markets[]}
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
@@ -59,7 +71,9 @@ describe('SimpleMarketToolbar', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
element: <SimpleMarketToolbar data={filterData as Market[]} />,
|
||||
element: (
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
),
|
||||
},
|
||||
]);
|
||||
const location = useLocation();
|
||||
@@ -152,7 +166,7 @@ describe('SimpleMarketToolbar', () => {
|
||||
}));
|
||||
render(
|
||||
<MockedProvider mocks={[]} addTypename={false}>
|
||||
<SimpleMarketToolbar data={filterData as Market[]} />
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
@@ -173,7 +187,7 @@ describe('SimpleMarketToolbar', () => {
|
||||
(useParams as jest.Mock).mockImplementation(() => ({}));
|
||||
render(
|
||||
<MockedProvider mocks={[]} addTypename={false}>
|
||||
<SimpleMarketToolbar data={filterData as Market[]} />
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
@@ -197,7 +211,7 @@ describe('SimpleMarketToolbar', () => {
|
||||
}));
|
||||
render(
|
||||
<MockedProvider mocks={[]} addTypename={false}>
|
||||
<SimpleMarketToolbar data={filterData as Market[]} />
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { useNavigate, useParams, Link } from 'react-router-dom';
|
||||
import {
|
||||
@@ -14,11 +14,11 @@ import {
|
||||
Icon,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import useMarketFiltersData from '../../hooks/use-markets-filter';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { HorizontalMenu } from '../horizontal-menu';
|
||||
import type { HorizontalMenuItem } from '../horizontal-menu';
|
||||
import * as constants from './constants';
|
||||
import { useMarketFilters } from '../../hooks/use-markets-filter';
|
||||
|
||||
interface Props {
|
||||
data: Market[];
|
||||
@@ -27,7 +27,7 @@ interface Props {
|
||||
const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
const navigate = useNavigate();
|
||||
const params = useParams();
|
||||
const { products, assetsPerProduct } = useMarketFilters(data);
|
||||
const { products, assetsPerProduct } = useMarketFiltersData(data);
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
|
||||
const onStateChange = useCallback(
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
import LocalContext from '../../context/local-context';
|
||||
|
||||
const ConnectWallet = () => {
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
const {
|
||||
vegaWalletDialog: { setConnect },
|
||||
} = useContext(LocalContext);
|
||||
return (
|
||||
<section
|
||||
className="p-8 bg-white-normal dark:bg-offBlack"
|
||||
@@ -16,7 +17,7 @@ const ConnectWallet = () => {
|
||||
{t('Please connect your Vega wallet to make a trade')}
|
||||
</h3>
|
||||
<div className="mb-4">
|
||||
<Button variant="primary" onClick={openVegaWalletDialog} size="lg">
|
||||
<Button variant="primary" onClick={() => setConnect(true)} size="lg">
|
||||
{t('Connect Vega wallet')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
|
||||
export const DATE_FORMAT = 'dd MMMM yyyy HH:mm';
|
||||
export const EXPIRE_DATE_FORMAT = 'MMM dd';
|
||||
|
||||
export const TRADABLE_STATES = {
|
||||
[MarketState.STATE_ACTIVE]: true,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
export interface VegaWalletDialogState {
|
||||
connect: boolean;
|
||||
manage: boolean;
|
||||
setConnect: (isOpen: boolean) => void;
|
||||
setManage: (isOpen: boolean) => void;
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -26,6 +26,5 @@ query EstimateOrder(
|
||||
marginLevels {
|
||||
initialLevel
|
||||
}
|
||||
totalFeeAmount
|
||||
}
|
||||
}
|
||||
-3
@@ -3,9 +3,6 @@ query MarketMarkPrice($marketId: ID!) {
|
||||
decimalPlaces
|
||||
data {
|
||||
markPrice
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: MarketMarkPrice
|
||||
// ====================================================
|
||||
|
||||
export interface MarketMarkPrice_market_data {
|
||||
__typename: "MarketData";
|
||||
/**
|
||||
* The mark price (an unsigned integer)
|
||||
*/
|
||||
markPrice: string;
|
||||
}
|
||||
|
||||
export interface MarketMarkPrice_market {
|
||||
__typename: "Market";
|
||||
/**
|
||||
* The number of decimal places that an integer must be shifted by in order to get a correct
|
||||
* number denominated in the currency of the market. (uint64)
|
||||
*
|
||||
* Examples:
|
||||
* Currency Balance decimalPlaces Real Balance
|
||||
* GBP 100 0 GBP 100
|
||||
* GBP 100 2 GBP 1.00
|
||||
* GBP 100 4 GBP 0.01
|
||||
* GBP 1 4 GBP 0.0001 ( 0.01p )
|
||||
*
|
||||
* GBX (pence) 100 0 GBP 1.00 (100p )
|
||||
* GBX (pence) 100 2 GBP 0.01 ( 1p )
|
||||
* GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
|
||||
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
|
||||
*/
|
||||
decimalPlaces: number;
|
||||
/**
|
||||
* marketData for the given market
|
||||
*/
|
||||
data: MarketMarkPrice_market_data | null;
|
||||
}
|
||||
|
||||
export interface MarketMarkPrice {
|
||||
/**
|
||||
* An instrument that is trading on the Vega network
|
||||
*/
|
||||
market: MarketMarkPrice_market | null;
|
||||
}
|
||||
|
||||
export interface MarketMarkPriceVariables {
|
||||
marketId: string;
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { AccountType } from "@vegaprotocol/types";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: PartyMarketData
|
||||
// ====================================================
|
||||
|
||||
export interface PartyMarketData_party_accounts_asset {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The ID of the asset
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
|
||||
*/
|
||||
decimals: number;
|
||||
}
|
||||
|
||||
export interface PartyMarketData_party_accounts_market {
|
||||
__typename: "Market";
|
||||
/**
|
||||
* Market ID
|
||||
*/
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface PartyMarketData_party_accounts {
|
||||
__typename: "Account";
|
||||
/**
|
||||
* Account type (General, Margin, etc)
|
||||
*/
|
||||
type: AccountType;
|
||||
/**
|
||||
* Balance as string - current account balance (approx. as balances can be updated several times per second)
|
||||
*/
|
||||
balance: string;
|
||||
/**
|
||||
* Asset, the 'currency'
|
||||
*/
|
||||
asset: PartyMarketData_party_accounts_asset;
|
||||
/**
|
||||
* Market (only relevant to margin accounts)
|
||||
*/
|
||||
market: PartyMarketData_party_accounts_market | null;
|
||||
}
|
||||
|
||||
export interface PartyMarketData_party_marginsConnection_edges_node_market {
|
||||
__typename: "Market";
|
||||
/**
|
||||
* Market ID
|
||||
*/
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface PartyMarketData_party_marginsConnection_edges_node {
|
||||
__typename: "MarginLevels";
|
||||
/**
|
||||
* Market in which the margin is required for this party
|
||||
*/
|
||||
market: PartyMarketData_party_marginsConnection_edges_node_market;
|
||||
/**
|
||||
* This is the minimum margin required for a party to place a new order on the network (unsigned integer)
|
||||
*/
|
||||
initialLevel: string;
|
||||
/**
|
||||
* Minimal margin for the position to be maintained in the network (unsigned integer)
|
||||
*/
|
||||
maintenanceLevel: string;
|
||||
/**
|
||||
* If the margin is between maintenance and search, the network will initiate a collateral search (unsigned integer)
|
||||
*/
|
||||
searchLevel: string;
|
||||
}
|
||||
|
||||
export interface PartyMarketData_party_marginsConnection_edges {
|
||||
__typename: "MarginEdge";
|
||||
node: PartyMarketData_party_marginsConnection_edges_node;
|
||||
}
|
||||
|
||||
export interface PartyMarketData_party_marginsConnection {
|
||||
__typename: "MarginConnection";
|
||||
/**
|
||||
* The margin levels in this connection
|
||||
*/
|
||||
edges: PartyMarketData_party_marginsConnection_edges[] | null;
|
||||
}
|
||||
|
||||
export interface PartyMarketData_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Collateral accounts relating to a party
|
||||
*/
|
||||
accounts: PartyMarketData_party_accounts[] | null;
|
||||
/**
|
||||
* Margin levels for a market
|
||||
*/
|
||||
marginsConnection: PartyMarketData_party_marginsConnection | null;
|
||||
}
|
||||
|
||||
export interface PartyMarketData {
|
||||
/**
|
||||
* An entity that is trading on the Vega network
|
||||
*/
|
||||
party: PartyMarketData_party | null;
|
||||
}
|
||||
|
||||
export interface PartyMarketDataVariables {
|
||||
partyId: string;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { Side, OrderTimeInForce, OrderType } from "@vegaprotocol/types";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: EstimateOrder
|
||||
// ====================================================
|
||||
|
||||
export interface EstimateOrder_estimateOrder_fee {
|
||||
__typename: "TradeFee";
|
||||
/**
|
||||
* The maker fee, paid by the aggressive party to the other party (the one who had an order in the book)
|
||||
*/
|
||||
makerFee: string;
|
||||
/**
|
||||
* The infrastructure fee, a fee paid to the validators to maintain the Vega network
|
||||
*/
|
||||
infrastructureFee: string;
|
||||
/**
|
||||
* The fee paid to the liquidity providers that committed liquidity to the market
|
||||
*/
|
||||
liquidityFee: string;
|
||||
}
|
||||
|
||||
export interface EstimateOrder_estimateOrder_marginLevels {
|
||||
__typename: "MarginLevels";
|
||||
/**
|
||||
* This is the minimum margin required for a party to place a new order on the network (unsigned integer)
|
||||
*/
|
||||
initialLevel: string;
|
||||
}
|
||||
|
||||
export interface EstimateOrder_estimateOrder {
|
||||
__typename: "OrderEstimate";
|
||||
/**
|
||||
* The estimated fee if the order was to trade
|
||||
*/
|
||||
fee: EstimateOrder_estimateOrder_fee;
|
||||
/**
|
||||
* The margin requirement for this order
|
||||
*/
|
||||
marginLevels: EstimateOrder_estimateOrder_marginLevels;
|
||||
}
|
||||
|
||||
export interface EstimateOrder {
|
||||
/**
|
||||
* Return an estimation of the potential cost for a new order
|
||||
*/
|
||||
estimateOrder: EstimateOrder_estimateOrder;
|
||||
}
|
||||
|
||||
export interface EstimateOrderVariables {
|
||||
marketId: string;
|
||||
partyId: string;
|
||||
price?: string | null;
|
||||
size: string;
|
||||
side: Side;
|
||||
timeInForce: OrderTimeInForce;
|
||||
expiration?: string | null;
|
||||
type: OrderType;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { AccountType } from "@vegaprotocol/types";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: MarketPositions
|
||||
// ====================================================
|
||||
|
||||
export interface MarketPositions_party_accounts_asset {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
|
||||
*/
|
||||
decimals: number;
|
||||
}
|
||||
|
||||
export interface MarketPositions_party_accounts_market {
|
||||
__typename: "Market";
|
||||
/**
|
||||
* Market ID
|
||||
*/
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface MarketPositions_party_accounts {
|
||||
__typename: "Account";
|
||||
/**
|
||||
* Account type (General, Margin, etc)
|
||||
*/
|
||||
type: AccountType;
|
||||
/**
|
||||
* Balance as string - current account balance (approx. as balances can be updated several times per second)
|
||||
*/
|
||||
balance: string;
|
||||
/**
|
||||
* Asset, the 'currency'
|
||||
*/
|
||||
asset: MarketPositions_party_accounts_asset;
|
||||
/**
|
||||
* Market (only relevant to margin accounts)
|
||||
*/
|
||||
market: MarketPositions_party_accounts_market | null;
|
||||
}
|
||||
|
||||
export interface MarketPositions_party_positionsConnection_edges_node_market {
|
||||
__typename: "Market";
|
||||
/**
|
||||
* Market ID
|
||||
*/
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface MarketPositions_party_positionsConnection_edges_node {
|
||||
__typename: "Position";
|
||||
/**
|
||||
* Open volume (uint64)
|
||||
*/
|
||||
openVolume: string;
|
||||
/**
|
||||
* Market relating to this position
|
||||
*/
|
||||
market: MarketPositions_party_positionsConnection_edges_node_market;
|
||||
}
|
||||
|
||||
export interface MarketPositions_party_positionsConnection_edges {
|
||||
__typename: "PositionEdge";
|
||||
/**
|
||||
* The position
|
||||
*/
|
||||
node: MarketPositions_party_positionsConnection_edges_node;
|
||||
}
|
||||
|
||||
export interface MarketPositions_party_positionsConnection {
|
||||
__typename: "PositionConnection";
|
||||
/**
|
||||
* The positions in this connection
|
||||
*/
|
||||
edges: MarketPositions_party_positionsConnection_edges[] | null;
|
||||
}
|
||||
|
||||
export interface MarketPositions_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Collateral accounts relating to a party
|
||||
*/
|
||||
accounts: MarketPositions_party_accounts[] | null;
|
||||
/**
|
||||
* Trading positions relating to a party
|
||||
*/
|
||||
positionsConnection: MarketPositions_party_positionsConnection | null;
|
||||
}
|
||||
|
||||
export interface MarketPositions {
|
||||
/**
|
||||
* An entity that is trading on the Vega network
|
||||
*/
|
||||
party: MarketPositions_party | null;
|
||||
}
|
||||
|
||||
export interface MarketPositionsVariables {
|
||||
partyId: string;
|
||||
}
|
||||
+1
-2
@@ -15,7 +15,7 @@ export type EstimateOrderQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type EstimateOrderQuery = { __typename?: 'Query', estimateOrder: { __typename?: 'OrderEstimate', totalFeeAmount: string, fee: { __typename?: 'TradeFee', makerFee: string, infrastructureFee: string, liquidityFee: string }, marginLevels: { __typename?: 'MarginLevels', initialLevel: string } } };
|
||||
export type EstimateOrderQuery = { __typename?: 'Query', estimateOrder: { __typename?: 'OrderEstimate', fee: { __typename?: 'TradeFee', makerFee: string, infrastructureFee: string, liquidityFee: string }, marginLevels: { __typename?: 'MarginLevels', initialLevel: string } } };
|
||||
|
||||
|
||||
export const EstimateOrderDocument = gql`
|
||||
@@ -38,7 +38,6 @@ export const EstimateOrderDocument = gql`
|
||||
marginLevels {
|
||||
initialLevel
|
||||
}
|
||||
totalFeeAmount
|
||||
}
|
||||
}
|
||||
`;
|
||||
+1
-4
@@ -8,7 +8,7 @@ export type MarketMarkPriceQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketMarkPriceQuery = { __typename?: 'Query', market?: { __typename?: 'Market', decimalPlaces: number, data?: { __typename?: 'MarketData', markPrice: string, market: { __typename?: 'Market', id: string } } | null } | null };
|
||||
export type MarketMarkPriceQuery = { __typename?: 'Query', market?: { __typename?: 'Market', decimalPlaces: number, data?: { __typename?: 'MarketData', markPrice: string } | null } | null };
|
||||
|
||||
|
||||
export const MarketMarkPriceDocument = gql`
|
||||
@@ -17,9 +17,6 @@ export const MarketMarkPriceDocument = gql`
|
||||
decimalPlaces
|
||||
data {
|
||||
markPrice
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ export type MarketPositionsQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type MarketPositionsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accounts?: Array<{ __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', decimals: number }, market?: { __typename?: 'Market', id: string } | null }> | null, positionsConnection?: { __typename?: 'PositionConnection', edges?: Array<{ __typename?: 'PositionEdge', node: { __typename?: 'Position', openVolume: string, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
|
||||
export type MarketPositionsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accounts?: Array<{ __typename?: 'Account', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', decimals: number }, market?: { __typename?: 'Market', id: string } | 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`
|
||||
+1
-1
@@ -8,7 +8,7 @@ export type PartyMarketDataQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type PartyMarketDataQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accounts?: Array<{ __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, decimals: number }, market?: { __typename?: 'Market', id: string } | 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 type PartyMarketDataQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accounts?: Array<{ __typename?: 'Account', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, decimals: number }, market?: { __typename?: 'Market', id: string } | 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`
|
||||
+10
-6
@@ -1,8 +1,8 @@
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
||||
import useCalculateSlippage from './use-calculate-slippage';
|
||||
|
||||
const mockData = {
|
||||
decimalPlaces: 0,
|
||||
@@ -59,6 +59,11 @@ let mockOrderBookData = {
|
||||
data: mockData,
|
||||
};
|
||||
|
||||
jest.mock('@vegaprotocol/market-depth', () => ({
|
||||
...jest.requireActual('@vegaprotocol/market-depth'),
|
||||
useOrderBookData: jest.fn(() => mockOrderBookData),
|
||||
}));
|
||||
|
||||
jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
...jest.requireActual('@vegaprotocol/react-helpers'),
|
||||
useDataProvider: jest.fn(() => ({
|
||||
@@ -66,7 +71,6 @@ jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
marketsConnection: [],
|
||||
},
|
||||
})),
|
||||
useThrottledDataProvider: jest.fn(() => mockOrderBookData),
|
||||
}));
|
||||
|
||||
describe('useCalculateSlippage Hook', () => {
|
||||
@@ -82,7 +86,7 @@ describe('useCalculateSlippage Hook', () => {
|
||||
marketId: 'marketId',
|
||||
order: {
|
||||
size: '10',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
side: Side.SIDE_BUY,
|
||||
} as OrderSubmissionBody['orderSubmission'],
|
||||
}),
|
||||
{
|
||||
@@ -99,7 +103,7 @@ describe('useCalculateSlippage Hook', () => {
|
||||
marketId: 'marketId',
|
||||
order: {
|
||||
size: '10',
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
side: Side.SIDE_SELL,
|
||||
} as OrderSubmissionBody['orderSubmission'],
|
||||
}),
|
||||
{
|
||||
@@ -125,7 +129,7 @@ describe('useCalculateSlippage Hook', () => {
|
||||
marketId: 'marketId',
|
||||
order: {
|
||||
size: '10',
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
side: Side.SIDE_SELL,
|
||||
} as OrderSubmissionBody['orderSubmission'],
|
||||
}),
|
||||
{
|
||||
+12
-14
@@ -1,15 +1,14 @@
|
||||
import { useMemo } from 'react';
|
||||
import { marketDepthProvider } from '@vegaprotocol/market-depth';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
import { useOrderBookData } from '@vegaprotocol/market-depth';
|
||||
import { marketProvider } from '@vegaprotocol/market-list';
|
||||
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import {
|
||||
formatNumber,
|
||||
toBigNum,
|
||||
useDataProvider,
|
||||
useThrottledDataProvider,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface Props {
|
||||
@@ -17,22 +16,19 @@ interface Props {
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
}
|
||||
|
||||
export const useCalculateSlippage = ({ marketId, order }: Props) => {
|
||||
const useCalculateSlippage = ({ marketId, order }: Props) => {
|
||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||
const { data } = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketDepthProvider,
|
||||
variables,
|
||||
},
|
||||
5000
|
||||
);
|
||||
const { data: market } = useDataProvider<SingleMarketFieldsFragment, never>({
|
||||
const { data } = useOrderBookData({
|
||||
variables,
|
||||
throttleMilliseconds: 5000,
|
||||
});
|
||||
const { data: market } = useDataProvider<Market, never>({
|
||||
dataProvider: marketProvider,
|
||||
noUpdate: true,
|
||||
variables,
|
||||
});
|
||||
const volPriceArr =
|
||||
data?.depth[order.side === Schema.Side.SIDE_BUY ? 'sell' : 'buy'] || [];
|
||||
data?.depth[order.side === Side.SIDE_BUY ? 'sell' : 'buy'] || [];
|
||||
if (volPriceArr.length && market) {
|
||||
const decimals = market.decimalPlaces ?? 0;
|
||||
const positionDecimals = market.positionDecimalPlaces ?? 0;
|
||||
@@ -73,3 +69,5 @@ export const useCalculateSlippage = ({ marketId, order }: Props) => {
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default useCalculateSlippage;
|
||||
@@ -7,9 +7,12 @@ describe('local values hook', () => {
|
||||
const { result } = renderHook(() => useLocalValues('light', setTheme));
|
||||
expect(result.current.vegaWalletDialog).toBeDefined();
|
||||
expect(result.current.vegaWalletDialog.manage).toBe(false);
|
||||
expect(result.current.vegaWalletDialog.connect).toBe(false);
|
||||
act(() => {
|
||||
result.current.vegaWalletDialog.setConnect(true);
|
||||
result.current.vegaWalletDialog.setManage(true);
|
||||
});
|
||||
expect(result.current.vegaWalletDialog.manage).toBe(true);
|
||||
expect(result.current.vegaWalletDialog.connect).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,16 +2,17 @@ import { useMemo, useState } from 'react';
|
||||
import type { LocalValues } from '../context/local-context';
|
||||
|
||||
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
||||
const [connect, setConnect] = useState<boolean>(false);
|
||||
const [manage, setManage] = useState<boolean>(false);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
return useMemo<LocalValues>(
|
||||
() => ({
|
||||
vegaWalletDialog: { manage, setManage },
|
||||
vegaWalletDialog: { connect, manage, setConnect, setManage },
|
||||
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
|
||||
theme,
|
||||
toggleTheme,
|
||||
}),
|
||||
[manage, theme, toggleTheme, menuOpen]
|
||||
[connect, manage, theme, toggleTheme, menuOpen]
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { useMemo, useRef } from 'react';
|
||||
import type {
|
||||
MarketMarkPrice,
|
||||
MarketMarkPriceVariables,
|
||||
} from './__generated__/MarketMarkPrice';
|
||||
|
||||
const MARKET_MARK_PRICE = gql`
|
||||
query MarketMarkPrice($marketId: ID!) {
|
||||
market(id: $marketId) {
|
||||
decimalPlaces
|
||||
data {
|
||||
markPrice
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default (marketId: string) => {
|
||||
const memoRef = useRef<MarketMarkPrice | null>(null);
|
||||
const { data } = useQuery<MarketMarkPrice, MarketMarkPriceVariables>(
|
||||
MARKET_MARK_PRICE,
|
||||
{
|
||||
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
-1
@@ -1,5 +1,5 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import useMarketPositions from './use-market-positions';
|
||||
|
||||
let mockNotEmptyData = {
|
||||
party: {
|
||||
@@ -0,0 +1,78 @@
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type {
|
||||
MarketPositions,
|
||||
MarketPositionsVariables,
|
||||
} from './__generated__/marketPositions';
|
||||
|
||||
const MARKET_POSITIONS_QUERY = gql`
|
||||
query MarketPositions($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
id
|
||||
accounts {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
decimals
|
||||
}
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
positionsConnection {
|
||||
edges {
|
||||
node {
|
||||
openVolume
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
marketId: string;
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
export type PositionMargin = {
|
||||
openVolume: BigNumber;
|
||||
balance: BigNumber;
|
||||
balanceDecimals?: number;
|
||||
} | null;
|
||||
|
||||
export default ({ marketId, partyId }: Props): PositionMargin => {
|
||||
const { data } = useQuery<MarketPositions, MarketPositionsVariables>(
|
||||
MARKET_POSITIONS_QUERY,
|
||||
{
|
||||
pollInterval: 5000,
|
||||
variables: { partyId },
|
||||
skip: !partyId,
|
||||
fetchPolicy: 'no-cache',
|
||||
}
|
||||
);
|
||||
|
||||
const account = data?.party?.accounts?.find(
|
||||
(nodes) => nodes.market?.id === marketId
|
||||
);
|
||||
|
||||
if (account) {
|
||||
const balance = new BigNumber(account.balance || 0);
|
||||
const openVolume = new BigNumber(
|
||||
data?.party?.positionsConnection?.edges?.find(
|
||||
(nodes) => nodes.node.market.id === marketId
|
||||
)?.node.openVolume || 0
|
||||
);
|
||||
if (!balance.isZero() && !openVolume.isZero()) {
|
||||
return {
|
||||
balance,
|
||||
balanceDecimals: account?.asset.decimals,
|
||||
openVolume,
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export const useMarketFilters = (data: Market[]) => {
|
||||
const useMarketFilters = (data: Market[]) => {
|
||||
const [products, setProducts] = useState<string[]>([]);
|
||||
const [assetsPerProduct, setAssetsPerProduct] = useState<
|
||||
Record<string, string[]>
|
||||
@@ -36,3 +36,5 @@ export const useMarketFilters = (data: Market[]) => {
|
||||
}, [data]);
|
||||
return { products, assetsPerProduct };
|
||||
};
|
||||
|
||||
export default useMarketFilters;
|
||||
|
||||
+17
-23
@@ -1,10 +1,14 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { AccountType, Schema } from '@vegaprotocol/types';
|
||||
import useMaximumPositionSize from './use-maximum-position-size';
|
||||
import type { PartyBalanceQuery_party_accounts } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
import {
|
||||
AccountType,
|
||||
OrderTimeInForce,
|
||||
OrderType,
|
||||
Side,
|
||||
} 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';
|
||||
|
||||
const defaultMockMarketPositions = {
|
||||
openVolume: new BigNumber(1),
|
||||
@@ -13,8 +17,8 @@ const defaultMockMarketPositions = {
|
||||
|
||||
let mockMarketPositions: PositionMargin | null = defaultMockMarketPositions;
|
||||
|
||||
const mockAccount: Account = {
|
||||
__typename: 'AccountBalance',
|
||||
const mockAccount: PartyBalanceQuery_party_accounts = {
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '200000',
|
||||
asset: {
|
||||
@@ -26,12 +30,11 @@ const mockAccount: Account = {
|
||||
},
|
||||
};
|
||||
|
||||
const mockOrder: OrderSubmissionBody['orderSubmission'] = {
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
const mockOrder = {
|
||||
type: OrderType.TYPE_MARKET,
|
||||
size: '1',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_IOC,
|
||||
marketId: 'market-id',
|
||||
side: Side.SIDE_BUY,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_IOC,
|
||||
};
|
||||
|
||||
jest.mock('./use-settlement-account', () => {
|
||||
@@ -39,18 +42,9 @@ jest.mock('./use-settlement-account', () => {
|
||||
useSettlementAccount: jest.fn(() => mockAccount),
|
||||
};
|
||||
});
|
||||
jest.mock('./use-market-positions', () => jest.fn(() => mockMarketPositions));
|
||||
|
||||
jest.mock('./use-market-positions', () => ({
|
||||
useMarketPositions: ({
|
||||
marketId,
|
||||
partyId,
|
||||
}: {
|
||||
marketId: string;
|
||||
partyId: string;
|
||||
}) => mockMarketPositions,
|
||||
}));
|
||||
|
||||
describe('useMaximumPositionSize', () => {
|
||||
describe('useMaximumPositionSize Hook', () => {
|
||||
it('should return correct size when no open positions', () => {
|
||||
mockMarketPositions = null;
|
||||
const price = '50';
|
||||
@@ -87,7 +81,7 @@ describe('useMaximumPositionSize', () => {
|
||||
|
||||
it('should return correct size when open positions and opposite side', () => {
|
||||
const price = '50';
|
||||
mockOrder.side = Schema.Side.SIDE_SELL;
|
||||
mockOrder.side = Side.SIDE_SELL;
|
||||
mockMarketPositions = defaultMockMarketPositions;
|
||||
const expected = 4001;
|
||||
const { result } = renderHook(() =>
|
||||
+7
-9
@@ -1,13 +1,13 @@
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import useMarketPositions from './use-market-positions';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import type { PartyBalanceQuery_party_accounts } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import { AccountType, Schema } from '@vegaprotocol/types';
|
||||
import { AccountType, Side } from '@vegaprotocol/types';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
accounts: Account[];
|
||||
accounts: PartyBalanceQuery_party_accounts[];
|
||||
marketId: string;
|
||||
price?: string;
|
||||
settlementAssetId: string;
|
||||
@@ -17,7 +17,7 @@ interface Props {
|
||||
const getSize = (balance: string, price: string) =>
|
||||
new BigNumber(balance).dividedBy(new BigNumber(price));
|
||||
|
||||
export const useMaximumPositionSize = ({
|
||||
export default ({
|
||||
marketId,
|
||||
accounts,
|
||||
partyId,
|
||||
@@ -47,10 +47,8 @@ export const useMaximumPositionSize = ({
|
||||
}
|
||||
|
||||
const isSameSide =
|
||||
(marketPositions.openVolume.isPositive() &&
|
||||
order.side === Schema.Side.SIDE_BUY) ||
|
||||
(marketPositions.openVolume.isNegative() &&
|
||||
order.side === Schema.Side.SIDE_SELL);
|
||||
(marketPositions.openVolume.isPositive() && order.side === Side.SIDE_BUY) ||
|
||||
(marketPositions.openVolume.isNegative() && order.side === Side.SIDE_SELL);
|
||||
|
||||
const adjustedForVolume = new BigNumber(size)[isSameSide ? 'minus' : 'plus'](
|
||||
marketPositions.openVolume
|
||||
+8
-8
@@ -1,17 +1,17 @@
|
||||
import * as React from 'react';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import useOrderCloseOut from './use-order-closeout';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import type { PartyBalanceQuery } from './__generated__/PartyBalance';
|
||||
import { useOrderCloseOut } from './use-order-closeout';
|
||||
import type { DealTicketMarketFragment } from '../components/deal-ticket/__generated___/DealTicket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartyBalanceQuery } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
...jest.requireActual('@vegaprotocol/wallet'),
|
||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
||||
}));
|
||||
|
||||
describe('useOrderCloseOut', () => {
|
||||
describe('useOrderCloseOut Hook', () => {
|
||||
const order = { size: '2', side: 'SIDE_BUY' };
|
||||
const market = {
|
||||
decimalPlaces: 5,
|
||||
@@ -44,7 +44,7 @@ describe('useOrderCloseOut', () => {
|
||||
},
|
||||
};
|
||||
|
||||
it('should return proper null value', () => {
|
||||
it('return proper buy value', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
@@ -58,10 +58,10 @@ describe('useOrderCloseOut', () => {
|
||||
),
|
||||
}
|
||||
);
|
||||
expect(result.current).toEqual(null);
|
||||
expect(result.current).toEqual(' - ');
|
||||
});
|
||||
|
||||
it('should return proper sell value', () => {
|
||||
it('return proper sell value', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
@@ -81,7 +81,7 @@ describe('useOrderCloseOut', () => {
|
||||
expect(result.current).toEqual('1.00000');
|
||||
});
|
||||
|
||||
it('should return proper empty value', () => {
|
||||
it('return proper empty value', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
+57
-21
@@ -1,14 +1,49 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartyBalanceQuery } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { addDecimal, formatNumber } from '@vegaprotocol/react-helpers';
|
||||
import { useMarketPositions } from './use-market-positions';
|
||||
import { useMarketDataMarkPrice } from './use-market-data-mark-price';
|
||||
import { usePartyMarketDataQuery } from './__generated__/PartyMarketData';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type { DealTicketMarketFragment } from '../components/deal-ticket/__generated___/DealTicket';
|
||||
import type { PartyBalanceQuery } from './__generated__/PartyBalance';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import useMarketPositions from './use-market-positions';
|
||||
import useMarketData from './use-market-data';
|
||||
import type {
|
||||
PartyMarketData,
|
||||
PartyMarketDataVariables,
|
||||
} from './__generated__/PartyMarketData';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
|
||||
const CLOSEOUT_PRICE_QUERY = gql`
|
||||
query PartyMarketData($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
id
|
||||
accounts {
|
||||
type
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
decimals
|
||||
}
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
marginsConnection {
|
||||
edges {
|
||||
node {
|
||||
market {
|
||||
id
|
||||
}
|
||||
initialLevel
|
||||
maintenanceLevel
|
||||
searchLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
@@ -16,23 +51,22 @@ interface Props {
|
||||
partyData?: PartyBalanceQuery;
|
||||
}
|
||||
|
||||
export const useOrderCloseOut = ({
|
||||
order,
|
||||
market,
|
||||
partyData,
|
||||
}: Props): string | null => {
|
||||
const useOrderCloseOut = ({ order, market, partyData }: Props): string => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const account = useSettlementAccount(
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
||||
partyData?.party?.accounts || []
|
||||
);
|
||||
const { data } = usePartyMarketDataQuery({
|
||||
pollInterval: 5000,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
const { data } = useQuery<PartyMarketData, PartyMarketDataVariables>(
|
||||
CLOSEOUT_PRICE_QUERY,
|
||||
{
|
||||
pollInterval: 5000,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
}
|
||||
);
|
||||
|
||||
const markPriceData = useMarketDataMarkPrice(market.id);
|
||||
const markPriceData = useMarketData(market.id);
|
||||
const marketPositions = useMarketPositions({
|
||||
marketId: market.id,
|
||||
partyId: pubKey || '',
|
||||
@@ -60,10 +94,10 @@ export const useOrderCloseOut = ({
|
||||
);
|
||||
const volume = new BigNumber(
|
||||
addDecimal(
|
||||
marketPositions?.openVolume.toString() || '0',
|
||||
marketPositions?.openVolume.toNumber() || 0,
|
||||
market.positionDecimalPlaces
|
||||
)
|
||||
)[order.side === Schema.Side.SIDE_BUY ? 'plus' : 'minus'](order.size);
|
||||
)[order.side === Side.SIDE_BUY ? 'plus' : 'minus'](order.size);
|
||||
const markPrice = new BigNumber(
|
||||
addDecimal(
|
||||
markPriceData?.market?.data?.markPrice || 0,
|
||||
@@ -78,5 +112,7 @@ export const useOrderCloseOut = ({
|
||||
if (closeOut.isPositive()) {
|
||||
return formatNumber(closeOut, market.decimalPlaces);
|
||||
}
|
||||
return null;
|
||||
return ' - ';
|
||||
};
|
||||
|
||||
export default useOrderCloseOut;
|
||||
+9
-18
@@ -2,9 +2,9 @@ import { renderHook } from '@testing-library/react';
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PositionMargin } from './use-market-positions';
|
||||
import { useOrderMargin } from './use-order-margin';
|
||||
import type { DealTicketMarketFragment } from '../components/deal-ticket/__generated___/DealTicket';
|
||||
import useOrderMargin from './use-order-margin';
|
||||
|
||||
let mockEstimateData = {
|
||||
estimateOrder: {
|
||||
@@ -27,18 +27,9 @@ let mockMarketPositions: PositionMargin = {
|
||||
openVolume: new BigNumber(1),
|
||||
balance: new BigNumber(100000),
|
||||
};
|
||||
jest.mock('./use-market-positions', () => jest.fn(() => mockMarketPositions));
|
||||
|
||||
jest.mock('./use-market-positions', () => ({
|
||||
useMarketPositions: ({
|
||||
marketId,
|
||||
partyId,
|
||||
}: {
|
||||
marketId: string;
|
||||
partyId: string;
|
||||
}) => mockMarketPositions,
|
||||
}));
|
||||
|
||||
describe('useOrderMargin', () => {
|
||||
describe('useOrderMargin Hook', () => {
|
||||
const order = {
|
||||
size: '2',
|
||||
side: 'SIDE_BUY',
|
||||
@@ -59,7 +50,7 @@ describe('useOrderMargin', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should calculate margin correctly', () => {
|
||||
it('margin should be properly calculated', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useOrderMargin({
|
||||
order: order as OrderSubmissionBody['orderSubmission'],
|
||||
@@ -77,7 +68,7 @@ describe('useOrderMargin', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should calculate fees correctly', () => {
|
||||
it('fees should be properly calculated', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useOrderMargin({
|
||||
order: order as OrderSubmissionBody['orderSubmission'],
|
||||
@@ -85,10 +76,10 @@ describe('useOrderMargin', () => {
|
||||
partyId,
|
||||
})
|
||||
);
|
||||
expect(result.current?.totalFees).toEqual('300000');
|
||||
expect(result.current?.fees).toEqual('300000');
|
||||
});
|
||||
|
||||
it('should not subtract initialMargin if there is no position', () => {
|
||||
it('if there is no positions initialMargin should not be subtracted', () => {
|
||||
mockMarketPositions = null;
|
||||
const { result } = renderHook(() =>
|
||||
useOrderMargin({
|
||||
@@ -104,7 +95,7 @@ describe('useOrderMargin', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should return empty value if API fails', () => {
|
||||
it('if api fails, should return empty value', () => {
|
||||
mockEstimateData = {
|
||||
estimateOrder: {
|
||||
fee: {
|
||||
@@ -0,0 +1,119 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import type {
|
||||
EstimateOrder,
|
||||
EstimateOrderVariables,
|
||||
EstimateOrder_estimateOrder_fee,
|
||||
} from './__generated__/estimateOrder';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
import { addDecimal, removeDecimal } from '@vegaprotocol/react-helpers';
|
||||
import useMarketPositions from './use-market-positions';
|
||||
import useMarketData from './use-market-data';
|
||||
|
||||
export const ESTIMATE_ORDER_QUERY = gql`
|
||||
query EstimateOrder(
|
||||
$marketId: ID!
|
||||
$partyId: ID!
|
||||
$price: String
|
||||
$size: String!
|
||||
$side: Side!
|
||||
$timeInForce: OrderTimeInForce!
|
||||
$expiration: String
|
||||
$type: OrderType!
|
||||
) {
|
||||
estimateOrder(
|
||||
marketId: $marketId
|
||||
partyId: $partyId
|
||||
price: $price
|
||||
size: $size
|
||||
side: $side
|
||||
timeInForce: $timeInForce
|
||||
expiration: $expiration
|
||||
type: $type
|
||||
) {
|
||||
fee {
|
||||
makerFee
|
||||
infrastructureFee
|
||||
liquidityFee
|
||||
}
|
||||
marginLevels {
|
||||
initialLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
market: DealTicketMarketFragment;
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
const addFees = (feeObj: EstimateOrder_estimateOrder_fee) => {
|
||||
return new BigNumber(feeObj.makerFee)
|
||||
.plus(feeObj.liquidityFee)
|
||||
.plus(feeObj.infrastructureFee);
|
||||
};
|
||||
|
||||
export interface OrderMargin {
|
||||
margin: string;
|
||||
fees: string | null;
|
||||
}
|
||||
|
||||
const useOrderMargin = ({
|
||||
order,
|
||||
market,
|
||||
partyId,
|
||||
}: Props): OrderMargin | null => {
|
||||
const marketPositions = useMarketPositions({ marketId: market.id, partyId });
|
||||
const markPriceData = useMarketData(market.id);
|
||||
const { data } = useQuery<EstimateOrder, EstimateOrderVariables>(
|
||||
ESTIMATE_ORDER_QUERY,
|
||||
{
|
||||
variables: {
|
||||
marketId: market.id,
|
||||
partyId,
|
||||
price: markPriceData?.market?.data?.markPrice || '',
|
||||
size: removeDecimal(
|
||||
BigNumber.maximum(
|
||||
0,
|
||||
new BigNumber(marketPositions?.openVolume || 0)[
|
||||
order.side === Side.SIDE_BUY ? 'plus' : 'minus'
|
||||
](order.size)
|
||||
).toString(),
|
||||
market.positionDecimalPlaces
|
||||
),
|
||||
side: order.side === Side.SIDE_BUY ? Side.SIDE_BUY : Side.SIDE_SELL,
|
||||
timeInForce: order.timeInForce,
|
||||
type: order.type,
|
||||
},
|
||||
skip:
|
||||
!partyId ||
|
||||
!market.id ||
|
||||
!order.size ||
|
||||
!markPriceData?.market?.data?.markPrice,
|
||||
}
|
||||
);
|
||||
|
||||
if (data?.estimateOrder.marginLevels.initialLevel) {
|
||||
const fees =
|
||||
data?.estimateOrder?.fee && addFees(data.estimateOrder.fee).toString();
|
||||
return {
|
||||
margin: addDecimal(
|
||||
BigNumber.maximum(
|
||||
0,
|
||||
new BigNumber(data.estimateOrder.marginLevels.initialLevel).minus(
|
||||
marketPositions?.balance || 0
|
||||
)
|
||||
).toString(),
|
||||
market.decimalPlaces
|
||||
),
|
||||
fees: addDecimal(fees, market.decimalPlaces),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default useOrderMargin;
|
||||
+8
-8
@@ -1,13 +1,13 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import type { PartyBalanceQuery_party_accounts } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
||||
|
||||
describe('useSettlementAccount Hook', () => {
|
||||
it('should filter accounts by settlementAssetId', () => {
|
||||
const accounts: Account[] = [
|
||||
const accounts: PartyBalanceQuery_party_accounts[] = [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '2000000000000000000000',
|
||||
asset: {
|
||||
@@ -19,7 +19,7 @@ describe('useSettlementAccount Hook', () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '1000000000',
|
||||
asset: {
|
||||
@@ -31,7 +31,7 @@ describe('useSettlementAccount Hook', () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
balance: '5000000000000000000',
|
||||
asset: {
|
||||
@@ -43,7 +43,7 @@ describe('useSettlementAccount Hook', () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
__typename: 'Account',
|
||||
type: AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
balance: '5000000000000000000',
|
||||
asset: {
|
||||
@@ -75,12 +75,12 @@ describe('useSettlementAccount Hook', () => {
|
||||
});
|
||||
|
||||
it('should return null if no accounts', () => {
|
||||
const accounts: Account[] = [];
|
||||
const accounts: PartyBalanceQuery_party_accounts[] = [];
|
||||
const settlementAssetId =
|
||||
'6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61';
|
||||
const { result } = renderHook(() =>
|
||||
useSettlementAccount(settlementAssetId, accounts)
|
||||
);
|
||||
expect(result.current).toBe(null);
|
||||
expect(result.current).toBe(undefined);
|
||||
});
|
||||
});
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
import type { PartyBalanceQuery_party_accounts } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
import type { AccountType } from '@vegaprotocol/types';
|
||||
import { useMemo } from 'react';
|
||||
import type { AccountFragment as Account } from './__generated__/PartyBalance';
|
||||
|
||||
export const useSettlementAccount = (
|
||||
settlementAssetId: string,
|
||||
accounts: Account[],
|
||||
accounts: PartyBalanceQuery_party_accounts[],
|
||||
type?: AccountType
|
||||
): Account | null => {
|
||||
): PartyBalanceQuery_party_accounts | null => {
|
||||
const callback = () =>
|
||||
accounts.find((account) => {
|
||||
if (type) {
|
||||
@@ -16,5 +16,5 @@ export const useSettlementAccount = (
|
||||
return account.asset.id === settlementAssetId;
|
||||
});
|
||||
const account = useMemo(callback, [accounts, settlementAssetId, type]);
|
||||
return account || null;
|
||||
return account as PartyBalanceQuery_party_accounts;
|
||||
};
|
||||
@@ -3,9 +3,11 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node", "@testing-library/jest-dom"]
|
||||
"types": ["jest", "node", "@testing-library/jest-dom"],
|
||||
"jsx": "react",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"files": ["../../node_modules/@nrwl/react/typings/cssmodule.d.ts"],
|
||||
"include": [
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
|
||||
@@ -10,7 +10,7 @@ module.exports = defineConfig({
|
||||
},
|
||||
baseUrl: 'http://localhost:3000',
|
||||
fileServerFolder: '.',
|
||||
fixturesFolder: './src/fixtures',
|
||||
fixturesFolder: false,
|
||||
specPattern: '**/*.cy.{js,jsx,ts,tsx}',
|
||||
modifyObstructiveCode: false,
|
||||
supportFile: './src/support/index.js',
|
||||
@@ -27,6 +27,7 @@ module.exports = defineConfig({
|
||||
networkQueryUrl: 'http://localhost:3028/query',
|
||||
ethUrl: 'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
|
||||
commitHash: 'dev',
|
||||
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: true,
|
||||
tsConfig: 'tsconfig.json',
|
||||
grepTags: '@regression @smoke @slow',
|
||||
grepFilterSpecs: true,
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
{
|
||||
"eighteenDecimal": [
|
||||
"governance.proposal.asset.minProposerBalance",
|
||||
"governance.proposal.asset.minVoterBalance",
|
||||
"governance.proposal.freeform.minProposerBalance",
|
||||
"governance.proposal.freeform.minVoterBalance",
|
||||
"governance.proposal.market.minProposerBalance",
|
||||
"governance.proposal.market.minVoterBalance",
|
||||
"governance.proposal.updateMarket.minProposerBalance",
|
||||
"governance.proposal.updateMarket.minVoterBalance",
|
||||
"governance.proposal.updateNetParam.minProposerBalance",
|
||||
"governance.proposal.updateNetParam.minVoterBalance",
|
||||
"reward.staking.delegation.maxPayoutPerEpoch",
|
||||
"reward.staking.delegation.maxPayoutPerParticipant",
|
||||
"reward.staking.delegation.minimumValidatorStake",
|
||||
"spam.protection.delegation.min.tokens",
|
||||
"spam.protection.proposal.min.tokens",
|
||||
"spam.protection.voting.min.tokens",
|
||||
"validators.delegation.minAmount"
|
||||
],
|
||||
"fiveDecimal": [
|
||||
"governance.proposal.updateAsset.minProposerBalance",
|
||||
"governance.proposal.updateAsset.minVoterBalance",
|
||||
"governance.proposal.updateAsset.requiredParticipation",
|
||||
"governance.proposal.updateMarket.minProposerEquityLikeShare",
|
||||
"market.fee.factors.infrastructureFee",
|
||||
"market.fee.factors.makerFee",
|
||||
"market.liquidity.bondPenaltyParameter",
|
||||
"market.liquidity.maximumLiquidityFeeFactorLevel",
|
||||
"market.liquidity.minimum.probabilityOfTrading.lpOrders",
|
||||
"market.liquidity.probabilityOfTrading.tau.scaling",
|
||||
"market.liquidity.stakeToCcySiskas",
|
||||
"market.liquidity.targetstake.triggering.ratio",
|
||||
"market.liquidityProvision.minLpStakeQuantumMultiple",
|
||||
"market.liquidityProvision.shapes.maxSize",
|
||||
"market.stake.target.scalingFactor",
|
||||
"network.validators.ersatz.multipleOfTendermintValidators",
|
||||
"network.validators.ersatz.rewardFactor",
|
||||
"network.validators.incumbentBonus",
|
||||
"network.validators.minimumEthereumEventsForNewValidator",
|
||||
"network.validators.multisig.numberOfSigners",
|
||||
"network.validators.tendermint.number",
|
||||
"reward.staking.delegation.competitionLevel",
|
||||
"reward.staking.delegation.delegatorShare",
|
||||
"reward.staking.delegation.minValidators",
|
||||
"reward.staking.delegation.optimalStakeMultiplier",
|
||||
"reward.staking.delegation.payoutFraction",
|
||||
"rewards.marketCreationQuantumMultiple",
|
||||
"spam.pow.difficulty",
|
||||
"spam.pow.increaseDifficulty",
|
||||
"spam.pow.numberOfPastBlocks",
|
||||
"spam.pow.numberOfTxPerBlock",
|
||||
"spam.protection.max.batchSize",
|
||||
"spam.protection.max.delegations",
|
||||
"spam.protection.max.proposals",
|
||||
"spam.protection.max.votes",
|
||||
"spam.protection.maxUserTransfersPerEpoch",
|
||||
"transfer.fee.factor",
|
||||
"transfer.minTransferQuantumMultiple",
|
||||
"snapshot.interval.length"
|
||||
],
|
||||
"json": [
|
||||
"blockchains.ethereumConfig",
|
||||
"market.margin.scalingFactors",
|
||||
"market.monitor.price.defaultParameters"
|
||||
],
|
||||
"percentage": [
|
||||
"governance.proposal.asset.requiredMajority",
|
||||
"governance.proposal.asset.requiredParticipation",
|
||||
"governance.proposal.freeform.requiredMajority",
|
||||
"governance.proposal.freeform.requiredParticipation",
|
||||
"governance.proposal.market.requiredMajority",
|
||||
"governance.proposal.market.requiredParticipation",
|
||||
"governance.proposal.updateMarket.requiredMajority",
|
||||
"governance.proposal.updateMarket.requiredMajorityLP",
|
||||
"governance.proposal.updateMarket.requiredParticipation",
|
||||
"governance.proposal.updateMarket.requiredParticipationLP",
|
||||
"governance.proposal.updateNetParam.requiredMajority",
|
||||
"governance.proposal.updateNetParam.requiredParticipation",
|
||||
"validators.vote.required"
|
||||
],
|
||||
"duration": [
|
||||
"governance.proposal.asset.maxClose",
|
||||
"governance.proposal.asset.maxEnact",
|
||||
"governance.proposal.asset.minClose",
|
||||
"governance.proposal.asset.minEnact",
|
||||
"governance.proposal.freeform.maxClose",
|
||||
"governance.proposal.freeform.minClose",
|
||||
"governance.proposal.market.maxClose",
|
||||
"governance.proposal.market.maxEnact",
|
||||
"governance.proposal.market.minClose",
|
||||
"governance.proposal.market.minEnact",
|
||||
"governance.proposal.updateAsset.maxClose",
|
||||
"governance.proposal.updateAsset.maxEnact",
|
||||
"governance.proposal.updateAsset.minClose",
|
||||
"governance.proposal.updateAsset.minEnact",
|
||||
"governance.proposal.updateMarket.maxClose",
|
||||
"governance.proposal.updateMarket.maxEnact",
|
||||
"governance.proposal.updateMarket.minClose",
|
||||
"governance.proposal.updateMarket.minEnact",
|
||||
"governance.proposal.updateNetParam.maxClose",
|
||||
"governance.proposal.updateNetParam.maxEnact",
|
||||
"governance.proposal.updateNetParam.minClose",
|
||||
"governance.proposal.updateNetParam.minEnact",
|
||||
"market.auction.maximumDuration",
|
||||
"market.auction.minimumDuration",
|
||||
"market.liquidity.providers.fee.distributionTimeStep",
|
||||
"market.stake.target.timeWindow",
|
||||
"market.value.windowLength",
|
||||
"network.checkpoint.timeElapsedBetweenCheckpoints",
|
||||
"network.floatingPointUpdates.delay",
|
||||
"reward.staking.delegation.payoutDelay",
|
||||
"spam.pow.hashFunction",
|
||||
"validators.epoch.length"
|
||||
],
|
||||
"date": [
|
||||
"limits.assets.proposeEnabledFrom",
|
||||
"limits.markets.proposeEnabledFrom"
|
||||
],
|
||||
"id": ["reward.asset"]
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
context('Asset page', { tags: '@regression' }, function () {
|
||||
before('gather system asset information', function () {
|
||||
cy.get_asset_information().as('assetsInfo');
|
||||
});
|
||||
|
||||
describe('Verify elements on page', function () {
|
||||
const assetsNavigation = 'a[href="/assets"]';
|
||||
const assetHeader = '[data-testid="asset-header"]';
|
||||
@@ -11,63 +7,59 @@ context('Asset page', { tags: '@regression' }, function () {
|
||||
before('Navigate to assets page', function () {
|
||||
cy.visit('/');
|
||||
cy.get(assetsNavigation).click();
|
||||
|
||||
// Check we have enough enough assets
|
||||
const assetNames = Object.keys(this.assetsInfo);
|
||||
assert.isAtLeast(
|
||||
assetNames.length,
|
||||
5,
|
||||
'Ensuring we have at least 5 assets to test'
|
||||
);
|
||||
});
|
||||
|
||||
it('should be able to see assets page sections', function () {
|
||||
const assetNames = Object.keys(this.assetsInfo);
|
||||
assetNames.forEach((assetName) => {
|
||||
cy.get(assetHeader)
|
||||
.contains(assetName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection).should('not.be.empty');
|
||||
});
|
||||
});
|
||||
it('Assets page is displayed', function () {
|
||||
cy.common_validate_blocks_data_displayed(assetHeader);
|
||||
});
|
||||
|
||||
it('should be able to see all asset details displayed in JSON', function () {
|
||||
const assetNames = Object.keys(this.assetsInfo);
|
||||
assetNames.forEach((assetName) => {
|
||||
cy.get(assetHeader)
|
||||
.contains(assetName)
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection)
|
||||
.invoke('text')
|
||||
.convert_string_json_to_js_object()
|
||||
.then((assetsListedInJson) => {
|
||||
const assetInfo = this.assetsInfo[assetName];
|
||||
|
||||
assert.equal(assetsListedInJson.name, assetInfo.name);
|
||||
assert.equal(assetsListedInJson.id, assetInfo.id);
|
||||
assert.equal(assetsListedInJson.decimals, assetInfo.decimals);
|
||||
assert.equal(assetsListedInJson.symbol, assetInfo.symbol);
|
||||
assert.equal(
|
||||
assetsListedInJson.source.__typename,
|
||||
assetInfo.source.__typename
|
||||
it('Assets and all asset details are displayed', function () {
|
||||
cy.get_asset_information().then((assetsInfo) => {
|
||||
const assetNames = Object.keys(assetsInfo);
|
||||
assert.isAtLeast(
|
||||
assetNames.length,
|
||||
3,
|
||||
'Ensuring we have at least 3 assets to test'
|
||||
);
|
||||
assetNames.forEach((assetName) => {
|
||||
const assetInfo = assetsInfo[assetName];
|
||||
cy.get(assetHeader).contains(assetInfo.symbol);
|
||||
cy.get(assetHeader)
|
||||
.contains(assetName)
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection).within(() => {
|
||||
cy.contains(`"name": "${assetName}"`).should('be.visible');
|
||||
cy.contains(`"id": "${assetInfo.id}"`).should('be.visible');
|
||||
cy.contains(`"decimals": ${assetInfo.decimals}`).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains(`"symbol": "${assetInfo.symbol}"`).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains(
|
||||
`"__typename": "${assetInfo.infrastructureFeeAccount.__typename}"`
|
||||
).should('be.visible');
|
||||
cy.contains(
|
||||
`"type": "${assetInfo.infrastructureFeeAccount.type}"`
|
||||
).should('be.visible');
|
||||
cy.contains(
|
||||
`"balance": "${assetInfo.infrastructureFeeAccount.balance}"`
|
||||
).should('be.visible');
|
||||
cy.contains(
|
||||
`"__typename": "${assetInfo.source.__typename}"`
|
||||
).should('be.visible');
|
||||
|
||||
if (assetInfo.source.__typename == 'ERC20') {
|
||||
assert.equal(
|
||||
assetsListedInJson.source.contractAddress,
|
||||
assetInfo.source.contractAddress
|
||||
);
|
||||
cy.contains(
|
||||
`"contractAddress": "${assetInfo.source.contractAddress}"`
|
||||
).should('be.visible');
|
||||
}
|
||||
|
||||
if (assetInfo.source.__typename == 'BuiltinAsset') {
|
||||
assert.equal(
|
||||
assetsListedInJson.source.maxFaucetAmountMint,
|
||||
assetInfo.source.maxFaucetAmountMint
|
||||
);
|
||||
cy.contains(
|
||||
`"maxFaucetAmountMint": "${assetInfo.source.maxFaucetAmountMint}"`
|
||||
).should('be.visible');
|
||||
}
|
||||
|
||||
let knownAssetTypes = ['BuiltinAsset', 'ERC20'];
|
||||
@@ -75,37 +67,28 @@ context('Asset page', { tags: '@regression' }, function () {
|
||||
knownAssetTypes,
|
||||
assetInfo.source.__typename,
|
||||
`Checking that current asset type of ${assetInfo.source.__typename} /
|
||||
is one of: ${knownAssetTypes}: /
|
||||
If fail then we need to add extra tests for un-encountered asset types`
|
||||
is one of: ${knownAssetTypes}: /
|
||||
If fail then we need to add extra tests for un-encountered asset types`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to switch assets between light and dark mode', function () {
|
||||
it('Assets page able to switch between light and dark mode', function () {
|
||||
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
|
||||
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
|
||||
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
|
||||
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
|
||||
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
|
||||
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
|
||||
const blackThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
|
||||
const blackThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
|
||||
const blackThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
|
||||
const themeSwitcher = '[data-testid="theme-switcher"]';
|
||||
const jsonFields = '.hljs';
|
||||
const sideMenuBackground = '.absolute';
|
||||
|
||||
// Engage dark mode if not allready set
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.then((background_color) => {
|
||||
if (background_color.includes(whiteThemeSideMenuBackgroundColor))
|
||||
cy.get(themeSwitcher).click();
|
||||
});
|
||||
|
||||
// Engage white mode
|
||||
cy.get(themeSwitcher).click();
|
||||
|
||||
// White Mode
|
||||
cy.get(themeSwitcher).click();
|
||||
cy.get(assetsNavigation)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeSelectedMenuOptionColor);
|
||||
@@ -120,29 +103,19 @@ context('Asset page', { tags: '@regression' }, function () {
|
||||
cy.get(themeSwitcher).click();
|
||||
cy.get(assetsNavigation)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSelectedMenuOptionColor);
|
||||
.and('include', blackThemeSelectedMenuOptionColor);
|
||||
cy.get(jsonFields)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeJsonFieldBackColor);
|
||||
.and('include', blackThemeJsonFieldBackColor);
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSideMenuBackgroundColor);
|
||||
.and('include', blackThemeSideMenuBackgroundColor);
|
||||
});
|
||||
|
||||
it('should be able to see assets page displayed in mobile', function () {
|
||||
it('Assets page displayed in mobile', function () {
|
||||
cy.common_switch_to_mobile_and_click_toggle();
|
||||
cy.get(assetsNavigation).click();
|
||||
|
||||
const assetNames = Object.keys(this.assetsInfo);
|
||||
assetNames.forEach((assetName) => {
|
||||
cy.get(assetHeader)
|
||||
.contains(assetName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection).should('not.be.empty');
|
||||
});
|
||||
});
|
||||
cy.common_validate_blocks_data_displayed(assetHeader);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,267 +1,33 @@
|
||||
context('Network parameters page', { tags: '@smoke' }, function () {
|
||||
before('navigate to network parameter page', function () {
|
||||
cy.fixture('net_parameter_format_lookup').as('networkParameterFormat');
|
||||
before('visit token home page', function () {
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
describe('Verify elements on page', function () {
|
||||
const networkParametersNavigation = 'a[href="/network-parameters"]';
|
||||
const networkParametersHeader = '[data-testid="network-param-header"]';
|
||||
const tableRows = '[data-testid="key-value-table-row"]';
|
||||
|
||||
before('navigate to network parameter page', function () {
|
||||
cy.visit('/');
|
||||
beforeEach('Navigate to network parameter page', function () {
|
||||
cy.get(networkParametersNavigation).click();
|
||||
});
|
||||
|
||||
it('should show network parameter heading at top of page', function () {
|
||||
cy.get(networkParametersHeader)
|
||||
.should('have.text', 'Network Parameters')
|
||||
.and('be.visible');
|
||||
it('Network paremeter page is displayed', function () {
|
||||
verifyNetworkParametersPageDisplayed();
|
||||
});
|
||||
|
||||
it('should list each of the network parameters available', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
const numberOfNetworkParametersInSystem =
|
||||
Object.keys(network_parameters).length;
|
||||
cy.get(tableRows).should(
|
||||
'have.length',
|
||||
numberOfNetworkParametersInSystem
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should list each network parameter displayed with json - in the correct format', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (this.networkParameterFormat.json.includes(parameterName)) {
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.invoke('text')
|
||||
.convert_string_json_to_js_object()
|
||||
.then((jsonOnPage) => {
|
||||
cy.wrap(parameterValue, { log: false })
|
||||
.convert_string_json_to_js_object()
|
||||
.then((jsonInSystem) =>
|
||||
assert.deepEqual(
|
||||
jsonOnPage,
|
||||
jsonInSystem,
|
||||
`Checking ${parameterName} has the correct value of ${jsonInSystem}`
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should list each network parameter displayed as a percentage - in the correct format', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (this.networkParameterFormat.percentage.includes(parameterName)) {
|
||||
const formattedPercentageParameter =
|
||||
(parseFloat(parameterValue) * 100).toFixed(0) + '%';
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.invoke('text')
|
||||
.then((parameterValueOnPage) => {
|
||||
assert.equal(
|
||||
parameterValueOnPage,
|
||||
formattedPercentageParameter,
|
||||
`Checking ${parameterName} has the correct value of ${formattedPercentageParameter}`
|
||||
);
|
||||
cy.contains(parameterValueOnPage).should('be.visible');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should list each network parameter displayed as an id - in the correct format', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (this.networkParameterFormat.id.includes(parameterName)) {
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.should('contain', parameterValue)
|
||||
.and('be.visible')
|
||||
.invoke('text');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should list each network parameter displayed as a date - in the correct format', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (this.networkParameterFormat.date.includes(parameterName)) {
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.should('contain', parameterValue)
|
||||
.and('be.visible');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should list each network parameter displayed as a duration - in the correct format', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (this.networkParameterFormat.duration.includes(parameterName)) {
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.should('contain', parameterValue)
|
||||
.and('be.visible');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should list each network parameter displayed as a currency value with four decimals - in the correct format', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (this.networkParameterFormat.fiveDecimal.includes(parameterName)) {
|
||||
cy.convert_number_to_four_decimal(parameterValue)
|
||||
.add_commas_to_number_if_large_enough()
|
||||
.then((parameterValueFormatted) => {
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.invoke('text')
|
||||
.then((parameterValueOnPage) => {
|
||||
assert.equal(
|
||||
parameterValueOnPage,
|
||||
parameterValueFormatted,
|
||||
`Checking ${parameterName} has the correct value of ${parameterValueFormatted}`
|
||||
);
|
||||
cy.contains(parameterValueOnPage).should('be.visible');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should list each network parameter displayed as a currency value with eighteen decimals - in the correct format', function () {
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (
|
||||
this.networkParameterFormat.eighteenDecimal.includes(parameterName)
|
||||
) {
|
||||
cy.convert_number_to_eighteen_decimal(parameterValue)
|
||||
.add_commas_to_number_if_large_enough()
|
||||
.then((parameterValueFormatted) => {
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.invoke('text')
|
||||
.then((parameterValueOnPage) => {
|
||||
assert.equal(
|
||||
parameterValueOnPage,
|
||||
parameterValueFormatted,
|
||||
`Checking ${parameterName} has the correct value of ${parameterValueFormatted}`
|
||||
);
|
||||
cy.contains(parameterValueOnPage).should('be.visible');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to switch network parameter page - between light and dark mode', function () {
|
||||
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
|
||||
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
|
||||
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
|
||||
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
|
||||
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
|
||||
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
|
||||
const themeSwitcher = '[data-testid="theme-switcher"]';
|
||||
const jsonFields = '.hljs';
|
||||
const sideMenuBackground = '.absolute';
|
||||
|
||||
// Engage dark mode if not allready set
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.then((background_color) => {
|
||||
if (background_color.includes(whiteThemeSideMenuBackgroundColor))
|
||||
cy.get(themeSwitcher).click();
|
||||
});
|
||||
|
||||
// Engage white mode
|
||||
cy.get(themeSwitcher).click();
|
||||
|
||||
// White Mode
|
||||
cy.get(networkParametersNavigation)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeSelectedMenuOptionColor);
|
||||
cy.get(jsonFields)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeJsonFieldBackColor);
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeSideMenuBackgroundColor);
|
||||
|
||||
// Dark Mode
|
||||
cy.get(themeSwitcher).click();
|
||||
cy.get(networkParametersNavigation)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSelectedMenuOptionColor);
|
||||
cy.get(jsonFields)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeJsonFieldBackColor);
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSideMenuBackgroundColor);
|
||||
});
|
||||
|
||||
it('should be able to see network parameters - on mobile', function () {
|
||||
it('Network parameter page displayed on mobile', function () {
|
||||
cy.common_switch_to_mobile_and_click_toggle();
|
||||
cy.get(networkParametersNavigation).click();
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
network_parameters = Object.entries(network_parameters);
|
||||
network_parameters.forEach((network_parameter) => {
|
||||
const parameterName = network_parameter[0];
|
||||
cy.get(tableRows)
|
||||
.contains(parameterName)
|
||||
.should('be.visible')
|
||||
.next()
|
||||
.should('not.be.empty')
|
||||
.and('be.visible');
|
||||
});
|
||||
});
|
||||
verifyNetworkParametersPageDisplayed();
|
||||
});
|
||||
});
|
||||
|
||||
function verifyNetworkParametersPageDisplayed() {
|
||||
cy.get('[data-testid="network-param-header"]').should(
|
||||
'have.text',
|
||||
'Network Parameters'
|
||||
);
|
||||
cy.common_verify_json_parameters(18);
|
||||
cy.common_verify_json_string_values(6);
|
||||
cy.common_verify_json_int_values(7);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -33,20 +33,6 @@ context('Parties page', { tags: '@regression' }, function () {
|
||||
// Deliberate slow entry of party id/key - enabling transactions to sync
|
||||
cy.get(partiesSearchBox).type(vegaWalletPublicKey, { delay: 120 });
|
||||
cy.get(partiesSearchAction).click();
|
||||
cy.get_connected_parties_accounts().as('party_accounts');
|
||||
|
||||
// Ensure balance of each party asset is correct
|
||||
cy.get('@party_accounts').then((accounts) => {
|
||||
assetsInTest.forEach((asset) => {
|
||||
cy.get_asset_decimals(assetData[asset].id).then((assetDecimals) => {
|
||||
assert.equal(
|
||||
accounts[assetData[asset].id].balance,
|
||||
assetData[asset].amount + assetDecimals,
|
||||
`Checking ${assetData[asset].id} faucet was successfull`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should see party address id - having searched', function () {
|
||||
@@ -56,7 +42,7 @@ context('Parties page', { tags: '@regression' }, function () {
|
||||
.should('be.visible');
|
||||
});
|
||||
|
||||
it('should see each asset and balance - within asset data section', function () {
|
||||
it('should see each asset - within asset data section', function () {
|
||||
assetsInTest.forEach((asset) => {
|
||||
cy.contains(assetData[asset].name, txTimeout).should('be.visible');
|
||||
cy.contains(assetData[asset].name)
|
||||
@@ -102,97 +88,26 @@ context('Parties page', { tags: '@regression' }, function () {
|
||||
it('should be able to see JSON of each asset containing correct balance and decimals', function () {
|
||||
cy.get(partiesJsonSection).should('be.visible');
|
||||
|
||||
assetsInTest.forEach((assetInTest) => {
|
||||
assetsInTest.forEach((asset) => {
|
||||
cy.get(partiesJsonSection)
|
||||
.invoke('text')
|
||||
.convert_string_json_to_js_object()
|
||||
.get_party_accounts_data_from_js_object()
|
||||
.then((accountsListedInJson) => {
|
||||
cy.get_asset_information().then((assetsInfo) => {
|
||||
const assetInfo =
|
||||
assetsInfo[accountsListedInJson[assetInTest].asset.name];
|
||||
|
||||
.get_party_accounts_data()
|
||||
.then((accounts) => {
|
||||
cy.get_asset_decimals(asset).then((assetDecimals) => {
|
||||
assert.equal(
|
||||
accountsListedInJson[assetInTest].asset.name,
|
||||
assetInfo.name
|
||||
accounts[asset].balance,
|
||||
assetData[asset].amount + assetDecimals
|
||||
);
|
||||
assert.equal(
|
||||
accountsListedInJson[assetInTest].asset.id,
|
||||
assetInfo.id
|
||||
);
|
||||
assert.equal(
|
||||
accountsListedInJson[assetInTest].asset.decimals,
|
||||
assetInfo.decimals
|
||||
);
|
||||
assert.equal(
|
||||
accountsListedInJson[assetInTest].asset.symbol,
|
||||
assetInfo.symbol
|
||||
);
|
||||
assert.equal(
|
||||
accountsListedInJson[assetInTest].asset.source.__typename,
|
||||
assetInfo.source.__typename
|
||||
);
|
||||
cy.get_asset_decimals(assetInTest).then((assetDecimals) => {
|
||||
assert.equal(
|
||||
accountsListedInJson[assetInTest].balance,
|
||||
assetData[assetInTest].amount + assetDecimals
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to switch parties page between light and dark mode', function () {
|
||||
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
|
||||
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
|
||||
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
|
||||
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
|
||||
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
|
||||
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
|
||||
const themeSwitcher = '[data-testid="theme-switcher"]';
|
||||
const jsonFields = '.hljs';
|
||||
const sideMenuBackground = '.absolute';
|
||||
|
||||
// Engage dark mode if not allready set
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.then((background_color) => {
|
||||
if (background_color.includes(whiteThemeSideMenuBackgroundColor))
|
||||
cy.get(themeSwitcher).click();
|
||||
});
|
||||
|
||||
// Engage white mode
|
||||
cy.get(themeSwitcher).click();
|
||||
|
||||
// White Mode
|
||||
cy.get(partiesMenuHeader)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeSelectedMenuOptionColor);
|
||||
cy.get(jsonFields)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeJsonFieldBackColor);
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeSideMenuBackgroundColor);
|
||||
|
||||
// Dark Mode
|
||||
cy.get(themeSwitcher).click();
|
||||
cy.get(partiesMenuHeader)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSelectedMenuOptionColor);
|
||||
cy.get(jsonFields)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeJsonFieldBackColor);
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSideMenuBackgroundColor);
|
||||
});
|
||||
|
||||
after(
|
||||
'teardown environment to prevent test data bleeding into other tests',
|
||||
function () {
|
||||
if (Cypress.env('TEARDOWN_NETWORK_AFTER_FLOWS')) {
|
||||
if (Cypress.env('CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS')) {
|
||||
cy.restart_vegacapsule_network();
|
||||
}
|
||||
}
|
||||
@@ -207,39 +122,28 @@ context('Parties page', { tags: '@regression' }, function () {
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('get_connected_parties_accounts', () => {
|
||||
const mutation =
|
||||
'{partiesConnection {edges{node{accountsConnection{edges{node{\
|
||||
balance type asset {id symbol decimals}}}}}}}}';
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `http://localhost:3028/query`,
|
||||
body: {
|
||||
query: mutation,
|
||||
},
|
||||
headers: { 'content-type': 'application/json' },
|
||||
})
|
||||
.its(
|
||||
`body.data.partiesConnection.edges.1.node.accountsConnection.edges`
|
||||
)
|
||||
.then(function (response) {
|
||||
let accounts = {};
|
||||
response.forEach((account) => {
|
||||
accounts[account.node.asset.id] = account.node;
|
||||
});
|
||||
return accounts;
|
||||
});
|
||||
});
|
||||
Cypress.Commands.add(
|
||||
'convert_string_json_to_js_object',
|
||||
{ prevSubject: true },
|
||||
(jsonBlobString) => {
|
||||
return JSON.parse(jsonBlobString);
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add(
|
||||
'get_party_accounts_data_from_js_object',
|
||||
'get_party_accounts_data',
|
||||
{ prevSubject: true },
|
||||
(jsObject) => {
|
||||
const accounts = jsObject.party.accounts.reduce(function (
|
||||
account,
|
||||
entry
|
||||
) {
|
||||
account[entry.asset.id] = entry;
|
||||
account[entry.asset.id] = {
|
||||
balance: entry.balance,
|
||||
id: entry.asset.id,
|
||||
decimals: entry.asset.decimals,
|
||||
name: entry.asset.name,
|
||||
};
|
||||
return account;
|
||||
},
|
||||
{});
|
||||
|
||||
@@ -1,300 +1,25 @@
|
||||
context('Validator page', { tags: '@smoke' }, function () {
|
||||
const validatorMenuHeading = 'a[href="/validators"]';
|
||||
const tendermintDataHeader = '[data-testid="tendermint-header"]';
|
||||
const vegaDataHeader = '[data-testid="vega-header"]';
|
||||
const jsonSection = '.language-json';
|
||||
|
||||
before('Visit validators page and obtain data', function () {
|
||||
cy.visit('/');
|
||||
cy.get(validatorMenuHeading).click();
|
||||
cy.get_validators().as('validators');
|
||||
cy.get_nodes().as('nodes');
|
||||
});
|
||||
|
||||
describe('Verify elements on page', function () {
|
||||
before('Ensure at least two validators are present', function () {
|
||||
assert.isAtLeast(
|
||||
this.validators.length,
|
||||
2,
|
||||
'Ensuring at least two validators exist'
|
||||
);
|
||||
const validatorNavigation = 'a[href="/validators"]';
|
||||
|
||||
it('Validator page is displayed', function () {
|
||||
cy.visit('/');
|
||||
cy.get(validatorNavigation).click();
|
||||
validateValidatorsDisplayed();
|
||||
});
|
||||
|
||||
it('should be able to see validator page sections', function () {
|
||||
cy.get(vegaDataHeader)
|
||||
.contains('Vega data')
|
||||
.and('is.visible')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection).should('not.be.empty');
|
||||
});
|
||||
|
||||
cy.get(tendermintDataHeader)
|
||||
.contains('Tendermint data')
|
||||
.and('is.visible')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection).should('not.be.empty');
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to see relevant validator information in tendermint section', function () {
|
||||
cy.get(tendermintDataHeader)
|
||||
.contains('Tendermint data')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection)
|
||||
.invoke('text')
|
||||
.convert_string_json_to_js_object()
|
||||
.then((validatorsInJson) => {
|
||||
this.validators.forEach((validator, index) => {
|
||||
const validatorInJson =
|
||||
validatorsInJson.result.validators[index];
|
||||
|
||||
assert.equal(
|
||||
validatorInJson.address,
|
||||
validator.address,
|
||||
`Checking that validator address shown in json matches system data`
|
||||
);
|
||||
cy.contains(validator.address).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
validatorInJson.pub_key.type,
|
||||
validator.pub_key.type,
|
||||
`Checking that validator public key type shown in json matches system data`
|
||||
);
|
||||
cy.contains(validator.pub_key.type).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
validatorInJson.pub_key.value,
|
||||
validator.pub_key.value,
|
||||
`Checking that validator public key value shown in json matches system data`
|
||||
);
|
||||
cy.contains(validator.pub_key.value).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
validatorInJson.voting_power,
|
||||
validator.voting_power,
|
||||
`Checking that validator voting power in json matches system data`
|
||||
);
|
||||
cy.contains(validator.voting_power).should('be.visible');
|
||||
|
||||
// Proposer priority can change frequently mid test
|
||||
// Therefore only checking the field name is present.
|
||||
cy.contains('proposer_priority').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to see relevant node information in vega data section', function () {
|
||||
cy.get(vegaDataHeader)
|
||||
.contains('Vega data')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection)
|
||||
.invoke('text')
|
||||
.convert_string_json_to_js_object()
|
||||
.then((nodesInJson) => {
|
||||
this.nodes.forEach((node, index) => {
|
||||
const nodeInJson = nodesInJson.nodes[index];
|
||||
|
||||
// Vegacapsule shows no info or null for following fields:
|
||||
// name, infoURL, avatarUrl, location, epoch data
|
||||
// Therefore, these values remain unchecked.
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.__typename,
|
||||
node.__typename,
|
||||
`Checking that node __typename shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.__typename).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.id,
|
||||
node.id,
|
||||
`Checking that node id shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.id).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.pubkey,
|
||||
node.pubkey,
|
||||
`Checking that node pubkey shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.pubkey).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.tmPubkey,
|
||||
node.tmPubkey,
|
||||
`Checking that node tmPubkey shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.tmPubkey).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.ethereumAddress,
|
||||
node.ethereumAddress,
|
||||
`Checking that node ethereumAddress shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.ethereumAddress).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.stakedByOperator,
|
||||
node.stakedByOperator,
|
||||
`Checking that node stakedByOperator value shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.stakedByOperator).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.stakedByDelegates,
|
||||
node.stakedByDelegates,
|
||||
`Checking that node stakedByDelegates value shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.stakedByDelegates).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.stakedTotal,
|
||||
node.stakedTotal,
|
||||
`Checking that node stakedTotal shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.stakedTotal).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.pendingStake,
|
||||
node.pendingStake,
|
||||
`Checking that node pendingStake shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.pendingStake).should('be.visible');
|
||||
|
||||
assert.equal(
|
||||
nodeInJson.status,
|
||||
node.status,
|
||||
`Checking that node status shown in json matches system data`
|
||||
);
|
||||
cy.contains(node.status).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to see validator page displayed on mobile', function () {
|
||||
it('Validator page is displayed on mobile', function () {
|
||||
cy.common_switch_to_mobile_and_click_toggle();
|
||||
cy.get(validatorMenuHeading).click();
|
||||
cy.get(vegaDataHeader)
|
||||
.contains('Vega data')
|
||||
.and('is.visible')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection).should('not.be.empty');
|
||||
});
|
||||
|
||||
cy.get(tendermintDataHeader)
|
||||
.contains('Tendermint data')
|
||||
.and('is.visible')
|
||||
.next()
|
||||
.within(() => {
|
||||
cy.get(jsonSection).should('not.be.empty');
|
||||
});
|
||||
|
||||
cy.get(tendermintDataHeader)
|
||||
.contains('Tendermint data')
|
||||
.next()
|
||||
.within(() => {
|
||||
this.validators.forEach((validator) => {
|
||||
cy.contains(validator.address).should('be.visible');
|
||||
cy.contains(validator.pub_key.type).should('be.visible');
|
||||
cy.contains(validator.pub_key.value).should('be.visible');
|
||||
cy.contains(validator.voting_power).should('be.visible');
|
||||
// Proposer priority can change frequently mid test
|
||||
// Therefore only checking the field name is present.
|
||||
cy.contains('proposer_priority').should('be.visible');
|
||||
});
|
||||
});
|
||||
cy.get(validatorNavigation).click();
|
||||
validateValidatorsDisplayed();
|
||||
});
|
||||
|
||||
it('should be able to switch validator page between light and dark mode', function () {
|
||||
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
|
||||
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
|
||||
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
|
||||
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
|
||||
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
|
||||
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
|
||||
const themeSwitcher = '[data-testid="theme-switcher"]';
|
||||
const jsonFields = '.hljs';
|
||||
const sideMenuBackground = '.absolute';
|
||||
|
||||
// Engage dark mode if not allready set
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.then((background_color) => {
|
||||
if (background_color.includes(whiteThemeSideMenuBackgroundColor))
|
||||
cy.get(themeSwitcher).click();
|
||||
});
|
||||
|
||||
// Engage white mode
|
||||
cy.get(themeSwitcher).click();
|
||||
|
||||
// White Mode
|
||||
cy.get(validatorMenuHeading)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeSelectedMenuOptionColor);
|
||||
cy.get(jsonFields)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeJsonFieldBackColor);
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', whiteThemeSideMenuBackgroundColor);
|
||||
|
||||
// Dark Mode
|
||||
cy.get(themeSwitcher).click();
|
||||
cy.get(validatorMenuHeading)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSelectedMenuOptionColor);
|
||||
cy.get(jsonFields)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeJsonFieldBackColor);
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.and('include', darkThemeSideMenuBackgroundColor);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('get_validators', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `http://localhost:26617/validators`,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
})
|
||||
.its(`body.result.validators`)
|
||||
.then(function (response) {
|
||||
let validators = [];
|
||||
response.forEach((account, index) => {
|
||||
validators[index] = account;
|
||||
});
|
||||
return validators;
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('get_nodes', () => {
|
||||
const mutation =
|
||||
'{nodes { id name infoUrl avatarUrl pubkey tmPubkey ethereumAddress \
|
||||
location stakedByOperator stakedByDelegates stakedTotal pendingStake \
|
||||
epochData { total offline online __typename } status name __typename}}';
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `http://localhost:3028/query`,
|
||||
body: {
|
||||
query: mutation,
|
||||
},
|
||||
headers: { 'content-type': 'application/json' },
|
||||
})
|
||||
.its(`body.data.nodes`)
|
||||
.then(function (response) {
|
||||
let nodes = [];
|
||||
response.forEach((node) => {
|
||||
nodes.push(node);
|
||||
});
|
||||
return nodes;
|
||||
});
|
||||
});
|
||||
function validateValidatorsDisplayed() {
|
||||
cy.get('[data-testid="tendermint-header"]').should(
|
||||
'have.text',
|
||||
'Tendermint data'
|
||||
);
|
||||
cy.get('[data-testid="tendermint-data"]').should('not.be.empty');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
|
||||
Cypress.Commands.add(
|
||||
'common_validate_blocks_data_displayed',
|
||||
function (headerTestId) {
|
||||
@@ -27,6 +25,33 @@ Cypress.Commands.add('common_switch_to_mobile_and_click_toggle', function () {
|
||||
cy.get('[data-testid="open-menu"]').click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('common_verify_json_parameters', function (expectedNum) {
|
||||
cy.get('.hljs-attr')
|
||||
.should('have.length.at.least', expectedNum)
|
||||
.each(($paramName) => {
|
||||
cy.wrap($paramName).should('not.be.empty');
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add(
|
||||
'common_verify_json_string_values',
|
||||
function (expectedNum) {
|
||||
cy.get('.hljs-string')
|
||||
.should('have.length.at.least', expectedNum)
|
||||
.each(($paramValue) => {
|
||||
cy.wrap($paramValue).should('not.be.empty');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add('common_verify_json_int_values', function (expectedNum) {
|
||||
cy.get('.hljs-number')
|
||||
.should('have.length.at.least', expectedNum)
|
||||
.each(($paramValue) => {
|
||||
cy.wrap($paramValue).should('not.be.empty');
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('monitor_clipboard', () => {
|
||||
cy.window().then((win) => {
|
||||
return cy.stub(win, 'prompt').returns(win.prompt);
|
||||
@@ -42,38 +67,3 @@ Cypress.Commands.add(
|
||||
return clipboard.args[0][1];
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add(
|
||||
'convert_string_json_to_js_object',
|
||||
{ prevSubject: true },
|
||||
(jsonBlobString) => {
|
||||
// Note: this is a chaining function
|
||||
return JSON.parse(jsonBlobString);
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add(
|
||||
'add_commas_to_number_if_large_enough',
|
||||
{ prevSubject: true },
|
||||
(number) => {
|
||||
// This will turn 10000000.0000 into 10,000,000.000
|
||||
// Note: this is a chaining function
|
||||
const beforeDecimal = number.split('.')[0];
|
||||
const afterDecimal = number.split('.')[1];
|
||||
const beforeDecimalWithCommas = beforeDecimal
|
||||
.toString()
|
||||
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
const formattedValue = beforeDecimalWithCommas + '.' + afterDecimal;
|
||||
return formattedValue;
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add('convert_number_to_eighteen_decimal', (number) => {
|
||||
// this will take a number like this : 700000000000000000000
|
||||
// and convert it to a number like this: 700.000000000000000000
|
||||
return BigNumber((number / 1000000000000000000).toString()).toFixed(18);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('convert_number_to_four_decimal', (number) => {
|
||||
return parseFloat(number).toFixed(4);
|
||||
});
|
||||
|
||||
+1
-2
@@ -2,11 +2,10 @@ NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-exp
|
||||
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_BLOCK_EXPLORER=
|
||||
|
||||
# App flags
|
||||
NX_EXPLORER_ASSETS=1
|
||||
|
||||
@@ -3,7 +3,7 @@ NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-exp
|
||||
NX_TENDERMINT_URL=http://localhost:26617
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||
NX_VEGA_URL=http://localhost:3028/query
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ NX_TENDERMINT_URL=https://n04.d.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
|
||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
NX_VEGA_ENV=DEVNET
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_BLOCK_EXPLORER=
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user