Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf6d6e70bc | ||
|
|
9e2dc19426 | ||
|
|
344971d5a9 | ||
|
|
de1f8b5895 | ||
|
|
5b826f89d8 | ||
|
|
246c07f355 | ||
|
|
642bc8072b | ||
|
|
de8e543bf4 | ||
|
|
787a8ea1b3 | ||
|
|
d28ff4cfe7 | ||
|
|
71e1a116c7 | ||
|
|
f0fc737e58 | ||
|
|
fe447167ca | ||
|
|
02a8a8d9ec | ||
|
|
f7bee22ba6 | ||
|
|
df6ae6e8fa | ||
|
|
e25391a18c | ||
|
|
c9b71af830 | ||
|
|
9dfce9e723 | ||
|
|
ad7f263811 | ||
|
|
2afd182f03 | ||
|
|
6134ac9015 | ||
|
|
0ccf564ee7 | ||
|
|
f212f5bb28 | ||
|
|
22c1a4ad6a | ||
|
|
0a0d74dcbd | ||
|
|
031cd9258e | ||
|
|
be39008b42 | ||
|
|
20b663a092 | ||
|
|
41646086e4 | ||
|
|
7c0bed2f14 | ||
|
|
ce62342d9a | ||
|
|
9aa672968f | ||
|
|
4b7a513e98 | ||
|
|
1aff7b1437 | ||
|
|
b749a05736 | ||
|
|
a5aed85b43 | ||
|
|
2c5a4e479b | ||
|
|
d84612028e | ||
|
|
fd8bf74cff |
@@ -1,6 +1,6 @@
|
||||
# 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_URL=https://api.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
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { connectVegaWallet } from '../support/vega-wallet';
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import {
|
||||
generateMarket,
|
||||
generateMarketData,
|
||||
generateMarketsCandles,
|
||||
generateMarketsData,
|
||||
generateSimpleMarkets,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
|
||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
||||
@@ -27,7 +28,8 @@ describe('market selector', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'DealTicket', generateDealTicket());
|
||||
aliasQuery(req, 'MarketData', generateMarketData());
|
||||
aliasQuery(req, 'Market', generateMarket());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
generateMarketsCandles,
|
||||
generateMarketsData,
|
||||
generateMarket,
|
||||
generateMarketData,
|
||||
} from '../support/mocks/generate-markets';
|
||||
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
|
||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
||||
@@ -28,7 +28,6 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'DealTicket', generateDealTicket());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
@@ -37,6 +36,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||
aliasQuery(req, 'Market', generateMarket());
|
||||
aliasQuery(req, 'MarketData', generateMarketData());
|
||||
});
|
||||
cy.visit('/markets');
|
||||
cy.wait('@Markets').then((response) => {
|
||||
@@ -270,7 +270,10 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
.find('dt')
|
||||
.eq(3)
|
||||
.should('have.text', 'Est. Fees (tDAI)');
|
||||
cy.get('#step-2-panel').find('dd').eq(3).should('have.text', '3 (3.03%)');
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(3)
|
||||
.should('have.text', '3.00 (3.03%)');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -292,7 +295,10 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
|
||||
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
|
||||
|
||||
cy.get('#step-3-panel').find('dd').eq(3).should('have.text', '3 (3.03%)');
|
||||
cy.get('#step-3-panel')
|
||||
.find('dd')
|
||||
.eq(3)
|
||||
.should('have.text', '3.00 (3.03%)');
|
||||
|
||||
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
|
||||
|
||||
|
||||
@@ -116,7 +116,12 @@ export const protoMarket: Market = {
|
||||
product: {
|
||||
__typename: 'Future',
|
||||
quoteName: 'DAI',
|
||||
settlementAsset: { symbol: 'tDAI', __typename: 'Asset', decimals: 5 },
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
@@ -144,4 +149,8 @@ export const singleMarket: SingleMarketFieldsFragment = {
|
||||
},
|
||||
},
|
||||
},
|
||||
depth: {
|
||||
__typename: 'MarketDepth',
|
||||
lastTrade: { price: '9893006', __typename: 'Trade' },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import type { DealTicketQuery } from '@vegaprotocol/deal-ticket';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateDealTicket = (
|
||||
override?: PartialDeep<DealTicketQuery>
|
||||
): DealTicketQuery => {
|
||||
const defaultResult: DealTicketQuery = {
|
||||
market: {
|
||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
||||
decimalPlaces: 5,
|
||||
positionDecimalPlaces: 0,
|
||||
state: Schema.MarketState.STATE_ACTIVE,
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||
product: {
|
||||
quoteName: 'DAI',
|
||||
settlementAsset: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'Future',
|
||||
},
|
||||
__typename: 'Instrument',
|
||||
},
|
||||
__typename: 'TradableInstrument',
|
||||
},
|
||||
depth: {
|
||||
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);
|
||||
};
|
||||
@@ -11,6 +11,7 @@ import type {
|
||||
import { protoMarket, protoCandles, singleMarket } from './commons';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type { MarketQuery } from '@vegaprotocol/market-list';
|
||||
import type { MarketDataQuery } from '@vegaprotocol/market-list';
|
||||
|
||||
export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
const markets: Market[] = [
|
||||
@@ -38,8 +39,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'XYZalpha',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-XYZalpha',
|
||||
symbol: 'XYZalpha',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -72,8 +74,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'XYZbeta',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-XYZbeta',
|
||||
symbol: 'XYZbeta',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -107,8 +110,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'DAI',
|
||||
settlementAsset: {
|
||||
symbol: 'tDAI',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tDAI',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -141,8 +145,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'XYZbeta',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-XYZbeta',
|
||||
symbol: 'XYZbeta',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -174,8 +179,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'tUSDC',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tUSDC',
|
||||
symbol: 'tUSDC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -209,8 +215,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'tBTC',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tBTC',
|
||||
symbol: 'tBTC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -243,8 +250,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'XYZgamma',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-XYZgamma',
|
||||
symbol: 'XYZgamma',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -278,8 +286,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'tBTC',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tBTC',
|
||||
symbol: 'tBTC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -313,8 +322,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'BTC',
|
||||
settlementAsset: {
|
||||
symbol: 'tBTC',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tBTC',
|
||||
symbol: 'tBTC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -349,8 +359,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'tUSDC',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tUSDC',
|
||||
symbol: 'tUSDC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -385,8 +396,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'EURO',
|
||||
settlementAsset: {
|
||||
symbol: 'tEURO',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tEURO',
|
||||
symbol: 'tEURO',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -419,8 +431,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'XYZgamma',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-XYZgamma',
|
||||
symbol: 'XYZgamma',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -454,8 +467,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'tBTC',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tBTC',
|
||||
symbol: 'tBTC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -489,8 +503,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
|
||||
__typename: 'Future',
|
||||
quoteName: 'USD',
|
||||
settlementAsset: {
|
||||
symbol: 'tBTC',
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tBTC',
|
||||
symbol: 'tBTC',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
@@ -1139,52 +1154,51 @@ export const generateFillsMarkets = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const markets = [
|
||||
{
|
||||
data: {
|
||||
market: {
|
||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
||||
__typename: 'Market',
|
||||
},
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
staticMidPrice: '0',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '0',
|
||||
bestBidPrice: '0',
|
||||
bestOfferPrice: '0',
|
||||
markPrice: '17588787',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
__typename: 'MarketData',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
{
|
||||
data: {
|
||||
market: {
|
||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
||||
__typename: 'Market',
|
||||
},
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
staticMidPrice: '0',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '0',
|
||||
bestBidPrice: '0',
|
||||
bestOfferPrice: '0',
|
||||
markPrice: '84377569',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
__typename: 'MarketData',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
];
|
||||
export const generateMarketsData = (
|
||||
override?: PartialDeep<MarketsDataQuery>
|
||||
): MarketsDataQuery => {
|
||||
const markets = [
|
||||
{
|
||||
data: {
|
||||
market: {
|
||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
||||
__typename: 'Market',
|
||||
},
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
staticMidPrice: '0',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '0',
|
||||
bestBidPrice: '0',
|
||||
bestOfferPrice: '0',
|
||||
markPrice: '17588787',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
__typename: 'MarketData',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
{
|
||||
data: {
|
||||
market: {
|
||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
||||
__typename: 'Market',
|
||||
},
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
staticMidPrice: '0',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '0',
|
||||
bestBidPrice: '0',
|
||||
bestOfferPrice: '0',
|
||||
markPrice: '84377569',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
__typename: 'MarketData',
|
||||
},
|
||||
__typename: 'Market',
|
||||
},
|
||||
];
|
||||
|
||||
const defaultResult: MarketsDataQuery = {
|
||||
marketsConnection: {
|
||||
__typename: 'MarketConnection',
|
||||
@@ -1240,9 +1254,10 @@ export const generatePositionsMarkets = () => {
|
||||
},
|
||||
product: {
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tDAI',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
quoteName: 'DAI',
|
||||
__typename: 'Future',
|
||||
@@ -1294,9 +1309,10 @@ export const generatePositionsMarkets = () => {
|
||||
},
|
||||
product: {
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tDAI',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
quoteName: 'DAI',
|
||||
__typename: 'Future',
|
||||
@@ -1349,9 +1365,10 @@ export const generatePositionsMarkets = () => {
|
||||
},
|
||||
product: {
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-tEURO',
|
||||
symbol: 'tEURO',
|
||||
decimals: 5,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
quoteName: 'EURO',
|
||||
__typename: 'Future',
|
||||
@@ -1382,3 +1399,34 @@ export const generateMarket = (): MarketQuery => {
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const generateMarketData = (): MarketDataQuery => {
|
||||
return {
|
||||
marketsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
data: {
|
||||
market: {
|
||||
id: protoMarket.id,
|
||||
__typename: 'Market',
|
||||
},
|
||||
marketTradingMode:
|
||||
Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
staticMidPrice: '0',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '0',
|
||||
bestStaticOfferPrice: '0',
|
||||
indicativeVolume: '0',
|
||||
bestBidPrice: '0',
|
||||
bestOfferPrice: '0',
|
||||
markPrice: '17588787',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
__typename: 'MarketData',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ export const generatePartyBalance = (
|
||||
balance: '88474051',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
@@ -47,7 +47,7 @@ export const generatePartyBalance = (
|
||||
balance: '3412867',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
@@ -62,7 +62,7 @@ export const generatePartyBalance = (
|
||||
balance: '70007',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
id: 'dai-id',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
|
||||
@@ -19,7 +19,7 @@ NX_DEPLOY_URL=$DEPLOY_URL
|
||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
||||
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/stagnet3-network.json"
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_URL="https://api.n01.stagnet3.vega.xyz/graphql"
|
||||
NX_VEGA_URL="https://api.stagnet3.vega.xyz/graphql"
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 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_URL=https://api.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
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import type {
|
||||
AccountFragment,
|
||||
DealTicketMarketFragment,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type { MarketDealTicketAsset } from '@vegaprotocol/market-list';
|
||||
|
||||
const tDAI: DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'] =
|
||||
{
|
||||
__typename: 'Asset',
|
||||
id: '1',
|
||||
symbol: 'tDAI',
|
||||
name: 'TDAI',
|
||||
decimals: 2,
|
||||
};
|
||||
const tDAI: MarketDealTicketAsset = {
|
||||
__typename: 'Asset',
|
||||
id: '1',
|
||||
symbol: 'tDAI',
|
||||
name: 'TDAI',
|
||||
decimals: 2,
|
||||
};
|
||||
|
||||
const accounts: AccountFragment[] = [
|
||||
{
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import classNames from 'classnames';
|
||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import type {
|
||||
AccountFragment,
|
||||
DealTicketMarketFragment,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
|
||||
|
||||
interface DealTicketBalanceProps {
|
||||
settlementAsset: DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
accounts: AccountFragment[];
|
||||
isWalletConnected: boolean;
|
||||
className?: string;
|
||||
|
||||
@@ -2,16 +2,21 @@ import { useParams } from 'react-router-dom';
|
||||
import compact from 'lodash/compact';
|
||||
import {
|
||||
DealTicketManager,
|
||||
DealTicketContainer as Container,
|
||||
usePartyBalanceQuery,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { DealTicketSteps } from './deal-ticket-steps';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
import Baubles from './baubles-decor';
|
||||
import ConnectWallet from '../wallet-connector';
|
||||
import { useMemo } from 'react';
|
||||
import type {
|
||||
MarketDataUpdateFieldsFragment,
|
||||
MarketDealTicket,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { marketDealTicketProvider } from '@vegaprotocol/market-list';
|
||||
|
||||
const tempEmptyText = (
|
||||
<p>{t('Please select a market from the markets page')}</p>
|
||||
@@ -21,52 +26,64 @@ export const DealTicketContainer = () => {
|
||||
const { marketId } = useParams<{ marketId: string }>();
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
const { data: partyData, loading } = usePartyBalanceQuery({
|
||||
const { data: partyData } = usePartyBalanceQuery({
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
});
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId: marketId || '',
|
||||
}),
|
||||
[marketId]
|
||||
);
|
||||
const { data, loading } = useDataProvider<
|
||||
MarketDealTicket,
|
||||
MarketDataUpdateFieldsFragment
|
||||
>({
|
||||
dataProvider: marketDealTicketProvider,
|
||||
variables,
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
const accounts = compact(partyData?.party?.accountsConnection?.edges).map(
|
||||
(e) => e.node
|
||||
);
|
||||
|
||||
const loader = <Loader />;
|
||||
|
||||
const container = marketId ? (
|
||||
<Container marketId={marketId}>
|
||||
{(data) => {
|
||||
if (!data.market) {
|
||||
return null as unknown as JSX.Element;
|
||||
if (marketId && data) {
|
||||
const balance = (
|
||||
<DealTicketBalance
|
||||
className="mb-4"
|
||||
settlementAsset={
|
||||
data.tradableInstrument.instrument.product?.settlementAsset
|
||||
}
|
||||
accounts={accounts || []}
|
||||
isWalletConnected={!!pubKey}
|
||||
/>
|
||||
);
|
||||
|
||||
const accounts = compact(
|
||||
partyData?.party?.accountsConnection?.edges
|
||||
).map((e) => e.node);
|
||||
const balance = (
|
||||
<DealTicketBalance
|
||||
className="mb-4"
|
||||
settlementAsset={
|
||||
data.market.tradableInstrument.instrument.product?.settlementAsset
|
||||
}
|
||||
accounts={accounts || []}
|
||||
isWalletConnected={!!pubKey}
|
||||
/>
|
||||
);
|
||||
const container = (
|
||||
<DealTicketManager market={data}>
|
||||
{loading ? loader : balance}
|
||||
<DealTicketSteps market={data} />
|
||||
</DealTicketManager>
|
||||
);
|
||||
|
||||
return (
|
||||
<DealTicketManager market={data.market}>
|
||||
{loading ? loader : balance}
|
||||
<DealTicketSteps market={data.market} />
|
||||
</DealTicketManager>
|
||||
);
|
||||
}}
|
||||
</Container>
|
||||
return (
|
||||
<section className="flex p-4 md:p-6">
|
||||
<section className="w-full md:w-1/2 md:min-w-[500px]">
|
||||
{pubKey ? container : <ConnectWallet />}
|
||||
</section>
|
||||
<Baubles />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
return marketId ? (
|
||||
<Splash>
|
||||
<p>{t('Could not load market')}</p>
|
||||
</Splash>
|
||||
) : (
|
||||
tempEmptyText
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="flex p-4 md:p-6">
|
||||
<section className="w-full md:w-1/2 md:min-w-[500px]">
|
||||
{pubKey ? container : <ConnectWallet />}
|
||||
</section>
|
||||
<Baubles />
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import compact from 'lodash/compact';
|
||||
import { Stepper } from '../stepper';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
getDefaultOrder,
|
||||
useOrderCloseOut,
|
||||
@@ -24,7 +23,6 @@ import {
|
||||
toDecimal,
|
||||
removeDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
addDecimalsNormalizeNumber,
|
||||
addDecimal,
|
||||
formatNumber,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
@@ -42,9 +40,10 @@ import ReviewTrade from './review-trade';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { DealTicketSlippage } from './deal-ticket-slippage';
|
||||
import { useOrderValidation } from './use-order-validation';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
|
||||
interface DealTicketMarketProps {
|
||||
market: DealTicketMarketFragment;
|
||||
market: MarketDealTicket;
|
||||
}
|
||||
|
||||
export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
@@ -71,17 +70,10 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
const step = toDecimal(market.positionDecimalPlaces);
|
||||
const order = watch();
|
||||
const { pubKey } = useVegaWallet();
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: pubKey || '',
|
||||
});
|
||||
const { message: invalidText, isDisabled } = useOrderValidation({
|
||||
market,
|
||||
orderType: order.type,
|
||||
orderTimeInForce: order.timeInForce,
|
||||
order,
|
||||
fieldErrors: errors,
|
||||
estMargin,
|
||||
});
|
||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
||||
|
||||
@@ -130,11 +122,18 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
);
|
||||
return new BigNumber(market?.depth?.lastTrade?.price)
|
||||
.multipliedBy(multiplier)
|
||||
.toNumber();
|
||||
.toString();
|
||||
}
|
||||
return null;
|
||||
return undefined;
|
||||
}, [market?.depth?.lastTrade?.price, order.side, slippage]);
|
||||
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: pubKey || '',
|
||||
derivedPrice: price,
|
||||
});
|
||||
|
||||
const formattedPrice =
|
||||
price && addDecimalsFormatNumber(price, market.decimalPlaces);
|
||||
|
||||
@@ -158,7 +157,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
.decimalPlaces(2)
|
||||
.toString();
|
||||
|
||||
return `${addDecimalsNormalizeNumber(
|
||||
return `${addDecimalsFormatNumber(
|
||||
estMargin.totalFees,
|
||||
assetDecimals
|
||||
)} (${formatNumber(addDecimal(percentage, assetDecimals), 2)}%)`;
|
||||
|
||||
@@ -5,17 +5,17 @@ import {
|
||||
KeyValueTableRow,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
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 { gql, useQuery } from '@apollo/client';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { MarketExpires } from '@vegaprotocol/market-info';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
MarketTags,
|
||||
MarketTagsVariables,
|
||||
} from './__generated__/MarketTags';
|
||||
import { Schema } from '@vegaprotocol/types';
|
||||
import { MarketExpires } from '@vegaprotocol/market-info';
|
||||
|
||||
export const MARKET_TAGS_QUERY = gql`
|
||||
query MarketTags($marketId: ID!) {
|
||||
@@ -32,7 +32,7 @@ export const MARKET_TAGS_QUERY = gql`
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
market: DealTicketMarketFragment;
|
||||
market: MarketDealTicket;
|
||||
isDisabled: boolean;
|
||||
transactionStatus?: string;
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
|
||||
@@ -3,12 +3,15 @@ import { renderHook } from '@testing-library/react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
||||
import { MarketStateMapping, Schema } from '@vegaprotocol/types';
|
||||
import {
|
||||
MarketStateMapping,
|
||||
Schema as Types,
|
||||
Schema,
|
||||
} from '@vegaprotocol/types';
|
||||
import type { ValidationProps } from './use-order-validation';
|
||||
import { marketTranslations, useOrderValidation } from './use-order-validation';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
import * as DealTicket from '@vegaprotocol/deal-ticket';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
jest.mock('@vegaprotocol/wallet');
|
||||
jest.mock('@vegaprotocol/deal-ticket', () => {
|
||||
@@ -19,7 +22,7 @@ jest.mock('@vegaprotocol/deal-ticket', () => {
|
||||
});
|
||||
|
||||
type SettlementAsset =
|
||||
DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
const asset: SettlementAsset = {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id',
|
||||
@@ -28,7 +31,7 @@ const asset: SettlementAsset = {
|
||||
decimals: 2,
|
||||
};
|
||||
|
||||
const market: DealTicketMarketFragment = {
|
||||
const market: MarketDealTicket = {
|
||||
id: 'market-id',
|
||||
decimalPlaces: 2,
|
||||
positionDecimalPlaces: 1,
|
||||
@@ -40,10 +43,17 @@ const market: DealTicketMarketFragment = {
|
||||
__typename: 'Instrument',
|
||||
id: 'instrument-id',
|
||||
name: 'instrument-name',
|
||||
code: 'instriment-code',
|
||||
metadata: {
|
||||
tags: [],
|
||||
},
|
||||
product: {
|
||||
__typename: 'Future',
|
||||
quoteName: 'quote-name',
|
||||
settlementAsset: asset,
|
||||
dataSourceSpecForTradingTermination: {
|
||||
id: 'dataSource-id',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -63,6 +73,25 @@ const market: DealTicketMarketFragment = {
|
||||
liquidityFee: '3',
|
||||
},
|
||||
},
|
||||
data: {
|
||||
__typename: 'MarketData',
|
||||
bestBidPrice: '1605489971',
|
||||
bestOfferPrice: '1606823730',
|
||||
markPrice: '1606823730',
|
||||
trigger: Types.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||
staticMidPrice: '1606156850',
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
indicativeVolume: '0',
|
||||
indicativePrice: '0',
|
||||
bestStaticBidPrice: '1605489971',
|
||||
bestStaticOfferPrice: '1606823730',
|
||||
targetStake: '8561302732',
|
||||
suppliedStake: '727654170336',
|
||||
auctionStart: null,
|
||||
auctionEnd: null,
|
||||
market: { __typename: 'Market', id: 'market-id' },
|
||||
},
|
||||
marketTimestamps: {},
|
||||
};
|
||||
|
||||
const defaultWalletContext = {
|
||||
@@ -75,19 +104,19 @@ const defaultWalletContext = {
|
||||
connector: null,
|
||||
};
|
||||
|
||||
const order = {
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
marketId: 'market-id',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
size: '0.1',
|
||||
};
|
||||
|
||||
const defaultOrder = {
|
||||
market,
|
||||
market: { ...market },
|
||||
step: 0.1,
|
||||
orderType: Schema.OrderType.TYPE_MARKET,
|
||||
orderTimeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
estMargin: {
|
||||
margin: '0,000001',
|
||||
totalFees: '0,000006',
|
||||
fees: {
|
||||
makerFee: '0,000003',
|
||||
liquidityFee: '0,000002',
|
||||
infrastructureFee: '0,000001',
|
||||
},
|
||||
order: {
|
||||
...order,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -127,9 +156,9 @@ describe('useOrderValidation', () => {
|
||||
|
||||
it('Returns empty string when given valid data', () => {
|
||||
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
|
||||
balance: new BigNumber(0),
|
||||
margin: new BigNumber(100),
|
||||
asset,
|
||||
balance: '0',
|
||||
margin: '100',
|
||||
balanceError: false,
|
||||
});
|
||||
|
||||
const { result } = setup();
|
||||
@@ -142,9 +171,9 @@ describe('useOrderValidation', () => {
|
||||
|
||||
it('Returns an error message when no keypair found', () => {
|
||||
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
|
||||
balance: new BigNumber(0),
|
||||
margin: new BigNumber(100),
|
||||
asset,
|
||||
balance: '0',
|
||||
margin: '100',
|
||||
balanceError: false,
|
||||
});
|
||||
const { result } = setup(defaultOrder, { pubKey: null });
|
||||
expect(result.current).toStrictEqual({
|
||||
@@ -183,9 +212,10 @@ describe('useOrderValidation', () => {
|
||||
'Returns an error message for market state suspended or pending',
|
||||
({ state }) => {
|
||||
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
|
||||
balance: new BigNumber(0),
|
||||
margin: new BigNumber(100),
|
||||
asset,
|
||||
balance: '0',
|
||||
margin: '100',
|
||||
balanceError: false,
|
||||
// asset,
|
||||
});
|
||||
const { result } = setup({
|
||||
market: {
|
||||
@@ -193,8 +223,11 @@ describe('useOrderValidation', () => {
|
||||
state,
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
||||
},
|
||||
orderType: Schema.OrderType.TYPE_LIMIT,
|
||||
orderTimeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTT,
|
||||
order: {
|
||||
...order,
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTT,
|
||||
},
|
||||
});
|
||||
expect(result.current).toStrictEqual({
|
||||
isDisabled: false,
|
||||
@@ -216,7 +249,10 @@ describe('useOrderValidation', () => {
|
||||
({ tradingMode, errorMessage }) => {
|
||||
const { result } = setup({
|
||||
market: { ...defaultOrder.market, tradingMode },
|
||||
orderType: Schema.OrderType.TYPE_MARKET,
|
||||
order: {
|
||||
...order,
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
},
|
||||
});
|
||||
expect(result.current.isDisabled).toBeTruthy();
|
||||
expect(result.current.message).toBe(errorMessage);
|
||||
@@ -239,8 +275,11 @@ describe('useOrderValidation', () => {
|
||||
({ tradingMode, orderTimeInForce, errorMessage }) => {
|
||||
const { result } = setup({
|
||||
market: { ...defaultOrder.market, tradingMode },
|
||||
orderType: Schema.OrderType.TYPE_LIMIT,
|
||||
orderTimeInForce,
|
||||
order: {
|
||||
...order,
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
timeInForce: orderTimeInForce,
|
||||
},
|
||||
});
|
||||
expect(result.current).toStrictEqual({
|
||||
isDisabled: true,
|
||||
@@ -261,7 +300,10 @@ describe('useOrderValidation', () => {
|
||||
({ fieldName, errorType, section, errorMessage }) => {
|
||||
const { result } = setup({
|
||||
fieldErrors: { [fieldName]: { type: errorType } },
|
||||
orderType: Schema.OrderType.TYPE_LIMIT,
|
||||
order: {
|
||||
...order,
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
},
|
||||
});
|
||||
expect(result.current).toStrictEqual({
|
||||
isDisabled: true,
|
||||
@@ -300,9 +342,9 @@ describe('useOrderValidation', () => {
|
||||
|
||||
it('Returns an error message when the estimated margin is higher than collateral', async () => {
|
||||
const invalidatedMockValue = {
|
||||
balance: new BigNumber(100),
|
||||
margin: new BigNumber(200),
|
||||
asset,
|
||||
balance: '100',
|
||||
margin: '200',
|
||||
balanceError: true,
|
||||
};
|
||||
|
||||
jest
|
||||
@@ -315,9 +357,9 @@ describe('useOrderValidation', () => {
|
||||
|
||||
const testElement = (
|
||||
<DealTicket.MarginWarning
|
||||
margin={invalidatedMockValue.margin.toString()}
|
||||
balance={invalidatedMockValue.balance.toString()}
|
||||
asset={invalidatedMockValue.asset}
|
||||
margin={invalidatedMockValue.margin}
|
||||
balance={invalidatedMockValue.balance}
|
||||
asset={asset}
|
||||
/>
|
||||
);
|
||||
expect((result.current.message as React.ReactElement)?.props).toEqual(
|
||||
|
||||
@@ -6,10 +6,6 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { MarketStateMapping, Schema } from '@vegaprotocol/types';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import type {
|
||||
DealTicketMarketFragment,
|
||||
OrderMargin,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
MarketDataGrid,
|
||||
compileGridData,
|
||||
@@ -18,6 +14,7 @@ import {
|
||||
ERROR_SIZE_DECIMAL,
|
||||
useOrderMarginValidation,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
||||
|
||||
export const DEAL_TICKET_SECTION = {
|
||||
TYPE: 'sec-type',
|
||||
@@ -32,11 +29,9 @@ export const ERROR_EXPIRATION_IN_THE_PAST = 'ERROR_EXPIRATION_IN_THE_PAST';
|
||||
|
||||
export type ValidationProps = {
|
||||
step?: number;
|
||||
market: DealTicketMarketFragment;
|
||||
orderType: Schema.OrderType;
|
||||
orderTimeInForce: Schema.OrderTimeInForce;
|
||||
market: MarketDealTicket;
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
fieldErrors?: FieldErrors<OrderSubmissionBody['orderSubmission']>;
|
||||
estMargin: OrderMargin | null;
|
||||
};
|
||||
|
||||
export const marketTranslations = (marketState: Schema.MarketState) => {
|
||||
@@ -55,9 +50,7 @@ export type DealTicketSection =
|
||||
export const useOrderValidation = ({
|
||||
market,
|
||||
fieldErrors,
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
estMargin,
|
||||
order,
|
||||
}: ValidationProps): {
|
||||
message: ReactNode | string;
|
||||
isDisabled: boolean;
|
||||
@@ -65,7 +58,7 @@ export const useOrderValidation = ({
|
||||
} => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const minSize = toDecimal(market.positionDecimalPlaces);
|
||||
const isInvalidOrderMargin = useOrderMarginValidation({ market, estMargin });
|
||||
const isInvalidOrderMargin = useOrderMarginValidation({ market, order });
|
||||
|
||||
const fieldErrorChecking = useMemo<{
|
||||
message: ReactNode | string;
|
||||
@@ -91,7 +84,7 @@ export const useOrderValidation = ({
|
||||
|
||||
if (
|
||||
fieldErrors?.price?.type === 'required' &&
|
||||
orderType !== Schema.OrderType.TYPE_MARKET
|
||||
order.type !== Schema.OrderType.TYPE_MARKET
|
||||
) {
|
||||
return {
|
||||
isDisabled: true,
|
||||
@@ -102,7 +95,7 @@ export const useOrderValidation = ({
|
||||
|
||||
if (
|
||||
fieldErrors?.price?.type === 'min' &&
|
||||
orderType !== Schema.OrderType.TYPE_MARKET
|
||||
order.type !== Schema.OrderType.TYPE_MARKET
|
||||
) {
|
||||
return {
|
||||
isDisabled: true,
|
||||
@@ -151,7 +144,7 @@ export const useOrderValidation = ({
|
||||
fieldErrors?.price?.type,
|
||||
fieldErrors?.expiresAt?.type,
|
||||
fieldErrors?.expiresAt?.message,
|
||||
orderType,
|
||||
order.type,
|
||||
minSize,
|
||||
market.positionDecimalPlaces,
|
||||
]);
|
||||
@@ -210,7 +203,7 @@ export const useOrderValidation = ({
|
||||
}
|
||||
|
||||
if (isMarketInAuction(market)) {
|
||||
if (orderType === Schema.OrderType.TYPE_MARKET) {
|
||||
if (order.type === Schema.OrderType.TYPE_MARKET) {
|
||||
if (
|
||||
market.tradingMode ===
|
||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||
@@ -269,12 +262,12 @@ export const useOrderValidation = ({
|
||||
};
|
||||
}
|
||||
if (
|
||||
orderType === Schema.OrderType.TYPE_LIMIT &&
|
||||
order.type === Schema.OrderType.TYPE_LIMIT &&
|
||||
[
|
||||
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC,
|
||||
Schema.OrderTimeInForce.TIME_IN_FORCE_GFN,
|
||||
].includes(orderTimeInForce)
|
||||
].includes(order.timeInForce)
|
||||
) {
|
||||
if (
|
||||
market.tradingMode ===
|
||||
@@ -343,17 +336,14 @@ export const useOrderValidation = ({
|
||||
return fieldErrorChecking;
|
||||
}
|
||||
|
||||
if (
|
||||
isInvalidOrderMargin.balance.isGreaterThan(0) &&
|
||||
isInvalidOrderMargin.balance.isLessThan(isInvalidOrderMargin.margin)
|
||||
) {
|
||||
if (isInvalidOrderMargin.balanceError) {
|
||||
return {
|
||||
isDisabled: false,
|
||||
message: (
|
||||
<MarginWarning
|
||||
margin={isInvalidOrderMargin.margin.toString()}
|
||||
balance={isInvalidOrderMargin.balance.toString()}
|
||||
asset={isInvalidOrderMargin.asset}
|
||||
margin={isInvalidOrderMargin.margin}
|
||||
balance={isInvalidOrderMargin.balance}
|
||||
asset={market.tradableInstrument.instrument.product.settlementAsset}
|
||||
/>
|
||||
),
|
||||
section: DEAL_TICKET_SECTION.PRICE,
|
||||
@@ -386,8 +376,8 @@ export const useOrderValidation = ({
|
||||
market,
|
||||
fieldErrorChecking,
|
||||
isInvalidOrderMargin,
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
order.type,
|
||||
order.timeInForce,
|
||||
]);
|
||||
|
||||
return { message, isDisabled, section };
|
||||
|
||||
@@ -16,7 +16,7 @@ import { useAccountColumnDefinitions } from '.';
|
||||
|
||||
const AccountsManager = () => {
|
||||
const { partyId = '' } = useOutletContext<{ partyId: string }>();
|
||||
const { isOpen, symbol, setOpen } = useAssetDetailsDialogStore();
|
||||
const { isOpen, id, setOpen } = useAssetDetailsDialogStore();
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const dataRef = useRef<AccountFields[] | null>(null);
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
@@ -66,7 +66,7 @@ const AccountsManager = () => {
|
||||
/>
|
||||
</AsyncRenderer>
|
||||
<AssetDetailsDialog
|
||||
assetSymbol={symbol}
|
||||
assetId={id}
|
||||
open={isOpen}
|
||||
onChange={(open) => setOpen(open)}
|
||||
/>
|
||||
|
||||
@@ -15,14 +15,14 @@ const useAccountColumnDefinitions = () => {
|
||||
field: 'asset.symbol',
|
||||
headerClass: 'uppercase justify-start',
|
||||
cellClass: 'uppercase flex h-full items-center md:pl-4',
|
||||
cellRenderer: ({ value }: GroupCellRendererParams) =>
|
||||
cellRenderer: ({ value, data }: GroupCellRendererParams) =>
|
||||
value && value.length > 0 ? (
|
||||
<div className="md:pl-4 grid h-full items-center" title={value}>
|
||||
<div className="truncate min-w-0">
|
||||
<button
|
||||
className="hover:underline"
|
||||
onClick={() => {
|
||||
open(value);
|
||||
open(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{value}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
|
||||
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n00.stagnet3.vega.xyz/websocket
|
||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
|
||||
# App flags
|
||||
|
||||
@@ -18,22 +18,21 @@ context('Home Page', function () {
|
||||
const statTitles = {
|
||||
0: 'Status',
|
||||
1: 'Height',
|
||||
2: 'Validating nodes',
|
||||
3: 'Uptime',
|
||||
4: 'Total nodes',
|
||||
5: 'Inactive nodes',
|
||||
6: 'Total staked',
|
||||
7: 'Backlog',
|
||||
8: 'Trades / second',
|
||||
9: 'Orders / block',
|
||||
10: 'Orders / second',
|
||||
11: 'Transactions / block',
|
||||
12: 'Block time',
|
||||
13: 'Time',
|
||||
14: 'App',
|
||||
15: 'Tendermint',
|
||||
16: 'Up since',
|
||||
17: 'Chain ID',
|
||||
2: 'Uptime',
|
||||
3: 'Total nodes',
|
||||
4: 'Inactive nodes',
|
||||
5: 'Total staked',
|
||||
6: 'Backlog',
|
||||
7: 'Trades / second',
|
||||
8: 'Orders / block',
|
||||
9: 'Orders / second',
|
||||
10: 'Transactions / block',
|
||||
11: 'Block time',
|
||||
12: 'Time',
|
||||
13: 'App',
|
||||
14: 'Tendermint',
|
||||
15: 'Up since',
|
||||
16: 'Chain ID',
|
||||
};
|
||||
|
||||
cy.get('[data-testid="stats-title"]')
|
||||
@@ -41,41 +40,40 @@ context('Home Page', function () {
|
||||
cy.wrap($list).should('have.text', statTitles[index]);
|
||||
})
|
||||
.then(($list) => {
|
||||
cy.wrap($list).should('have.length', 18);
|
||||
cy.wrap($list).should('have.length', 17);
|
||||
});
|
||||
|
||||
cy.get(statsValue).eq(0).should('have.text', 'CONNECTED');
|
||||
cy.get(statsValue).eq(1).should('not.be.empty');
|
||||
cy.get(statsValue).eq(2).should('have.text', '2');
|
||||
cy.get(statsValue)
|
||||
.eq(3)
|
||||
.eq(2)
|
||||
.invoke('text')
|
||||
.should('match', /\d+d \d+h \d+m \d+s/i);
|
||||
cy.get(statsValue).eq(4).should('have.text', '2');
|
||||
cy.get(statsValue).eq(5).should('have.text', '0');
|
||||
cy.get(statsValue).eq(3).should('have.text', '2');
|
||||
cy.get(statsValue).eq(4).should('have.text', '0');
|
||||
cy.get(statsValue)
|
||||
.eq(6)
|
||||
.eq(5)
|
||||
.invoke('text')
|
||||
.should('match', /\d+\.\d\d(?!\d)/i);
|
||||
cy.get(statsValue).eq(6).should('have.text', '0');
|
||||
cy.get(statsValue).eq(7).should('have.text', '0');
|
||||
cy.get(statsValue).eq(8).should('have.text', '0');
|
||||
cy.get(statsValue).eq(9).should('have.text', '0');
|
||||
cy.get(statsValue).eq(10).should('have.text', '0');
|
||||
cy.get(statsValue).eq(10).should('not.be.empty');
|
||||
cy.get(statsValue).eq(11).should('not.be.empty');
|
||||
cy.get(statsValue).eq(12).should('not.be.empty');
|
||||
cy.get(statsValue).eq(13).should('not.be.empty');
|
||||
if (Cypress.env('NIGHTLY_RUN') != true) {
|
||||
cy.get(statsValue)
|
||||
.eq(14)
|
||||
.eq(13)
|
||||
.invoke('text')
|
||||
.should('match', /v\d+\.\d+\.\d+/i);
|
||||
}
|
||||
cy.get(statsValue)
|
||||
.eq(15)
|
||||
.eq(14)
|
||||
.invoke('text')
|
||||
.should('match', /\d+\.\d+\.\d+/i);
|
||||
cy.get(statsValue).eq(15).should('not.be.empty');
|
||||
cy.get(statsValue).eq(16).should('not.be.empty');
|
||||
cy.get(statsValue).eq(17).should('not.be.empty');
|
||||
});
|
||||
|
||||
it('Block height should be updating', function () {
|
||||
|
||||
@@ -148,7 +148,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
|
||||
const parameterName = network_parameter[0];
|
||||
const parameterValue = network_parameter[1];
|
||||
if (this.networkParameterFormat.fiveDecimal.includes(parameterName)) {
|
||||
cy.convert_number_to_four_decimal(parameterValue)
|
||||
cy.convert_number_to_max_four_decimal(parameterValue)
|
||||
.add_commas_to_number_if_large_enough()
|
||||
.then((parameterValueFormatted) => {
|
||||
cy.get(tableRows)
|
||||
@@ -179,7 +179,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
|
||||
if (
|
||||
this.networkParameterFormat.eighteenDecimal.includes(parameterName)
|
||||
) {
|
||||
cy.convert_number_to_eighteen_decimal(parameterValue)
|
||||
cy.convert_number_to_max_eighteen_decimal(parameterValue)
|
||||
.add_commas_to_number_if_large_enough()
|
||||
.then((parameterValueFormatted) => {
|
||||
cy.get(tableRows)
|
||||
@@ -212,7 +212,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
|
||||
const jsonFields = '.hljs';
|
||||
const sideMenuBackground = '.absolute';
|
||||
|
||||
// Engage dark mode if not allready set
|
||||
// Engage dark mode if not already set
|
||||
cy.get(sideMenuBackground)
|
||||
.should('have.css', 'background-color')
|
||||
.then((background_color) => {
|
||||
|
||||
@@ -68,12 +68,19 @@ Cypress.Commands.add(
|
||||
}
|
||||
);
|
||||
|
||||
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_max_eighteen_decimal', (number) => {
|
||||
// this will take a number like this : 700000000000000000001
|
||||
// and convert it to a number like this: 700.000000000000000001
|
||||
const value = BigNumber(number / 1000000000000000000).toString();
|
||||
return parseFloat(value).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 18,
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('convert_number_to_four_decimal', (number) => {
|
||||
return parseFloat(number).toFixed(4);
|
||||
Cypress.Commands.add('convert_number_to_max_four_decimal', (number) => {
|
||||
return parseFloat(number).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 4,
|
||||
});
|
||||
});
|
||||
|
||||
+5
-3
@@ -1,12 +1,14 @@
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
|
||||
NX_TENDERMINT_URL=https://tm.be.stagnet3.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet3.vega.xyz/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_ENV=STAGNET3
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_BLOCK_EXPLORER=
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
# App flags
|
||||
NX_EXPLORER_ASSETS=1
|
||||
|
||||
@@ -5,6 +5,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
# App flags
|
||||
NX_EXPLORER_ASSETS=1
|
||||
|
||||
@@ -7,3 +7,4 @@ NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https:
|
||||
NX_VEGA_ENV=DEVNET
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
@@ -1,9 +1,10 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://be.explorer.vega.xyz
|
||||
NX_TENDERMINT_URL=https://be.explorer.vega.xyz/websocket
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.explorer.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_ENV=MAINNET
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest/
|
||||
NX_ETHERSCAN_URL=https://etherscan.io
|
||||
|
||||
@@ -8,3 +8,4 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_TENDERMINT_URL=https://tm.n01.sandbox.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.sandbox.vega.xyz/websocket
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
@@ -7,6 +7,7 @@ NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
NX_TENDERMINT_URL=https://tm.be.stagnet1.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet1.vega.xyz/websocket
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
|
||||
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet3.vega.xyz/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_ENV=STAGNET3
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_BLOCK_EXPLORER=https://blockexplorer.n01.stagnet3.vega.xyz/rest
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||
@@ -1,12 +1,13 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.testnet.vega.xyz/websocket
|
||||
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.testnet.vega.xyz/
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_NETWORKS={}
|
||||
NX_VEGA_NETWORKS={}
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
@@ -5,3 +5,4 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26607/websocket
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_BLOCK_EXPLORER=
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
@@ -66,6 +66,14 @@
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"generate-types": {
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.62.1/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
|
||||
]
|
||||
}
|
||||
},
|
||||
"build-netlify": {
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
|
||||
@@ -26,7 +26,7 @@ const AssetLink = ({ id, ...props }: AssetLinkProps) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Link className="underline" {...props} to={`/${Routes.MARKETS}#${id}`}>
|
||||
<Link className="underline" {...props} to={`/${Routes.ASSETS}#${id}`}>
|
||||
{label}
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DATA_SOURCES } from '../../../config';
|
||||
|
||||
export enum EthExplorerLinkTypes {
|
||||
block = 'block',
|
||||
address = 'address',
|
||||
tx = 'tx',
|
||||
}
|
||||
|
||||
export type EthExplorerLinkProps = Partial<typeof HTMLAnchorElement> & {
|
||||
id: string;
|
||||
type: EthExplorerLinkTypes;
|
||||
};
|
||||
|
||||
export const EthExplorerLink = ({
|
||||
id,
|
||||
type,
|
||||
...props
|
||||
}: EthExplorerLinkProps) => {
|
||||
const link = `${DATA_SOURCES.ethExplorerUrl}/${type}/${id}`;
|
||||
return (
|
||||
<a
|
||||
className="underline external"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
{...props}
|
||||
href={link}
|
||||
>
|
||||
{id}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
@@ -19,7 +19,7 @@ const MarketLink = ({ id, ...props }: MarketLinkProps) => {
|
||||
variables: { id },
|
||||
});
|
||||
|
||||
let label: string = id;
|
||||
let label = id;
|
||||
|
||||
if (data?.market?.tradableInstrument.instrument.name) {
|
||||
label = data.market.tradableInstrument.instrument.name;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface TimeProps {
|
||||
date: string | null | undefined;
|
||||
}
|
||||
|
||||
export const Time = ({ date }: TimeProps) => {
|
||||
if (!date) {
|
||||
return <>{t('Date unknown')}</>;
|
||||
}
|
||||
const timeFormatted = new Date(date).toLocaleString();
|
||||
|
||||
return <span>{timeFormatted}</span>;
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ExplorerNodeVoteQueryVariables = Types.Exact<{
|
||||
id: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ExplorerNodeVoteQuery = { __typename?: 'Query', withdrawal?: { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: string, withdrawnTimestamp?: string | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string } } | null, deposit?: { __typename?: 'Deposit', id: string, status: Types.DepositStatus, createdTimestamp: string, creditedTimestamp?: string | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string } } | null };
|
||||
|
||||
|
||||
export const ExplorerNodeVoteDocument = gql`
|
||||
query ExplorerNodeVote($id: ID!) {
|
||||
withdrawal(id: $id) {
|
||||
id
|
||||
status
|
||||
createdTimestamp
|
||||
withdrawnTimestamp
|
||||
txHash
|
||||
asset {
|
||||
id
|
||||
name
|
||||
decimals
|
||||
}
|
||||
party {
|
||||
id
|
||||
}
|
||||
}
|
||||
deposit(id: $id) {
|
||||
id
|
||||
status
|
||||
createdTimestamp
|
||||
creditedTimestamp
|
||||
txHash
|
||||
asset {
|
||||
id
|
||||
name
|
||||
decimals
|
||||
}
|
||||
party {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useExplorerNodeVoteQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useExplorerNodeVoteQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useExplorerNodeVoteQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useExplorerNodeVoteQuery({
|
||||
* variables: {
|
||||
* id: // value for 'id'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useExplorerNodeVoteQuery(baseOptions: Apollo.QueryHookOptions<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>(ExplorerNodeVoteDocument, options);
|
||||
}
|
||||
export function useExplorerNodeVoteLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>(ExplorerNodeVoteDocument, options);
|
||||
}
|
||||
export type ExplorerNodeVoteQueryHookResult = ReturnType<typeof useExplorerNodeVoteQuery>;
|
||||
export type ExplorerNodeVoteLazyQueryHookResult = ReturnType<typeof useExplorerNodeVoteLazyQuery>;
|
||||
export type ExplorerNodeVoteQueryResult = Apollo.QueryResult<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>;
|
||||
@@ -0,0 +1,139 @@
|
||||
import { TxDetailsChainMultisigThreshold } from './tx-multisig-threshold';
|
||||
import { TxDetailsChainMultisigSigner } from './tx-multisig-signer';
|
||||
import { TxDetailsChainEventBuiltinDeposit } from './tx-builtin-deposit';
|
||||
import { TxDetailsChainEventStakeDeposit } from './tx-stake-deposit';
|
||||
import { TxDetailsChainEventStakeRemove } from './tx-stake-remove';
|
||||
import { TxDetailsChainEventStakeTotalSupply } from './tx-stake-totalsupply';
|
||||
import { TxDetailsChainEventBuiltinWithdrawal } from './tx-builtin-withdrawal';
|
||||
import { TxDetailsChainEventErc20AssetList } from './tx-erc20-asset-list';
|
||||
import { TxDetailsChainEventErc20AssetLimitsUpdated } from './tx-erc20-asset-limits-updated';
|
||||
import { TxDetailsChainEventErc20BridgePause } from './tx-erc20-bridge-pause';
|
||||
import { TxDetailsChainEventDeposit } from './tx-erc20-deposit';
|
||||
|
||||
import isUndefined from 'lodash/isUndefined';
|
||||
|
||||
import type { BlockExplorerTransactionResult } from '../../../../routes/types/block-explorer-response';
|
||||
|
||||
interface ChainEventProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the chain event to determine which details view to show. The list of types
|
||||
* comes from the Swagger document that Block Explorer provides, which can be viewed at
|
||||
* https://docs.vega.xyz/testnet/api/rest/explorer/block-explorer-list-transactions
|
||||
*
|
||||
* This component should have one entry per chain event type, however if there isn't
|
||||
* a bespoke view for an event the tx-details-shared will still render some basic
|
||||
* overview and the transaction viewer will still let people view the raw TX.
|
||||
*
|
||||
* Most chain events simply render more table rows for the header table
|
||||
*
|
||||
* @returns React.JSXElement
|
||||
*/
|
||||
export const ChainEvent = ({ txData }: ChainEventProps) => {
|
||||
const e = txData?.command.chainEvent;
|
||||
if (!e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Builtin Asset events
|
||||
if (e.builtin) {
|
||||
if (e.builtin.deposit) {
|
||||
return <TxDetailsChainEventBuiltinDeposit deposit={e.builtin.deposit} />;
|
||||
}
|
||||
|
||||
if (e.builtin?.withdrawal) {
|
||||
return (
|
||||
<TxDetailsChainEventBuiltinWithdrawal
|
||||
withdrawal={e.builtin?.withdrawal}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ERC20 asset events
|
||||
if (e.erc20) {
|
||||
if (e.erc20.deposit) {
|
||||
return <TxDetailsChainEventDeposit deposit={e.erc20.deposit} />;
|
||||
}
|
||||
|
||||
if (e.erc20.withdrawal) {
|
||||
return (
|
||||
<TxDetailsChainEventBuiltinWithdrawal withdrawal={e.erc20.withdrawal} />
|
||||
);
|
||||
}
|
||||
|
||||
if (e.erc20.assetList) {
|
||||
return (
|
||||
<TxDetailsChainEventErc20AssetList assetList={e.erc20.assetList} />
|
||||
);
|
||||
}
|
||||
|
||||
if (e.erc20.assetLimitsUpdated) {
|
||||
return (
|
||||
<TxDetailsChainEventErc20AssetLimitsUpdated
|
||||
assetLimitsUpdated={e.erc20.assetLimitsUpdated}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const bridgeStopped = e.erc20.bridgeStopped;
|
||||
const bridgeResumed = e.erc20.bridgeResumed;
|
||||
if (!isUndefined(bridgeStopped) || !isUndefined(bridgeResumed)) {
|
||||
const isPaused = bridgeStopped === false || bridgeResumed === true;
|
||||
return <TxDetailsChainEventErc20BridgePause isPaused={isPaused} />;
|
||||
}
|
||||
}
|
||||
|
||||
// ERC20 multisig events
|
||||
if (e.erc20Multisig) {
|
||||
if (e.erc20Multisig.thresholdSet) {
|
||||
return (
|
||||
<TxDetailsChainMultisigThreshold
|
||||
thresholdSet={e.erc20Multisig.thresholdSet}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (e.erc20Multisig.signerAdded) {
|
||||
return (
|
||||
<TxDetailsChainMultisigSigner signer={e.erc20Multisig.signerAdded} />
|
||||
);
|
||||
}
|
||||
|
||||
if (e.erc20Multisig.signerRemoved) {
|
||||
return (
|
||||
<TxDetailsChainMultisigSigner signer={e.erc20Multisig.signerRemoved} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Staking events
|
||||
if (e.stakingEvent) {
|
||||
if (e.stakingEvent.stakeDeposited) {
|
||||
return (
|
||||
<TxDetailsChainEventStakeDeposit
|
||||
deposit={e.stakingEvent.stakeDeposited}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (e.stakingEvent.stakeRemoved) {
|
||||
return (
|
||||
<TxDetailsChainEventStakeRemove remove={e.stakingEvent.stakeRemoved} />
|
||||
);
|
||||
}
|
||||
|
||||
if (e.stakingEvent.totalSupply) {
|
||||
return (
|
||||
<TxDetailsChainEventStakeTotalSupply
|
||||
update={e.stakingEvent.totalSupply}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If we hit this return, tx-shared-details should give a basic overview
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Returns a reasonably formatted time from unix timestamp of block height
|
||||
*
|
||||
* @param date String or null date
|
||||
* @returns String date in locale time
|
||||
*/
|
||||
export function getBlockTime(date?: string) {
|
||||
if (!date) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
const timeInSeconds = parseInt(date, 10);
|
||||
const timeInMs = timeInSeconds * 1000;
|
||||
|
||||
return new Date(timeInMs).toLocaleString();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { AssetLink, PartyLink } from '../../../links';
|
||||
|
||||
interface TxDetailsChainEventBuiltinDepositProps {
|
||||
deposit: components['schemas']['vegaBuiltinAssetDeposit'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone deposited some of a builtin asset. Builtin assets
|
||||
* have no value outside the Vega chain and should appear only
|
||||
* on Test networks.
|
||||
*/
|
||||
export const TxDetailsChainEventBuiltinDeposit = ({
|
||||
deposit,
|
||||
}: TxDetailsChainEventBuiltinDepositProps) => {
|
||||
if (!deposit) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain Event type')}</TableCell>
|
||||
<TableCell>{t('Built-in asset deposit')}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={deposit.partyId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={deposit.vegaAssetId || ''} /> ({t('built in asset')})
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>{deposit.amount}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { AssetLink, PartyLink } from '../../../links';
|
||||
|
||||
interface TxDetailsChainEventBuiltinDepositProps {
|
||||
withdrawal: components['schemas']['vegaBuiltinAssetWithdrawal'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone withdrew some of a builtin asset. Builtin assets
|
||||
* have no value outside the Vega chain and should appear only
|
||||
* on Test networks, so someone withdrawing it is pretty rare
|
||||
*/
|
||||
export const TxDetailsChainEventBuiltinWithdrawal = ({
|
||||
withdrawal,
|
||||
}: TxDetailsChainEventBuiltinDepositProps) => {
|
||||
if (!withdrawal) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain Event type')}</TableCell>
|
||||
<TableCell>{t('Built-in asset withdrawal')}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={withdrawal.partyId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={withdrawal.vegaAssetId || ''} /> ({t('built in asset')}
|
||||
)
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>{withdrawal.amount}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { AssetLink } from '../../../links';
|
||||
|
||||
interface TxDetailsChainEventErc20AssetDelistProps {
|
||||
assetDelist: components['schemas']['vegaERC20AssetDelist'];
|
||||
}
|
||||
|
||||
/**
|
||||
* An ERC20 asset was removed from the bridge,
|
||||
* The link should link to an asset that doesn't exist. Which feels odd
|
||||
* but I think is better than having no link - in case something
|
||||
* weird is up and it still exists
|
||||
*/
|
||||
export const TxDetailsChainEventErc20AssetDelist = ({
|
||||
assetDelist,
|
||||
}: TxDetailsChainEventErc20AssetDelistProps) => {
|
||||
if (!assetDelist) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain event type')}</TableCell>
|
||||
<TableCell>{t('ERC20 asset removed')}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Removed Vega asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={assetDelist.vegaAssetId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { AssetLink } from '../../../links';
|
||||
import {
|
||||
EthExplorerLink,
|
||||
EthExplorerLinkTypes,
|
||||
} from '../../../links/eth-explorer-link/eth-explorer-link';
|
||||
|
||||
interface TxDetailsChainEventErc20AssetLimitsUpdatedProps {
|
||||
assetLimitsUpdated: components['schemas']['vegaERC20AssetLimitsUpdated'];
|
||||
}
|
||||
|
||||
/**
|
||||
* An ERC20 asset was had its limits changed. The limits are in place
|
||||
* at first to prevent users depositing large sums while the network
|
||||
* is still new, as a safety measure.
|
||||
* - Lifetime limit is how much can be withdrawn of this asset to a
|
||||
* single ethereum address
|
||||
* - Withdraw threshold is the size of a withdrawal that will incur
|
||||
* a delay in processing. The delay is set by a network parameter
|
||||
*/
|
||||
export const TxDetailsChainEventErc20AssetLimitsUpdated = ({
|
||||
assetLimitsUpdated,
|
||||
}: TxDetailsChainEventErc20AssetLimitsUpdatedProps) => {
|
||||
if (!assetLimitsUpdated) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain event type')}</TableCell>
|
||||
<TableCell>{t('ERC20 asset limits updated')}</TableCell>
|
||||
</TableRow>
|
||||
|
||||
{assetLimitsUpdated.sourceEthereumAddress ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('ERC20 asset')}</TableCell>
|
||||
<TableCell>
|
||||
<EthExplorerLink
|
||||
id={assetLimitsUpdated.sourceEthereumAddress}
|
||||
type={EthExplorerLinkTypes.address}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Vega asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={assetLimitsUpdated.vegaAssetId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Total lifetime limit')}</TableCell>
|
||||
<TableCell>{assetLimitsUpdated.lifetimeLimits}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Asset withdrawal threshold')}</TableCell>
|
||||
<TableCell>{assetLimitsUpdated.withdrawThreshold}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { AssetLink } from '../../../links';
|
||||
import {
|
||||
EthExplorerLink,
|
||||
EthExplorerLinkTypes,
|
||||
} from '../../../links/eth-explorer-link/eth-explorer-link';
|
||||
|
||||
interface TxDetailsChainEventErc20AssetListProps {
|
||||
assetList: components['schemas']['vegaERC20AssetList'];
|
||||
}
|
||||
|
||||
/**
|
||||
* An ERC20 asset was proposed and then enacted on the bridge,
|
||||
* a Asset List event will be emitted that tells the core to
|
||||
* create the asset. That's this event - it's very basic
|
||||
*/
|
||||
export const TxDetailsChainEventErc20AssetList = ({
|
||||
assetList,
|
||||
}: TxDetailsChainEventErc20AssetListProps) => {
|
||||
if (!assetList) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain event type')}</TableCell>
|
||||
<TableCell>{t('ERC20 asset added')}</TableCell>
|
||||
</TableRow>
|
||||
{assetList.assetSource ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Source')}</TableCell>
|
||||
<TableCell>
|
||||
<EthExplorerLink
|
||||
id={assetList.assetSource}
|
||||
type={EthExplorerLinkTypes.address}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Added Vega asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={assetList.vegaAssetId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
|
||||
interface TxDetailsChainEventErc20BridgePauseProps {
|
||||
isPaused: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The bridge was either paused or unpaused, preventing withdrawals
|
||||
* or deposits from being enacted. This will only happen if the
|
||||
* validators have signed a multisig bundle requiring it to happen
|
||||
*/
|
||||
export const TxDetailsChainEventErc20BridgePause = ({
|
||||
isPaused,
|
||||
}: TxDetailsChainEventErc20BridgePauseProps) => {
|
||||
const event = isPaused ? 'pause' : 'unpaused';
|
||||
|
||||
return (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain event type')}</TableCell>
|
||||
<TableCell>{t(`ERC20 bridge ${event}`)}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { AssetLink, PartyLink } from '../../../links';
|
||||
import {
|
||||
EthExplorerLink,
|
||||
EthExplorerLinkTypes,
|
||||
} from '../../../links/eth-explorer-link/eth-explorer-link';
|
||||
|
||||
interface TxDetailsChainEventProps {
|
||||
deposit: components['schemas']['vegaERC20Deposit'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone deposited some erc20
|
||||
*/
|
||||
export const TxDetailsChainEventDeposit = ({
|
||||
deposit,
|
||||
}: TxDetailsChainEventProps) => {
|
||||
if (!deposit) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain event type')}</TableCell>
|
||||
<TableCell>{t('ERC20 deposit')}</TableCell>
|
||||
</TableRow>
|
||||
{deposit.sourceEthereumAddress ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Source')}</TableCell>
|
||||
<TableCell>
|
||||
<EthExplorerLink
|
||||
id={deposit.sourceEthereumAddress}
|
||||
type={EthExplorerLinkTypes.address}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={deposit.targetPartyId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={deposit.vegaAssetId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>{deposit.amount}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { AssetLink } from '../../../links';
|
||||
import {
|
||||
EthExplorerLink,
|
||||
EthExplorerLinkTypes,
|
||||
} from '../../../links/eth-explorer-link/eth-explorer-link';
|
||||
|
||||
interface TxDetailsChainEventWithdrawalProps {
|
||||
withdrawal: components['schemas']['vegaERC20Withdrawal'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone deposited some erc20
|
||||
*/
|
||||
export const TxDetailsChainEventWithdrawal = ({
|
||||
withdrawal,
|
||||
}: TxDetailsChainEventWithdrawalProps) => {
|
||||
if (!withdrawal) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain event type')}</TableCell>
|
||||
<TableCell>{t('ERC20 withdrawal')}</TableCell>
|
||||
</TableRow>
|
||||
|
||||
{withdrawal.targetEthereumAddress ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<EthExplorerLink
|
||||
id={withdrawal.targetEthereumAddress}
|
||||
type={EthExplorerLinkTypes.address}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={withdrawal.vegaAssetId || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { getBlockTime } from './lib/get-block-time';
|
||||
|
||||
interface TxDetailsChainMultisigSignerProps {
|
||||
signer:
|
||||
| components['schemas']['vegaERC20SignerAdded']
|
||||
| components['schemas']['vegaERC20SignerRemoved'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone updated multsig signer set, either removing or adding someone
|
||||
*/
|
||||
export const TxDetailsChainMultisigSigner = ({
|
||||
signer,
|
||||
}: TxDetailsChainMultisigSignerProps) => {
|
||||
if (!signer) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const blockTime = getBlockTime(signer.blockTime);
|
||||
const target =
|
||||
'newSigner' in signer
|
||||
? signer.newSigner
|
||||
: 'oldSigner' in signer
|
||||
? signer.oldSigner
|
||||
: '';
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain Event type')}</TableCell>
|
||||
{'newSigner' in signer
|
||||
? t('Add ERC20 bridge multisig signer')
|
||||
: t('Remove ERC20 bridge multsig signer')}
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>
|
||||
{'newSigner' in signer ? t('Add signer') : t('Remove signer')}
|
||||
</TableCell>
|
||||
<TableCell>{target}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Signer change at')}</TableCell>
|
||||
<TableCell>{blockTime}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import isNumber from 'lodash/isNumber';
|
||||
|
||||
/**
|
||||
* Returns a reasonably formatted time from unix timestamp of block height
|
||||
*
|
||||
* @param date String or null date
|
||||
* @returns String date in locale time
|
||||
*/
|
||||
function getBlockTime(date?: string) {
|
||||
if (!date) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
const timeInSeconds = parseInt(date, 10);
|
||||
const timeInMs = timeInSeconds * 1000;
|
||||
|
||||
return new Date(timeInMs).toLocaleString();
|
||||
}
|
||||
|
||||
interface TxDetailsChainMultisigThresholdProps {
|
||||
thresholdSet: components['schemas']['vegaERC20MultiSigEvent']['thresholdSet'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone updated multsig threshold value on the smart contract.
|
||||
* It's a percentage, with 1000 being 100% and 0 being 0%.
|
||||
*/
|
||||
export const TxDetailsChainMultisigThreshold = ({
|
||||
thresholdSet,
|
||||
}: TxDetailsChainMultisigThresholdProps) => {
|
||||
if (!thresholdSet) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const blockTime = getBlockTime(thresholdSet.blockTime);
|
||||
const threshold = isNumber(thresholdSet.newThreshold)
|
||||
? thresholdSet.newThreshold / 10
|
||||
: '-';
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain Event type')}</TableCell>
|
||||
<TableCell>{t('ERC20 multisig threshold set')}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Threshold')}</TableCell>
|
||||
<TableCell>{threshold}%</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Threshold set from')}</TableCell>
|
||||
<TableCell>{blockTime}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { PartyLink } from '../../../links';
|
||||
|
||||
interface TxDetailsChainEventStakeDepositProps {
|
||||
deposit: components['schemas']['vegaStakeDeposited'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone addedd some stake for a particular party
|
||||
* This should link to the Governance asset, but doesn't
|
||||
* as that would require checking the Network Paramters
|
||||
* Ethereum address should also be a link to an ETH block explorer
|
||||
*/
|
||||
export const TxDetailsChainEventStakeDeposit = ({
|
||||
deposit,
|
||||
}: TxDetailsChainEventStakeDepositProps) => {
|
||||
if (!deposit) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain Event type')}</TableCell>
|
||||
<TableCell>{t('Stake deposited')}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Source')}</TableCell>
|
||||
<TableCell>{deposit.ethereumAddress || ''}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={deposit.vegaPublicKey || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>{deposit.amount}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Deposited at')}</TableCell>
|
||||
<TableCell>{deposit.amount}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import { PartyLink } from '../../../links';
|
||||
|
||||
interface TxDetailsChainEventStakeRemoveProps {
|
||||
remove: components['schemas']['vegaStakeRemoved'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Someone addedd some stake for a particular party
|
||||
* This should link to the Governance asset, but doesn't
|
||||
* as that would require checking the Network Parameters
|
||||
* Ethereum address should also be a link to an ETH block explorer
|
||||
*/
|
||||
export const TxDetailsChainEventStakeRemove = ({
|
||||
remove,
|
||||
}: TxDetailsChainEventStakeRemoveProps) => {
|
||||
if (!remove) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain Event type')}</TableCell>
|
||||
<TableCell>{t('Stake removed')}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Source')}</TableCell>
|
||||
<TableCell>{remove.ethereumAddress || ''}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={remove.vegaPublicKey || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>{remove.amount}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Deposited at')}</TableCell>
|
||||
<TableCell>{remove.blockTime}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
import { formatNumber, t, toBigNum } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import type { components } from '../../../../../types/explorer';
|
||||
import {
|
||||
EthExplorerLink,
|
||||
EthExplorerLinkTypes,
|
||||
} from '../../../links/eth-explorer-link/eth-explorer-link';
|
||||
|
||||
interface TxDetailsChainEventStakeTotalSupplyProps {
|
||||
update: components['schemas']['vegaStakeTotalSupply'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Chain event set the total supply of the governance asset
|
||||
* Happens whenever the total supply changes, or when the chain
|
||||
* restarts and the total supply is detected.
|
||||
*/
|
||||
export const TxDetailsChainEventStakeTotalSupply = ({
|
||||
update,
|
||||
}: TxDetailsChainEventStakeTotalSupplyProps) => {
|
||||
if (!update) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
let totalSupply = update.totalSupply || '';
|
||||
if (totalSupply.length > 0) {
|
||||
totalSupply = formatNumber(toBigNum(totalSupply, 18));
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Chain Event type')}</TableCell>
|
||||
<TableCell>{t('Stake total supply update')}</TableCell>
|
||||
</TableRow>
|
||||
|
||||
{update.tokenAddress ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Source')}</TableCell>
|
||||
<TableCell>
|
||||
<EthExplorerLink
|
||||
id={update.tokenAddress}
|
||||
type={EthExplorerLinkTypes.address}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : null}
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Total supply')}</TableCell>
|
||||
<TableCell>{totalSupply}</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
query ExplorerNodeVote($id: ID!) {
|
||||
withdrawal(id: $id) {
|
||||
id
|
||||
status
|
||||
createdTimestamp
|
||||
withdrawnTimestamp
|
||||
txHash
|
||||
asset {
|
||||
id
|
||||
name
|
||||
decimals
|
||||
}
|
||||
party {
|
||||
id
|
||||
}
|
||||
}
|
||||
deposit(id: $id) {
|
||||
id
|
||||
status
|
||||
createdTimestamp
|
||||
creditedTimestamp
|
||||
txHash
|
||||
asset {
|
||||
id
|
||||
name
|
||||
decimals
|
||||
}
|
||||
party {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { TableRow, TableCell } from '../../../table';
|
||||
import { BlockLink, PartyLink } from '../../../links/';
|
||||
@@ -6,6 +5,7 @@ import { TimeAgo } from '../../../time-ago';
|
||||
|
||||
import type { BlockExplorerTransactionResult } from '../../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../../routes/blocks/tendermint-blocks-response';
|
||||
import { Time } from '../../../time';
|
||||
|
||||
interface TxDetailsSharedProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
@@ -29,11 +29,6 @@ export const TxDetailsShared = ({
|
||||
|
||||
const time: string = blockData?.result.block.header.time || '';
|
||||
const height: string = blockData?.result.block.header.height || '';
|
||||
let timeFormatted = '';
|
||||
|
||||
if (time) {
|
||||
timeFormatted = new Date(time).toLocaleString();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -56,7 +51,9 @@ export const TxDetailsShared = ({
|
||||
<TableCell>
|
||||
{time ? (
|
||||
<div>
|
||||
<span className="mr-5">{timeFormatted} </span>
|
||||
<span className="mr-5">
|
||||
<Time date={time} />
|
||||
</span>
|
||||
<span>
|
||||
<TimeAgo date={time} />
|
||||
</span>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import React from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
BlockExplorerTransactionResult,
|
||||
BatchMarketInstructions,
|
||||
} from '../../../routes/types/block-explorer-response';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableWithTbody, TableRow, TableCell } from '../../table';
|
||||
@@ -26,16 +22,17 @@ export const TxDetailsBatch = ({
|
||||
pubKey,
|
||||
blockData,
|
||||
}: TxDetailsBatchProps) => {
|
||||
if (!txData) {
|
||||
if (!txData || !txData.command.batchMarketInstructions) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const cmd = txData.command as BatchMarketInstructions;
|
||||
|
||||
const batchSubmissions = cmd.batchMarketInstructions.submissions.length;
|
||||
const batchAmendments = cmd.batchMarketInstructions.amendments.length;
|
||||
const batchCancellations = cmd.batchMarketInstructions.cancellations.length;
|
||||
const batchTotal = batchSubmissions + batchAmendments + batchCancellations;
|
||||
const countSubmissions =
|
||||
txData.command.batchMarketInstructions.submissions?.length || 0;
|
||||
const countAmendments =
|
||||
txData.command.batchMarketInstructions.amendments?.length || 0;
|
||||
const countCancellations =
|
||||
txData.command.batchMarketInstructions.cancellations?.length || 0;
|
||||
const countTotal = countSubmissions + countAmendments + countCancellations;
|
||||
|
||||
return (
|
||||
<TableWithTbody>
|
||||
@@ -43,7 +40,7 @@ export const TxDetailsBatch = ({
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Batch size')}</TableCell>
|
||||
<TableCell>
|
||||
<span>{batchTotal}</span>
|
||||
<span>{countTotal}</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
@@ -51,7 +48,7 @@ export const TxDetailsBatch = ({
|
||||
<span className="ml-5">{t('Submissions')}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span>{batchSubmissions}</span>
|
||||
<span>{countSubmissions}</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
@@ -59,7 +56,7 @@ export const TxDetailsBatch = ({
|
||||
<span className="ml-5">{t('Amendments')}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span>{batchAmendments}</span>
|
||||
<span>{countAmendments}</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
@@ -67,7 +64,7 @@ export const TxDetailsBatch = ({
|
||||
<span className="ml-5">{t('Cancellations')}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span>{batchCancellations}</span>
|
||||
<span>{countCancellations}</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableWithTbody>
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import React from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
BlockExplorerTransactionResult,
|
||||
ChainEvent,
|
||||
} from '../../../routes/types/block-explorer-response';
|
||||
import { AssetLink, PartyLink } from '../../links';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||
import { TableWithTbody } from '../../table';
|
||||
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { ChainEvent } from './chain-events';
|
||||
|
||||
interface TxDetailsChainEventProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
@@ -20,10 +17,10 @@ interface TxDetailsChainEventProps {
|
||||
* Multiple events will relay the same data, from each validator, so that the
|
||||
* deposit/withdrawal can be verified independently.
|
||||
*
|
||||
* Design considerations so far:
|
||||
* - The ethereum address should be a link to an Ethereum explorer
|
||||
* - Sender and recipient are shown because they are easy
|
||||
* - Amount is not shown because there is no formatter by asset component
|
||||
* There are so many chain events that the specific components have been broken
|
||||
* out in to individual components. `getChainEventComponent` determines which
|
||||
* is the most appropriate based on the transaction shape. See that function
|
||||
* for more information.
|
||||
*/
|
||||
export const TxDetailsChainEvent = ({
|
||||
txData,
|
||||
@@ -33,32 +30,11 @@ export const TxDetailsChainEvent = ({
|
||||
if (!txData) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
const cmd = txData.command as ChainEvent;
|
||||
const assetId = cmd.chainEvent.erc20.deposit.vegaAssetId;
|
||||
const sender = cmd.chainEvent.erc20.deposit.sourceEthereumAddress;
|
||||
const recipient = cmd.chainEvent.erc20.deposit.targetPartyId;
|
||||
|
||||
return (
|
||||
<TableWithTbody>
|
||||
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Asset')}</TableCell>
|
||||
<TableCell>
|
||||
<AssetLink id={assetId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Sender')}</TableCell>
|
||||
<TableCell>
|
||||
<span>{sender}</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Recipient')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={recipient} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<ChainEvent txData={txData} />
|
||||
</TableWithTbody>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { DATA_SOURCES } from '../../../config';
|
||||
import { t, useFetch } from '@vegaprotocol/react-helpers';
|
||||
import { TxDetailsOrder } from './tx-order';
|
||||
@@ -10,11 +10,10 @@ import { TxDetailsGeneric } from './tx-generic';
|
||||
import { TxDetailsBatch } from './tx-batch';
|
||||
import { TxDetailsChainEvent } from './tx-chain-event';
|
||||
import { TxContent } from '../../../routes/txs/id/tx-content';
|
||||
|
||||
type resultOrNull = BlockExplorerTransactionResult | undefined;
|
||||
import { TxDetailsNodeVote } from './tx-node-vote';
|
||||
|
||||
interface TxDetailsWrapperProps {
|
||||
txData: resultOrNull;
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
pubKey: string | undefined;
|
||||
height: string;
|
||||
}
|
||||
@@ -27,7 +26,8 @@ export const TxDetailsWrapper = ({
|
||||
const {
|
||||
state: { data: blockData },
|
||||
} = useFetch<TendermintBlocksResponse>(
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${height}`
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${height}`,
|
||||
{ cache: 'force-cache' }
|
||||
);
|
||||
|
||||
const child = useMemo(() => getTransactionComponent(txData), [txData]);
|
||||
@@ -61,7 +61,7 @@ export const TxDetailsWrapper = ({
|
||||
* @param txData
|
||||
* @returns JSX.Element
|
||||
*/
|
||||
function getTransactionComponent(txData: resultOrNull) {
|
||||
function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
|
||||
if (!txData) {
|
||||
return TxDetailsGeneric;
|
||||
}
|
||||
@@ -77,6 +77,8 @@ function getTransactionComponent(txData: resultOrNull) {
|
||||
return TxDetailsBatch;
|
||||
case 'Chain Event':
|
||||
return TxDetailsChainEvent;
|
||||
case 'Node Vote':
|
||||
return TxDetailsNodeVote;
|
||||
default:
|
||||
return TxDetailsGeneric;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import React from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
BlockExplorerTransactionResult,
|
||||
ValidatorHeartbeat,
|
||||
} from '../../../routes/types/block-explorer-response';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import { BlockLink, NodeLink } from '../../links/';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
@@ -56,11 +52,12 @@ export const TxDetailsHeartbeat = ({
|
||||
pubKey,
|
||||
blockData,
|
||||
}: TxDetailsHeartbeatProps) => {
|
||||
if (!txData) {
|
||||
if (!txData || !txData.command.validatorHeartbeat) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const cmd = txData.command as ValidatorHeartbeat;
|
||||
const nodeId = txData.command.validatorHeartbeat.nodeId || '';
|
||||
const blockHeight = txData.command.blockHeight || '';
|
||||
|
||||
return (
|
||||
<TableWithTbody>
|
||||
@@ -68,18 +65,18 @@ export const TxDetailsHeartbeat = ({
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Node')}</TableCell>
|
||||
<TableCell>
|
||||
<NodeLink id={cmd.validatorHeartbeat.nodeId} />
|
||||
<NodeLink id={nodeId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Signed block height')}</TableCell>
|
||||
<TableCell>
|
||||
<BlockLink height={cmd.blockHeight} />
|
||||
<BlockLink height={blockHeight} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Freshness (lower is better)')}</TableCell>
|
||||
<TableCell>{scoreFreshness(txData.block, cmd.blockHeight)}</TableCell>
|
||||
<TableCell>{scoreFreshness(txData.block, blockHeight)}</TableCell>
|
||||
</TableRow>
|
||||
</TableWithTbody>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import React from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
AmendLiquidityProvisionOrder,
|
||||
BlockExplorerTransactionResult,
|
||||
} from '../../../routes/types/block-explorer-response';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import { MarketLink } from '../../links/';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
@@ -29,7 +25,7 @@ export const TxDetailsLPAmend = ({
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const cmd = txData.command as AmendLiquidityProvisionOrder;
|
||||
const marketId = txData.command.liquidityProvisionAmendment?.marketId || '';
|
||||
|
||||
return (
|
||||
<TableWithTbody>
|
||||
@@ -37,7 +33,7 @@ export const TxDetailsLPAmend = ({
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Market')}</TableCell>
|
||||
<TableCell>
|
||||
<MarketLink id={cmd.liquidityProvisionAmendment.marketId} />
|
||||
<MarketLink id={marketId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableWithTbody>
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||
import type { ExplorerNodeVoteQueryResult } from './__generated___/node-vote';
|
||||
import { useExplorerNodeVoteQuery } from './__generated___/node-vote';
|
||||
import { PartyLink } from '../../links';
|
||||
import { Time } from '../../time';
|
||||
|
||||
interface TxDetailsNodeVoteProps {
|
||||
txData: BlockExplorerTransactionResult | undefined;
|
||||
pubKey: string | undefined;
|
||||
blockData: TendermintBlocksResponse | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is not yet a custom component for a transaction, just display
|
||||
* the basic details. This allows someone to view the decoded transaction.
|
||||
*/
|
||||
export const TxDetailsNodeVote = ({
|
||||
txData,
|
||||
pubKey,
|
||||
blockData,
|
||||
}: TxDetailsNodeVoteProps) => {
|
||||
const id = txData?.command.nodeVote?.reference || '';
|
||||
|
||||
const { data } = useExplorerNodeVoteQuery({
|
||||
variables: {
|
||||
id,
|
||||
},
|
||||
// Required as one of these queries will needlessly error
|
||||
errorPolicy: 'ignore',
|
||||
});
|
||||
|
||||
if (!txData) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<TableWithTbody>
|
||||
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||
{data && !!data.deposit
|
||||
? TxDetailsNodeVoteDeposit({ deposit: data })
|
||||
: data && !!data.withdrawal
|
||||
? TxDetailsNodeVoteWithdrawal({ withdrawal: data })
|
||||
: null}
|
||||
</TableWithTbody>
|
||||
);
|
||||
};
|
||||
|
||||
interface TxDetailsNodeVoteDepositProps {
|
||||
deposit: ExplorerNodeVoteQueryResult['data'];
|
||||
}
|
||||
|
||||
export function TxDetailsNodeVoteDeposit({
|
||||
deposit,
|
||||
}: TxDetailsNodeVoteDepositProps) {
|
||||
if (!deposit) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Witnessed Event type')}</TableCell>
|
||||
{deposit?.deposit?.txHash ? (
|
||||
<TableCell>{t('ERC20 deposit')}</TableCell>
|
||||
) : (
|
||||
<TableCell>{t('Built-in asset deposit')}</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('To party')}:</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={deposit?.deposit?.party?.id || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Credited on')}:</TableCell>
|
||||
<TableCell>
|
||||
<Time date={deposit?.deposit?.creditedTimestamp} />
|
||||
</TableCell>
|
||||
{deposit?.deposit?.txHash ? (
|
||||
<TxHash hash={deposit?.deposit?.txHash} />
|
||||
) : null}
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
interface TxDetailsNodeVoteWithdrawalProps {
|
||||
withdrawal: ExplorerNodeVoteQueryResult['data'];
|
||||
}
|
||||
|
||||
export function TxDetailsNodeVoteWithdrawal({
|
||||
withdrawal,
|
||||
}: TxDetailsNodeVoteWithdrawalProps) {
|
||||
if (!withdrawal) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Witnessed Event type')}</TableCell>
|
||||
{withdrawal?.withdrawal?.txHash ? (
|
||||
<TableCell>{t('ERC20 withdrawal')}</TableCell>
|
||||
) : (
|
||||
<TableCell>{t('Built-in asset withdrawal')}</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('From party')}:</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={withdrawal?.deposit?.party?.id || ''} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Withdrawn on')}:</TableCell>
|
||||
<TableCell>
|
||||
<Time date={withdrawal?.withdrawal?.withdrawnTimestamp} />
|
||||
</TableCell>
|
||||
{withdrawal?.withdrawal?.txHash ? (
|
||||
<TxHash hash={withdrawal?.withdrawal?.txHash} />
|
||||
) : null}
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
interface TxDetailsEthTxHashProps {
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export function TxHash({ hash }: TxDetailsEthTxHashProps) {
|
||||
if (!hash) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>Ethereum TX:</TableCell>
|
||||
<TableCell>{hash}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
import React from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
BlockExplorerTransactionResult,
|
||||
SubmitOrder,
|
||||
} from '../../../routes/types/block-explorer-response';
|
||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||
import { MarketLink } from '../../links/';
|
||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||
@@ -26,11 +22,10 @@ export const TxDetailsOrder = ({
|
||||
pubKey,
|
||||
blockData,
|
||||
}: TxDetailsOrderProps) => {
|
||||
if (!txData) {
|
||||
if (!txData || !txData.command.orderSubmission) {
|
||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||
}
|
||||
|
||||
const cmd = txData.command as SubmitOrder;
|
||||
const marketId = txData.command.orderSubmission.marketId || '-';
|
||||
|
||||
return (
|
||||
<TableWithTbody>
|
||||
@@ -38,7 +33,7 @@ export const TxDetailsOrder = ({
|
||||
<TableRow modifier="bordered">
|
||||
<TableCell>{t('Market')}</TableCell>
|
||||
<TableCell>
|
||||
<MarketLink id={cmd.orderSubmission.marketId} />
|
||||
<MarketLink id={marketId} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableWithTbody>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { components } from '../../../types/explorer';
|
||||
|
||||
interface TxOrderTypeProps {
|
||||
orderType: string;
|
||||
chainEvent?: components['schemas']['v1ChainEvent'];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@@ -32,13 +36,73 @@ const displayString: StringMap = {
|
||||
ValidatorHeartbeat: 'Validator Heartbeat',
|
||||
};
|
||||
|
||||
export const TxOrderType = ({ orderType }: TxOrderTypeProps) => {
|
||||
/**
|
||||
* Given a chain event, will try to provide a more useful label
|
||||
* @param chainEvent
|
||||
* @returns
|
||||
*/
|
||||
export function getLabelForChainEvent(
|
||||
chainEvent: components['schemas']['v1ChainEvent']
|
||||
): string {
|
||||
if (chainEvent.builtin) {
|
||||
if (chainEvent.builtin.deposit) {
|
||||
return t('Built-in deposit');
|
||||
} else if (chainEvent.builtin.withdrawal) {
|
||||
return t('Built-in withdraw');
|
||||
}
|
||||
return t('Built-in event');
|
||||
} else if (chainEvent.erc20) {
|
||||
if (chainEvent.erc20.assetDelist) {
|
||||
return t('ERC20 delist');
|
||||
} else if (chainEvent.erc20.assetList) {
|
||||
return t('ERC20 list');
|
||||
} else if (chainEvent.erc20.bridgeResumed) {
|
||||
return t('Bridge resume');
|
||||
} else if (chainEvent.erc20.bridgeStopped) {
|
||||
return t('Bridge pause');
|
||||
} else if (chainEvent.erc20.deposit) {
|
||||
return t('ERC20 deposit');
|
||||
} else if (chainEvent.erc20.withdrawal) {
|
||||
return t('ERC20 withdraw');
|
||||
}
|
||||
return t('ERC20 event');
|
||||
} else if (chainEvent.stakingEvent) {
|
||||
if (chainEvent.stakingEvent.stakeDeposited) {
|
||||
return t('Stake add');
|
||||
} else if (chainEvent.stakingEvent.stakeRemoved) {
|
||||
return t('Stake remove');
|
||||
}
|
||||
return t('Staking event');
|
||||
} else if (chainEvent.erc20Multisig) {
|
||||
if (chainEvent.erc20Multisig.signerAdded) {
|
||||
return t('Signer adde');
|
||||
} else if (chainEvent.erc20Multisig.signerRemoved) {
|
||||
return t('Signer remove');
|
||||
} else if (chainEvent.erc20Multisig.thresholdSet) {
|
||||
return t('Signer threshold');
|
||||
}
|
||||
return t('Multisig update');
|
||||
}
|
||||
return t('Chain Event');
|
||||
}
|
||||
|
||||
export const TxOrderType = ({ orderType, chainEvent }: TxOrderTypeProps) => {
|
||||
let type = displayString[orderType] || orderType;
|
||||
|
||||
let colours = 'text-white dark:text-white bg-zinc-800 dark:bg-zinc-800';
|
||||
|
||||
// This will get unwieldy and should probably produce a different colour of tag
|
||||
if (type === 'Chain Event' && !!chainEvent) {
|
||||
type = getLabelForChainEvent(chainEvent);
|
||||
colours =
|
||||
'text-white dark-text-white bg-vega-pink-dark dark:bg-vega-pink-dark';
|
||||
}
|
||||
return (
|
||||
<div
|
||||
data-testid="tx-type"
|
||||
className="text-sm rounded-md leading-none px-2 py-2 inline-block text-white dark:text-white bg-zinc-800 dark:bg-zinc-800 "
|
||||
className={`text-sm rounded-md leading-none px-2 py-2 inline-block ${colours}`}
|
||||
>
|
||||
{displayString[orderType] || orderType}
|
||||
{type}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ export const TxsInfiniteListItem = ({
|
||||
type,
|
||||
block,
|
||||
index,
|
||||
command,
|
||||
}: Partial<BlockExplorerTransactionResult>) => {
|
||||
if (
|
||||
!hash ||
|
||||
@@ -54,7 +55,7 @@ export const TxsInfiniteListItem = ({
|
||||
/>
|
||||
</div>
|
||||
<div className="text-sm col-span-5 xl:col-span-2 leading-none flex items-center">
|
||||
<TxOrderType orderType={type} />
|
||||
<TxOrderType orderType={type} chainEvent={command?.chainEvent} />
|
||||
</div>
|
||||
<div
|
||||
className="text-sm col-span-3 xl:col-span-1 leading-none flex items-center"
|
||||
|
||||
@@ -26,7 +26,7 @@ const generateTxs = (number: number): BlockExplorerTransactionResult[] => {
|
||||
expiresAt: '1664966445481288736',
|
||||
type: 'TYPE_LIMIT',
|
||||
reference: 'traderbot',
|
||||
peggedOrder: null,
|
||||
peggedOrder: undefined,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -93,7 +93,7 @@ export const TxsInfiniteList = ({
|
||||
{({ onItemsRendered, ref }) => (
|
||||
<List
|
||||
className="List"
|
||||
height={595}
|
||||
height={995}
|
||||
itemCount={itemCount}
|
||||
itemSize={isStacked ? 134 : 72}
|
||||
onItemsRendered={onItemsRendered}
|
||||
|
||||
@@ -42,7 +42,9 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
|
||||
</TableRow>
|
||||
</thead>
|
||||
<tbody>
|
||||
{decodedBlockData.map(({ TxHash, PubKey, Type }) => {
|
||||
{decodedBlockData.map(({ TxHash, PubKey, Type, Command }) => {
|
||||
const chainEvent = JSON.parse(Command || '');
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
modifier="bordered"
|
||||
@@ -66,7 +68,7 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell modifier="bordered">
|
||||
<TxOrderType orderType={Type} />
|
||||
<TxOrderType orderType={Type} chainEvent={chainEvent} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
||||
@@ -16,6 +16,7 @@ export const ENV = {
|
||||
blockExplorerUrl: windowOrDefault('NX_BLOCK_EXPLORER'),
|
||||
tendermintUrl: windowOrDefault('NX_TENDERMINT_URL'),
|
||||
tendermintWebsocketUrl: windowOrDefault('NX_TENDERMINT_WEBSOCKET_URL'),
|
||||
ethExplorerUrl: windowOrDefault('NX_ETHERSCAN_URL'),
|
||||
},
|
||||
flags: {
|
||||
assets: truthy.includes(windowOrDefault('NX_EXPLORER_ASSETS')),
|
||||
|
||||
+27
-21
@@ -3,41 +3,47 @@ import { Schema as Types } from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type AssetsFieldsFragment = { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string }, infrastructureFeeAccount?: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null } | null };
|
||||
|
||||
export type ExplorerAssetsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ExplorerAssetsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string }, infrastructureFeeAccount?: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null } | null } } | null> | null } | null };
|
||||
|
||||
|
||||
export const AssetsFieldsFragmentDoc = gql`
|
||||
fragment AssetsFields on Asset {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
}
|
||||
infrastructureFeeAccount {
|
||||
type
|
||||
balance
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const ExplorerAssetsDocument = gql`
|
||||
query ExplorerAssets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
}
|
||||
infrastructureFeeAccount {
|
||||
type
|
||||
balance
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
...AssetsFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
${AssetsFieldsFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useExplorerAssetsQuery__
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
fragment AssetsFields on Asset {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
}
|
||||
|
||||
infrastructureFeeAccount {
|
||||
type
|
||||
balance
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query ExplorerAssets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
}
|
||||
infrastructureFeeAccount {
|
||||
type
|
||||
balance
|
||||
market {
|
||||
id
|
||||
}
|
||||
}
|
||||
...AssetsFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { getNodes, t } from '@vegaprotocol/react-helpers';
|
||||
import React from 'react';
|
||||
import { RouteTitle } from '../../components/route-title';
|
||||
import { SubHeading } from '../../components/sub-heading';
|
||||
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||
import { useExplorerAssetsQuery } from './__generated__/assets';
|
||||
import type { AssetsFieldsFragment } from './__generated__/assets';
|
||||
|
||||
const Assets = () => {
|
||||
const { data } = useExplorerAssetsQuery();
|
||||
|
||||
const assets = data?.assetsConnection?.edges?.map((n) => {
|
||||
return n?.node;
|
||||
});
|
||||
const assets = getNodes<AssetsFieldsFragment>(data?.assetsConnection);
|
||||
|
||||
if (!assets || assets.length === 0) {
|
||||
return <section></section>;
|
||||
|
||||
@@ -44,7 +44,7 @@ const Blocks = () => {
|
||||
refetch,
|
||||
} = useFetch<TendermintBlockchainResponse>(
|
||||
`${DATA_SOURCES.tendermintUrl}/blockchain`,
|
||||
undefined,
|
||||
{ cache: 'no-cache' },
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ const Block = () => {
|
||||
const {
|
||||
state: { data: blockData, loading, error },
|
||||
} = useFetch<TendermintBlocksResponse>(
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${block}`
|
||||
`${DATA_SOURCES.tendermintUrl}/block?height=${block}`,
|
||||
{ cache: 'force-cache' }
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
+18
-16
@@ -1,3 +1,4 @@
|
||||
import type { components } from '../../../types/explorer';
|
||||
import type { UnknownObject } from '../../components/nested-data-list';
|
||||
|
||||
export interface BlockExplorerTransactionResult {
|
||||
@@ -8,13 +9,7 @@ export interface BlockExplorerTransactionResult {
|
||||
type: string;
|
||||
code: number;
|
||||
cursor: string;
|
||||
command:
|
||||
| ValidatorHeartbeat
|
||||
| SubmitOrder
|
||||
| StateVariableProposal
|
||||
| AmendLiquidityProvisionOrder
|
||||
| BatchMarketInstructions
|
||||
| ChainEvent;
|
||||
command: components['schemas']['v1InputData'];
|
||||
}
|
||||
|
||||
export interface BlockExplorerTransactions {
|
||||
@@ -103,16 +98,23 @@ export interface BatchCancellationInstruction {
|
||||
export interface ChainEvent {
|
||||
blockHeight: string;
|
||||
nonce: string;
|
||||
chainEvent: {
|
||||
erc20: {
|
||||
deposit: ERC20Deposit;
|
||||
};
|
||||
chainEvent: components['schemas']['v1ChainEvent'];
|
||||
}
|
||||
|
||||
export interface ChainEventErc20Multisig {
|
||||
erc20Multisig: {
|
||||
block: string;
|
||||
index: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ERC20Deposit {
|
||||
vegaAssetId: string;
|
||||
sourceEthereumAddress: string;
|
||||
targetPartyId: string;
|
||||
amount: string;
|
||||
export interface ChainEventErc20Deposit {
|
||||
erc20: {
|
||||
deposit: {
|
||||
vegaAssetId: string;
|
||||
sourceEthereumAddress: string;
|
||||
targetPartyId: string;
|
||||
amount: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
+1563
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"lib": ["es5", "es6", "dom", "dom.iterable"]
|
||||
},
|
||||
"exclude": ["./src/types/explorer.d.ts"],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 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_URL=https://api.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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 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_URL=https://api.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
|
||||
|
||||
+60
-4
@@ -8,8 +8,17 @@ import type {
|
||||
} from 'ag-grid-community';
|
||||
import 'ag-grid-community/dist/styles/ag-grid.css';
|
||||
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
|
||||
import { t, addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
||||
import { Icon, AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
t,
|
||||
addDecimalsFormatNumber,
|
||||
formatNumberPercentage,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
Icon,
|
||||
AsyncRenderer,
|
||||
TooltipCellComponent,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import type { Market } from '@vegaprotocol/liquidity';
|
||||
import {
|
||||
useMarketsLiquidity,
|
||||
@@ -50,9 +59,11 @@ export const MarketList = () => {
|
||||
sortable: true,
|
||||
unSortIcon: true,
|
||||
cellClass: ['flex', 'flex-col', 'justify-center'],
|
||||
tooltipComponent: TooltipCellComponent,
|
||||
}}
|
||||
getRowId={getRowId}
|
||||
isRowClickable
|
||||
tooltipShowDelay={500}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Market (futures)')}
|
||||
@@ -78,6 +89,7 @@ export const MarketList = () => {
|
||||
}}
|
||||
minWidth={100}
|
||||
flex="1"
|
||||
headerTooltip={t('The market name and settlement asset')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
@@ -90,10 +102,11 @@ export const MarketList = () => {
|
||||
.decimals
|
||||
)} (${displayChange(data.volumeChange)})`
|
||||
}
|
||||
headerTooltip={t('The trade volume over the last 24h')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('Committed bond/stake')}
|
||||
headerName={t('Committed bond')}
|
||||
field="liquidityCommitted"
|
||||
valueFormatter={({ value, data }: ValueFormatterParams) =>
|
||||
formatWithAsset(
|
||||
@@ -101,6 +114,47 @@ export const MarketList = () => {
|
||||
data.tradableInstrument.instrument.product.settlementAsset
|
||||
)
|
||||
}
|
||||
headerTooltip={t(
|
||||
'The amount of funds allocated to provide liquidity'
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('Target stake')}
|
||||
field="target"
|
||||
valueFormatter={({ value, data }: ValueFormatterParams) =>
|
||||
formatWithAsset(
|
||||
value,
|
||||
data.tradableInstrument.instrument.product.settlementAsset
|
||||
)
|
||||
}
|
||||
headerTooltip={t(
|
||||
'The ideal committed liquidity to operate the market. If total commitment currently below this level then LPs can set the fee level with new commitment.'
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('% Target stake met')}
|
||||
valueFormatter={({ data }: ValueFormatterParams) => {
|
||||
const roundedPercentage =
|
||||
parseInt(
|
||||
(data.liquidityCommitted / parseFloat(data.target)).toFixed(0)
|
||||
) * 100;
|
||||
const display = Number.isNaN(roundedPercentage)
|
||||
? 'N/A'
|
||||
: formatNumberPercentage(toBigNum(roundedPercentage, 2));
|
||||
return display;
|
||||
}}
|
||||
headerTooltip={t('% Target stake met')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('Fee levels')}
|
||||
field="fees"
|
||||
valueFormatter={({ value, data }: ValueFormatterParams) =>
|
||||
`${value.factors.liquidityFee}%`
|
||||
}
|
||||
headerTooltip={t('Fee level for this market')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
@@ -117,6 +171,9 @@ export const MarketList = () => {
|
||||
<Status trigger={data.data?.trigger} tradingMode={value} />
|
||||
);
|
||||
}}
|
||||
headerTooltip={t(
|
||||
'The current market status - those below the target stake mark are most in need of liquidity'
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
@@ -154,7 +211,6 @@ export const MarketList = () => {
|
||||
sortable={false}
|
||||
cellStyle={{ overflow: 'unset' }}
|
||||
/>
|
||||
<AgGridColumn headerName={t('Est. return / APY')} field="apy" />
|
||||
</Grid>
|
||||
|
||||
<HealthDialog
|
||||
|
||||
+38
-5
@@ -11,6 +11,7 @@ import type {
|
||||
import { formatWithAsset } from '@vegaprotocol/liquidity';
|
||||
|
||||
import { Grid } from '../../grid';
|
||||
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
const formatToHours = ({ value }: { value?: string | null }) => {
|
||||
if (!value) {
|
||||
@@ -39,11 +40,14 @@ export const LPProvidersGrid = ({
|
||||
return (
|
||||
<Grid
|
||||
rowData={liquidityProviders}
|
||||
tooltipShowDelay={500}
|
||||
defaultColDef={{
|
||||
resizable: true,
|
||||
sortable: true,
|
||||
unSortIcon: true,
|
||||
cellClass: ['flex', 'flex-col', 'justify-center'],
|
||||
tooltipComponent: TooltipCellComponent,
|
||||
minWidth: 100,
|
||||
}}
|
||||
getRowId={getRowId}
|
||||
rowHeight={92}
|
||||
@@ -53,11 +57,13 @@ export const LPProvidersGrid = ({
|
||||
field="party.id"
|
||||
flex="1"
|
||||
minWidth={100}
|
||||
headerTooltip={t('Liquidity providers')}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Time in market')}
|
||||
headerName={t('Duration')}
|
||||
valueFormatter={formatToHours}
|
||||
field="createdAt"
|
||||
headerTooltip={t('Time in market')}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Equity-like share')}
|
||||
@@ -67,23 +73,50 @@ export const LPProvidersGrid = ({
|
||||
? `${parseFloat(parseFloat(value).toFixed(2)) * 100}%`
|
||||
: '';
|
||||
}}
|
||||
headerTooltip={t(
|
||||
'The share of the markets liquidity held - the earlier you commit liquidity the greater % fees you earn'
|
||||
)}
|
||||
minWidth={140}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('committed bond/stake')}
|
||||
headerName={t('committed bond')}
|
||||
field="commitmentAmount"
|
||||
valueFormatter={({ value }: { value?: string | null }) =>
|
||||
value ? formatWithAsset(value, settlementAsset) : '0'
|
||||
}
|
||||
headerTooltip={t('The amount of funds allocated to provide liquidity')}
|
||||
minWidth={140}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Margin Req.')}
|
||||
field="margin"
|
||||
headerTooltip={t(
|
||||
'Margin required for arising positions based on liquidity commitment'
|
||||
)}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('24h Fees')}
|
||||
field="fees"
|
||||
headerTooltip={t(
|
||||
'Total fees earned by the liquidity provider in the last 24 hours'
|
||||
)}
|
||||
/>
|
||||
<AgGridColumn headerName={t('Margin Req.')} field="margin" />
|
||||
<AgGridColumn headerName={t('24h Fees')} field="fees" />
|
||||
<AgGridColumn
|
||||
headerName={t('Fee level')}
|
||||
valueFormatter={({ value }: { value?: string | null }) => `${value}%`}
|
||||
field="fee"
|
||||
headerTooltip={t(
|
||||
"The market's liquidity fee, or the percentage of a trade's value which is collected from the price taker for every trade"
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn headerName={t('APY')} field="apy" />
|
||||
<AgGridColumn
|
||||
headerName={t('APY')}
|
||||
field="apy"
|
||||
headerTooltip={t(
|
||||
'An annualised estimate based on the total liquidity provision fees and maker fees collected by liquidity providers, the maximum margin needed and maximum commitment (bond) over the course of 7 epochs'
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import { Lozenge, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import {
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
AuctionTriggerMapping,
|
||||
Schema,
|
||||
} from '@vegaprotocol/types';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
|
||||
import { Indicator } from '../indicator';
|
||||
|
||||
@@ -33,17 +34,46 @@ export const Status = ({
|
||||
return MarketTradingModeMapping[tradingMode];
|
||||
};
|
||||
|
||||
const status = getStatus();
|
||||
const tooltipDescription = t(getTooltipDescription(status));
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('inline-flex whitespace-normal', {
|
||||
'text-base': size === 'large',
|
||||
'text-sm': size === 'small',
|
||||
})}
|
||||
>
|
||||
<Lozenge className="border border-greys-light-300 bg-greys-light-100 flex items-center">
|
||||
<Indicator status={tradingMode} />
|
||||
{getStatus()}
|
||||
</Lozenge>
|
||||
<div>
|
||||
<Tooltip description={tooltipDescription}>
|
||||
<div
|
||||
className={classNames('inline-flex whitespace-normal', {
|
||||
'text-base': size === 'large',
|
||||
'text-sm': size === 'small',
|
||||
})}
|
||||
>
|
||||
<Lozenge className="border border-greys-light-300 bg-greys-light-100 flex items-center">
|
||||
<Indicator status={tradingMode} />
|
||||
{status}
|
||||
</Lozenge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getTooltipDescription = (status: string) => {
|
||||
let tooltipDescription = '';
|
||||
switch (status) {
|
||||
case MarketTradingModeMapping.TRADING_MODE_CONTINUOUS:
|
||||
tooltipDescription =
|
||||
'This is the standard trading mode where trades are executed whenever orders are received';
|
||||
break;
|
||||
case `${MarketTradingModeMapping.TRADING_MODE_MONITORING_AUCTION} - ${AuctionTriggerMapping.AUCTION_TRIGGER_LIQUIDITY}`:
|
||||
tooltipDescription =
|
||||
'This market is in auction until it reaches sufficient liquidity';
|
||||
break;
|
||||
case MarketTradingModeMapping.TRADING_MODE_OPENING_AUCTION:
|
||||
tooltipDescription =
|
||||
'This is a new market in an opening auction to determine a fair mid-price before starting continuous trading.';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return tooltipDescription;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 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_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"hosts": ["https://api.n01.stagnet3.vega.xyz/graphql"]
|
||||
"hosts": ["https://api.stagnet3.vega.xyz/graphql"]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET3;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
|
||||
@@ -644,7 +644,7 @@ context(
|
||||
it('Unable to create a proposal - when no tokens are associated', function () {
|
||||
cy.vega_wallet_teardown();
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||
'0.000000000000000000',
|
||||
'0.00',
|
||||
txTimeout
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
@@ -759,7 +759,7 @@ context(
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'0.999900000000000000'
|
||||
'0.9999'
|
||||
);
|
||||
});
|
||||
cy.navigate_to('governance');
|
||||
@@ -804,7 +804,7 @@ context(
|
||||
cy.get(connectToVegaWalletButton).should('not.exist');
|
||||
// 3001-VOTE-100
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||
'1.000000000000000000',
|
||||
'1.00',
|
||||
txTimeout
|
||||
);
|
||||
cy.vote_for_proposal('against');
|
||||
|
||||
@@ -116,7 +116,7 @@ context(
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'proposal_submission.terms.closing_timestamp: cannot be after enactment time'
|
||||
'Invalid params: proposal_submission.terms.closing_timestamp (cannot be after enactment time)'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
cy.get(minVoteDeadline).click();
|
||||
@@ -157,7 +157,7 @@ context(
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'*: unknown field "signers" in vega.DataSourceDefinition'
|
||||
'Invalid params: the transaction is malformed'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -554,7 +554,7 @@ context(
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'0.000000000000000000'
|
||||
'0.00'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -608,7 +608,7 @@ context(
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'0.000000000000000000'
|
||||
'0.00'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -656,7 +656,7 @@ context(
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'2.000000000000000000'
|
||||
'2.00'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -819,7 +819,7 @@ context(
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'12.000000000000000000'
|
||||
'12.00'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ context(
|
||||
before('visit staking tab and connect vega wallet', function () {
|
||||
cy.visit('/');
|
||||
cy.verify_page_header('The $VEGA token');
|
||||
cy.vega_wallet_connect();
|
||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||
});
|
||||
|
||||
@@ -109,7 +108,7 @@ context(
|
||||
cy.get(ethWalletAssociatedBalances, txTimeout)
|
||||
.contains(vegaWalletPublicKeyShort)
|
||||
.parent()
|
||||
.should('contain', '1,001.000000000000000000', txTimeout);
|
||||
.should('contain', '1,001.00', txTimeout);
|
||||
|
||||
cy.get(ethWalletTotalAssociatedBalance, txTimeout)
|
||||
.contains('1,001.00', txTimeout)
|
||||
@@ -118,7 +117,7 @@ context(
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'1,001.000000000000000000'
|
||||
'1,001.00'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,10 +43,6 @@ context(
|
||||
it('Able to open withdrawal form with vega wallet connected', function () {
|
||||
// needs to reload page for withdrawal form to be displayed in ci - not reproducible outside of ci
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.visit('/');
|
||||
cy.navigate_to('withdrawals');
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(selectAsset)
|
||||
.find('option')
|
||||
.should('have.length.at.least', 2);
|
||||
@@ -79,7 +75,7 @@ context(
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(selectAsset).select(usdtName);
|
||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||
cy.getByTestId(withdrawalThreshold).should('have.text', '100,000.00000T');
|
||||
cy.getByTestId(withdrawalThreshold).should('have.text', '100,000.00T');
|
||||
cy.getByTestId(delayTime).should('have.text', 'None');
|
||||
cy.getByTestId(amountInput).click().type('100');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
@@ -94,7 +90,7 @@ context(
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/txs/');
|
||||
cy.getByTestId(withdrawalAssetSymbol).should('have.text', usdcSymbol);
|
||||
cy.getByTestId(withdrawalAmount).should('have.text', '100.00000');
|
||||
cy.getByTestId(withdrawalAmount).should('have.text', '100.00');
|
||||
cy.getByTestId(withdrawalRecipient)
|
||||
.should('have.text', truncatedWithdrawalEthAddress)
|
||||
.and('have.attr', 'href')
|
||||
@@ -118,7 +114,7 @@ context(
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('[col-id="asset.symbol"]').should('have.text', usdcSymbol);
|
||||
cy.get('[col-id="amount"]').should('have.text', '100.00000');
|
||||
cy.get('[col-id="amount"]').should('have.text', '100.00');
|
||||
cy.get('[col-id="details.receiverAddress"]')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
@@ -163,7 +159,7 @@ context(
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('[col-id="asset.symbol"]').should('have.text', usdcSymbol);
|
||||
cy.get('[col-id="amount"]').should('have.text', '100.00000');
|
||||
cy.get('[col-id="amount"]').should('have.text', '100.00');
|
||||
cy.get('[col-id="details.receiverAddress"]')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
|
||||
@@ -4,6 +4,7 @@ const validatorTitle = '[data-testid="validator-node-title"]';
|
||||
const validatorId = '[data-testid="validator-id"]';
|
||||
const validatorPubKey = '[data-testid="validator-public-key"]';
|
||||
const ethAddressLink = '[data-testid="link"]';
|
||||
const validatorStatus = '[data-testid="validator-status"]';
|
||||
const totalStake = '[data-testid="total-stake"]';
|
||||
const pendingStake = '[data-testid="pending-stake"]';
|
||||
const stakedByOperator = '[data-testid="staked-by-operator"]';
|
||||
@@ -162,6 +163,10 @@ context('Staking Page - verify elements on page', function () {
|
||||
});
|
||||
// TODO validators missing url for more information about them 2001-STKE-09
|
||||
|
||||
it('Should be able to see validator status', function () {
|
||||
cy.get(validatorStatus).should('have.text', 'Consensus');
|
||||
});
|
||||
|
||||
// 2001-STKE-012
|
||||
it('Should be able to see total stake', function () {
|
||||
cy.get(totalStake).invoke('text').should('match', stakeNumberRegex);
|
||||
|
||||
@@ -141,7 +141,7 @@ context(
|
||||
cy.get(currencyValue)
|
||||
.should('be.visible')
|
||||
.invoke('text')
|
||||
.should('match', /\d{0,3}(,\d{3})*\.\d{18}$/);
|
||||
.should('match', /\d{0,3}(,\d{3})*\.\d{2}$/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -210,7 +210,7 @@ context(
|
||||
cy.get(currencyValue)
|
||||
.should('be.visible')
|
||||
.invoke('text')
|
||||
.should('match', /\d{0,3}(,\d{3})*\.\d{18}$/);
|
||||
.should('match', /\d{0,3}(,\d{3})*\.\d{2}$/);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -197,18 +197,14 @@ context(
|
||||
{ tags: '@smoke' },
|
||||
function () {
|
||||
cy.get(walletContainer).within(() => {
|
||||
cy.get(currencyValue)
|
||||
.should('be.visible')
|
||||
.and('have.text', `0.000000000000000000`);
|
||||
cy.get(currencyValue).should('be.visible').and('have.text', `0.00`);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
it('should have Unstaked value visible', { tags: '@smoke' }, function () {
|
||||
cy.get(walletContainer).within(() => {
|
||||
cy.get(vegaUnstaked)
|
||||
.should('be.visible')
|
||||
.and('have.text', `0.000000000000000000`);
|
||||
cy.get(vegaUnstaked).should('be.visible').and('have.text', `0.00`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -331,7 +327,7 @@ context(
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('10.00000').should('be.visible'));
|
||||
.within(() => cy.contains_exactly('10.00').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
@@ -351,7 +347,7 @@ context(
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('6.00000').should('be.visible'));
|
||||
.within(() => cy.contains_exactly('6.00').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
@@ -371,7 +367,7 @@ context(
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('8.00000').should('be.visible'));
|
||||
.within(() => cy.contains_exactly('8.00').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
@@ -391,7 +387,7 @@ context(
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('2.00000').should('be.visible'));
|
||||
.within(() => cy.contains_exactly('2.00').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
|
||||
@@ -208,7 +208,7 @@ Cypress.Commands.add(
|
||||
if (parseFloat(unstakedBalance) != parseFloat(tokenAmount)) {
|
||||
cy.vega_wallet_teardown();
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||
'0.000000000000000000',
|
||||
'0.00',
|
||||
txTimeout
|
||||
);
|
||||
cy.staking_page_associate_tokens(tokenAmount);
|
||||
|
||||
@@ -93,19 +93,24 @@ Cypress.Commands.add('faucet_asset', function (assetEthAddress) {
|
||||
Cypress.Commands.add('vega_wallet_teardown', function () {
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance)
|
||||
.first()
|
||||
.invoke('text')
|
||||
.then((balance) => {
|
||||
if (balance != '0.000000000000000000') {
|
||||
if (balance != '0.00') {
|
||||
cy.vega_wallet_teardown_vesting(this.vestingContract);
|
||||
cy.vega_wallet_teardown_staking(this.stakingBridgeContract);
|
||||
}
|
||||
});
|
||||
cy.get('[data-test-id="associated-amount"]', { timeout: 30000 }).should(
|
||||
'contain.text',
|
||||
'0.00'
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, { timeout: transactionTimeout }).should(
|
||||
'contain',
|
||||
'0.000000000000000000',
|
||||
'0.00',
|
||||
{ timeout: transactionTimeout }
|
||||
);
|
||||
});
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_FAIRGROUND=false
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_EXPLORER_URL=https://staging3.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
import { createConnectors } from './lib/web3-connectors';
|
||||
import { ENV } from './config/env';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
import { WithdrawalDialog } from '@vegaprotocol/withdraws';
|
||||
|
||||
const cache: InMemoryCacheConfig = {
|
||||
typePolicies: {
|
||||
@@ -97,6 +98,7 @@ const Web3Container = ({
|
||||
</div>
|
||||
<VegaWalletDialogs />
|
||||
<TransactionModal />
|
||||
<WithdrawalDialog />
|
||||
</>
|
||||
</BalanceManager>
|
||||
</AppLoader>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user