Merge remote-tracking branch 'origin/master' into feat/75-link-like-button

This commit is contained in:
sam-keen 2022-03-25 11:12:01 +00:00
commit 9b4a41be07
224 changed files with 4575 additions and 676 deletions

View File

@ -25,6 +25,13 @@
"case": "kebabCase",
"ignore": ["\\[[a-zA-Z]+\\]\\.page"]
}
],
"no-restricted-imports": [
"warn",
{
"name": "lodash",
"message": "Import the specific methods you need from lodash e.g. `import get from 'lodash/get'`. This helps with bundle sizing."
}
]
}
},

View File

@ -1,23 +1,3 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://n04.d.vega.xyz/tm"

View File

@ -1,23 +1,3 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://mainnet-observer-proxy01.ops.vega.xyz/"
@ -28,7 +8,6 @@ NX_VEGA_URL = "https://api.token.vega.xyz/query"
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

View File

@ -1,30 +1,9 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://n03.s.vega.xyz/tm"
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.s.vega.xyz/tm/websocket"
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1

View File

@ -1,23 +1,3 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://n03.stagnet2.vega.xyz/tm"

View File

@ -1,23 +1,3 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"

View File

@ -1,4 +1,23 @@
Feature: Home page
Scenario: Visit Home page
Scenario Outline: Succesfful search for specific id by <IdType>
Given I am on the homepage
When I search for '<Id>'
Then I am redirected to page containing id '<Id>'
Examples:
| IdType | Id |
| Block Id | 973624 |
| Tx Hash | 9ED3718AA8308E7E08EC588EE7AADAF49711D2138860D8914B4D81A2054D9FB8 |
| Tx Id | 0x61DCCEBB955087F50D0B85382DAE138EDA9631BF1A4F92E563D528904AA38898 |
Scenario Outline: Error message displayed when invalid search by <invalidType>
Given I am on the homepage
When I search for '<Id>'
Then search error message "<errorMessage>" is displayed
Examples:
| invalidType | Id | errorMessage |
| wrong string length | 9ED3718AA8308E7E08EC588EE7AADAF497D2138860D8914B4D81A2054D9FB8 | Something doesn't look right |
| invalid hash | 9ED3718AA8308E7E08ECht8EE753DAF49711D2138860D8914B4D81A2054D9FB8 | Transaction is not hexadecimal |
| empty search | | Search required |

View File

