Compare commits

..
Author SHA1 Message Date
Madalina Raicu 99f05ebe57 fix: create custom ID for liquidity provision entries 2022-11-14 13:08:31 -05:00
Madalina Raicu 41ca079814 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-13 20:04:39 -05:00
mattrussell36 f54017a5d5 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-14 00:09:59 +00:00
mattrussell36 f97821b9f8 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-13 18:04:29 +00:00
mattrussell36 17dcaa1add chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-13 12:05:13 +00:00
mattrussell36 c6e10816dd chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-13 06:04:19 +00:00
mattrussell36 bc81ac71a4 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-13 00:10:13 +00:00
mattrussell36 97291757c0 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-12 18:06:46 +00:00
mattrussell36 464cbc0630 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-12 12:05:41 +00:00
mattrussell36 3cca733048 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-12 06:05:17 +00:00
mattrussell36 adcab595cf chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-12 00:10:58 +00:00
m.ray ff4c998853 fix: remove NX_VEGA_URL from .env in trading app (#2044) 2022-11-11 11:04:37 -08:00
mattrussell36 123cdb11d5 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-11 18:04:48 +00:00
m.ray 43aed3de6e fix: remove NX_VEGA_URL from trading console (#2042)
* fix: remove NX_VEGA_URL that points to one default node

* Update apps/trading/.env
2022-11-11 17:48:58 +00:00
Madalina Raicu 38c76f24a3 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-11 16:35:08 +00:00
m.ray f702df5ce5 fix: use estimate order query with simple order size, no open volume check (#2038)
* fix: use estimate order query with simple order size, no open volume check

* fix:  update console-lite-e2e to use stagnet3
2022-11-11 16:23:17 +00:00
m.ray 011ea97d23 fix: estimate order margin query asset decimal places fix (#2029)
* fix: estimate margin and fees update fix - use asset dp and normalize

* fix: update styling in fees breakdown component

* fix: fix cypress tests

* fix: format with asset dp only in react components

* fix: fix number formattingcd

* fix: remove comment

* fix: rename getMaximumDigitsNumberFormat

* fix: fix console-lite cypress tests
2022-11-11 14:44:53 +00:00
Sam Keen d3cb3896f4 fix(1837): account for proposal vote and enactment deadlines being uncoupled (#2005)
* Fix/1837: Remove 2 seconds from proposal vote deadline on submission to ensure the deadline is always slightly below the maximum the API accepts

* fix(1837): Adjust for vote deadline and enactment deadline being decoupled in the API

* fix(1837): Removed unnecessary dependencies

* fix(1837): A couple of extra tests for get-enactment-timestamp

* fix(1837): propose-update-asset.tsx tweaked to ensure max enactment button works properly
2022-11-11 14:30:03 +00:00
Sam Keen 266f87be8f feat(#1879): refactored delegations api query (#2021)
* feat(1879): Delegations - removed from explorer queries as currently unused

* feat(1879): Delegations - used delegationsConnection in vega-wallet

* feat(1879): Delegations - updated Token staking form to use new api and query

* feat(1879): updated Token staking info and validator table to use new delegations api
2022-11-11 13:47:29 +00:00
Radosław Szpiech bae5d6069a fix: deal ticket dates set to next day (#2035)
* fix: deal ticket dates set to next day

* fix: fix
2022-11-11 14:28:55 +01:00
Joe Tsang 3df69788fb chore: update pipelines to use v0.62.1 (#2030) 2022-11-11 14:28:20 +01:00
Dexter Edwards 85120c0a3b ci: fix verify workflow tirggers (#2032) 2022-11-11 12:45:38 +00:00
mattrussell36 f278a0bada chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-11 12:04:21 +00:00
Art f2688c33b6 fix(1854): view asset launches deposit (#2026) 2022-11-11 11:45:50 +00:00
Madalina Raicu ab1308316f Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-11 10:44:16 +00:00
Matthew Russell 38030ba1ec chore: make apps use stagnet3 as default env (#2024) 2022-11-11 11:06:47 +01:00
Dexter Edwards cdff4886b2 chore: remove dead sorting logic (#2016)
* chore: remove dead sorting logic

* style: lint

* style: lint
2022-11-11 09:08:49 +00:00
mattrussell36 d5045b8ec4 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-11 06:04:32 +00:00
mattrussell36 053d83876f chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-11 00:10:42 +00:00
botond 0a3a7467d4 fix: remove new typegen files from console-lite to fix typegen errors (#2022) 2022-11-10 15:10:37 -08:00
m.ray e0b2fb9bf3 fix: deal ticket fees value formatting (#2014)
* fix: #2002 use asset dp for estimate order

* Update libs/deal-ticket/src/hooks/use-fee-deal-ticket-details.tsx

* fix: fix linting issue for format value with market dp
2022-11-10 12:09:32 -08:00
Bartłomiej Głownia 25699b6283 feat(#1643): orders table filtering (#2000)
* feat(#1643): add grid set filter, amend filters in orders table

* feat(#1643): strictly type variables in orders data provider

* feat(#1643): add date range param to orders query

* feat(#1643): add date range filter

* feat(#1643): handle data provider updates after variables change in ag-grid infinite row model

* feat(#1643): fix unit tests

* feat(#1643): use DateRangeFilter in positions table instead of agDateColumnFilter

* feat(#1643): add date range filter support to orders data provider

* feat(#1643): fix update functions

* feat(#1643): remove sortable from orders list columns

* chore: remove console.log
2022-11-10 11:08:13 -08:00
m.ray 7ba72e3c8c feat: #1853 filter ledger entries by date (#2018) 2022-11-10 18:51:29 +00:00
Art 0ec511a72f feat: 1655 persist deal ticket, 1694 GTT in the past (#1865) 2022-11-10 19:06:10 +01:00
mattrussell36 82c8b4a0e5 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-10 18:05:12 +00:00
Edd f15259de3f fix(#2012): fix mainnet block explorer (#2020)
* chore(explorer): add urls for mainnet explorer api
2022-11-10 16:24:19 +00:00
macqbatandmaciek 4435fe6ea0 chore: upgrade ag-grid version (#2019)
* chore: upgrade ag-grid version

* chore: overwrite ag-grid css wrong css

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-11-10 16:19:59 +00:00
botond df8a22a19e chore: migrate withdrawals lib (#2009)
* chore: cleanup lib types

* chore: migrate withdrawals

* fix: withdrawals query and types

* fix: types

* fix: orders build

* fix: withdraws build

* fix: format

* fix: more build stuff in withdrawal lib

* fix: format

* fix: more withdrawal builds

* fix: format

* fix: orders build again

* fix: remaining build errors

* fix: format

* fix: withdrawal tests

* fix: trick git to pick up file rename?

* fix: rename back to orders

* fix: rename generated file
2022-11-10 14:13:58 +00:00
Ciaran McGhie 045454b484 feat(1355): lp dashboard adding equity like share (#2017)
* refactor: use the lpAggregatedDataProvider rather than liquidityProvisionsDataProvider

The lpAggregatedDataProvider seems to provide the same data as the
liquidityProvisionsDataProvider, but also contains further details that
we'll need for other fields on the liquitidy provider details page.

* feat: replace GALPS with equity-like share and fetch value from LiquidityProviderFeeShare

Updates the type for LiquidityProviders prop to more accurately reflect
that we're using the data from lpAggregatedDataProvider, which includes
the fee share data.

We use the fee share data to display equity-like share % for each LP, and
have replaced GALPS, which was previously empty, with this value.
2022-11-10 14:08:57 +00:00
Dexter Edwards dccc750154 fix(1758): data node being down (#1871)
* fix: timeout data node requests for node switcher

* chore: generate apollo client library

* chore: migrate console lite to use new apollo client package

* chore: migrate explorer across

* chore: remove completely unused file

* chore: migrate stats

* chore: migrate trading

* chore: migrate multisigner app

* chore: migrate token over

* chore: final migrations

* test: adjust tests for new behaviour

* fix: build script

* Update libs/apollo-client/src/lib/apollo-client.ts

* chore: fix conflicts

* fix: cache

* test: setup mocks before each test

* style: lint

* style: lint

* chore: resolve conflicts

* test: fix tests
2022-11-10 13:08:12 +00:00
mattrussell36 d0d06bd4ab chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-10 12:05:32 +00:00
Sam Keen 7f8185372d chore(1987): persist ui behind dialog when staking (#1997)
* Chore/1987: Persist UI behind dialog when staking

* feat(1987): Placed staking form tx status notifications in separate component
2022-11-10 11:31:11 +00:00
Radosław Szpiech 4fedd94243 test: add orders for market in auction (#2008) 2022-11-10 11:56:48 +01:00
Joe Tsang 6a0ec22ee4 chore(test updates): fix withdrawal tests (#2007)
* chore: update withdrawal tests

* chore: fix teardown for manual flow

* chore: add wait

* chore: remove waits

* chore: update vega to v 0.62

* chore: reload page for first withdrawal

* chore: add navigate to withdrawals

* chore: add click

* fix: lint

* chore: turn off teardown and revert tag change
2022-11-10 09:53:30 +00:00
mattrussell36 9a987f752c chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-10 06:04:25 +00:00
m.ray f6c2a7aa56 chore(#1972): delete deposit page and update deposit cypress tests (#1990)
* fix: #1972 update deposit cypress tests and delete deposit trading page

* fix: #1972 remove portfolio/deposit route
2022-11-09 16:45:30 -08:00
mattrussell36 d099c94378 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-10 00:09:53 +00:00
mattrussell36 4d45167e20 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-09 18:04:13 +00:00
macqbatandmaciek 8d2c3ba4ad chore: handle overlapping text in price cell (#1988)
* feat: filter assets to withdraw - add logic for filtering out zero balanced accounts

* chore: handle overlapping text in price cell - add title with value

* chore: handle overlapping text in price cell - add title with value

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-11-09 13:47:01 +01:00
mattrussell36 6bf5b42a79 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-09 12:05:59 +00:00
Elmar cb9ceb2f7d fix(explorer): reduce limit of txs from 100 to 20 (#1985) 2022-11-09 09:34:16 +00:00
macqbatandmaciek b4ab94b54b chore: filter assets to withdraw (#1974)
* feat: filter assets to withdraw

* feat: filter assets to withdraw - add some test

* feat: filter assets to withdraw - add some test

* feat: filter assets to withdraw - add logic for filtering out zero balanced accounts

* feat: filter assets to withdraw - add logic for filtering out zero balanced accounts

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-11-09 09:23:23 +01:00
mattrussell36 2983d5461c chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-09 06:05:02 +00:00
Matthew Russell 5666b8f8e4 chore: add custom export executor for next app (#1999)
* chore: add custom export executor for next app

* chore: update tsconfig path for export executor
2022-11-08 18:59:49 -08:00
Matthew Russell 71e8235faf chore(#1905): updates to accomodate changes to datasource apis (#1919)
* chore: updates to accomodate change to datasource apis

* chore: update types for proposal submission

* chore: update queries to work with latest core changes
2022-11-08 17:05:48 -08:00
mattrussell36 d3e79b76d5 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-09 00:10:56 +00:00
mattrussell36 fbc8cf2511 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-08 18:04:49 +00:00
Joe Tsang 3ff6514cf8 chore(token tests): update failing tests (#1995)
* chore: update capsule files

* chore: fix failing staking tests

* chore: move capsule teardown var to cypress config

* chore: update teardown in workdflows
2022-11-08 17:44:01 +00:00
malinantonsson 0d69ffb4a8 feat(#1355): liquidity provision dashboard details (#1802)
* feat: generate new nx application

* feat: add env variables & render a headline

* feat: add cypress projectId and delete unused files

* feat: render LP grid

* feat: create liquidity provision lib

* feat: liquidity provision calculate volume

* feat: add volume change, generate types

* feat: add EnvironmentProvider

* feat: add LP health bar

* feat: liquidity provision health

* feat: liquidity provider dashboard healthbars

* feat: liquidity provider dashnoard - add auction trigger

* feat: liquidity provider dashboard - display multiple fees

* feat: liquidity provision provider refactor

* feat: liquidity provision provider refactor

* feat: liquidity provision dashboard - add router

* feat: liquidity provision open details in new window

* feat: liquidity provision details page

* feat: liquidity provision details volume

* feat: liquidity provision formatting

* feat: move market candle providers

* feat: liquidity provision styles

* feat: add liquidity provision status

* feat: liquidity provision details

* feat: liquidity move colors

* feat: liquidty provision details

* feat: fix merge

* Feat/lp health bar redesign (#1903)

* feat: liquidity provision details page

* feat: liquidity provision details

* feat: liquidity health bar redesign

* feat: fix merge

* feat: health bar redesign

* feat: add vega colors
2022-11-08 17:43:35 +00:00
Madalina Raicu 3f3c0e18ab Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-08 16:14:53 +00:00
Radosław Szpiech 5cf6c11d36 chore: change condition check directly in test job (#1989)
It fixes the issue with required jobs in PR.
2022-11-08 16:58:46 +01:00
Matthew Russell 12ae6477a9 ci: add check for pr title (#1973)
* chore: addd lint_pr workflow

* ci: add workflow for commitlint on pr title

* ci: install and use config-conventional

* ci: add npx so command is found

* ci: update action name
2022-11-08 15:38:30 +00:00
Radosław Szpiech 205f348a01 fix: add missing yarn install in provision workflow (#1986) 2022-11-08 13:07:50 +00:00
Radosław Szpiech 55725930d7 Fix/fix wallet issue (#1983)
fix: change boolean to strings in conditionals
2022-11-08 14:01:37 +01:00
mattrussell36 23d548ffbb chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-08 12:05:14 +00:00
Radosław Szpiech 77bb148a70 fix: output path fixed to trigger jobs (#1978) 2022-11-08 12:21:29 +01:00
GordsportandDexter 37882378b6 chore: update add issues to project action (#1975)
* chore: update add issues to project action

chore: update add issues to project action

The GitHub projects API has been replaced with ProjectsV2. This PR corrects the add issues to project action.

* style: fix formatting

Co-authored-by: Dexter <dexter.edwards93@gmail.com>
2022-11-08 11:07:10 +00:00
Radosław Szpiech 64b06ca801 chore(#1897): create separate e2e workflows to be run in parallel (#1969)
* test: modify existing workflows to make them run specific tests on separate runners

* chore: increase token-e2e job timeout
2022-11-08 10:33:22 +00:00
Madalina Raicu 29e7a9de03 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-08 10:11:34 +00:00
Matthew Russell c576037b58 chore(#1873): trading hash router (#1921)
* chore: make liquidity page client side only

* chore: switch to hash based router

* chore: add index files for each page

* chore: tidy up _app

* chore: convert to use useRoutes

* fix: active state with react-router NavLink

* feat: add routes enum

* chore: restrict link and router imports from next

* chore: update testing navigation to use hash routes

* fix: typoe in eslint rule message

* chore: remove unnecessary getInitialProps function definition

* chore: wrap tests with memory router

* chore: delete unused index.page file

* chore: update suspense fallback state

* chore: add comment for link component span usage, update link to use toolkit styles

* chore: fix lint issues

* chore: delete client deposit page

* chore: revert title in _app so title gets set correctly without rerender

* revert: removal of deposit page so deposit e2e tests still pass

* chore: move client router to index page so valid status codes are still sent

* fix: wrong route path for markets page, cypress tests
2022-11-08 08:23:38 +01:00
mattrussell36 8542f6c5d8 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-08 06:04:18 +00:00
Matthew RussellandMadalina Raicu 9b360af2c1 feat(#862): show current node and button to open node switcher (#1894)
* feat: add node url to footer, add link to change node

* feat: add test for trading footer

* chore: add comment about url manipulation

* fix: #862 fix cypress tests

* fix: #862 remove constant link

Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2022-11-07 16:53:43 -08:00
mattrussell36 b4a20042d3 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-08 00:10:25 +00:00
m.ray fe09ed9c0f fix: #1826 fix vega docs links (#1967) 2022-11-07 18:12:40 +00:00
mattrussell36 39652bda98 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-07 18:04:39 +00:00
Sam Keen d026c9bdd6 Feat/1513: Vote buttons using subscription and dialog for tx (#1943)
* Feat/1513: Vote buttons using subscription and dialog for tx

* Feat/1513: Staking journey using dialog

* Feat/1513: Cleaning up unused imports

* Feat/1513: Format tweak
2022-11-07 17:46:57 +00:00
EddandDexter e31422ae82 Add some (not very important) unit test coverage for token (#1963)
* chore(token): add some low value lib unit tests

* fix: use native number simplification

Co-authored-by: Dexter <dexter.edwards93@gmail.com>
2022-11-07 17:46:44 +00:00
Sam Keen 927b2a86d1 Feat/1924: Reward details API queries refactor (#1966)
* Feat/1924: Reward details API queries refactor. Also now shows rewards of any asset type

* Lint fix
2022-11-07 17:46:35 +00:00
Dexter EdwardsandSam Keen 113eb90469 Chore/list asset (#1964)
* chore: add whitelist asset function

* feat: add whitelist button

* test: fix tests for proposal form

* test: add tests for new component

* chore: revert incorectly comitted changes

* Update apps/token/src/routes/governance/components/proposal/proposal.spec.tsx

Co-authored-by: Sam Keen <samuel@vegaprotocol.io>

Co-authored-by: Sam Keen <samuel@vegaprotocol.io>
2022-11-07 17:17:03 +00:00
Sam Keen e5432888aa Fix/1831: External link component used for proposals docs/explorer links (#1956)
* Fix/1831: External link component used for proposals docs/explorer links

* proposal-form-terms.tsx docs link no longer needs to be rendered if a docs link isn't provided
2022-11-07 15:40:08 +00:00
Elmar 5a764d190f Feat/1416 tx detail (#1953)
* chore(explorer): add new vega colours to tw config

* feat(explorer): add new nested data list component

* feat(explorer): abstract page header with copy to new component

* feat(explorer): update styles tx details page

* fix(explorer): linting errors

* fix(explorer): fix txs type

* fix(explorer): fix strong typing

* fix(explorer): fix styling error for e2e test
2022-11-07 15:36:39 +00:00
Dexter Edwards da99e731fa Chore/1925 network params (#1927)
* chore: remove network parameters query from token that was unused

* chore: begin migrating network parameters queries

* chore: more network parameter query migrations

* chore: more network params query migrations

* test: fix tests

* test: fix tests in web3 provider

* test: fix remaining tests

* test: fix e2e test build

* chore: move generic params helper into react helpers

* chore: missed migration

* chore: more migrations

* test: fix test

* test: final test migrations

* fix: e2e test mock

* chore: update type

* chore: update helper script

* test: fix query

* test: fix reduce logic

* test: fix query aliasing
2022-11-07 14:57:35 +00:00
macqbatandmaciek dc5881b71b chore: fix update results from dataProvider when variable change (#1962)
* chore: fix race conditions in useDataProvider hook

* chore: fix race conditions in useDataProvider hook - populate fix to other modules

* chore: fix race conditions in useDataProvider hook - populate fix to other modules

* chore: fix race conditions in useDataProvider hook - populate fix to other modules

* chore: fix race conditions in useDataProvider hook - populate fix to other modules

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-11-07 13:14:21 +01:00
Sam Keen e2b789000c Fix/1847: Withdrawal form displaying lack of assets when connected with an uninitialised party id (#1960) 2022-11-07 12:08:30 +00:00
mattrussell36 a853f91ca2 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-07 12:06:24 +00:00
Madalina Raicu 8b4d8895fc Merge branches 'develop' and 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-07 10:28:44 +00:00
mattrussell36 c58677bc2b chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-07 06:04:23 +00:00
mattrussell36 aebf9eb1ca chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-07 00:10:43 +00:00
mattrussell36 080c444ee1 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-06 18:05:03 +00:00
Madalina Raicu 36b2f9a5a9 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-06 12:56:19 +00:00
mattrussell36 d17dc6fc58 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-06 12:05:21 +00:00
mattrussell36 b970406e3c chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-06 06:04:45 +00:00
mattrussell36 c38be57511 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-06 00:12:28 +00:00
mattrussell36 bebe8e783a chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-05 18:05:11 +00:00
mattrussell36 bf04d6ace7 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-05 12:04:44 +00:00
mattrussell36 9a10adebcf chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-05 06:04:46 +00:00
mattrussell36 5b6a77dec5 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-05 00:11:06 +00:00
mattrussell36 31145cbf6b chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-04 18:04:29 +00:00
Radosław Szpiech 58caf0733d test: add separate workflows for each app (#1958) 2022-11-04 14:13:54 +01:00
mattrussell36 6dca9b88c6 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-04 12:05:48 +00:00
Madalina Raicu 962f5041ec Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-04 11:56:17 +00:00
Art 7e52f25e27 chore: 1638 deposit flow (#1928) 2022-11-04 10:47:53 +00:00
Art 28b38c3ebf feat: ledger entries (#1944) 2022-11-04 10:47:39 +00:00
m.ray 750d6a31eb fix: #1639 use connected button to populate eth address in withdrawal dialog (#1954) 2022-11-04 10:42:37 +00:00
mattrussell36 7d14b95ce3 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-04 06:04:33 +00:00
mattrussell36 b41b415b72 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-04 00:10:30 +00:00
mattrussell36 0c7485bc56 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-03 18:04:38 +00:00
Dexter 57446c508a fix: multisigner app 2022-11-03 17:21:08 +00:00
Sam Keen 999c768090 Feat/1912: visual improvements to validator table (#1949)
* Feat/1912: pinned validator column so that it's unaffected by scrolling

* Feat/1912: spacing
2022-11-03 15:19:07 +00:00
macqbatandmaciek 596c273657 Bug/1686 decimal issues with size and price (#1938)
* chore: fix order validation when market is in pending state

* chore: fix order validation when market is in pending state

* chore: fix order validation when market is in pending state

* chore: fix order validation when market is in pending state - add some urgent memo

* chore: fix order validation when market is in pending state - add unit test

* chore: fix order validation when market is in pending state - add memos in right places

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-11-03 15:17:44 +00:00
m.ray e36d571cbf fix: #1678 consistent no data state (#1950) 2022-11-03 12:57:16 +00:00
m.ray 769828a39d Fix/1763 trade futures (#1948)
* feat: #1763 display the product type in select market lists

* fix: #1763 add on top of deal ticket button notice that you are buying product type contracts

* fix: #1763 remove message above deal-ticket button

* fix: #1763 left align product type title

* fix: #1763 header align left for product type
2022-11-03 12:57:06 +00:00
mattrussell36 64ce0e9c44 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-03 12:04:40 +00:00
mattrussell36 9f36033199 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-03 06:04:26 +00:00
mattrussell36 8053aa714c chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-03 00:10:57 +00:00
mattrussell36 6f61fbd460 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-02 18:05:08 +00:00
Madalina Raicu 2c881cf35e Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-02 16:25:45 +00:00
Bartłomiej Głownia f4de989852 fix(#1740): fix market candles subscription update (#1937) 2022-11-02 15:47:15 +00:00
macqbatandmaciek 0ee6773cb6 Feat/1657 show deal ticket errors contextually (#1900)
* feat: deal ticket contextual validation

* feat: deal ticket contextual validation

* feat: show deal ticket errors contextually

* feat: show deal ticket errors contextually

* feat: show deal ticket errors contextually

* feat: show deal ticket errors contextually - adjust int tests

* feat: show deal ticket errors contextually - adjust size and price sections

* feat: show deal ticket errors contextually - fix lin failings

* feat: show deal ticket errors contextually - use set timeout for create a transition effect

* feat: show deal ticket errors contextually - removing animations

* feat: show deal ticket errors contextually - reove unnecessary cast of section prop

* feat: show deal ticket errors contextually - reove unnecessary cast of section prop

* feat: show deal ticket errors contextually - add clickable order button, refactor error passing

* feat: show deal ticket errors contextually - fix market-info int tests

* feat: show deal ticket errors contextually - fix market-trade int tests

* feat: show deal ticket errors contextually - add back price after reset

* feat: show deal ticket errors contextually - remove reset after sent

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-11-02 16:45:23 +01:00
mattrussell36 25eac19ac1 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-02 12:05:11 +00:00
Dexter Edwards c338ce0046 chore: migrate nodes queries (#1923)
* chore: migrate nodes queries

* chore: fix tests

* chore: migrate nodes list over to new typings
2022-11-02 11:48:11 +00:00
Bartłomiej Głownia e4baf5caee chore(#1932): make positions table fill available space (#1933)
* chore(#1932): make positions table fill available space

* chore: switch console-lite e2e fron stagnet to testnet
2022-11-02 12:45:18 +01:00
Bartłomiej Głownia 3415c8d86c feat(1646): add positions table sorting and filtering (#1920)
* feat(1646): add positions table sorting and filtering

* feat(1646): add positions table sorting and filtering - fixes
2022-11-02 08:01:40 +01:00
mattrussell36 186bcfa95a chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-02 06:08:06 +00:00
mattrussell36 10219a508b chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-02 00:09:51 +00:00
Matthew Russell d87ab9cad7 chore: update wallet link in wallet UI (#1918) 2022-11-01 15:37:18 -07:00
Matthew RussellandMadalina Raicu cd5f769c02 chore: adjust margin requirement spacing (#1922)
Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2022-11-01 18:45:30 +00:00
mattrussell36 f242cb9772 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-01 18:04:29 +00:00
mattrussell36 9a0851bec0 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-01 12:05:52 +00:00
Madalina Raicu 94c6bdf234 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-11-01 11:26:55 +00:00
m.ray 3e970f7023 fix: 1875 & 1876 fix deal ticket fees display and remove insignificant trailing zeros (#1898) 2022-11-01 11:03:29 +00:00
marco 082683a541 change label (#1917) 2022-11-01 09:48:58 +00:00
Dexter Edwards 92be8dfabf Chore/1877 deprecated apis stake (#1914)
* chore: generate types

* chore: remove type policy as it is bad

* chore: migrate all usages of depreacted stake field

* chore: fix build
2022-11-01 09:38:02 +00:00
AndyWhiteVega fc309e7409 Test/block exp parties test fixes (#1907)
* test: fix tests

* test: re-instate comments
2022-11-01 09:22:24 +00:00
mattrussell36 60268d4fc7 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-01 06:09:32 +00:00
Dexter Edwards da068fbbc7 fix: token and percentage amounts in vote information (#1906)
* fix: token and percentage amounts in vote information

* test: adjust tests for new behviour

* style: lint
2022-10-31 18:58:48 -07:00
Dexter Edwards ac03ad8e3d chore: remove duplicated addDecimal function (#1908)
* chore: remove duplicated addDecimal function

* style: lint

* test: fix e2e test
2022-10-31 18:56:01 -07:00
mattrussell36 da6a3755db chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-01 00:11:57 +00:00
Bartłomiej Głownia 1862ebbc6c fix: change way how summary row is updated to avoid rerender (#1910) 2022-10-31 13:57:26 -07:00
mattrussell36 9a20721970 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-31 18:06:56 +00:00
Sam Keen 1f8469a97a Feat/1666: Added min requirements for raw proposal form. Tests failing (#1884)
* Feat/1666: Added min requirements for raw proposal form. Tests failing

* Feat/1666: Tests now passing
2022-10-31 16:02:04 +00:00
Dexter Edwards 03e39e8323 fix: get queries script (#1911) 2022-10-31 14:31:51 +00:00
mattrussell36 a5466f6e8a chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-31 12:05:17 +00:00
Madalina Raicu 43389ff6f9 fix: use n08 in .env.testnet 2022-10-31 10:43:02 +00:00
mattrussell36 0e344ef88d chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-31 06:04:46 +00:00
mattrussell36 b6d342f0d0 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-31 00:11:31 +00:00
mattrussell36 3d45eaa3c3 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-30 18:04:26 +00:00
mattrussell36 baa7bd3438 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-30 12:04:58 +00:00
mattrussell36 85bcdc1702 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-30 06:04:22 +00:00
mattrussell36 37441918b6 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-30 00:10:41 +00:00
mattrussell36 165e4fdc49 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-29 18:05:09 +00:00
mattrussell36 dbdfd13f45 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-29 12:04:55 +00:00
mattrussell36 e6b65d9541 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-29 06:04:46 +00:00
mattrussell36 98340c93a2 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-29 00:08:58 +00:00
mattrussell36 d3bf8b09cf chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-28 18:04:21 +00:00
Bartłomiej Głownia ef07536159 feat(958): add cancel all orders button (#1861) 2022-10-28 16:15:21 +01:00
Bartłomiej Głownia 13a77d1583 fix: order positions by market name instead of updatedAt (#1902) 2022-10-28 16:14:29 +01:00
Matthew Russell f5ea0563b3 Feat/725 network header styles (#1893)
* feat: add yellow theme for navbar, adjust dropdown and theme switcher styles

* feat: set yellow theme when network is testnet

* feat: adjust button styles to accomodate different color backgrounds
2022-10-28 16:13:14 +01:00
m.ray a90970399c feat: 1651 market select snags (#1874)
* feat: #1651 market select snags

* fix: #1651 fix markets.cy.ts cypress test

* fix: #1651 prevent default and stop propagation on select markets asset click
2022-10-28 13:41:33 +01:00
mattrussell36 b86c3386c6 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-28 12:04:55 +00:00
botond b3a8176297 chore: migrate network stats and clean up liquidity lib (#1896)
* chore: migrate network stats and clean up liquidity lib

* fix: format

* fix: test imports

* fix: format

* fix: market info expiry format tests

* fix: format again

* fix: build
2022-10-28 12:48:42 +01:00
Madalina Raicu 0855d3bae6 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-28 11:03:07 +01:00
m.ray b273e2740d fix: 1842 set expiry to date time format (#1866)
* fix: #1842 set expiry to date time format

* fix: #1842 consistent expiry date time
2022-10-28 09:49:38 +01:00
Bartłomiej Głownia 0be668ae86 fix: cast sequence number to bigint depth provider update, add captureException for update skip (#1895) 2022-10-28 08:58:56 +01:00
mattrussell36 1cf398ad5f chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-28 06:05:07 +00:00
mattrussell36 3e8f92c858 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-28 00:10:53 +00:00
Sam Keen bcb0f9636a Fix/1888: Multisig - add and remove signer methods nonce needs to be an int (#1890)
* Fix/1888: Multisig - nonce needs to be an int

* Fix/1888: Handle big numbers and do it without making ts angry
2022-10-27 22:37:33 +01:00
macqbatandmaciek 5ecf7d6a9f Feat/1660 validate available margin (#1860)
* feat: deal ticket margin validation

* feat: deal ticket margin validation - working solution

* feat: deal ticket margin validation - add int test

* feat: deal ticket margin validation - improve int test

* feat: deal ticket margin validation - improve int test

* feat: deal ticket margin validation - fix unit test

* feat: deal ticket margin validation - improve case when no account

* feat: deal ticket margin validation - fix unit test

* feat: deal ticket margin validation - fix int test

* feat: deal ticket margin validation - fix int test

* feat: deal ticket margin validation - fix int test

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-10-27 20:12:03 +02:00
mattrussell36 75db1d3ec6 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-27 18:04:59 +00:00
Madalina Raicu 2fcee815e5 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-27 15:01:57 +01:00
Madalina Raicu 3aab601180 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-26 15:35:12 +01:00
Madalina Raicu 8561c1d0bc Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-26 10:34:30 +01:00
Madalina Raicu e0f5f43777 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-25 08:00:09 +01:00
Madalina Raicu 81ff3ceff0 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-23 00:38:55 +01:00
Madalina Raicu 5f9287a220 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-21 16:20:36 +01:00
Madalina Raicu 76827b239a Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-18 13:25:22 +01:00
Madalina Raicu 464b964cba Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-12 15:42:39 +01:00
Madalina Raicu 2c0287be32 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-10 09:28:15 +01:00
Madalina Raicu 0f60018ab4 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-07 16:36:10 +01:00
Madalina Raicu 934d75643f Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-05 21:24:40 +01:00
Madalina Raicu 1eb8565739 Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop 2022-10-05 17:36:48 +01:00
585 changed files with 23967 additions and 9453 deletions
@@ -14,18 +14,18 @@ runs:
if: ${{ inputs.all }}
shell: bash
run: |
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vega-linux-amd64.zip' -q
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ inputs.version }}/vega-linux-amd64.zip' -q
unzip vega-linux-amd64.zip -d ${{ inputs.gobin }}
- name: Install date-node binaries
if: ${{ inputs.all }}
shell: bash
run: |
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/data-node-linux-amd64.zip' -q
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ inputs.version }}/data-node-linux-amd64.zip' -q
unzip data-node-linux-amd64.zip -d ${{ inputs.gobin }}
- name: Install Vega wallet binaries
shell: bash
run: |
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vegawallet-linux-amd64.zip' -q
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ inputs.version }}/vegawallet-linux-amd64.zip' -q
unzip vegawallet-linux-amd64.zip -d ${{ inputs.gobin }}
+5 -5
View File
@@ -5,7 +5,7 @@ inputs:
description: 'Wallet password'
capsule:
description: 'Is Capsule network used'
default: false
default: 'false'
runs:
using: 'composite'
steps:
@@ -29,17 +29,17 @@ runs:
shell: bash
run: vegawallet key generate -w UI_Trading_Test -p ./passphrase --home ~/.vegacapsule/testnet/wallet
- name: Import fairground network
- name: Import network
shell: bash
if: ${{ inputs.capsule==false }}
if: ${{ inputs.capsule=='false' }}
run: vegawallet network import --from-url="https://raw.githubusercontent.com/vegaprotocol/networks-internal/master/stagnet3/stagnet3.toml" --force --home ~/.vegacapsule/testnet/wallet
- name: Start service using fairground network
shell: bash
if: ${{ inputs.capsule==false }}
if: ${{ inputs.capsule=='false' }}
run: vegawallet service run --network stagnet3 --automatic-consent --no-version-check --home ~/.vegacapsule/testnet/wallet &
- name: Start service using capsule network
shell: bash
if: ${{ inputs.capsule==true }}
if: ${{ inputs.capsule=='true' }}
run: vegawallet service run --network DV --automatic-consent --home ~/.vegacapsule/testnet/wallet &
+13 -11
View File
@@ -1,25 +1,27 @@
---
name: Auto Assign Issue to New Project
name: 'Add Issues To Project Board'
'on':
issues:
types: [opened]
types:
- opened
env:
GH_TOKEN: ${{ secrets.GH_NEW_CARD_TO_PROJECT }}
PROJECT_ID: ${{ secrets.FRONT_END_PROJECT_ID }}
ISSUE_ID: ${{ github.event.issue.node_id }}
USER: ${{ github.actor }}
jobs:
add_issue:
runs-on: ubuntu-latest
steps:
- name: Add Issue to New Front End Project Board
env:
GITHUB_TOKEN: ${{ secrets.GH_NEW_CARD_TO_PROJECT }}
PROJECT_ID: ${{ secrets.FRONT_END_PROJECT_ID }}
ISSUE_ID: ${{ github.event.issue.node_id }}
- name: 'Add issue to project board'
run: |
gh api graphql -f query='
mutation($project:ID!, $issue:ID!) {
addProjectNextItem(input: {projectId: $project, contentId: $issue}) {
projectNextItem {
mutation($user:String!, $project:ID!, $issue:ID!) {
addProjectV2ItemById(input: {clientMutationId: $user, projectId: $project, contentId: $issue}) {
item {
id
}
}
}' -f project=$PROJECT_ID -f issue=$ISSUE_ID --jq '.data.addProjectNextItem.projectNextItem.id'
}' -f project=$PROJECT_ID -f issue=$ISSUE_ID -f user=$USER
@@ -10,150 +10,52 @@ on:
required: true
type: choice
options:
- explorer-e2e
- console-lite-e2e
- explorer-e2e
- liquidity-provision-dashboard-e2e
- stats-e2e
- token-e2e
- trading-e2e
smokeOnly:
description: 'Run only smoke tests?'
tags:
description: 'Test tags to run'
required: true
type: boolean
default: false
type: string
default: '@smoke, @regression, @slow'
skip-nx-cache:
description: 'Add --skip-nx-cache to cypress test'
required: false
type: boolean
default: false
env:
GOBIN: /home/runner/go/bin
VEGA_VERSION: 'v0.62.1'
jobs:
manual:
name: Run Cypress tests -- manual trigger
runs-on: self-hosted
env:
GO111MODULE: 'on'
GOBIN: /home/runner/go/bin
VEGA_VERSION: 'v0.58.0'
runs-on: ubuntu-latest
steps:
#######
## Setup flags
#######
- name: Set smoke tag
if: ${{ github.event.inputs.smokeOnly == 'true' }}
run: echo TAGS="--env.grepTags @smoke" >> $GITHUB_ENV
- name: Set tags
run: echo TAGS="--env.grepTags '[ ${{ github.event.inputs.tags }} ]'" >> $GITHUB_ENV
- name: Set --skip-nx-cache flag
if: ${{ github.event.inputs.skip-nx-cache == 'true' }}
run: echo SKIP_NX_CACHE="--skip-nx-cache" >> $GITHUB_ENV
# See if we capsule is needed for this project
- name: Set capsule flag
if: ${{ github.event.inputs.project == 'explorer-e2e' || github.event.inputs.project == 'token-e2e'}}
run: echo RUN_CAPSULE=true >> $GITHUB_ENV
outputs:
vega-version: ${{env.VEGA_VERSION}}
gobin: ${{env.GOBIN}}
skip-cache: ${{env.SKIP_NX_CACHE}}
tags: ${{env.TAGS}}
#######
## Setup langs
#######
- name: Set up Go
uses: actions/setup-go@v3
id: go
with:
go-version: 1.19
- name: Set up Node 16
uses: actions/setup-node@v2
id: npm
with:
node-version: 16
#######
## Install Yarn
#######
- name: Setup yarn
run: npm install -g yarn
#######
## Checkout repos
#######
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v2
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
#######
## Build and run Vegacapsule network
#######
- name: Install Vega binaries
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
with:
all: ${{ env.RUN_CAPSULE }}
version: ${{ env.VEGA_VERSION }}
gobin: ${{ env.GOBIN }}
- name: Build and run Vegacapsule network
if: ${{ env.RUN_CAPSULE }}
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
with:
github-token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
######
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: ${{ env.RUN_CAPSULE }}
######
## Run some tests
######
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: yarn nx run ${{ github.event.inputs.project }}:e2e ${{ env.SKIP_NX_CACHE }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ env.TAGS }}
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: false
######
## Upload logs
######
- name: Logs
if: ${{ env.RUN_CAPSULE }}
run: vegacapsule network logs > vega-capsule-logs.txt
- uses: actions/upload-artifact@v2
if: ${{ env.RUN_CAPSULE }}
with:
name: logs
path: ./vega-capsule-logs.txt
dispatch:
needs: manual
uses: ./.github/workflows/tests-dispatcher.yml
secrets: inherit
with:
project: ${{ inputs.project }}
vega-version: ${{needs.manual.outputs.vega-version}}
gobin: ${{needs.manual.outputs.gobin}}
skip-cache: ${{needs.manual.outputs.skip-cache}}
tags: ${{needs.manual.outputs.tags}}
capsule-teardown: false
+9 -112
View File
@@ -9,115 +9,12 @@ on:
jobs:
nightly:
name: Run Cypress tests -- nightly
runs-on: self-hosted
timeout-minutes: 60
env:
GO111MODULE: 'on'
GOBIN: /home/runner/go/bin
VEGA_VERSION: 'v0.58.0'
RUN_CAPSULE: true
steps:
#######
## Setup langs
#######
- name: Set up Go
uses: actions/setup-go@v3
id: go
with:
go-version: 1.19
- name: Set up Node 16
uses: actions/setup-node@v2
id: npm
with:
node-version: 16
#######
## Install Yarn
#######
- name: Setup yarn
run: npm install -g yarn
#######
## Checkout repos
#######
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v2
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
#######
## Build and run Vegacapsule network
#######
- name: Install Vega binaries
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
with:
all: ${{ env.RUN_CAPSULE }}
version: ${{ env.VEGA_VERSION }}
gobin: ${{ env.GOBIN }}
- name: Build and run Vegacapsule network
if: ${{ env.RUN_CAPSULE }}
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
with:
github-token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
######
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: ${{ env.RUN_CAPSULE }}
######
## Run some tests
######
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: yarn nx run-many --skip-nx-cache --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome --parallel=1
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_NIGHTLY_RUN: true
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: true
######
## Upload logs
######
- name: Logs
run: vegacapsule network logs > vega-capsule-logs.txt
- uses: actions/upload-artifact@v2
with:
name: logs
path: ./vega-capsule-logs.txt
uses: ./.github/workflows/tests-dispatcher.yml
secrets: inherit
with:
project: '[console-lite-e2e, explorer-e2e, liquidity-provision-dashboard-e2e, stats-e2e, token-e2e, trading-e2e]'
vega-version: 'v0.62.1'
gobin: /home/runner/go/bin
tags: --env.grepTags '[ @smoke, @regression, @slow ]'
night-run: true
capsule-teardown: false
+20 -96
View File
@@ -1,4 +1,4 @@
name: Cypress tests
name: Cypress tests - PR
on:
push:
@@ -12,41 +12,14 @@ on:
- synchronize
- ready_for_review
env:
GOBIN: /home/runner/go/bin
VEGA_VERSION: 'v0.62.1'
jobs:
pr:
name: Run Cypress tests - PR
runs-on: self-hosted
timeout-minutes: 30
env:
GO111MODULE: 'on'
GOBIN: /home/runner/go/bin
VEGA_VERSION: 'v0.58.0'
runs-on: ubuntu-latest
steps:
#######
## Setup langs
#######
- name: Set up Go
uses: actions/setup-go@v3
id: go
with:
go-version: 1.19
- name: Set up Node 16
uses: actions/setup-node@v2
id: npm
with:
node-version: 16
#######
## Install Yarn
#######
- name: Setup yarn
run: npm install -g yarn
#######
## Checkout repos
#######
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v2
@@ -76,71 +49,22 @@ jobs:
main-branch-name: ${{ github.base_ref || github.ref_name }}
set-environment-variables-for-job: true
# See if we capsule is needed for this project
# See affected projects
- name: See affected apps
run: echo AFFECTED=$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects) >> $GITHUB_ENV
working-directory: frontend-monorepo
- name: See if capsule is necessary
if: ${{ contains(env.AFFECTED, 'token') || contains(env.AFFECTED, 'token-e2e') || contains(env.AFFECTED, 'explorer') || contains(env.AFFECTED, 'explorer-e2e') }}
run: echo RUN_CAPSULE=true >> $GITHUB_ENV
outputs:
projects: ${{ env.AFFECTED }}
vega-version: ${{ env.VEGA_VERSION }}
gobin: ${{ env.GOBIN }}
#######
## Build and run Vegacapsule network
#######
- name: Install Vega binaries
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
with:
all: ${{ env.RUN_CAPSULE }}
version: ${{ env.VEGA_VERSION }}
gobin: ${{ env.GOBIN }}
- name: Build and run Vegacapsule network
if: ${{ env.RUN_CAPSULE }}
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
with:
github-token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
######
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: ${{ env.RUN_CAPSULE }}
######
## Run some tests
######
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx affected:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.grepTags='@smoke' --browser chrome
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: false
######
## Upload logs
######
- name: Logs
if: ${{ env.RUN_CAPSULE }}
run: vegacapsule network logs > vega-capsule-logs.txt
- uses: actions/upload-artifact@v2
if: ${{ env.RUN_CAPSULE }}
with:
name: logs
path: ./vega-capsule-logs.txt
dispatch:
needs: pr
uses: ./.github/workflows/tests-dispatcher.yml
secrets: inherit
with:
project: ${{ needs.pr.outputs.projects }}
vega-version: ${{needs.pr.outputs.vega-version}}
gobin: ${{needs.pr.outputs.gobin}}
tags: "--env.grepTags='@smoke'"
@@ -0,0 +1,87 @@
name: Cypress - console-lite
on:
workflow_call:
inputs:
trigger:
required: true
type: string
default: 'false'
vega-version:
required: true
type: string
gobin:
required: false
type: string
default: /home/runner/go/bin
skip-cache:
required: false
type: string
tags:
required: false
type: string
jobs:
console-lite-e2e:
if: ${{ inputs.trigger == 'true' }}
runs-on: self-hosted
steps:
# Add GOBIN to PATH
- name: Add GOBIN to PATH
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
#######
## Build and run Vegacapsule network
#######
- name: Install Vega binaries
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
with:
all: false
version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
######
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: false
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx run console-lite-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
+119
View File
@@ -0,0 +1,119 @@
name: Cypress - explorer
on:
workflow_call:
inputs:
trigger:
required: true
type: string
default: 'false'
vega-version:
required: true
type: string
gobin:
required: false
type: string
default: /home/runner/go/bin
skip-cache:
required: false
type: string
tags:
required: false
type: string
night-run:
required: false
type: boolean
default: false
capsule-teardown:
required: false
type: boolean
default: false
jobs:
explorer-e2e:
if: ${{ inputs.trigger == 'true' }}
runs-on: self-hosted
timeout-minutes: 30
steps:
# Add GOBIN to PATH
- name: Add GOBIN to PATH
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
#######
## Build and run Vegacapsule network
#######
- name: Install Vega binaries
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
with:
all: true
version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
- name: Build and run Vegacapsule network
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
with:
github-token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
######
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: true
######
## Run some tests
######
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx run explorer-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: ${{ inputs.capsule-teardown }}
CYPRESS_NIGHTLY_RUN: ${{ inputs.night-run }}
######
## Upload logs
######
- name: Logs
run: vegacapsule network logs > vega-capsule-logs.txt
- uses: actions/upload-artifact@v2
with:
name: logs
path: ./vega-capsule-logs.txt
@@ -0,0 +1,47 @@
name: Cypress - liquidity provision dashboard
on:
workflow_call:
inputs:
trigger:
required: true
type: string
default: 'false'
jobs:
liquidity-provision-dashboard-e2e:
timeout-minutes: 10
if: ${{ inputs.trigger == 'true' }}
runs-on: self-hosted
steps:
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx run liquidity-provision-dashboard-e2e:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
working-directory: frontend-monorepo
env:
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
+47
View File
@@ -0,0 +1,47 @@
name: Cypress - stats
on:
workflow_call:
inputs:
trigger:
required: true
type: string
default: 'false'
jobs:
stats-e2e:
runs-on: self-hosted
if: ${{ inputs.trigger == 'true' }}
timeout-minutes: 10
steps:
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx run stats-e2e:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
working-directory: frontend-monorepo
env:
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
+114
View File
@@ -0,0 +1,114 @@
name: Cypress - token
on:
workflow_call:
inputs:
trigger:
required: true
type: string
default: 'false'
vega-version:
required: true
type: string
gobin:
required: false
type: string
default: /home/runner/go/bin
skip-cache:
required: false
type: string
tags:
required: false
type: string
capsule-teardown:
required: false
type: boolean
default: false
jobs:
token-e2e:
if: ${{ inputs.trigger == 'true' }}
runs-on: self-hosted
timeout-minutes: 60
steps:
# Add GOBIN to PATH
- name: Add GOBIN to PATH
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
#######
## Build and run Vegacapsule network
#######
- name: Install Vega binaries
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
with:
all: true
version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
- name: Build and run Vegacapsule network
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
with:
github-token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
######
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: true
######
## Run some tests
######
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx run token-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: ${{ inputs.capsule-teardown }}
######
## Upload logs
######
- name: Logs
run: vegacapsule network logs > vega-capsule-logs.txt
- uses: actions/upload-artifact@v2
with:
name: logs
path: ./vega-capsule-logs.txt
+88
View File
@@ -0,0 +1,88 @@
name: Cypress - trading
on:
workflow_call:
inputs:
trigger:
required: true
type: string
default: 'false'
vega-version:
required: true
type: string
gobin:
required: false
type: string
default: /home/runner/go/bin
skip-cache:
required: false
type: string
tags:
required: false
type: string
jobs:
trading-e2e:
if: ${{ inputs.trigger == 'true' }}
timeout-minutes: 30
runs-on: self-hosted
steps:
# Add GOBIN to PATH
- name: Add GOBIN to PATH
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
with:
fetch-depth: 0
path: './frontend-monorepo'
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: |
frontend-monorepo/node_modules
/home/runner/.cache/Cypress
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
# Install frontend dependencies
- name: Install root dependencies
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
#######
## Build and run Vegacapsule network
#######
- name: Install Vega binaries
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
with:
all: false
version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
######
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: false
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
run: yarn cypress install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx run trading-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
+21
View File
@@ -0,0 +1,21 @@
---
name: Verify PR title
on:
pull_request:
types: [opened, ready_for_review, reopened, edited, synchronize]
jobs:
lint_pr:
runs-on: ubuntu-latest
steps:
- name: Use Node.js 16
id: Node
uses: actions/setup-node@v2
with:
node-version: 16.14.0
- name: Install commitlint cli and config
run: npm install @commitlint/cli @commitlint/config-conventional
- name: Create config
run: echo "module.exports = {extends:['@commitlint/config-conventional']};" > commitlint.config.js
- name: Check PR title
run: echo "${{ github.event.pull_request.title }}" | npx commitlint
+81
View File
@@ -0,0 +1,81 @@
on:
workflow_call:
inputs:
project:
required: true
type: string
vega-version:
required: true
type: string
gobin:
required: false
type: string
default: /home/runner/go/bin
skip-cache:
required: false
type: string
tags:
required: false
type: string
night-run:
required: false
type: boolean
capsule-teardown:
required: false
type: boolean
jobs:
run-console-lite-e2e:
uses: ./.github/workflows/cypress-console-lite-e2e.yml
secrets: inherit
with:
trigger: ${{ contains(inputs.project, 'console-lite-e2e') || contains(inputs.project, 'console-lite') }}
vega-version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
run-explorer-e2e:
uses: ./.github/workflows/cypress-explorer-e2e.yml
secrets: inherit
with:
trigger: ${{ contains(inputs.project, 'explorer-e2e') || contains(inputs.project, 'explorer') }}
vega-version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
night-run: ${{ inputs.night-run }}
capsule-teardown: ${{ inputs.capsule-teardown }}
run-liquidity-e2e:
uses: ./.github/workflows/cypress-liquidity-provision-dashboard-e2e.yml
secrets: inherit
with:
trigger: ${{ contains(inputs.project, 'liquidity-provision-dashboard-e2e') || contains(inputs.project, 'liquidity-provision-dashboard') }}
run-stats-e2e:
uses: ./.github/workflows/cypress-stats-e2e.yml
secrets: inherit
with:
trigger: ${{ contains(inputs.project, 'stats-e2e') || contains(inputs.project, 'stats') }}
run-token-e2e:
uses: ./.github/workflows/cypress-token-e2e.yml
secrets: inherit
with:
trigger: ${{ contains(inputs.project, 'token-e2e') || contains(inputs.project, 'token') }}
vega-version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
capsule-teardown: ${{ inputs.capsule-teardown }}
run-trading-e2e:
uses: ./.github/workflows/cypress-trading-e2e.yml
secrets: inherit
with:
trigger: ${{ contains(inputs.project, 'trading-e2e') || contains(inputs.project, 'trading') }}
vega-version: ${{ inputs.vega-version }}
gobin: ${{ inputs.gobin }}
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
@@ -266,10 +266,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
.find('dt')
.eq(3)
.should('have.text', 'Est. Fees (tDAI)');
cy.get('#step-2-panel')
.find('dd')
.eq(3)
.should('have.text', '3.00000 (3.03%)');
cy.get('#step-2-panel').find('dd').eq(3).should('have.text', '3 (3.03%)');
}
});
@@ -291,10 +288,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
cy.get('#step-3-panel')
.find('dd')
.eq(3)
.should('have.text', '3.00000 (3.03%)');
cy.get('#step-3-panel').find('dd').eq(3).should('have.text', '3 (3.03%)');
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
@@ -95,8 +95,7 @@ describe('Portfolio page', { tags: '@smoke' }, () => {
});
it('data should be properly rendered', () => {
cy.getByTestId('positions-asset-tDAI').should('exist');
cy.getByTestId('positions-asset-tEURO').should('exist');
cy.get('.ag-center-cols-container .ag-row').should('have.length', 2);
});
});
@@ -138,7 +138,7 @@ export const singleMarket: SingleMarketFieldsFragment = {
id: 'dai-id',
name: 'DAI Name',
},
oracleSpecForTradingTermination: {
dataSourceSpecForTradingTermination: {
id: 'oid',
},
},
@@ -1,15 +1,29 @@
import { Schema as Types } from '@vegaprotocol/types';
export const generatePartyMarketData = () => {
return {
party: {
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
accounts: [
{
type: 'General',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '1200000',
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
market: null,
__typename: 'AccountBalance',
},
{
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '0.000000001',
asset: {
__typename: 'Asset',
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tUSD',
name: 'usd',
decimals: 0,
},
},
],
marginsConnection: { edges: null, __typename: 'MarginConnection' },
positionsConnection: { edges: null, __typename: 'PositionConnection' },
+3 -3
View File
@@ -17,9 +17,9 @@ NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/testnet-network.json"
NX_VEGA_ENV = 'TESTNET'
NX_VEGA_URL="https://api.n11.testnet.vega.xyz/graphql"
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/stagnet3-network.json"
NX_VEGA_ENV=STAGNET3
NX_VEGA_URL="https://api.n01.stagnet3.vega.xyz/graphql"
NX_VEGA_WALLET_URL=http://localhost:1789
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+1 -1
View File
@@ -4,4 +4,4 @@ NX_VEGA_ENV=SANDBOX
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","STAGNET1":"https://stagnet1.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
NX_VEGA_EXPLORER_URL=https://sandbox.explorer.vega.xyz
NX_VEGA_DOCS_URL=https://docs.vega.xyz/docs/testnet
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
+26 -2
View File
@@ -1,6 +1,5 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { createClient } from './lib/apollo-client';
import { ThemeContext } from '@vegaprotocol/react-helpers';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
@@ -16,6 +15,7 @@ import Header from './components/header';
import { Main } from './components/main';
import LocalContext from './context/local-context';
import useLocalValues from './hooks/use-local-values';
import type { InMemoryCacheConfig } from '@apollo/client';
function App() {
const [theme, toggleTheme] = useThemeSwitcher();
@@ -30,10 +30,34 @@ function App() {
setMenuOpen(false);
}, [location, setMenuOpen]);
const cacheConfig: InMemoryCacheConfig = {
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
};
return (
<EnvironmentProvider>
<ThemeContext.Provider value={theme}>
<NetworkLoader createClient={createClient}>
<NetworkLoader cache={cacheConfig}>
<VegaWalletProvider>
<LocalContext.Provider value={localValues}>
<AppLoader>
@@ -26,6 +26,9 @@ import {
toDecimal,
removeDecimal,
addDecimalsFormatNumber,
addDecimalsNormalizeNumber,
addDecimal,
formatNumber,
} from '@vegaprotocol/react-helpers';
import {
useOrderSubmit,
@@ -68,19 +71,20 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
const emptyString = ' - ';
const step = toDecimal(market.positionDecimalPlaces);
const order = watch();
const { message: invalidText, isDisabled } = useOrderValidation({
market,
orderType: order.type,
orderTimeInForce: order.timeInForce,
fieldErrors: errors,
});
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
const { pubKey } = useVegaWallet();
const estMargin = useOrderMargin({
order,
market,
partyId: pubKey || '',
});
const { message: invalidText, isDisabled } = useOrderValidation({
market,
orderType: order.type,
orderTimeInForce: order.timeInForce,
fieldErrors: errors,
estMargin,
});
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
const { data: partyBalance } = usePartyBalanceQuery({
variables: { partyId: pubKey || '' },
@@ -141,6 +145,9 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
return null;
}, [market.decimalPlaces, order.size, price]);
const assetDecimals =
market.tradableInstrument.instrument.product.settlementAsset.decimals;
const fees = useMemo(() => {
if (estMargin?.totalFees && notionalSize) {
const percentage = new BigNumber(estMargin?.totalFees)
@@ -149,11 +156,14 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
.decimalPlaces(2)
.toString();
return `${estMargin.totalFees} (${percentage}%)`;
return `${addDecimalsNormalizeNumber(
estMargin.totalFees,
assetDecimals
)} (${formatNumber(addDecimal(percentage, assetDecimals), 2)}%)`;
}
return null;
}, [estMargin?.totalFees, notionalSize]);
}, [assetDecimals, estMargin?.totalFees, notionalSize]);
const max = useMemo(() => {
return new BigNumber(maxTrade)
@@ -1,40 +1,22 @@
import { useMemo } from 'react';
import { DepositManager } from '@vegaprotocol/deposits';
import { useState } from 'react';
import { t } from '@vegaprotocol/react-helpers';
import { enabledAssetsProvider } from '@vegaprotocol/assets';
import { useDataProvider } from '@vegaprotocol/react-helpers';
import { Networks, useEnvironment } from '@vegaprotocol/environment';
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { Web3Container } from '@vegaprotocol/web3';
import { Button } from '@vegaprotocol/ui-toolkit';
import { DepositDialog } from '@vegaprotocol/deposits';
/**
* Fetches data required for the Deposit page
*/
export const DepositContainer = () => {
const { VEGA_ENV } = useEnvironment();
const { pubKey } = useVegaWallet();
const variables = useMemo(() => ({ partyId: pubKey }), [pubKey]);
const { data, loading, error } = useDataProvider({
dataProvider: enabledAssetsProvider,
variables,
skip: !pubKey,
});
const [depositDialog, setDepositDialog] = useState(false);
return (
<AsyncRenderer data={data} loading={loading} error={error}>
{data && data.length ? (
<Web3Container>
<DepositManager
assets={data}
isFaucetable={VEGA_ENV !== Networks.MAINNET}
/>
</Web3Container>
) : (
<Splash>
<p>{t('No assets on this network')}</p>
</Splash>
)}
</AsyncRenderer>
<div>
<DepositDialog
depositDialog={depositDialog}
setDepositDialog={setDepositDialog}
/>
<Button size="sm" onClick={() => setDepositDialog(true)}>
{t('Make deposit')}
</Button>
</div>
);
};
@@ -32,10 +32,8 @@ const AccountsManager = () => {
dataProvider: aggregatedAccountsDataProvider,
update,
variables,
updateOnInit: true,
});
if (!dataRef.current && data) {
dataRef.current = data;
}
const getRows = async ({
successCallback,
startRow,
@@ -65,8 +65,8 @@ const OrdersManager = () => {
defaultColDef={defaultColDef}
/>
<orderCancel.Dialog
title={getCancelDialogTitle(orderCancel.cancelledOrder?.status)}
intent={getCancelDialogIntent(orderCancel.cancelledOrder?.status)}
title={getCancelDialogTitle(orderCancel)}
intent={getCancelDialogIntent(orderCancel)}
content={{
Complete: (
<OrderFeedback
@@ -11,11 +11,8 @@ import {
positiveClassNames,
t,
} from '@vegaprotocol/react-helpers';
import type {
OrderFieldsFragment,
Order,
CancelOrderArgs,
} from '@vegaprotocol/orders';
import type { OrderFieldsFragment, Order } from '@vegaprotocol/orders';
import type { OrderCancellationBody } from '@vegaprotocol/wallet';
import { isOrderActive } from '@vegaprotocol/orders';
import {
OrderRejectionReasonMapping,
@@ -34,7 +31,7 @@ type OrderTimeKey = keyof typeof OrderTimeInForceMapping;
interface Props {
setEditOrder: (order: Order) => void;
orderCancel: {
cancel: (args: CancelOrderArgs) => void;
cancel: (args: OrderCancellationBody['orderCancellation']) => void;
[key: string]: unknown;
};
}
@@ -1,58 +0,0 @@
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { useRef } from 'react';
import type { AgGridReact } from 'ag-grid-react';
import type { Position } from '@vegaprotocol/positions';
import { PriceFlashCell, t } from '@vegaprotocol/react-helpers';
import { AssetBalance } from '@vegaprotocol/accounts';
import { usePositionsData } from '@vegaprotocol/positions';
import { ConsoleLiteGrid } from '../../console-lite-grid';
import useColumnDefinitions from './use-column-definitions';
interface Props {
partyId: string;
assetSymbol: string;
}
const getRowId = ({ data }: { data: Position }) => data.marketId;
const PositionsAsset = ({ partyId, assetSymbol }: Props) => {
const gridRef = useRef<AgGridReact | null>(null);
const { data, error, loading, getRows } = usePositionsData(
partyId,
gridRef,
assetSymbol
);
const { columnDefs, defaultColDef } = useColumnDefinitions();
return (
<AsyncRenderer loading={loading} error={error} data={data}>
<div
data-testid={`positions-asset-${assetSymbol}`}
className="flex justify-between items-center px-4 pt-3 pb-1"
>
<h4>
{assetSymbol} {t('markets')}
</h4>
<div className="text-sm text-neutral-500 dark:text-neutral-300">
{assetSymbol} {t('balance')}:
<span data-testid="balance" className="pl-1 font-mono">
<AssetBalance partyId={partyId} assetSymbol={assetSymbol} />
</span>
</div>
</div>
<ConsoleLiteGrid<Position & { id: undefined }>
ref={gridRef}
domLayout="autoHeight"
classNamesParam="h-auto"
columnDefs={columnDefs}
defaultColDef={defaultColDef}
getRowId={getRowId}
rowModelType={data?.length ? 'infinite' : 'clientSide'}
rowData={data?.length ? undefined : []}
datasource={{ getRows }}
components={{ PriceFlashCell }}
/>
</AsyncRenderer>
);
};
export default PositionsAsset;
@@ -1,26 +1,37 @@
import { useOutletContext } from 'react-router-dom';
import { t } from '@vegaprotocol/react-helpers';
import { usePositionsAssets } from '@vegaprotocol/positions';
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
import PositionsAsset from './positions-asset';
import { PriceFlashCell } from '@vegaprotocol/react-helpers';
import { usePositionsData, getRowId } from '@vegaprotocol/positions';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { ConsoleLiteGrid } from '../../console-lite-grid';
import { useRef } from 'react';
import type { AgGridReact } from 'ag-grid-react';
import type { Position } from '@vegaprotocol/positions';
import { NO_DATA_MESSAGE } from '../../../constants';
import useColumnDefinitions from './use-column-definitions';
const Positions = () => {
const gridRef = useRef<AgGridReact | null>(null);
const { partyId } = useOutletContext<{ partyId: string }>();
const { data, error, loading, assetSymbols } = usePositionsAssets(partyId);
const { data, error, loading } = usePositionsData(partyId, gridRef);
const { columnDefs, defaultColDef } = useColumnDefinitions();
return (
<AsyncRenderer loading={loading} error={error} data={data}>
{assetSymbols && assetSymbols.length > 0 && (
<div className="w-full, h-max">
{assetSymbols?.map((assetSymbol) => (
<PositionsAsset
key={assetSymbol}
partyId={partyId}
assetSymbol={assetSymbol}
/>
))}
</div>
)}
{assetSymbols?.length === 0 && <Splash>{t('No data to display')}</Splash>}
<AsyncRenderer
loading={loading}
error={error}
data={data?.length ? data : null}
noDataMessage={NO_DATA_MESSAGE}
>
<ConsoleLiteGrid<Position>
ref={gridRef}
domLayout="autoHeight"
classNamesParam="h-auto"
columnDefs={columnDefs}
defaultColDef={defaultColDef}
getRowId={getRowId}
rowData={data || undefined}
components={{ PriceFlashCell }}
/>
</AsyncRenderer>
);
};
@@ -1,88 +0,0 @@
import {
ApolloClient,
from,
HttpLink,
InMemoryCache,
split,
} from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient as createWSClient } from 'graphql-ws';
import { getMainDefinition } from '@apollo/client/utilities';
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const urlHTTP = new URL(base);
const urlWS = new URL(base);
// Replace http with ws, preserving if its a secure connection eg. https => wss
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
const cache = new InMemoryCache({
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: urlHTTP.href,
credentials: 'same-origin',
});
const wsLink = new GraphQLWsLink(
createWSClient({
url: urlWS.href,
})
);
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink
);
const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(graphQLErrors);
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, splitLink]),
cache,
});
}
@@ -87,7 +87,7 @@ context('Asset page', { tags: '@regression' }, function () {
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
const darkThemeSelectedMenuOptionColor = 'rgb(215, 251, 80)';
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
const themeSwitcher = '[data-testid="theme-switcher"]';
@@ -205,7 +205,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
const darkThemeSelectedMenuOptionColor = 'rgb(215, 251, 80)';
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
const themeSwitcher = '[data-testid="theme-switcher"]';
+36 -22
View File
@@ -50,9 +50,9 @@ context('Parties page', { tags: '@regression' }, function () {
});
it('should see party address id - having searched', function () {
cy.contains('Address')
cy.getByTestId('parties-header')
.siblings()
.contains(vegaWalletPublicKey)
.contains(vegaWalletPublicKey.substring(0, 14))
.should('be.visible');
});
@@ -76,28 +76,42 @@ context('Parties page', { tags: '@regression' }, function () {
});
});
it('should be able to copy the party address id', function () {
cy.monitor_clipboard().as('clipboard');
cy.contains('Address').siblings().last().click();
cy.get('@clipboard')
.get_copied_text_from_clipboard()
.should('equal', vegaWalletPublicKey);
});
it(
'should be able to copy the party address id',
{ browser: 'chrome' },
function () {
cy.monitor_clipboard().as('clipboard');
cy.getByTestId('parties-header')
.next()
.within(() => {
cy.get('button').click();
});
cy.get('@clipboard')
.get_copied_text_from_clipboard()
.should('equal', vegaWalletPublicKey);
}
);
it('should be able to copy an asset id', function () {
cy.monitor_clipboard().as('clipboard');
it(
'should be able to copy an asset id',
{ browser: 'chrome' },
function () {
cy.monitor_clipboard().as('clipboard');
cy.contains(assetData.fDAI.name, txTimeout).should('be.visible');
cy.contains(assetData.fDAI.name)
.siblings()
.within(() => {
cy.get('[data-state="closed"]').last().click({ force: true });
});
cy.contains(assetData.fDAI.name, txTimeout).should('be.visible');
cy.contains(assetData.fDAI.name)
.parent()
.parent()
.siblings()
.within(() => {
cy.get('[data-state="closed"]').last().click({ force: true });
});
cy.get('@clipboard')
.get_copied_text_from_clipboard()
.should('equal', assetData.fDAI.id);
});
cy.get('@clipboard')
.get_copied_text_from_clipboard()
.should('equal', assetData.fDAI.id);
}
);
it('should be able to see JSON of each asset containing correct balance and decimals', function () {
cy.get(partiesJsonSection).should('be.visible');
@@ -147,7 +161,7 @@ context('Parties page', { tags: '@regression' }, function () {
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
const darkThemeSelectedMenuOptionColor = 'rgb(215, 251, 80)';
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
const themeSwitcher = '[data-testid="theme-switcher"]';
@@ -216,7 +216,7 @@ context('Validator page', { tags: '@smoke' }, function () {
const whiteThemeSelectedMenuOptionColor = 'rgb(255, 7, 127)';
const whiteThemeJsonFieldBackColor = 'rgb(255, 255, 255)';
const whiteThemeSideMenuBackgroundColor = 'rgb(255, 255, 255)';
const darkThemeSelectedMenuOptionColor = 'rgb(223, 255, 11)';
const darkThemeSelectedMenuOptionColor = 'rgb(215, 251, 80)';
const darkThemeJsonFieldBackColor = 'rgb(38, 38, 38)';
const darkThemeSideMenuBackgroundColor = 'rgb(0, 0, 0)';
const themeSwitcher = '[data-testid="theme-switcher"]';
+3 -3
View File
@@ -1,10 +1,10 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
NX_TENDERMINT_URL=https://be.explorer.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://be.explorer.vega.xyz
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
NX_VEGA_URL=https://api.vega.xyz/query
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=MAINNET
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_BLOCK_EXPLORER=
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest/
+1 -1
View File
@@ -3,7 +3,7 @@ NX_VEGA_URL=https://api.sandbox.vega.xyz/graphql
NX_VEGA_ENV=SANDBOX
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
NX_VEGA_EXPLORER_URL=https://sandbox.explorer.vega.xyz
NX_VEGA_DOCS_URL=https://docs.vega.xyz/docs/testnet
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
+10 -2
View File
@@ -9,12 +9,12 @@ import {
useEnvironment,
} from '@vegaprotocol/environment';
import { NetworkInfo } from '@vegaprotocol/network-info';
import { createClient } from './lib/apollo-client';
import { Nav } from './components/nav';
import { Header } from './components/header';
import { Main } from './components/main';
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
import { ENV } from './config/env';
import type { InMemoryCacheConfig } from '@apollo/client';
function App() {
const { VEGA_ENV } = useEnvironment();
@@ -36,10 +36,18 @@ function App() {
});
}, [VEGA_ENV]);
const cacheConfig: InMemoryCacheConfig = {
typePolicies: {
Node: {
keyFields: false,
},
},
};
return (
<ThemeContext.Provider value={theme}>
<TendermintWebsocketProvider>
<NetworkLoader createClient={createClient}>
<NetworkLoader cache={cacheConfig}>
<div
className={`${
menuOpen && 'h-[100vh] overflow-hidden'
@@ -0,0 +1 @@
export * from './nested-data-list';
@@ -0,0 +1,110 @@
import { render, waitFor } from '@testing-library/react';
import {
BORDER_COLOURS,
NestedDataList,
sortNestedDataByChildren,
} from './nested-data-list';
import userEvent from '@testing-library/user-event';
const mockData = {
nonce: '5980890939790185837',
validatorHeartbeat: {
nodeId: 'e07d2cd299659590c16ec1cc1c69936ad747083c379ea6b6cfeaa6e22c8af0cb',
ethereumSignature: {
value:
'8b157cb43a716ad541065f643e38cd92d7b1857c7beeb7d81e878be4f9a48f5a346be973e478eba3c18907888678625ba6700b086f65406d5ce0af0cae1d419300',
algo: 'eth',
version: 0,
},
vegaSignature: {
value:
'abffba6ddf07b3a732214dd780c35c94f7f0aeb9c5e9ce7d1a3ee641926a6ac568a2ecf0160c859633d327712c7a1b1590db4245d40646559a1ab2cc44d6fa01',
algo: 'vega/ed25519',
version: 0,
},
},
blockHeight: '174534',
};
describe('NestedDataList', () => {
it('should display the parent as a button', () => {
const tree = render(<NestedDataList data={mockData} />);
const { getAllByRole } = tree;
expect(getAllByRole('button')[0]).toHaveTextContent('Validator Heartbeat');
});
it('should display the children when a row is clicked', async () => {
const tree = render(<NestedDataList data={mockData} />);
const user = userEvent.setup();
const { getAllByRole } = tree;
const parent = getAllByRole('listitem', { name: 'Validator Heartbeat' });
const nestedContainer = parent[0].querySelector('[aria-hidden]');
const expandBtn = parent[0].querySelector('button');
expect(nestedContainer).toHaveAttribute('aria-hidden', 'true');
await user.click(expandBtn as HTMLButtonElement);
await waitFor(() => nestedContainer);
expect(nestedContainer).toHaveAttribute('aria-hidden', 'false');
});
it('add border to the title of the parent', () => {
const tree = render(<NestedDataList data={mockData} />);
const { getAllByRole } = tree;
const parent = getAllByRole('listitem', { name: 'Validator Heartbeat' });
expect(parent[0]).toHaveClass('pl-4 border-l-4');
});
it('add a border the children with the same colour', () => {
const tree = render(<NestedDataList data={mockData} />);
const { getAllByRole } = tree;
const parent = getAllByRole('listitem', { name: 'Validator Heartbeat' });
expect(parent[0].querySelector('li')).toHaveClass('pl-4 border-l-4 pt-2');
});
it('should repeat the border colours in the correct order', () => {
const colourMockData = {
t0: {
t1: {
t2: {
t3: {
t4: {
t5: {
t6: {
t7: {
t8: {
hello: 'world',
},
},
},
},
},
},
},
},
},
};
const tree = render(<NestedDataList data={colourMockData} />);
const { getByTestId } = tree;
for (let i = 0; i < 8; i++) {
const item = getByTestId(`T${i}`);
const expected = BORDER_COLOURS.dark[i % 5];
expect(item.style.borderColor.toUpperCase()).toBe(expected);
}
});
it('should sort the data by values with children', () => {
const mockData = {
nonce: '5980890939790185837',
validatorHeartbeat: {
nodeId:
'e07d2cd299659590c16ec1cc1c69936ad747083c379ea6b6cfeaa6e22c8af0cb',
someArray: ['0', '1', '2'],
},
blockHeight: '174534',
};
const expected = ['nonce', 'blockHeight', 'validatorHeartbeat'];
const result = sortNestedDataByChildren(mockData);
expect(result).toStrictEqual(expected);
});
});
@@ -0,0 +1,178 @@
import React, { useCallback, useContext, useMemo, useState } from 'react';
import classNames from 'classnames';
import isObject from 'lodash/isObject';
import { ThemeContext } from '@vegaprotocol/react-helpers';
import { Icon } from '@vegaprotocol/ui-toolkit';
import { IconNames } from '@blueprintjs/icons';
import { VegaColours } from '@vegaprotocol/tailwindcss-config';
import isArray from 'lodash/isArray';
export type UnknownObject = Record<string, unknown>;
export type UnknownArray = unknown[];
interface NestedDataListProps {
data: UnknownObject | UnknownArray;
level?: number;
}
interface NestedDataListItemProps {
label: string;
value: unknown;
index: number;
}
export const BORDER_COLOURS = {
dark: [
VegaColours.pink.dark,
VegaColours.purple.dark,
VegaColours.green.dark,
VegaColours.blue.dark,
VegaColours.yellow.dark,
],
light: [
VegaColours.pink.DEFAULT,
VegaColours.purple.DEFAULT,
VegaColours.green.DEFAULT,
VegaColours.blue.DEFAULT,
VegaColours.yellow.DEFAULT,
],
};
const camelToTitle = (text: string) => {
const result = text.replace(/([A-Z])/g, ' $1');
return result.charAt(0).toUpperCase() + result.slice(1);
};
const getBorderColour = (index: number, theme: keyof typeof BORDER_COLOURS) => {
const colours = BORDER_COLOURS[theme];
const length = colours.length;
const modulo = index % length;
return colours[modulo];
};
const NestedDataListItem = ({
label,
value,
index,
}: NestedDataListItemProps) => {
const [isCollapsed, setCollapsed] = useState(true);
const toggleVisible = useCallback(
(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.stopPropagation();
setCollapsed(!isCollapsed);
},
[isCollapsed]
);
const hasChildren = isObject(value) && !!Object.keys(value).length;
const title = useMemo(() => camelToTitle(label), [label]);
const theme = useContext(ThemeContext);
const currentLevelBorder = useMemo(
() => getBorderColour(index, theme),
[index, theme]
);
const nextLevelBorder = useMemo(
() => getBorderColour(index + 1, theme),
[index, theme]
);
const isArr = isArray(value);
const listItemClasses = classNames('pl-4 border-l-4', {
'pt-10 last:pb-0': hasChildren,
'first:pt-0': hasChildren && !index,
'pt-2': !hasChildren && index,
});
const titleClasses = classNames({
'text-xl pl-4 border-l-4 font-alpha': hasChildren,
'text-base font-medium whitespace-nowrap': !hasChildren,
});
return (
<li
data-testid={title}
title={title}
className={listItemClasses}
style={{ borderColor: currentLevelBorder }}
>
<div className="flex flex-wrap">
<h4 className={titleClasses} style={{ borderColor: nextLevelBorder }}>
{hasChildren ? (
<button
className="flex items-center gap-2"
type="button"
onClick={toggleVisible}
>
<span className="">{title}</span>
<small className="px-1 text-sm rounded bg-vega-light-200 dark:bg-vega-dark-200">
{isArr ? 'array' : typeof value}
</small>
<Icon
name={
isCollapsed ? IconNames.CHEVRON_DOWN : IconNames.CHEVRON_UP
}
/>
</button>
) : (
<span className="mr-2">{title}:</span>
)}
</h4>
{!hasChildren && (
<code className="text-vega-light-400 mb-2 last:mb-0 dark:text-vega-dark-400 break-all">
{JSON.stringify(value, null, ' ')}
</code>
)}
</div>
{hasChildren && (
<div aria-hidden={isCollapsed} className={isCollapsed ? 'hidden' : ''}>
<NestedDataList
data={value as UnknownObject | UnknownArray}
level={index + 1}
/>
</div>
)}
</li>
);
};
export const sortNestedDataByChildren = (data: UnknownObject | UnknownArray) =>
Object.keys(data)
.filter((key) => key)
.sort((a, b) => {
const isArr = isArray(data);
const valA = isArr ? data[+a] : data[a];
const valB = isArr ? data[+b] : data[b];
const hasChildrenA = isObject(valA) && !!Object.keys(valA).length;
const hasChildrenB = isObject(valB) && !!Object.keys(valB).length;
if (hasChildrenA && !hasChildrenB) {
return 1;
}
if (!hasChildrenA && hasChildrenB) {
return -1;
}
return 0;
});
export const NestedDataList = ({ data, level = 0 }: NestedDataListProps) => {
const nestedItems = useMemo(() => {
const sortedData = sortNestedDataByChildren(data);
const isArr = isArray(data);
if (sortedData.length) {
return sortedData.map((key) => (
<NestedDataListItem
key={key}
label={key}
value={isArr ? data[Number(key)] : data[key]}
index={level}
/>
));
}
return null;
}, [data, level]);
return <ul className="list-none">{nestedItems}</ul>;
};
@@ -0,0 +1 @@
export * from './page-header';
@@ -0,0 +1,49 @@
import React from 'react';
import type { ReactNode } from 'react';
import { TruncateInline } from '../truncate/truncate';
import { CopyWithTooltip, Icon } from '@vegaprotocol/ui-toolkit';
interface PageHeaderProps {
title: string;
truncateStart?: number;
truncateEnd?: number;
copy?: boolean;
prefix?: string | ReactNode;
className?: string;
}
export const PageHeader = ({
prefix,
title,
truncateStart,
truncateEnd,
copy = false,
className,
}: PageHeaderProps) => {
const titleClasses = 'text-4xl xl:text-5xl uppercase font-alpha';
return (
<header className={className}>
<span className={`${titleClasses} block`}>{prefix}</span>
<div className="flex items-center gap-x-4">
<h2 className={titleClasses}>
{truncateStart && truncateEnd ? (
<TruncateInline
text={title}
startChars={truncateStart}
endChars={truncateEnd}
/>
) : (
title
)}
</h2>
{copy && (
<CopyWithTooltip data-testid="copy-to-clipboard" text={title}>
<button className="bg-zinc-100 dark:bg-zinc-900 rounded-sm py-2 px-3">
<Icon name="duplicate" className="" />
</button>
</CopyWithTooltip>
)}
</div>
</header>
);
};
+15 -6
View File
@@ -17,17 +17,26 @@ export interface IUseTxsData {
filters?: string;
}
export const getTxsDataUrl = ({ limit = 10, filters = '' }) => {
let url = `${DATA_SOURCES.blockExplorerUrl}/transactions?limit=${limit}`;
interface IGetTxsDataUrl {
limit?: string;
filters?: string;
}
export const getTxsDataUrl = ({ limit, filters }: IGetTxsDataUrl) => {
const url = new URL(`${DATA_SOURCES.blockExplorerUrl}/transactions`);
if (limit) {
url.searchParams.append('limit', limit);
}
if (filters) {
url = `${url}&${filters}`;
url.searchParams.append('filters', filters);
}
return url;
};
export const useTxsData = ({ limit = 10, filters }: IUseTxsData) => {
export const useTxsData = ({ limit, filters }: IUseTxsData) => {
const [{ txsData, hasMoreTxs, lastCursor }, setTxsState] =
useState<TxsStateProps>({
txsData: [],
@@ -35,12 +44,12 @@ export const useTxsData = ({ limit = 10, filters }: IUseTxsData) => {
lastCursor: '',
});
const url = getTxsDataUrl({ limit, filters });
const url = getTxsDataUrl({ limit: limit?.toString(), filters });
const {
state: { data, error, loading },
refetch,
} = useFetch<BlockExplorerTransactions>(url, {}, false);
} = useFetch<BlockExplorerTransactions>(url.href, {}, false);
useEffect(() => {
if (data?.transactions?.length) {
@@ -1,52 +0,0 @@
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const urlHTTP = new URL(base);
const urlWS = new URL(base);
// Replace http with ws, preserving if its a secure connection eg. https => wss
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
const cache = new InMemoryCache({
typePolicies: {
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: urlHTTP.href,
credentials: 'same-origin',
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(graphQLErrors);
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, httpLink]),
cache,
});
}
@@ -1,27 +0,0 @@
query AssetsQuery {
assetsConnection {
edges {
node {
id
name
symbol
decimals
source {
... on ERC20 {
contractAddress
}
... on BuiltinAsset {
maxFaucetAmountMint
}
}
infrastructureFeeAccount {
type
balance
market {
id
}
}
}
}
}
}
@@ -1,67 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type AssetsQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type AssetsQueryQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string }, infrastructureFeeAccount?: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null } | null } } | null> | null } | null };
export const AssetsQueryDocument = gql`
query AssetsQuery {
assetsConnection {
edges {
node {
id
name
symbol
decimals
source {
... on ERC20 {
contractAddress
}
... on BuiltinAsset {
maxFaucetAmountMint
}
}
infrastructureFeeAccount {
type
balance
market {
id
}
}
}
}
}
}
`;
/**
* __useAssetsQueryQuery__
*
* To run a query within a React component, call `useAssetsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useAssetsQueryQuery` 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 } = useAssetsQueryQuery({
* variables: {
* },
* });
*/
export function useAssetsQueryQuery(baseOptions?: Apollo.QueryHookOptions<AssetsQueryQuery, AssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<AssetsQueryQuery, AssetsQueryQueryVariables>(AssetsQueryDocument, options);
}
export function useAssetsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<AssetsQueryQuery, AssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<AssetsQueryQuery, AssetsQueryQueryVariables>(AssetsQueryDocument, options);
}
export type AssetsQueryQueryHookResult = ReturnType<typeof useAssetsQueryQuery>;
export type AssetsQueryLazyQueryHookResult = ReturnType<typeof useAssetsQueryLazyQuery>;
export type AssetsQueryQueryResult = Apollo.QueryResult<AssetsQueryQuery, AssetsQueryQueryVariables>;
@@ -1,74 +0,0 @@
query ProposalsQuery {
proposals {
id
reference
state
datetime
rejectionReason
party {
id
}
terms {
closingDatetime
enactmentDatetime
change {
... on NewMarket {
instrument {
name
}
}
... on UpdateMarket {
marketId
}
... on NewAsset {
__typename
symbol
source {
... on BuiltinAsset {
maxFaucetAmountMint
}
... on ERC20 {
contractAddress
}
}
}
... on UpdateNetworkParameter {
networkParameter {
key
value
}
}
}
}
votes {
yes {
totalTokens
totalNumber
votes {
value
party {
id
stake {
currentStakeAvailable
}
}
datetime
}
}
no {
totalTokens
totalNumber
votes {
value
party {
id
stake {
currentStakeAvailable
}
}
datetime
}
}
}
}
}
@@ -1,114 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ProposalsQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ProposalsQueryQuery = { __typename?: 'Query', proposals?: Array<{ __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', symbol: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string } } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null } } }> | null };
export const ProposalsQueryDocument = gql`
query ProposalsQuery {
proposals {
id
reference
state
datetime
rejectionReason
party {
id
}
terms {
closingDatetime
enactmentDatetime
change {
... on NewMarket {
instrument {
name
}
}
... on UpdateMarket {
marketId
}
... on NewAsset {
__typename
symbol
source {
... on BuiltinAsset {
maxFaucetAmountMint
}
... on ERC20 {
contractAddress
}
}
}
... on UpdateNetworkParameter {
networkParameter {
key
value
}
}
}
}
votes {
yes {
totalTokens
totalNumber
votes {
value
party {
id
stake {
currentStakeAvailable
}
}
datetime
}
}
no {
totalTokens
totalNumber
votes {
value
party {
id
stake {
currentStakeAvailable
}
}
datetime
}
}
}
}
}
`;
/**
* __useProposalsQueryQuery__
*
* To run a query within a React component, call `useProposalsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useProposalsQueryQuery` 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 } = useProposalsQueryQuery({
* variables: {
* },
* });
*/
export function useProposalsQueryQuery(baseOptions?: Apollo.QueryHookOptions<ProposalsQueryQuery, ProposalsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ProposalsQueryQuery, ProposalsQueryQueryVariables>(ProposalsQueryDocument, options);
}
export function useProposalsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ProposalsQueryQuery, ProposalsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ProposalsQueryQuery, ProposalsQueryQueryVariables>(ProposalsQueryDocument, options);
}
export type ProposalsQueryQueryHookResult = ReturnType<typeof useProposalsQueryQuery>;
export type ProposalsQueryLazyQueryHookResult = ReturnType<typeof useProposalsQueryLazyQuery>;
export type ProposalsQueryQueryResult = Apollo.QueryResult<ProposalsQueryQuery, ProposalsQueryQueryVariables>;
@@ -1,133 +0,0 @@
query MarketsQuery {
markets {
id
fees {
factors {
makerFee
infrastructureFee
liquidityFee
}
}
tradableInstrument {
instrument {
name
metadata {
tags
}
id
code
product {
... on Future {
settlementAsset {
id
name
decimals
globalRewardPoolAccount {
balance
}
}
}
}
}
riskModel {
... on LogNormalRiskModel {
tau
riskAversionParameter
params {
r
sigma
mu
}
}
... on SimpleRiskModel {
params {
factorLong
factorShort
}
}
}
marginCalculator {
scalingFactors {
searchLevel
initialMargin
collateralRelease
}
}
}
decimalPlaces
openingAuction {
durationSecs
volume
}
priceMonitoringSettings {
parameters {
triggers {
horizonSecs
probability
auctionExtensionSecs
}
}
}
liquidityMonitoringParameters {
triggeringRatio
targetStakeParameters {
timeWindow
scalingFactor
}
}
tradingMode
state
proposal {
id
}
state
accounts {
asset {
id
name
}
balance
type
}
data {
markPrice
bestBidPrice
bestBidVolume
bestOfferPrice
bestOfferVolume
bestStaticBidPrice
bestStaticBidVolume
bestStaticOfferPrice
bestStaticOfferVolume
midPrice
staticMidPrice
timestamp
openInterest
auctionEnd
auctionStart
indicativePrice
indicativeVolume
trigger
extensionTrigger
targetStake
suppliedStake
priceMonitoringBounds {
minValidPrice
maxValidPrice
trigger {
auctionExtensionSecs
probability
}
referencePrice
}
marketValueProxy
liquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
}
}
}
@@ -1,173 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketsQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type MarketsQueryQuery = { __typename?: 'Query', markets?: Array<{ __typename?: 'Market', id: string, decimalPlaces: number, tradingMode: Types.MarketTradingMode, state: Types.MarketState, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, id: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', settlementAsset: { __typename?: 'Asset', id: string, name: string, decimals: number, globalRewardPoolAccount?: { __typename?: 'AccountBalance', balance: string } | null } } }, riskModel: { __typename?: 'LogNormalRiskModel', tau: number, riskAversionParameter: number, params: { __typename?: 'LogNormalModelParams', r: number, sigma: number, mu: number } } | { __typename?: 'SimpleRiskModel', params: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } }, marginCalculator?: { __typename?: 'MarginCalculator', scalingFactors: { __typename?: 'ScalingFactors', searchLevel: number, initialMargin: number, collateralRelease: number } } | null }, openingAuction: { __typename?: 'AuctionDuration', durationSecs: number, volume: number }, priceMonitoringSettings: { __typename?: 'PriceMonitoringSettings', parameters?: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null } | null }, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: number, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, proposal?: { __typename?: 'Proposal', id?: string | null } | null, accounts?: Array<{ __typename?: 'AccountBalance', balance: string, type: Types.AccountType, asset: { __typename?: 'Asset', id: string, name: string } }> | null, data?: { __typename?: 'MarketData', markPrice: string, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, midPrice: string, staticMidPrice: string, timestamp: string, openInterest: string, auctionEnd?: string | null, auctionStart?: string | null, indicativePrice: string, indicativeVolume: string, trigger: Types.AuctionTrigger, extensionTrigger: Types.AuctionTrigger, targetStake?: string | null, suppliedStake?: string | null, marketValueProxy: string, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', auctionExtensionSecs: number, probability: number } }> | null, liquidityProviderFeeShare?: Array<{ __typename?: 'LiquidityProviderFeeShare', equityLikeShare: string, averageEntryValuation: string, party: { __typename?: 'Party', id: string } }> | null } | null }> | null };
export const MarketsQueryDocument = gql`
query MarketsQuery {
markets {
id
fees {
factors {
makerFee
infrastructureFee
liquidityFee
}
}
tradableInstrument {
instrument {
name
metadata {
tags
}
id
code
product {
... on Future {
settlementAsset {
id
name
decimals
globalRewardPoolAccount {
balance
}
}
}
}
}
riskModel {
... on LogNormalRiskModel {
tau
riskAversionParameter
params {
r
sigma
mu
}
}
... on SimpleRiskModel {
params {
factorLong
factorShort
}
}
}
marginCalculator {
scalingFactors {
searchLevel
initialMargin
collateralRelease
}
}
}
decimalPlaces
openingAuction {
durationSecs
volume
}
priceMonitoringSettings {
parameters {
triggers {
horizonSecs
probability
auctionExtensionSecs
}
}
}
liquidityMonitoringParameters {
triggeringRatio
targetStakeParameters {
timeWindow
scalingFactor
}
}
tradingMode
state
proposal {
id
}
state
accounts {
asset {
id
name
}
balance
type
}
data {
markPrice
bestBidPrice
bestBidVolume
bestOfferPrice
bestOfferVolume
bestStaticBidPrice
bestStaticBidVolume
bestStaticOfferPrice
bestStaticOfferVolume
midPrice
staticMidPrice
timestamp
openInterest
auctionEnd
auctionStart
indicativePrice
indicativeVolume
trigger
extensionTrigger
targetStake
suppliedStake
priceMonitoringBounds {
minValidPrice
maxValidPrice
trigger {
auctionExtensionSecs
probability
}
referencePrice
}
marketValueProxy
liquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
}
}
}
`;
/**
* __useMarketsQueryQuery__
*
* To run a query within a React component, call `useMarketsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketsQueryQuery` 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 } = useMarketsQueryQuery({
* variables: {
* },
* });
*/
export function useMarketsQueryQuery(baseOptions?: Apollo.QueryHookOptions<MarketsQueryQuery, MarketsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketsQueryQuery, MarketsQueryQueryVariables>(MarketsQueryDocument, options);
}
export function useMarketsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketsQueryQuery, MarketsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketsQueryQuery, MarketsQueryQueryVariables>(MarketsQueryDocument, options);
}
export type MarketsQueryQueryHookResult = ReturnType<typeof useMarketsQueryQuery>;
export type MarketsQueryLazyQueryHookResult = ReturnType<typeof useMarketsQueryLazyQuery>;
export type MarketsQueryQueryResult = Apollo.QueryResult<MarketsQueryQuery, MarketsQueryQueryVariables>;
@@ -1,6 +0,0 @@
query NetworkParametersQuery {
networkParameters {
key
value
}
}
@@ -1,27 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: NetworkParametersQuery
// ====================================================
export interface NetworkParametersQuery_networkParameters {
__typename: "NetworkParameter";
/**
* The name of the network parameter
*/
key: string;
/**
* The value of the network parameter
*/
value: string;
}
export interface NetworkParametersQuery {
/**
* Return the full list of network parameters
*/
networkParameters: NetworkParametersQuery_networkParameters[] | null;
}
@@ -1,46 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type NetworkParametersQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type NetworkParametersQueryQuery = { __typename?: 'Query', networkParameters?: Array<{ __typename?: 'NetworkParameter', key: string, value: string }> | null };
export const NetworkParametersQueryDocument = gql`
query NetworkParametersQuery {
networkParameters {
key
value
}
}
`;
/**
* __useNetworkParametersQueryQuery__
*
* To run a query within a React component, call `useNetworkParametersQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useNetworkParametersQueryQuery` 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 } = useNetworkParametersQueryQuery({
* variables: {
* },
* });
*/
export function useNetworkParametersQueryQuery(baseOptions?: Apollo.QueryHookOptions<NetworkParametersQueryQuery, NetworkParametersQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<NetworkParametersQueryQuery, NetworkParametersQueryQueryVariables>(NetworkParametersQueryDocument, options);
}
export function useNetworkParametersQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<NetworkParametersQueryQuery, NetworkParametersQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<NetworkParametersQueryQuery, NetworkParametersQueryQueryVariables>(NetworkParametersQueryDocument, options);
}
export type NetworkParametersQueryQueryHookResult = ReturnType<typeof useNetworkParametersQueryQuery>;
export type NetworkParametersQueryLazyQueryHookResult = ReturnType<typeof useNetworkParametersQueryLazyQuery>;
export type NetworkParametersQueryQueryResult = Apollo.QueryResult<NetworkParametersQueryQuery, NetworkParametersQueryQueryVariables>;
@@ -1,22 +1,28 @@
import { render, screen } from '@testing-library/react';
import type { NetworkParamsQuery } from '@vegaprotocol/react-helpers';
import { NetworkParametersTable } from './network-parameters';
import type { NetworkParametersQuery } from './__generated__/NetworkParametersQuery';
describe('NetworkParametersTable', () => {
it('renders correctly when it has network params', () => {
const data: NetworkParametersQuery = {
networkParameters: [
{
__typename: 'NetworkParameter',
key: 'market.liquidityProvision.minLpStakeQuantumMultiple',
value: '1',
},
{
__typename: 'NetworkParameter',
key: 'market.fee.factors.infrastructureFee',
value: '0.0005',
},
],
const data: NetworkParamsQuery = {
networkParametersConnection: {
edges: [
{
node: {
__typename: 'NetworkParameter',
key: 'market.liquidityProvision.minLpStakeQuantumMultiple',
value: '1',
},
},
{
node: {
__typename: 'NetworkParameter',
key: 'market.fee.factors.infrastructureFee',
value: '0.0005',
},
},
],
},
};
render(<NetworkParametersTable data={data} loading={false} />);
expect(screen.getByTestId('network-param-header')).toHaveTextContent(
@@ -34,19 +40,25 @@ describe('NetworkParametersTable', () => {
});
it('renders the rows in ascending order', () => {
const data: NetworkParametersQuery = {
networkParameters: [
{
__typename: 'NetworkParameter',
key: 'market.fee.factors.infrastructureFee',
value: '0.0005',
},
{
__typename: 'NetworkParameter',
key: 'market.liquidityProvision.minLpStakeQuantumMultiple',
value: '1',
},
],
const data: NetworkParamsQuery = {
networkParametersConnection: {
edges: [
{
node: {
__typename: 'NetworkParameter',
key: 'market.fee.factors.infrastructureFee',
value: '0.0005',
},
},
{
node: {
__typename: 'NetworkParameter',
key: 'market.liquidityProvision.minLpStakeQuantumMultiple',
value: '1',
},
},
],
},
};
render(<NetworkParametersTable data={data} loading={false} />);
expect(screen.getByTestId('network-param-header')).toHaveTextContent(
@@ -1,4 +1,3 @@
import { gql, useQuery } from '@apollo/client';
import {
AsyncRenderer,
KeyValueTable,
@@ -12,11 +11,10 @@ import {
} from '@vegaprotocol/react-helpers';
import { suitableForSyntaxHighlighter } from '@vegaprotocol/react-helpers';
import { RouteTitle } from '../../components/route-title';
import type {
NetworkParametersQuery,
NetworkParametersQuery_networkParameters,
} from './__generated__/NetworkParametersQuery';
import orderBy from 'lodash/orderBy';
import type { NetworkParamsQuery } from '@vegaprotocol/react-helpers';
import { useNetworkParamsQuery } from '@vegaprotocol/react-helpers';
import compact from 'lodash/compact';
const PERCENTAGE_PARAMS = [
'governance.proposal.asset.requiredMajority',
@@ -57,7 +55,7 @@ const BIG_NUMBER_PARAMS = [
export const NetworkParameterRow = ({
row: { key, value },
}: {
row: NetworkParametersQuery_networkParameters;
row: { key: string; value: string };
}) => {
const isSyntaxRow = suitableForSyntaxHighlighter(value);
@@ -86,18 +84,9 @@ export const NetworkParameterRow = ({
);
};
export const NETWORK_PARAMETERS_QUERY = gql`
query NetworkParametersQuery {
networkParameters {
key
value
}
}
`;
export interface NetworkParametersTableProps
extends React.HTMLAttributes<HTMLTableElement> {
data?: NetworkParametersQuery;
data?: NetworkParamsQuery | undefined;
error?: Error;
loading: boolean;
}
@@ -118,7 +107,9 @@ export const NetworkParametersTable = ({
error={error}
render={(data) => {
const ascParams = orderBy(
data.networkParameters || [],
compact(data.networkParametersConnection.edges).map(
({ node }) => node
) || [],
(param) => param.key,
'asc'
);
@@ -135,8 +126,6 @@ export const NetworkParametersTable = ({
);
export const NetworkParameters = () => {
const { data, loading, error } = useQuery<NetworkParametersQuery>(
NETWORK_PARAMETERS_QUERY
);
const { data, loading, error } = useNetworkParamsQuery();
return <NetworkParametersTable data={data} error={error} loading={loading} />;
};
@@ -1,26 +0,0 @@
query OracleSpecs {
oracleSpecsConnection {
edges {
node {
status
id
createdAt
updatedAt
pubKeys
filters {
key {
name
type
}
conditions {
value
operator
}
}
data {
pubKeys
}
}
}
}
}
@@ -3,25 +3,13 @@
// @generated
// This file was automatically generated and should not be edited.
import { OracleSpecStatus, PropertyKeyType, ConditionOperator } from "@vegaprotocol/types";
import { DataSourceSpecStatus, ConditionOperator, PropertyKeyType } from "@vegaprotocol/types";
// ====================================================
// GraphQL query operation: OracleSpecs
// ====================================================
export interface OracleSpecs_oracleSpecs_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface OracleSpecs_oracleSpecs_filters_conditions {
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType_conditions {
__typename: "Condition";
/**
* The value to compare against.
@@ -33,35 +21,101 @@ export interface OracleSpecs_oracleSpecs_filters_conditions {
operator: ConditionOperator;
}
export interface OracleSpecs_oracleSpecs_filters {
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType {
__typename: "DataSourceSpecConfigurationTime";
conditions: (OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType_conditions | null)[];
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal {
__typename: "DataSourceDefinitionInternal";
sourceType: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export type OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer = OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress | OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey;
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers {
__typename: "Signer";
signer: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions {
__typename: "Condition";
/**
* The value to compare against.
*/
value: string | null;
/**
* The type of comparison to make on the value.
*/
operator: ConditionOperator;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters {
__typename: "Filter";
/**
* The oracle data property key targeted by the filter.
* key is the data source data property key targeted by the filter.
*/
key: OracleSpecs_oracleSpecs_filters_key;
key: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: OracleSpecs_oracleSpecs_filters_conditions[] | null;
conditions: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions[] | null;
}
export interface OracleSpecs_oracleSpecs_data {
__typename: "OracleData";
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType {
__typename: "DataSourceSpecConfiguration";
/**
* The list of public keys that signed the data
* signers is the list of authorized signatures that signed the data for this
* data source. All the public keys in the data should be contained in this
* list.
*/
pubKeys: string[] | null;
signers: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers[] | null;
/**
* filters describes which source data are considered of interest or not for
* the product (or the risk model).
*/
filters: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters[] | null;
}
export interface OracleSpecs_oracleSpecs {
__typename: "OracleSpec";
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal {
__typename: "DataSourceDefinitionExternal";
sourceType: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType;
}
export type OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType = OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal | OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal;
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data {
__typename: "DataSourceDefinition";
sourceType: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec {
__typename: "DataSourceSpec";
/**
* Status describes the status of the oracle spec
*/
status: OracleSpecStatus;
/**
* ID is a hash generated from the OracleSpec data.
* ID is a hash generated from the DataSourceSpec data.
*/
id: string;
/**
@@ -73,20 +127,102 @@ export interface OracleSpecs_oracleSpecs {
*/
updatedAt: string | null;
/**
* The list of authorized public keys that signed the data for this
* oracle. All the public keys in the oracle data should be contained in these
* public keys.
* Status describes the status of the data source spec
*/
pubKeys: string[] | null;
status: DataSourceSpecStatus;
data: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec {
__typename: "ExternalDataSourceSpec";
spec: OracleSpecs_oracleSpecs_dataSourceSpec_spec;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export type OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer = OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_ETHAddress | OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_PubKey;
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers {
__typename: "Signer";
signer: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_data {
__typename: "Property";
/**
* Filters describes which oracle data are considered of interest or not for
* the product (or the risk model).
* Name of the property
*/
filters: OracleSpecs_oracleSpecs_filters[] | null;
name: string;
/**
* Value of the property
*/
value: string;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data {
__typename: "Data";
/**
* signers is the list of public keys/ETH addresses that signed the data
*/
signers: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers[] | null;
/**
* properties contains all the properties sent by a data source
*/
data: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_data[] | null;
/**
* List of all the data specs that matched this source data.
* When the array is empty, it means no data spec matched this source data.
*/
matchedSpecIds: string[] | null;
/**
* RFC3339Nano formatted date and time for when the data was broadcast to the markets
* with a matching data spec.
* It has no value when the source data does not match any data spec.
*/
broadcastAt: string;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData {
__typename: "ExternalData";
data: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node {
__typename: "OracleData";
externalData: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges {
__typename: "OracleDataEdge";
/**
* The oracle data source
*/
node: OracleSpecs_oracleSpecs_dataConnection_edges_node;
}
export interface OracleSpecs_oracleSpecs_dataConnection {
__typename: "OracleDataConnection";
/**
* The oracle data spec
*/
edges: (OracleSpecs_oracleSpecs_dataConnection_edges | null)[] | null;
}
export interface OracleSpecs_oracleSpecs {
__typename: "OracleSpec";
dataSourceSpec: OracleSpecs_oracleSpecs_dataSourceSpec;
/**
* Data list all the oracle data broadcast to this spec
*/
data: OracleSpecs_oracleSpecs_data[];
dataConnection: OracleSpecs_oracleSpecs_dataConnection;
}
export interface OracleSpecs {
@@ -1,66 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type OracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type OracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', status: Types.OracleSpecStatus, id: string, createdAt: string, updatedAt?: string | null, pubKeys?: Array<string> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null, data: Array<{ __typename?: 'OracleData', pubKeys?: Array<string> | null }> } } | null> | null } | null };
export const OracleSpecsDocument = gql`
query OracleSpecs {
oracleSpecsConnection {
edges {
node {
status
id
createdAt
updatedAt
pubKeys
filters {
key {
name
type
}
conditions {
value
operator
}
}
data {
pubKeys
}
}
}
}
}
`;
/**
* __useOracleSpecsQuery__
*
* To run a query within a React component, call `useOracleSpecsQuery` and pass it any options that fit your needs.
* When your component renders, `useOracleSpecsQuery` 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 } = useOracleSpecsQuery({
* variables: {
* },
* });
*/
export function useOracleSpecsQuery(baseOptions?: Apollo.QueryHookOptions<OracleSpecsQuery, OracleSpecsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<OracleSpecsQuery, OracleSpecsQueryVariables>(OracleSpecsDocument, options);
}
export function useOracleSpecsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<OracleSpecsQuery, OracleSpecsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<OracleSpecsQuery, OracleSpecsQueryVariables>(OracleSpecsDocument, options);
}
export type OracleSpecsQueryHookResult = ReturnType<typeof useOracleSpecsQuery>;
export type OracleSpecsLazyQueryHookResult = ReturnType<typeof useOracleSpecsLazyQuery>;
export type OracleSpecsQueryResult = Apollo.QueryResult<OracleSpecsQuery, OracleSpecsQueryVariables>;
+80 -21
View File
@@ -11,23 +11,79 @@ import { SubHeading } from '../../components/sub-heading';
const ORACLE_SPECS_QUERY = gql`
query OracleSpecs {
oracleSpecs {
status
id
createdAt
updatedAt
pubKeys
filters {
key {
name
type
}
conditions {
value
operator
dataSourceSpec {
spec {
id
createdAt
updatedAt
status
data {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
value
operator
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
filters {
key {
name
type
}
conditions {
value
operator
}
}
}
}
}
}
}
}
}
data {
pubKeys
dataConnection {
edges {
node {
externalData {
data {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
data {
name
value
}
matchedSpecIds
broadcastAt
}
}
}
}
}
}
}
@@ -53,12 +109,15 @@ const Oracles = () => {
<section>
<RouteTitle data-testid="oracle-specs-heading">{t('Oracles')}</RouteTitle>
{data?.oracleSpecs
? data.oracleSpecs.map((o) => (
<React.Fragment key={o.id}>
<SubHeading id={o.id.toString()}>{o.id}</SubHeading>
<SyntaxHighlighter data={o} />
</React.Fragment>
))
? data.oracleSpecs.map((o) => {
const id = o.dataSourceSpec.spec.id;
return (
<React.Fragment key={id}>
<SubHeading id={id.toString()}>{id}</SubHeading>
<SyntaxHighlighter data={o} />
</React.Fragment>
);
})
: null}
</section>
);
@@ -1,32 +0,0 @@
query PartyAssetsQuery($partyId: ID!) {
party(id: $partyId) {
id
delegations {
amount
node {
id
name
}
epoch
}
stake {
currentStakeAvailable
}
accounts {
asset {
name
id
decimals
symbol
source {
__typename
... on ERC20 {
contractAddress
}
}
}
type
balance
}
}
}
@@ -1,75 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type PartyAssetsQueryQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type PartyAssetsQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, delegations?: Array<{ __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } }> | null, stake: { __typename?: 'PartyStake', currentStakeAvailable: string }, accounts?: Array<{ __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } } }> | null } | null };
export const PartyAssetsQueryDocument = gql`
query PartyAssetsQuery($partyId: ID!) {
party(id: $partyId) {
id
delegations {
amount
node {
id
name
}
epoch
}
stake {
currentStakeAvailable
}
accounts {
asset {
name
id
decimals
symbol
source {
__typename
... on ERC20 {
contractAddress
}
}
}
type
balance
}
}
}
`;
/**
* __usePartyAssetsQueryQuery__
*
* To run a query within a React component, call `usePartyAssetsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `usePartyAssetsQueryQuery` 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 } = usePartyAssetsQueryQuery({
* variables: {
* partyId: // value for 'partyId'
* },
* });
*/
export function usePartyAssetsQueryQuery(baseOptions: Apollo.QueryHookOptions<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>(PartyAssetsQueryDocument, options);
}
export function usePartyAssetsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>(PartyAssetsQueryDocument, options);
}
export type PartyAssetsQueryQueryHookResult = ReturnType<typeof usePartyAssetsQueryQuery>;
export type PartyAssetsQueryLazyQueryHookResult = ReturnType<typeof usePartyAssetsQueryLazyQuery>;
export type PartyAssetsQueryQueryResult = Apollo.QueryResult<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>;
@@ -9,33 +9,8 @@ import { AccountType } from "@vegaprotocol/types";
// GraphQL query operation: PartyAssetsQuery
// ====================================================
export interface PartyAssetsQuery_party_delegations_node {
__typename: "Node";
/**
* The node URL eg n01.vega.xyz
*/
id: string;
name: string;
}
export interface PartyAssetsQuery_party_delegations {
__typename: "Delegation";
/**
* Amount delegated
*/
amount: string;
/**
* URL of node you are delegating to
*/
node: PartyAssetsQuery_party_delegations_node;
/**
* Epoch of delegation
*/
epoch: number;
}
export interface PartyAssetsQuery_party_stake {
__typename: "PartyStake";
export interface PartyAssetsQuery_party_stakingSummary {
__typename: "StakingSummary";
/**
* The stake currently available for the party
*/
@@ -102,11 +77,10 @@ export interface PartyAssetsQuery_party {
* Party identifier
*/
id: string;
delegations: PartyAssetsQuery_party_delegations[] | null;
/**
* The staking information for this Party
*/
stake: PartyAssetsQuery_party_stake;
stakingSummary: PartyAssetsQuery_party_stakingSummary;
/**
* Collateral accounts relating to a party
*/
@@ -9,16 +9,10 @@ import {
import React, { useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { SubHeading } from '../../../components/sub-heading';
import {
CopyWithTooltip,
Icon,
SyntaxHighlighter,
AsyncRenderer,
} from '@vegaprotocol/ui-toolkit';
import { SyntaxHighlighter, AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { Panel } from '../../../components/panel';
import { InfoPanel } from '../../../components/info-panel';
import { toNonHex } from '../../../components/search/detect-search';
import { TruncateInline } from '../../../components/truncate/truncate';
import { DATA_SOURCES } from '../../../config';
import type {
PartyAssetsQuery,
@@ -27,20 +21,13 @@ import type {
import type { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
import { useTxsData } from '../../../hooks/use-txs-data';
import { TxsInfiniteList } from '../../../components/txs';
import { PageHeader } from '../../../components/page-header';
const PARTY_ASSETS_QUERY = gql`
query PartyAssetsQuery($partyId: ID!) {
party(id: $partyId) {
id
delegations {
amount
node {
id
name
}
epoch
}
stake {
stakingSummary {
currentStakeAvailable
}
accounts {
@@ -91,19 +78,12 @@ const Party = () => {
);
const header = data?.party?.id ? (
<header className="flex items-center gap-x-4">
<TruncateInline
text={data.party.id}
startChars={visibleChars}
endChars={visibleChars}
className="text-4xl xl:text-5xl uppercase font-alpha"
/>
<CopyWithTooltip text={data.party.id}>
<button className="bg-zinc-100 dark:bg-zinc-900 rounded-sm py-2 px-3">
<Icon name="duplicate" className="" />
</button>
</CopyWithTooltip>
</header>
<PageHeader
title={data.party.id}
copy
truncateStart={visibleChars}
truncateEnd={visibleChars}
/>
) : (
<Panel>
<p>No party found for key {party}</p>
@@ -142,10 +122,10 @@ const Party = () => {
const staking = (
<section>
{data?.party?.stake?.currentStakeAvailable ? (
{data?.party?.stakingSummary?.currentStakeAvailable ? (
<InfoPanel
title={t('Current Stake Available')}
id={data?.party?.stake?.currentStakeAvailable}
id={data?.party?.stakingSummary?.currentStakeAvailable}
copy={false}
/>
) : (
@@ -4,7 +4,7 @@ import { BlocksRefetch } from '../../../components/blocks';
import { TxsInfiniteList, TxsStatsInfo } from '../../../components/txs';
import { useTxsData } from '../../../hooks/use-txs-data';
const BE_TXS_PER_REQUEST = 100;
const BE_TXS_PER_REQUEST = 20;
export const TxsList = () => {
const { hasMoreTxs, loadTxs, error, txsData, refreshTxs, loading } =
+24 -8
View File
@@ -1,14 +1,16 @@
import React from 'react';
import { useParams } from 'react-router-dom';
import { Link, useParams } from 'react-router-dom';
import { useFetch } from '@vegaprotocol/react-helpers';
import { DATA_SOURCES } from '../../../config';
import { RouteTitle } from '../../../components/route-title';
import { RenderFetched } from '../../../components/render-fetched';
import { TxContent } from './tx-content';
import { TxDetails } from './tx-details';
import { t } from '@vegaprotocol/react-helpers';
import type { BlockExplorerTransaction } from '../../../routes/types/block-explorer-response';
import { toNonHex } from '../../../components/search/detect-search';
import { PageHeader } from '../../../components/page-header';
import { Routes } from '../../../routes/route-names';
import { IconNames } from '@blueprintjs/icons';
import { Icon } from '@vegaprotocol/ui-toolkit';
const Tx = () => {
const { txHash } = useParams<{ txHash: string }>();
@@ -22,7 +24,25 @@ const Tx = () => {
return (
<section>
<RouteTitle>{t('Transaction details')}</RouteTitle>
<Link
className="font-normal underline underline-offset-4 block mb-5"
to={`/${Routes.TX}`}
>
<Icon
className="text-vega-light-300 dark:text-vega-light-300"
name={IconNames.CHEVRON_LEFT}
/>
All Transactions
</Link>
<PageHeader
title={hash}
prefix="Transaction"
copy
truncateStart={5}
truncateEnd={9}
className="mb-5"
/>
<RenderFetched error={tTxError} loading={tTxLoading}>
<>
@@ -32,10 +52,6 @@ const Tx = () => {
pubKey={data?.transaction.submitter}
/>
<h2 className="text-2xl uppercase mb-4">
{t('Transaction content')}
</h2>
<TxContent data={data?.transaction} />
</>
</RenderFetched>
@@ -1,13 +1,6 @@
import { t } from '@vegaprotocol/react-helpers';
import { StatusMessage } from '../../../components/status-message';
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
import {
TableWithTbody,
TableCell,
TableHeader,
TableRow,
} from '../../../components/table';
import { TxOrderType } from '../../../components/txs';
import { NestedDataList } from '../../../components/nested-data-list';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
interface TxContentProps {
@@ -23,21 +16,5 @@ export const TxContent = ({ data }: TxContentProps) => {
);
}
return (
<>
<TableWithTbody className="mb-12">
<TableRow modifier="bordered">
<TableHeader scope="row" className="w-[160px]">
{t('Type')}
</TableHeader>
<TableCell modifier="bordered">
<TxOrderType orderType={data.type} />
</TableCell>
</TableRow>
</TableWithTbody>
<h3 className="font-mono mb-8">{t('Decoded transaction content')}</h3>
<SyntaxHighlighter data={data.command} />
</>
);
return <NestedDataList data={data.command} />;
};
@@ -25,11 +25,6 @@ const renderComponent = (txData: BlockExplorerTransactionResult) => (
);
describe('Transaction details', () => {
it('Renders the tx hash', () => {
render(renderComponent(txData));
expect(screen.getByText(hash)).toBeInTheDocument();
});
it('Renders the pubKey', () => {
render(renderComponent(txData));
expect(screen.getByText(pubKey)).toBeInTheDocument();
@@ -39,9 +34,4 @@ describe('Transaction details', () => {
render(renderComponent(txData));
expect(screen.getByText(height)).toBeInTheDocument();
});
it('Renders a copy button', () => {
render(renderComponent(txData));
expect(screen.getByTestId('copy-tx-to-clipboard')).toBeInTheDocument();
});
});
@@ -1,15 +1,9 @@
import { Routes } from '../../route-names';
import { CopyWithTooltip, Icon } from '@vegaprotocol/ui-toolkit';
import {
TableWithTbody,
TableCell,
TableHeader,
TableRow,
} from '../../../components/table';
import { t } from '@vegaprotocol/react-helpers';
import { HighlightedLink } from '../../../components/highlighted-link';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import React from 'react';
import { TruncateInline } from '../../../components/truncate/truncate';
import { Link } from 'react-router-dom';
interface TxDetailsProps {
txData: BlockExplorerTransactionResult | undefined;
@@ -24,40 +18,32 @@ export const TxDetails = ({ txData, pubKey, className }: TxDetailsProps) => {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const truncatedSubmitter = (
<TruncateInline text={pubKey || ''} startChars={5} endChars={5} />
);
return (
<TableWithTbody className={className}>
<TableRow modifier="bordered">
<TableCell>{t('Hash')}</TableCell>
<TableCell modifier="bordered" data-testid="hash">
{txData.hash}
<CopyWithTooltip text={txData.hash}>
<button
title={t('Copy tx to clipboard')}
data-testid="copy-tx-to-clipboard"
className="underline"
>
<Icon name="duplicate" className="ml-2" />
</button>
</CopyWithTooltip>
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableHeader scope="row" className="w-[160px]">
{t('Submitted by')}
</TableHeader>
<TableCell modifier="bordered" data-testid="submitted-by">
<HighlightedLink to={`/${Routes.PARTIES}/${pubKey}`} text={pubKey} />
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Block')}</TableCell>
<TableCell modifier="bordered" data-testid="block">
<HighlightedLink
to={`/${Routes.BLOCKS}/${txData.block}`}
text={txData.block}
/>
</TableCell>
</TableRow>
</TableWithTbody>
<section className="mb-10">
<h3 className="text-3xl xl:text-4xl uppercase font-alpha mb-4">
{txData.type} by{' '}
<Link
className="font-bold underline"
to={`/${Routes.PARTIES}/${pubKey}`}
>
{truncatedSubmitter}
</Link>
</h3>
<p className="text-xl xl:text-2xl uppercase font-alpha">
Block{' '}
<Link
className="font-bold underline"
to={`/${Routes.BLOCKS}/${txData.block}`}
>
{txData.block}
</Link>
{', '}
Index {txData.index}
</p>
</section>
);
};
@@ -1,22 +0,0 @@
query NodesQuery {
nodes {
id
name
infoUrl
avatarUrl
pubkey
tmPubkey
ethereumAddress
location
stakedByOperator
stakedByDelegates
stakedTotal
pendingStake
epochData {
total
offline
online
}
status
}
}
@@ -1,62 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type NodesQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type NodesQueryQuery = { __typename?: 'Query', nodes?: Array<{ __typename?: 'Node', id: string, name: string, infoUrl: string, avatarUrl?: string | null, pubkey: string, tmPubkey: string, ethereumAddress: string, location: string, stakedByOperator: string, stakedByDelegates: string, stakedTotal: string, pendingStake: string, status: Types.NodeStatus, epochData?: { __typename?: 'EpochData', total: number, offline: number, online: number } | null }> | null };
export const NodesQueryDocument = gql`
query NodesQuery {
nodes {
id
name
infoUrl
avatarUrl
pubkey
tmPubkey
ethereumAddress
location
stakedByOperator
stakedByDelegates
stakedTotal
pendingStake
epochData {
total
offline
online
}
status
}
}
`;
/**
* __useNodesQueryQuery__
*
* To run a query within a React component, call `useNodesQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useNodesQueryQuery` 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 } = useNodesQueryQuery({
* variables: {
* },
* });
*/
export function useNodesQueryQuery(baseOptions?: Apollo.QueryHookOptions<NodesQueryQuery, NodesQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<NodesQueryQuery, NodesQueryQueryVariables>(NodesQueryDocument, options);
}
export function useNodesQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<NodesQueryQuery, NodesQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<NodesQueryQuery, NodesQueryQueryVariables>(NodesQueryDocument, options);
}
export type NodesQueryQueryHookResult = ReturnType<typeof useNodesQueryQuery>;
export type NodesQueryLazyQueryHookResult = ReturnType<typeof useNodesQueryLazyQuery>;
export type NodesQueryQueryResult = Apollo.QueryResult<NodesQueryQuery, NodesQueryQueryVariables>;
+2 -2
View File
@@ -20,7 +20,7 @@
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
<script src="./assets/env-config.js"></script>
</head>
<body>
<div id="root"></div>
<body class="dark:bg-black h-full w-full">
<div id="root" class="h-full w-full"></div>
</body>
</html>
+9 -1
View File
@@ -1,6 +1,9 @@
const { join } = require('path');
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
const theme = require('../../libs/tailwindcss-config/src/theme');
const {
VegaColours,
} = require('../../libs/tailwindcss-config/src/vega-colours');
const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes');
module.exports = {
@@ -11,7 +14,12 @@ module.exports = {
],
darkMode: 'class',
theme: {
extend: theme,
extend: {
...theme,
colors: {
vega: VegaColours,
},
},
},
plugins: [vegaCustomClasses],
};
@@ -1,14 +1,17 @@
import { useRoutes } from 'react-router-dom';
import '../styles.scss';
import { Header } from './components/header';
import { Intro } from './components/intro';
import { MarketList } from './components/market-list';
import { Navbar } from './components/navbar';
import { routerConfig } from './routes/router-config';
const AppRouter = () => useRoutes(routerConfig);
export function App() {
return (
<div className="max-h-full min-h-full bg-white">
<Header />
<Intro />
<MarketList />
<Navbar />
<AppRouter />
</div>
);
}
@@ -0,0 +1,25 @@
import { t } from '@vegaprotocol/react-helpers';
import { Intro } from './intro';
import { MarketList } from './market-list';
export function Dashboard() {
return (
<>
<div className="px-16 pt-20 pb-12 bg-greys-light-100">
<div className="max-w-screen-xl mx-auto">
<h1 className="font-alpha uppercase text-5xl mb-8">
{t('Top liquidity opportunities')}
</h1>
<Intro />
</div>
</div>
<div className="px-16 py-6">
<div className="max-w-screen-xl mx-auto">
<MarketList />
</div>
</div>
</>
);
}
@@ -0,0 +1 @@
export * from './dashboard';
@@ -5,20 +5,20 @@ import { ExternalLink } from '@vegaprotocol/ui-toolkit';
const LINKS = {
testnet: [
{
label: 'Understand how liquidity fees are calculated',
label: 'Learn about liquidity fees',
url: 'https://docs.vega.xyz/docs/testnet/tutorials/providing-liquidity#resources',
},
{
label: 'How to provide liquidity',
label: 'Provide liquidity',
url: 'https://docs.vega.xyz/docs/testnet/tutorials/providing-liquidity#overview',
},
{
label: 'How to view existing liquidity provisions',
label: 'View your liquidity provisions',
url: 'https://docs.vega.xyz/docs/testnet/tutorials/providing-liquidity#viewing-existing-liquidity-provisions',
},
{
label: 'How to amend or remove liquidity',
url: 'https://docs.vega.xyz/docs/testnet/tutorials/providing-liquidity#amending-a-liquidity-commitment',
label: 'Amend or remove liquidity',
url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#amending-a-liquidity-commitment',
},
],
mainnet: [],
@@ -29,12 +29,11 @@ type Network = 'testnet' | 'mainnet';
export const Intro = ({ network = 'testnet' }: { network?: Network }) => {
return (
<div className="mx-6 my-6 px-6 py-6 bg-neutral-100" data-testid="intro">
<h2 className="text-xl font-medium mb-1">
{t('Become a liquidity provider')}
</h2>
<p className="text-base mb-2">
{t('Earn a cut of the fees paid by price takers during trading.')}
<div>
<p className="font-alpha text-2xl font-medium mb-2">
{t(
'Become a liquidity provider and earn a cut of the fees paid during trading.'
)}
</p>
<div>
<ul className="flex flex-wrap">
@@ -0,0 +1,171 @@
import { useCallback, useState } from 'react';
import { AgGridColumn } from 'ag-grid-react';
import type {
ValueFormatterParams,
GetRowIdParams,
RowClickedEvent,
} from 'ag-grid-community';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { t, addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
import { Icon, AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import type { Market } from '@vegaprotocol/liquidity';
import {
useMarketsLiquidity,
formatWithAsset,
displayChange,
} from '@vegaprotocol/liquidity';
import type { MarketTradingMode } from '@vegaprotocol/types';
import { HealthBar } from '../../health-bar';
import { Grid } from '../../grid';
import { HealthDialog } from '../../health-dialog';
import { Status } from '../../status';
export const MarketList = () => {
const { data, error, loading } = useMarketsLiquidity();
const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false);
const getRowId = useCallback(({ data }: GetRowIdParams) => data.id, []);
const localData = data?.markets;
return (
<AsyncRenderer loading={loading} error={error} data={localData}>
<div
className="grow w-full"
style={{ minHeight: 500, overflow: 'hidden' }}
>
<Grid
gridOptions={{
onRowClicked: ({ data }: RowClickedEvent) => {
window.open(
`/markets/${data.id}`,
'_blank',
'noopener,noreferrer'
);
},
}}
rowData={localData}
defaultColDef={{
resizable: true,
sortable: true,
unSortIcon: true,
cellClass: ['flex', 'flex-col', 'justify-center'],
}}
getRowId={getRowId}
isRowClickable
>
<AgGridColumn
headerName={t('Market (futures)')}
field="tradableInstrument.instrument.name"
cellRenderer={({
value,
data,
}: {
value: string;
data: Market;
}) => {
return (
<>
<span className="leading-3">{value}</span>
<span className="leading-3">
{
data?.tradableInstrument?.instrument?.product
?.settlementAsset?.symbol
}
</span>
</>
);
}}
minWidth={100}
flex="1"
/>
<AgGridColumn
headerName={t('Volume (24h)')}
field="dayVolume"
valueFormatter={({ value, data }: ValueFormatterParams) =>
`${addDecimalsFormatNumber(
value,
data.tradableInstrument.instrument.product.settlementAsset
.decimals
)} (${displayChange(data.volumeChange)})`
}
/>
<AgGridColumn
headerName={t('Committed bond/stake')}
field="liquidityCommitted"
valueFormatter={({ value, data }: ValueFormatterParams) =>
formatWithAsset(
value,
data.tradableInstrument.instrument.product.settlementAsset
)
}
/>
<AgGridColumn
headerName={t('Status')}
field="tradingMode"
cellRenderer={({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => {
return (
<Status trigger={data.data?.trigger} tradingMode={value} />
);
}}
/>
<AgGridColumn
headerComponent={() => {
return (
<div>
<span>{t('Health')}</span>{' '}
<button
onClick={() => setIsHealthDialogOpen(true)}
aria-label={t('open tooltip')}
>
<Icon name="info-sign" />
</button>
</div>
);
}}
field="tradingMode"
cellRenderer={({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => (
<HealthBar
status={value}
target={data.target}
decimals={
data.tradableInstrument.instrument.product.settlementAsset
.decimals
}
levels={data.feeLevels}
/>
)}
sortable={false}
cellStyle={{ overflow: 'unset' }}
/>
<AgGridColumn headerName={t('Est. return / APY')} field="apy" />
</Grid>
<HealthDialog
isOpen={isHealthDialogOpen}
onChange={() => {
setIsHealthDialogOpen(!isHealthDialogOpen);
}}
/>
</div>
</AsyncRenderer>
);
};
@@ -0,0 +1,107 @@
import { useParams } from 'react-router-dom';
import { useMemo } from 'react';
import {
t,
useDataProvider,
makeDerivedDataProvider,
} from '@vegaprotocol/react-helpers';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import {
getFeeLevels,
sumLiquidityCommitted,
marketLiquidityDataProvider,
lpAggregatedDataProvider,
} from '@vegaprotocol/liquidity';
import type { MarketLpQuery } from '@vegaprotocol/liquidity';
import { Market } from './market';
import { Header } from './header';
import { LPProvidersGrid } from './providers';
const formatMarket = (data: MarketLpQuery) => {
return {
name: data?.market?.tradableInstrument.instrument.name,
symbol:
data?.market?.tradableInstrument.instrument.product.settlementAsset
.symbol,
settlementAsset:
data?.market?.tradableInstrument.instrument.product.settlementAsset,
targetStake: data?.market?.data?.targetStake,
tradingMode: data?.market?.data?.marketTradingMode,
trigger: data?.market?.data?.trigger,
};
};
export const lpDataProvider = makeDerivedDataProvider(
[marketLiquidityDataProvider, lpAggregatedDataProvider],
([market, lpAggregatedData]) => ({
market: { ...formatMarket(market) },
liquidityProviders: lpAggregatedData || [],
})
);
const useMarketDetails = (marketId: string | undefined) => {
const { data, loading, error } = useDataProvider({
dataProvider: lpDataProvider,
noUpdate: true,
variables: useMemo(() => ({ marketId }), [marketId]),
});
const liquidityProviders = data?.liquidityProviders || [];
return {
data: {
name: data?.market?.name,
symbol: data?.market?.symbol,
liquidityProviders: liquidityProviders,
feeLevels: getFeeLevels(liquidityProviders),
comittedLiquidity: sumLiquidityCommitted(liquidityProviders) || 0,
settlementAsset: data?.market?.settlementAsset || {},
targetStake: data?.market?.targetStake || '0',
tradingMode: data?.market.tradingMode,
},
error,
loading: loading,
};
};
export const Detail = () => {
const { marketId } = useParams<{ marketId: string }>();
const { data, loading, error } = useMarketDetails(marketId);
return (
<AsyncRenderer loading={loading} error={error} data={data}>
<div className="px-16 pt-14 pb-12 bg-greys-light-100">
<div className="max-w-screen-xl mx-auto">
<Header name={data.name} symbol={data.symbol} />
</div>
</div>
<div className="px-16">
<div className="max-w-screen-xl mx-auto">
<div className="py-12">
{marketId && (
<Market
marketId={marketId}
feeLevels={data.feeLevels}
comittedLiquidity={data.comittedLiquidity}
settlementAsset={data.settlementAsset}
targetStake={data.targetStake}
tradingMode={data.tradingMode}
/>
)}
</div>
<div>
<h2 className="font-alpha text-2xl mb-4">
{t('Current Liquidity Provision')}
</h2>
<LPProvidersGrid
liquidityProviders={data.liquidityProviders}
settlementAsset={data.settlementAsset}
/>
</div>
</div>
</div>
</AsyncRenderer>
);
};
@@ -0,0 +1,26 @@
import { t } from '@vegaprotocol/react-helpers';
import { Link } from 'react-router-dom';
import { Icon } from '@vegaprotocol/ui-toolkit';
export const Header = ({
name,
symbol,
}: {
name?: string;
symbol?: string;
}) => {
return (
<div>
<div className="mb-6">
<Link to="/">
<Icon name="chevron-left" className="mr-2" />
<span className="underline font-alpha text-lg font-medium">
{t('Liquidity opportunities')}
</span>
</Link>
</div>
<h1 className="font-alpha text-5xl mb-6">{name}</h1>
<p className="font-alpha text-4xl">{symbol}</p>
</div>
);
};
@@ -0,0 +1 @@
export * from './detail';
@@ -0,0 +1 @@
export * from './last-24h-volume';
@@ -0,0 +1,114 @@
import { useState, useMemo, useRef, useCallback } from 'react';
import throttle from 'lodash/throttle';
import {
useYesterday,
useDataProvider,
addDecimalsFormatNumber,
} from '@vegaprotocol/react-helpers';
import { Interval } from '@vegaprotocol/types';
import {
calcDayVolume,
getChange,
displayChange,
} from '@vegaprotocol/liquidity';
import type { Candle } from '@vegaprotocol/market-list';
import { marketCandlesProvider } from '@vegaprotocol/market-list';
const DEBOUNCE_UPDATE_TIME = 500;
export const Last24hVolume = ({
marketId,
decimals,
}: {
marketId: string;
decimals: number;
}) => {
const [candleVolume, setCandleVolume] = useState<string>();
const [volumeChange, setVolumeChange] = useState<string>(' - ');
const yesterday = useYesterday();
const yTimestamp = useMemo(() => {
return new Date(yesterday).toISOString();
}, [yesterday]);
const variables = useMemo(
() => ({
marketId: marketId,
interval: Interval.INTERVAL_I1H,
since: yTimestamp,
}),
[marketId, yTimestamp]
);
const variables24hAgo = useMemo(
() => ({
marketId: marketId,
interval: Interval.INTERVAL_I1D,
since: yTimestamp,
}),
[marketId, yTimestamp]
);
const throttledSetCandles = useRef(
throttle((data: Candle[]) => {
setCandleVolume(calcDayVolume(data));
}, DEBOUNCE_UPDATE_TIME)
).current;
const update = useCallback(
({ data }: { data: Candle[] | null }) => {
if (data) {
throttledSetCandles(data);
}
return true;
},
[throttledSetCandles]
);
const { data, error } = useDataProvider<Candle[], Candle>({
dataProvider: marketCandlesProvider,
variables: variables,
update,
skip: !marketId,
});
const throttledSetVolumeChange = useRef(
throttle((candles: Candle[]) => {
const candle24hAgo = candles?.[0];
setVolumeChange(getChange(data || [], candle24hAgo?.close));
}, DEBOUNCE_UPDATE_TIME)
).current;
const updateCandle24hAgo = useCallback(
({ data }: { data: Candle[] | null }) => {
if (data) {
throttledSetVolumeChange(data);
}
return true;
},
[throttledSetVolumeChange]
);
useDataProvider<Candle[], Candle>({
dataProvider: marketCandlesProvider,
update: updateCandle24hAgo,
variables: variables24hAgo,
skip: !marketId || !data,
updateOnInit: true,
});
return (
<div>
<span className="text-3xl">
{!error && candleVolume
? addDecimalsFormatNumber(candleVolume, decimals)
: '0'}{' '}
</span>
<span className="text-lg text-greys-light-400">
({displayChange(volumeChange)})
</span>
</div>
);
};
@@ -0,0 +1 @@
export * from './market';
@@ -0,0 +1,118 @@
import { useState } from 'react';
import { t } from '@vegaprotocol/react-helpers';
import { Icon } from '@vegaprotocol/ui-toolkit';
import { formatWithAsset } from '@vegaprotocol/liquidity';
import type { MarketTradingMode, AuctionTrigger } from '@vegaprotocol/types';
import { HealthBar } from '../../health-bar';
import { HealthDialog } from '../../health-dialog';
import { Last24hVolume } from '../last-24h-volume';
import { Status } from '../../status';
interface Levels {
fee: string;
commitmentAmount: number;
}
interface settlementAsset {
symbol?: string;
decimals?: number;
}
export const Market = ({
marketId,
feeLevels,
comittedLiquidity,
settlementAsset,
targetStake,
tradingMode,
trigger,
}: {
marketId: string;
feeLevels: Levels[];
comittedLiquidity: number;
targetStake: string;
settlementAsset?: settlementAsset;
tradingMode?: MarketTradingMode;
trigger?: AuctionTrigger;
}) => {
const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false);
return (
<div>
<div className="border border-greys-light-200 rounded-2xl px-2 py-6">
<table className="w-full">
<thead>
<tr
className="text-sm text-greys-light-400 text-left font-alpha"
style={{ fontFeatureSettings: "'liga' off, 'calt' off" }}
>
<th className="font-medium px-4">{t('Volume (24h)')}</th>
<th className="font-medium px-4">{t('Commited Liquidity')}</th>
<th className="font-medium px-4">{t('Status')}</th>
<th className="font-medium flex items-center px-4">
<span>{t('Health')}</span>{' '}
<button
onClick={() => setIsHealthDialogOpen(true)}
aria-label={t('open tooltip')}
className="flex ml-1"
>
<Icon name="info-sign" />
</button>
</th>
<th className="font-medium">{t('Est. APY')}</th>
</tr>
</thead>
<tbody>
<tr>
<td className="px-4">
<div>
{marketId && settlementAsset?.decimals && (
<Last24hVolume
marketId={marketId}
decimals={settlementAsset.decimals}
/>
)}
</div>
</td>
<td className="px-4">
<span className="text-3xl">
{comittedLiquidity && settlementAsset
? formatWithAsset(`${comittedLiquidity}`, settlementAsset)
: '0'}
</span>
</td>
<td className="px-4">
<Status
trigger={trigger}
tradingMode={tradingMode}
size="large"
/>
</td>
<td className="px-4">
{tradingMode && settlementAsset?.decimals && feeLevels && (
<HealthBar
status={tradingMode}
target={targetStake}
decimals={settlementAsset.decimals}
levels={feeLevels}
/>
)}
</td>
<td className="px-4">
<span className="text-3xl"></span>
</td>
</tr>
</tbody>
</table>
</div>
<HealthDialog
isOpen={isHealthDialogOpen}
onChange={() => {
setIsHealthDialogOpen(!isHealthDialogOpen);
}}
/>
</div>
);
};
@@ -0,0 +1 @@
export * from './providers';
@@ -0,0 +1,88 @@
import { useCallback } from 'react';
import { AgGridColumn } from 'ag-grid-react';
import type { GetRowIdParams } from 'ag-grid-community';
import { t } from '@vegaprotocol/react-helpers';
import type {
LiquidityProviderFeeShareFieldsFragment,
LiquidityProvisionFieldsFragment,
} from '@vegaprotocol/liquidity';
import { formatWithAsset } from '@vegaprotocol/liquidity';
import { Grid } from '../../grid';
const formatToHours = ({ value }: { value?: string | null }) => {
if (!value) {
return '-';
}
const MS_IN_HOUR = 1000 * 60 * 60;
const created = new Date(value).getTime();
const now = new Date().getTime();
return `${Math.round(Math.abs(now - created) / MS_IN_HOUR)}h`;
};
export const LPProvidersGrid = ({
liquidityProviders,
settlementAsset,
}: {
liquidityProviders: LiquidityProvisionFieldsFragment &
LiquidityProviderFeeShareFieldsFragment[];
settlementAsset: {
decimals?: number;
symbol?: string;
};
}) => {
const getRowId = useCallback(({ data }: GetRowIdParams) => data.party.id, []);
return (
<Grid
rowData={liquidityProviders}
defaultColDef={{
resizable: true,
sortable: true,
unSortIcon: true,
cellClass: ['flex', 'flex-col', 'justify-center'],
}}
getRowId={getRowId}
rowHeight={92}
>
<AgGridColumn
headerName={t('LPs')}
field="party.id"
flex="1"
minWidth={100}
/>
<AgGridColumn
headerName={t('Time in market')}
valueFormatter={formatToHours}
field="createdAt"
/>
<AgGridColumn
headerName={t('Equity-like share')}
field="equityLikeShare"
valueFormatter={({ value }: { value?: string | null }) => {
const valueOr0 = value ? value : '';
return `${parseInt(valueOr0) * 100}%`;
}}
/>
<AgGridColumn
headerName={t('committed bond/stake')}
field="commitmentAmount"
valueFormatter={({ value }: { value?: string | null }) =>
value ? formatWithAsset(value, settlementAsset) : '0'
}
/>
<AgGridColumn headerName={t('Margin Req.')} field="margin" />
<AgGridColumn headerName={t('24h Fees')} field="fees" />
<AgGridColumn
headerName={t('Fee level')}
valueFormatter={({ value }: { value?: string | null }) => `${value}%`}
field="fee"
/>
<AgGridColumn headerName={t('APY')} field="apy" />
</Grid>
);
};
@@ -0,0 +1,50 @@
.ag-theme-alpine {
--ag-line-height: 24px;
--ag-row-hover-color: transparent;
--ag-header-background-color: transparent;
--ag-odd-row-background-color: transparent;
--ag-header-foreground-color: #626262;
--ag-secondary-foreground-color: #626262;
--ag-font-size: 16px;
--ag-background-color: transparent;
--ag-range-selection-border-color: transparent;
font-family: AlphaLyrae, Helvetica Neue, -apple-system, BlinkMacSystemFont,
Segoe UI, Roboto, Arial, Noto Sans, sans-serif, Apple Color Emoji,
Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
font-feature-settings: 'liga' off, 'calt' off;
}
.ag-theme-alpine .ag-cell {
display: flex;
}
.ag-theme-alpine .ag-header {
border-bottom: 1px solid #a7a7a7;
font-size: 15px;
line-height: 1em;
text-transform: uppercase;
}
.ag-theme-alpine .ag-root-wrapper {
border: none;
}
.ag-theme-alpine .ag-header-row {
font-weight: 500;
}
.ag-theme-alpine .ag-row {
border: none;
border-bottom: 1px solid #bfccd6;
font-size: 12px;
}
.ag-theme-alpine .ag-root-wrapper-body.ag-layout-normal {
height: auto;
}
.ag-theme-alpine.row-hover .ag-row:hover {
background: #f0f0f0;
cursor: pointer;
}
@@ -0,0 +1,51 @@
import { useRef, useCallback, useEffect } from 'react';
import type { ReactNode } from 'react';
import { AgGridReact } from 'ag-grid-react';
import type {
AgGridReactProps,
AgReactUiProps,
AgGridReact as AgGridReactType,
} from 'ag-grid-react';
import classNames from 'classnames';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import './grid.scss';
type Props = (AgGridReactProps | AgReactUiProps) & {
isRowClickable?: boolean;
style?: React.CSSProperties;
children: ReactNode;
};
export const Grid = ({ isRowClickable, children, ...props }: Props) => {
const gridRef = useRef<AgGridReactType | null>(null);
const resizeGrid = useCallback(() => {
gridRef.current?.api?.sizeColumnsToFit();
}, [gridRef]);
const handleOnGridReady = useCallback(() => {
resizeGrid();
}, [resizeGrid]);
useEffect(() => {
window.addEventListener('resize', resizeGrid);
return () => window.removeEventListener('resize', resizeGrid);
}, [resizeGrid]);
return (
<AgGridReact
className={classNames('ag-theme-alpine h-full font-alpha', {
'row-hover': isRowClickable,
})}
rowHeight={92}
ref={gridRef}
onGridReady={handleOnGridReady}
suppressRowClickSelection
{...props}
>
{children}
</AgGridReact>
);
};
@@ -0,0 +1 @@
export * from './grid';
@@ -1,12 +0,0 @@
import { t } from '@vegaprotocol/react-helpers';
export const Header = () => {
return (
<div className="flex items-stretch px-6 py-6" data-testid="header">
<h1 className="text-3xl">{t('Top liquidity opportunities')}</h1>
<div className="flex items-center gap-2 ml-auto relative z-10">
{t('Network switcher')}
</div>
</div>
);
};
@@ -1,18 +1,19 @@
import classNames from 'classnames';
import { MarketTradingMode } from '@vegaprotocol/types';
import type { MarketTradingMode } from '@vegaprotocol/types';
import { t, addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
import { BigNumber } from 'bignumber.js';
import type { ReactNode } from 'react';
const marketTradingModeStyle = {
[MarketTradingMode.TRADING_MODE_CONTINUOUS]: '#00a88a',
[MarketTradingMode.TRADING_MODE_MONITORING_AUCTION]: '#fb8e7f',
[MarketTradingMode.TRADING_MODE_OPENING_AUCTION]: '#68e2e4',
[MarketTradingMode.TRADING_MODE_BATCH_AUCTION]: 'batch',
[MarketTradingMode.TRADING_MODE_NO_TRADING]: 'none',
};
import { getColorForStatus } from '../../lib/utils';
const COPY_CLASS = 'text-[8px] leading-[1.2em] font-medium';
import { Indicator } from '../indicator';
const Remainder = () => (
<div className="bg-greys-light-200 h-[inherit] relative flex-1"></div>
);
const COPY_CLASS =
'text-sm font-medium whitespace-nowrap text-white font-alpha';
const Tooltip = ({
children,
@@ -24,27 +25,13 @@ const Tooltip = ({
return (
<div
className={classNames(
'absolute top-0 left-1/2 -translate-x-2/4 -translate-y-[120%] border border-[#bfccd6] py-0.5 px-2 flex-col z-10 bg-white group-hover:flex min-w-[65px]',
'absolute top-0 left-1/2 -translate-x-2/4 -translate-y-[80%] p-2 z-10 bg-greys-light-400 group-hover:flex rounded',
{
flex: isExpanded,
hidden: !isExpanded,
}
)}
>
<div
className="absolute w-0 h-0 translate-y-full translate-x-2/4 left-[calc(50% - 8px)] -bottom-px border-4"
style={{
left: 'calc(50% - 8px)',
borderColor: '#bfccd6 transparent transparent transparent',
}}
></div>
<div
style={{
left: 'calc(50% - 8px)',
borderColor: 'white transparent transparent transparent',
}}
className="absolute bottom-0 w-0 h-0 translate-y-full translate-x-2/4 left-[calc(50% - 8px)] border-4"
></div>
{children}
</div>
);
@@ -62,17 +49,20 @@ const Target = ({
return (
<div
className={classNames(
'absolute top-0 left-1/2 -translate-x-2/4 px-1.5 group'
'absolute top-1/2 left-1/2 -translate-x-2/4 -translate-y-1/2 px-1.5 group'
)}
style={{ left: `${targetPercent}%` }}
>
<div
className={classNames('health-target w-0.5 h-8 bg-black', {
'h-[72px]': isLarge,
})}
>
{children}
</div>
className={classNames(
'health-target w-0.5 bg-black group-hover:scale-x-150 group-hover:scale-y-108',
{
'h-6': !isLarge,
'h-12': isLarge,
}
)}
></div>
{children}
</div>
);
};
@@ -81,14 +71,14 @@ const Level = ({
children,
commitmentAmount,
total,
index,
status,
backgroundColor,
opacity,
}: {
children: ReactNode;
index: number;
status: MarketTradingMode;
commitmentAmount: number;
total: number;
backgroundColor: string;
opacity: number;
}) => {
const width = new BigNumber(commitmentAmount)
.div(total)
@@ -97,26 +87,26 @@ const Level = ({
return (
<div
className={classNames(`relative h-[inherit] w-full group`)}
className={classNames(`relative h-[inherit] w-full group min-w-[1px]`)}
style={{
width: `${width}%`,
opacity: 1 - 0.1 * index,
}}
>
<div
className="relative w-full h-[inherit]"
className="relative w-full h-[inherit] group-hover:scale-y-150"
style={{
opacity: 1 - 0.1 * index,
backgroundColor: marketTradingModeStyle[status],
opacity,
backgroundColor,
}}
></div>
{children}
</div>
);
};
const Full = () => (
<div className="bg-neutral-100 w-full h-[inherit] absolute bottom-0 left-0"></div>
<div className="bg-transparent w-full h-[inherit] absolute bottom-0 left-0"></div>
);
interface Levels {
@@ -126,7 +116,7 @@ interface Levels {
export const HealthBar = ({
status,
target,
target = '0',
decimals,
levels,
size = 'small',
@@ -151,6 +141,7 @@ export const HealthBar = ({
targetNumber * 2 >= committedNumber ? targetNumber * 2 : committedNumber;
const targetPercent = (targetNumber / total) * 100;
const isLarge = size === 'large';
const backgroundColor = getColorForStatus(status);
return (
<div className="w-full">
@@ -168,36 +159,50 @@ export const HealthBar = ({
>
<Full />
<div className="health-bars h-[inherit] flex w-full">
<div className="health-bars h-[inherit] flex w-full gap-0.5">
{levels.map((p, index) => {
const { commitmentAmount, fee } = p;
const prevLevel = levels[index - 1]?.commitmentAmount;
const opacity = 1 - 0.2 * index;
return (
<Level
status={status}
commitmentAmount={commitmentAmount}
index={index}
total={total}
backgroundColor={backgroundColor}
opacity={opacity}
>
<Tooltip isExpanded={isExpanded}>
<span className={COPY_CLASS}>
{fee}% {t('Fee')}
</span>
<span className={COPY_CLASS}>
{addDecimalsFormatNumber(commitmentAmount, decimals)}
</span>
<div className="mt-1.5 inline-flex">
<Indicator status={status} opacity={opacity} />
</div>
<div className="flex flex-col">
<span className={COPY_CLASS}>
{fee}% {t('Fee')}
</span>
<span className={classNames(COPY_CLASS, 'opacity-60')}>
{prevLevel
? addDecimalsFormatNumber(prevLevel, decimals)
: '0'}{' '}
- {addDecimalsFormatNumber(commitmentAmount, decimals)}
</span>
</div>
</Tooltip>
</Level>
);
})}
{(total !== committedNumber || levels.length === 0) && (
<Remainder />
)}
</div>
</div>
<Target targetPercent={targetPercent} isLarge={isLarge}>
<Tooltip isExpanded={isExpanded}>
<span className={COPY_CLASS}>{t('Target stake')}</span>
<div className="mt-1.5 inline-flex">
<Indicator />
</div>
<span className={COPY_CLASS}>
{addDecimalsFormatNumber(target, decimals)}
{t('Target stake')} {addDecimalsFormatNumber(target, decimals)}
</span>
</Tooltip>
</Target>
@@ -0,0 +1 @@
export * from './health-bar';
@@ -1,8 +1,9 @@
import { t } from '@vegaprotocol/react-helpers';
import { Dialog } from '@vegaprotocol/ui-toolkit';
import { MarketTradingMode } from '@vegaprotocol/types';
import classNames from 'classnames';
import { HealthBar } from './health-bar';
import { HealthBar } from '../health-bar';
interface HealthDialogProps {
isOpen: boolean;
@@ -58,36 +59,48 @@ const ROWS = [
export const HealthDialog = ({ onChange, isOpen }: HealthDialogProps) => {
return (
<Dialog size="medium" open={isOpen} onChange={onChange}>
<h1 className="text-xl mb-4 pr-2 font-bold" data-testid="dialog-title">
<h1 className="text-2xl mb-5 pr-2 font-medium font-alpha uppercase liga-0-calt-0">
{t('Health')}
</h1>
<p className="text-xl mb-4">
<p className="text-lg font-medium font-alpha mb-8 liga-0-calt-0">
{t(
'Market health is a representation of market and liquidity status and how close that market is to moving from one fee level to another.'
)}
</p>
<table className="table-fixed">
<thead>
<th className="w-1/2 text-left">{t('Market status')}</th>
<th className="w-1/2 text-left">{t('Liquidity status')}</th>
<thead className="border-b border-greys-light-300">
<th className="w-1/2 text-left font-medium font-alpha text-base pb-4 uppercase liga-0-calt-0">
{t('Market status')}
</th>
<th className="w-1/2 text-lef font-medium font-alpha text-base pb-4 uppercase liga-0-calt-0">
{t('Liquidity status')}
</th>
</thead>
<tbody>
{ROWS.map((r) => {
{ROWS.map((r, index) => {
const isFirstRow = index === 0;
return (
<tr key={r.key}>
<td className="pr-4 py-10">
<h2 className="font-bold text-base">{t(r.title)}</h2>
<p className="text-base">{t(r.copy)}</p>
<td
className={classNames('pr-4 pb-10', { 'pt-8': isFirstRow })}
>
<h2 className="font-medium font-alpha uppercase text-base liga-0-calt-0">
{t(r.title)}
</h2>
<p className="font-medium font-alpha text-lg liga-0-calt-0">
{t(r.copy)}
</p>
</td>
<td className="py-10">
<td
className={classNames('pl-4 pb-10', { 'pt-8': isFirstRow })}
>
<HealthBar
size="large"
levels={r.data.levels}
status={r.data.status}
target={r.data.target}
decimals={r.data.decimals}
isExpanded
/>
</td>
</tr>
@@ -0,0 +1 @@
export * from './health-dialog';
@@ -0,0 +1 @@
export * from './indicator';
@@ -0,0 +1,24 @@
import type { MarketTradingMode } from '@vegaprotocol/types';
import { getColorForStatus } from '../../lib/utils';
export const Indicator = ({
status,
opacity,
}: {
status?: MarketTradingMode;
opacity?: number;
}) => {
const backgroundColor = status ? getColorForStatus(status) : undefined;
return (
<div className="inline-block w-2 h-2 mr-1 rounded-full bg-white overflow-hidden shrink-0">
<div
className="h-full bg-black"
style={{
opacity,
backgroundColor,
}}
/>
</div>
);
};
@@ -1,189 +0,0 @@
import { useCallback, useRef, useEffect, useState } from 'react';
import { AgGridReact, AgGridColumn } from 'ag-grid-react';
import type { AgGridReact as AgGridReactType } from 'ag-grid-react';
import type {
GroupCellRendererParams,
ValueFormatterParams,
GetRowIdParams,
} from 'ag-grid-community';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { formatNumber, t } from '@vegaprotocol/react-helpers';
import { useMarketsLiquidity } from '@vegaprotocol/liquidity';
import { Icon } from '@vegaprotocol/ui-toolkit';
import type { Market } from '@vegaprotocol/liquidity';
import { formatWithAsset } from '@vegaprotocol/liquidity';
import {
MarketTradingModeMapping,
MarketTradingMode,
AuctionTrigger,
AuctionTriggerMapping,
} from '@vegaprotocol/types';
import { HealthBar } from './health-bar';
import { HealthDialog } from './health-dialog';
import './market-list.scss';
const displayValue = (value: string) => {
return parseFloat(value) > 0 ? `+${value}` : value;
};
const marketNameCellRenderer = ({
value,
data,
}: {
value: string;
data: Market;
}) => {
return (
<>
<span style={{ lineHeight: '12px' }}>{value}</span>
<span style={{ lineHeight: '12px' }}>
{data?.tradableInstrument?.instrument?.product?.settlementAsset?.symbol}
</span>
</>
);
};
const healthCellRenderer = ({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => {
return (
<div>
<HealthBar
status={value}
target={data.target}
decimals={
data.tradableInstrument.instrument.product.settlementAsset.decimals
}
levels={data.feeLevels}
/>
</div>
);
};
export const MarketList = () => {
const { data, error, loading } = useMarketsLiquidity();
const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false);
const gridRef = useRef<AgGridReactType | null>(null);
const getRowId = useCallback(({ data }: GetRowIdParams) => data.id, []);
const handleOnGridReady = useCallback(() => {
gridRef.current?.api?.sizeColumnsToFit();
}, [gridRef]);
useEffect(() => {
window.addEventListener('resize', handleOnGridReady);
return () => window.removeEventListener('resize', handleOnGridReady);
}, [handleOnGridReady]);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :( </p>;
const localData = data?.markets;
return (
<div
className="px-6 py-6 grow"
data-testid="market-list"
style={{ minHeight: 500, overflow: 'hidden' }}
>
<AgGridReact
rowData={localData}
className="ag-theme-alpine h-full"
defaultColDef={{
resizable: true,
sortable: true,
unSortIcon: true,
cellClass: ['flex', 'flex-col', 'justify-center'],
}}
getRowId={getRowId}
rowHeight={92}
ref={gridRef}
>
<AgGridColumn
headerName={t('Market (futures)')}
field="tradableInstrument.instrument.name"
cellRenderer={marketNameCellRenderer}
minWidth={100}
/>
<AgGridColumn
headerName={t('Volume (24h)')}
field="dayVolume"
cellRenderer={({ value, data }: GroupCellRendererParams) => {
return (
<div>
{formatNumber(value)} ({displayValue(data.volumeChange)})
</div>
);
}}
/>
<AgGridColumn
headerName={t('Committed bond/stake')}
field="liquidityCommitted"
valueFormatter={({ value, data }: ValueFormatterParams) =>
formatWithAsset(
value,
data.tradableInstrument.instrument.product.settlementAsset
)
}
/>
<AgGridColumn
headerName={t('Status')}
field="tradingMode"
valueFormatter={({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => {
return value ===
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
data.data?.trigger &&
data.data.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
? `${MarketTradingModeMapping[value]}
- ${AuctionTriggerMapping[data.data.trigger]}`
: MarketTradingModeMapping[value];
}}
/>
<AgGridColumn
headerComponent={() => {
return (
<div>
<span>{t('Health')}</span>{' '}
<button
onClick={() => setIsHealthDialogOpen(true)}
aria-label={t('open tooltip')}
>
<Icon name="info-sign" />
</button>
</div>
);
}}
field="tradingMode"
cellRenderer={healthCellRenderer}
sortable={false}
cellStyle={{ overflow: 'unset' }}
/>
<AgGridColumn headerName={t('Est. return / APY')} field="apy" />
</AgGridReact>
<HealthDialog
isOpen={isHealthDialogOpen}
onChange={() => {
setIsHealthDialogOpen(!isHealthDialogOpen);
}}
/>
</div>
);
};
@@ -0,0 +1 @@
export * from './navbar';

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