Compare commits

...
67 Commits
Author SHA1 Message Date
Matthew Russell 308bd406a6 fix: accomodate type changes for libs/liquidity 2022-09-12 22:25:14 -07:00
Matthew Russell 4ffff8a9c7 fix: query type generation and type errors 2022-09-12 22:20:38 -07:00
Matthew Russell ac4b48610c chore: fix all queries and regen types 2022-09-12 22:20:38 -07:00
Matthew Russell 2b28b29820 fix: tooltip should be on data not label 2022-09-12 22:19:20 -07:00
Matthew Russell bf5e428460 fix: unused and superfluous classes, define border color in one place 2022-09-12 14:11:28 -07:00
Matthew Russell 73359e9ff7 fix: border too thick, use grid head component 2022-09-12 12:25:40 -07:00
mattrussell36 f34edf1862 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-12 18:04:57 +00:00
m.ray d8512afb2b fix: #1297 Order submission expiresAt is only available when the time in force is of type GTT (#1308)
* fix: #1297 Order submission expires at is only available when the time in force is of type GTT

* fix: add expires at visible in edit dialog

* fix:#1297 add GTC and GTT tests for expires at
2022-09-12 14:28:07 +01:00
PeteWilliams 549e0e004d Chore/design updates (#1305)
* chore: design updates

* chore: design updates

* chore: design updates

* chore: design updates

* chore: design updates

* chore: design updates

* chore: design updates

* chore: design updates

* chore: design updates

* chore: design updates

* fix: fix lint tests

* chore: fixes ag grid invisible header seperators

* fix: fixing conflicts

* fix: fixing conflicts

* chore: fix header spacing

* chore: fix dropdown hover colour

* fix: formatting change to pass test
2022-09-12 14:05:39 +01:00
Joe Tsang 8b08e48840 chore: attempt to fix home tests (#1311)
* chore: attempt to fix home tests

* chore: revert timeout increase

* chore: visit homepage in hook
2022-09-12 13:56:01 +01:00
mattrussell36 846f9114d8 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-12 12:05:17 +00:00
Radosław Szpiech a9216c12a3 chore: env changed to custom (#1307) 2022-09-12 12:22:49 +02:00
d85c5d7c1f chore: LP tooltips & move market-info lib (#1267)
* feat(#473): add positions metrics data provider

* feat(#473) add positions stats

* feat(#473) add positions stats

* feat(#473): add positions stats

* feat(#473): add positions stats

* feat(#473): position metrics, test and refactoring

* feat(#473): add unit tests to positions table

* feat(#473): fix spelling, order positions by updated at desc

* feat(#473): protect from division by 0

* feat(#473): fix trading positions e2e tests

* feat(#473): fix e2e data mocks

* feat(#473): post code review clean up

* feat(#993): dependencies handling in data provider

* feat(#993): fix e2e tests data mocks

* feat(#993): remove position metrics mocks, add market data market id

* feat: #994 add price monitoring bounds and candles update interface

* fix: move best bid price to diff section

* feat(#993): add missing mocks, fix combine function

* fix: add insurance pool and calc volume 24h

* feat: display some oracle min info, asset id, insurance pool, move open interest and 24hVol

* fix: add  market-info.cy.ts case

* fix: remove # from numbered price monitoring settings

* fix: add insurance pool test

* fix: format 24hvol

* feat(#993): set loading initially to true, add unit tests

* feat(#993): cleanup, add comments

* feat(#993): remove undefined from client type

* fix: remove indicativeVolume and oracleSpecBinding from market info

* feat(#993): cosmetic changes

* fix: add oracleSpecBinding back

* Update libs/deal-ticket/src/components/info-market.tsx

Co-authored-by: botond <105208209+notbot00@users.noreply.github.com>

* feat: add initial queries

* fix: memo yesterday's timestamp

* fix: add back info

* fix: update query

* fix: add view full oracle details link and update mappings

* fix: regen code, make link reactnode, fix index.ts

* feat: add liquidity lib, refactor info market

* fix: remove liquidity query from deal-ticket

* feat:(#993): pass informaton about update callback cause

* fix: small ui tweaks

* fix: display in grid

* feat: navigate to oracle by termination id

* feat: #491 add use liquidity provision merging

* fix: remove logs, add extra check on my liquidity provision

* fix: type number trivially inferred from a number literal, remove type annotation

* fix: cypress tests and formatting for market info

* Update libs/deal-ticket/src/components/market-info/info-market.tsx

* fix: use position decimal places for stake and market value proxy

* fix: #491 use size/position decimal places for obligation, supplied and commitment amount

* fix: add size component and use decimal places

* fix: update readme liquidity

* fix: #491 add correct asset decimal formatters

* Update libs/deal-ticket/src/components/market-info/tooltip-mapping.tsx

Co-authored-by: candida-d <62548908+candida-d@users.noreply.github.com>

* fix: make link instead of button to open liquidity

* fix: #491 add liquidity page, link to trading mode tooltip, tabs hidden or choose active

* fix: remove LP dialog, use only link to page

* fix: add market id in LP view

* fix: follow trade grid design

* fix: add one line tabs , remove link styling, remove any, add value formatters

* fix: remove falsy check LP undefined

* fix: keep date formatter in LP table

* fix: add generic type market info, hooks in body function

* fix: revert number formatters

* fix: use one param only in network params query

* fix:  use network param in web3 lib

* fix: move lp container to trading app

* fix: remove resizable panel

* feat: add header component, remove isEstimate

* chore: remove unnecessary type cast

* fix: fix build with children map clone element

* chore: lint

* fix: move use network params to react helpers

* fix: add const for LP tabs

* fix: fix formatting on LP page

* fix: only show tilde for liquidity monitoring auction end date

* fix: market id being rendered twice in market info

* chore: fix lint

* fix: types for generate withdraw form query

* chore: fix intermittent failing withdrawal test

* Update libs/deal-ticket/src/components/market-info/info-market.tsx

* fix: route to LP and update selected market

* fix: add market-info lib

* fix: add tooltips to header stat

* fix: add overflow-y on div within auto sizer

* fix: fix merge conflicts

* fix: size and dialog

* fix: format target stake and supplied stake

* fix: add tooltips ag-grid and fix decimals

* fix: overflow on both axes auto-sizer

* fix: remove symbol, add to commitment

* fix: update tooltips and headers after demo

* fix: network switcher background

* fix: remove any from market info

* fix: integration test

* fix: remove e2e test for risk factors for now until grpc error sorted

* fix: get liquidity panel  by test-id

* fix: fix market-info.cy.ts test

* fix: liquidity test

* f
ix: fix link data test id

Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
Co-authored-by: botond <105208209+notbot00@users.noreply.github.com>
Co-authored-by: candida-d <62548908+candida-d@users.noreply.github.com>
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
Co-authored-by: Joe <joe@vega.xyz>
2022-09-12 11:07:29 +02:00
Joe Tsang 7675fe0ab0 test: add test for filtering assets not enabled (#1303)
* test: add test for filtering assets not enabled

* chore: fix lint

* chore: load homepage before test
2022-09-12 09:22:34 +02:00
mattrussell36 bd51564207 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-12 06:28:44 +00:00
mattrussell36 fac08bc831 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-12 00:10:11 +00:00
mattrussell36 a34ea77488 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-11 18:04:08 +00:00
mattrussell36 e50afc64ff chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-11 12:04:30 +00:00
mattrussell36 9f4bf97465 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-11 06:06:37 +00:00
mattrussell36 dc59f56a6f chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-11 00:10:25 +00:00
mattrussell36 8a9372c88a chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-10 18:05:25 +00:00
mattrussell36 8563625079 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-10 12:05:08 +00:00
mattrussell36 946ee9423b chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-10 06:08:32 +00:00
mattrussell36 e3aa1e40c8 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-10 00:11:11 +00:00
mattrussell36 179d34ff40 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-09 18:04:28 +00:00
botond 7613a9fa9f Feat/migrate libs (#1266)
* feat: add new generator with config

* feat: split off gql queries to separate files for the new generator

* fix: delete dummy schema

* feat: add generated queries with new codegen

* fix: regenerate from scratch and remove duplicates

* fix: libs and app gen folders

* fix: remove more duplicate queries

* fix: add generated files to be ignored by the formatter

* fix: format

* feat: migrate assets to use new code generator

* fix: generated imports

* fix: lint

* fix: accounts export

* fix: more imports

* fix: add type alias for new type system and regenerate

* fix: format

* fix: export

* fix: format

* fix: delete leftover file from merge

* chore: migrate candles-chart lib

* fix: remove redundant asset files

* chore: migrate accounts

* chore: update glob

* chore: add cleanup to fix-imports to support type migrations for now

* fix: imports

* fix: update market types

* fix: type import paths

* fix: format

* fix: import

* fix: types in e2e tests

* fix: format

* fix: lint
2022-09-09 16:14:48 +01:00
mattrussell36 1beaad5759 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-09 12:04:51 +00:00
Joe Tsang 8958db0612 Test/626 oracle info (#1294)
* test: update market info tests

* test: update withdrawal test to include new info

* chore: re add withdrawal mock

* chore: wait for mock

* chore: change cypress browser to electron

* chore: resolved pr comments
2022-09-09 10:36:53 +01:00
mattrussell36 4db77a8e8a chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-09 06:13:33 +00:00
mattrussell36 097cf5da94 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-09 00:10:31 +00:00
mattrussell36 3f1ea6b83d chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-08 18:04:18 +00:00
macqbatandmaciek 93f41d429f feat: [console-lite] - fast fix small css on market selector (#1290)
Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-09-08 15:55:17 +02:00
Elmar 37aa5be725 Feat/1089 override slippage (#1283)
* feat(console-lite): add traffic light component

* fix(console-lite): add slippage to deal ticket estimates

* feat(console-lite): refactor deal ticket steps and add slippage dialog

* feat(console-lite): add e2e tests for slippage and fix broken ones

* fix(console-lite): fix styling issue after theme update
2022-09-08 13:04:17 +01:00
macqbatandmaciek 65528a8007 feat: [console-lite] - additional unit tests (#1273)
* feat: [console-lite] - additional unit tests

* feat: [console-lite] - additional unit tests

* feat: [console-lite] - additional unit tests

* feat: [console-lite] - additional unit tests - fixes after feedback

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-09-08 13:18:32 +02:00
Edd 87ae478b9c fix(positions): split market name more defensively (#1265) 2022-09-08 11:12:01 +01:00
botond dc59859964 fix: readme with new env var for type gen (#1288) 2022-09-08 12:07:08 +02:00
Joe Tsang 621feada26 chore: revert back to using previous ubuntu runners (#1286) 2022-09-08 10:37:11 +01:00
Dexter Edwards bb81c1786c chore: remove build and test precommit checks (#1285) 2022-09-08 10:24:11 +01:00
mattrussell36 760be23c27 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-08 06:18:41 +00:00
mattrussell36 19e12145cb chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-08 00:11:15 +00:00
Art c83b5bf93c chore(#1259): replaced market name with tradable instrument name (#1269)
* chore: replaced market name with tradable instrument name (1259)

* removed lodash import that must have added itself magically

* =aligned cypress tests with code changed

* =aligned console lite cypress mocks to the code changes

* changed cypress market info key details test

* changed cypress market info key details test

* generate markets for console lite
2022-09-07 11:37:39 -07:00
botond 9f6376c1b2 fix: dialog alignment (#1281) 2022-09-07 11:35:48 -07:00
Mikołaj Młodzikowski b5271d07e4 chore: use bigger runners for capusle (#1248) 2022-09-07 11:14:52 -07:00
mattrussell36 6ddf706cf2 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-07 18:04:21 +00:00
Art d2791f2e59 chore: proposal schema change (1057) (#1169)
* chore: moved proposal queries to lib/governance

* chore: used new rationale title and description

* chore: addressed PR comments, refactored

* chore: moved proposal queries to lib/governance

* chore: used new rationale title and description

* chore: addressed PR comments, refactored

* fix: dropped s after merge

* fix: fixed lodash imports
2022-09-07 18:35:29 +02:00
Art 9de3683bf3 chore: filter assets by status (1108) (#1192)
* chore: filter assets by status (1108)

* chore: moved asset status

* chore: re-adding filterin after merge (changed upstream)

* chore: filter assets by status (1108)

* chore: moved asset status

* types

* fixed deposit cypress tests
2022-09-07 18:01:16 +02:00
botond 293e2ffbc3 Fix/UI dialog overflows (#1276)
* fix: dialog overflows

* fix: hide close icon when no change function passed in
2022-09-07 14:02:23 +01:00
mattrussell36 beeb1db1e1 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-07 12:04:38 +00:00
cae6162a7f feat: liquidity provisions view (#1133)
* feat(#473): add positions metrics data provider

* feat(#473) add positions stats

* feat(#473) add positions stats

* feat(#473): add positions stats

* feat(#473): add positions stats

* feat(#473): position metrics, test and refactoring

* feat(#473): add unit tests to positions table

* feat(#473): fix spelling, order positions by updated at desc

* feat(#473): protect from division by 0

* feat(#473): fix trading positions e2e tests

* feat(#473): fix e2e data mocks

* feat(#473): post code review clean up

* feat(#993): dependencies handling in data provider

* feat(#993): fix e2e tests data mocks

* feat(#993): remove position metrics mocks, add market data market id

* feat: #994 add price monitoring bounds and candles update interface

* fix: move best bid price to diff section

* feat(#993): add missing mocks, fix combine function

* fix: add insurance pool and calc volume 24h

* feat: display some oracle min info, asset id, insurance pool, move open interest and 24hVol

* fix: add  market-info.cy.ts case

* fix: remove # from numbered price monitoring settings

* fix: add insurance pool test

* fix: format 24hvol

* feat(#993): set loading initially to true, add unit tests

* feat(#993): cleanup, add comments

* feat(#993): remove undefined from client type

* fix: remove indicativeVolume and oracleSpecBinding from market info

* feat(#993): cosmetic changes

* fix: add oracleSpecBinding back

* Update libs/deal-ticket/src/components/info-market.tsx

Co-authored-by: botond <105208209+notbot00@users.noreply.github.com>

* feat: add initial queries

* fix: memo yesterday's timestamp

* fix: add back info

* fix: update query

* fix: add view full oracle details link and update mappings

* fix: regen code, make link reactnode, fix index.ts

* feat: add liquidity lib, refactor info market

* fix: remove liquidity query from deal-ticket

* feat:(#993): pass informaton about update callback cause

* fix: small ui tweaks

* fix: display in grid

* feat: navigate to oracle by termination id

* feat: #491 add use liquidity provision merging

* fix: remove logs, add extra check on my liquidity provision

* fix: type number trivially inferred from a number literal, remove type annotation

* fix: cypress tests and formatting for market info

* Update libs/deal-ticket/src/components/market-info/info-market.tsx

* fix: use position decimal places for stake and market value proxy

* fix: #491 use size/position decimal places for obligation, supplied and commitment amount

* fix: add size component and use decimal places

* fix: update readme liquidity

* fix: #491 add correct asset decimal formatters

* Update libs/deal-ticket/src/components/market-info/tooltip-mapping.tsx

Co-authored-by: candida-d <62548908+candida-d@users.noreply.github.com>

* fix: make link instead of button to open liquidity

* fix: #491 add liquidity page, link to trading mode tooltip, tabs hidden or choose active

* fix: remove LP dialog, use only link to page

* fix: add market id in LP view

* fix: follow trade grid design

* fix: add one line tabs , remove link styling, remove any, add value formatters

* fix: remove falsy check LP undefined

* fix: keep date formatter in LP table

* fix: add generic type market info, hooks in body function

* fix: revert number formatters

* fix: use one param only in network params query

* fix:  use network param in web3 lib

* fix: move lp container to trading app

* fix: remove resizable panel

* feat: add header component, remove isEstimate

* chore: remove unnecessary type cast

* fix: fix build with children map clone element

* chore: lint

* fix: move use network params to react helpers

* fix: add const for LP tabs

* fix: fix formatting on LP page

* fix: only show tilde for liquidity monitoring auction end date

* fix: market id being rendered twice in market info

* chore: fix lint

* fix: types for generate withdraw form query

* chore: fix intermittent failing withdrawal test

* Update libs/deal-ticket/src/components/market-info/info-market.tsx

* chore: add another wait for market

Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
Co-authored-by: botond <105208209+notbot00@users.noreply.github.com>
Co-authored-by: candida-d <62548908+candida-d@users.noreply.github.com>
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
Co-authored-by: Joe <joe@vega.xyz>
2022-09-07 12:05:28 +01:00
Joe Tsang fa6ddcfdf1 Chore/use vega 0.54.0 (#1268)
* chore: change vega version to use 0.54.0

* chore: update remaining workflows
2022-09-07 10:26:26 +01:00
Joe Tsang e06b5e741c chore: fix test manual and nightly workflows (#1264) 2022-09-07 09:05:02 +01:00
mattrussell36 925c1721aa chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-07 06:26:40 +00:00
mattrussell36 002b11eb4a chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-07 00:08:41 +00:00
mattrussell36 bc1324aafe chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-06 18:04:20 +00:00
Joe Tsang 510b6ad0d5 Test/840 positions update (#1250)
* test: add test for positions in portfolio

* test: update position validation to include updates

* chore: add wait for marketlist
2022-09-06 17:34:40 +01:00
AndyWhiteVega e97f82edfe test: checkout front end changes to cypress workflows (#1258)
* test: checkout front end changes to cypress workflows

* test: remove old fe checkout

* test: remove dup
2022-09-06 15:03:49 +01:00
Dexter Edwards bacd2a509e fix: polling not working on governance page (#1255)
* fix: polling not working on governance page

* style: lint
2022-09-06 15:03:23 +01:00
mattrussell36 f401870848 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-06 12:05:27 +00:00
Matthew Russell a5f21ed1f8 fix: styles on staking and nodes page (#1252) 2022-09-06 10:10:31 +01:00
botond a57d484496 Fix/1083: Update type generator (#1219)
* feat: add new generator with config

* feat: split off gql queries to separate files for the new generator

* fix: delete dummy schema

* feat: add generated queries with new codegen

* fix: regenerate from scratch and remove duplicates

* fix: libs and app gen folders

* fix: remove more duplicate queries

* fix: add generated files to be ignored by the formatter

* fix: format

* fix: generated imports

* fix: lint

* fix: accounts export

* fix: more imports

* fix: add type alias for new type system and regenerate

* fix: format

* fix: delete leftover file from merge
2022-09-06 10:03:10 +01:00
mattrussell36 b531094fda chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-06 06:27:47 +00:00
macqbatandmaciek 7fe282a9fb feat: [console-lite] - refactor market-list view afetr design update (#1244)
* feat: [console-lite] - refactor market-list view afetr design update

* feat: [console-lite] - refactor market-list fix failing test

* feat: [console-lite] - refactor market-list fix failing test

* feat: [console-lite] - refactor market-list fix failing test

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-09-06 08:13:17 +02:00
Matthew Russell 5eb06254de feat (#896): large withdraws (#1180)
* feat: add deposits table to deposits tab on portfolio page

* feat: refactor use-withdraw hook to not invoke eth tx

* feat: rename hook for clarity

* feat: fix withdrawal creation test

* feat: update withdraw-manager and withrawals-table tests

* chore: fix lint

* feat: remove web3 input to avoid double dialog

* chore: use renderHook from testing-library/react

* chore: update to use non deprecated fields

* chore: remove usage of all bridge contract

* feat: correctly merge cache update in withdrawals table

* feat: changes to support token app withdrawals

* chore: add height to ag grid table wrapping element

* feat: add txhash col to withdraw table

* feat: provide better ui if withdrawal is not ready to be completed

* feat: use separate dialogs for txs

* feat: allow user to immediately complete withdrawal if delay not triggered

* feat: add withdraw store to tidy up state management

* chore: fix tests

* chore: convert callback to promises, fix tests, delete withdraw page

* chore: fix lint errors

* fix: withdrawals link in nav

* feat: style changes after design update

* fix: proposal form test

* chore: tidy error ui logic

* feat: review comments

* chore: lint

* feat: add better typing for tables

* chore: put withdrawals tab at the end

* chore: update i18n

* fix: dialog in positions manager due to rename

* chore: increase spacing in withdrawal form

* chore: update tests

* chore: lint

* chore: use new assetsConnection and update cy test

* fix: incorrect shape of withdrawal generate function

* feat: delete withdrawals page now that its shown on the portfolio page

* chore: update tests to check for withdrawals page

* chore: fix tests again

* fix: page title test
2022-09-05 18:30:13 -07:00
mattrussell36 578d6ecf6f chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-06 00:08:57 +00:00
m.ray 744c084ca2 feat: add network switcher to block explorer (#1242)
* feat: add network switcher to block explorer

* fix: add mock for @vegaprotocol/environment

* fix: #723 add test to see if network switcher gets rendered

* fix: formatting on header.spec.tsx
2022-09-05 20:28:21 +01:00
mattrussell36 adec04918e chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-05 18:04:46 +00:00
Matthew Russell 9cb84df35c chore: refactor global store (#1241) 2022-09-05 15:25:33 +01:00
531 changed files with 22081 additions and 6946 deletions
@@ -47,6 +47,14 @@ jobs:
## Checkout capsule
#######
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
path: './frontend-monorepo'
# Checkout capsule to build local network
- name: Checkout capsule
uses: actions/checkout@v2
@@ -70,7 +78,7 @@ jobs:
uses: actions/checkout@v2
with:
repository: vegaprotocol/vega
ref: develop
ref: v0.54.0
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
path: './vega'
@@ -120,18 +128,13 @@ jobs:
## Run some tests
######
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
- name: Install root dependencies
run: yarn install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: yarn nx run ${{ github.event.inputs.project }}:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
run: yarn nx run ${{ github.event.inputs.project }}:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
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 }}
@@ -31,6 +31,14 @@ jobs:
## Checkout capsule
#######
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
path: './frontend-monorepo'
# Checkout capsule to build local network
- name: Checkout capsule
uses: actions/checkout@v2
@@ -54,7 +62,7 @@ jobs:
uses: actions/checkout@v2
with:
repository: vegaprotocol/vega
ref: develop
ref: v0.54.0
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
path: './vega'
@@ -104,18 +112,13 @@ jobs:
## Run some tests
######
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v2
with:
ref: master
fetch-depth: 0
- name: Install root dependencies
run: yarn install
working-directory: frontend-monorepo
- name: Run Cypress tests
run: yarn nx run-many --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
run: yarn nx run-many --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
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 }}
+2 -2
View File
@@ -69,7 +69,7 @@ jobs:
uses: actions/checkout@v2
with:
repository: vegaprotocol/vega
ref: develop
ref: v0.54.0
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
path: './vega'
@@ -130,7 +130,7 @@ jobs:
working-directory: frontend-monorepo
- name: Run Cypress tests
run: npx nx affected:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
run: npx nx affected:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
working-directory: frontend-monorepo
env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
-4
View File
@@ -6,7 +6,3 @@ yarn commitlint --edit "${1}"
# Lint all staged files
yarn lint-staged
# Build & test affected apps
yarn nx affected:build --uncommitted
yarn nx affected:test --uncommitted
+1
View File
@@ -3,6 +3,7 @@
/dist
/coverage
__generated__
__generated___
apps/static/src/assets/devnet-tranches.json
apps/static/src/assets/mainnet-tranches.json
+2 -2
View File
@@ -69,10 +69,10 @@ Run `nx serve my-app` for a dev server. Navigate to the port specified in `app/<
### Using Apollo GraphQL and Generate Types
In order to generate the schemas for your GraphQL queries, you can run `NX_VEGA_URL=[YOUR URL HERE] nx run types:generate`.
In order to generate the schemas for your GraphQL queries, you can run `GRAPHQL_SCHEMA_PATH=[YOUR SCHEMA FILE / API URL HERE] nx run types:generate`.
```bash
export NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
export GRAPHQL_SCHEMA_PATH=https://api.n11.testnet.vega.xyz/graphql
yarn nx run types:generate
```
@@ -39,7 +39,7 @@ describe('market selector', () => {
connectVegaWallet();
cy.get('input[placeholder="Search"]').should(
'have.value',
markets[0].name
markets[0].tradableInstrument.instrument.name
);
cy.getByTestId('arrow-button').click();
cy.getByTestId('market-pane').should('be.visible');
@@ -47,7 +47,7 @@ describe('market selector', () => {
.children()
.find('[role="button"]')
.first()
.should('contain.text', markets[0].name);
.should('contain.text', markets[0].tradableInstrument.instrument.name);
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
@@ -70,8 +70,8 @@ describe('market selector', () => {
cy.get('input[placeholder="Search"]').type('aa');
const filtered = markets.filter(
(market) =>
market.data.market.state === 'STATE_ACTIVE' &&
market.name.match(/aa/i)
market.state === 'STATE_ACTIVE' &&
market.tradableInstrument.instrument.name.match(/aa/i)
);
cy.getByTestId('market-pane')
.children()
@@ -88,7 +88,7 @@ describe('market selector', () => {
);
cy.get('input[placeholder="Search"]').should(
'have.value',
filtered[filtered.length - 1].name
filtered[filtered.length - 1].tradableInstrument.instrument.name
);
}
});
@@ -131,7 +131,7 @@ describe('market selector', () => {
cy.getByTestId('dialog-close').click();
cy.get('input[placeholder="Search"]').should(
'have.value',
markets[0].name
markets[0].tradableInstrument.instrument.name
);
}
});
@@ -170,7 +170,50 @@ describe('Market trade', () => {
.find('button')
.should('have.text', '2');
cy.get('button').contains('Max').click();
cy.getByTestId('price-slippage-value').should('have.text', '0.02%');
}
});
it('slippage value should be displayed', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click();
cy.get('button').contains('Max').click();
cy.get('#step-2-panel')
.find('dl')
.eq(2)
.find('dd')
.should('have.text', '0.02%');
}
});
it('allow slippage value to be adjusted', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').click();
cy.get('button[aria-label="Open short position"]').click();
cy.get('#step-2-control').click();
cy.get('button').contains('Max').click();
cy.get('#step-2-panel')
.find('dl')
.eq(2)
.find('dd')
.should('have.text', '0.02%');
cy.get('#step-2-panel').find('dl').eq(2).find('button').click();
cy.get('#input-order-slippage')
.focus()
.type('{backspace}{backspace}{backspace}1');
cy.getByTestId('slippage-dialog').find('button').click();
cy.get('#step-2-panel')
.find('dl')
.eq(2)
.find('dd')
.should('have.text', '1%');
}
});
@@ -195,9 +238,9 @@ describe('Market trade', () => {
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel')
.find('dt')
.eq(3)
.eq(2)
.should('have.text', 'Est. Position Size (tDAI)');
cy.get('#step-2-panel').find('dd').eq(3).should('have.text', '197.86012');
cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012');
}
});
@@ -210,11 +253,11 @@ describe('Market trade', () => {
cy.get('#step-2-control').click();
cy.get('#step-2-panel')
.find('dt')
.eq(4)
.eq(3)
.should('have.text', 'Est. Fees (tDAI)');
cy.get('#step-2-panel')
.find('dd')
.eq(4)
.eq(3)
.should('have.text', '3.00000 (3.03%)');
}
});
@@ -75,18 +75,11 @@ const protoCandles = [
export const protoMarket = {
id: 'first-btcusd-id',
name: 'AAVEDAI Monthly (30 Jun 2022)',
data: {
market: {
id: 'first-btcusd-id',
state: 'STATE_ACTIVE',
__typename: 'Market',
},
__typename: 'MarketData',
},
state: 'STATE_ACTIVE',
tradableInstrument: {
instrument: {
code: 'AAVEDAI.MF21',
name: 'AAVEDAI Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:2839D9B2329C9E70',
@@ -2,13 +2,13 @@ export const generateDealTicket = () => {
return {
market: {
id: 'first-btcusd-id',
name: 'AAVEDAI Monthly (30 Jun 2022)',
decimalPlaces: 5,
positionDecimalPlaces: 0,
state: 'STATE_ACTIVE',
tradingMode: 'Continuous',
tradableInstrument: {
instrument: {
name: 'AAVEDAI Monthly (30 Jun 2022)',
product: {
quoteName: 'DAI',
settlementAsset: {
@@ -6,11 +6,11 @@ export const generateMarketNames = () => {
{ ...protoMarket },
{
id: '1d7ddf67dac4924db03f5bf58571a7bcb1908d70c66580467717aabc5345b68a',
name: 'Apple Monthly (30 Jun 2022)',
state: 'STATE_SUSPENDED',
tradableInstrument: {
instrument: {
code: 'AAPL.MF21',
name: 'Apple Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:4899E01009F1A721',
@@ -32,11 +32,11 @@ export const generateMarketNames = () => {
},
{
id: '87ae87cd3244fc1fab4b0e2dad2437879864192bb969f3109b69293421644c8b',
name: 'Tesla Quarterly (30 Jun 2022)',
state: 'STATE_SUSPENDED',
tradableInstrument: {
instrument: {
code: 'TSLA.QM21',
name: 'Tesla Quarterly (30 Jun 2022)',
metadata: {
tags: [
'formerly:5A86B190C384997F',
@@ -58,11 +58,11 @@ export const generateMarketNames = () => {
},
{
id: '69205712a854f1bbfb69fa3d11b60e01a1e249bafb5ece88115e7451e8ef07b3',
name: 'BTCUSD Monthly (30 Jun 2022)',
state: 'STATE_SUSPENDED',
tradableInstrument: {
instrument: {
code: 'BTCUSD.MF21',
name: 'BTCUSD Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:076BB86A5AA41E3E',
@@ -83,11 +83,11 @@ export const generateMarketNames = () => {
},
{
id: 'ethbtc-quaterly',
name: 'ETHBTC Quarterly (30 Jun 2022)',
state: 'STATE_ACTIVE',
tradableInstrument: {
instrument: {
code: 'ETHBTC.QM21',
name: 'ETHBTC Quarterly (30 Jun 2022)',
metadata: {
tags: [
'formerly:1F0BB6EB5703B099',
@@ -108,11 +108,11 @@ export const generateMarketNames = () => {
},
{
id: '3c62b2714c4332d1a689a5352bff090e6aabccfd6bd87ce018936b38372530c9',
name: 'UNIDAI Monthly (30 Jun 2022)',
state: 'STATE_ACTIVE',
tradableInstrument: {
instrument: {
code: 'UNIDAI.MF21',
name: 'UNIDAI Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:3C58ED2A4A6C5D7E',
@@ -6,19 +6,11 @@ export const generateSimpleMarkets = () => {
{ ...protoMarket },
{
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
name: 'CELUSD (June 2022)',
state: 'Active',
data: {
market: {
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
state: 'STATE_PENDING',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'CELUSD',
name: 'CELUSD (June 2022)',
metadata: {
tags: [
'base:CEL',
@@ -43,19 +35,11 @@ export const generateSimpleMarkets = () => {
},
{
id: 'ccf2f04865e5951ac3405da6e16b7cbdb535a0ad32df4df2dbed4262cf473255',
name: 'XMRUSD market',
state: 'Suspended',
data: {
market: {
id: 'ccf2f04865e5951ac3405da6e16b7cbdb535a0ad32df4df2dbed4262cf473255',
state: 'STATE_PROPOSED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'XMRUSD',
name: 'XMRUSD market',
metadata: {
tags: [
'base:monero',
@@ -80,19 +64,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '6030e5b4e0ca3297a26081e5af4d453f97f96baab2d74bf56f84efcffc4c382f',
name: 'UNIDAI Monthly (30 Jun 2022)',
state: 'Active',
data: {
market: {
id: '6030e5b4e0ca3297a26081e5af4d453f97f96baab2d74bf56f84efcffc4c382f',
state: 'STATE_SUSPENDED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'UNIDAI.MF21',
name: 'UNIDAI Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:3C58ED2A4A6C5D7E',
@@ -191,19 +167,11 @@ export const generateSimpleMarkets = () => {
},
{
id: 'de74a5572045b300e8ec50d136896912ec76e7d7ec135bc305dfd4854d9363a4',
name: 'XMRUSD market',
state: 'Pending',
data: {
market: {
id: 'de74a5572045b300e8ec50d136896912ec76e7d7ec135bc305dfd4854d9363a4',
state: 'STATE_ACTIVE',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'XMRUSD',
name: 'XMRUSD market',
metadata: {
tags: [
'base:monero',
@@ -301,19 +269,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '31ea96284611771e486c820acb26a325a99664f9854b5a7e7ad99023efa8f9e6',
name: 'ApeCoin (18 Jul 2022)',
state: 'Closed',
data: {
market: {
id: '31ea96284611771e486c820acb26a325a99664f9854b5a7e7ad99023efa8f9e6',
state: 'STATE_PROPOSED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'APE/USD',
name: 'ApeCoin (18 Jul 2022)',
metadata: {
tags: [
'quote:USD',
@@ -337,19 +297,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '34cff959cdc2ffdb0f167820d701fe8b51cc6b8588e650d93369aaa22d6f8b74',
name: 'BTCUSD Monthly (18 Jul 2022)',
state: 'Settled',
data: {
market: {
id: '34cff959cdc2ffdb0f167820d701fe8b51cc6b8588e650d93369aaa22d6f8b74',
state: 'STATE_PROPOSED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'BTCUSD.MF21',
name: 'BTCUSD Monthly (18 Jul 2022)',
metadata: {
tags: [
'formerly:076BB86A5AA41E3E',
@@ -375,19 +327,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '87b0bbb3c171baa5d97dfc3852332829c91e5c5dc9f7c8fb584c6d8ac75aaaf2',
name: 'Builders Club x ETHcc',
state: 'Settled',
data: {
market: {
id: '87b0bbb3c171baa5d97dfc3852332829c91e5c5dc9f7c8fb584c6d8ac75aaaf2',
state: 'STATE_ACTIVE',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'LTCUSD',
name: 'Builders Club x ETHcc',
metadata: {
tags: [
'base:litecoin',
@@ -473,19 +417,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '45266143c6e9b58f4cff9b8906e971c531bb29ea7af01066973f9b77e8134823',
name: 'BTCUSD Monthly (18 Jul 2022)',
state: 'Pending',
data: {
market: {
id: '45266143c6e9b58f4cff9b8906e971c531bb29ea7af01066973f9b77e8134823',
state: 'STATE_PROPOSED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'BTCUSD.MF21',
name: 'BTCUSD Monthly (18 Jul 2022)',
metadata: {
tags: [
'formerly:076BB86A5AA41E3E',
@@ -511,19 +447,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '65663ebdc96161162769c4d5c5508137416748178d7cb28e2cb0d07a151a2bc6',
name: 'ETHBTC Quarterly (30 Jun 2022)',
state: 'Active',
data: {
market: {
id: '65663ebdc96161162769c4d5c5508137416748178d7cb28e2cb0d07a151a2bc6',
state: 'STATE_ACTIVE',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'ETHBTC.QM21',
name: 'ETHBTC Quarterly (30 Jun 2022)',
metadata: {
tags: [
'formerly:1F0BB6EB5703B099',
@@ -622,19 +550,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '234afabd27e3bce1a879039c041f9f00f915d98459935ddafd0169d38dd13850',
name: 'Apple Monthly (30 Jun 2022)',
state: 'Active',
data: {
market: {
id: '234afabd27e3bce1a879039c041f9f00f915d98459935ddafd0169d38dd13850',
state: 'STATE_ACTIVE',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'AAPL.MF21',
name: 'Apple Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:4899E01009F1A721',
@@ -734,19 +654,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '9f2a3c1caa67bb0773ec18d908d32b55b129b9ec2d106a8e9a87f6aa5c0375a6',
name: 'Tesla Quarterly (30 Jun 2022)',
state: 'Active',
data: {
market: {
id: '9f2a3c1caa67bb0773ec18d908d32b55b129b9ec2d106a8e9a87f6aa5c0375a6',
state: 'STATE_ACTIVE',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'TSLA.QM21',
name: 'Tesla Quarterly (30 Jun 2022)',
metadata: {
tags: [
'formerly:5A86B190C384997F',
@@ -846,19 +758,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '8a45ee934d3ddac4b036f9884df1064a5353c620a56f775ba36597d0edef9a7a',
name: 'Go big or Go home',
state: 'Active',
data: {
market: {
id: '8a45ee934d3ddac4b036f9884df1064a5353c620a56f775ba36597d0edef9a7a',
state: 'STATE_SUSPENDED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'LTCUSD',
name: 'Go big or Go home',
metadata: {
tags: [
'base:litecoin',
@@ -897,19 +801,11 @@ export const generateSimpleMarkets = () => {
},
{
id: 'aede7b9ac0c3b225004929c5455160a00f59864aad32ec366e8a2bff1b30fd0f',
name: 'BTCUSD Monthly (08 Jul 2022)',
state: 'Active',
data: {
market: {
id: 'aede7b9ac0c3b225004929c5455160a00f59864aad32ec366e8a2bff1b30fd0f',
state: 'STATE_PROPOSED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'BTCUSD.MF21',
name: 'BTCUSD Monthly (08 Jul 2022)',
metadata: {
tags: [
'formerly:076BB86A5AA41E3E',
@@ -935,19 +831,11 @@ export const generateSimpleMarkets = () => {
},
{
id: '9398707e01daa1a1f1ca6ff87cf8d6c03fe7373ce31121ce81b99a129e6bda47',
name: 'BTCUSD Monthly (18 Jul 2022)',
state: 'Active',
data: {
market: {
id: '9398707e01daa1a1f1ca6ff87cf8d6c03fe7373ce31121ce81b99a129e6bda47',
state: 'STATE_PROPOSED',
__typename: 'Market',
},
__typename: 'MarketData',
},
tradableInstrument: {
instrument: {
code: 'BTCUSD.MF21',
name: 'BTCUSD Monthly (18 Jul 2022)',
metadata: {
tags: [
'formerly:076BB86A5AA41E3E',
@@ -978,14 +866,15 @@ export const generateSimpleMarkets = () => {
export const generateLongListMarkets = (count: number) => {
const markets = [];
for (let i = 0; i < count; i++) {
const { id, name } = protoMarket;
markets.push({
...protoMarket,
id: id + i,
name: name + i,
data: {
...protoMarket.data,
id: id + i,
id: protoMarket.id + i,
tradableInstrument: {
...protoMarket.tradableInstrument,
instrument: {
...protoMarket.tradableInstrument.instrument,
name: protoMarket.tradableInstrument.instrument.name + i,
},
},
});
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "__generated__"],
"ignorePatterns": ["!**/*", "__generated__", "__generated___"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+22
View File
@@ -1,7 +1,29 @@
import '@testing-library/jest-dom';
import { defaultFallbackInView } from 'react-intersection-observer';
import ResizeObserver from 'resize-observer-polyfill';
defaultFallbackInView(true);
global.ResizeObserver = ResizeObserver;
global.DOMRect = class DOMRect {
bottom = 0;
left = 0;
right = 0;
top = 0;
constructor(
public x = 0,
public y = 0,
public width = 0,
public height = 0
) {}
static fromRect(other?: DOMRectInit): DOMRect {
return new DOMRect(other?.x, other?.y, other?.width, other?.height);
}
toJSON() {
return JSON.stringify(this);
}
};
Object.defineProperty(window, 'matchMedia', {
writable: true,
@@ -0,0 +1,11 @@
query MarketTags($marketId: ID!) {
market(id: $marketId) {
tradableInstrument {
instrument {
metadata {
tags
}
}
}
}
}
@@ -0,0 +1,14 @@
query PartyBalanceQuery($partyId: ID!) {
party(id: $partyId) {
accounts {
type
balance
asset {
id
symbol
name
decimals
}
}
}
}
@@ -0,0 +1,54 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketTagsQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type MarketTagsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null } } } } | null };
export const MarketTagsDocument = gql`
query MarketTags($marketId: ID!) {
market(id: $marketId) {
tradableInstrument {
instrument {
metadata {
tags
}
}
}
}
}
`;
/**
* __useMarketTagsQuery__
*
* To run a query within a React component, call `useMarketTagsQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketTagsQuery` 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 } = useMarketTagsQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useMarketTagsQuery(baseOptions: Apollo.QueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
}
export function useMarketTagsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
}
export type MarketTagsQueryHookResult = ReturnType<typeof useMarketTagsQuery>;
export type MarketTagsLazyQueryHookResult = ReturnType<typeof useMarketTagsLazyQuery>;
export type MarketTagsQueryResult = Apollo.QueryResult<MarketTagsQuery, MarketTagsQueryVariables>;
@@ -0,0 +1,57 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type PartyBalanceQueryQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accounts?: Array<{ __typename?: 'Account', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } }> | null } | null };
export const PartyBalanceQueryDocument = gql`
query PartyBalanceQuery($partyId: ID!) {
party(id: $partyId) {
accounts {
type
balance
asset {
id
symbol
name
decimals
}
}
}
}
`;
/**
* __usePartyBalanceQueryQuery__
*
* To run a query within a React component, call `usePartyBalanceQueryQuery` and pass it any options that fit your needs.
* When your component renders, `usePartyBalanceQueryQuery` 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 } = usePartyBalanceQueryQuery({
* variables: {
* partyId: // value for 'partyId'
* },
* });
*/
export function usePartyBalanceQueryQuery(baseOptions: Apollo.QueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
}
export function usePartyBalanceQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
}
export type PartyBalanceQueryQueryHookResult = ReturnType<typeof usePartyBalanceQueryQuery>;
export type PartyBalanceQueryLazyQueryHookResult = ReturnType<typeof usePartyBalanceQueryLazyQuery>;
export type PartyBalanceQueryQueryResult = Apollo.QueryResult<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>;
@@ -4,6 +4,7 @@ import { t } from '@vegaprotocol/react-helpers';
import { Icon, Tooltip } from '@vegaprotocol/ui-toolkit';
import { IconNames } from '@blueprintjs/icons';
import * as constants from './constants';
import { TrafficLight } from '../traffic-light';
interface DealTicketEstimatesProps {
quoteName?: string;
@@ -13,6 +14,7 @@ interface DealTicketEstimatesProps {
fees?: string;
notionalSize?: string;
size?: string;
slippage?: string;
}
interface DataTitleProps {
@@ -20,7 +22,7 @@ interface DataTitleProps {
quoteName?: string;
}
const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
export const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
<dt>
{children}
{quoteName && <small> ({quoteName})</small>}
@@ -28,14 +30,20 @@ const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
);
interface ValueTooltipProps {
value: string;
value?: string;
children?: ReactNode;
description: string;
id?: string;
}
const ValueTooltipRow = ({ value, description, id }: ValueTooltipProps) => (
export const ValueTooltipRow = ({
value,
children,
description,
id,
}: ValueTooltipProps) => (
<dd className="flex gap-x-2 items-center">
{value}
{value || children}
<Tooltip align="center" description={description}>
<div className="cursor-help" id={id || ''} tabIndex={-1}>
<Icon
@@ -56,6 +64,7 @@ export const DealTicketEstimates = ({
fees,
notionalSize,
size,
slippage,
}: DealTicketEstimatesProps) => (
<dl className="text-black dark:text-white">
{size && (
@@ -93,7 +102,7 @@ export const DealTicketEstimates = ({
</div>
)}
{estMargin && (
<div className="flex justify-between mb-8">
<div className="flex justify-between mb-2">
<DataTitle quoteName={quoteName}>{t('Est. Margin')}</DataTitle>
<ValueTooltipRow
value={estMargin}
@@ -102,17 +111,23 @@ export const DealTicketEstimates = ({
</div>
)}
{estCloseOut && (
<div className="flex justify-between">
<dt>
<span>{t('Est. Close out')}</span>
&nbsp;
<small>({quoteName})</small>
</dt>
<div className="flex justify-between mb-2">
<DataTitle quoteName={quoteName}>{t('Est. Close out')}</DataTitle>
<ValueTooltipRow
value={estCloseOut}
description={constants.EST_CLOSEOUT_TOOLTIP_TEXT}
/>
</div>
)}
{slippage && (
<div className="flex justify-between mb-2">
<DataTitle>{t('Est. Price Impact / Slippage')}</DataTitle>
<ValueTooltipRow description={constants.EST_SLIPPAGE}>
<TrafficLight value={parseFloat(slippage)} q1={1} q2={5}>
{slippage}%
</TrafficLight>
</ValueTooltipRow>
</div>
)}
</dl>
);
@@ -0,0 +1,149 @@
import React, { useCallback, useState } from 'react';
import { BigNumber } from 'bignumber.js';
import { t } from '@vegaprotocol/react-helpers';
import {
SliderRoot,
SliderThumb,
SliderTrack,
SliderRange,
FormGroup,
} from '@vegaprotocol/ui-toolkit';
import { InputSetter } from '../input-setter';
interface DealTicketSizeInputProps {
step: number;
min: number;
max: number;
value: number;
onValueChange: (value: number) => void;
positionDecimalPlaces: number;
}
const getSizeLabel = (value: number): string => {
const MIN_LABEL = 'Min';
const MAX_LABEL = 'Max';
if (value === 0) {
return MIN_LABEL;
} else if (value === 100) {
return MAX_LABEL;
}
return `${value}%`;
};
export const DealTicketSizeInput = ({
value,
step,
min,
max,
onValueChange,
positionDecimalPlaces,
}: DealTicketSizeInputProps) => {
const sizeRatios = [0, 25, 50, 75, 100];
const [inputValue, setInputValue] = useState(value);
const onInputValueChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
let value = parseFloat(event.target.value);
const isLessThanMin = value < min;
const isMoreThanMax = value > max;
if (isLessThanMin) {
value = min;
} else if (isMoreThanMax) {
value = max;
}
if (value) {
onValueChange(value);
}
setInputValue(value);
},
[min, max, onValueChange, setInputValue]
);
const onButtonValueChange = (size: number) => {
const newVal = new BigNumber(size)
.decimalPlaces(positionDecimalPlaces)
.toNumber();
onValueChange(newVal);
setInputValue(newVal);
};
const onSliderValueChange = useCallback(
(value: number[]) => {
const val = value[0];
setInputValue(val);
onValueChange(val);
},
[onValueChange]
);
return (
<div>
<div className="flex justify-between text-black dark:text-white mb-2">
<span data-testid="min-label">{min}</span>
<span data-testid="max-label">{max}</span>
</div>
<SliderRoot
className="mb-2"
value={[value]}
onValueChange={onSliderValueChange}
step={step}
min={min}
max={max}
>
<SliderTrack className="bg-lightGrey dark:bg-offBlack">
<SliderRange className="!bg-black dark:!bg-white" />
</SliderTrack>
<SliderThumb />
</SliderRoot>
<div
data-testid="percentage-selector"
className="flex w-full justify-between text-black dark:text-white mb-6"
>
{sizeRatios.map((size, index) => {
const proportionalSize = size ? (size / 100) * max : min;
return (
<button
className="no-underline hover:underline text-blue"
onClick={() => onButtonValueChange(proportionalSize)}
type="button"
key={index}
>
{getSizeLabel(size)}
</button>
);
})}
</div>
<dl className="text-black dark:text-white">
<div className="flex items-center justify-between">
<dt>{t('Contracts')}</dt>
<dd className="flex justify-end w-full">
<FormGroup
hideLabel={true}
label="Enter Size"
labelFor="trade-size-input"
className="mb-1"
>
<InputSetter
id="input-order-size-market"
type="number"
step={step}
min={min}
max={max}
className="w-full"
value={inputValue}
onChange={onInputValueChange}
>
{inputValue}
</InputSetter>
</FormGroup>
</dd>
</div>
</dl>
</div>
);
};
@@ -1,27 +1,13 @@
import React, { useCallback, useState } from 'react';
import classNames from 'classnames';
import { IconNames } from '@blueprintjs/icons';
import { t } from '@vegaprotocol/react-helpers';
import {
SliderRoot,
SliderThumb,
SliderTrack,
SliderRange,
FormGroup,
Icon,
Tooltip,
} from '@vegaprotocol/ui-toolkit';
import { BigNumber } from 'bignumber.js';
import React from 'react';
import { DealTicketEstimates } from './deal-ticket-estimates';
import { InputSetter } from '../input-setter';
import * as constants from './constants';
import { DealTicketSizeInput } from './deal-ticket-size-input';
interface DealTicketSizeProps {
step: number;
min: number;
max: number;
value: number;
onValueChange: (value: number[]) => void;
size: number;
onSizeChange: (value: number) => void;
name: string;
quoteName: string;
price: string;
@@ -30,173 +16,33 @@ interface DealTicketSizeProps {
fees: string;
positionDecimalPlaces: number;
notionalSize: string;
slippage: string | null;
}
const getSizeLabel = (value: number): string => {
const MIN_LABEL = 'Min';
const MAX_LABEL = 'Max';
if (value === 0) {
return MIN_LABEL;
} else if (value === 100) {
return MAX_LABEL;
}
return `${value}%`;
};
export const DealTicketSize = ({
value,
step,
min,
max,
price,
quoteName,
onValueChange,
size,
onSizeChange,
estCloseOut,
positionDecimalPlaces,
fees,
notionalSize,
slippage,
}: DealTicketSizeProps) => {
const sizeRatios = [0, 25, 50, 75, 100];
const [inputValue, setInputValue] = useState(value);
const onInputValueChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const value = parseFloat(event.target.value);
const isLessThanMin = value < min;
const isMoreThanMax = value > max;
if (value) {
if (isLessThanMin) {
onValueChange([min]);
} else if (isMoreThanMax) {
onValueChange([max]);
} else {
onValueChange([value]);
}
}
setInputValue(value);
},
[min, max, onValueChange, setInputValue]
);
const onButtonValueChange = useCallback(
(size: number) => {
const newVal = new BigNumber(size)
.decimalPlaces(positionDecimalPlaces)
.toNumber();
onValueChange([newVal]);
setInputValue(newVal);
},
[onValueChange, positionDecimalPlaces]
);
const onSliderValueChange = useCallback(
(value: number[]) => {
setInputValue(value[0]);
onValueChange(value);
},
[onValueChange]
);
return max === 0 ? (
<p>Not enough balance to trade</p>
) : (
<div>
<div className="flex justify-between text-black dark:text-white mb-2">
<span data-testid="min-label">{min}</span>
<span data-testid="max-label">{max}</span>
</div>
<SliderRoot
className="mb-2"
value={[value]}
onValueChange={onSliderValueChange}
<DealTicketSizeInput
step={step}
min={min}
max={max}
>
<SliderTrack className="bg-lightGrey dark:bg-offBlack">
<SliderRange className="!bg-black dark:!bg-white" />
</SliderTrack>
<SliderThumb />
</SliderRoot>
<div
data-testid="percentage-selector"
className="flex w-full justify-between text-black dark:text-white mb-6"
>
{sizeRatios.map((size, index) => {
const proportionalSize = size ? (size / 100) * max : min;
return (
<button
className="no-underline hover:underline text-blue"
onClick={() => onButtonValueChange(proportionalSize)}
type="button"
key={index}
>
{getSizeLabel(size)}
</button>
);
})}
</div>
<dl className="text-black dark:text-white">
<div className="flex items-center justify-between mb-4">
<dt>{t('Contracts')}</dt>
<dd className="flex justify-end w-full">
<FormGroup
hideLabel={true}
label="Enter Size"
labelFor="trade-size-input"
>
<InputSetter
id="input-order-size-market"
type="number"
step={step}
min={min}
max={max}
className="w-full"
value={inputValue}
onChange={onInputValueChange}
/>
</FormGroup>
</dd>
</div>
</dl>
{slippage && (
<dl className="text-black dark:text-white">
<div className="flex items-center justify-between mb-8">
<dt>{t('Est. Price Impact / Slippage')}</dt>
<dd
className="flex justify-end gap-x-5"
data-testid="price-slippage-value"
aria-label={t('Est. Price Impact / Slippage')}
>
<span
className={classNames({
'text-darkerGreen dark:text-lightGreen':
parseFloat(slippage) < 1,
'text-amber':
parseFloat(slippage) >= 1 && parseFloat(slippage) < 5,
'text-vega-red': parseFloat(slippage) >= 5,
})}
>
{slippage}%
</span>
<Tooltip align="center" description={constants.EST_SLIPPAGE}>
<div className="cursor-help" tabIndex={-1}>
<Icon
name={IconNames.ISSUE}
className="block rotate-180"
ariaLabel={constants.EST_SLIPPAGE}
/>
</div>
</Tooltip>
</dd>
</div>
</dl>
)}
value={size}
onValueChange={onSizeChange}
positionDecimalPlaces={positionDecimalPlaces}
/>
<DealTicketEstimates
quoteName={quoteName}
fees={fees}
@@ -0,0 +1,104 @@
import React, { useCallback, useState } from 'react';
import { t } from '@vegaprotocol/react-helpers';
import * as constants from './constants';
import { TrafficLight } from '../traffic-light';
import { Dialog, Icon, Intent, Tooltip } from '@vegaprotocol/ui-toolkit';
import { InputSetter } from '../../components/input-setter';
import { IconNames } from '@blueprintjs/icons';
import { DataTitle, ValueTooltipRow } from './deal-ticket-estimates';
interface DealTicketSlippageProps {
step?: number;
min?: number;
max?: number;
value: number;
onValueChange(value: number): void;
}
export const DealTicketSlippage = ({
value,
step = 0.01,
min = 0,
max = 50,
onValueChange,
}: DealTicketSlippageProps) => {
const [isDialogVisible, setIsDialogVisible] = useState(false);
const onChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
const numericValue = parseFloat(value);
onValueChange(numericValue);
},
[onValueChange]
);
const toggleDialog = useCallback(() => {
setIsDialogVisible(!isDialogVisible);
}, [isDialogVisible]);
const formLabel = (
<label className="flex items-center mb-1">
<span className="mr-1">{t('Adjust slippage tolerance')}</span>
<Tooltip align="center" description={constants.EST_SLIPPAGE}>
<div className="cursor-help" tabIndex={-1}>
<Icon
name={IconNames.ISSUE}
className="block rotate-180"
ariaLabel={constants.EST_SLIPPAGE}
/>
</div>
</Tooltip>
</label>
);
return (
<>
<Dialog
open={isDialogVisible}
onChange={toggleDialog}
intent={Intent.None}
title={t('Transaction Settings')}
>
<div data-testid="slippage-dialog">
{formLabel}
<InputSetter
id="input-order-slippage"
isInputVisible
hasError={!value}
type="number"
step={step}
min={min}
max={max}
className="w-full"
value={value}
onChange={onChange}
>
{value}%
</InputSetter>
</div>
</Dialog>
<dl className="text-black dark:text-white">
<div className="flex justify-between mb-2">
<DataTitle>{t('Est. Price Impact / Slippage')}</DataTitle>
<div className="flex">
<div className="mr-1">
<ValueTooltipRow description={constants.EST_SLIPPAGE}>
<TrafficLight value={value} q1={1} q2={5}>
{value}%
</TrafficLight>
</ValueTooltipRow>
</div>
<button type="button" onClick={toggleDialog}>
<Icon
name={IconNames.COG}
className="block rotate-180"
ariaLabel={t('Override slippage value')}
/>
</button>
</div>
</div>
</dl>
</>
);
};
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useForm, Controller } from 'react-hook-form';
import { Stepper } from '../stepper';
@@ -10,7 +10,7 @@ import type { Order } from '@vegaprotocol/orders';
import { useVegaWallet, VegaTxStatus } from '@vegaprotocol/wallet';
import {
t,
addDecimal,
addDecimalsFormatNumber,
toDecimal,
removeDecimal,
} from '@vegaprotocol/react-helpers';
@@ -33,6 +33,8 @@ import useOrderCloseOut from '../../hooks/use-order-closeout';
import useOrderMargin from '../../hooks/use-order-margin';
import useMaximumPositionSize from '../../hooks/use-maximum-position-size';
import useCalculateSlippage from '../../hooks/use-calculate-slippage';
import { Side, OrderType } from '@vegaprotocol/types';
import { DealTicketSlippage } from './deal-ticket-slippage';
interface DealTicketMarketProps {
market: DealTicketQuery_market;
@@ -62,28 +64,26 @@ export const DealTicketSteps = ({
defaultValues: getDefaultOrder(market),
});
const [max, setMax] = useState<number | null>(null);
const emptyString = ' - ';
const step = toDecimal(market.positionDecimalPlaces);
const orderType = watch('type');
const orderTimeInForce = watch('timeInForce');
const orderSide = watch('side');
const orderSize = watch('size');
const order = watch();
const estCloseOut = useOrderCloseOut({ order, market, partyData });
const { message: invalidText, isDisabled } = useOrderValidation({
market,
orderType,
orderTimeInForce,
fieldErrors: errors,
});
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
const { keypair } = useVegaWallet();
const estMargin = useOrderMargin({
order,
market,
partyId: keypair?.pub || '',
});
const value = new BigNumber(orderSize).toNumber();
const price =
market.depth.lastTrade &&
addDecimal(market.depth.lastTrade.price, market.decimalPlaces);
const emptyString = ' - ';
const [notionalSize, setNotionalSize] = useState<string | null>(null);
const [fees, setFees] = useState<string | null>(null);
const maxTrade = useMaximumPositionSize({
partyId: keypair?.pub || '',
@@ -94,46 +94,48 @@ export const DealTicketSteps = ({
price: market?.depth?.lastTrade?.price,
order,
});
const estCloseOut = useOrderCloseOut({ order, market, partyData });
const slippage = useCalculateSlippage({ marketId: market.id, order });
useEffect(() => {
setMax(
new BigNumber(maxTrade)
.decimalPlaces(market.positionDecimalPlaces)
.toNumber()
);
}, [maxTrade, market.positionDecimalPlaces]);
const { message: invalidText, isDisabled } = useOrderValidation({
market,
orderType,
orderTimeInForce,
fieldErrors: errors,
});
const { submit, transaction, finalizedOrder, TransactionDialog } =
useOrderSubmit();
const onSizeChange = (value: number[]) => {
const newVal = new BigNumber(value[0])
.decimalPlaces(market.positionDecimalPlaces)
.toString();
const isValid = validateSize(step)(newVal);
if (isValid !== 'step') {
setValue('size', newVal);
}
};
const [slippageValue, setSlippageValue] = useState(
slippage ? parseFloat(slippage) : 0
);
const transactionStatus =
transaction.status === VegaTxStatus.Requested ||
transaction.status === VegaTxStatus.Pending
? 'pending'
: 'default';
useEffect(() => {
if (market?.depth?.lastTrade?.price) {
const size = new BigNumber(market.depth.lastTrade.price)
.multipliedBy(value)
setSlippageValue(slippage ? parseFloat(slippage) : 0);
}, [slippage]);
const price = useMemo(() => {
if (slippage && market?.depth?.lastTrade?.price) {
const isLong = order.side === Side.SIDE_BUY;
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
parseFloat(slippage) / 100
);
return new BigNumber(market?.depth?.lastTrade?.price)
.multipliedBy(multiplier)
.toNumber();
setNotionalSize(addDecimal(size, market.decimalPlaces));
}
}, [market, value]);
return null;
}, [market?.depth?.lastTrade?.price, order.side, slippage]);
useEffect(() => {
const formattedPrice =
price && addDecimalsFormatNumber(price, market.decimalPlaces);
const notionalSize = useMemo(() => {
if (price) {
const size = new BigNumber(price).multipliedBy(orderSize).toNumber();
return addDecimalsFormatNumber(size, market.decimalPlaces);
}
return null;
}, [market.decimalPlaces, orderSize, price]);
const fees = useMemo(() => {
if (estMargin?.fees && notionalSize) {
const percentage = new BigNumber(estMargin?.fees)
.dividedBy(notionalSize)
@@ -141,17 +143,66 @@ export const DealTicketSteps = ({
.decimalPlaces(2)
.toString();
setFees(`${estMargin.fees} (${percentage}%)`);
return `${estMargin.fees} (${percentage}%)`;
}
}, [estMargin, notionalSize]);
const transactionStatus =
transaction.status === VegaTxStatus.Requested ||
transaction.status === VegaTxStatus.Pending
? 'pending'
: 'default';
return null;
}, [estMargin?.fees, notionalSize]);
const onSubmit = React.useCallback(
const max = useMemo(() => {
return new BigNumber(maxTrade)
.decimalPlaces(market.positionDecimalPlaces)
.toNumber();
}, [market.positionDecimalPlaces, maxTrade]);
const onSizeChange = useCallback(
(value: number) => {
const newVal = new BigNumber(value)
.decimalPlaces(market.positionDecimalPlaces)
.toString();
const isValid = validateSize(step)(newVal);
if (isValid !== 'step') {
setValue('size', newVal);
}
},
[market.positionDecimalPlaces, setValue, step]
);
const onSlippageChange = useCallback(
(value: number) => {
if (market?.depth?.lastTrade?.price) {
if (value) {
const isLong = order.side === Side.SIDE_BUY;
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
value / 100
);
const bestAskPrice = new BigNumber(market?.depth?.lastTrade?.price)
.multipliedBy(multiplier)
.decimalPlaces(market.decimalPlaces)
.toString();
setValue('price', bestAskPrice);
if (orderType === OrderType.TYPE_MARKET) {
setValue('type', OrderType.TYPE_LIMIT);
}
} else {
setValue('type', OrderType.TYPE_MARKET);
setValue('price', market?.depth?.lastTrade?.price);
}
}
setSlippageValue(value);
},
[
market.decimalPlaces,
market?.depth?.lastTrade?.price,
order.side,
orderType,
setValue,
]
);
const onSubmit = useCallback(
(order: Order) => {
if (transactionStatus !== 'pending') {
submit({
@@ -180,7 +231,7 @@ export const DealTicketSteps = ({
ItemRenderer={MarketNameRenderer}
/>
),
value: market.name,
value: market.tradableInstrument.instrument.name,
},
{
label: t('Select Direction'),
@@ -199,25 +250,30 @@ export const DealTicketSteps = ({
label: t('Choose Position Size'),
component:
max !== null ? (
<DealTicketSize
step={step}
min={step}
max={max}
onValueChange={onSizeChange}
value={new BigNumber(orderSize).toNumber()}
name="size"
price={price || emptyString}
positionDecimalPlaces={market.positionDecimalPlaces}
quoteName={
market.tradableInstrument.instrument.product.settlementAsset
.symbol
}
notionalSize={notionalSize || emptyString}
estCloseOut={estCloseOut}
fees={fees || emptyString}
estMargin={estMargin?.margin || emptyString}
slippage={slippage}
/>
<>
<DealTicketSize
step={step}
min={step}
max={max}
onSizeChange={onSizeChange}
size={new BigNumber(orderSize).toNumber()}
name="size"
price={formattedPrice || emptyString}
positionDecimalPlaces={market.positionDecimalPlaces}
quoteName={
market.tradableInstrument.instrument.product.settlementAsset
.symbol
}
notionalSize={notionalSize || emptyString}
estCloseOut={estCloseOut}
fees={fees || emptyString}
estMargin={estMargin?.margin || emptyString}
/>
<DealTicketSlippage
value={slippageValue}
onValueChange={onSlippageChange}
/>
</>
) : (
'loading...'
),
@@ -241,21 +297,22 @@ export const DealTicketSteps = ({
order={order}
estCloseOut={estCloseOut}
estMargin={estMargin?.margin || emptyString}
price={price || emptyString}
price={formattedPrice || emptyString}
quoteName={
market.tradableInstrument.instrument.product.settlementAsset
.symbol
}
notionalSize={notionalSize || emptyString}
fees={fees || emptyString}
slippage={slippageValue}
/>
<TransactionDialog
<Dialog
title={getOrderDialogTitle(finalizedOrder?.status)}
intent={getOrderDialogIntent(finalizedOrder?.status)}
icon={getOrderDialogIcon(finalizedOrder?.status)}
>
<OrderFeedback transaction={transaction} order={finalizedOrder} />
</TransactionDialog>
</Dialog>
</div>
),
disabled: true,
@@ -43,6 +43,7 @@ interface Props {
price: string;
fees: string;
notionalSize: string;
slippage: number;
}
export default ({
@@ -55,6 +56,7 @@ export default ({
fees,
price,
notionalSize,
slippage,
}: Props) => {
const { data: tagsData } = useQuery<MarketTags, MarketTagsVariables>(
MARKET_TAGS_QUERY,
@@ -105,6 +107,7 @@ export default ({
fees={fees}
estCloseOut={estCloseOut}
notionalSize={notionalSize}
slippage={slippage.toString()}
/>
<div className="mt-12 max-w-sm">
@@ -0,0 +1,17 @@
query Deposits {
assetsConnection {
edges {
node {
id
name
symbol
decimals
source {
... on ERC20 {
contractAddress
}
}
}
}
}
}
@@ -3,6 +3,8 @@
// @generated
// This file was automatically generated and should not be edited.
import { AssetStatus } from "@vegaprotocol/types";
// ====================================================
// GraphQL query operation: Deposits
// ====================================================
@@ -39,6 +41,10 @@ export interface Deposits_assetsConnection_edges_node {
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
*/
decimals: number;
/**
* The status of the asset in the Vega network
*/
status: AssetStatus;
/**
* The origin source of the asset (e.g: an ERC20 asset)
*/
@@ -62,5 +68,5 @@ export interface Deposits {
/**
* The list of all assets in use in the Vega network or the specified asset if ID is provided
*/
assetsConnection: Deposits_assetsConnection;
assetsConnection: Deposits_assetsConnection | null;
}
@@ -0,0 +1,57 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type DepositsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type DepositsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } } } | null> | null } | null };
export const DepositsDocument = gql`
query Deposits {
assetsConnection {
edges {
node {
id
name
symbol
decimals
source {
... on ERC20 {
contractAddress
}
}
}
}
}
}
`;
/**
* __useDepositsQuery__
*
* To run a query within a React component, call `useDepositsQuery` and pass it any options that fit your needs.
* When your component renders, `useDepositsQuery` 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 } = useDepositsQuery({
* variables: {
* },
* });
*/
export function useDepositsQuery(baseOptions?: Apollo.QueryHookOptions<DepositsQuery, DepositsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<DepositsQuery, DepositsQueryVariables>(DepositsDocument, options);
}
export function useDepositsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<DepositsQuery, DepositsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<DepositsQuery, DepositsQueryVariables>(DepositsDocument, options);
}
export type DepositsQueryHookResult = ReturnType<typeof useDepositsQuery>;
export type DepositsLazyQueryHookResult = ReturnType<typeof useDepositsLazyQuery>;
export type DepositsQueryResult = Apollo.QueryResult<DepositsQuery, DepositsQueryVariables>;
@@ -1,11 +1,10 @@
import { gql, useQuery } from '@apollo/client';
import { DepositManager } from '@vegaprotocol/deposits';
import { t } from '@vegaprotocol/react-helpers';
import { getEnabledAssets, t } 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 { assetsConnectionToAssets } from '@vegaprotocol/react-helpers';
import type { Deposits } from './__generated__/Deposits';
const DEPOSITS_QUERY = gql`
@@ -17,6 +16,7 @@ const DEPOSITS_QUERY = gql`
name
symbol
decimals
status
source {
... on ERC20 {
contractAddress
@@ -40,7 +40,7 @@ export const DepositContainer = () => {
skip: !keypair?.pub,
});
const assets = assetsConnectionToAssets(data?.assetsConnection);
const assets = getEnabledAssets(data);
return (
<AsyncRenderer<Deposits> data={data} loading={loading} error={error}>
@@ -22,9 +22,8 @@ export const NavigationDrawer = ({
const width = 'w-full md:w-auto md:min-w-[15%] shrink-0';
const position = 'absolute inset-0 h-full z-10 md:static';
const background = 'bg-black/50 dark:bg-white/50';
const border = 'border-r border-neutral-300 dark:border-neutral-700';
const flex = 'flex justify-end overflow-hidden';
const joinedClasses = [flex, width, position, background, border].join(' ');
const joinedClasses = [flex, width, position, background].join(' ');
const outerStyles = classNames(joinedClasses, {
visible: isMenuOpen,
@@ -12,7 +12,7 @@ const Header = () => {
} = useContext(LocalContext);
return (
<div
className="flex items-stretch pr-6 py-6 bg-black text-neutral-400 border-b border-neutral-300 dark:border-neutral-700"
className="flex items-stretch pr-6 py-6 bg-black text-neutral-400"
data-testid="header"
>
<Logo />
@@ -1,20 +1,19 @@
import React, { useCallback, useState } from 'react';
import type { ReactNode } from 'react';
import { t } from '@vegaprotocol/react-helpers';
import { Input } from '@vegaprotocol/ui-toolkit';
import type { InputProps } from '@vegaprotocol/ui-toolkit';
interface InputSetterProps {
buttonLabel?: string;
value: string | number;
isInputVisible?: boolean;
onValueChange?: () => string;
children?: ReactNode;
}
export const InputSetter = ({
buttonLabel = t('set'),
value = '',
isInputVisible = false,
onValueChange,
children,
...props
}: InputSetterProps & InputProps) => {
const [isInputToggled, setIsInputToggled] = useState(isInputVisible);
@@ -35,7 +34,7 @@ export const InputSetter = ({
return isInputToggled ? (
<div className="flex items-center">
<Input {...props} value={value} onKeyDown={onInputEnter} />
<Input {...props} onKeyDown={onInputEnter} />
<button
type="button"
className="no-underline hover:underline text-blue ml-2"
@@ -47,10 +46,10 @@ export const InputSetter = ({
) : (
<button
type="button"
className="no-underline hover:underline text-blue"
className="no-underline hover:underline text-blue py-1.5"
onClick={toggleInput}
>
{value}
{children || props.value}
</button>
);
};
@@ -8,7 +8,7 @@ interface TabBarProps {
export const TabBar = ({ className }: TabBarProps) => (
<div role="group" aria-label="Tab Bar Navigation Menu" className={className}>
<div role="presentation" className="py-[42px]" />
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-4 border-t border-neutral-300 dark:border-neutral-700">
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-4 border-t border-neutral-300 dark:border-neutral-600">
<Nav tabs className="flex justify-evenly items-center" />
</div>
</div>
@@ -0,0 +1,5 @@
subscription CandleLive($marketId: ID!) {
candles(marketId: $marketId, interval: INTERVAL_I1H) {
close
}
}
@@ -0,0 +1,39 @@
fragment SimpleMarketDataFields on ObservableMarketData {
marketId
marketState
}
query SimpleMarkets($CandleSince: String!) {
markets {
id
state
tradableInstrument {
instrument {
name
code
metadata {
tags
}
product {
__typename
... on Future {
quoteName
settlementAsset {
symbol
}
}
}
}
}
candles(interval: INTERVAL_I1H, since: $CandleSince) {
open
close
}
}
}
subscription SimpleMarketDataSub($marketIds: [ID!]!) {
marketsData(marketIds: $marketIds) {
...SimpleMarketDataFields
}
}
@@ -1,30 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
import { MarketState } from "@vegaprotocol/types";
// ====================================================
// GraphQL fragment: SimpleMarketDataFields
// ====================================================
export interface SimpleMarketDataFields_market {
__typename: "Market";
/**
* Market ID
*/
id: string;
/**
* Current state of the market
*/
state: MarketState;
}
export interface SimpleMarketDataFields {
__typename: "MarketData";
/**
* market ID of the associated mark price
*/
market: SimpleMarketDataFields_market;
}
@@ -9,29 +9,25 @@ import { MarketState } from "@vegaprotocol/types";
// GraphQL subscription operation: SimpleMarketDataSub
// ====================================================
export interface SimpleMarketDataSub_marketData_market {
__typename: "Market";
export interface SimpleMarketDataSub_marketsData {
__typename: "ObservableMarketData";
/**
* Market ID
* current state of the market
*/
id: string;
/**
* Current state of the market
*/
state: MarketState;
}
export interface SimpleMarketDataSub_marketData {
__typename: "MarketData";
marketState: MarketState;
/**
* market ID of the associated mark price
*/
market: SimpleMarketDataSub_marketData_market;
marketId: string;
}
export interface SimpleMarketDataSub {
/**
* Subscribe to the mark price changes
*/
marketData: SimpleMarketDataSub_marketData;
marketsData: SimpleMarketDataSub_marketsData[];
}
export interface SimpleMarketDataSubVariables {
marketIds: string[];
}
@@ -9,26 +9,6 @@ import { MarketState } from "@vegaprotocol/types";
// GraphQL query operation: SimpleMarkets
// ====================================================
export interface SimpleMarkets_markets_data_market {
__typename: "Market";
/**
* Market ID
*/
id: string;
/**
* Current state of the market
*/
state: MarketState;
}
export interface SimpleMarkets_markets_data {
__typename: "MarketData";
/**
* market ID of the associated mark price
*/
market: SimpleMarkets_markets_data_market;
}
export interface SimpleMarkets_markets_tradableInstrument_instrument_metadata {
__typename: "InstrumentMetadata";
/**
@@ -63,6 +43,10 @@ export interface SimpleMarkets_markets_tradableInstrument_instrument {
* A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string)
*/
code: string;
/**
* Full and fairly descriptive name for the instrument
*/
name: string;
/**
* Metadata for this instrument
*/
@@ -99,18 +83,10 @@ export interface SimpleMarkets_markets {
* Market ID
*/
id: string;
/**
* Market full name
*/
name: string;
/**
* Current state of the market
*/
state: MarketState;
/**
* marketData for the given market
*/
data: SimpleMarkets_markets_data | null;
/**
* An instance of, or reference to, a tradable instrument.
*/
@@ -0,0 +1,43 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type CandleLiveSubscriptionVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type CandleLiveSubscription = { __typename?: 'Subscription', candles: { __typename?: 'Candle', close: string } };
export const CandleLiveDocument = gql`
subscription CandleLive($marketId: ID!) {
candles(marketId: $marketId, interval: INTERVAL_I1H) {
close
}
}
`;
/**
* __useCandleLiveSubscription__
*
* To run a query within a React component, call `useCandleLiveSubscription` and pass it any options that fit your needs.
* When your component renders, `useCandleLiveSubscription` 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 subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useCandleLiveSubscription({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useCandleLiveSubscription(baseOptions: Apollo.SubscriptionHookOptions<CandleLiveSubscription, CandleLiveSubscriptionVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useSubscription<CandleLiveSubscription, CandleLiveSubscriptionVariables>(CandleLiveDocument, options);
}
export type CandleLiveSubscriptionHookResult = ReturnType<typeof useCandleLiveSubscription>;
export type CandleLiveSubscriptionResult = Apollo.SubscriptionResult<CandleLiveSubscription>;
@@ -0,0 +1,115 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type SimpleMarketDataFieldsFragment = { __typename?: 'ObservableMarketData', marketId: string, marketState: Types.MarketState };
export type SimpleMarketsQueryVariables = Types.Exact<{
CandleSince: Types.Scalars['String'];
}>;
export type SimpleMarketsQuery = { __typename?: 'Query', markets?: Array<{ __typename?: 'Market', id: string, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', symbol: string } } } }, candles?: Array<{ __typename?: 'Candle', open: string, close: string } | null> | null }> | null };
export type SimpleMarketDataSubSubscriptionVariables = Types.Exact<{
marketIds: Array<Types.Scalars['ID']> | Types.Scalars['ID'];
}>;
export type SimpleMarketDataSubSubscription = { __typename?: 'Subscription', marketsData: Array<{ __typename?: 'ObservableMarketData', marketId: string, marketState: Types.MarketState }> };
export const SimpleMarketDataFieldsFragmentDoc = gql`
fragment SimpleMarketDataFields on ObservableMarketData {
marketId
marketState
}
`;
export const SimpleMarketsDocument = gql`
query SimpleMarkets($CandleSince: String!) {
markets {
id
state
tradableInstrument {
instrument {
name
code
metadata {
tags
}
product {
__typename
... on Future {
quoteName
settlementAsset {
symbol
}
}
}
}
}
candles(interval: INTERVAL_I1H, since: $CandleSince) {
open
close
}
}
}
`;
/**
* __useSimpleMarketsQuery__
*
* To run a query within a React component, call `useSimpleMarketsQuery` and pass it any options that fit your needs.
* When your component renders, `useSimpleMarketsQuery` 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 } = useSimpleMarketsQuery({
* variables: {
* CandleSince: // value for 'CandleSince'
* },
* });
*/
export function useSimpleMarketsQuery(baseOptions: Apollo.QueryHookOptions<SimpleMarketsQuery, SimpleMarketsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<SimpleMarketsQuery, SimpleMarketsQueryVariables>(SimpleMarketsDocument, options);
}
export function useSimpleMarketsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<SimpleMarketsQuery, SimpleMarketsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<SimpleMarketsQuery, SimpleMarketsQueryVariables>(SimpleMarketsDocument, options);
}
export type SimpleMarketsQueryHookResult = ReturnType<typeof useSimpleMarketsQuery>;
export type SimpleMarketsLazyQueryHookResult = ReturnType<typeof useSimpleMarketsLazyQuery>;
export type SimpleMarketsQueryResult = Apollo.QueryResult<SimpleMarketsQuery, SimpleMarketsQueryVariables>;
export const SimpleMarketDataSubDocument = gql`
subscription SimpleMarketDataSub($marketIds: [ID!]!) {
marketsData(marketIds: $marketIds) {
...SimpleMarketDataFields
}
}
${SimpleMarketDataFieldsFragmentDoc}`;
/**
* __useSimpleMarketDataSubSubscription__
*
* To run a query within a React component, call `useSimpleMarketDataSubSubscription` and pass it any options that fit your needs.
* When your component renders, `useSimpleMarketDataSubSubscription` 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 subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useSimpleMarketDataSubSubscription({
* variables: {
* marketIds: // value for 'marketIds'
* },
* });
*/
export function useSimpleMarketDataSubSubscription(baseOptions: Apollo.SubscriptionHookOptions<SimpleMarketDataSubSubscription, SimpleMarketDataSubSubscriptionVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useSubscription<SimpleMarketDataSubSubscription, SimpleMarketDataSubSubscriptionVariables>(SimpleMarketDataSubDocument, options);
}
export type SimpleMarketDataSubSubscriptionHookResult = ReturnType<typeof useSimpleMarketDataSubSubscription>;
export type SimpleMarketDataSubSubscriptionResult = Apollo.SubscriptionResult<SimpleMarketDataSubSubscription>;
@@ -195,3 +195,5 @@ export const ROW_CLASS_RULES = {
'cursor-pointer': ({ data }: { data: SimpleMarkets_markets }) =>
IS_MARKET_TRADABLE(data || {}),
};
export const LARGE_SCREENS = ['xl', 'xxl'];
@@ -10,28 +10,15 @@ import type {
SimpleMarketDataSub_marketData,
} from './__generated__/SimpleMarketDataSub';
const MARKET_DATA_FRAGMENT = gql`
fragment SimpleMarketDataFields on MarketData {
market {
id
state
}
}
`;
export const MARKETS_QUERY = gql`
${MARKET_DATA_FRAGMENT}
query SimpleMarkets($CandleSince: String!) {
markets {
id
name
state
data {
...SimpleMarketDataFields
}
tradableInstrument {
instrument {
code
name
metadata {
tags
}
@@ -55,10 +42,10 @@ export const MARKETS_QUERY = gql`
`;
const MARKET_DATA_SUB = gql`
${MARKET_DATA_FRAGMENT}
subscription SimpleMarketDataSub {
marketData {
...SimpleMarketDataFields
subscription SimpleMarketDataSub($marketIds: [ID!]!) {
marketsData(marketIds: $marketIds) {
marketState
marketId
}
}
`;
@@ -78,7 +65,7 @@ const update = (
return produce(data, (draft) => {
const index = draft.findIndex((m) => m.id === delta.market.id);
if (index !== -1) {
draft[index].data = delta;
draft[index].state = delta.market.state;
}
// @TODO - else push new market to draft
});
@@ -6,17 +6,19 @@ import {
waitFor,
cleanup,
getAllByRole,
fireEvent,
} from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing';
import { BrowserRouter } from 'react-router-dom';
import { MarketState } from '@vegaprotocol/types';
import SimpleMarketList from './simple-market-list';
import { MARKETS_QUERY } from './data-provider';
import type {
SimpleMarkets_markets,
SimpleMarkets,
} from './__generated__/SimpleMarkets';
import { MarketState } from '@vegaprotocol/types';
import type { SimpleMarketDataSub_marketData } from './__generated__/SimpleMarketDataSub';
const mockedNavigate = jest.fn();
@@ -30,93 +32,85 @@ jest.mock('date-fns', () => ({
subDays: () => new Date('2022-06-02T11:11:21.721Z'),
}));
let updateMock: ({
delta,
}: {
delta: SimpleMarketDataSub_marketData;
}) => boolean;
let mockData = [
{
id: '1',
name: 'Market 1',
state: MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
product: {
settlementAsset: {
symbol: 'tUSD',
},
},
metadata: {
tags: [],
},
},
},
},
{
id: '2',
name: 'Market 2',
state: MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
product: {
settlementAsset: {
symbol: 'ETH',
},
},
metadata: {
tags: [],
},
},
},
},
] as unknown as SimpleMarkets_markets[];
const mockUseDataProvider = ({ update }: { update: () => boolean }) => {
updateMock = update;
return { data: mockData, loading: false, error: false };
};
jest.mock('@vegaprotocol/react-helpers', () => ({
...jest.requireActual('@vegaprotocol/react-helpers'),
useDataProvider: jest.fn((args) => mockUseDataProvider(args)),
}));
const mockIsTradable = jest.fn((_arg) => true);
jest.mock('../../constants', () => ({
...jest.requireActual('../../constants'),
IS_MARKET_TRADABLE: jest.fn((arg) => mockIsTradable(arg)),
}));
describe('SimpleMarketList', () => {
afterEach(() => {
jest.clearAllMocks();
cleanup();
});
it('should be properly renderer as empty', async () => {
const mocks: MockedResponse<SimpleMarkets> = {
request: {
query: MARKETS_QUERY,
variables: {
CandleSince: '2022-06-02T11:11:21.721Z',
},
const mocks: MockedResponse<SimpleMarkets> = {
request: {
query: MARKETS_QUERY,
variables: {
CandleSince: '2022-06-02T11:11:21.721Z',
},
result: {
data: { markets: [] },
},
};
await act(async () => {
render(
<MockedProvider mocks={[mocks]}>
<SimpleMarketList />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
await new Promise((resolve) => setTimeout(resolve, 0));
});
await waitFor(() => {
expect(screen.getByText('No data to display')).toBeInTheDocument();
});
});
},
result: {
data: { markets: mockData },
},
};
it('should be properly rendered with some data', async () => {
const data = [
{
id: '1',
data: {
market: {
state: MarketState.STATE_ACTIVE,
},
},
tradableInstrument: {
instrument: {
product: {
settlementAsset: {
symbol: 'tUSD',
},
},
metadata: {
tags: [],
},
},
},
},
{
id: '2',
data: {
market: {
state: MarketState.STATE_ACTIVE,
},
},
tradableInstrument: {
instrument: {
product: {
settlementAsset: {
symbol: 'ETH',
},
},
metadata: {
tags: [],
},
},
},
},
] as unknown as SimpleMarkets_markets[];
const mocks: MockedResponse<SimpleMarkets> = {
request: {
query: MARKETS_QUERY,
variables: {
CandleSince: '2022-06-02T11:11:21.721Z',
},
},
result: {
data: { markets: data },
},
};
await act(async () => {
render(
<MockedProvider mocks={[mocks]}>
@@ -136,4 +130,92 @@ describe('SimpleMarketList', () => {
expect(getAllByRole(container as HTMLDivElement, 'row')).toHaveLength(2);
});
});
it('update should return proper boolean value', async () => {
await act(async () => {
render(
<MockedProvider mocks={[mocks]}>
<SimpleMarketList />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
await new Promise((resolve) => setTimeout(resolve, 0));
});
await waitFor(() => {
expect(
document.querySelector('.ag-center-cols-container')
).toBeInTheDocument();
});
await expect(
updateMock({
delta: {
__typename: 'MarketData',
market: {
__typename: 'Market',
id: '2',
state: MarketState.STATE_ACTIVE,
},
},
})
).toEqual(true);
await expect(
updateMock({
delta: {
__typename: 'MarketData',
market: {
__typename: 'Market',
id: '2',
state: MarketState.STATE_SUSPENDED,
},
},
})
).toEqual(false);
});
it('click on row should be properly handled', async () => {
await act(async () => {
render(
<MockedProvider mocks={[mocks]}>
<SimpleMarketList />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
await new Promise((resolve) => setTimeout(resolve, 0));
});
await waitFor(() => {
expect(
document.querySelector('.ag-center-cols-container')
).toBeInTheDocument();
});
mockIsTradable.mockClear();
const container = document.querySelector('.ag-center-cols-container');
const firstRow = getAllByRole(container as HTMLDivElement, 'row')[0];
expect(firstRow).toHaveAttribute('row-id', '1');
fireEvent.click(firstRow);
await waitFor(() => {
expect(mockIsTradable).toHaveBeenCalledWith({
...mockData[0],
percentChange: '-',
});
expect(mockedNavigate).toHaveBeenCalledWith(`/trading/${mockData[0].id}`);
});
});
it('should be properly renderer as empty', async () => {
mockData = [];
await act(async () => {
render(
<MockedProvider mocks={[mocks]}>
<SimpleMarketList />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
await new Promise((resolve) => setTimeout(resolve, 0));
});
await waitFor(() => {
expect(screen.getByText('No data to display')).toBeInTheDocument();
});
});
});
@@ -45,7 +45,7 @@ export type RouterParams = Partial<{
}>;
const SimpleMarketList = () => {
const { isMobile } = useScreenDimensions();
const { isMobile, screenSize } = useScreenDimensions();
const navigate = useNavigate();
const params = useParams<RouterParams>();
const theme = useContext(ThemeContext);
@@ -80,7 +80,7 @@ const SimpleMarketList = () => {
useEffect(() => {
const statuses: Record<string, MarketState | ''> = {};
data?.forEach((market) => {
statuses[market.id] = market.data?.market.state || '';
statuses[market.id] = market.state || '';
});
statusesRef.current = statuses;
}, [data, statusesRef]);
@@ -129,6 +129,10 @@ const SimpleMarketList = () => {
[handleRowClicked]
);
const shouldSuppressHorizontalScroll = useMemo(() => {
return !isMobile && constants.LARGE_SCREENS.includes(screenSize);
}, [isMobile, screenSize]);
return (
<div className="h-full p-4 md:p-6 grid grid-rows-[min-content,1fr]">
<SimpleMarketToolbar data={data || []} />
@@ -156,6 +160,7 @@ const SimpleMarketList = () => {
suppressRowTransform
onCellKeyDown={onCellKeyDown}
tabToNextCell={onTabToNextCell}
suppressHorizontalScroll={shouldSuppressHorizontalScroll}
/>
</AsyncRenderer>
</div>
@@ -0,0 +1,36 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import type { MarketNames_markets } from '@vegaprotocol/deal-ticket';
import { MarketState } from '@vegaprotocol/types';
import MarketNameRenderer from './simple-market-renderer';
describe('SimpleMarketRenderer', () => {
const market = {
id: 'marketId',
state: MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
code: 'Market code',
name: 'Market Name',
product: {
quoteName: 'Quote name',
},
metadata: {
tags: null,
},
},
},
} as MarketNames_markets;
it('should properly render not mobile', () => {
render(<MarketNameRenderer market={market} isMobile={false} />);
expect(screen.getByText('Market Name')).toBeInTheDocument();
expect(screen.getByText('Quote name')).toBeInTheDocument();
});
it('should properly render mobile', () => {
render(<MarketNameRenderer market={market} isMobile={true} />);
expect(screen.getByText('Market code')).toBeInTheDocument();
expect(screen.getByText('Quote name')).toBeInTheDocument();
});
});
@@ -17,7 +17,9 @@ const MarketNameRenderer = ({ market, isMobile }: Props) => {
)}
/>
<div className="col-span-2 uppercase justify-start text-black dark:text-white text-ui-small md:text-market self-end">
{isMobile ? market.tradableInstrument.instrument.code : market.name}{' '}
{isMobile
? market.tradableInstrument.instrument.code
: market.tradableInstrument.instrument.name}{' '}
<SimpleMarketExpires
tags={market.tradableInstrument.instrument.metadata.tags}
/>
@@ -1,11 +1,35 @@
import React from 'react';
import { useLocation, useRoutes, BrowserRouter } from 'react-router-dom';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import {
useLocation,
useRoutes,
BrowserRouter,
useParams,
} from 'react-router-dom';
import {
render,
screen,
fireEvent,
waitFor,
act,
getAllByText,
} from '@testing-library/react';
import { MockedProvider } from '@apollo/react-testing';
import { MarketState } from '@vegaprotocol/types';
import SimpleMarketToolbar from './simple-market-toolbar';
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
import { markets as filterData } from './mocks/market-filters.json';
const mockedNavigate = jest.fn();
jest.mock('react-router-dom', () => {
const actualRouter = jest.requireActual('react-router-dom');
return {
...actualRouter,
useNavigate: () => mockedNavigate,
useParams: jest.fn(() => actualRouter.useParams()),
};
});
describe('SimpleMarketToolbar', () => {
const WrappedCompForTest = () => {
const routes = useRoutes([
@@ -60,9 +84,8 @@ describe('SimpleMarketToolbar', () => {
</>
);
};
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
});
it('should be properly rendered', async () => {
@@ -83,7 +106,7 @@ describe('SimpleMarketToolbar', () => {
expect(screen.getByTestId('market-assets-menu').children).toHaveLength(6);
});
fireEvent.click(screen.getByTestId('state-trigger'));
waitFor(() => {
await waitFor(() => {
expect(screen.getByRole('menu')).toBeInTheDocument();
expect(screen.getByRole('menu').children).toHaveLength(10);
});
@@ -104,7 +127,7 @@ describe('SimpleMarketToolbar', () => {
await waitFor(() => {
expect(screen.getByTestId('location-display')).toHaveTextContent(
'/markets/STATE_ACTIVE/Future'
`/markets/${MarketState.STATE_ACTIVE}/Future`
);
});
@@ -115,17 +138,91 @@ describe('SimpleMarketToolbar', () => {
);
await waitFor(() => {
expect(screen.getByTestId('location-display')).toHaveTextContent(
'/markets/STATE_ACTIVE/Future/tEURO'
`/markets/${MarketState.STATE_ACTIVE}/Future/tEURO`
);
});
fireEvent.click(screen.getByTestId('state-trigger'));
waitFor(() => {
await waitFor(() => {
expect(screen.getByRole('menu')).toBeInTheDocument();
fireEvent.click(screen.getByText('Pending'));
expect(screen.getByTestId('location-display')).toHaveTextContent(
'/markets/Pending/Future/tEURO'
});
const menu = screen.getByRole('menu');
const pending = getAllByText(menu, 'Pending')[0];
await act(() => {
fireEvent.click(pending);
});
await waitFor(() => {
expect(mockedNavigate).toHaveBeenCalledWith(
`/markets/${MarketState.STATE_PENDING}/Future/tEURO`
);
});
});
it('stateChange callback should work well', async () => {
(useParams as jest.Mock).mockImplementation(() => ({
asset: 'asset1',
product: 'product1',
state: 'state1',
}));
render(
<MockedProvider mocks={[]} addTypename={false}>
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
fireEvent.click(screen.getByTestId('state-trigger'));
await waitFor(() => {
expect(screen.getByRole('menu')).toBeInTheDocument();
});
const menu = screen.getByRole('menu');
const suspended = getAllByText(menu, 'Suspended')[0];
fireEvent.click(suspended);
expect(mockedNavigate).toHaveBeenCalledWith(
`/markets/${MarketState.STATE_SUSPENDED}/product1/asset1`
);
});
it('stateChange callback should call navigate with url with state only', async () => {
(useParams as jest.Mock).mockImplementation(() => ({}));
render(
<MockedProvider mocks={[]} addTypename={false}>
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
fireEvent.click(screen.getByTestId('state-trigger'));
await waitFor(() => {
expect(screen.getByRole('menu')).toBeInTheDocument();
});
const menu = screen.getByRole('menu');
const closed = getAllByText(menu, 'Closed')[0];
fireEvent.click(closed);
expect(mockedNavigate).toHaveBeenCalledWith(
`/markets/${MarketState.STATE_CLOSED}`
);
});
it('stateChange callback should call navigate with no asset', async () => {
(useParams as jest.Mock).mockImplementation(() => ({
asset: 'all',
state: 'state1',
}));
render(
<MockedProvider mocks={[]} addTypename={false}>
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
fireEvent.click(screen.getByTestId('state-trigger'));
await waitFor(() => {
expect(screen.getByRole('menu')).toBeInTheDocument();
});
const menu = screen.getByRole('menu');
const active = getAllByText(menu, 'Active')[0];
fireEvent.click(active);
expect(mockedNavigate).toHaveBeenCalledWith('/markets');
});
});
@@ -75,7 +75,7 @@ const SimpleMarketToolbar = ({ data }: Props) => {
);
return (
<div className="w-full max-w-full mb-4 font-alpha">
<div className="w-full max-w-full mb-2 md:mb-8 font-alpha">
<ul
ref={slideContRef}
className="grid grid-flow-col auto-cols-min gap-4 relative pb-2 mb-2"
@@ -121,12 +121,13 @@ const SimpleMarketToolbar = ({ data }: Props) => {
style={sliderStyles}
/>
</ul>
<div className="grid gap-8 pb-4 mt-6 md:grid-cols-[min-content,min-content,1fr]">
<div className="pb-8">
<DropdownMenu onOpenChange={(open) => setOpen(open)}>
<div className="grid gap-4 pb-2 mt-2 md:mt-6 md:grid-cols-[min-content,min-content,1fr]">
<div className="pb-2">
<DropdownMenu open={isOpen} onOpenChange={(open) => setOpen(open)}>
<DropdownMenuTrigger
className="mr-2 w-auto text-capMenu text-black dark:text-white"
data-testid="state-trigger"
onClick={() => setOpen(!isOpen)}
>
<div className="w-full justify-between uppercase inline-flex items-center justify-center box-border">
{STATES_FILTER.find(
@@ -148,7 +149,7 @@ const SimpleMarketToolbar = ({ data }: Props) => {
<DropdownMenuContent>
{STATES_FILTER.map(({ value, text }) => (
<DropdownMenuCheckboxItem
className="uppercase text-ui dark:text-white"
className="uppercase text-ui"
key={value}
checked={
value === params.state ||
@@ -170,7 +171,7 @@ const SimpleMarketToolbar = ({ data }: Props) => {
</div>
{activeNumber > 0 && (
<ul
className="md:gap-6 gap-4 pb-4 md:ml-2 flex flex-wrap"
className="md:gap-x-6 gap-x-4 gap-y-1 pb-2 md:ml-2 flex flex-wrap"
data-testid="market-assets-menu"
aria-label={t('Asset on the market')}
>
@@ -88,7 +88,7 @@ export const Stepper = ({ steps }: StepperProps) => {
'md:mt-0 font-alpha uppercase text-black dark:text-white',
{
'mt-2 text-md md:text-2xl': isActive,
'mt-4 text-sm md:text-lg md:ml-8': !isActive,
'mt-4 text-sm md:text-lg md:ml-2': !isActive,
}
)}
>
@@ -0,0 +1 @@
export * from './traffic-light';
@@ -0,0 +1,25 @@
import React from 'react';
import type { ReactNode } from 'react';
import classNames from 'classnames';
interface TrafficLightProps {
value: number;
q1: number;
q2: number;
children: ReactNode;
}
export const TrafficLight = ({
value,
q1,
q2,
children,
}: TrafficLightProps) => {
const slippageClassName = classNames({
'text-darkerGreen dark:text-lightGreen': value < q1,
'text-amber': value >= q1 && value < q2,
'text-vega-red': value >= q2,
});
return <div className={slippageClassName}>{children || value}</div>;
};
+1 -1
View File
@@ -10,7 +10,7 @@ export const TRADABLE_STATES = {
};
export const IS_MARKET_TRADABLE = (market: SimpleMarkets_markets) =>
Boolean((market.data?.market.state ?? '') in TRADABLE_STATES && market?.id);
Boolean((market.state ?? '') in TRADABLE_STATES && market?.id);
export const MARKET_STATES_MAP: Record<MarketState | '', string> = {
[MarketState.STATE_ACTIVE]: t('Active'),
@@ -0,0 +1,30 @@
query EstimateOrder(
$marketId: ID!
$partyId: ID!
$price: String
$size: String!
$side: Side!
$timeInForce: OrderTimeInForce!
$expiration: String
$type: OrderType!
) {
estimateOrder(
marketId: $marketId
partyId: $partyId
price: $price
size: $size
side: $side
timeInForce: $timeInForce
expiration: $expiration
type: $type
) {
fee {
makerFee
infrastructureFee
liquidityFee
}
marginLevels {
initialLevel
}
}
}
@@ -0,0 +1,8 @@
query MarketMarkPrice($marketId: ID!) {
market(id: $marketId) {
decimalPlaces
data {
markPrice
}
}
}
@@ -0,0 +1,25 @@
query MarketPositions($partyId: ID!) {
party(id: $partyId) {
id
accounts {
type
balance
asset {
decimals
}
market {
id
}
}
positionsConnection {
edges {
node {
openVolume
market {
id
}
}
}
}
}
}
@@ -0,0 +1,28 @@
query PartyMarketData($partyId: ID!) {
party(id: $partyId) {
id
accounts {
type
balance
asset {
id
decimals
}
market {
id
}
}
marginsConnection {
edges {
node {
market {
id
}
initialLevel
maintenanceLevel
searchLevel
}
}
}
}
}
@@ -103,7 +103,7 @@ export interface PartyMarketData_party {
/**
* Margin levels for a market
*/
marginsConnection: PartyMarketData_party_marginsConnection;
marginsConnection: PartyMarketData_party_marginsConnection | null;
}
export interface PartyMarketData {
@@ -91,7 +91,7 @@ export interface MarketPositions_party {
/**
* Trading positions relating to a party
*/
positionsConnection: MarketPositions_party_positionsConnection;
positionsConnection: MarketPositions_party_positionsConnection | null;
}
export interface MarketPositions {
@@ -0,0 +1,78 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type EstimateOrderQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
partyId: Types.Scalars['ID'];
price?: Types.InputMaybe<Types.Scalars['String']>;
size: Types.Scalars['String'];
side: Types.Side;
timeInForce: Types.OrderTimeInForce;
expiration?: Types.InputMaybe<Types.Scalars['String']>;
type: Types.OrderType;
}>;
export type EstimateOrderQuery = { __typename?: 'Query', estimateOrder: { __typename?: 'OrderEstimate', fee: { __typename?: 'TradeFee', makerFee: string, infrastructureFee: string, liquidityFee: string }, marginLevels: { __typename?: 'MarginLevels', initialLevel: string } } };
export const EstimateOrderDocument = gql`
query EstimateOrder($marketId: ID!, $partyId: ID!, $price: String, $size: String!, $side: Side!, $timeInForce: OrderTimeInForce!, $expiration: String, $type: OrderType!) {
estimateOrder(
marketId: $marketId
partyId: $partyId
price: $price
size: $size
side: $side
timeInForce: $timeInForce
expiration: $expiration
type: $type
) {
fee {
makerFee
infrastructureFee
liquidityFee
}
marginLevels {
initialLevel
}
}
}
`;
/**
* __useEstimateOrderQuery__
*
* To run a query within a React component, call `useEstimateOrderQuery` and pass it any options that fit your needs.
* When your component renders, `useEstimateOrderQuery` 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 } = useEstimateOrderQuery({
* variables: {
* marketId: // value for 'marketId'
* partyId: // value for 'partyId'
* price: // value for 'price'
* size: // value for 'size'
* side: // value for 'side'
* timeInForce: // value for 'timeInForce'
* expiration: // value for 'expiration'
* type: // value for 'type'
* },
* });
*/
export function useEstimateOrderQuery(baseOptions: Apollo.QueryHookOptions<EstimateOrderQuery, EstimateOrderQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<EstimateOrderQuery, EstimateOrderQueryVariables>(EstimateOrderDocument, options);
}
export function useEstimateOrderLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<EstimateOrderQuery, EstimateOrderQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<EstimateOrderQuery, EstimateOrderQueryVariables>(EstimateOrderDocument, options);
}
export type EstimateOrderQueryHookResult = ReturnType<typeof useEstimateOrderQuery>;
export type EstimateOrderLazyQueryHookResult = ReturnType<typeof useEstimateOrderLazyQuery>;
export type EstimateOrderQueryResult = Apollo.QueryResult<EstimateOrderQuery, EstimateOrderQueryVariables>;
@@ -0,0 +1,51 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketMarkPriceQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type MarketMarkPriceQuery = { __typename?: 'Query', market?: { __typename?: 'Market', decimalPlaces: number, data?: { __typename?: 'MarketData', markPrice: string } | null } | null };
export const MarketMarkPriceDocument = gql`
query MarketMarkPrice($marketId: ID!) {
market(id: $marketId) {
decimalPlaces
data {
markPrice
}
}
}
`;
/**
* __useMarketMarkPriceQuery__
*
* To run a query within a React component, call `useMarketMarkPriceQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketMarkPriceQuery` 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 } = useMarketMarkPriceQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useMarketMarkPriceQuery(baseOptions: Apollo.QueryHookOptions<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>(MarketMarkPriceDocument, options);
}
export function useMarketMarkPriceLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>(MarketMarkPriceDocument, options);
}
export type MarketMarkPriceQueryHookResult = ReturnType<typeof useMarketMarkPriceQuery>;
export type MarketMarkPriceLazyQueryHookResult = ReturnType<typeof useMarketMarkPriceLazyQuery>;
export type MarketMarkPriceQueryResult = Apollo.QueryResult<MarketMarkPriceQuery, MarketMarkPriceQueryVariables>;
@@ -0,0 +1,68 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketPositionsQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type MarketPositionsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accounts?: Array<{ __typename?: 'Account', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', decimals: number }, market?: { __typename?: 'Market', id: string } | null }> | null, positionsConnection?: { __typename?: 'PositionConnection', edges?: Array<{ __typename?: 'PositionEdge', node: { __typename?: 'Position', openVolume: string, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
export const MarketPositionsDocument = gql`
query MarketPositions($partyId: ID!) {
party(id: $partyId) {
id
accounts {
type
balance
asset {
decimals
}
market {
id
}
}
positionsConnection {
edges {
node {
openVolume
market {
id
}
}
}
}
}
}
`;
/**
* __useMarketPositionsQuery__
*
* To run a query within a React component, call `useMarketPositionsQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketPositionsQuery` 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 } = useMarketPositionsQuery({
* variables: {
* partyId: // value for 'partyId'
* },
* });
*/
export function useMarketPositionsQuery(baseOptions: Apollo.QueryHookOptions<MarketPositionsQuery, MarketPositionsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketPositionsQuery, MarketPositionsQueryVariables>(MarketPositionsDocument, options);
}
export function useMarketPositionsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketPositionsQuery, MarketPositionsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketPositionsQuery, MarketPositionsQueryVariables>(MarketPositionsDocument, options);
}
export type MarketPositionsQueryHookResult = ReturnType<typeof useMarketPositionsQuery>;
export type MarketPositionsLazyQueryHookResult = ReturnType<typeof useMarketPositionsLazyQuery>;
export type MarketPositionsQueryResult = Apollo.QueryResult<MarketPositionsQuery, MarketPositionsQueryVariables>;
@@ -0,0 +1,71 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type PartyMarketDataQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type PartyMarketDataQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, accounts?: Array<{ __typename?: 'Account', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, decimals: number }, market?: { __typename?: 'Market', id: string } | null }> | null, marginsConnection?: { __typename?: 'MarginConnection', edges?: Array<{ __typename?: 'MarginEdge', node: { __typename?: 'MarginLevels', initialLevel: string, maintenanceLevel: string, searchLevel: string, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
export const PartyMarketDataDocument = gql`
query PartyMarketData($partyId: ID!) {
party(id: $partyId) {
id
accounts {
type
balance
asset {
id
decimals
}
market {
id
}
}
marginsConnection {
edges {
node {
market {
id
}
initialLevel
maintenanceLevel
searchLevel
}
}
}
}
}
`;
/**
* __usePartyMarketDataQuery__
*
* To run a query within a React component, call `usePartyMarketDataQuery` and pass it any options that fit your needs.
* When your component renders, `usePartyMarketDataQuery` 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 } = usePartyMarketDataQuery({
* variables: {
* partyId: // value for 'partyId'
* },
* });
*/
export function usePartyMarketDataQuery(baseOptions: Apollo.QueryHookOptions<PartyMarketDataQuery, PartyMarketDataQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<PartyMarketDataQuery, PartyMarketDataQueryVariables>(PartyMarketDataDocument, options);
}
export function usePartyMarketDataLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyMarketDataQuery, PartyMarketDataQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<PartyMarketDataQuery, PartyMarketDataQueryVariables>(PartyMarketDataDocument, options);
}
export type PartyMarketDataQueryHookResult = ReturnType<typeof usePartyMarketDataQuery>;
export type PartyMarketDataLazyQueryHookResult = ReturnType<typeof usePartyMarketDataLazyQuery>;
export type PartyMarketDataQueryResult = Apollo.QueryResult<PartyMarketDataQuery, PartyMarketDataQueryVariables>;
@@ -22,7 +22,7 @@ const useColumnDefinitions = ({ isMobile }: Props) => {
headerName: t('Markets'),
headerClass: 'uppercase',
minWidth: isMobile ? 160 : 350,
field: 'name',
field: 'tradableInstrument.instrument.name',
cellClass: 'overflow-visible',
cellRenderer: ({ data }: { data: SimpleMarketsType }) => (
<MarketNameRenderer market={data} isMobile={isMobile} />
@@ -93,13 +93,13 @@ const useColumnDefinitions = ({ isMobile }: Props) => {
{
colId: 'status',
headerName: t('Status'),
field: 'data.market.state',
field: 'state',
headerClass: 'uppercase',
minWidth: 100,
cellRenderer: ({ data }: { data: SimpleMarkets_markets }) => (
<div className="uppercase flex h-full items-center justify-center">
<div className="border text-center px-2 md:px-8 leading-4 md:leading-6">
{MARKET_STATES_MAP[data.data?.market.state || '']}
<div className="border text-center px-2 md:px-6 leading-4 md:leading-6">
{MARKET_STATES_MAP[data.state || '']}
</div>
</div>
),
@@ -27,7 +27,7 @@ const useMarketsFilterData = (
: params.state
? params.state
: MarketState.STATE_ACTIVE;
if (state && state !== item.data?.market.state) {
if (state && state !== item.state) {
return false;
}
return true;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "__generated__"],
"ignorePatterns": ["!**/*", "__generated__", "__generated___"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
@@ -2,6 +2,12 @@ import { render, screen } from '@testing-library/react';
import { Header } from './header';
import { MemoryRouter } from 'react-router-dom';
jest.mock('@vegaprotocol/environment', () => ({
NetworkSwitcher: () => (
<div data-testid="network-switcher">NetworkSwitcher</div>
),
}));
jest.mock('../search', () => ({
Search: () => <div data-testid="search">OrderList</div>,
}));
@@ -25,4 +31,10 @@ describe('Header', () => {
expect(screen.getByTestId('search')).toBeInTheDocument();
});
it('should render network switcher', () => {
render(renderComponent());
expect(screen.getByTestId('network-switcher')).toBeInTheDocument();
});
});
@@ -5,6 +5,7 @@ import { t } from '@vegaprotocol/react-helpers';
import { Search } from '../search';
import { Routes } from '../../routes/route-names';
import type { Dispatch, SetStateAction } from 'react';
import { NetworkSwitcher } from '@vegaprotocol/environment';
interface ThemeToggleProps {
theme: 'light' | 'dark';
@@ -27,14 +28,17 @@ export const Header = ({
);
return (
<header className={headerClasses}>
<Link to={Routes.HOME}>
<h1
className="text-3xl font-alpha uppercase calt mb-0"
data-testid="explorer-header"
>
{t('Vega Explorer')}
</h1>
</Link>
<div className="flex h-full items-center sm:items-stretch gap-4">
<Link to={Routes.HOME}>
<h1
className="text-3xl font-alpha uppercase calt mb-0"
data-testid="explorer-header"
>
{t('Vega Explorer')}
</h1>
</Link>
<NetworkSwitcher />
</div>
<button
data-testid="open-menu"
className="md:hidden"
@@ -0,0 +1,27 @@
query AssetsQuery {
assetsConnection {
edges {
node {
id
name
symbol
decimals
source {
... on ERC20 {
contractAddress
}
... on BuiltinAsset {
maxFaucetAmountMint
}
}
infrastructureFeeAccount {
type
balance
market {
id
}
}
}
}
}
}
@@ -96,5 +96,5 @@ export interface AssetsQuery {
/**
* The list of all assets in use in the Vega network or the specified asset if ID is provided
*/
assetsConnection: AssetsQuery_assetsConnection;
assetsConnection: AssetsQuery_assetsConnection | null;
}
@@ -0,0 +1,67 @@
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?: 'Account', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | 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,5 +1,6 @@
import compact from 'lodash/compact';
import { gql, useQuery } from '@apollo/client';
import { assetsConnectionToAssets, t } from '@vegaprotocol/react-helpers';
import { t } from '@vegaprotocol/react-helpers';
import React from 'react';
import { RouteTitle } from '../../components/route-title';
import { SubHeading } from '../../components/sub-heading';
@@ -39,7 +40,7 @@ export const ASSETS_QUERY = gql`
const Assets = () => {
const { data } = useQuery<AssetsQuery>(ASSETS_QUERY);
const assets = assetsConnectionToAssets(data?.assetsConnection);
const assets = compact(data?.assetsConnection?.edges).map((e) => e.node);
return (
<section>
@@ -0,0 +1,74 @@
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
}
}
}
}
}
@@ -9,7 +9,23 @@ import { ProposalState, ProposalRejectionReason, VoteValue } from "@vegaprotocol
// GraphQL query operation: ProposalsQuery
// ====================================================
export interface ProposalsQuery_proposals_party {
export interface ProposalsQuery_proposalsConnection_edges_node_rationale {
__typename: "ProposalRationale";
/**
* Title to be used to give a short description of the proposal in lists.
* This is to be between 0 and 100 unicode characters.
* This is mandatory for all proposals.
*/
title: string;
/**
* Description to show a short title / something in case the link goes offline.
* This is to be between 0 and 20k unicode characters.
* This is mandatory for all proposals.
*/
description: string;
}
export interface ProposalsQuery_proposalsConnection_edges_node_party {
__typename: "Party";
/**
* Party identifier
@@ -17,11 +33,11 @@ export interface ProposalsQuery_proposals_party {
id: string;
}
export interface ProposalsQuery_proposals_terms_change_UpdateAsset {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateAsset {
__typename: "UpdateAsset" | "NewFreeform";
}
export interface ProposalsQuery_proposals_terms_change_NewMarket_instrument {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket_instrument {
__typename: "InstrumentConfiguration";
/**
* Full and fairly descriptive name for the instrument
@@ -29,20 +45,20 @@ export interface ProposalsQuery_proposals_terms_change_NewMarket_instrument {
name: string;
}
export interface ProposalsQuery_proposals_terms_change_NewMarket {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket {
__typename: "NewMarket";
/**
* New market instrument configuration
*/
instrument: ProposalsQuery_proposals_terms_change_NewMarket_instrument;
instrument: ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket_instrument;
}
export interface ProposalsQuery_proposals_terms_change_UpdateMarket {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateMarket {
__typename: "UpdateMarket";
marketId: string;
}
export interface ProposalsQuery_proposals_terms_change_NewAsset_source_BuiltinAsset {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_BuiltinAsset {
__typename: "BuiltinAsset";
/**
* Maximum amount that can be requested by a party through the built-in asset faucet at a time
@@ -50,7 +66,7 @@ export interface ProposalsQuery_proposals_terms_change_NewAsset_source_BuiltinAs
maxFaucetAmountMint: string;
}
export interface ProposalsQuery_proposals_terms_change_NewAsset_source_ERC20 {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_ERC20 {
__typename: "ERC20";
/**
* The address of the ERC20 contract
@@ -58,9 +74,9 @@ export interface ProposalsQuery_proposals_terms_change_NewAsset_source_ERC20 {
contractAddress: string;
}
export type ProposalsQuery_proposals_terms_change_NewAsset_source = ProposalsQuery_proposals_terms_change_NewAsset_source_BuiltinAsset | ProposalsQuery_proposals_terms_change_NewAsset_source_ERC20;
export type ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source = ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_BuiltinAsset | ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_ERC20;
export interface ProposalsQuery_proposals_terms_change_NewAsset {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset {
__typename: "NewAsset";
/**
* The symbol of the asset (e.g: GBP)
@@ -69,10 +85,10 @@ export interface ProposalsQuery_proposals_terms_change_NewAsset {
/**
* The source of the new asset
*/
source: ProposalsQuery_proposals_terms_change_NewAsset_source;
source: ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source;
}
export interface ProposalsQuery_proposals_terms_change_UpdateNetworkParameter_networkParameter {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter_networkParameter {
__typename: "NetworkParameter";
/**
* The name of the network parameter
@@ -84,14 +100,14 @@ export interface ProposalsQuery_proposals_terms_change_UpdateNetworkParameter_ne
value: string;
}
export interface ProposalsQuery_proposals_terms_change_UpdateNetworkParameter {
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter {
__typename: "UpdateNetworkParameter";
networkParameter: ProposalsQuery_proposals_terms_change_UpdateNetworkParameter_networkParameter;
networkParameter: ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter_networkParameter;
}
export type ProposalsQuery_proposals_terms_change = ProposalsQuery_proposals_terms_change_UpdateAsset | ProposalsQuery_proposals_terms_change_NewMarket | ProposalsQuery_proposals_terms_change_UpdateMarket | ProposalsQuery_proposals_terms_change_NewAsset | ProposalsQuery_proposals_terms_change_UpdateNetworkParameter;
export type ProposalsQuery_proposalsConnection_edges_node_terms_change = ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateAsset | ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket | ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateMarket | ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset | ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter;
export interface ProposalsQuery_proposals_terms {
export interface ProposalsQuery_proposalsConnection_edges_node_terms {
__typename: "ProposalTerms";
/**
* RFC3339Nano time and date when voting closes for this proposal.
@@ -107,18 +123,18 @@ export interface ProposalsQuery_proposals_terms {
/**
* Actual change being introduced by the proposal - action the proposal triggers if passed and enacted.
*/
change: ProposalsQuery_proposals_terms_change;
change: ProposalsQuery_proposalsConnection_edges_node_terms_change;
}
export interface ProposalsQuery_proposals_votes_yes_votes_party_stake {
__typename: "PartyStake";
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party_stakingSummary {
__typename: "StakingSummary";
/**
* The stake currently available for the party
*/
currentStakeAvailable: string;
}
export interface ProposalsQuery_proposals_votes_yes_votes_party {
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party {
__typename: "Party";
/**
* Party identifier
@@ -127,10 +143,10 @@ export interface ProposalsQuery_proposals_votes_yes_votes_party {
/**
* The staking information for this Party
*/
stake: ProposalsQuery_proposals_votes_yes_votes_party_stake;
stakingSummary: ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party_stakingSummary;
}
export interface ProposalsQuery_proposals_votes_yes_votes {
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes {
__typename: "Vote";
/**
* The vote value cast
@@ -139,14 +155,14 @@ export interface ProposalsQuery_proposals_votes_yes_votes {
/**
* The party casting the vote
*/
party: ProposalsQuery_proposals_votes_yes_votes_party;
party: ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party;
/**
* RFC3339Nano time and date when the vote reached Vega network
*/
datetime: string;
}
export interface ProposalsQuery_proposals_votes_yes {
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes {
__typename: "ProposalVoteSide";
/**
* Total number of governance tokens from the votes cast for this side
@@ -159,18 +175,18 @@ export interface ProposalsQuery_proposals_votes_yes {
/**
* All votes cast for this side
*/
votes: ProposalsQuery_proposals_votes_yes_votes[] | null;
votes: ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes[] | null;
}
export interface ProposalsQuery_proposals_votes_no_votes_party_stake {
__typename: "PartyStake";
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party_stakingSummary {
__typename: "StakingSummary";
/**
* The stake currently available for the party
*/
currentStakeAvailable: string;
}
export interface ProposalsQuery_proposals_votes_no_votes_party {
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party {
__typename: "Party";
/**
* Party identifier
@@ -179,10 +195,10 @@ export interface ProposalsQuery_proposals_votes_no_votes_party {
/**
* The staking information for this Party
*/
stake: ProposalsQuery_proposals_votes_no_votes_party_stake;
stakingSummary: ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party_stakingSummary;
}
export interface ProposalsQuery_proposals_votes_no_votes {
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes {
__typename: "Vote";
/**
* The vote value cast
@@ -191,14 +207,14 @@ export interface ProposalsQuery_proposals_votes_no_votes {
/**
* The party casting the vote
*/
party: ProposalsQuery_proposals_votes_no_votes_party;
party: ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party;
/**
* RFC3339Nano time and date when the vote reached Vega network
*/
datetime: string;
}
export interface ProposalsQuery_proposals_votes_no {
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no {
__typename: "ProposalVoteSide";
/**
* Total number of governance tokens from the votes cast for this side
@@ -211,27 +227,31 @@ export interface ProposalsQuery_proposals_votes_no {
/**
* All votes cast for this side
*/
votes: ProposalsQuery_proposals_votes_no_votes[] | null;
votes: ProposalsQuery_proposalsConnection_edges_node_votes_no_votes[] | null;
}
export interface ProposalsQuery_proposals_votes {
export interface ProposalsQuery_proposalsConnection_edges_node_votes {
__typename: "ProposalVotes";
/**
* Yes votes cast for this proposal
*/
yes: ProposalsQuery_proposals_votes_yes;
yes: ProposalsQuery_proposalsConnection_edges_node_votes_yes;
/**
* No votes cast for this proposal
*/
no: ProposalsQuery_proposals_votes_no;
no: ProposalsQuery_proposalsConnection_edges_node_votes_no;
}
export interface ProposalsQuery_proposals {
export interface ProposalsQuery_proposalsConnection_edges_node {
__typename: "Proposal";
/**
* Proposal ID that is filled by Vega once proposal reaches the network
*/
id: string | null;
/**
* Rationale behind the proposal
*/
rationale: ProposalsQuery_proposalsConnection_edges_node_rationale;
/**
* A UUID reference to aid tracking proposals on Vega
*/
@@ -251,20 +271,36 @@ export interface ProposalsQuery_proposals {
/**
* Party that prepared the proposal
*/
party: ProposalsQuery_proposals_party;
party: ProposalsQuery_proposalsConnection_edges_node_party;
/**
* Terms of the proposal
*/
terms: ProposalsQuery_proposals_terms;
terms: ProposalsQuery_proposalsConnection_edges_node_terms;
/**
* Votes cast for this proposal
*/
votes: ProposalsQuery_proposals_votes;
votes: ProposalsQuery_proposalsConnection_edges_node_votes;
}
export interface ProposalsQuery_proposalsConnection_edges {
__typename: "ProposalEdge";
/**
* The proposal data
*/
node: ProposalsQuery_proposalsConnection_edges_node;
}
export interface ProposalsQuery_proposalsConnection {
__typename: "ProposalsConnection";
/**
* List of proposals available for the connection
*/
edges: (ProposalsQuery_proposalsConnection_edges | null)[] | null;
}
export interface ProposalsQuery {
/**
* All governance proposals in the Vega network
*/
proposals: ProposalsQuery_proposals[] | null;
proposalsConnection: ProposalsQuery_proposalsConnection | null;
}
@@ -0,0 +1,114 @@
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,98 +1,94 @@
import compact from 'lodash/compact';
import { gql, useQuery } from '@apollo/client';
import { t } from '@vegaprotocol/react-helpers';
import React from 'react';
import { RouteTitle } from '../../components/route-title';
import { SubHeading } from '../../components/sub-heading';
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
import { getProposals } from '@vegaprotocol/governance';
import type {
ProposalsQuery,
ProposalsQuery_proposals_terms_change,
ProposalsQuery_proposalsConnection_edges_node,
} from './__generated__/ProposalsQuery';
export function getProposalName(change: ProposalsQuery_proposals_terms_change) {
if (change.__typename === 'NewAsset') {
return t(`New asset: ${change.symbol}`);
} else if (change.__typename === 'NewMarket') {
return t(`New market: ${change.instrument.name}`);
} else if (change.__typename === 'UpdateMarket') {
return t(`Update market: ${change.marketId}`);
} else if (change.__typename === 'UpdateNetworkParameter') {
return t(`Update network: ${change.networkParameter.key}`);
}
return t('Unknown proposal');
}
const PROPOSAL_QUERY = gql`
const PROPOSALS_QUERY = gql`
query ProposalsQuery {
proposals {
id
reference
state
datetime
rejectionReason
party {
id
}
terms {
closingDatetime
enactmentDatetime
change {
... on NewMarket {
instrument {
name
}
proposalsConnection {
edges {
node {
id
rationale {
title
description
}
... on UpdateMarket {
marketId
reference
state
datetime
rejectionReason
party {
id
}
... on NewAsset {
__typename
symbol
source {
... on BuiltinAsset {
maxFaucetAmountMint
terms {
closingDatetime
enactmentDatetime
change {
... on NewMarket {
instrument {
name
}
}
... on ERC20 {
contractAddress
... on UpdateMarket {
marketId
}
... on NewAsset {
__typename
symbol
source {
... on BuiltinAsset {
maxFaucetAmountMint
}
... on ERC20 {
contractAddress
}
}
}
... on UpdateNetworkParameter {
networkParameter {
key
value
}
}
}
}
... on UpdateNetworkParameter {
networkParameter {
key
value
}
}
}
}
votes {
yes {
totalTokens
totalNumber
votes {
value
party {
id
stake {
currentStakeAvailable
yes {
totalTokens
totalNumber
votes {
value
party {
id
stakingSummary {
currentStakeAvailable
}
}
datetime
}
}
datetime
}
}
no {
totalTokens
totalNumber
votes {
value
party {
id
stake {
currentStakeAvailable
no {
totalTokens
totalNumber
votes {
value
party {
id
stakingSummary {
currentStakeAvailable
}
}
datetime
}
}
datetime
}
}
}
@@ -101,19 +97,25 @@ const PROPOSAL_QUERY = gql`
`;
const Governance = () => {
const { data } = useQuery<ProposalsQuery>(PROPOSAL_QUERY, {
const { data } = useQuery<ProposalsQuery>(PROPOSALS_QUERY, {
errorPolicy: 'ignore',
});
const proposals = compact(data?.proposalsConnection?.edges).map(
(e) => e.node
);
if (!data) return null;
return (
<section>
<RouteTitle data-testid="governance-header">
{t('Governance Proposals')}
</RouteTitle>
{data.proposals?.map((p) => (
{proposals.map((p) => (
<React.Fragment key={p.id}>
<SubHeading>{getProposalName(p.terms.change)}</SubHeading>
<SubHeading>
{p.rationale.title || p.rationale.description}
</SubHeading>
<SyntaxHighlighter data={p} />
</React.Fragment>
))}
@@ -0,0 +1,133 @@
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
}
}
}
}
@@ -465,10 +465,6 @@ export interface MarketsQuery_markets {
* Market ID
*/
id: string;
/**
* Market full name
*/
name: string;
/**
* Fees related data
*/
@@ -0,0 +1,173 @@
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?: 'Account', 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?: 'Account', 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>;
@@ -11,7 +11,6 @@ const MARKETS_QUERY = gql`
query MarketsQuery {
markets {
id
name
fees {
factors {
makerFee
@@ -154,7 +153,9 @@ const Markets = () => {
{data?.markets
? data.markets.map((m) => (
<React.Fragment key={m.id}>
<SubHeading data-testid="markets-header">{m.name}</SubHeading>
<SubHeading data-testid="markets-header">
{m.tradableInstrument.instrument.name}
</SubHeading>
<SyntaxHighlighter data={m} />
</React.Fragment>
))
@@ -0,0 +1,6 @@
query NetworkParametersQuery {
networkParameters {
key
value
}
}
@@ -0,0 +1,46 @@
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>;
@@ -0,0 +1,22 @@
query OracleSpecs {
oracleSpecs {
status
id
createdAt
updatedAt
pubKeys
filters {
key {
name
type
}
conditions {
value
operator
}
}
data {
pubKeys
}
}
}
@@ -0,0 +1,62 @@
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', oracleSpecs?: Array<{ __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 };
export const OracleSpecsDocument = gql`
query OracleSpecs {
oracleSpecs {
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>;
@@ -0,0 +1,32 @@
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
}
}
}
@@ -0,0 +1,75 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type 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?: 'Account', 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>;
@@ -0,0 +1,23 @@
query NodesQuery {
nodes {
id
name
infoUrl
avatarUrl
pubkey
tmPubkey
ethereumAddress
location
stakedByOperator
stakedByDelegates
stakedTotal
pendingStake
epochData {
total
offline
online
}
status
name
}
}
@@ -0,0 +1,63 @@
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
name
}
}
`;
/**
* __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>;
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -89,7 +89,7 @@
"tranche_end": "2022-10-12T00:53:20.000Z",
"total_added": "1010.000000000000000001",
"total_removed": "668.4622323651",
"locked_amount": "101.09377473363779510010009284627092851",
"locked_amount": "81.0314903602232870000802291983764587",
"deposits": [
{
"amount": "1000",
@@ -3,7 +3,7 @@ const navHome = '[href="/"]';
const navVesting = '[href="/vesting"]';
const navStaking = '[href="/staking"]';
const navRewards = '[href="/rewards"]';
const navWithdraw = '[href="/withdraw"]';
const navWithdraw = '[href="/withdrawals"]';
const navGovernance = '[href="/governance"]';
const tokenDetailsTable = '.token-details';
@@ -1,18 +1,17 @@
const connectToVegaBtn = '[data-testid="connect-to-vega-wallet-btn"]';
const warning = '[data-testid="callout"]';
context('Withdraw Page - verify elements on page', function () {
before('navigate to withdraw page', function () {
cy.visit('/').navigate_to('withdraw');
before('navigate to withdrawals page', function () {
cy.visit('/').navigate_to('withdrawals');
});
describe('with wallets disconnected', function () {
it('should have withdraw tab highlighted', function () {
cy.verify_tab_highlighted('withdraw');
cy.verify_tab_highlighted('withdrawals');
});
it('should have WITHDRAW header visible', function () {
cy.verify_page_header('Withdraw');
cy.verify_page_header('Withdrawals');
});
it('should have connect Vega wallet button', function () {
@@ -20,9 +19,5 @@ context('Withdraw Page - verify elements on page', function () {
.should('be.visible')
.and('have.text', 'Connect Vega wallet');
});
it('should have withdraw information box', function () {
cy.get(warning).should('be.visible');
});
});
});
@@ -12,7 +12,7 @@ const navigation = {
vesting: '[href="/vesting"]',
staking: '[href="/staking"]',
rewards: '[href="/rewards"]',
withdraw: '[href="/withdraw"]',
withdrawals: '[href="/withdrawals"]',
governance: '[href="/governance"]',
pageSpinner: '[data-testid="splash-loader"]',
};
+2 -2
View File
@@ -1,10 +1,10 @@
# App configuration variables
NX_VEGA_ENV=TESTNET
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_VEGA_REST=https://api.n11.testnet.vega.xyz
NX_VEGA_REST=https://api.n07.testnet.vega.xyz
NX_FAIRGROUND=false
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
+1 -1
View File
@@ -1,5 +1,5 @@
# App configuration variables
NX_VEGA_ENV=TESTNET
NX_VEGA_ENV=CUSTOM
NX_ETHEREUM_PROVIDER_URL=http://localhost:8545
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_FAIRGROUND=false
+1 -1
View File
@@ -1,6 +1,6 @@
{
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "__generated__"],
"ignorePatterns": ["!**/*", "__generated__", "__generated___"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+43
View File
@@ -0,0 +1,43 @@
extend type Delegation {
"The amount field formatted by the client"
amountFormatted: String!
}
extend type PartyStake {
"The currently available stake formatted by the client"
currentStakeAvailableFormatted: String!
}
extend type NodeData {
"The total staked field formatted by the client"
stakedTotalFormatted: String!
}
extend type Node {
"The total staked field formatted by the client"
stakedTotalFormatted: String!
"The pending staked field formatted by the client"
pendingStakeFormatted: String!
"The stakes by operator field formatted by the client"
stakedByOperatorFormatted: String!
"The stakes by delegates field formatted by the client"
stakedByDelegatesFormatted: String!
}
extend type Reward {
"The amount field formatted by the client"
amountFormatted: String!
}
extend type RewardPerAssetDetail {
"The total amount field formatted by the client"
totalAmountFormatted: String!
}
extend type Account {
"The balance field formatted by the client"
balanceFormatted: String!
}
+1 -1
View File
@@ -224,7 +224,7 @@ const NavLinks = ({
{ route: Routes.VESTING, text: t('Vesting') },
{ route: Routes.STAKING, text: t('Staking') },
{ route: Routes.REWARDS, text: t('Rewards') },
{ route: Routes.WITHDRAW, text: t('Withdraw') },
{ route: Routes.WITHDRAWALS, text: t('Withdraw') },
{ route: Routes.GOVERNANCE, text: t('Governance') },
];
const navClasses = classNames('flex', {
@@ -37,7 +37,7 @@ export const AmountInput = ({
}) => {
const { t } = useTranslation();
return (
<div className="flex">
<div className="flex gap-4">
<div className="flex-1">
<Input
data-testid="token-amount-input"
@@ -61,14 +61,12 @@ export const AmountInput = ({
/>
</div>
{maximum && (
<div className="flex flex-col justify-center p-8 h-28 my-0 mx-8">
<ButtonLink
onClick={() => setAmount(maximum.toString())}
data-testid="token-amount-use-maximum"
>
{t('Use maximum')}
</ButtonLink>
</div>
<ButtonLink
onClick={() => setAmount(maximum.toString())}
data-testid="token-amount-use-maximum"
>
{t('Use maximum')}
</ButtonLink>
)}
</div>
);
@@ -169,7 +167,7 @@ export const TokenInput = ({
} else if (requireApproval) {
approveContent = (
<Callout iconName="tick" intent={Intent.Success}>
<p>{`${currency} are approved for staking`}</p>
<p className="mb-0">{`${currency} are approved for staking`}</p>
</Callout>
);
}
@@ -188,7 +186,7 @@ export const TokenInput = ({
currency={currency}
/>
</FormGroup>
{approveContent ? <div className="mb-24">{approveContent}</div> : null}
{approveContent ? <div className="mb-4">{approveContent}</div> : null}
<Button
data-testid="token-input-submit-button"
fill={true}
@@ -0,0 +1,37 @@
query Delegations($partyId: ID!) {
epoch {
id
}
party(id: $partyId) {
id
delegations {
amountFormatted @client
amount
node {
id
name
}
epoch
}
stake {
currentStakeAvailable
currentStakeAvailableFormatted @client
}
accounts {
asset {
name
id
decimals
symbol
source {
__typename
... on ERC20 {
contractAddress
}
}
}
type
balance
}
}
}
@@ -28,6 +28,9 @@ export interface Delegations_party_delegations_node {
export interface Delegations_party_delegations {
__typename: "Delegation";
/**
* The amount field formatted by the client
*/
amountFormatted: string;
/**
* Amount delegated
@@ -49,6 +52,9 @@ export interface Delegations_party_stake {
* The stake currently available for the party
*/
currentStakeAvailable: string;
/**
* The currently available stake formatted by the client
*/
currentStakeAvailableFormatted: string;
}
@@ -1,52 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: PartyDelegations
// ====================================================
export interface PartyDelegations_epoch {
__typename: "Epoch";
/**
* Presumably this is an integer or something. If there's no such thing, disregard
*/
id: string;
}
export interface PartyDelegations_party_delegations {
__typename: "Delegation";
/**
* Amount delegated
*/
amount: string;
/**
* URL of node you are delegating to
*/
node: string;
/**
* Epoch of delegation
*/
epoch: number;
}
export interface PartyDelegations_party {
__typename: "Party";
delegations: PartyDelegations_party_delegations[] | null;
}
export interface PartyDelegations {
/**
* get data for a specific epoch, if id omitted it gets the current epoch
*/
epoch: PartyDelegations_epoch;
/**
* An entity that is trading on the VEGA network
*/
party: PartyDelegations_party | null;
}
export interface PartyDelegationsVariables {
partyId: string;
}

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