@ -9,7 +9,9 @@ export default class BasePage {
networkParametersUrl = '/network-parameters';
validatorsUrl = '/validators';
blockExplorerHeader = 'explorer-header';
searchField = 'search-input';
searchField = 'search';
searchButton = 'search-button';
searchError = 'search-error';
navigateToTxs() {
cy.get(`a[href='${this.transactionsUrl}']`).click();
@ -48,17 +50,31 @@ export default class BasePage {
}
search(searchText) {
cy.getByTestId(this.searchField).type(searchText);
if (searchText) {
cy.getByTestId(this.searchField).type(searchText);
}
}
clickSearch() {
cy.getByTestId(this.searchButton).click();
}
validateUrl(expectedUrl) {
cy.url().should('include', expectedUrl);
}
validateSearchDisplayed() {
cy.getByTestId(this.blockExplorerHeader).should(
'have.text',
'Vega Block Explorer'
'Vega Explorer'
);
cy.getByTestId(this.searchField).should('be.visible');
}
validateSearchErrorDisplayed(errorMessage) {
cy.getByTestId(this.searchError).should('have.text', errorMessage);
}
validateBlockDataDisplayed(headerTestId) {
cy.getByTestId(headerTestId).then(($assetHeaders) => {
const headersAmount = parseInt($assetHeaders.length);
@ -68,7 +84,7 @@ export default class BasePage {
});
cy.get('.language-json')
.each(($asset, index, $list) => {
.each(($asset) => {
expect($asset).to.not.be.empty;
})
.then(($list) => {

View File

@ -7,7 +7,7 @@ export default class NetworkParametersPage extends BasePage {
verifyNetworkParametersDisplayed() {
cy.getByTestId(this.networkParametersHeader).should(
'have.text',
'NetworkParameters'
'Network Parameters'
);
cy.getByTestId(this.parameters).should('not.be.empty');
}

View File

@ -77,6 +77,6 @@ export default class TransactionsPage extends BasePage {
}
clickOnTopTransaction() {
cy.getByTestId(this.transactionRow).first().find('a').click();
cy.getByTestId(this.transactionRow).first().find('a').first().click();
}
}

View File

@ -1,5 +1,20 @@
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
import BasePage from '../pages/base-page';
const basePage = new BasePage();
Given('I am on the homepage', () => {
cy.visit('/');
});
When('I search for {string}', (searchText) => {
basePage.search(searchText);
basePage.clickSearch();
});
Then('I am redirected to page containing id {string}', (expectedUrl) => {
basePage.validateUrl(expectedUrl);
});
Then('search error message {string} is displayed', (expectedErrorMsg) => {
basePage.validateSearchErrorDisplayed(expectedErrorMsg);
});

View File

@ -1,4 +1,4 @@
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
import NetworkPage from '../pages/network-page';
const networkPage = new NetworkPage();

View File

@ -18,17 +18,10 @@ NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
NX_TENDERMINT_WEBSOCKET_URL = "wss://lb.testnet.vega.xyz/tm/websocket"
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

View File

@ -1,34 +1,5 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://n04.d.vega.xyz/tm"
NX_TENDERMINT_WEBSOCKET_URL = "wss://n04.d.vega.xyz/tm/websocket"
NX_VEGA_URL = "https://n04.d.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

14
apps/explorer/.env.local Normal file
View File

@ -0,0 +1,14 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
NX_TENDERMINT_WEBSOCKET_URL = "wss://lb.testnet.vega.xyz/tm/websocket"
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

View File

@ -1,34 +1,5 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://mainnet-observer-proxy01.ops.vega.xyz/"
NX_TENDERMINT_WEBSOCKET_URL = "wss://mainnet-observer-proxy01.ops.vega.xyz/websocket"
NX_VEGA_URL = "https://api.token.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

View File

@ -1,35 +1,5 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://n03.s.vega.xyz/tm"
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.s.vega.xyz/tm/websocket"
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

View File

@ -1,34 +1,5 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://n03.stagnet2.vega.xyz/tm"
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.stagnet2.vega.xyz/tm/websocket"
NX_VEGA_URL = "https://n03.stagnet2.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

View File

@ -1,34 +1,5 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
NX_TENDERMINT_WEBSOCKET_URL = "wss://lb.testnet.vega.xyz/tm/websocket"
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
# App flags
NX_EXPLORER_ASSETS = 1
NX_EXPLORER_GENESIS = 1
NX_EXPLORER_GOVERNANCE = 1
NX_EXPLORER_MARKETS = 1
NX_EXPLORER_NETWORK_PARAMETERS = 1
NX_EXPLORER_PARTIES = 1
NX_EXPLORER_VALIDATORS = 1

View File

@ -7,5 +7,5 @@ module.exports = {
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/apps/explorer',
setupFilesAfterEnv: ['./src/app/setupTests.ts'],
setupFilesAfterEnv: ['./src/app/setup-tests.ts'],
};

View File

@ -1,6 +1,5 @@
@import './styles/colors';
@import './styles/fonts';
@import './styles/reset';
html,
body,
@ -39,18 +38,23 @@ body,
padding: 20px;
grid-column-start: 1;
grid-column-end: 1;
grid-row-start: 1;
grid-row-start: 2;
grid-row-end: 3;
overflow: hidden;
}
header {
padding: 20px;
border-bottom: 1px solid $white;
grid-column-start: 2;
grid-column-end: 2;
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
h1 {
font-family: $font-alpa-lyrae;
font-feature-settings: 'calt';
text-transform: uppercase;
}
}
main {

View File

@ -1,4 +1,4 @@
import App from './App';
import App from './app';
describe('App', () => {
it('should exist', () => {

View File

@ -4,7 +4,6 @@ import { ApolloProvider } from '@apollo/client';
import { createClient } from './lib/apollo-client';
import { Nav } from './components/nav';
import { Footer } from './components/footer';
import { Header } from './components/header';
import { Main } from './components/main';
import React from 'react';
@ -24,7 +23,6 @@ function App() {
<Nav />
<Header />
<Main />
<Footer />
</div>
</div>
</ApolloProvider>

View File

@ -1,15 +0,0 @@
// import packageJson from "../../../package.json";
export const Footer = () => {
return (
<footer>
<section>
<div>Reading Vega Fairground data from </div>
<div>
{/* Version/commit hash: {packageJson.version} / */}
{process.env['NX_COMMIT_REF'] || 'dev'}
</div>
</section>
</footer>
);
};

View File

@ -0,0 +1,28 @@
import { render, screen } from '@testing-library/react';
import { Header } from './header';
import { MemoryRouter } from 'react-router-dom';
jest.mock('../search', () => ({
Search: () => <div data-testid="search">OrderList</div>,
}));
const renderComponent = () => (
<MemoryRouter>
<Header />
</MemoryRouter>
);
describe('Header', () => {
it('should render heading', () => {
render(renderComponent());
expect(screen.getByTestId('explorer-header')).toHaveTextContent(
'Vega Explorer'
);
});
it('should render search', () => {
render(renderComponent());
expect(screen.getByTestId('search')).toBeInTheDocument();
});
});

View File

@ -0,0 +1,12 @@
import { Search } from '../search';
export const Header = () => {
return (
<header className="flex px-16 pt-16 pb-8">
<h1 className="text-h3" data-testid="explorer-header">
Vega Explorer
</h1>
<Search />
</header>
);
};

View File

@ -1,9 +1 @@
import Search from "../search";
export const Header = () => {
return (
<header>
<Search />
</header>
);
};
export * from './header';

View File

@ -1,5 +1,6 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { Routes } from '../../routes/router-config';
export const JumpToBlock = () => {
const navigate = useNavigate();
@ -14,7 +15,7 @@ export const JumpToBlock = () => {
const blockNumber = target.blockNumber.value;
if (blockNumber) {
navigate(`/blocks/${blockNumber}`);
navigate(`/${Routes.BLOCKS}/${blockNumber}`);
}
};
@ -28,15 +29,15 @@ export const JumpToBlock = () => {
</label>
<input
id="block-input"
type="tel"
name={'blockNumber'}
placeholder={'Block number'}
type="number"
name="blockNumber"
placeholder="Block number"
className="bg-white-25 border-white border px-8 py-4 placeholder-white-60"
/>
<input
className="border-white border px-28 py-4 cursor-pointer"
type={'submit'}
value={'Go'}
type="submit"
value="Go"
/>
</form>
);

View File

@ -14,7 +14,7 @@ export const Nav = () => {
}`
}
>
{r.name}
{r.text}
</NavLink>
))}
</nav>

View File

@ -1,12 +1,16 @@
import classnames from 'classnames';
import React from 'react';
import React, { HTMLAttributes } from 'react';
interface RouteTitleProps {
interface RouteTitleProps extends HTMLAttributes<HTMLHeadingElement> {
children: React.ReactNode;
className?: string;
}
export const RouteTitle = ({ children, className }: RouteTitleProps) => {
export const RouteTitle = ({
children,
className,
...props
}: RouteTitleProps) => {
const classes = classnames(
'font-alpha',
'text-h3',
@ -15,5 +19,9 @@ export const RouteTitle = ({ children, className }: RouteTitleProps) => {
'mb-28',
className
);
return <h1 className={classes}>{children}</h1>;
return (
<h1 className={classes} {...props}>
{children}
</h1>
);
};

View File

@ -1,108 +1 @@
import { gql, useQuery } from '@apollo/client';
import React from 'react';
import { useState } from 'react';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import debounce from 'lodash.debounce';
import { Guess, GuessVariables } from '@vegaprotocol/graphql';
const TX_LENGTH = 64;
enum PossibleIdTypes {
Block = 'Block',
Tx = 'Tx',
Party = 'Party',
Market = 'Market',
Unknown = 'Unknown',
}
const GUESS_QUERY = gql`
query Guess($guess: ID!) {
party(id: $guess) {
id
}
market(id: $guess) {
id
}
}
`;
const usePossibleType = (search: string) => {
const [possibleType, setPossibleType] = useState<PossibleIdTypes>();
const { data, loading, error } = useQuery<Guess, GuessVariables>(
GUESS_QUERY,
{
variables: {
guess: search,
},
skip: !search,
}
);
React.useEffect(() => {
if (!isNaN(Number(search))) {
setPossibleType(PossibleIdTypes.Block);
} else if (data?.party) {
setPossibleType(PossibleIdTypes.Party);
} else if (data?.market) {
setPossibleType(PossibleIdTypes.Market);
} else if (search.replace('0x', '').length === TX_LENGTH) {
setPossibleType(PossibleIdTypes.Tx);
} else {
setPossibleType(PossibleIdTypes.Unknown);
}
}, [data?.market, data?.party, search, setPossibleType]);
return {
loading,
error,
possibleType,
};
};
const useGuess = () => {
const [search, setSearch] = useState<string>('');
const [debouncedSearch, setDebouncedSearch] = useState<string>('');
const { loading, error, possibleType } = usePossibleType(debouncedSearch);
const debouncedSearchSet = React.useMemo(
() => debounce(setDebouncedSearch, 1000),
[setDebouncedSearch]
);
const onChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const search = event.target.value;
setSearch(search);
debouncedSearchSet(search);
},
[debouncedSearchSet]
);
return {
onChange,
search,
loading,
error,
possibleType,
};
};
const Search = () => {
const { search, onChange } = useGuess();
return (
<section>
<h1 data-testid="explorer-header">Vega Block Explorer</h1>
<fieldset>
<label htmlFor="search">Search: </label>
<input
data-testid="search-field"
name="search"
value={search}
onChange={(e) => onChange(e)}
/>
</fieldset>
</section>
);
};
export default Search;
export * from './search';

View File

@ -0,0 +1,140 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { Search } from './search';
import { MemoryRouter } from 'react-router-dom';
import { Routes } from '../../routes/router-config';
const mockedNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockedNavigate,
}));
beforeEach(() => {
mockedNavigate.mockClear();
});
const renderComponent = () => (
<MemoryRouter>
<Search />
</MemoryRouter>
);
const getInputs = () => ({
input: screen.getByTestId('search'),
button: screen.getByTestId('search-button'),
});
describe('Search', () => {
it('should render search input and button', () => {
render(renderComponent());
expect(screen.getByTestId('search')).toBeInTheDocument();
expect(screen.getByTestId('search-button')).toHaveTextContent('Search');
});
it('should render error if input is not known', async () => {
render(renderComponent());
const { button, input } = getInputs();
fireEvent.change(input, { target: { value: 'asd' } });
fireEvent.click(button);
expect(await screen.findByTestId('search-error')).toHaveTextContent(
"Something doesn't look right"
);
});
it('should render error if no input is given', async () => {
render(renderComponent());
const { button } = getInputs();
fireEvent.click(button);
expect(await screen.findByTestId('search-error')).toHaveTextContent(
'Search required'
);
});
it('should render error if transaction is not hex', async () => {
render(renderComponent());
const { button, input } = getInputs();
fireEvent.change(input, {
target: {
value:
'0x123456789012345678901234567890123456789012345678901234567890123Q',
},
});
fireEvent.click(button);
expect(await screen.findByTestId('search-error')).toHaveTextContent(
'Transaction is not hexadecimal'
);
});
it('should render error if transaction is not hex and does not have leading 0x', async () => {
render(renderComponent());
const { button, input } = getInputs();
fireEvent.change(input, {
target: {
value:
'123456789012345678901234567890123456789012345678901234567890123Q',
},
});
fireEvent.click(button);
expect(await screen.findByTestId('search-error')).toHaveTextContent(
'Transaction is not hexadecimal'
);
});
it('should redirect to transactions page', async () => {
render(renderComponent());
const { button, input } = getInputs();
fireEvent.change(input, {
target: {
value:
'0x1234567890123456789012345678901234567890123456789012345678901234',
},
});
fireEvent.click(button);
await waitFor(() => {
expect(mockedNavigate).toBeCalledWith(
`${Routes.TX}/0x1234567890123456789012345678901234567890123456789012345678901234`
);
});
});
it('should redirect to transactions page without proceeding 0x', async () => {
render(renderComponent());
const { button, input } = getInputs();
fireEvent.change(input, {
target: {
value:
'1234567890123456789012345678901234567890123456789012345678901234',
},
});
fireEvent.click(button);
await waitFor(() => {
expect(mockedNavigate).toBeCalledWith(
`${Routes.TX}/0x1234567890123456789012345678901234567890123456789012345678901234`
);
});
});
it('should redirect to blocks page if passed a number', async () => {
render(renderComponent());
const { button, input } = getInputs();
fireEvent.change(input, {
target: {
value: '123',
},
});
fireEvent.click(button);
await waitFor(() => {
expect(mockedNavigate).toBeCalledWith(`${Routes.BLOCKS}/123`);
});
});
});

View File

@ -0,0 +1,84 @@
import { FormGroup, Input, InputError, Button } from '@vegaprotocol/ui-toolkit';
import React from 'react';
import { useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';
import { Routes } from '../../routes/router-config';
const TX_LENGTH = 64;
interface FormFields {
search: string;
}
const isPrependedTransaction = (search: string) =>
search.startsWith('0x') && search.length === 2 + TX_LENGTH;
const isTransaction = (search: string) =>
!search.startsWith('0x') && search.length === TX_LENGTH;
const isBlock = (search: string) => !Number.isNaN(Number(search));
export const Search = () => {
const { register, handleSubmit } = useForm<FormFields>();
const navigate = useNavigate();
const [error, setError] = React.useState<Error | null>(null);
const onSubmit = React.useCallback(
(fields: FormFields) => {
setError(null);
const search = fields.search;
if (!search) {
setError(new Error('Search required'));
} else if (isPrependedTransaction(search)) {
if (Number.isNaN(Number(search))) {
setError(new Error('Transaction is not hexadecimal'));
} else {
navigate(`${Routes.TX}/${search}`);
}
} else if (isTransaction(search)) {
if (Number.isNaN(Number(`0x${search}`))) {
setError(new Error('Transaction is not hexadecimal'));
} else {
navigate(`${Routes.TX}/0x${search}`);
}
} else if (isBlock(search)) {
navigate(`${Routes.BLOCKS}/${Number(search)}`);
} else {
setError(new Error("Something doesn't look right"));
}
},
[navigate]
);
return (
<form
onSubmit={handleSubmit(onSubmit)}
className="flex-1 flex ml-16 justify-end"
>
<FormGroup className="w-2/3 mb-0">
<Input
{...register('search')}
id="search"
data-testid="search"
hasError={Boolean(error?.message)}
type="text"
autoFocus={true}
placeholder="Enter block number or transaction hash"
/>
{error?.message ? (
<InputError
data-testid="search-error"
intent="danger"
className="flex-1 w-full"
>
{error.message}
</InputError>
) : (
<div className="h-28"></div>
)}
</FormGroup>
<Button type="submit" variant="secondary" data-testid="search-button">
Search
</Button>
</form>
);
};

View File

@ -0,0 +1,27 @@
import classnames from 'classnames';
import { HTMLAttributes } from 'react';
interface SubHeadingProps extends HTMLAttributes<HTMLHeadingElement> {
children: React.ReactNode;
className?: string;
}
export const SubHeading = ({
children,
className,
...props
}: SubHeadingProps) => {
const classes = classnames(
'font-alpha',
'text-h4',
'uppercase',
'mt-12',
'mb-12',
className
);
return (
<h2 {...props} className={classes}>
{children}
</h2>
);
};

View File

@ -1,7 +1,7 @@
import React from 'react';
import { TendermintBlockchainResponse } from '../../../routes/blocks/tendermint-blockchain-response';
import { BlockData } from '../../blocks';
import { TxsPerBlock } from '../txs-per-block';
import { TendermintBlockchainResponse } from '../../routes/blocks/tendermint-blockchain-response';
import { BlockData } from '../blocks';
import { TxsPerBlock } from './txs-per-block';
interface TxsProps {
data: TendermintBlockchainResponse | undefined;

View File

@ -1,4 +1,3 @@
export { TxDetails } from './id/tx-details';
export { TxContent } from './id/tx-content';
export { TxList } from './pending/tx-list';
export { BlockTxsData } from './home/block-txs-data';
export { TxList } from './tx-list';
export { BlockTxsData } from './block-txs-data';
export { TxOrderType } from './tx-order-type';

View File

@ -1,4 +1,4 @@
import { TendermintUnconfirmedTransactionsResponse } from '../../../routes/txs/tendermint-unconfirmed-transactions-response.d';
import { TendermintUnconfirmedTransactionsResponse } from '../../routes/txs/tendermint-unconfirmed-transactions-response.d';
interface TxsProps {
data: TendermintUnconfirmedTransactionsResponse | undefined;

View File

@ -1,11 +1,11 @@
import useFetch from '../../../hooks/use-fetch';
import { ChainExplorerTxResponse } from '../../../routes/types/chain-explorer-response';
import { Routes } from '../../../routes/router-config';
import { DATA_SOURCES } from '../../../config';
import useFetch from '../../hooks/use-fetch';
import { ChainExplorerTxResponse } from '../../routes/types/chain-explorer-response';
import { Routes } from '../../routes/router-config';
import { DATA_SOURCES } from '../../config';
import { Link } from 'react-router-dom';
import { RenderFetched } from '../../render-fetched';
import { TruncateInline } from '../../truncate/truncate';
import { TxOrderType } from '../tx-order-type';
import { RenderFetched } from '../render-fetched';
import { TruncateInline } from '../truncate/truncate';
import { TxOrderType } from './tx-order-type';
interface TxsPerBlockProps {
blockHeight: string | undefined;
@ -31,20 +31,20 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
return (
<RenderFetched error={error} loading={loading} className="text-body-large">
<div className="overflow-x-auto whitespace-nowrap mb-28">
<table className="w-full">
<thead>
<tr className="font-mono">
<td>Transaction</td>
<td>From</td>
<td>Type</td>
</tr>
</thead>
<tbody>
{decodedBlockData &&
decodedBlockData.map(({ TxHash, PubKey, Type }) => {
{decodedBlockData && decodedBlockData.length ? (
<div className="overflow-x-auto whitespace-nowrap mb-28">
<table className="w-full">
<thead>
<tr className="font-mono">
<td>Transaction</td>
<td>From</td>
<td>Type</td>
</tr>
</thead>
<tbody>
{decodedBlockData.map(({ TxHash, PubKey, Type }) => {
return (
<tr data-testid="transaction-row" key={TxHash}>
<tr key={TxHash} data-testid="transaction-row">
<td>
<Link to={`/${Routes.TX}/${TxHash}`}>
<TruncateInline
@ -56,12 +56,14 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
</Link>
</td>
<td>
<TruncateInline
text={PubKey}
startChars={truncateLength}
endChars={truncateLength}
className="font-mono"
/>
<Link to={`/${Routes.PARTIES}/${PubKey}`}>
<TruncateInline
text={PubKey}
startChars={truncateLength}
endChars={truncateLength}
className="text-vega-yellow font-mono"
/>
</Link>
</td>
<td>
<TxOrderType className="mb-4" orderType={Type} />
@ -69,9 +71,14 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
</tr>
);
})}
</tbody>
</table>
</div>
</tbody>
</table>
</div>
) : (
<div className="font-mono mb-28">
No transactions in block {blockHeight}
</div>
)}
</RenderFetched>
);
};

View File

@ -57,7 +57,7 @@ function useFetch<T = unknown>(
}
const data = (await response.json()) as T;
if ('error' in data) {
if (data && 'error' in data) {
// @ts-ignore - data.error
throw new Error(data.error);
}

View File

@ -1,5 +1,7 @@
import { gql, useQuery } from '@apollo/client';
import React from 'react';
import { RouteTitle } from '../../components/route-title';
import { SubHeading } from '../../components/sub-heading';
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
import { AssetsQuery } from '@vegaprotocol/graphql';
@ -35,12 +37,12 @@ const Assets = () => {
if (!data || !data.assets) return null;
return (
<section>
<h1>Assets</h1>
<RouteTitle data-testid="assets-header">Assets</RouteTitle>
{data?.assets.map((a) => (
<React.Fragment key={a.id}>
<h2 data-testid="asset-header">
<SubHeading data-testid="asset-header">
{a.name} ({a.symbol})
</h2>
</SubHeading>
<SyntaxHighlighter data={a} />
</React.Fragment>
))}

View File

@ -4,7 +4,6 @@ import { DATA_SOURCES } from '../../../config';
import useFetch from '../../../hooks/use-fetch';
import { TendermintBlocksResponse } from '../tendermint-blocks-response';
import { RouteTitle } from '../../../components/route-title';
import { TxsPerBlock } from '../../../components/txs/txs-per-block';
import { SecondsAgo } from '../../../components/seconds-ago';
import {
Table,
@ -12,6 +11,7 @@ import {
TableHeader,
TableCell,
} from '../../../components/table';
import { TxsPerBlock } from '../../../components/txs/txs-per-block';
const Block = () => {
const { block } = useParams<{ block: string }>();

View File

@ -1,3 +1,4 @@
import { RouteTitle } from '../../components/route-title';
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
import { DATA_SOURCES } from '../../config';
import useFetch from '../../hooks/use-fetch';
@ -12,7 +13,7 @@ const Genesis = () => {
if (!genesis?.result.genesis) return null;
return (
<section>
<h1 data-testid="genesis-header">Genesis</h1>
<RouteTitle data-testid="genesis-header">Genesis</RouteTitle>
<SyntaxHighlighter data={genesis?.result.genesis} />
</section>
);

View File

@ -1,5 +1,7 @@
import { gql, useQuery } from '@apollo/client';
import React from 'react';
import { RouteTitle } from '../../components/route-title';
import { SubHeading } from '../../components/sub-heading';
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
import {
ProposalsQuery,
@ -100,14 +102,13 @@ const PROPOSAL_QUERY = gql`
const Governance = () => {
const { data } = useQuery<ProposalsQuery>(PROPOSAL_QUERY);
if (!data || !data.proposals) return null;
if (!data) return null;
return (
<section>
<h1>Governance</h1>
{data.proposals.map((p) => (
<RouteTitle data-testid="governance-header">Governance</RouteTitle>
{data.proposals?.map((p) => (
<React.Fragment key={p.id}>
{/* TODO get proposal name generator from console */}
<h2>{getProposalName(p.terms.change)}</h2>
<SubHeading>{getProposalName(p.terms.change)}</SubHeading>
<SyntaxHighlighter data={p} />
</React.Fragment>
))}

View File

@ -1,7 +1,9 @@
import { StatsManager } from '@vegaprotocol/mainnet-stats-manager';
const Home = () => {
return (
<section>
<h1>Home page content</h1>
<StatsManager className="mt-12 grid grid-cols-1 lg:grid-cols-2 lg:gap-16" />
</section>
);
};

View File

@ -3,6 +3,8 @@ import { MarketsQuery } from '@vegaprotocol/graphql';
import React from 'react';
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
import { RouteTitle } from '../../components/route-title';
import { SubHeading } from '../../components/sub-heading';
const MARKETS_QUERY = gql`
query MarketsQuery {
@ -148,14 +150,17 @@ const Markets = () => {
if (!data || !data.markets) return null;
return (
<section className="px-8 py-12">
<h1>Markets</h1>
{data.markets.map((m) => (
<React.Fragment key={m.id}>
<h2 data-testid="markets-header">{m.name}</h2>
<SyntaxHighlighter data={m} />
</React.Fragment>
))}
<section>
<RouteTitle data-testid="markets-heading">Markets</RouteTitle>
{data
? data.markets.map((m) => (
<React.Fragment key={m.id}>
<SubHeading data-testid="markets-header">{m.name}</SubHeading>
<SyntaxHighlighter data={m} />
</React.Fragment>
))
: null}
</section>
);
};

View File

@ -1,5 +1,7 @@
import { gql, useQuery } from '@apollo/client';
import { RouteTitle } from '../../components/route-title';
import { NetworkParametersQuery } from '@vegaprotocol/graphql';
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
export const NETWORK_PARAMETERS_QUERY = gql`
query NetworkParametersQuery {
@ -14,8 +16,10 @@ const NetworkParameters = () => {
const { data } = useQuery<NetworkParametersQuery>(NETWORK_PARAMETERS_QUERY);
return (
<section>
<h1 data-testid="network-param-header">NetworkParameters</h1>
<pre data-testid="parameters">{JSON.stringify(data, null, ' ')}</pre>
<RouteTitle data-testid="network-param-header">
Network Parameters
</RouteTitle>
{data ? <SyntaxHighlighter data={data} /> : null}
</section>
);
};

View File

@ -1,13 +1,57 @@
import React from "react";
import React from 'react';
import { RouteTitle } from '../../../components/route-title';
import { useNavigate } from 'react-router-dom';
import { Routes } from '../../router-config';
export const JumpToParty = () => {
const navigate = useNavigate();
const handleSubmit = React.useCallback(
() => (e: React.SyntheticEvent) => {
e.preventDefault();
const target = e.target as typeof e.target & {
partyId: { value: number };
};
const partyId = target.partyId.value;
if (partyId) {
navigate(`/${Routes.PARTIES}/${partyId}`);
}
},
[navigate]
);
return (
<form onSubmit={handleSubmit}>
<label
htmlFor="block-input"
className="block uppercase text-h5 font-bold"
>
Go to party
</label>
<input
id="block-input"
name="partyId"
placeholder="Party id"
className="bg-white-25 border-white border px-8 py-4 placeholder-white-60"
/>
<input
className="border-white border px-28 py-4 cursor-pointer"
type="submit"
value="Go"
/>
</form>
);
};
const Parties = () => {
return (
<section>
<h1>Parties</h1>
<h2>
Not sure what to do with this page? Could show all parties but would
eventually need to be rewritten. But that's not very useful either
</h2>
<RouteTitle data-testid="parties-header">Parties</RouteTitle>
<JumpToParty />
</section>
);
};

View File

@ -2,6 +2,9 @@ import { useQuery } from '@apollo/client';
import { gql } from '@apollo/client';
import React from 'react';
import { useParams } from 'react-router-dom';
import { RouteTitle } from '../../../components/route-title';
import { SubHeading } from '../../../components/sub-heading';
import { SyntaxHighlighter } from '../../../components/syntax-highlighter';
import { DATA_SOURCES } from '../../../config';
import useFetch from '../../../hooks/use-fetch';
import { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
@ -47,10 +50,13 @@ const PARTY_ASSETS_QUERY = gql`
const Party = () => {
const { party } = useParams<{ party: string }>();
const {
state: { data: partyData },
} = useFetch<TendermintSearchTransactionResponse>(
`${DATA_SOURCES.tendermintWebsocketUrl}/tx_search?query="tx.submitter=%27${party}%27"`
`${
DATA_SOURCES.tendermintUrl
}/tx_search?query="tx.submitter='${party?.replace('0x', '')}'"`
);
const { data } = useQuery<PartyAssetsQuery, PartyAssetsQueryVariables>(
@ -65,11 +71,20 @@ const Party = () => {
return (
<section>
<h1>Party</h1>
<h2>Tendermint Data</h2>
<pre>{JSON.stringify(partyData, null, ' ')}</pre>
<h2>Asset data</h2>
<pre>{JSON.stringify(data, null, ' ')}</pre>
<RouteTitle data-testid="parties-header">Party</RouteTitle>
{data ? (
<>
<SubHeading>Asset data</SubHeading>
<SyntaxHighlighter data={data} />
</>
) : null}
{partyData ? (
<>
<SubHeading>Tendermint Data</SubHeading>
<SyntaxHighlighter data={partyData} />
</>
) : null}
</section>
);
};

View File

@ -3,6 +3,7 @@ import { DATA_SOURCES } from '../../config';
import useFetch from '../../hooks/use-fetch';
import { TendermintUnconfirmedTransactionsResponse } from '../txs/tendermint-unconfirmed-transactions-response.d';
import { TxList } from '../../components/txs';
import { RouteTitle } from '../../components/route-title';
const PendingTxs = () => {
const {
@ -13,7 +14,9 @@ const PendingTxs = () => {
return (
<section>
<h1>Unconfirmed transactions</h1>
<RouteTitle data-testid="unconfirmed-transactions-header">
Unconfirmed transactions
</RouteTitle>
https://lb.testnet.vega.xyz/tm/unconfirmed_txs
<br />
<div>Number: {unconfirmedTransactions?.result?.n_txs || 0}</div>

View File

@ -34,6 +34,7 @@ const partiesRoutes = flags.parties
{
path: Routes.PARTIES,
name: 'Parties',
text: 'Parties',
element: <Party />,
children: [
{
@ -53,6 +54,7 @@ const assetsRoutes = flags.assets
? [
{
path: Routes.ASSETS,
text: 'Assets',
name: 'Assets',
element: <Assets />,
},
@ -64,6 +66,7 @@ const genesisRoutes = flags.genesis
{
path: Routes.GENESIS,
name: 'Genesis',
text: 'Genesis Parameters',
element: <Genesis />,
},
]
@ -74,6 +77,7 @@ const governanceRoutes = flags.governance
{
path: Routes.GOVERNANCE,
name: 'Governance',
text: 'Proposals',
element: <Governance />,
},
]
@ -84,6 +88,7 @@ const marketsRoutes = flags.markets
{
path: Routes.MARKETS,
name: 'Markets',
text: 'Markets',
element: <Markets />,
},
]
@ -94,6 +99,7 @@ const networkParametersRoutes = flags.networkParameters
{
path: Routes.NETWORK_PARAMETERS,
name: 'NetworkParameters',
text: 'Network Parameters',
element: <NetworkParameters />,
},
]
@ -103,6 +109,7 @@ const validators = flags.validators
{
path: Routes.VALIDATORS,
name: 'Validators',
text: 'Validators',
element: <Validators />,
},
]
@ -112,12 +119,14 @@ const routerConfig = [
{
path: Routes.HOME,
name: 'Home',
text: 'Home',
element: <Home />,
index: true,
},
{
path: Routes.TX,
name: 'Txs',
text: 'Transactions',
element: <Txs />,
children: [
{
@ -137,6 +146,7 @@ const routerConfig = [
{
path: Routes.BLOCKS,
name: 'Blocks',
text: 'Blocks',
element: <BlockPage />,
children: [
{

View File

@ -4,9 +4,10 @@ import useFetch from '../../../hooks/use-fetch';
import { TendermintTransactionResponse } from '../tendermint-transaction-response.d';
import { ChainExplorerTxResponse } from '../../types/chain-explorer-response';
import { DATA_SOURCES } from '../../../config';
import { TxContent, TxDetails } from '../../../components/txs';
import { RouteTitle } from '../../../components/route-title';
import { RenderFetched } from '../../../components/render-fetched';
import { TxContent } from './tx-content';
import { TxDetails } from './tx-details';
const Tx = () => {
const { txHash } = useParams<{ txHash: string }>();

View File

@ -1,8 +1,13 @@
import { StatusMessage } from '../../../components/status-message';
import { SyntaxHighlighter } from '../../../components/syntax-highlighter';
import {
Table,
TableCell,
TableHeader,
TableRow,
} from '../../../components/table';
import { TxOrderType } from '../../../components/txs';
import { ChainExplorerTxResponse } from '../../../routes/types/chain-explorer-response';
import { SyntaxHighlighter } from '../../syntax-highlighter';
import { Table, TableRow, TableHeader, TableCell } from '../../table';
import { TxOrderType } from '../tx-order-type';
import { StatusMessage } from '../../status-message';
interface TxContentProps {
data: ChainExplorerTxResponse | undefined;

View File

@ -1,8 +1,13 @@
import { Link } from 'react-router-dom';
import {
Table,
TableCell,
TableHeader,
TableRow,
} from '../../../components/table';
import { TruncateInline } from '../../../components/truncate/truncate';
import { Routes } from '../../../routes/router-config';
import { Result } from '../../../routes/txs/tendermint-transaction-response.d';
import { Table, TableRow, TableCell, TableHeader } from '../../table';
import { TruncateInline } from '../../truncate/truncate';
interface TxDetailsProps {
txData: Result | undefined;

View File

@ -1,5 +1,8 @@
import { gql, useQuery } from '@apollo/client';
import React from 'react';
import { RouteTitle } from '../../components/route-title';
import { SubHeading } from '../../components/sub-heading';
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
import { DATA_SOURCES } from '../../config';
import useFetch from '../../hooks/use-fetch';
import { TendermintValidatorsResponse } from './tendermint-validator-response';
@ -41,13 +44,21 @@ const Validators = () => {
return (
<section>
<h1>Validators</h1>
<h2 data-testid="tendermint-header">Tendermint data</h2>
<pre data-testid="tendermint-data">
{JSON.stringify(validators, null, ' ')}
</pre>
<h2 data-testid="vega-header">Vega data</h2>
<pre data-testid="vega-data">{JSON.stringify(data, null, ' ')}</pre>
<RouteTitle data-testid="validators-header">Validators</RouteTitle>
{data ? (
<>
<SubHeading data-testid="vega-header">Vega data</SubHeading>
<SyntaxHighlighter data-testid="vega-data" data={data} />
</>
) : null}
{validators ? (
<>
<SubHeading data-testid="tendermint-header">
Tendermint data
</SubHeading>
<SyntaxHighlighter data-testid="tendermint-data" data={validators} />
</>
) : null}
</section>
);
};

View File

@ -1,6 +0,0 @@
fieldset {
border: 0;
padding: 0;
margin: 0;
min-width: 0;
}

View File

@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
"types": ["jest", "node", "@testing-library/jest-dom"]
},
"include": [
"**/*.test.ts",

View File

@ -0,0 +1,10 @@
{
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@ -0,0 +1,14 @@
{
"baseUrl": "http://localhost:3010",
"projectId": "et4snf",
"fileServerFolder": ".",
"fixturesFolder": "./src/fixtures",
"integrationFolder": "./src/integration",
"modifyObstructiveCode": false,
"supportFile": "./src/support/index.ts",
"pluginsFile": false,
"video": true,
"videosFolder": "../../dist/cypress/apps/stats-mainnet-e2e/videos",
"screenshotsFolder": "../../dist/cypress/apps/stats-mainnet-e2e/screenshots",
"chromeWebSecurity": false
}

View File

@ -0,0 +1,28 @@
{
"root": "apps/stats-mainnet-e2e",
"sourceRoot": "apps/stats-mainnet-e2e/src",
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nrwl/cypress:cypress",
"options": {
"cypressConfig": "apps/stats-mainnet-e2e/cypress.json",
"devServerTarget": "stats-mainnet:serve"
},
"configurations": {
"production": {
"devServerTarget": "stats-mainnet:serve:production"
}
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/stats-mainnet-e2e/**/*.{js,ts}"]
}
}
},
"tags": [],
"implicitDependencies": ["stats-mainnet"]
}

View File

@ -0,0 +1,4 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io"
}

View File

@ -0,0 +1,7 @@
describe('stats-mainnet', () => {
beforeEach(() => cy.visit('/'));
it('should display header', () => {
cy.get('h3').should('have.text', '/ Mainnet');
});
});

View File

@ -0,0 +1,33 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
// eslint-disable-next-line @typescript-eslint/no-namespace
declare namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
login(email: string, password: string): void;
}
}
//
// -- This is a parent command --
Cypress.Commands.add('login', (email, password) => {
console.log('Custom command example: Login', email, password);
});
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

View File

@ -0,0 +1,17 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands';

View File

@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"sourceMap": false,
"outDir": "../../dist/out-tsc",
"allowJs": true,
"types": ["cypress", "node"]
},
"include": ["src/**/*.ts", "src/**/*.js"]
}

View File

@ -0,0 +1,11 @@
{
"presets": [
[
"@nrwl/react/babel",
{
"runtime": "automatic"
}
]
],
"plugins": []
}

View File

@ -0,0 +1,16 @@
# This file is used by:
# 1. autoprefixer to adjust CSS to support the below specified browsers
# 2. babel preset-env to adjust included polyfills
#
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
#
# If you need to support different browsers in production, you may tweak the list below.
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major version
last 2 iOS major versions
Firefox ESR
not IE 9-11 # For IE 9-11 support, remove 'not'.

View File

@ -0,0 +1,18 @@
{
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@ -0,0 +1,11 @@
module.exports = {
displayName: 'stats-mainnet',
preset: '../../jest.preset.js',
transform: {
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
'^.+\\.[tj]sx?$': 'babel-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/apps/stats-mainnet',
setupFilesAfterEnv: ['./src/setup-tests.ts'],
};

View File

@ -0,0 +1,10 @@
const { join } = require('path');
module.exports = {
plugins: {
tailwindcss: {
config: join(__dirname, 'tailwind.config.js'),
},
autoprefixer: {},
},
};

View File

@ -0,0 +1,74 @@
{
"root": "apps/stats-mainnet",
"sourceRoot": "apps/stats-mainnet/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/web:webpack",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"compiler": "babel",
"outputPath": "dist/apps/stats-mainnet",
"index": "apps/stats-mainnet/src/index.html",
"baseHref": "/",
"main": "apps/stats-mainnet/src/main.tsx",
"polyfills": "apps/stats-mainnet/src/polyfills.ts",
"tsConfig": "apps/stats-mainnet/tsconfig.app.json",
"assets": [
"apps/stats-mainnet/src/assets/favicon.ico",
"apps/stats-mainnet/src/assets"
],
"styles": ["apps/stats-mainnet/src/styles/styles.css"],
"scripts": [],
"webpackConfig": "@nrwl/react/plugins/webpack"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/stats-mainnet/src/environments/environment.ts",
"with": "apps/stats-mainnet/src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false
}
}
},
"serve": {
"executor": "@nrwl/web:dev-server",
"options": {
"port": 3010,
"buildTarget": "stats-mainnet:build",
"hmr": true
},
"configurations": {
"production": {
"buildTarget": "stats-mainnet:build:production",
"hmr": false
}
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/stats-mainnet/**/*.{ts,tsx,js,jsx}"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/apps/stats-mainnet"],
"options": {
"jestConfig": "apps/stats-mainnet/jest.config.js",
"passWithNoTests": true
}
}
},
"tags": []
}

View File

@ -0,0 +1,24 @@
import React, { useState } from 'react';
import { Header } from './components/header';
import { StatsManager } from '@vegaprotocol/mainnet-stats-manager';
function App() {
const [darkMode, setDarkMode] = useState<boolean>(
document.documentElement.classList.contains('dark-mode-preferred')
);
return (
<div
className={`w-screen min-h-screen grid pb-24 ${
darkMode ? 'bg-black text-white-80' : 'bg-white text-black-95'
}`}
>
<div className="layout-grid w-screen justify-self-center">
<Header darkMode={darkMode} setDarkMode={setDarkMode} />
<StatsManager className="max-w-3xl px-24" />
</div>
</div>
);
}
export default App;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,20 @@
{
"short_name": "Mainnet Stats",
"name": "Vega Mainnet statistics",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@ -0,0 +1,32 @@
import { VegaLogo } from '@vegaprotocol/ui-toolkit';
import { LightModeToggle, DarkModeToggle } from '../images';
import { VegaBackgroundVideo } from '../videos';
import { DarkModeState } from '../../config/types';
export const Header = ({ darkMode, setDarkMode }: DarkModeState) => {
return (
<header className="relative overflow-hidden py-8 mb-40 md:mb-64">
<VegaBackgroundVideo />
<div
className={`relative flex justify-center px-8 ${
darkMode ? 'bg-black' : 'bg-white'
}`}
>
<div className="w-full max-w-3xl p-20 flex items-center justify-between">
<VegaLogo />
<button
onClick={() => setDarkMode(!darkMode)}
aria-label="Switch theme color"
className={`transition-colors rounded-full cursor-pointer ${
darkMode ? 'hover:bg-neutral-900' : 'hover:bg-neutral-200'
}`}
>
{darkMode ? <LightModeToggle /> : <DarkModeToggle />}
</button>
</div>
</div>
</header>
);
};

View File

@ -0,0 +1 @@
export { Header } from './header';

View File

@ -0,0 +1,18 @@
export const DarkModeToggle = () => {
return (
<svg width="45" height="45">
<g>
<path
d="M22.5 27.79a5.29 5.29 0 1 0 0-10.58 5.29 5.29 0 0 0 0 10.58Z"
fill="currentColor"
></path>
<path
d="M15.01 22.5H10M35 22.5h-5.01M22.5 29.99V35M22.5 10v5.01M17.21 27.79l-3.55 3.55M31.34 13.66l-3.55 3.55M27.79 27.79l3.55 3.55M13.66 13.66l3.55 3.55"
stroke="currentColor"
strokeWidth="1.3"
strokeMiterlimit="10"
></path>
</g>
</svg>
);
};

View File

@ -0,0 +1,2 @@
export { DarkModeToggle } from './dark-mode-toggle';
export { LightModeToggle } from './light-mode-toggle';

View File

@ -0,0 +1,10 @@
export const LightModeToggle = () => {
return (
<svg width="45" height="45">
<path
d="M28.75 11.69A12.39 12.39 0 0 0 22.5 10a12.5 12.5 0 1 0 0 25c2.196 0 4.353-.583 6.25-1.69A12.46 12.46 0 0 0 35 22.5a12.46 12.46 0 0 0-6.25-10.81Zm-6.25 22a11.21 11.21 0 0 1-11.2-11.2 11.21 11.21 0 0 1 11.2-11.2c1.246 0 2.484.209 3.66.62a13.861 13.861 0 0 0-5 10.58 13.861 13.861 0 0 0 5 10.58 11.078 11.078 0 0 1-3.66.63v-.01Z"
fill="currentColor"
></path>
</svg>
);
};

View File

@ -0,0 +1 @@
export { VegaBackgroundVideo } from './vega-background-video';

View File

@ -0,0 +1,16 @@
export const VegaBackgroundVideo = () => {
return (
<video
autoPlay
muted
loop
playsInline
className="absolute left-0 top-0 w-full h-auto"
>
<source
src="https://d33wubrfki0l68.cloudfront.net/2500bc5ef1b96927e0220eeb2bef0b22b87bcda1/3e0d3/static/moshed-aa65f0933af9abe9afb5e5663c9b3f68.mp4"
type="video/mp4"
/>
</video>
);
};

View File

@ -0,0 +1,4 @@
export interface DarkModeState {
darkMode: boolean;
setDarkMode: (arg0: boolean) => void;
}

View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="assets/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Health check for Vega's mainnet" />
<link rel="apple-touch-icon" href="assets/apple-touch-icon.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="assets/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Vega Mainnet Stats</title>
<script>
// Set dark mode preference indicator here to avoid FOUC
if (
localStorage.theme === 'dark' ||
(!('theme' in localStorage) &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark-mode-preferred');
} else {
document.documentElement.classList.remove('dark-mode-preferred');
}
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -0,0 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './styles/styles.css';
import App from './app';
import reportWebVitals from './report-web-vitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@ -0,0 +1,7 @@
/**
* Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
*
* See: https://github.com/zloirock/core-js#babel
*/
import 'core-js/stable';
import 'regenerator-runtime/runtime';

View File

@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@ -0,0 +1,15 @@
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

Binary file not shown.

View File

@ -0,0 +1,39 @@
@tailwind base;
@tailwind components;
@font-face {
font-family: 'AlphaLyrae-Medium';
src: url('./AlphaLyrae-Medium.woff');
}
.layout-grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(2, auto) 1fr;
}
.stats-grid {
display: grid;
}
@media (min-width: 768px) {
.stats-grid {
grid-template-columns: 18rem 1fr;
grid-column-gap: 1.25rem;
align-items: flex-start;
}
}
@media (min-width: 640px) {
.promoted-stats {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (min-width: 768px) {
.promoted-stats {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
}
@tailwind utilities;

View File

@ -0,0 +1,12 @@
const { join } = require('path');
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
const theme = require('../../libs/tailwindcss-config/src/theme');
module.exports = {
content: [
join(__dirname, 'src/**/*.{js,ts,jsx,tsx}'),
...createGlobPatternsForDependencies(__dirname),
],
theme,
plugins: [],
};

View File

@ -0,0 +1,22 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

View File

@ -0,0 +1,25 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@ -0,0 +1,23 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.test.tsx",
"**/*.spec.tsx",
"**/*.test.js",
"**/*.spec.js",
"**/*.test.jsx",
"**/*.spec.jsx",
"**/*.d.ts"
],
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
]
}

24
apps/trading/.env Normal file
View File

@ -0,0 +1,24 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
NX_VERSION=$npm_package_version
NX_REPOSITORY_URL=$REPOSITORY_URL
NX_BRANCH=$BRANCH
NX_PULL_REQUEST=$PULL_REQUEST
NX_HEAD=$HEAD
NX_COMMIT_REF=$COMMIT_REF
NX_CONTEXT=$CONTEXT
NX_REVIEW_ID=$REVIEW_ID
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
NX_ETHEREUM_CHAIN_ID = 3
NX_INFURA_ID = "4f846e79e13f44d1b51bbd7ed9edefb8";

Some files were not shown because too many files have changed in this diff Show More