diff --git a/.github/workflows/publish-dist.yml b/.github/workflows/publish-dist.yml index f8c1c290a..6b1ee0686 100644 --- a/.github/workflows/publish-dist.yml +++ b/.github/workflows/publish-dist.yml @@ -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 > ${{ matirx.app }}-ipfs-hash + docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matrix.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' diff --git a/Makefile b/Makefile index 6d40e13d0..c5bda8cb0 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/apps/explorer/.env b/apps/explorer/.env index 2b9425530..609eae1bf 100644 --- a/apps/explorer/.env +++ b/apps/explorer/.env @@ -13,6 +13,7 @@ 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 diff --git a/apps/explorer/.env.mainnet b/apps/explorer/.env.mainnet index 1491fd823..52f0594fa 100644 --- a/apps/explorer/.env.mainnet +++ b/apps/explorer/.env.mainnet @@ -2,6 +2,7 @@ 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 diff --git a/apps/explorer/.env.stagnet1 b/apps/explorer/.env.stagnet1 index 37d1e4bf7..c9d92b181 100644 --- a/apps/explorer/.env.stagnet1 +++ b/apps/explorer/.env.stagnet1 @@ -1 +1,2 @@ -# .env is stagnet1, so there are no overrides required \ No newline at end of file +# .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"}' diff --git a/apps/explorer/src/app/app.tsx b/apps/explorer/src/app/app.tsx index 7afe05ce2..e17ececb0 100644 --- a/apps/explorer/src/app/app.tsx +++ b/apps/explorer/src/app/app.tsx @@ -1,9 +1,18 @@ -import { NetworkLoader, useInitializeEnv } from '@vegaprotocol/environment'; +import { + AppFailure, + NetworkLoader, + NodeGuard, + NodeSwitcherDialog, + useEnvironment, + useInitializeEnv, + useNodeSwitcherStore, +} 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 = ( @@ -12,10 +21,23 @@ const splashLoading = ( ); function App() { + const { VEGA_URL } = useEnvironment(); + const [nodeSwitcherOpen, setNodeSwitcherOpen] = useNodeSwitcherStore( + (store) => [store.dialogOpen, store.setDialogOpen] + ); return ( - + {t('Loading')}} + failure={} + > + + + ); diff --git a/apps/explorer/src/app/components/footer/footer.tsx b/apps/explorer/src/app/components/footer/footer.tsx index fd9f00c6d..e41fe3253 100644 --- a/apps/explorer/src/app/components/footer/footer.tsx +++ b/apps/explorer/src/app/components/footer/footer.tsx @@ -1,13 +1,19 @@ -import { NodeSwitcherDialog, useEnvironment } from '@vegaprotocol/environment'; +import { + useEnvironment, + useNodeSwitcherStore, +} from '@vegaprotocol/environment'; import { t } from '@vegaprotocol/i18n'; import { useScreenDimensions } from '@vegaprotocol/react-helpers'; import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit'; -import { useMemo, useState } from 'react'; +import { useMemo } from 'react'; import { ENV } from '../../config/env'; export const Footer = () => { const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment(); - const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false); + const setNodeSwitcherOpen = useNodeSwitcherStore( + (store) => store.setDialogOpen + ); + const { screenSize } = useScreenDimensions(); const showFullFeedbackLabel = useMemo( () => ['md', 'lg', 'xl', 'xxl', 'xxxl'].includes(screenSize), @@ -15,46 +21,40 @@ export const Footer = () => { ); return ( - <> - ); }; diff --git a/apps/governance-e2e/src/integration/flow/staking-flow.cy.ts b/apps/governance-e2e/src/integration/flow/staking-flow.cy.ts index f7683bb31..abcdbb8c1 100644 --- a/apps/governance-e2e/src/integration/flow/staking-flow.cy.ts +++ b/apps/governance-e2e/src/integration/flow/staking-flow.cy.ts @@ -7,6 +7,7 @@ import { waitForSpinner, navigateTo, navigation, + turnTelemetryOff, } from '../../support/common.functions'; import { clickOnValidatorFromList, @@ -56,6 +57,7 @@ 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'); @@ -67,6 +69,7 @@ context( 'teardown wallet & drill into a specific validator', function () { cy.clearLocalStorage(); + turnTelemetryOff(); cy.reload(); waitForSpinner(); cy.connectVegaWallet(); @@ -252,10 +255,10 @@ context( waitForBeginningOfEpoch(); cy.getByTestId(stakeValidatorListStakePercentage).should( 'have.text', - '100%' + '50.02%' ); navigateTo(navigation.validators); - validateValidatorListTotalStakeAndShare('0', '2.00', '100.00%'); + validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%'); } ); diff --git a/apps/governance-e2e/src/integration/view/validators.cy.ts b/apps/governance-e2e/src/integration/view/validators.cy.ts index 15186eb37..2c3ffce97 100644 --- a/apps/governance-e2e/src/integration/view/validators.cy.ts +++ b/apps/governance-e2e/src/integration/view/validators.cy.ts @@ -29,7 +29,10 @@ 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*\.?\d*$/; +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 context('Validators Page - verify elements on page', function () { before('navigate to validators page', function () { @@ -84,13 +87,13 @@ context('Validators Page - verify elements on page', function () { cy.get(stakedByOperatorToolTip) .invoke('text') - .should('contain', 'Staked by operator: 0.00'); + .should('contain', 'Staked by operator: 3,000.00'); cy.get(stakedByDelegatesToolTip) .invoke('text') .should('contain', 'Staked by delegates: 0.00'); cy.get(totalStakedToolTip) .invoke('text') - .should('contain', 'Total stake: 0.00'); + .should('contain', 'Total stake: 3,000.00'); }); it('Should be able to see validator normalised voting power', function () { @@ -106,10 +109,10 @@ context('Validators Page - verify elements on page', function () { cy.get(unnormalisedVotingPowerToolTip) .invoke('text') - .should('contain', 'Unnormalised voting power: 0.00%'); + .should('contain', 'Unnormalised voting power: 20.00%'); cy.get(normalisedVotingPowerToolTip) .invoke('text') - .should('contain', 'Normalised voting power: 0.10%'); + .should('contain', 'Normalised voting power: 50.00%'); }); // 2002-SINC-018 @@ -126,13 +129,13 @@ context('Validators Page - verify elements on page', function () { cy.get(performancePenaltyToolTip) .invoke('text') - .should('contain', 'Performance penalty: 100.00%'); + .should('contain', 'Performance penalty: 0.00%'); cy.get(overstakedPenaltyToolTip) .invoke('text') - .should('contain', 'Overstaked penalty:'); // value not asserted due to #2886 + .should('contain', 'Overstaked penalty: 60.00%'); // value not asserted due to #2886 cy.get(totalPenaltyToolTip) .invoke('text') - .should('contain', 'Total penalties: 0.00%'); + .should('contain', 'Total penalties: 60.00%'); }); it('Should be able to see validator pending stake', function () { diff --git a/apps/governance/src/app.tsx b/apps/governance/src/app.tsx index 13e55d089..0e44162cc 100644 --- a/apps/governance/src/app.tsx +++ b/apps/governance/src/app.tsx @@ -37,6 +37,10 @@ import { useEnvironment, NetworkLoader, useInitializeEnv, + NodeGuard, + AppFailure, + NodeSwitcherDialog, + useNodeSwitcherStore, } from '@vegaprotocol/environment'; import { ENV } from './config'; import type { InMemoryCacheConfig } from '@apollo/client'; @@ -48,6 +52,7 @@ import { TELEMETRY_ON, } from './components/telemetry-dialog/telemetry-dialog'; import { useLocalStorage } from '@vegaprotocol/react-helpers'; +import { useTranslation } from 'react-i18next'; const cache: InMemoryCacheConfig = { typePolicies: { @@ -181,9 +186,19 @@ const ScrollToTop = () => { const AppContainer = () => { const { config, loading, error } = useEthereumConfig(); - const { VEGA_ENV, GIT_COMMIT_HASH, GIT_BRANCH, ETHEREUM_PROVIDER_URL } = - useEnvironment(); + const { + VEGA_ENV, + VEGA_URL, + 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) { @@ -219,21 +234,29 @@ const AppContainer = () => {
- - loading={loading} - data={config} - error={error} - render={(cnf) => - cnf && ( - - ) + {t('Loading')}
} + failure={ + } - /> + > + + loading={loading} + data={config} + error={error} + render={(cnf) => + cnf && ( + + ) + } + /> +
+ ); }; diff --git a/apps/governance/src/i18n/translations/dev.json b/apps/governance/src/i18n/translations/dev.json index 8d9df1aca..d714cc82b 100644 --- a/apps/governance/src/i18n/translations/dev.json +++ b/apps/governance/src/i18n/translations/dev.json @@ -811,5 +811,6 @@ "OptOutOfTelemetry": "You can opt out any time via settings", "NoThanks": "No thanks", "ShareData": "Share data", - "ContinueSharingData": "Continue sharing data" + "ContinueSharingData": "Continue sharing data", + "NodeUnsuitable": "Node: {{url}} is unsuitable" } diff --git a/apps/static/src/assets/mainnet-tranches.json b/apps/static/src/assets/mainnet-tranches.json index 68e6a515c..24d490442 100644 --- a/apps/static/src/assets/mainnet-tranches.json +++ b/apps/static/src/assets/mainnet-tranches.json @@ -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": "1523.8177488329475", - "locked_amount": "6891.9471601080244395475", + "total_removed": "1979.64045368475", + "locked_amount": "6088.8928113908174973875", "deposits": [ { "amount": "188", @@ -228,6 +228,16 @@ "user": "0xDd7a98557586ce21f770662319C2047C5a3bD605", "tx": "0x2b3571c143ecebddf91fb62f402d516d51110edfe37b13200a6e5cf682dc5bb0" }, + { + "amount": "336.4580555509875", + "user": "0xf915Da10e5136352Ba049acB0545Deb119054256", + "tx": "0x7af5942634e236f5f9c580f4ed042794ed309e83885f652a55ab37793ea2e85c" + }, + { + "amount": "119.364649300815", + "user": "0xDd7a98557586ce21f770662319C2047C5a3bD605", + "tx": "0x47f5bf2c758c5270dd1b6519ac649ddabef8199f8a0bae319e36f8ac5c9c142e" + }, { "amount": "202.093666077975", "user": "0x1447Efc62d5077d7AbB20492dF831Dd6c9Eb1756", @@ -362,6 +372,12 @@ "tranche_id": 56, "tx": "0x2b3571c143ecebddf91fb62f402d516d51110edfe37b13200a6e5cf682dc5bb0" }, + { + "amount": "119.364649300815", + "user": "0xDd7a98557586ce21f770662319C2047C5a3bD605", + "tranche_id": 56, + "tx": "0x47f5bf2c758c5270dd1b6519ac649ddabef8199f8a0bae319e36f8ac5c9c142e" + }, { "amount": "195.89040769089", "user": "0xDd7a98557586ce21f770662319C2047C5a3bD605", @@ -370,8 +386,8 @@ } ], "total_tokens": "914.25", - "withdrawn_tokens": "504.71220630471", - "remaining_tokens": "409.53779369529" + "withdrawn_tokens": "624.076855605525", + "remaining_tokens": "290.173144394475" }, { "address": "0x9573BDF7FfC5519912d293e4D1f750eab2E471E7", @@ -705,6 +721,12 @@ } ], "withdrawals": [ + { + "amount": "336.4580555509875", + "user": "0xf915Da10e5136352Ba049acB0545Deb119054256", + "tranche_id": 56, + "tx": "0x7af5942634e236f5f9c580f4ed042794ed309e83885f652a55ab37793ea2e85c" + }, { "amount": "422.1034736680125", "user": "0xf915Da10e5136352Ba049acB0545Deb119054256", @@ -713,8 +735,8 @@ } ], "total_tokens": "1121.25", - "withdrawn_tokens": "422.1034736680125", - "remaining_tokens": "699.1465263319875" + "withdrawn_tokens": "758.561529219", + "remaining_tokens": "362.688470781" }, { "address": "0x237D23FcA6d7B2530C7614a9cB921CF27924911E", @@ -877,7 +899,7 @@ "tranche_start": "2023-04-06T00:00:00.000Z", "tranche_end": "2023-05-06T00:00:00.000Z", "total_added": "14610", - "total_removed": "6141.45090157707", + "total_removed": "6675.45090157707", "locked_amount": "0", "deposits": [ { @@ -1077,6 +1099,11 @@ "user": "0x9E53F72210479BF46aE7ABF77c48B0d611b3c3dB", "tx": "0x1dbcf713b48965a82aa2e17cb3e7db9a491668d859d408a39c8a74b0ea860b6b" }, + { + "amount": "534", + "user": "0x2586bA83696a92b5467Aaa0CF9EEC052F28F2c02", + "tx": "0x5aa922056cad64f97a7dfa750da57d63abfdaea4499192d4d57958bfb4fba2ea" + }, { "amount": "106.53500000286", "user": "0x6F32AA5A6198329c16e438512F992a0548C856f9", @@ -1200,10 +1227,17 @@ "tx": "0xf970ea0ce3e36fa0014d24bb830dd2ea0dbea06f6e53af486de5ee7e1c63e540" } ], - "withdrawals": [], + "withdrawals": [ + { + "amount": "534", + "user": "0x2586bA83696a92b5467Aaa0CF9EEC052F28F2c02", + "tranche_id": 54, + "tx": "0x5aa922056cad64f97a7dfa750da57d63abfdaea4499192d4d57958bfb4fba2ea" + } + ], "total_tokens": "534", - "withdrawn_tokens": "0", - "remaining_tokens": "534" + "withdrawn_tokens": "534", + "remaining_tokens": "0" }, { "address": "0xBf1AaB792D729fA125e6D7122D4b916a1E1C44B1", @@ -1826,7 +1860,7 @@ "tranche_start": "2023-03-06T00:00:00.000Z", "tranche_end": "2023-04-06T00:00:00.000Z", "total_added": "14099", - "total_removed": "3722.49002352036", + "total_removed": "3785.49002352036", "locked_amount": "0", "deposits": [ { @@ -2591,6 +2625,11 @@ } ], "withdrawals": [ + { + "amount": "63", + "user": "0x2a65Ae527C6Ff4665e048B0E0883c486A7BA4DBc", + "tx": "0xb0edcc25e422bc3db3ad8027dfdfc0928abd7a8af8957a1699e4cf2dc8cee8f7" + }, { "amount": "30", "user": "0xBe9F912Ad481C61B653463E8F1D2b2b310D49861", @@ -3629,10 +3668,17 @@ "tx": "0xd4a269b070cbaaff7e29a99f6b3997117d765f69512bb760e28bade799fcbba4" } ], - "withdrawals": [], + "withdrawals": [ + { + "amount": "63", + "user": "0x2a65Ae527C6Ff4665e048B0E0883c486A7BA4DBc", + "tranche_id": 53, + "tx": "0xb0edcc25e422bc3db3ad8027dfdfc0928abd7a8af8957a1699e4cf2dc8cee8f7" + } + ], "total_tokens": "63", - "withdrawn_tokens": "0", - "remaining_tokens": "63" + "withdrawn_tokens": "63", + "remaining_tokens": "0" }, { "address": "0xc3B1eB0feE837Db0A3ded5bf16A050726955195B", @@ -4861,7 +4907,7 @@ "tranche_end": "2023-12-05T00:00:00.000Z", "total_added": "86666.297", "total_removed": "0", - "locked_amount": "49802.2753121154213651374", + "locked_amount": "49504.9919953353951513585", "deposits": [ { "amount": "86666.297", @@ -4927,7 +4973,7 @@ "tranche_end": "2023-06-01T00:00:00.000Z", "total_added": "2500", "total_removed": "0", - "locked_amount": "312.4325905575906", + "locked_amount": "295.23443859381355", "deposits": [ { "amount": "2500", @@ -4960,7 +5006,7 @@ "tranche_end": "2023-11-01T00:00:00.000Z", "total_added": "15000.000000000000015", "total_removed": "0", - "locked_amount": "14327.0455917874395143270455917874395", + "locked_amount": "14224.9782986111115142249782986111115", "deposits": [ { "amount": "1.5e-14", @@ -5048,7 +5094,7 @@ "tranche_end": "2023-09-01T00:00:00.000Z", "total_added": "17500", "total_removed": "0", - "locked_amount": "10913.25608896940375", + "locked_amount": "10794.17758026368775", "deposits": [ { "amount": "12500", @@ -5315,7 +5361,7 @@ "tranche_end": "2023-08-01T00:00:00.000Z", "total_added": "37500", "total_removed": "18077.0118744", - "locked_amount": "17350.5026089625535", + "locked_amount": "17091.10506829343025", "deposits": [ { "amount": "7500", @@ -5734,7 +5780,7 @@ "tranche_end": "2023-12-05T00:00:00.000Z", "total_added": "129999.45", "total_removed": "0", - "locked_amount": "49756.837002255673748325", + "locked_amount": "49459.824919096584707505", "deposits": [ { "amount": "129999.45", @@ -5767,7 +5813,7 @@ "tranche_end": "2024-04-01T00:00:00.000Z", "total_added": "54144.7663", "total_removed": "0", - "locked_amount": "48485.46842731635829207292", + "locked_amount": "48300.2481374426486922947", "deposits": [ { "amount": "54144.7663", @@ -5800,7 +5846,7 @@ "tranche_end": "2023-09-03T00:00:00.000Z", "total_added": "62600", "total_removed": "0", - "locked_amount": "20022.5830035514954", + "locked_amount": "19807.852061136476024", "deposits": [ { "amount": "10000", @@ -5993,7 +6039,7 @@ "tranche_end": "2023-09-17T00:00:00.000Z", "total_added": "5000", "total_removed": "0", - "locked_amount": "1791.028665651953", + "locked_amount": "1773.87763191273475", "deposits": [ { "amount": "5000", @@ -7062,7 +7108,7 @@ "tranche_end": "2023-06-02T00:00:00.000Z", "total_added": "1939928.38", "total_removed": "1709370.7872515768348", - "locked_amount": "126202.1342632826843379468", + "locked_amount": "119547.7788438730317094704", "deposits": [ { "amount": "1852091.69", @@ -40934,7 +40980,7 @@ "tranche_end": "2023-06-05T00:00:00.000Z", "total_added": "3732368.4671", "total_removed": "715655.108029600523393", - "locked_amount": "218430.066175628697078272948", + "locked_amount": "208204.638696483881349131871", "deposits": [ { "amount": "1998.95815", @@ -42326,8 +42372,8 @@ "tranche_start": "2022-06-05T00:00:00.000Z", "tranche_end": "2023-12-05T00:00:00.000Z", "total_added": "15870102.715470999700000001", - "total_removed": "871680.07831804700259352", - "locked_amount": "6074226.5757489411253544394273819693295485", + "total_removed": "872635.89843522227071852", + "locked_amount": "6037967.8664430882362406121449295313314409", "deposits": [ { "amount": "16249.93", @@ -42836,6 +42882,11 @@ "user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b", "tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13" }, + { + "amount": "955.820117175268125", + "user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b", + "tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b" + }, { "amount": "10150.87581603206683", "user": "0xe3eB4CF43C072658401996b71D43eE26E573562D", @@ -45010,6 +45061,12 @@ "tranche_id": 2, "tx": "0x625e0c8fb8d5e2dd7fef0359bb396571f7d8aed05a601ddf0f6e6577edb26a13" }, + { + "amount": "955.820117175268125", + "user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b", + "tranche_id": 2, + "tx": "0x4301fcb38d16c1f6aa4a93a18a277a4e77eb3b4565bf98ca6218f6598b78b90b" + }, { "amount": "913.910324501590625", "user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b", @@ -46566,8 +46623,8 @@ } ], "total_tokens": "259998.8875", - "withdrawn_tokens": "159590.522104386423875", - "remaining_tokens": "100408.365395613576125" + "withdrawn_tokens": "160546.342221561692", + "remaining_tokens": "99452.545278438308" }, { "address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c", @@ -48948,7 +49005,7 @@ "tranche_start": "2021-11-05T00:00:00.000Z", "tranche_end": "2023-05-05T00:00:00.000Z", "total_added": "14597706.0446472999", - "total_removed": "6170228.182342542771392682", + "total_removed": "6246751.954791069035514289", "locked_amount": "0", "deposits": [ { @@ -49158,6 +49215,11 @@ } ], "withdrawals": [ + { + "amount": "76523.772448526264121607", + "user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3", + "tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67" + }, { "amount": "1257.7360413991436375", "user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b", @@ -56357,6 +56419,12 @@ } ], "withdrawals": [ + { + "amount": "76523.772448526264121607", + "user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3", + "tranche_id": 3, + "tx": "0x5c4a7a8fbab9c7c5899835a06397ea9f9dfbc434376dd0515482b8ba83944d67" + }, { "amount": "466184.354416277260082874", "user": "0xfc3b2D0b548d3edBb512CeE0Bb79Fb7FaD50AaF3", @@ -56371,8 +56439,8 @@ } ], "total_tokens": "575536.79731735", - "withdrawn_tokens": "499013.024868823735878393", - "remaining_tokens": "76523.772448526264121607" + "withdrawn_tokens": "575536.79731735", + "remaining_tokens": "0" }, { "address": "0xaAeD573103e3f981867C4cd31c6674DE1c8a13c3", @@ -56864,7 +56932,7 @@ "tranche_start": "2021-10-05T00:00:00.000Z", "tranche_end": "2023-04-05T00:00:00.000Z", "total_added": "5778205.3912159303", - "total_removed": "3480901.398845846498418769", + "total_removed": "3492469.400132244009296769", "locked_amount": "0", "deposits": [ { @@ -57009,6 +57077,11 @@ } ], "withdrawals": [ + { + "amount": "11568.001286397510878", + "user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7", + "tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046" + }, { "amount": "58898.87608135458795", "user": "0x83b1a48376E045D26420200345414e6b93066396", @@ -57979,6 +58052,12 @@ } ], "withdrawals": [ + { + "amount": "11568.001286397510878", + "user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7", + "tranche_id": 4, + "tx": "0xd4191eb657ad26e08faddde326514247ae4a88e8aefcc7592590f368010c4046" + }, { "amount": "209431.056913602489122", "user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7", @@ -57987,8 +58066,8 @@ } ], "total_tokens": "220999.0582", - "withdrawn_tokens": "209431.056913602489122", - "remaining_tokens": "11568.001286397510878" + "withdrawn_tokens": "220999.0582", + "remaining_tokens": "0" }, { "address": "0x9058e12e2F32cB1cD4D3123359963D77786477FC", @@ -59069,8 +59148,8 @@ "tranche_start": "2022-06-05T00:00:00.000Z", "tranche_end": "2023-06-05T00:00:00.000Z", "total_added": "472355.6199999996", - "total_removed": "44479.0535455583416", - "locked_amount": "34611.49258501772999518148756976", + "total_removed": "44544.1737890903416", + "locked_amount": "32991.215149911803725776786707268", "deposits": [ { "amount": "3000", @@ -65694,6 +65773,11 @@ "user": "0x0436E2E4EA467f9958403dc56635404EE1bb1E94", "tx": "0x97f5b5ec5ac839a8d182b9267b5d052cb70f9a18b648874337e3d5360b21a5fb" }, + { + "amount": "65.120243532", + "user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472", + "tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180" + }, { "amount": "182.662252664", "user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F", @@ -86287,6 +86371,12 @@ } ], "withdrawals": [ + { + "amount": "65.120243532", + "user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472", + "tranche_id": 5, + "tx": "0x4697229c7f272bd3fc06ecdc1b15143d28e20083e15f1b3cadb3fc80e80af180" + }, { "amount": "120.24984145", "user": "0x3F9E884B459a6AaC3f66b72555611AdE68a7F472", @@ -86295,8 +86385,8 @@ } ], "total_tokens": "200", - "withdrawn_tokens": "120.24984145", - "remaining_tokens": "79.75015855" + "withdrawn_tokens": "185.370084982", + "remaining_tokens": "14.629915018" }, { "address": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46", @@ -144401,6 +144491,11 @@ } ], "withdrawals": [ + { + "amount": "0", + "user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7", + "tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa" + }, { "amount": "0", "user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7", @@ -144696,6 +144791,12 @@ } ], "withdrawals": [ + { + "amount": "0", + "user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7", + "tranche_id": 9, + "tx": "0x7b20f640f6947ca553bb2ffb572e316f155781b051b198911b234c6c40e79eaa" + }, { "amount": "0", "user": "0x759C9ABABA492500c4c730bEB568B5b851Dec2c7", diff --git a/apps/trading-e2e/src/integration/closed-markets.cy.ts b/apps/trading-e2e/src/integration/closed-markets.cy.ts index a80f0ce47..0c63d9964 100644 --- a/apps/trading-e2e/src/integration/closed-markets.cy.ts +++ b/apps/trading-e2e/src/integration/closed-markets.cy.ts @@ -12,6 +12,7 @@ import { createMarketsDataFragment, assetQuery, networkParamsQuery, + nodeGuardQuery, } from '@vegaprotocol/mock'; import { addDecimalsFormatNumber, @@ -158,6 +159,7 @@ 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, diff --git a/apps/trading-e2e/src/support/trading.ts b/apps/trading-e2e/src/support/trading.ts index 99691e270..17b9f35f0 100644 --- a/apps/trading-e2e/src/support/trading.ts +++ b/apps/trading-e2e/src/support/trading.ts @@ -20,6 +20,7 @@ import { marketsDataQuery, marketsQuery, networkParamsQuery, + nodeGuardQuery, ordersQuery, positionsQuery, proposalListQuery, @@ -82,6 +83,7 @@ const mockTradingPage = ( ) => { aliasGQLQuery(req, 'ChainId', chainIdQuery()); aliasGQLQuery(req, 'Statistics', statisticsQuery()); + aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery()); aliasGQLQuery( req, 'Markets', diff --git a/apps/trading/components/app-loader/app-loader.tsx b/apps/trading/components/app-loader/app-loader.tsx index 8a63dd8cb..64e9ac040 100644 --- a/apps/trading/components/app-loader/app-loader.tsx +++ b/apps/trading/components/app-loader/app-loader.tsx @@ -1,5 +1,6 @@ import type { InMemoryCacheConfig } from '@apollo/client'; import { + AppFailure, NetworkLoader, NodeGuard, useEnvironment, @@ -9,7 +10,6 @@ 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'), { diff --git a/apps/trading/components/app-loader/index.tsx b/apps/trading/components/app-loader/index.tsx index 624edba38..2a7420559 100644 --- a/apps/trading/components/app-loader/index.tsx +++ b/apps/trading/components/app-loader/index.tsx @@ -1,3 +1,2 @@ -export * from './app-failure'; export * from './app-loader'; export * from './web3-provider'; diff --git a/apps/trading/components/footer/footer.spec.tsx b/apps/trading/components/footer/footer.spec.tsx index 4ddfbbd0c..9e8a77c31 100644 --- a/apps/trading/components/footer/footer.spec.tsx +++ b/apps/trading/components/footer/footer.spec.tsx @@ -4,18 +4,15 @@ 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', })), -})); - -const mockSetNodeSwitcher = jest.fn(); -jest.mock('../../stores', () => ({ - ...jest.requireActual('../../stores'), - useGlobalStore: () => mockSetNodeSwitcher, + useNodeSwitcherStore: jest.fn(() => mockSetNodeSwitcher), })); describe('NodeHealth', () => { diff --git a/apps/trading/components/footer/footer.tsx b/apps/trading/components/footer/footer.tsx index 8fdaa7f08..dd45db002 100644 --- a/apps/trading/components/footer/footer.tsx +++ b/apps/trading/components/footer/footer.tsx @@ -1,11 +1,14 @@ import { useCallback } from 'react'; -import { useEnvironment, useNodeHealth } from '@vegaprotocol/environment'; +import { + useEnvironment, + useNodeHealth, + useNodeSwitcherStore, +} 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 ( @@ -20,9 +23,7 @@ export const Footer = () => { export const NodeHealth = () => { const { VEGA_URL, VEGA_INCIDENT_URL } = useEnvironment(); - const setNodeSwitcher = useGlobalStore( - (store) => (open: boolean) => store.update({ nodeSwitcherDialog: open }) - ); + const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen); const { datanodeBlockHeight, text, intent } = useNodeHealth(); const onClick = useCallback(() => { setNodeSwitcher(true); diff --git a/apps/trading/pages/_app.page.tsx b/apps/trading/pages/_app.page.tsx index 05c86867e..1d1074b86 100644 --- a/apps/trading/pages/_app.page.tsx +++ b/apps/trading/pages/_app.page.tsx @@ -21,9 +21,10 @@ import { NodeSwitcherDialog, useEnvironment, useInitializeEnv, + useNodeSwitcherStore, } from '@vegaprotocol/environment'; import './styles.css'; -import { useGlobalStore, usePageTitleStore } from '../stores'; +import { usePageTitleStore } from '../stores'; import { Footer } from '../components/footer'; import DialogsContainer from './dialogs-container'; import ToastsManager from './toasts-manager'; @@ -115,11 +116,10 @@ function AppBody({ Component }: AppProps) { function VegaTradingApp(props: AppProps) { const status = useEnvironment((store) => store.status); - const { nodeSwitcherOpen, setNodeSwitcher } = useGlobalStore((store) => ({ - nodeSwitcherOpen: store.nodeSwitcherDialog, - setNodeSwitcher: (open: boolean) => - store.update({ nodeSwitcherDialog: open }), - })); + const [nodeSwitcherOpen, setNodeSwitcher] = useNodeSwitcherStore((store) => [ + store.dialogOpen, + store.setDialogOpen, + ]); useInitializeEnv(); diff --git a/apps/trading/stores/global.ts b/apps/trading/stores/global.ts index aac6a71b9..f631d6827 100644 --- a/apps/trading/stores/global.ts +++ b/apps/trading/stores/global.ts @@ -3,7 +3,6 @@ import { create } from 'zustand'; import produce from 'immer'; interface GlobalStore { - nodeSwitcherDialog: boolean; marketId: string | null; update: (store: Partial>) => void; shouldDisplayWelcomeDialog: boolean; @@ -15,7 +14,6 @@ interface PageTitleStore { } export const useGlobalStore = create()((set) => ({ - nodeSwitcherDialog: false, marketId: LocalStorage.getItem('marketId') || null, shouldDisplayWelcomeDialog: false, update: (newState) => { diff --git a/docker/prepare-dist.sh b/docker/prepare-dist.sh index af3c51fdd..1f5f2b290 100755 --- a/docker/prepare-dist.sh +++ b/docker/prepare-dist.sh @@ -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 diff --git a/libs/candles-chart/src/lib/data-source.spec.ts b/libs/candles-chart/src/lib/data-source.spec.ts new file mode 100644 index 000000000..50cc226b0 --- /dev/null +++ b/libs/candles-chart/src/lib/data-source.spec.ts @@ -0,0 +1,280 @@ +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[] } = + { + [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; + + 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, + }); + }); + }); +}); diff --git a/libs/candles-chart/src/lib/data-source.ts b/libs/candles-chart/src/lib/data-source.ts index 237cadad2..fb1e7494a 100644 --- a/libs/candles-chart/src/lib/data-source.ts +++ b/libs/candles-chart/src/lib/data-source.ts @@ -1,4 +1,11 @@ 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'; @@ -153,7 +160,6 @@ export class VegaDataSource implements DataSource { }, fetchPolicy: 'no-cache', }); - if (data?.market?.candlesConnection?.edges) { const decimalPlaces = data.market.decimalPlaces; const positionDecimalPlaces = data.market.positionDecimalPlaces; @@ -163,8 +169,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 []; @@ -213,6 +219,85 @@ 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, diff --git a/libs/cypress/mock.ts b/libs/cypress/mock.ts index 3c90c5cda..d2aff6cfc 100644 --- a/libs/cypress/mock.ts +++ b/libs/cypress/mock.ts @@ -7,6 +7,7 @@ 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'; diff --git a/apps/trading/components/app-loader/app-failure.tsx b/libs/environment/src/components/app-failure/app-failure.tsx similarity index 65% rename from apps/trading/components/app-loader/app-failure.tsx rename to libs/environment/src/components/app-failure/app-failure.tsx index 842db1e2c..7afb9e4c3 100644 --- a/apps/trading/components/app-loader/app-failure.tsx +++ b/libs/environment/src/components/app-failure/app-failure.tsx @@ -1,6 +1,6 @@ import { t } from '@vegaprotocol/i18n'; import { Button } from '@vegaprotocol/ui-toolkit'; -import { useGlobalStore } from '../../stores'; +import { useNodeSwitcherStore } from '../../hooks/use-node-switcher-store'; export const AppFailure = ({ title, @@ -9,17 +9,13 @@ export const AppFailure = ({ title: string; error?: string | null; }) => { - const { setNodeSwitcher } = useGlobalStore((store) => ({ - nodeSwitcherOpen: store.nodeSwitcherDialog, - setNodeSwitcher: (open: boolean) => - store.update({ nodeSwitcherDialog: open }), - })); + const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen); const nonIdealWrapperClasses = 'h-full min-h-screen flex items-center justify-center'; return (
-

{title}

+

{title}

{error &&

{error}

}