Compare commits

..
Author SHA1 Message Date
Dexter 77b970cdbf fix: show vega node in list, cache bust 2023-05-09 19:03:43 +01:00
39 changed files with 261 additions and 880 deletions
+1 -1
View File
@@ -119,7 +119,7 @@ jobs:
run: |
echo "Check ipfs-hash"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matrix.app }}-ipfs-hash
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matirx.app }}-ipfs-hash
echo "List html directory"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
+9 -9
View File
@@ -1,20 +1,20 @@
.PHONY: latest-release
latest-release:
gh release list | head -n 1 | awk '{print $1}'
gh release list | head -n 1 | awk '{print $1}'
.PHONY: show-latest-release
show-latest-release:
gh release view `gh release list | head -n 1 | awk '{print $1}'`
gh release view `gh release list | head -n 1 | awk '{print $1}'`
.PHONY: recalculate-ipfs
recalculate-ipfs:
echo "ipfs hash inside the image"
docker run --rm ${TAG} cat /ipfs-hash
echo "recalculating ipfs hash"
docker run --rm ${TAG} ipfs add -rw /usr/share/nginx/html
echo "ipfs hash inside the image"
docker run --rm ${TAG} cat /ipfs-hash
echo "recalculating ipfs hash"
docker run --rm ${TAG} ipfs add -rw /usr/share/nginx/html
.PHONY: eject-ipfs-hash
unpack:
docker create --name=dist ${TAG}
docker cp dist:/usr/share/nginx/html dist
docker rm dist
docker create --name=dist ${TAG}
docker cp dist:/usr/share/nginx/html dist
docker rm dist
-1
View File
@@ -13,7 +13,6 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_VEGA_GOVERNANCE_URL=https://stagnet1.governance.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.jsoo
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
# App flags
NX_EXPLORER_ASSETS=1
-1
View File
@@ -2,7 +2,6 @@
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
NX_VEGA_URL=https://api.vega.community/graphql
NX_VEGA_ENV=MAINNET
NX_BLOCK_EXPLORER=https://be.vega.community/rest/
NX_ETHERSCAN_URL=https://etherscan.io
+1 -2
View File
@@ -1,2 +1 @@
# .env is stagnet1, so there are no overrides required
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET3":"https://stagnet3.explorer.vega.xyz"}'
# .env is stagnet1, so there are no overrides required
+2 -24
View File
@@ -1,18 +1,9 @@
import {
AppFailure,
NetworkLoader,
NodeGuard,
NodeSwitcherDialog,
useEnvironment,
useInitializeEnv,
useNodeSwitcherStore,
} from '@vegaprotocol/environment';
import { NetworkLoader, useInitializeEnv } from '@vegaprotocol/environment';
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
import { RouterProvider } from 'react-router-dom';
import { router } from './routes/router-config';
import { t } from '@vegaprotocol/i18n';
const splashLoading = (
<Splash>
@@ -21,23 +12,10 @@ const splashLoading = (
);
function App() {
const { VEGA_URL } = useEnvironment();
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useNodeSwitcherStore(
(store) => [store.dialogOpen, store.setDialogOpen]
);
return (
<TendermintWebsocketProvider>
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
<NodeGuard
skeleton={<div>{t('Loading')}</div>}
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
>
<RouterProvider router={router} fallbackElement={splashLoading} />
</NodeGuard>
<NodeSwitcherDialog
open={nodeSwitcherOpen}
setOpen={setNodeSwitcherOpen}
/>
<RouterProvider router={router} fallbackElement={splashLoading} />
</NetworkLoader>
</TendermintWebsocketProvider>
);
@@ -1,19 +1,13 @@
import {
useEnvironment,
useNodeSwitcherStore,
} from '@vegaprotocol/environment';
import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
import { useMemo } from 'react';
import { useMemo, useState } from 'react';
import { ENV } from '../../config/env';
export const Footer = () => {
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
const setNodeSwitcherOpen = useNodeSwitcherStore(
(store) => store.setDialogOpen
);
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
const { screenSize } = useScreenDimensions();
const showFullFeedbackLabel = useMemo(
() => ['md', 'lg', 'xl', 'xxl', 'xxxl'].includes(screenSize),
@@ -21,40 +15,46 @@ export const Footer = () => {
);
return (
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-xs md:text-md md:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
<div className="flex justify-between gap-2 align-middle">
{GIT_COMMIT_HASH && (
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
<p data-testid="git-commit-hash">
{t('Version')}:{' '}
<Link
href={
GIT_ORIGIN_URL
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
: undefined
}
target={GIT_ORIGIN_URL ? '_blank' : undefined}
>
{GIT_COMMIT_HASH}
</Link>
</p>
<>
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-xs md:text-md md:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
<div className="flex justify-between gap-2 align-middle">
{GIT_COMMIT_HASH && (
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
<p data-testid="git-commit-hash">
{t('Version')}:{' '}
<Link
href={
GIT_ORIGIN_URL
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
: undefined
}
target={GIT_ORIGIN_URL ? '_blank' : undefined}
>
{GIT_COMMIT_HASH}
</Link>
</p>
</div>
)}
<div className="content-center flex pl-2 md:border-r border-neutral-700 dark:border-neutral-300 pr-4">
{VEGA_URL && <NodeUrl url={VEGA_URL} />}
<Link className="ml-2" onClick={() => setNodeSwitcherOpen(true)}>
{t('Change')}
</Link>
</div>
)}
<div className="content-center flex pl-2 md:border-r border-neutral-700 dark:border-neutral-300 pr-4">
{VEGA_URL && <NodeUrl url={VEGA_URL} />}
<Link className="ml-2" onClick={() => setNodeSwitcherOpen(true)}>
{t('Change')}
</Link>
<div className="flex pl-2 content-center">
<ExternalLink href={ENV.addresses.feedback}>
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
</ExternalLink>
</div>
</div>
<div className="flex pl-2 content-center">
<ExternalLink href={ENV.addresses.feedback}>
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
</ExternalLink>
</div>
</div>
</footer>
</footer>
<NodeSwitcherDialog
open={nodeSwitcherOpen}
setOpen={setNodeSwitcherOpen}
/>
</>
);
};
@@ -7,7 +7,6 @@ import {
waitForSpinner,
navigateTo,
navigation,
turnTelemetryOff,
} from '../../support/common.functions';
import {
clickOnValidatorFromList,
@@ -57,7 +56,6 @@ context(
// 2001-STKE-002, 2001-STKE-032
before('visit staking tab and connect vega wallet', function () {
cy.visit('/');
cy.validatorsSelfDelegate();
ethereumWalletConnect();
// this is a workaround for #2422 which can be removed once issue is resolved
cy.associateTokensToVegaWallet('4');
@@ -69,7 +67,6 @@ context(
'teardown wallet & drill into a specific validator',
function () {
cy.clearLocalStorage();
turnTelemetryOff();
cy.reload();
waitForSpinner();
cy.connectVegaWallet();
@@ -255,10 +252,10 @@ context(
waitForBeginningOfEpoch();
cy.getByTestId(stakeValidatorListStakePercentage).should(
'have.text',
'50.02%'
'100%'
);
navigateTo(navigation.validators);
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
validateValidatorListTotalStakeAndShare('0', '2.00', '100.00%');
}
);
@@ -29,10 +29,7 @@ const performancePenaltyToolTip = '[data-testid="performance-penalty-tooltip"]';
const overstakedPenaltyToolTip = '[data-testid="overstaked-penalty-tooltip"]';
const totalPenaltyToolTip = '[data-testid="total-penalty-tooltip"]';
const epochCountDown = '[data-testid="epoch-countdown"]';
const stakeNumberRegex = /^\d{1,3}(,\d{3})*(\.\d+)?$/;
// If running locally, validators need to have self-stake to be displayed
// Run cy.validatorsSelfDelegate() in before hook
const stakeNumberRegex = /^\d*\.?\d*$/;
context('Validators Page - verify elements on page', function () {
before('navigate to validators page', function () {
@@ -87,13 +84,13 @@ context('Validators Page - verify elements on page', function () {
cy.get(stakedByOperatorToolTip)
.invoke('text')
.should('contain', 'Staked by operator: 3,000.00');
.should('contain', 'Staked by operator: 0.00');
cy.get(stakedByDelegatesToolTip)
.invoke('text')
.should('contain', 'Staked by delegates: 0.00');
cy.get(totalStakedToolTip)
.invoke('text')
.should('contain', 'Total stake: 3,000.00');
.should('contain', 'Total stake: 0.00');
});
it('Should be able to see validator normalised voting power', function () {
@@ -109,10 +106,10 @@ context('Validators Page - verify elements on page', function () {
cy.get(unnormalisedVotingPowerToolTip)
.invoke('text')
.should('contain', 'Unnormalised voting power: 20.00%');
.should('contain', 'Unnormalised voting power: 0.00%');
cy.get(normalisedVotingPowerToolTip)
.invoke('text')
.should('contain', 'Normalised voting power: 50.00%');
.should('contain', 'Normalised voting power: 0.10%');
});
// 2002-SINC-018
@@ -129,13 +126,13 @@ context('Validators Page - verify elements on page', function () {
cy.get(performancePenaltyToolTip)
.invoke('text')
.should('contain', 'Performance penalty: 0.00%');
.should('contain', 'Performance penalty: 100.00%');
cy.get(overstakedPenaltyToolTip)
.invoke('text')
.should('contain', 'Overstaked penalty: 60.00%'); // value not asserted due to #2886
.should('contain', 'Overstaked penalty:'); // value not asserted due to #2886
cy.get(totalPenaltyToolTip)
.invoke('text')
.should('contain', 'Total penalties: 60.00%');
.should('contain', 'Total penalties: 0.00%');
});
it('Should be able to see validator pending stake', function () {
+14 -37
View File
@@ -37,10 +37,6 @@ import {
useEnvironment,
NetworkLoader,
useInitializeEnv,
NodeGuard,
AppFailure,
NodeSwitcherDialog,
useNodeSwitcherStore,
} from '@vegaprotocol/environment';
import { ENV } from './config';
import type { InMemoryCacheConfig } from '@apollo/client';
@@ -52,7 +48,6 @@ import {
TELEMETRY_ON,
} from './components/telemetry-dialog/telemetry-dialog';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { useTranslation } from 'react-i18next';
const cache: InMemoryCacheConfig = {
typePolicies: {
@@ -186,19 +181,9 @@ const ScrollToTop = () => {
const AppContainer = () => {
const { config, loading, error } = useEthereumConfig();
const {
VEGA_ENV,
VEGA_URL,
GIT_COMMIT_HASH,
GIT_BRANCH,
ETHEREUM_PROVIDER_URL,
} = useEnvironment();
const { VEGA_ENV, GIT_COMMIT_HASH, GIT_BRANCH, ETHEREUM_PROVIDER_URL } =
useEnvironment();
const [telemetryOn] = useLocalStorage(TELEMETRY_ON);
const { t } = useTranslation();
const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [
store.dialogOpen,
store.setDialogOpen,
]);
useEffect(() => {
if (ENV.dsn && telemetryOn) {
@@ -234,29 +219,21 @@ const AppContainer = () => {
<ScrollToTop />
<AppStateProvider>
<div className="grid min-h-full text-white">
<NodeGuard
skeleton={<div>{t('Loading')}</div>}
failure={
<AppFailure title={t('NodeUnsuitable', { url: VEGA_URL })} />
<AsyncRenderer<EthereumConfig | null>
loading={loading}
data={config}
error={error}
render={(cnf) =>
cnf && (
<Web3Container
chainId={Number(cnf.chain_id)}
providerUrl={ETHEREUM_PROVIDER_URL}
/>
)
}
>
<AsyncRenderer<EthereumConfig | null>
loading={loading}
data={config}
error={error}
render={(cnf) =>
cnf && (
<Web3Container
chainId={Number(cnf.chain_id)}
providerUrl={ETHEREUM_PROVIDER_URL}
/>
)
}
/>
</NodeGuard>
/>
</div>
</AppStateProvider>
<NodeSwitcherDialog open={nodeSwitcherOpen} setOpen={setNodeSwitcher} />
</Router>
);
};
@@ -811,6 +811,5 @@
"OptOutOfTelemetry": "You can opt out any time via settings",
"NoThanks": "No thanks",
"ShareData": "Share data",
"ContinueSharingData": "Continue sharing data",
"NodeUnsuitable": "Node: {{url}} is unsuitable"
"ContinueSharingData": "Continue sharing data"
}
+39 -140
View File
@@ -48,8 +48,8 @@
"tranche_start": "2023-04-20T00:00:00.000Z",
"tranche_end": "2023-05-20T00:00:00.000Z",
"total_added": "19242.125",
"total_removed": "1979.64045368475",
"locked_amount": "6088.8928113908174973875",
"total_removed": "1523.8177488329475",
"locked_amount": "6891.9471601080244395475",
"deposits": [
{
"amount": "188",
@@ -228,16 +228,6 @@
"user": "0xDd7a98557586ce21f770662319C2047C5a3bD605",
"tx": "0x2b3571c143ecebddf91fb62f402d516d51110edfe37b13200a6e5cf682dc5bb0"
},
{
"amount": "336.4580555509875",
"user": "0xf915Da10e5136352Ba049acB0545Deb119054256",
"tx": "0x7af5942634e236f5f9c580f4ed042794ed309e83885f652a55ab37793ea2e85c"
},
{
"amount": "119.364649300815",
"user": "0xDd7a98557586ce21f770662319C2047C5a3bD605",
"tx": "0x47f5bf2c758c5270dd1b6519ac649ddabef8199f8a0bae319e36f8ac5c9c142e"
},
{
"amount": "202.093666077975",
"user": "0x1447Efc62d5077d7AbB20492dF831Dd6c9Eb1756",
@@ -372,12 +362,6 @@
"tranche_id": 56,
"tx": "0x2b3571c143ecebddf91fb62f402d516d51110edfe37b13200a6e5cf682dc5bb0"
},
{
"amount": "119.364649300815",
"user": "0xDd7a98557586ce21f770662319C2047C5a3bD605",
"tranche_id": 56,
"tx": "0x47f5bf2c758c5270dd1b6519ac649ddabef8199f8a0bae319e36f8ac5c9c142e"
},
{
"amount": "195.89040769089",
"user": "0xDd7a98557586ce21f770662319C2047C5a3bD605",
@@ -386,8 +370,8 @@
}
],
"total_tokens": "914.25",
"withdrawn_tokens": "624.076855605525",
"remaining_tokens": "290.173144394475"
"withdrawn_tokens": "504.71220630471",
"remaining_tokens": "409.53779369529"
},
{
"address": "0x9573BDF7FfC5519912d293e4D1f750eab2E471E7",
@@ -721,12 +705,6 @@
}
],
"withdrawals": [
{
"amount": "336.4580555509875",
"user": "0xf915Da10e5136352Ba049acB0545Deb119054256",
"tranche_id": 56,
"tx": "0x7af5942634e236f5f9c580f4ed042794ed309e83885f652a55ab37793ea2e85c"
},
{
"amount": "422.1034736680125",
"user": "0xf915Da10e5136352Ba049acB0545Deb119054256",
@@ -735,8 +713,8 @@
}
],
"total_tokens": "1121.25",
"withdrawn_tokens": "758.561529219",
"remaining_tokens": "362.688470781"
"withdrawn_tokens": "422.1034736680125",
"remaining_tokens": "699.1465263319875"
},
{
"address": "0x237D23FcA6d7B2530C7614a9cB921CF27924911E",
@@ -899,7 +877,7 @@
"tranche_start": "2023-04-06T00:00:00.000Z",
"tranche_end": "2023-05-06T00:00:00.000Z",
"total_added": "14610",
"total_removed": "6675.45090157707",
"total_removed": "6141.45090157707",
"locked_amount": "0",
"deposits": [
{
@@ -1099,11 +1077,6 @@
"user": "0x9E53F72210479BF46aE7ABF77c48B0d611b3c3dB",
"tx": "0x1dbcf713b48965a82aa2e17cb3e7db9a491668d859d408a39c8a74b0ea860b6b"
},
{
"amount": "534",
"user": "0x2586bA83696a92b5467Aaa0CF9EEC052F28F2c02",
"tx": "0x5aa922056cad64f97a7dfa750da57d63abfdaea4499192d4d57958bfb4fba2ea"
},
{
"amount": "106.53500000286",
"user": "0x6F32AA5A6198329c16e438512F992a0548C856f9",
@@ -1227,17 +1200,10 @@
"tx": "0xf970ea0ce3e36fa0014d24bb830dd2ea0dbea06f6e53af486de5ee7e1c63e540"
}
],
"withdrawals": [
{
"amount": "534",
"user": "0x2586bA83696a92b5467Aaa0CF9EEC052F28F2c02",
"tranche_id": 54,
"tx": "0x5aa922056cad64f97a7dfa750da57d63abfdaea4499192d4d57958bfb4fba2ea"
}
],
"withdrawals": [],
"total_tokens": "534",
"withdrawn_tokens": "534",
"remaining_tokens": "0"
"withdrawn_tokens": "0",
"remaining_tokens": "534"
},
{
"address": "0xBf1AaB792D729fA125e6D7122D4b916a1E1C44B1",
@@ -1860,7 +1826,7 @@
"tranche_start": "2023-03-06T00:00:00.000Z",
"tranche_end": "2023-04-06T00:00:00.000Z",
"total_added": "14099",
"total_removed": "3785.49002352036",
"total_removed": "3722.49002352036",
"locked_amount": "0",
"deposits": [
{
@@ -2625,11 +2591,6 @@
}
],
"withdrawals": [
{
"amount": "63",
"user": "0x2a65Ae527C6Ff4665e048B0E0883c486A7BA4DBc",
"tx": "0xb0edcc25e422bc3db3ad8027dfdfc0928abd7a8af8957a1699e4cf2dc8cee8f7"
},
{
"amount": "30",
"user": "0xBe9F912Ad481C61B653463E8F1D2b2b310D49861",
@@ -3668,17 +3629,10 @@
"tx": "0xd4a269b070cbaaff7e29a99f6b3997117d765f69512bb760e28bade799fcbba4"
}
],
"withdrawals": [
{
"amount": "63",
"user": "0x2a65Ae527C6Ff4665e048B0E0883c486A7BA4DBc",
"tranche_id": 53,
"tx": "0xb0edcc25e422bc3db3ad8027dfdfc0928abd7a8af8957a1699e4cf2dc8cee8f7"
}
],
"withdrawals": [],
"total_tokens": "63",
"withdrawn_tokens": "63",
"remaining_tokens": "0"
"withdrawn_tokens": "0",
"remaining_tokens": "63"
},
{
"address": "0xc3B1eB0feE837Db0A3ded5bf16A050726955195B",
@@ -4907,7 +4861,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "86666.297",
"total_removed": "0",
"locked_amount": "49504.9919953353951513585",
"locked_amount": "49802.2753121154213651374",
"deposits": [
{
"amount": "86666.297",
@@ -4973,7 +4927,7 @@
"tranche_end": "2023-06-01T00:00:00.000Z",
"total_added": "2500",
"total_removed": "0",
"locked_amount": "295.23443859381355",
"locked_amount": "312.4325905575906",
"deposits": [
{
"amount": "2500",
@@ -5006,7 +4960,7 @@
"tranche_end": "2023-11-01T00:00:00.000Z",
"total_added": "15000.000000000000015",
"total_removed": "0",
"locked_amount": "14224.9782986111115142249782986111115",
"locked_amount": "14327.0455917874395143270455917874395",
"deposits": [
{
"amount": "1.5e-14",
@@ -5094,7 +5048,7 @@
"tranche_end": "2023-09-01T00:00:00.000Z",
"total_added": "17500",
"total_removed": "0",
"locked_amount": "10794.17758026368775",
"locked_amount": "10913.25608896940375",
"deposits": [
{
"amount": "12500",
@@ -5361,7 +5315,7 @@
"tranche_end": "2023-08-01T00:00:00.000Z",
"total_added": "37500",
"total_removed": "18077.0118744",
"locked_amount": "17091.10506829343025",
"locked_amount": "17350.5026089625535",
"deposits": [
{
"amount": "7500",
@@ -5780,7 +5734,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "49459.824919096584707505",
"locked_amount": "49756.837002255673748325",
"deposits": [
{
"amount": "129999.45",
@@ -5813,7 +5767,7 @@
"tranche_end": "2024-04-01T00:00:00.000Z",
"total_added": "54144.7663",
"total_removed": "0",
"locked_amount": "48300.2481374426486922947",
"locked_amount": "48485.46842731635829207292",
"deposits": [
{
"amount": "54144.7663",
@@ -5846,7 +5800,7 @@
"tranche_end": "2023-09-03T00:00:00.000Z",
"total_added": "62600",
"total_removed": "0",
"locked_amount": "19807.852061136476024",
"locked_amount": "20022.5830035514954",
"deposits": [
{
"amount": "10000",
@@ -6039,7 +5993,7 @@
"tranche_end": "2023-09-17T00:00:00.000Z",
"total_added": "5000",
"total_removed": "0",
"locked_amount": "1773.87763191273475",
"locked_amount": "1791.028665651953",
"deposits": [
{
"amount": "5000",
@@ -7108,7 +7062,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "1709370.7872515768348",
"locked_amount": "119547.7788438730317094704",
"locked_amount": "126202.1342632826843379468",
"deposits": [
{
"amount": "1852091.69",
@@ -40980,7 +40934,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "715655.108029600523393",
"locked_amount": "208204.638696483881349131871",
"locked_amount": "218430.066175628697078272948",
"deposits": [
{
"amount": "1998.95815",
@@ -42372,8 +42326,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15870102.715470999700000001",
"total_removed": "872635.89843522227071852",
"locked_amount": "6037967.8664430882362406121449295313314409",
"total_removed": "871680.07831804700259352",
"locked_amount": "6074226.5757489411253544394273819693295485",
"deposits": [
{
"amount": "16249.93",
@@ -42882,11 +42836,6 @@
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
},
{
"amount": "955.820117175268125",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b"
},
{
"amount": "10150.87581603206683",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
@@ -45061,12 +45010,6 @@
"tranche_id": 2,
"tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13"
},
{
"amount": "955.820117175268125",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 2,
"tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b"
},
{
"amount": "913.910324501590625",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -46623,8 +46566,8 @@
}
],
"total_tokens": "259998.8875",
"withdrawn_tokens": "160546.342221561692",
"remaining_tokens": "99452.545278438308"
"withdrawn_tokens": "159590.522104386423875",
"remaining_tokens": "100408.365395613576125"
},
{
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
@@ -49005,7 +48948,7 @@
"tranche_start": "2021-11-05T00:00:00.000Z",
"tranche_end": "2023-05-05T00:00:00.000Z",
"total_added": "14597706.0446472999",
"total_removed": "6246751.954791069035514289",
"total_removed": "6170228.182342542771392682",
"locked_amount": "0",
"deposits": [
{
@@ -49215,11 +49158,6 @@
}
],
"withdrawals": [
{
"amount": "76523.772448526264121607",
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
"tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67"
},
{
"amount": "1257.7360413991436375",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@@ -56419,12 +56357,6 @@
}
],
"withdrawals": [
{
"amount": "76523.772448526264121607",
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
"tranche_id": 3,
"tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67"
},
{
"amount": "466184.354416277260082874",
"user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3",
@@ -56439,8 +56371,8 @@
}
],
"total_tokens": "575536.79731735",
"withdrawn_tokens": "575536.79731735",
"remaining_tokens": "0"
"withdrawn_tokens": "499013.024868823735878393",
"remaining_tokens": "76523.772448526264121607"
},
{
"address": "0xaAeD573103e3f981867C4cd31c6674DE1c8a13c3",
@@ -56932,7 +56864,7 @@
"tranche_start": "2021-10-05T00:00:00.000Z",
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "5778205.3912159303",
"total_removed": "3492469.400132244009296769",
"total_removed": "3480901.398845846498418769",
"locked_amount": "0",
"deposits": [
{
@@ -57077,11 +57009,6 @@
}
],
"withdrawals": [
{
"amount": "11568.001286397510878",
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
"tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046"
},
{
"amount": "58898.87608135458795",
"user": "0x83b1a48376E045D26420200345414e6b93066396",
@@ -58052,12 +57979,6 @@
}
],
"withdrawals": [
{
"amount": "11568.001286397510878",
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
"tranche_id": 4,
"tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046"
},
{
"amount": "209431.056913602489122",
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
@@ -58066,8 +57987,8 @@
}
],
"total_tokens": "220999.0582",
"withdrawn_tokens": "220999.0582",
"remaining_tokens": "0"
"withdrawn_tokens": "209431.056913602489122",
"remaining_tokens": "11568.001286397510878"
},
{
"address": "0x9058e12e2F32cB1cD4D3123359963D77786477FC",
@@ -59148,8 +59069,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "44544.1737890903416",
"locked_amount": "32991.215149911803725776786707268",
"total_removed": "44479.0535455583416",
"locked_amount": "34611.49258501772999518148756976",
"deposits": [
{
"amount": "3000",
@@ -65773,11 +65694,6 @@
"user": "0x0436E2E4EA467f9958403dc56635404EE1bb1E94",
"tx": "0x97f5b5ec5ac839a8d182b9267b5d052cb70f9a18b648874337e3d5360b21a5fb"
},
{
"amount": "65.120243532",
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
"tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180"
},
{
"amount": "182.662252664",
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
@@ -86371,12 +86287,6 @@
}
],
"withdrawals": [
{
"amount": "65.120243532",
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
"tranche_id": 5,
"tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180"
},
{
"amount": "120.24984145",
"user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472",
@@ -86385,8 +86295,8 @@
}
],
"total_tokens": "200",
"withdrawn_tokens": "185.370084982",
"remaining_tokens": "14.629915018"
"withdrawn_tokens": "120.24984145",
"remaining_tokens": "79.75015855"
},
{
"address": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46",
@@ -144491,11 +144401,6 @@
}
],
"withdrawals": [
{
"amount": "0",
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
"tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa"
},
{
"amount": "0",
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
@@ -144791,12 +144696,6 @@
}
],
"withdrawals": [
{
"amount": "0",
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
"tranche_id": 9,
"tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa"
},
{
"amount": "0",
"user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7",
@@ -12,7 +12,6 @@ import {
createMarketsDataFragment,
assetQuery,
networkParamsQuery,
nodeGuardQuery,
} from '@vegaprotocol/mock';
import {
addDecimalsFormatNumber,
@@ -159,7 +158,6 @@ describe('Closed markets', { tags: '@smoke' }, () => {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
aliasGQLQuery(req, 'NetworkParams', networkParamsQuery());
aliasGQLQuery(
req,
@@ -6,7 +6,6 @@ const row = 'key-value-table-row';
const marketTitle = 'accordion-title';
const externalLink = 'external-link';
const accordionContent = 'accordion-content';
const providerName = 'provider-name';
describe('market info is displayed', { tags: '@smoke' }, () => {
beforeEach(() => {
@@ -182,20 +181,9 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
cy.getByTestId(marketTitle).contains('Oracle').click();
cy.getByTestId(accordionContent)
.getByTestId(providerName)
.getByTestId('provider-name')
.and('contain', 'Another oracle');
cy.getByTestId(providerName).should('be.visible').click();
cy.getByTestId('dialog-content')
.eq(1)
.within(() => {
cy.getByTestId('block-explorer-link').contains('Block explorer');
cy.getByTestId('github-link').contains('Oracle repository');
cy.getByTestId('verified-accounts').contains('0 proofs of ownership');
});
cy.getByTestId('dialog-close').click();
cy.getByTestId(accordionContent)
.getByTestId('verified-proofs')
.and('contain', '1');
@@ -17,6 +17,7 @@ describe('ethereum wallet', { tags: '@smoke', testIsolation: true }, () => {
it('can connect', () => {
// 0004-EWAL-001
cy.wait('@NetworkParams');
cy.getByTestId('Deposits').click();
cy.getByTestId('deposit-button').click();
cy.getByTestId('connect-eth-wallet-btn').click();
@@ -29,6 +30,7 @@ describe('ethereum wallet', { tags: '@smoke', testIsolation: true }, () => {
it('should see QR code modal for WalletConnect', () => {
// 0004-EWAL-003
cy.wait('@NetworkParams');
cy.getByTestId('Deposits').click();
cy.getByTestId('deposit-button').click();
cy.getByTestId('connect-eth-wallet-btn').click();
-2
View File
@@ -20,7 +20,6 @@ import {
marketsDataQuery,
marketsQuery,
networkParamsQuery,
nodeGuardQuery,
ordersQuery,
positionsQuery,
proposalListQuery,
@@ -83,7 +82,6 @@ const mockTradingPage = (
) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
aliasGQLQuery(
req,
'Markets',
@@ -1,6 +1,6 @@
import { t } from '@vegaprotocol/i18n';
import { Button } from '@vegaprotocol/ui-toolkit';
import { useNodeSwitcherStore } from '../../hooks/use-node-switcher-store';
import { useGlobalStore } from '../../stores';
export const AppFailure = ({
title,
@@ -9,13 +9,17 @@ export const AppFailure = ({
title: string;
error?: string | null;
}) => {
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
const { setNodeSwitcher } = useGlobalStore((store) => ({
nodeSwitcherOpen: store.nodeSwitcherDialog,
setNodeSwitcher: (open: boolean) =>
store.update({ nodeSwitcherDialog: open }),
}));
const nonIdealWrapperClasses =
'h-full min-h-screen flex items-center justify-center';
return (
<div className={nonIdealWrapperClasses}>
<div className="text-center">
<p className="text-xl mb-4">{title}</p>
<h1 className="text-xl mb-4">{title}</h1>
{error && <p className="text-sm mb-8">{error}</p>}
<Button onClick={() => setNodeSwitcher(true)}>
{t('Change node')}
@@ -1,6 +1,5 @@
import type { InMemoryCacheConfig } from '@apollo/client';
import {
AppFailure,
NetworkLoader,
NodeGuard,
useEnvironment,
@@ -10,6 +9,7 @@ import { MaintenancePage } from '@vegaprotocol/ui-toolkit';
import { VegaWalletProvider } from '@vegaprotocol/wallet';
import dynamic from 'next/dynamic';
import type { ReactNode } from 'react';
import { AppFailure } from './app-failure';
import { Web3Provider } from './web3-provider';
export const DynamicLoader = dynamic(() => import('../preloader/preloader'), {
@@ -1,2 +1,3 @@
export * from './app-failure';
export * from './app-loader';
export * from './web3-provider';
@@ -4,15 +4,18 @@ import { NodeHealth, NodeUrl, HealthIndicator } from './footer';
import { MockedProvider } from '@apollo/client/testing';
import { Intent } from '@vegaprotocol/ui-toolkit';
const mockSetNodeSwitcher = jest.fn();
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
useEnvironment: jest.fn().mockImplementation(() => ({
VEGA_URL: 'https://vega-url.wtf',
VEGA_INCIDENT_URL: 'https://blog.vega.community',
})),
useNodeSwitcherStore: jest.fn(() => mockSetNodeSwitcher),
}));
const mockSetNodeSwitcher = jest.fn();
jest.mock('../../stores', () => ({
...jest.requireActual('../../stores'),
useGlobalStore: () => mockSetNodeSwitcher,
}));
describe('NodeHealth', () => {
+5 -6
View File
@@ -1,14 +1,11 @@
import { useCallback } from 'react';
import {
useEnvironment,
useNodeHealth,
useNodeSwitcherStore,
} from '@vegaprotocol/environment';
import { useEnvironment, useNodeHealth } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import type { Intent } from '@vegaprotocol/ui-toolkit';
import { Indicator, ExternalLink } from '@vegaprotocol/ui-toolkit';
import classNames from 'classnames';
import type { ButtonHTMLAttributes, ReactNode } from 'react';
import { useGlobalStore } from '../../stores';
export const Footer = () => {
return (
@@ -23,7 +20,9 @@ export const Footer = () => {
export const NodeHealth = () => {
const { VEGA_URL, VEGA_INCIDENT_URL } = useEnvironment();
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
const setNodeSwitcher = useGlobalStore(
(store) => (open: boolean) => store.update({ nodeSwitcherDialog: open })
);
const { datanodeBlockHeight, text, intent } = useNodeHealth();
const onClick = useCallback(() => {
setNodeSwitcher(true);
+6 -6
View File
@@ -21,10 +21,9 @@ import {
NodeSwitcherDialog,
useEnvironment,
useInitializeEnv,
useNodeSwitcherStore,
} from '@vegaprotocol/environment';
import './styles.css';
import { usePageTitleStore } from '../stores';
import { useGlobalStore, usePageTitleStore } from '../stores';
import { Footer } from '../components/footer';
import DialogsContainer from './dialogs-container';
import ToastsManager from './toasts-manager';
@@ -116,10 +115,11 @@ function AppBody({ Component }: AppProps) {
function VegaTradingApp(props: AppProps) {
const status = useEnvironment((store) => store.status);
const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [
store.dialogOpen,
store.setDialogOpen,
]);
const { nodeSwitcherOpen, setNodeSwitcher } = useGlobalStore((store) => ({
nodeSwitcherOpen: store.nodeSwitcherDialog,
setNodeSwitcher: (open: boolean) =>
store.update({ nodeSwitcherDialog: open }),
}));
useInitializeEnv();
+2
View File
@@ -3,6 +3,7 @@ import { create } from 'zustand';
import produce from 'immer';
interface GlobalStore {
nodeSwitcherDialog: boolean;
marketId: string | null;
update: (store: Partial<Omit<GlobalStore, 'update'>>) => void;
shouldDisplayWelcomeDialog: boolean;
@@ -14,6 +15,7 @@ interface PageTitleStore {
}
export const useGlobalStore = create<GlobalStore>()((set) => ({
nodeSwitcherDialog: false,
marketId: LocalStorage.getItem('marketId') || null,
shouldDisplayWelcomeDialog: false,
update: (newState) => {
+2 -2
View File
@@ -1,7 +1,7 @@
#!/bin/bash -e
yarn --pure-lockfile
app=${1:-trading}
flags="--env=${2:-mainnet}"
app={$1:-trading}
flags="--env=${$2:-mainnet}"
yarn install
if [ "${app}" = "trading" ]; then
yarn nx export trading $flags
@@ -1,280 +0,0 @@
import { VegaDataSource } from './data-source';
import type { ApolloClient } from '@apollo/client';
import { Interval } from 'pennant';
import type {
CandleFieldsFragment,
CandlesQuery,
} from './__generated__/Candles';
import * as Schema from '@vegaprotocol/types';
const returnDataMocks = (nodes: CandleFieldsFragment[]): CandlesQuery => {
return {
data: {
market: {
decimalPlaces: 1,
positionDecimalPlaces: 1,
candlesConnection: {
edges: nodes.map((node) => ({ node })),
},
},
},
} as CandlesQuery;
};
const dataMocks: { [key in Schema.Interval]: Partial<CandleFieldsFragment>[] } =
{
[Schema.Interval.INTERVAL_I1M]: [
{
__typename: 'Candle',
periodStart: '2023-05-10T12:00:00Z',
lastUpdateInPeriod: '',
close: '10',
volume: '1',
},
{
__typename: 'Candle',
periodStart: '2023-05-10T12:05:00Z',
lastUpdateInPeriod: '',
close: '5',
volume: '2',
},
],
[Schema.Interval.INTERVAL_I5M]: [
{
__typename: 'Candle',
periodStart: '2023-05-10T12:00:00Z',
lastUpdateInPeriod: '',
close: '10',
volume: '1',
},
{
__typename: 'Candle',
periodStart: '2023-05-10T12:25:00Z',
lastUpdateInPeriod: '',
close: '5',
volume: '2',
},
],
[Schema.Interval.INTERVAL_I15M]: [
{
__typename: 'Candle',
periodStart: '2023-05-10T12:00:00Z',
lastUpdateInPeriod: '',
close: '10',
volume: '1',
},
{
__typename: 'Candle',
periodStart: '2023-05-10T13:15:00Z',
lastUpdateInPeriod: '',
close: '5',
volume: '2',
},
],
[Schema.Interval.INTERVAL_I1H]: [
{
__typename: 'Candle',
periodStart: '2023-05-10T12:00:00Z',
lastUpdateInPeriod: '',
close: '10',
volume: '1',
},
{
__typename: 'Candle',
periodStart: '2023-05-10T17:00:00Z',
lastUpdateInPeriod: '',
close: '5',
volume: '2',
},
],
[Schema.Interval.INTERVAL_I6H]: [
{
__typename: 'Candle',
periodStart: '2023-05-10T12:00:00Z',
lastUpdateInPeriod: '',
close: '10',
volume: '1',
},
{
__typename: 'Candle',
periodStart: '2023-05-11T18:00:00Z',
lastUpdateInPeriod: '',
close: '5',
volume: '2',
},
],
[Schema.Interval.INTERVAL_I1D]: [
{
__typename: 'Candle',
periodStart: '2023-05-10T00:00:00Z',
lastUpdateInPeriod: '',
close: '10',
volume: '1',
},
{
__typename: 'Candle',
periodStart: '2023-05-15T00:00:00Z',
lastUpdateInPeriod: '',
close: '5',
volume: '2',
},
],
[Schema.Interval.INTERVAL_BLOCK]: [],
};
describe('VegaDataSource', () => {
const marketId = 'marketId';
const partyId = 'partyId';
const client = {
query: jest.fn().mockImplementation(({ variables: { interval } }) => {
return returnDataMocks(
dataMocks[interval as Schema.Interval] as CandleFieldsFragment[]
);
}),
} as unknown as ApolloClient<object>;
it('should be properly initialized', () => {
const dataSource = new VegaDataSource(client, marketId, partyId);
expect(dataSource).toBeInstanceOf(VegaDataSource);
expect(dataSource.onReady).toBeDefined();
expect(dataSource.query).toBeDefined();
expect(dataSource.subscribeData).toBeDefined();
expect(dataSource.unsubscribeData).toBeDefined();
expect(dataSource.decimalPlaces).toBeDefined();
expect(dataSource.positionDecimalPlaces).toBeDefined();
});
describe('query should return continuous data', () => {
it('when interval is I1M', async () => {
const dataSource = new VegaDataSource(client, marketId, partyId);
const data = await dataSource.query(Interval.I1M, '');
expect(data).toHaveLength(6);
expect(data[1]).toStrictEqual({
date: new Date('2023-05-10T12:01:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
expect(data[2]).toStrictEqual({
date: new Date('2023-05-10T12:02:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
});
it('when interval is I5M', async () => {
const dataSource = new VegaDataSource(client, marketId, partyId);
const data = await dataSource.query(Interval.I5M, '');
expect(data).toHaveLength(6);
expect(data[1]).toStrictEqual({
date: new Date('2023-05-10T12:05:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
expect(data[2]).toStrictEqual({
date: new Date('2023-05-10T12:10:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
});
it('when interval is I15M', async () => {
const dataSource = new VegaDataSource(client, marketId, partyId);
const data = await dataSource.query(Interval.I15M, '');
expect(data).toHaveLength(6);
expect(data[1]).toStrictEqual({
date: new Date('2023-05-10T12:15:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
expect(data[2]).toStrictEqual({
date: new Date('2023-05-10T12:30:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
});
it('when interval is I1H', async () => {
const dataSource = new VegaDataSource(client, marketId, partyId);
const data = await dataSource.query(Interval.I1H, '');
expect(data).toHaveLength(6);
expect(data[1]).toStrictEqual({
date: new Date('2023-05-10T13:00:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
expect(data[2]).toStrictEqual({
date: new Date('2023-05-10T14:00:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
});
it('when interval is I6H', async () => {
const dataSource = new VegaDataSource(client, marketId, partyId);
const data = await dataSource.query(Interval.I6H, '');
expect(data).toHaveLength(6);
expect(data[1]).toStrictEqual({
date: new Date('2023-05-10T18:00:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
expect(data[2]).toStrictEqual({
date: new Date('2023-05-11T00:00:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
});
it('when interval is I1D', async () => {
const dataSource = new VegaDataSource(client, marketId, partyId);
const data = await dataSource.query(Interval.I1D, '');
expect(data).toHaveLength(6);
expect(data[1]).toStrictEqual({
date: new Date('2023-05-11T00:00:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
expect(data[2]).toStrictEqual({
date: new Date('2023-05-12T00:00:00Z'),
high: 1,
low: 1,
open: 1,
close: 1,
volume: 0,
});
});
});
});
+3 -88
View File
@@ -1,11 +1,4 @@
import type { ApolloClient } from '@apollo/client';
import type { Duration } from 'date-fns';
import {
add,
differenceInDays,
differenceInHours,
differenceInMinutes,
} from 'date-fns';
import type { Candle, DataSource } from 'pennant';
import { Interval as PennantInterval } from 'pennant';
@@ -160,6 +153,7 @@ export class VegaDataSource implements DataSource {
},
fetchPolicy: 'no-cache',
});
if (data?.market?.candlesConnection?.edges) {
const decimalPlaces = data.market.decimalPlaces;
const positionDecimalPlaces = data.market.positionDecimalPlaces;
@@ -169,8 +163,8 @@ export class VegaDataSource implements DataSource {
.filter((node): node is CandleFieldsFragment => !!node)
.map((node) =>
parseCandle(node, decimalPlaces, positionDecimalPlaces)
)
.reduce(checkGranulationContinuity(interval), []);
);
return candles;
} else {
return [];
@@ -219,85 +213,6 @@ export class VegaDataSource implements DataSource {
}
}
const getDuration = (
interval: PennantInterval,
multiplier: number
): Duration => {
switch (interval) {
case 'I1D':
return {
days: 1 * multiplier,
};
case 'I1H':
return {
hours: 1 * multiplier,
};
case 'I1M':
return {
minutes: 1 * multiplier,
};
case 'I5M':
return {
minutes: 5 * multiplier,
};
case 'I6H':
return {
hours: 6 * multiplier,
};
case 'I15M':
return {
minutes: 15 * multiplier,
};
}
};
const getDifference = (
interval: PennantInterval,
dateLeft: Date,
dateRight: Date
): number => {
switch (interval) {
case 'I1D':
return differenceInDays(dateRight, dateLeft);
case 'I6H':
return differenceInHours(dateRight, dateLeft) / 6;
case 'I1H':
return differenceInHours(dateRight, dateLeft);
case 'I15M':
return differenceInMinutes(dateRight, dateLeft) / 15;
case 'I5M':
return differenceInMinutes(dateRight, dateLeft) / 5;
case 'I1M':
return differenceInMinutes(dateRight, dateLeft);
}
};
const checkGranulationContinuity =
(interval: PennantInterval) =>
(agg: Candle[], candle: Candle, i: number): Candle[] => {
if (agg.length && i) {
const previous = agg[agg.length - 1];
const difference = getDifference(interval, previous.date, candle.date);
if (difference > 1) {
for (let j = 1; j < difference; j++) {
const duration = getDuration(interval, j);
const newStartDate = add(previous.date, duration);
const newParsedCandle: Candle = {
date: newStartDate,
high: previous.close,
low: previous.close,
open: previous.close,
close: previous.close,
volume: 0,
};
agg.push(newParsedCandle);
}
}
}
agg.push(candle);
return agg;
};
function parseCandle(
candle: CandleFieldsFragment,
decimalPlaces: number,
-1
View File
@@ -7,7 +7,6 @@ export * from '../candles-chart/src/lib/chart.mock';
export * from '../deal-ticket/src/hooks/estimate-order.mock';
export * from '../deposits/src/lib/deposit.mock';
export * from '../environment/src/utils/node.mock';
export * from '../environment/src/components/node-guard/node-guard.mock';
export * from '../fills/src/lib/fills.mock';
export * from '../proposals/src/lib/proposals-data-provider/proposals.mock';
export * from '../ledger/src/lib/ledger-entries.mock';
@@ -97,7 +97,7 @@ export const useColumnSizes = ({
const setSizes = useCallback(
(apiEvent: GridReadyEvent | GridSizeChangedEvent) => {
if (!storeKey || !Object.keys(sizes).length || !widthRef.current) {
apiEvent?.api.sizeColumnsToFit();
apiEvent.api.sizeColumnsToFit();
} else {
const recalculatedSizes = recalculateSizes(sizes);
const newSizes = Object.entries(recalculatedSizes).map(
@@ -1 +0,0 @@
export * from './app-failure';
-1
View File
@@ -1,4 +1,3 @@
export * from './app-failure';
export * from './network-loader';
export * from './network-switcher';
export * from './node-guard';
@@ -1,11 +0,0 @@
query NodeGuard {
lastBlockHeight
networkParametersConnection {
edges {
node {
key
value
}
}
}
}
@@ -1,51 +0,0 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type NodeGuardQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type NodeGuardQuery = { __typename?: 'Query', lastBlockHeight: string, networkParametersConnection: { __typename?: 'NetworkParametersConnection', edges?: Array<{ __typename?: 'NetworkParameterEdge', node: { __typename?: 'NetworkParameter', key: string, value: string } } | null> | null } };
export const NodeGuardDocument = gql`
query NodeGuard {
lastBlockHeight
networkParametersConnection {
edges {
node {
key
value
}
}
}
}
`;
/**
* __useNodeGuardQuery__
*
* To run a query within a React component, call `useNodeGuardQuery` and pass it any options that fit your needs.
* When your component renders, `useNodeGuardQuery` 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 } = useNodeGuardQuery({
* variables: {
* },
* });
*/
export function useNodeGuardQuery(baseOptions?: Apollo.QueryHookOptions<NodeGuardQuery, NodeGuardQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<NodeGuardQuery, NodeGuardQueryVariables>(NodeGuardDocument, options);
}
export function useNodeGuardLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<NodeGuardQuery, NodeGuardQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<NodeGuardQuery, NodeGuardQueryVariables>(NodeGuardDocument, options);
}
export type NodeGuardQueryHookResult = ReturnType<typeof useNodeGuardQuery>;
export type NodeGuardLazyQueryHookResult = ReturnType<typeof useNodeGuardLazyQuery>;
export type NodeGuardQueryResult = Apollo.QueryResult<NodeGuardQuery, NodeGuardQueryVariables>;
@@ -1,53 +0,0 @@
import type { NodeGuardQuery } from './__generated__/NodeGuard';
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
export const nodeGuardQuery = (
override?: PartialDeep<NodeGuardQuery>
): NodeGuardQuery => {
const defaultResult: NodeGuardQuery = {
lastBlockHeight: '11',
networkParametersConnection: {
__typename: 'NetworkParametersConnection',
edges: [
{
__typename: 'NetworkParameterEdge',
node: {
__typename: 'NetworkParameter' as const,
key: 'governance.proposal.market.requiredMajority',
value: '0.66',
},
},
{
__typename: 'NetworkParameterEdge',
node: {
__typename: 'NetworkParameter' as const,
key: 'blockchains.ethereumConfig',
value: JSON.stringify({
network_id: '3',
chain_id: '3',
collateral_bridge_contract: {
address: '0x7fe27d970bc8Afc3B11Cc8d9737bfB66B1efd799',
},
multisig_control_contract: {
address: '0x6eBc32d66277D94DB8FF2ccF86E36f37F29a52D3',
deployment_block_height: 12341882,
},
staking_bridge_contract: {
address: '0xFFb0A0d4806502ceF491aF1141f66669A1Bd0D03',
deployment_block_height: 11177313,
},
token_vesting_contract: {
address: '0x680fF88252FA7071CAce7398e77872d54D781d0B',
deployment_block_height: 11177353,
},
confirmations: 3,
}),
},
},
],
},
};
return merge(defaultResult, override);
};
@@ -1,5 +1,5 @@
import type { ReactNode } from 'react';
import { useNodeGuardQuery } from './__generated__/NodeGuard';
import { useStatisticsQuery } from '../../utils/__generated__/Node';
export const NodeGuard = ({
children,
@@ -10,19 +10,14 @@ export const NodeGuard = ({
failure: ReactNode;
skeleton: ReactNode;
}) => {
const { data, error, loading } = useNodeGuardQuery();
const wrapperClasses =
'h-full min-h-screen flex items-center justify-center text-black dark:text-white';
const { error, loading } = useStatisticsQuery();
const wrapperClasses = 'h-full min-h-screen flex items-center justify-center';
if (loading) {
return <div className={wrapperClasses}>{skeleton}</div>;
}
// It is possible for nodes to have a functioning datanode, but not return
// any net params. The app cannot safely function without net params
const netParamEdges = data?.networkParametersConnection.edges;
if (error || !netParamEdges || !netParamEdges.length) {
if (error) {
return <div className={wrapperClasses}>{failure}</div>;
}
@@ -96,13 +96,13 @@ describe('RowData', () => {
mockHeaders(props.url);
render(renderComponent(props, statsQueryMock, subMock));
// radio should be enabled until query resolves
// radio should be disabled until query resolves
expect(
screen.getByRole('radio', {
checked: false,
name: props.url,
})
).toBeEnabled();
).toBeDisabled();
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
'Checking'
);
@@ -124,7 +124,7 @@ describe('RowData', () => {
});
});
it('radio button still enabled if query fails', async () => {
it('radio button disabled if query fails', async () => {
mockHeaders(props.url, {});
const failedQueryMock: MockedResponse<StatisticsQuery> = {
@@ -149,7 +149,7 @@ describe('RowData', () => {
checked: false,
name: props.url,
})
).toBeEnabled();
).toBeDisabled();
expect(screen.getByTestId('response-time-cell')).toHaveTextContent(
'Checking'
);
@@ -170,7 +170,7 @@ describe('RowData', () => {
checked: false,
name: props.url,
})
).toBeEnabled();
).toBeDisabled();
});
});
@@ -207,6 +207,19 @@ describe('RowData', () => {
expect(screen.getByTestId('block-height-cell')).toHaveClass('text-danger');
});
it('disables radio button if url is invalid', () => {
mockHeaders(props.url, { blockHeight: 100 });
render(renderComponent(props, statsQueryMock, subMock));
expect(
screen.getByRole('radio', {
checked: false,
name: props.url,
})
).toBeDisabled();
});
it('doesnt render the radio if its the custom row', () => {
render(
renderComponent(
@@ -124,6 +124,29 @@ export const RowData = ({
return false;
};
const getIsNodeDisabled = () => {
if (!isValidUrl(url)) {
return true;
}
// if still waiting or query errored disable node
if (loading || error) {
return true;
}
if (subLoading || subError) {
return true;
}
// if we are still waiting for a header entry for this
// url disable the node
if (!headers) {
return true;
}
return false;
};
const getSubFailed = (
subError: ApolloError | undefined,
subFailed: boolean
@@ -137,7 +160,12 @@ export const RowData = ({
<>
{id !== CUSTOM_NODE_KEY && (
<div className="break-all" data-testid="node">
<Radio id={`node-url-${id}`} value={url} label={url} />
<Radio
id={`node-url-${id}`}
value={url}
label={url}
disabled={getIsNodeDisabled()}
/>
</div>
)}
<LayoutCell
-1
View File
@@ -1,6 +1,5 @@
export * from './use-environment';
export * from './use-links';
export * from './use-node-health';
export * from './use-node-switcher-store';
export * from './use-vega-releases';
export * from './use-vega-release';
@@ -1,11 +0,0 @@
import { create } from 'zustand';
export const useNodeSwitcherStore = create<{
dialogOpen: boolean;
setDialogOpen: (isOpen: boolean) => void;
}>()((set) => ({
dialogOpen: false,
setDialogOpen: (isOpen) => {
set({ dialogOpen: isOpen });
},
}));
+56 -55
View File
@@ -1,11 +1,7 @@
import { Fragment } from 'react';
import { Fragment, useState } from 'react';
import { t } from '@vegaprotocol/i18n';
import { Link, Lozenge } from '@vegaprotocol/ui-toolkit';
import {
NodeSwitcherDialog,
useEnvironment,
useNodeSwitcherStore,
} from '@vegaprotocol/environment';
import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment';
const getFeedbackLinks = (gitOriginUrl?: string) =>
[
@@ -23,59 +19,64 @@ export const NetworkInfo = () => {
GITHUB_FEEDBACK_URL,
ETHEREUM_PROVIDER_URL,
} = useEnvironment();
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
const feedbackLinks = getFeedbackLinks(GITHUB_FEEDBACK_URL);
return (
<div data-testid="git-info">
<p data-testid="git-network-data" className="mb-2">
{t('Reading network data from')}{' '}
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
{VEGA_URL}
</Lozenge>
. <Link onClick={() => setNodeSwitcher(true)}>{t('Edit')}</Link>
</p>
<p data-testid="git-eth-data" className="mb-2 break-all">
{t('Reading Ethereum data from')}{' '}
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
{ETHEREUM_PROVIDER_URL}
</Lozenge>
.{' '}
</p>
{GIT_COMMIT_HASH && (
<p data-testid="git-commit-hash" className="mb-2">
{t('Version/commit hash')}:{' '}
<Link
href={
GIT_ORIGIN_URL
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
: undefined
}
target={GIT_ORIGIN_URL ? '_blank' : undefined}
>
{GIT_COMMIT_HASH}
</Link>
<>
<div data-testid="git-info">
<p data-testid="git-network-data" className="mb-2">
{t('Reading network data from')}{' '}
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
{VEGA_URL}
</Lozenge>
. <Link onClick={() => setNodeSwitcherOpen(true)}>{t('Edit')}</Link>
</p>
)}
{feedbackLinks.length > 0 && (
<p>
{t('Known issues and feedback on')}{' '}
{feedbackLinks.map(({ name, url }, index) => (
<Fragment key={index}>
<Link key={index} href={url}>
{name}
</Link>
{feedbackLinks.length > 1 &&
index < feedbackLinks.length - 2 &&
','}
{feedbackLinks.length > 1 &&
index === feedbackLinks.length - 1 &&
`, ${t('and')} `}
</Fragment>
))}
<p data-testid="git-eth-data" className="mb-2 break-all">
{t('Reading Ethereum data from')}{' '}
<Lozenge className="bg-neutral-300 dark:bg-neutral-700">
{ETHEREUM_PROVIDER_URL}
</Lozenge>
.{' '}
</p>
)}
</div>
{GIT_COMMIT_HASH && (
<p data-testid="git-commit-hash" className="mb-2">
{t('Version/commit hash')}:{' '}
<Link
href={
GIT_ORIGIN_URL
? `${GIT_ORIGIN_URL}/commit/${GIT_COMMIT_HASH}`
: undefined
}
target={GIT_ORIGIN_URL ? '_blank' : undefined}
>
{GIT_COMMIT_HASH}
</Link>
</p>
)}
{feedbackLinks.length > 0 && (
<p>
{t('Known issues and feedback on')}{' '}
{feedbackLinks.map(({ name, url }, index) => (
<Fragment key={index}>
<Link key={index} href={url}>
{name}
</Link>
{feedbackLinks.length > 1 &&
index < feedbackLinks.length - 2 &&
','}
{feedbackLinks.length > 1 &&
index === feedbackLinks.length - 1 &&
`, ${t('and')} `}
</Fragment>
))}
</p>
)}
</div>
<NodeSwitcherDialog
open={nodeSwitcherOpen}
setOpen={setNodeSwitcherOpen}
/>
</>
);
};