Compare commits

...
Author SHA1 Message Date
Dariusz Majcherczyk 8fc719dd4d chore: formatting fix 2022-12-28 13:34:45 +01:00
Dariusz Majcherczyk f7a33c47ca chore: tests will be added after the proper implementation is prepared 2022-12-28 13:33:08 +01:00
mattrussell36 15d2aed343 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-28 06:08:30 +00:00
mattrussell36 0284eaf9a2 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-28 00:12:18 +00:00
mattrussell36 c9c240cb29 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-27 18:08:12 +00:00
macqbat 64aa39fe4b feat: add animated preloader (#2464)
* feat: add animated preloader

* feat: add animated preloader - add scss lines

* feat: add animated preloader - add scss lines

* feat: add animated preloader - ref scss lines

* feat: add animated preloader - add preloader property to loader component
2022-12-27 15:46:44 +00:00
m.ray 485c609791 fix: governance links to proposals (#2478) (#2480)
* fix: governance links to proposals

* fix:  fix proposals link in governance.cy.js

* fix: fix link for https://vega.xyz/governance
2022-12-27 15:18:42 +00:00
m.ray 61457bc24d fix(#2474): liquidity provisions table has incorrect supplied values (#2475)
* fix(#2472): lp table supplied calculate bond account balance fixed

* fix(#2472): unit tests in accounts-data-provider.spec.ts

* fix(#2472): unit tests in accounts.mock.ts
2022-12-27 14:10:09 +00:00
botond 2217925285 fix: env ssl to subscription (#2440)
* fix: rename ssl environment check to subscription

* fix: format
2022-12-27 13:28:54 +00:00
daro-maj 28fe7458ca chore: cover 7003-MORD e2e tests order list - fields (#2477)
* chore: cover 7003-MORD e2e tests order list - fields

* chore: formating fix
2022-12-27 14:10:08 +01:00
mattrussell36 2cb88624f3 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-27 12:07:23 +00:00
mattrussell36 d2ae780996 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-27 06:08:39 +00:00
mattrussell36 bd129f1229 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-27 00:12:33 +00:00
mattrussell36 f3cd2db1ce chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-26 18:08:27 +00:00
mattrussell36 418ea41e22 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-26 12:07:29 +00:00
mattrussell36 bcc1c8a474 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-26 06:06:54 +00:00
mattrussell36 496fdee10e chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-26 00:12:57 +00:00
mattrussell36 c8fc91a3bd chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-25 18:07:33 +00:00
mattrussell36 48cccc2678 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-25 12:07:02 +00:00
mattrussell36 9d66eeae51 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-25 06:06:12 +00:00
mattrussell36 7ab20d07f9 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-25 00:10:37 +00:00
mattrussell36 b0aa1b8a3e chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-24 18:08:19 +00:00
mattrussell36 13ffe8a8d0 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-24 12:08:48 +00:00
mattrussell36 01420c56ff chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-24 06:08:31 +00:00
mattrussell36 15bb7b94ad chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-24 00:09:36 +00:00
mattrussell36 d65ef297a9 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-23 18:08:21 +00:00
daro-maj 4062c493cb chore: cover 7003-MORD-007-7003 and MORD-008-MORD e2e tests (#2471) 2022-12-23 08:16:13 -05:00
mattrussell36 786ab51bd1 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-23 12:08:37 +00:00
Radosław Szpiech 6cb2e3a3cf chore: move mocks next to graphql queries (#2469)
* chore: move mocks next to graphql queries

* chore: mock functions rework

* chore: clean up
2022-12-23 12:36:25 +01:00
Matthew Russell cf0e0ce4b2 chore: add core as codeowners for graphql file changes (#2468) 2022-12-23 09:50:34 +00:00
mattrussell36 9c21a4481a chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-23 06:06:19 +00:00
mattrussell36 7a6c69d773 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-23 00:12:04 +00:00
mattrussell36 4f10a75386 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-22 18:08:06 +00:00
Art 9c26f4d01b chore: console dapp routes for skeleton page (2361) (#2450)
* chore: console dapp routes for skeleton page (2361)

* chore: console dapp routes for skeleton page (2361)

* chore: console dapp routes for skeleton page (2361)
2022-12-22 15:24:20 +01:00
mattrussell36 b3bbe260c6 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-22 12:08:44 +00:00
Mikołaj Młodzikowski 69a4ecdbde feat: adjust logs names (#2460)
* feat: adjust logs

* feat: adjust logs names
2022-12-22 12:12:54 +01:00
Bartłomiej Głownia dbba734672 feat: add filters to Orders query (#2446) 2022-12-22 10:52:09 +00:00
Matthew Russell 1c57ec4df1 chore: remove unused component testing config for cypress, allow jsx in cypress imports (#2455) 2022-12-22 10:49:55 +00:00
Dexter Edwards f4fa0bd25a fix: flickering (#2445)
* fix: flickering

* Update apps/token/src/routes/staking/home/validator-tables/validator-tables.tsx
2022-12-22 10:49:26 +00:00
daro-maj c2595b533d chore: 7003 mord amend and cancel e2e tests (#2449)
* chore: cover e2e tests for: Amend order - price and Cancel orders

* chore: fix for formating

* chore: rework

* chore: fix for formating
2022-12-22 10:49:15 +00:00
Art 65316075fa feat: view proposed network changes (579) (#2444) 2022-12-22 10:49:02 +00:00
Mikołaj Młodzikowski 46955dd933 feat: adjust logs (#2459) 2022-12-22 11:18:03 +01:00
mattrussell36 024ed575fc chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-22 06:06:49 +00:00
mattrussell36 871d7068da chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-22 00:10:03 +00:00
mattrussell36 efbb75ec01 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-21 18:08:11 +00:00
m.ray 57c9ea9471 chore(#2410): market info reduce font sizes (#2443)
* chore(#2410): market info reduce font sizes

* chore(#2410): text-sm to row class name in market info
2022-12-21 16:06:50 +00:00
Joe Tsang 448f8f4ba5 chore: update workflow files (#2448)
* chore: update workflow files

* chore: fix wallet flow
2022-12-21 12:43:43 +00:00
mattrussell36 5a5cd1daeb chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-21 12:08:41 +00:00
Joe Tsang d7365c4b66 test(2433): capsule wallet script (#2447)
* chore: added bash script for vega wallet

* chore: update readme

* chore: fix lint
2022-12-21 11:36:27 +00:00
m.ray b6c448b630 fix(#2413): collateral table to have separate used available cells (#2436)
* fix(#2413): separate collateral used and available cells

* fix(#2413): fix accounts table test update

* fix(#2413): move progress bar in breakdown.tsx
2022-12-21 10:35:15 +00:00
ArtandBartłomiej Głownia 87e1f9998e feat: transaction store and toasts (#2382)
* feat: add eth and vega transaction stores

feat: replace useStoredEthereumTransaction with useEthTransactionManager

feat: add event bus subsciption to vega transaction store

feat: handle order cancellation

feat: rename Deposit, Order and Withdraw status field to be unique

Revert "feat: rename Deposit, Order and Withdraw status field to be unique"

This reverts commit f0b314d53fb3ada6fbebaba4fd1e5af6f38beaed.

feat: split transaction update subscription

feat: handle order and deposit transaction

feat: handle withdrawal creation through transaction store

feat: handle withdraw approval

feat: handle panding withdrawls, add createdAt

feat: handle transaction toast/dialog dismissal

feat: add use vega transaction store tests

feat: add use vega transaction store tests

feat: add use vega transaction menager tests

feat: add use vega transaction menager tests

feat: add use vega transaction updater tests

feat: improve use vega transaction updater tests

feat: add use eth transaction store

feat: add use eth withdraw approvals store

feat: add use eth transaction updater tests

fixed tests

* feat: toasts

feat: toasts

feat: toasts

* feat: add use eth withdraw approval manager tests

* feat: add use eth transaction manager tests

* feat: add use eth transaction manager tests

* feat: add useEthWithdrawApprovalsManager tests

* feat: remove Web3Container react container from CreateWithdrawalDialog

* feat: remove Web3Container react container around TransactionsHandler

* feat: remove unnecessary async from PendingWithdrawalsTable

* feat: remove comments from WithdrawalFeedback

* fixed z-index issue

* cypress

Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
2022-12-21 10:29:32 +01:00
mattrussell36 bdff40b4bc chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-21 06:06:25 +00:00
Matthew Russell 0b4f918208 chore(#2412): refactor theme context (#2435)
* chore: switch theme to zustand, delete context

* chore: switch apps/componenets to consume the hook

* chore: update storybook theme usage to use documentElement

* chore: dry up theme switcher listener for storybooks

* feat: optional theme param to allow toggling

* chore: add additional check for matchMedia function

* chore: change block explorer test to use light theme as its the default

* chore: remove unused headerprops for multisig-signer

* chore: remove unused props from theme switcher component

* chore: dry up validateTheme func

* chore: remove unused props from explorer header test

* chore: use new theme switcher in account history container
2022-12-20 18:55:35 -08:00
Matthew Russell df609d442c chore: remove settlementDataDecimals field and regen graphql (#2442) 2022-12-20 17:36:54 -08:00
mattrussell36 5730e39b32 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-21 00:12:17 +00:00
mattrussell36 83e9bc8ff6 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-20 18:06:15 +00:00
macqbat a830e4729f chore: fix too big margin in tooltips (#2438) 2022-12-20 14:41:30 +01:00
mattrussell36 e3ff090915 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-20 12:06:59 +00:00
m.rayandMatthew Russell c5b6032184 feat(#469): account history with pennant price chart (#2434)
* feat: account hitory poc

* feat(#469): update account history and chart

* feat(#469): remove radix toggle group

* fix: add use memo and some tweaks to make sure you pass undefined to cancel all

* feat(#469): add new version pennant

* feat(#469): style account history chart and no data splash

* fix(#469): use splash only

* fix(#469): sort assets list

* feat(#469): new pennant version

* fix: update query

* fix: update query

* Update libs/orders/src/lib/components/order-list/order-list.tsx

* Update libs/assets/src/lib/asset-details-dialog.tsx

* feat(#469): update test on trading positions tab

* Update apps/trading-e2e/src/integration/trading-positions.cy.ts

* fix: click on positions in portfolio

* feat(#469): refactor with async renderer

* feat(#469): refactor date range in account history

Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2022-12-20 11:22:35 +00:00
m.ray cb80c6d417 chore(#2430): update stake reward to reward payout mapping (#2437) 2022-12-20 10:58:33 +00:00
macqbat b9ff2388db chore(2415): get rid of polling queries on deal ticket (#2427)
* chore: get rid of polling queries on dael ticket

* chore: get rid of polling queries on dael ticket - fix tests

* chore: get rid of polling queries on deal ticket - fix linter

* chore: get rid of polling queries on deal ticket - fix linter

* chore: get rid of polling queries on deal ticket - adjust int test

* chore: get rid of polling queries on deal ticket - adjust int test in console-lite

* chore: get rid of polling queries on deal ticket - adjust unit some test

* chore: get rid of polling queries on deal ticket - adjust unit some test

* chore: get rid of polling queries on deal ticket - clean up some redundant types

* chore: get rid of polling queries on deal ticket - clean up some redundant files
2022-12-20 10:01:10 +01:00
mattrussell36 07b766e4d2 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-20 06:07:35 +00:00
mattrussell36 d19ef2607d chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-20 00:12:55 +00:00
mattrussell36 af0b7391c9 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-19 18:06:12 +00:00
mattrussell36 9ea980c603 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-19 12:07:09 +00:00
mattrussell36 2741551c18 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-19 06:06:21 +00:00
mattrussell36 b06003990c chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-19 00:10:32 +00:00
mattrussell36 377d219220 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-18 18:08:14 +00:00
mattrussell36 0f20f79a5e chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-18 12:07:55 +00:00
mattrussell36 f658ae4d64 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-18 06:08:06 +00:00
mattrussell36 4e7192264c chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-18 00:10:54 +00:00
mattrussell36 69ecf00999 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-17 18:05:51 +00:00
mattrussell36 cbb7189328 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-17 12:09:09 +00:00
mattrussell36 a05ff9c41a chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-17 06:07:33 +00:00
mattrussell36 62b80a6438 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-17 00:12:13 +00:00
mattrussell36 4f76724e3e chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-16 18:06:16 +00:00
Joe Tsang e20061d921 chore: fix failing governance test (#2426)
* chore: fix failing governance test

* chore: use parentuntil

* chore: increase timeout for proposal query

* chore: remove wait for proposal in smoke test

* chore: add wallet teardown
2022-12-16 17:18:39 +00:00
Sam Keen f133200c7f fix(2380): fixed block duration field to account for the new api format (#2423)
* fix(2380): fixed block duration field to account for the new api format

* fix(2380): removed unneeded import

* fix(2380): a little more hardened against duration being undefined and different environments returning different data

* fix(2380): improved comment
2022-12-16 12:25:20 +00:00
mattrussell36 98d01d7933 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-16 12:07:31 +00:00
Sam Keen 0a3509faad feat(2034): governance home (#2299)
* feat(2034): quickly-assembled governance home

* feat(2034): tweaks

* feat(2034): tidied up new homepage

* feat(2034): e2e test tweak

* feat(2034): tweaks from PR comments and adjusted epoch progress bg-colour

* feat(2034): fix linting
2022-12-16 10:11:14 +00:00
Matthew Russell 070f2a2045 chore: remove unused page-query-container component (#2407) 2022-12-16 10:09:57 +00:00
Joe Tsang 7a56e1695d test(2229): unhappy path test updates (#2417)
* test: update tests and add workaround

* chore: remove smoke test due to bug

* chore: remove only

* chore: add wallet teardown

* chore: increase wait
2022-12-16 10:06:02 +00:00
mattrussell36 bbfef16889 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-16 06:08:21 +00:00
mattrussell36 ba0211698f chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-16 00:10:27 +00:00
mattrussell36 9f9d44e87d chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-15 18:08:24 +00:00
Mikołaj Młodzikowski 349eba7053 feat: always store logs from failed capsule runs (#2421) 2022-12-15 17:07:00 +01:00
Ciaran McGhie b28d671975 feat: add market duration/age to market list page (#2419) 2022-12-15 13:15:40 +00:00
macqbat 7d5cc9b080 chore: change name of the column (#2420) 2022-12-15 13:38:55 +01:00
m.rayandRado dce802d153 fix(#2273): remove show market only checkbox (#2418)
* fix: remove show market only checkbox

* chore: fix tests

* chore: lint fix

Co-authored-by: Rado <szpiechrados@gmail.com>
2022-12-15 12:36:56 +00:00
mattrussell36 6d646e3baf chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-15 12:06:50 +00:00
Sam KeenandDexter Edwards 05b07c2bfe feat(2356): use validator performance score from previous epoch (#2365)
* feat(1913): validator table column heading mouseovers

* feat(2089): stake needed for promotion tooltip

* feat(2089): normalised voting power tooltip

* feat(2089): total stake tooltip

* feat(2089): total stake tooltip for standby-pending-validators-table

* feat(2089): total penalties tooltip

* feat(2089): tooltip colour tweakage

* feat(2089): unit tests for the shared validator data functions

* feat(2089): removed unused import from tooltip.tsx

* Update apps/token/src/routes/staking/home/validator-tables/standby-pending-validators-table.tsx

Co-authored-by: Dexter Edwards <dexter.edwards93@gmail.com>

* feat(2089): tweaks from PR comments

* feat(2356): display previous epoch validator performance score instead of current epoch

* feat(2356): added condition to ensure no divide by zero errors

Co-authored-by: Dexter Edwards <dexter.edwards93@gmail.com>
2022-12-15 10:06:08 +00:00
macqbat e653ad328f feat(2036): add markets to the navbar (#2402)
* feat: add markets to the navbar

* feat: add markets to the navbar - adjust failing int test
2022-12-15 08:45:03 +01:00
mattrussell36 6b7a04176b chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-15 06:08:21 +00:00
mattrussell36 ac44f4c553 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-15 00:10:00 +00:00
mattrussell36 b52386622c chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-14 18:05:46 +00:00
Edd b47caa7667 feat(explorer): improve party account list display (#2391)
* feat(explorer): party account list as table
2022-12-14 16:36:47 +00:00
Sam Keen 071a9ab34b feat(2326): style Token validators (#2388)
* feat(2326): styled up validators intro as per designs, including site-wide tweaking to headers for consistency

* feat(2326): styled up reduced height epoch progress bar

* feat(2326): styled up inline 'reveal all validators' table row. Test failing

* feat(2326): failing test fixed

* feat(2326): components and styling for validator table

* feat(2326): making proposals section consistent with new validators styling

* feat(2326): extra consistency changes

* feat(2326): linting fixes

* feat(2326): a couple of e2e test fixes

* feat(2326): more e2e test fixes
2022-12-14 13:25:03 +00:00
m.ray e49ad9da6a feat(#2273): orders and fills on trading page to be market specific (#2395)
* feat(#2273): make orders and fills tabs market specific in trade grid

* feat(#2273): fix order navigation and show orders for this market only checkbox

* fix(#2273): fills container should not require market

* feat(#2273): add marketId as hook dependency

* fix: use data-testid in trading orders

* fix(#2273): default to false
2022-12-14 12:59:59 +00:00
mattrussell36 b508d7b252 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-14 12:08:22 +00:00
817521bb08 feat(#1853): ledger entries date filtering (#2267)
* chore: update ledger entries columns

* fix: yarn generate types against stagnet3

* fix: orderbook decimal places issue  (#2235)

* fix: positions table fixes notional dp (#2144)

* fix: update decimals on position notional size

* fix: normalize values

* fix: fix positions unit tests

* fix: remove liquidation price

* fix: positions linting issue

* fix: remove liquidation price test

* fix: remove total summary row

* fix: remove comments

* fix: cypress test to not show trailing 0s

* fix: add back liq. price est as cell only

* fix: remove not used params

* chore: merge with release/testnet

* fix: orderbook dp

* Update libs/positions/src/lib/positions-table.spec.tsx

* feat(#1853): use date range filter

* feat(#1853): add date range filter to ledger entries on update

* chore(#1853): add extra checks

* fix: update types on stagnet3

* fix: add checkpoint balance restore

* fix(#1853): fix ledger generic make data provider cast in ledger entries

* fix(#1853): fix transfer type

* fix(#1853): remove TransferTypeMapping cast type

* fix(#1853): remove pagination filtering and use formatForInput from date

* fix(#1853): call filterChangedCallback in onChange method

* fix(#1853): remove subscription from ledger entries table

* fix(#1853): filterChangedCallback called in useEffect gets triggered also on reset

* fix: use-order-list-data hook order of params for makeInfiniteScrollGetRows

* fix(#1853): fix ledger build import all as schema

* fix(#1853): fix schema import

Co-authored-by: maciek <maciek@vegaprotocol.io>
Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
2022-12-14 09:43:16 +00:00
mattrussell36 f60e8a2910 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-14 06:05:55 +00:00
mattrussell36 a557678513 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-14 00:12:41 +00:00
mattrussell36 9ff68ecba3 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-13 18:08:29 +00:00
Dexter Edwards 48e0cf0808 fix(2286): remove usage all votes (#2385)
* chore: remove instances of calling all user votes

* chore: remove console.log

* test: fix tests

* chore: fix test types
2022-12-13 13:53:00 +00:00
macqbat c14e57cfd5 feat(2146): adjust and refactor welcome dialogs (#2384)
* feat: adjust and refactor welcome dialogs

* feat: adjust and refactor welcome dialogs - add int tests

* feat: adjust and refactor welcome dialogs - small fixes and imprvments

* feat: adjust and refactor welcome dialogs - fix a typo

* feat: adjust and refactor welcome dialogs - fix a property name

* feat: adjust and refactor welcome dialogs - fix an unit test
2022-12-13 14:31:28 +01:00
mattrussell36 01addaea7c chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-13 12:06:27 +00:00
mattrussell36 9002e63961 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-13 06:05:54 +00:00
mattrussell36 098bdb5e3a chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-13 00:10:22 +00:00
mattrussell36 2514a2342b chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-12 18:08:10 +00:00
mattrussell36 4600d6e4ca chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-12 12:07:06 +00:00
Ciaran McGhieandMadalina Raicu c217741924 chore: improve typing in markets list page on the lpdashboard (#2363)
* chore: add some missing properties to the Market type

* chore: improve typing of value formatters in market list page

Replacing ValueFormatterParams with VegaValueFormatterParams<T, Y> in a
bunch of places. Doing this also highlighted we weren't dealing with a
bunch of undefined cases, so we now have fallback formatting for those.

Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2022-12-12 11:46:33 +00:00
Edd 1180a5ff97 feat(explorer): delegate/undelegate submission view (#2381)
* fix(explorer): initial tx delegation view

* fix(explorer): fix dangling duplicate type

* feat(explorer): add governanceasset component to show prices correct for that asset

* feat(explorer): add undelegate view

* feat(explorer): status code component shows error message if available

* fix(explorer): remove unused type
2022-12-12 11:46:09 +00:00
m.ray 71399105ee feat(#2307): make liquidity provision table more prominent (#2350)
* feat(#2307): make liquidity provision table more prominent

* feat(#2307): show title only if content is defined

* feat(#2307): filter LP to show active, undeployed and pending

* fix(#2307): remove showTitle attribute

* fix: check marketId and name before building href

* fix(#2307): revert header changes
2022-12-12 09:44:58 +00:00
mattrussell36 3bca206e45 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-12 06:05:57 +00:00
mattrussell36 044e9639e9 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-12 00:10:26 +00:00
mattrussell36 2cde42971e chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-11 18:05:59 +00:00
mattrussell36 c6c320a2ff chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-11 12:06:12 +00:00
mattrussell36 757cbd0f49 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-11 06:05:53 +00:00
mattrussell36 d70ff8d3d6 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-11 00:13:36 +00:00
mattrussell36 7ba2acefda chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-10 18:07:33 +00:00
mattrussell36 03a1d10fe4 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-10 12:10:05 +00:00
mattrussell36 39f55cee5d chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-10 06:06:02 +00:00
mattrussell36 5227d118fc chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-10 00:10:30 +00:00
mattrussell36 16e095104f chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-09 18:08:34 +00:00
Radosław Szpiech e6531daa41 chore: print vega and vegacapsule version on workflow start (#2377)
* chore: print vega and vegacapsule version on workflow start

* chore: print vega and vegacapsule version on workflow start
2022-12-09 15:20:03 +01:00
Dexter Edwards 7bf753e6c2 fix: token dependency graph (#2371)
* chore: fix dependency graph

* fix: silly error

* fix: remove uneeded generics
2022-12-09 14:02:56 +00:00
Dexter Edwards 22610c2d0a fix: proposals list (#2374)
* fix: proposals list

* Update apps/token/src/routes/governance/components/proposals-list/proposals-list.tsx
2022-12-09 14:01:33 +00:00
mattrussell36 4b86b981b3 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-09 12:08:41 +00:00
Radosław Szpiech 615748548b chore: remove chainID request to wallet in e2e (#2370) 2022-12-09 12:08:26 +01:00
Edd 13c9dffc3d feat(explorer): add withdrawsubmission view (#2366)
* feat(explorer): add withdraw view
* fix(explorer): regenerate types after rebasing develop
2022-12-09 11:02:01 +00:00
macqbatandcandida-d fa8868d42a feat(2298): handle lost connection with wallet during order setting (#2344)
* feat: handle lost connection with wallet during order setting

* Update libs/deal-ticket/src/components/deal-ticket/deal-ticket-manager.tsx

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

* feat: handle lost connection with wallet during order setting - adjust wording

* feat: handle lost connection with wallet during order setting - adjust wording

* feat: handle lost connection with wallet during order setting - adjust wording

* fix: handle lost connection with wallet add print vega version

* fix: handle lost connection with wallet add print vega version

Co-authored-by: candida-d <62548908+candida-d@users.noreply.github.com>
2022-12-09 11:33:13 +01:00
mattrussell36 d382887b95 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-09 06:08:22 +00:00
mattrussell36 74265b25d7 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-12-09 00:10:15 +00:00
botond 2211abbd72 chore: cleanup type gen (#2362)
* chore: remove apollo type gen and clean up types lib

* fix: format

* fix: tests

* fix: format

* fix: hammer token types til sh*t turns green

* fix: format

* fix: apparently format again

* fix: lint

* fix: build-specs

* fix: format

* chore: regen types

* chore: regenerate types again

* fix: format
2022-12-08 21:13:30 +00:00
743 changed files with 17935 additions and 22170 deletions
@@ -8,21 +8,17 @@ outputs:
runs:
using: 'composite'
steps:
- name: Create passphrase
shell: bash
run: echo "${{ inputs.passphrase }}" > ./passphrase
- name: Initialize wallet
shell: bash
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
- name: Import wallet
shell: bash
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
- name: Generate second public key
shell: bash
run: vega wallet key generate -w capsule_wallet -p ./passphrase --home ~/.vegacapsule/testnet/wallet
run: vega wallet key generate -w capsule_wallet -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
- name: Import network
shell: bash
@@ -30,13 +26,13 @@ runs:
- name: Init api-token
shell: bash
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file passphrase
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file ./frontend-monorepo/vegacapsule/passphrase
- name: Generate api-token
id: generate-api-token
shell: bash
run: echo api-token=$(vega wallet api-token generate --wallet-name capsule_wallet --tokens-passphrase-file passphrase --wallet-passphrase-file passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
run: echo api-token=$(vega wallet api-token generate --wallet-name capsule_wallet --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --wallet-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
- name: Start service using capsule network
shell: bash
run: vega wallet service run -n DV --load-tokens --tokens-passphrase-file passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
run: vega wallet service run -n DV --load-tokens --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
@@ -19,6 +19,9 @@ jobs:
if: ${{ inputs.trigger == 'true' }}
runs-on: self-hosted
steps:
- name: Vega version
run: vega version
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
+15 -3
View File
@@ -24,6 +24,12 @@ jobs:
runs-on: self-hosted
timeout-minutes: 30
steps:
- name: Vega version
run: vega version
- name: Vegacapsule version
run: vegacapsule version
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
@@ -85,10 +91,16 @@ jobs:
## Upload logs
######
- name: Logs
run: vegacapsule network logs > vega-capsule-logs.txt
# Artifact path is not valid: /ganache-1/capsule-logscolletor.stderr-2022-12-22T10:20:30Z.log. Contains the following character: Colon :
- name: Rename files to allow archive
if: ${{ always() }}
run: |
while read -r file; do
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
- uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: logs
path: ./vega-capsule-logs.txt
path: /home/runner/.vegacapsule/testnet/logs
+15 -3
View File
@@ -20,6 +20,12 @@ jobs:
runs-on: self-hosted
timeout-minutes: 60
steps:
- name: Vega version
run: vega version
- name: Vegacapsule version
run: vegacapsule version
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
@@ -80,10 +86,16 @@ jobs:
## Upload logs
######
- name: Logs
run: vegacapsule network logs > vega-capsule-logs.txt
# Artifact path is not valid: /ganache-1/capsule-logscolletor.stderr-2022-12-22T10:20:30Z.log. Contains the following character: Colon :
- name: Rename files to allow archive
if: ${{ always() }}
run: |
while read -r file; do
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
- uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: logs
path: ./vega-capsule-logs.txt
path: /home/runner/.vegacapsule/testnet/logs
@@ -20,6 +20,9 @@ jobs:
timeout-minutes: 30
runs-on: self-hosted
steps:
- name: Vega version
run: vega version
# Checkout front ends
- name: Checkout frontend mono repo
uses: actions/checkout@v3
+1
View File
@@ -1 +1,2 @@
* @vegaprotocol/frontend
*.graphql @vegaprotocol/core
+17
View File
@@ -156,6 +156,23 @@ In order to run the bootstrap command to generate and start a new network, we mu
vegacapsule network bootstrap --config-path=../frontend-monorepo/vegacapsule/config.hcl
```
In order to setup and run vegawallet for e2e capsule tests, in a separate terminal window:
1. cd into `./vegacapsule`
2. run:
```bash
bash setup-vegawallet.sh
```
3. copy generated `api-token` and paste the token into `CYPRESS_VEGA_WALLET_API_TOKEN` environment variable in either `apps/token-e2e/.env` or `apps/explorer-e2e/.env` depending on which project needs testing.
Note: The script is only needed if capsule was built for first time or fresh. To run existing wallet service for capsule:
```bash
vega wallet service run -n DV --load-tokens --tokens-passphrase-file passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet
```
# 📑 License
[MIT](./LICENSE)
@@ -1,15 +1,6 @@
import { aliasQuery } from '@vegaprotocol/cypress';
import {
generateSimpleMarkets,
generateMarketsCandles,
} from '../support/mocks/generate-markets';
describe('simple trading app', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'Markets', generateSimpleMarkets());
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
});
cy.mockConsole();
cy.visit('/');
});
@@ -1,18 +1,11 @@
import { aliasQuery } from '@vegaprotocol/cypress';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import type { MarketsQuery } from '@vegaprotocol/market-list';
import {
generateLongListMarkets,
generateSimpleMarkets,
generateMarketsCandles,
} from '../support/mocks/generate-markets';
import { marketCandlesQuery, marketsQuery } from '@vegaprotocol/mock';
describe('market list', { tags: '@smoke' }, () => {
describe('simple url', () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'Markets', generateSimpleMarkets());
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
});
cy.mockConsole();
cy.visit('/markets');
});
@@ -64,10 +57,7 @@ describe('market list', { tags: '@smoke' }, () => {
describe('url params should select filters', () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'Markets', generateSimpleMarkets());
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
});
cy.mockConsole();
});
it('suspended status', () => {
@@ -100,14 +90,26 @@ describe('market list', { tags: '@smoke' }, () => {
});
describe('long list of results should be handled properly', () => {
it('handles 1000 markets', () => {
beforeEach(() => {
cy.mockConsole();
cy.viewport(1440, 900);
const market = marketsQuery().marketsConnection?.edges[0];
const edges = new Array(1000)
.fill('')
.map(() => Object.assign({}, market));
cy.mockGQL((req) => {
aliasQuery(req, 'Markets', generateLongListMarkets(1000));
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
aliasGQLQuery(
req,
'Markets',
marketsQuery({ marketsConnection: { edges } })
);
aliasGQLQuery(req, 'MarketsCandles', marketCandlesQuery());
});
performance.mark('start-1k');
cy.visit('/markets');
cy.wait('@Markets');
});
it('handles 1000 markets', () => {
cy.get('.ag-center-cols-container', { timeout: 50000 }).then(() => {
performance.mark('end-1k');
performance.measure('load-1k', 'start-1k', 'end-1k');
@@ -1,155 +1,84 @@
import { aliasQuery } from '@vegaprotocol/cypress';
import {
generateMarket,
generateMarketData,
generateMarketsCandles,
generateMarketsData,
generateSimpleMarkets,
} from '../support/mocks/generate-markets';
import { generateMarketTags } from '../support/mocks/generate-market-tags';
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
import { generateMarketNames } from '../support/mocks/generate-market-names';
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
import type { Market, MarketsQuery } from '@vegaprotocol/market-list';
import { generateChainId } from '../support/mocks/generate-chain-id';
import { generateStatistics } from '../support/mocks/generate-statistics';
const marketId = 'market-0';
const marketName = 'ACTIVE MARKET';
describe('market selector', { tags: '@smoke' }, () => {
let markets: Market[];
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Markets', generateSimpleMarkets());
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
aliasQuery(req, 'MarketsData', generateMarketsData());
aliasQuery(req, 'MarketData', generateMarketData());
aliasQuery(req, 'Market', generateMarket());
aliasQuery(req, 'MarketTags', generateMarketTags());
aliasQuery(req, 'MarketPositions', generateMarketPositions());
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
aliasQuery(req, 'PartyBalance', generatePartyBalance());
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
aliasQuery(req, 'MarketNames', generateMarketNames());
aliasQuery(req, 'MarketDepth', generateMarketDepth());
});
cy.visit('/markets');
cy.wait('@Markets').then((response) => {
const data: MarketsQuery | undefined = response?.response?.body?.data;
if (data?.marketsConnection?.edges.length) {
markets = data?.marketsConnection?.edges.map((edge) => edge.node);
}
});
cy.mockConsole();
cy.visit(`/trading/${marketId}`);
cy.connectVegaWallet();
cy.wait('@Markets');
});
it('should be properly rendered', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.get('input[placeholder="Search"]').should(
'have.value',
markets[0].tradableInstrument.instrument.name
);
cy.getByTestId('arrow-button').click();
cy.getByTestId('market-pane').should('be.visible');
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.first()
.should('contain.text', markets[0].tradableInstrument.instrument.name);
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.first()
.click();
cy.getByTestId('market-pane').should('not.be.visible');
}
cy.get('input[placeholder="Search"]').should('have.value', marketName);
cy.getByTestId('arrow-button').click();
cy.getByTestId('market-pane').should('be.visible');
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.first()
.should('contain.text', marketName);
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.first()
.click();
cy.getByTestId('market-pane').should('not.be.visible');
});
it('typing should change list', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.should('have.length.at.least', 1);
cy.get('input[placeholder="Search"]').clear();
cy.get('input[placeholder="Search"]').type('aa');
const filtered = markets.filter(
(market) =>
market.state === 'STATE_ACTIVE' &&
market.tradableInstrument.instrument.name.match(/aa/i)
);
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.should('have.length', filtered.length);
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.last()
.click();
cy.location('pathname').should(
'eq',
`/trading/${filtered[filtered.length - 1].id}`
);
cy.get('input[placeholder="Search"]').should(
'have.value',
filtered[filtered.length - 1].tradableInstrument.instrument.name
);
}
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.should('have.length.at.least', 1);
cy.get('input[placeholder="Search"]').clear();
cy.get('input[placeholder="Search"]').type('ACTIVE');
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.should('have.length', 1);
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.last()
.click();
cy.location('pathname').should('eq', `/trading/${marketId}`);
cy.get('input[placeholder="Search"]').should('have.value', marketName);
});
// constantly failing on ci
it.skip('keyboard navigation should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.get('input[placeholder="Search"]').clear();
cy.focused().realPress('ArrowDown');
cy.focused().should('contain.text', 'AAVEDAI Monthly');
cy.focused().realPress('ArrowDown');
cy.focused().should('contain.text', 'ETHBTC').realPress('Enter');
cy.location('pathname').should('eq', '/trading/ethbtc-quaterly');
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.get('input[placeholder="Search"]').clear();
cy.focused().realPress('ArrowDown');
cy.focused().should('contain.text', marketName);
cy.focused().realPress('ArrowDown');
cy.focused().should('contain.text', 'ETHBTC').realPress('Enter');
cy.location('pathname').should('eq', '/trading/ethbtc-quaterly');
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.get('input[placeholder="Search"]').clear();
cy.getByTestId('market-pane').should('be.visible');
cy.get('body').realPress('ArrowDown');
cy.get('body').realPress('Tab');
cy.getByTestId('market-pane').should('not.be.visible');
}
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.get('input[placeholder="Search"]').clear();
cy.getByTestId('market-pane').should('be.visible');
cy.get('body').realPress('ArrowDown');
cy.get('body').realPress('Tab');
cy.getByTestId('market-pane').should('not.be.visible');
});
it('mobile view', () => {
if (markets?.length) {
cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.get('[role="dialog"]').should('not.exist');
cy.getByTestId('arrow-button').click();
cy.get('[role="dialog"]').should('be.visible');
cy.get('input[placeholder="Search"]').then((search) => {
cy.wrap(search).clear();
});
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.should('have.length', 9);
cy.get('div[role="dialog"]').should('have.class', 'w-screen');
cy.getByTestId('dialog-close').click();
cy.get('input[placeholder="Search"]').should(
'have.value',
markets[0].tradableInstrument.instrument.name
);
}
cy.viewport('iphone-xr');
cy.visit(`/trading/${marketId}`);
cy.get('[role="dialog"]').should('not.exist');
cy.getByTestId('arrow-button').click();
cy.get('[role="dialog"]').should('be.visible');
cy.get('input[placeholder="Search"]').then((search) => {
cy.wrap(search).clear();
});
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
.should('have.length', 3);
cy.get('div[role="dialog"]').should('have.class', 'w-screen');
cy.getByTestId('dialog-close').click();
cy.get('input[placeholder="Search"]').should('have.value', marketName);
});
});
@@ -1,53 +1,38 @@
import { aliasQuery } from '@vegaprotocol/cypress';
import {
generateSimpleMarkets,
generateMarketsCandles,
generateMarketsData,
generateMarket,
generateMarketData,
} from '../support/mocks/generate-markets';
import { generateMarketTags } from '../support/mocks/generate-market-tags';
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
import type { MarketsQuery, Market } from '@vegaprotocol/market-list';
import { generateChainId } from '../support/mocks/generate-chain-id';
import { generateStatistics } from '../support/mocks/generate-statistics';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { marketQuery, marketsQuery } from '@vegaprotocol/mock';
describe('Market trade', { tags: '@smoke' }, () => {
let markets: Market[];
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Markets', generateSimpleMarkets());
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
aliasQuery(req, 'MarketsData', generateMarketsData());
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
aliasQuery(req, 'MarketTags', generateMarketTags());
aliasQuery(req, 'MarketPositions', generateMarketPositions());
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
aliasQuery(req, 'PartyBalance', generatePartyBalance());
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
aliasQuery(req, 'MarketDepth', generateMarketDepth());
aliasQuery(req, 'Market', generateMarket());
aliasQuery(req, 'MarketData', generateMarketData());
});
cy.visit('/markets');
cy.wait('@Markets').then((response) => {
const data: MarketsQuery | undefined = response?.response?.body?.data;
if (data?.marketsConnection?.edges.length) {
markets = data?.marketsConnection?.edges.map((edge) => edge.node);
}
});
const marketId =
marketsQuery().marketsConnection?.edges[1].node.id || 'market-1';
const marketOverride = {
market: {
depth: {
lastTrade: {
price: '9893006',
},
},
id: marketId,
tradableInstrument: {
instrument: {
product: {
settlementAsset: {
id: 'asset-id-2',
name: 'DAI Name',
symbol: 'tDAI',
},
},
},
},
},
};
describe('Market trade with wallet disconnected', { tags: '@smoke' }, () => {
before(() => {
cy.mockConsole();
cy.visit(`/trading/${marketId}`);
cy.wait('@Market');
console.log('marketId', marketId);
});
it('should not display steps if wallet is disconnected', () => {
cy.visit(`/trading/${markets[0].id}`);
it('should not display steps', () => {
cy.getByTestId('trading-connect-wallet')
.find('h3')
.should('have.text', 'Please connect your Vega wallet to make a trade');
@@ -58,273 +43,236 @@ describe('Market trade', { tags: '@smoke' }, () => {
.find('a')
.should('have.text', 'https://vega.xyz/wallet');
});
});
describe('Market trade', { tags: '@regression' }, () => {
beforeEach(() => {
cy.mockConsole();
cy.mockGQL((req) => {
aliasGQLQuery(req, 'Market', marketQuery(marketOverride));
});
cy.visit(`/trading/${marketId}`);
cy.connectVegaWallet();
cy.wait('@Market');
});
it('side selector should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').should(
'have.text',
'Long'
);
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('#step-1-control [aria-label^="Selected value"]').should(
'have.text',
'Short'
);
}
cy.get('#step-1-control [aria-label^="Selected value"]').should(
'have.text',
'Long'
);
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('#step-1-control [aria-label^="Selected value"]').should(
'have.text',
'Short'
);
});
it('side selector mobile view should work well', () => {
if (markets?.length) {
cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.getByTestId('next-button').scrollIntoView().click();
cy.viewport('iphone-xr');
cy.getByTestId('next-button').scrollIntoView().click();
cy.get('button[aria-label="Open long position"]').should(
'have.class',
'selected'
);
cy.get('button[aria-label="Open short position"]').should(
'not.have.class',
'selected'
);
cy.get('button[aria-label="Open long position"]').should(
'have.class',
'selected'
);
cy.get('button[aria-label="Open short position"]').should(
'not.have.class',
'selected'
);
cy.get('button[aria-label="Open short position"]').click();
cy.get('button[aria-label="Open long position"]').should(
'not.have.class',
'selected'
);
cy.get('button[aria-label="Open short position"]').should(
'have.class',
'selected'
);
cy.getByTestId('next-button').scrollIntoView().click();
cy.get('#step-1-control').should(
'contain.html',
'aria-label="Selected value Short"'
);
}
cy.get('button[aria-label="Open short position"]').click();
cy.get('button[aria-label="Open long position"]').should(
'not.have.class',
'selected'
);
cy.get('button[aria-label="Open short position"]').should(
'have.class',
'selected'
);
cy.getByTestId('next-button').scrollIntoView().click();
cy.get('#step-1-control').should(
'contain.html',
'aria-label="Selected value Short"'
);
});
it('size slider should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
cy.get('#step-2-panel').find('[role="slider"]').type('{rightarrow}');
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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
cy.get('#step-2-panel').find('[role="slider"]').type('{rightarrow}');
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '2');
}
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '2');
});
it('percentage selection should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
cy.getByTestId('max-label').should('have.text', '21');
cy.getByTestId('max-label').should('have.text', '10');
cy.getByTestId('percentage-selector')
.find('button')
.contains('Max')
.click();
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '21');
}
cy.getByTestId('percentage-selector')
.find('button')
.contains('Max')
.click();
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '10');
});
it('size input should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('input')
.type('{backspace}2');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '2');
cy.get('button').contains('Max').click();
}
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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel').find('dd').eq(0).find('input').type('{backspace}2');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '2');
cy.get('button').contains('Max').click();
});
it('slippage value should be displayed', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.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-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.01%');
});
it('allow slippage value to be adjusted', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.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.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.01%');
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.getByTestId('slippage-dialog').find('button').click();
cy.get('#step-2-panel')
.find('dl')
.eq(2)
.find('dd')
.should('have.text', '1%');
}
cy.get('#step-2-panel')
.find('dl')
.eq(2)
.find('dd')
.should('have.text', '1%');
});
it('notional position size should be present', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel')
.find('dd')
.eq(0)
.find('input')
.type('{backspace}2');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel')
.find('dt')
.eq(2)
.should('have.text', 'Est. Position Size (tDAI)');
cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012');
}
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('#step-2-panel')
.find('dd')
.eq(0)
.find('button')
.should('have.text', '1');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel').find('dd').eq(0).find('input').type('{backspace}2');
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
cy.get('#step-2-panel')
.find('dt')
.eq(2)
.should('have.text', 'Est. Position Size (tDAI)');
cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012');
});
it('total fees should be displayed', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.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('#step-2-panel')
.find('dt')
.eq(3)
.should('have.text', 'Est. Fees (tDAI)');
cy.get('#step-2-panel')
.find('dd')
.eq(3)
.should('have.text', '3.00 (3.03%)');
}
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('#step-2-panel')
.find('dt')
.eq(3)
.should('have.text', 'Est. Fees (tDAI)');
cy.get('#step-2-panel')
.find('dd')
.eq(3)
.should('have.text', '3.00 (3.03%)');
});
it('order review should display proper calculations', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.get('#step-3-control').click();
cy.get('#step-3-control').click();
cy.getByTestId('review-trade')
.get('#contracts_tooltip_trigger')
.trigger('click')
.realTouch();
cy.getByTestId('review-trade')
.get('#contracts_tooltip_trigger')
.trigger('click')
.realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The number of contracts determines'
);
cy.get('#step-3-panel').find('dd').eq(1).should('have.text', '1');
cy.get('[data-radix-popper-content-wrapper]').contains(
'The number of contracts determines'
);
cy.get('#step-3-panel').find('dd').eq(1).should('have.text', '1');
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
cy.get('#step-3-panel')
.find('dd')
.eq(3)
.should('have.text', '3.00 (3.03%)');
cy.get('#step-3-panel')
.find('dd')
.eq(3)
.should('have.text', '3.00 (3.03%)');
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
cy.get('#step-3-panel')
.find('dd')
.eq(4)
.should('have.text', '45,126.90058');
cy.getByTestId('place-order').should('be.enabled').click();
}
cy.getByTestId('place-order').should('be.enabled').click();
});
it('info tooltip on mobile view should work well', () => {
if (markets?.length) {
cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
cy.get('#step-3-control').click();
cy.viewport('iphone-xr');
cy.get('#step-3-control').click();
// Start from the bottom tooltip to ensure the tooltip above
// can be interacted with
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The notional size represents the position size'
);
// Start from the bottom tooltip to ensure the tooltip above
// can be interacted with
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The notional size represents the position size'
);
cy.getByTestId('review-trade')
.get('#contracts_tooltip_trigger')
.realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The number of contracts determines'
);
}
cy.getByTestId('review-trade')
.get('#contracts_tooltip_trigger')
.realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The number of contracts determines'
);
});
});
@@ -1,20 +1,16 @@
import { aliasQuery } from '@vegaprotocol/cypress';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import {
generatePositions,
emptyPositions,
generateMargins,
} from '../support/mocks/generate-positions';
import { generateAccounts } from '../support/mocks/generate-accounts';
import { generateAssets } from '../support/mocks/generate-assets';
import { generateOrders } from '../support/mocks/generate-orders';
import { generateFills } from '../support/mocks/generate-fills';
import {
generateFillsMarkets,
generateMarketsData,
generatePositionsMarkets,
} from '../support/mocks/generate-markets';
import { generateChainId } from '../support/mocks/generate-chain-id';
import { generateStatistics } from '../support/mocks/generate-statistics';
accountsQuery,
assetsQuery,
chainIdQuery,
fillsQuery,
marginsQuery,
marketsDataQuery,
marketsQuery,
ordersQuery,
positionsQuery,
statisticsQuery,
} from '@vegaprotocol/mock';
describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
it('button for wallet connect should work', () => {
@@ -29,14 +25,14 @@ describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
describe('Portfolio page tabs', { tags: '@smoke' }, () => {
before(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', generatePositions());
aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'Markets', generatePositionsMarkets());
aliasQuery(req, 'MarketsData', generateMarketsData());
aliasQuery(req, 'Accounts', generateAccounts());
aliasQuery(req, 'Assets', generateAssets());
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'Positions', positionsQuery());
aliasGQLQuery(req, 'Margins', marginsQuery());
aliasGQLQuery(req, 'Markets', marketsQuery());
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
aliasGQLQuery(req, 'Accounts', accountsQuery());
aliasGQLQuery(req, 'Assets', assetsQuery());
});
});
@@ -63,21 +59,21 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Assets view', () => {
before(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', generatePositions());
aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'Markets', generatePositionsMarkets());
aliasQuery(req, 'MarketsData', generateMarketsData());
aliasQuery(req, 'Accounts', generateAccounts());
aliasQuery(req, 'Assets', generateAssets());
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'Positions', positionsQuery());
aliasGQLQuery(req, 'Margins', marginsQuery());
aliasGQLQuery(req, 'Markets', marketsQuery());
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
aliasGQLQuery(req, 'Accounts', accountsQuery());
aliasGQLQuery(req, 'Assets', assetsQuery());
});
cy.visit('/portfolio/assets');
cy.connectVegaWallet();
});
it('data should be properly rendered', () => {
cy.get('.ag-center-cols-container .ag-row').should('have.length', 3);
cy.get('.ag-center-cols-container .ag-row').should('have.length', 5);
cy.get(
'.ag-center-cols-container [row-id="ACCOUNT_TYPE_GENERAL-asset-id-null"]'
)
@@ -94,14 +90,14 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Positions view', () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', generatePositions());
aliasQuery(req, 'Accounts', generateAccounts());
aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'Markets', generatePositionsMarkets());
aliasQuery(req, 'MarketsData', generateMarketsData());
aliasQuery(req, 'Assets', generateAssets());
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'Positions', positionsQuery());
aliasGQLQuery(req, 'Margins', marginsQuery());
aliasGQLQuery(req, 'Markets', marketsQuery());
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
aliasGQLQuery(req, 'Accounts', accountsQuery());
aliasGQLQuery(req, 'Assets', assetsQuery());
});
cy.visit('/portfolio/positions');
cy.connectVegaWallet();
@@ -115,10 +111,10 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Orders view', () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Orders', generateOrders());
aliasQuery(req, 'Markets', generateFillsMarkets());
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'Orders', ordersQuery());
aliasGQLQuery(req, 'Markets', marketsQuery());
});
cy.visit('/portfolio/orders');
cy.connectVegaWallet();
@@ -132,10 +128,11 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Fills view', () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Fills', generateFills());
aliasQuery(req, 'Markets', generateFillsMarkets());
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'Orders', ordersQuery());
aliasGQLQuery(req, 'Markets', marketsQuery());
aliasGQLQuery(req, 'Fills', fillsQuery());
});
cy.visit('/portfolio/fills');
cy.connectVegaWallet();
@@ -149,20 +146,20 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
describe('Empty views', () => {
beforeEach(() => {
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', generateChainId());
aliasQuery(req, 'Statistics', generateStatistics());
aliasQuery(req, 'Positions', emptyPositions());
aliasQuery(req, 'Accounts', { party: null });
aliasQuery(req, 'Orders', { party: null });
aliasQuery(req, 'Fills', { party: null });
aliasQuery(req, 'Markets', {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'Positions', { party: null });
aliasGQLQuery(req, 'Accounts', { party: null });
aliasGQLQuery(req, 'Orders', { party: null });
aliasGQLQuery(req, 'Fills', { party: null });
aliasGQLQuery(req, 'Markets', {
marketsConnection: { edges: [], __typename: 'MarketConnection' },
});
aliasQuery(req, 'Assets', {
aliasGQLQuery(req, 'Assets', {
assetsConnection: { edges: null, __typename: 'AssetsConnection' },
});
aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'MarketsData', generateMarketsData());
aliasGQLQuery(req, 'Margins', marginsQuery());
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
});
cy.visit('/portfolio');
cy.connectVegaWallet();
@@ -1,9 +0,0 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
@@ -0,0 +1,56 @@
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
import {
accountsQuery,
assetsQuery,
chainIdQuery,
estimateOrderQuery,
fillsQuery,
marginsQuery,
marketDataQuery,
marketDepthQuery,
marketQuery,
marketsCandlesQuery,
marketsDataQuery,
marketsQuery,
ordersQuery,
positionsQuery,
statisticsQuery,
} from '@vegaprotocol/mock';
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
mockConsole(): void;
}
}
}
const mockPage = (req: CyHttpMessages.IncomingHttpRequest) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'Markets', marketsQuery());
aliasGQLQuery(req, 'MarketsCandles', marketsCandlesQuery());
aliasGQLQuery(req, 'MarketsData', marketsDataQuery());
aliasGQLQuery(req, 'MarketData', marketDataQuery());
aliasGQLQuery(req, 'Market', marketQuery());
aliasGQLQuery(req, 'MarketTags', {});
aliasGQLQuery(req, 'EstimateOrder', estimateOrderQuery());
aliasGQLQuery(req, 'MarketNames', {});
aliasGQLQuery(req, 'MarketDepth', marketDepthQuery());
aliasGQLQuery(req, 'Positions', positionsQuery());
aliasGQLQuery(req, 'Margins', marginsQuery());
aliasGQLQuery(req, 'Accounts', accountsQuery());
aliasGQLQuery(req, 'Assets', assetsQuery());
aliasGQLQuery(req, 'SimpleMarkets', marketsQuery());
aliasGQLQuery(req, 'Orders', ordersQuery());
aliasGQLQuery(req, 'Fills', fillsQuery());
};
export const addMockConsole = () => {
Cypress.Commands.add('mockConsole', () => {
cy.mockGQL(mockPage);
});
};
+3 -32
View File
@@ -1,36 +1,7 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
import '@vegaprotocol/cypress';
import 'cypress-real-events/support';
// Import commands.js using ES2015 syntax:
import './commands';
import registerCypressGrep from '@cypress/grep';
import { aliasQuery } from '@vegaprotocol/cypress';
registerCypressGrep();
import { addMockConsole } from './console-mock';
before(() => {
// Mock chainId fetch which happens on every page for wallet connection
cy.mockGQL((req) => {
aliasQuery(req, 'ChainId', {
statistics: {
__typename: 'Statistics',
chainId:
Cypress.env('VEGA_ENV').toLowerCase() ||
'vega-fairground-202210041151',
},
});
});
});
registerCypressGrep();
addMockConsole();
@@ -1,156 +0,0 @@
import type { Market } from '@vegaprotocol/market-list';
import { Schema } from '@vegaprotocol/types';
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
export const protoCandles = [
{ open: '9556163', close: '9587028', __typename: 'Candle' },
{
open: '9587028',
close: '9769899',
__typename: 'Candle',
},
{ open: '9769899', close: '9586292', __typename: 'Candle' },
{
open: '9586292',
close: '9261774',
__typename: 'Candle',
},
{ open: '9261773', close: '9236369', __typename: 'Candle' },
{
open: '9236369',
close: '9226070',
__typename: 'Candle',
},
{ open: '9226077', close: '9233252', __typename: 'Candle' },
{
open: '9249854',
close: '9333038',
__typename: 'Candle',
},
{ open: '9333038', close: '9410371', __typename: 'Candle' },
{
open: '9410371',
close: '9626249',
__typename: 'Candle',
},
{ open: '9626247', close: '9493253', __typename: 'Candle' },
{
open: '9493253',
close: '9309054',
__typename: 'Candle',
},
{ open: '9309054', close: '9378428', __typename: 'Candle' },
{
open: '9378428',
close: '9352996',
__typename: 'Candle',
},
{ open: '9352996', close: '9451142', __typename: 'Candle' },
{
open: '9451142',
close: '9691070',
__typename: 'Candle',
},
{ open: '9691071', close: '9622031', __typename: 'Candle' },
{
open: '9622034',
close: '9519285',
__typename: 'Candle',
},
{ open: '9528904', close: '9671275', __typename: 'Candle' },
{
open: '9671275',
close: '9988454',
__typename: 'Candle',
},
{ open: '9982457', close: '10085537', __typename: 'Candle' },
{
open: '10085537',
close: '9967390',
__typename: 'Candle',
},
{ open: '9967390', close: '9974844', __typename: 'Candle' },
{
open: '9974844',
close: '9940706',
__typename: 'Candle',
},
];
export const protoMarket: Market = {
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
state: Schema.MarketState.STATE_ACTIVE,
decimalPlaces: 5,
positionDecimalPlaces: 0,
marketTimestamps: {
__typename: 'MarketTimestamps',
close: '',
open: '',
},
fees: {
__typename: 'Fees',
factors: {
__typename: 'FeeFactors',
makerFee: '',
infrastructureFee: '',
liquidityFee: '',
},
},
tradableInstrument: {
instrument: {
id: '',
code: 'AAVEDAI.MF21',
name: 'AAVEDAI Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:2839D9B2329C9E70',
'base:AAVE',
'quote:DAI',
'class:fx/crypto',
'monthly',
'sector:defi',
],
__typename: 'InstrumentMetadata',
},
product: {
__typename: 'Future',
quoteName: 'DAI',
settlementAsset: {
__typename: 'Asset',
id: 'asset-id',
symbol: 'tDAI',
decimals: 5,
},
},
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
__typename: 'Market',
};
export const singleMarket: SingleMarketFieldsFragment = {
...protoMarket,
tradableInstrument: {
...protoMarket.tradableInstrument,
instrument: {
...protoMarket.tradableInstrument.instrument,
product: {
...protoMarket.tradableInstrument.instrument.product,
settlementAsset: {
...protoMarket.tradableInstrument.instrument.product.settlementAsset,
id: 'dai-id',
name: 'DAI Name',
},
dataSourceSpecForTradingTermination: {
id: 'oid',
},
},
},
},
depth: {
__typename: 'MarketDepth',
lastTrade: { price: '9893006', __typename: 'Trade' },
},
};
@@ -1,95 +0,0 @@
import merge from 'lodash/merge';
import type { AccountsQuery } from '@vegaprotocol/accounts';
import { Schema as Types } from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest';
export const generateAccounts = (
override?: PartialDeep<AccountsQuery>
): AccountsQuery => {
const defaultAccounts: AccountsQuery = {
party: {
__typename: 'Party',
id: Cypress.env('VEGA_PUBLIC_KEY'),
accountsConnection: {
__typename: 'AccountsConnection',
edges: [
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '100000000',
market: null,
asset: {
__typename: 'Asset',
id: 'asset-id',
},
},
},
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '100000000',
market: {
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
__typename: 'Market',
},
asset: {
__typename: 'Asset',
id: 'asset-id-2',
},
},
},
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
balance: '1000',
market: {
__typename: 'Market',
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
},
asset: {
__typename: 'Asset',
id: 'asset-id',
},
},
},
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
balance: '1000',
market: {
__typename: 'Market',
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
},
asset: {
__typename: 'Asset',
id: 'asset-id-2',
},
},
},
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '100000000',
market: null,
asset: {
__typename: 'Asset',
id: 'asset-0',
},
},
},
],
},
},
};
return merge(defaultAccounts, override);
};
@@ -1,120 +0,0 @@
import merge from 'lodash/merge';
import type { AssetsQuery } from '@vegaprotocol/assets';
import { Schema as Types } from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest';
export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
const defaultAssets: AssetsQuery = {
assetsConnection: {
edges: [
{
node: {
id: 'asset-id',
symbol: 'tEURO',
decimals: 5,
name: 'Euro',
source: {
__typename: 'ERC20',
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
lifetimeLimit: '1',
withdrawThreshold: '2',
},
quantum: '',
status: Types.AssetStatus.STATUS_ENABLED,
infrastructureFeeAccount: {
balance: '1',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: {
balance: '2',
__typename: 'AccountBalance',
},
takerFeeRewardAccount: {
balance: '3',
__typename: 'AccountBalance',
},
makerFeeRewardAccount: {
balance: '4',
__typename: 'AccountBalance',
},
lpFeeRewardAccount: {
balance: '5',
__typename: 'AccountBalance',
},
marketProposerRewardAccount: {
balance: '6',
__typename: 'AccountBalance',
},
__typename: 'Asset',
},
},
{
node: {
id: 'asset-id-2',
symbol: 'tDAI',
decimals: 5,
name: 'DAI',
source: {
__typename: 'ERC20',
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
lifetimeLimit: '1',
withdrawThreshold: '2',
},
quantum: '',
status: Types.AssetStatus.STATUS_ENABLED,
infrastructureFeeAccount: {
balance: '1',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: {
balance: '2',
__typename: 'AccountBalance',
},
takerFeeRewardAccount: {
balance: '3',
__typename: 'AccountBalance',
},
makerFeeRewardAccount: {
balance: '4',
__typename: 'AccountBalance',
},
lpFeeRewardAccount: {
balance: '5',
__typename: 'AccountBalance',
},
marketProposerRewardAccount: {
balance: '6',
__typename: 'AccountBalance',
},
__typename: 'Asset',
},
},
{
node: {
id: 'asset-0',
symbol: 'AST0',
decimals: 5,
name: 'Asto',
source: {
__typename: 'BuiltinAsset',
maxFaucetAmountMint: '3',
},
quantum: '',
status: Types.AssetStatus.STATUS_ENABLED,
infrastructureFeeAccount: {
balance: '0',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: null,
takerFeeRewardAccount: null,
makerFeeRewardAccount: null,
lpFeeRewardAccount: null,
marketProposerRewardAccount: null,
__typename: 'Asset',
},
},
],
},
};
return merge(defaultAssets, override);
};
@@ -1,16 +0,0 @@
import type { ChainIdQuery } from '@vegaprotocol/react-helpers';
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
export const generateChainId = (
override?: PartialDeep<ChainIdQuery>
): ChainIdQuery => {
const defaultResult = {
statistics: {
__typename: 'Statistics',
chainId: Cypress.env('VEGA_ENV').toLowerCase() || 'test-chain-id',
},
};
return merge(defaultResult, override);
};
@@ -1,17 +0,0 @@
export const generateEstimateOrder = () => {
return {
estimateOrder: {
fee: {
__typename: 'TradeFee',
makerFee: '100000',
liquidityFee: '100000',
infrastructureFee: '100000',
},
marginLevels: {
initialLevel: '2844054.80937741220203',
__typename: 'MarginLevels',
},
__typename: 'OrderEstimate',
},
};
};
@@ -1,111 +0,0 @@
import type { FillsQuery, FillFieldsFragment } from '@vegaprotocol/fills';
import { Schema } from '@vegaprotocol/types';
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
export const generateFills = (
override?: PartialDeep<FillsQuery>
): FillsQuery => {
const fills: FillFieldsFragment[] = [
generateFill({
buyer: {
id: Cypress.env('VEGA_PUBLIC_KEY'),
},
}),
generateFill({
id: '1',
seller: {
id: Cypress.env('VEGA_PUBLIC_KEY'),
},
aggressor: Schema.Side.SIDE_SELL,
buyerFee: {
infrastructureFee: '5000',
},
market: {
id: 'market-1',
},
}),
generateFill({
id: '2',
seller: {
id: Cypress.env('VEGA_PUBLIC_KEY'),
},
aggressor: Schema.Side.SIDE_BUY,
}),
generateFill({
id: '3',
aggressor: Schema.Side.SIDE_SELL,
market: {
id: 'market-2',
},
buyer: {
id: Cypress.env('VEGA_PUBLIC_KEY'),
},
}),
];
const defaultResult: FillsQuery = {
party: {
id: 'buyer-id',
tradesConnection: {
__typename: 'TradeConnection',
edges: fills.map((f) => {
return {
__typename: 'TradeEdge',
node: f,
cursor: '3',
};
}),
pageInfo: {
__typename: 'PageInfo',
startCursor: '1',
endCursor: '2',
hasNextPage: false,
hasPreviousPage: false,
},
},
__typename: 'Party',
},
};
return merge(defaultResult, override);
};
export const generateFill = (override?: PartialDeep<FillFieldsFragment>) => {
const defaultFill: FillFieldsFragment = {
__typename: 'Trade',
id: '0',
createdAt: new Date().toISOString(),
price: '10000000',
size: '50000',
buyOrder: 'buy-order',
sellOrder: 'sell-order',
aggressor: Schema.Side.SIDE_BUY,
buyer: {
__typename: 'Party',
id: 'buyer-id',
},
seller: {
__typename: 'Party',
id: 'seller-id',
},
buyerFee: {
__typename: 'TradeFee',
makerFee: '100',
infrastructureFee: '100',
liquidityFee: '100',
},
sellerFee: {
__typename: 'TradeFee',
makerFee: '200',
infrastructureFee: '200',
liquidityFee: '200',
},
market: {
__typename: 'Market',
id: 'market-0',
},
};
return merge(defaultFill, override);
};
@@ -1,210 +0,0 @@
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import type { MarketDepthQuery } from '../../../../../libs/market-depth/src/lib/__generated___/MarketDepth';
export const generateMarketDepth = (
override?: PartialDeep<MarketDepthQuery>
): MarketDepthQuery => {
const defaultResult: MarketDepthQuery = {
market: {
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
depth: {
sell: [
{
price: '9893007',
volume: '3',
numberOfOrders: '3',
__typename: 'PriceLevel',
},
{
price: '9893010',
volume: '4',
numberOfOrders: '4',
__typename: 'PriceLevel',
},
{
price: '9893012',
volume: '1',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893015',
volume: '1',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893017',
volume: '2',
numberOfOrders: '2',
__typename: 'PriceLevel',
},
{
price: '9893021',
volume: '4',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893025',
volume: '5',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893125',
volume: '4',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893135',
volume: '2',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893165',
volume: '5',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893175',
volume: '3',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893185',
volume: '3',
numberOfOrders: '3',
__typename: 'PriceLevel',
},
{
price: '9894185',
volume: '1',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9894585',
volume: '1',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9895585',
volume: '4',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9896585',
volume: '2',
numberOfOrders: '2',
__typename: 'PriceLevel',
},
],
buy: [
{
price: '9893005',
volume: '4',
numberOfOrders: '3',
__typename: 'PriceLevel',
},
{
price: '9893003',
volume: '2',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9893001',
volume: '1',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9892006',
volume: '3',
numberOfOrders: '2',
__typename: 'PriceLevel',
},
{
price: '9891006',
volume: '2',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9891001',
volume: '1',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9890101',
volume: '2',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9890091',
volume: '5',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9890081',
volume: '4',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9890050',
volume: '2',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9890040',
volume: '6',
numberOfOrders: '3',
__typename: 'PriceLevel',
},
{
price: '9890030',
volume: '6',
numberOfOrders: '2',
__typename: 'PriceLevel',
},
{
price: '9890021',
volume: '3',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9890011',
volume: '1',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
{
price: '9890001',
volume: '11',
numberOfOrders: '1',
__typename: 'PriceLevel',
},
],
sequenceNumber: '1661773865550746910',
__typename: 'MarketDepth',
},
__typename: 'Market',
},
};
return merge(defaultResult, override);
};
@@ -1,9 +0,0 @@
export const generateMarketMarkPrice = () => {
return {
market: {
decimalPlaces: 5,
data: { markPrice: '692748', __typename: 'MarketData' },
__typename: 'Market',
},
};
};
@@ -1,136 +0,0 @@
import { protoMarket } from './commons';
export const generateMarketNames = () => {
return {
markets: [
{ ...protoMarket },
{
id: '1d7ddf67dac4924db03f5bf58571a7bcb1908d70c66580467717aabc5345b68a',
state: 'STATE_SUSPENDED',
tradableInstrument: {
instrument: {
code: 'AAPL.MF21',
name: 'Apple Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:4899E01009F1A721',
'quote:USD',
'ticker:AAPL',
'class:equities/single-stock-futures',
'sector:tech',
'listing_venue:NASDAQ',
'country:US',
],
__typename: 'InstrumentMetadata',
},
product: { quoteName: 'USD', __typename: 'Future' },
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
__typename: 'Market',
},
{
id: '87ae87cd3244fc1fab4b0e2dad2437879864192bb969f3109b69293421644c8b',
state: 'STATE_SUSPENDED',
tradableInstrument: {
instrument: {
code: 'TSLA.QM21',
name: 'Tesla Quarterly (30 Jun 2022)',
metadata: {
tags: [
'formerly:5A86B190C384997F',
'quote:EURO',
'ticker:TSLA',
'class:equities/single-stock-futures',
'sector:tech',
'listing_venue:NASDAQ',
'country:US',
],
__typename: 'InstrumentMetadata',
},
product: { quoteName: 'EURO', __typename: 'Future' },
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
__typename: 'Market',
},
{
id: '69205712a854f1bbfb69fa3d11b60e01a1e249bafb5ece88115e7451e8ef07b3',
state: 'STATE_SUSPENDED',
tradableInstrument: {
instrument: {
code: 'BTCUSD.MF21',
name: 'BTCUSD Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:076BB86A5AA41E3E',
'base:BTC',
'quote:USD',
'class:fx/crypto',
'monthly',
'sector:crypto',
],
__typename: 'InstrumentMetadata',
},
product: { quoteName: 'USD', __typename: 'Future' },
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
__typename: 'Market',
},
{
id: 'ethbtc-quaterly',
state: 'STATE_ACTIVE',
tradableInstrument: {
instrument: {
code: 'ETHBTC.QM21',
name: 'ETHBTC Quarterly (30 Jun 2022)',
metadata: {
tags: [
'formerly:1F0BB6EB5703B099',
'base:ETH',
'quote:BTC',
'class:fx/crypto',
'quarterly',
'sector:crypto',
],
__typename: 'InstrumentMetadata',
},
product: { quoteName: 'BTC', __typename: 'Future' },
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
__typename: 'Market',
},
{
id: '3c62b2714c4332d1a689a5352bff090e6aabccfd6bd87ce018936b38372530c9',
state: 'STATE_ACTIVE',
tradableInstrument: {
instrument: {
code: 'UNIDAI.MF21',
name: 'UNIDAI Monthly (30 Jun 2022)',
metadata: {
tags: [
'formerly:3C58ED2A4A6C5D7E',
'base:UNI',
'quote:DAI',
'class:fx/crypto',
'monthly',
'sector:defi',
],
__typename: 'InstrumentMetadata',
},
product: { quoteName: 'DAI', __typename: 'Future' },
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
__typename: 'Market',
},
],
};
};
@@ -1,72 +0,0 @@
import type { MarketPositionsQuery } from '@vegaprotocol/deal-ticket';
import { Schema } from '@vegaprotocol/types';
export const generateMarketPositions = (): MarketPositionsQuery => {
return {
party: {
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
accountsConnection: {
__typename: 'AccountsConnection',
edges: [
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
decimals: 5,
},
balance: '400000000000000000000',
market: {
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
__typename: 'Market',
},
},
},
{
__typename: 'AccountEdge',
node: {
type: Schema.AccountType.ACCOUNT_TYPE_MARGIN,
asset: {
decimals: 5,
},
balance: '265329',
market: {
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
__typename: 'Market',
},
},
},
],
},
positionsConnection: {
edges: [
{
node: {
openVolume: '3',
market: {
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
__typename: 'Market',
},
__typename: 'Position',
},
__typename: 'PositionEdge',
},
{
node: {
openVolume: '12',
market: {
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
__typename: 'Market',
},
__typename: 'Position',
},
__typename: 'PositionEdge',
},
],
__typename: 'PositionConnection',
},
__typename: 'Party',
},
};
};
@@ -1,25 +0,0 @@
export const generateMarketTags = () => {
return {
market: {
tradableInstrument: {
instrument: {
metadata: {
tags: [
'formerly:2839D9B2329C9E70',
'base:AAVE',
'quote:DAI',
'class:fx/crypto',
'monthly',
'sector:defi',
'settlement:2022-08-01',
],
__typename: 'InstrumentMetadata',
},
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
__typename: 'Market',
},
};
};
File diff suppressed because it is too large Load Diff
@@ -1,143 +0,0 @@
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
import type { OrdersQuery, OrderFieldsFragment } from '@vegaprotocol/orders';
import { Schema } from '@vegaprotocol/types';
export const generateOrders = (
override?: PartialDeep<OrdersQuery>
): OrdersQuery => {
const orders: OrderFieldsFragment[] = [
{
__typename: 'Order',
id: '066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
market: {
__typename: 'Market',
id: 'market-0',
},
size: '10',
type: Schema.OrderType.TYPE_LIMIT,
status: Schema.OrderStatus.STATUS_FILLED,
side: Schema.Side.SIDE_BUY,
remaining: '0',
price: '20000000',
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
createdAt: new Date(2020, 1, 30).toISOString(),
updatedAt: null,
expiresAt: null,
rejectionReason: null,
liquidityProvision: null,
peggedOrder: null,
},
{
__typename: 'Order',
id: '48DB6767E4E4E0F649C5A13ABFADE39F8451C27DA828DAF14B7A1E8E5EBDAD99',
market: {
__typename: 'Market',
id: 'market-1',
},
size: '1',
type: Schema.OrderType.TYPE_LIMIT,
status: Schema.OrderStatus.STATUS_FILLED,
side: Schema.Side.SIDE_BUY,
remaining: '0',
price: '100',
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
createdAt: new Date(2020, 1, 29).toISOString(),
updatedAt: null,
expiresAt: null,
rejectionReason: null,
liquidityProvision: null,
peggedOrder: null,
},
{
__typename: 'Order',
id: '4e93702990712c41f6995fcbbd94f60bb372ad12d64dfa7d96d205c49f790336',
market: {
__typename: 'Market',
id: 'market-2',
},
size: '1',
type: Schema.OrderType.TYPE_LIMIT,
status: Schema.OrderStatus.STATUS_FILLED,
side: Schema.Side.SIDE_BUY,
remaining: '0',
price: '20000',
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
createdAt: new Date(2020, 1, 28).toISOString(),
updatedAt: null,
expiresAt: null,
rejectionReason: null,
liquidityProvision: null,
peggedOrder: null,
},
{
__typename: 'Order',
id: '94737d2bafafa4bc3b80a56ef084ae52a983b91aa067c31e243c61a0f962a836',
market: {
__typename: 'Market',
id: 'market-3',
},
size: '1',
type: Schema.OrderType.TYPE_LIMIT,
status: Schema.OrderStatus.STATUS_ACTIVE,
side: Schema.Side.SIDE_BUY,
remaining: '0',
price: '100000',
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
createdAt: new Date(2020, 1, 27).toISOString(),
updatedAt: null,
expiresAt: null,
rejectionReason: null,
liquidityProvision: null,
peggedOrder: null,
},
{
__typename: 'Order',
id: '94aead3ca92dc932efcb503631b03a410e2a5d4606cae6083e2406dc38e52f78',
market: {
__typename: 'Market',
id: 'market-3',
},
size: '10',
type: Schema.OrderType.TYPE_LIMIT,
status: Schema.OrderStatus.STATUS_PARTIALLY_FILLED,
side: Schema.Side.SIDE_SELL,
remaining: '3',
price: '100000',
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
createdAt: new Date(2020, 1, 27).toISOString(),
updatedAt: null,
expiresAt: null,
liquidityProvision: null,
peggedOrder: null,
rejectionReason: null,
},
];
const defaultResult: OrdersQuery = {
party: {
id: Cypress.env('VEGA_PUBLIC_KEY'),
ordersConnection: {
__typename: 'OrderConnection',
edges: orders.map((f) => {
return {
__typename: 'OrderEdge',
node: f,
cursor: f.id,
};
}),
pageInfo: {
__typename: 'PageInfo',
startCursor:
'066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
endCursor:
'94737d2bafafa4bc3b80a56ef084ae52a983b91aa067c31e243c61a0f962a836',
hasNextPage: false,
hasPreviousPage: false,
},
},
__typename: 'Party',
},
};
return merge(defaultResult, override);
};
@@ -1,81 +0,0 @@
import merge from 'lodash/merge';
import type { PartyBalanceQuery } from '@vegaprotocol/deal-ticket';
import type { PartialDeep } from 'type-fest';
import { Schema as Types } from '@vegaprotocol/types';
export const generatePartyBalance = (
override?: PartialDeep<PartyBalanceQuery>
): PartyBalanceQuery => {
const defaultResult: PartyBalanceQuery = {
party: {
accountsConnection: {
__typename: 'AccountsConnection',
edges: [
{
__typename: 'AccountEdge',
node: {
balance: '88474051',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: 'dai-id',
symbol: 'tDAI',
name: 'tDAI TEST',
decimals: 5,
__typename: 'Asset',
},
__typename: 'AccountBalance',
},
},
{
__typename: 'AccountEdge',
node: {
balance: '100000000',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
name: 'tEURO TEST',
decimals: 5,
__typename: 'Asset',
},
__typename: 'AccountBalance',
},
},
{
__typename: 'AccountEdge',
node: {
balance: '3412867',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: 'dai-id',
symbol: 'tDAI',
name: 'tDAI TEST',
decimals: 5,
__typename: 'Asset',
},
__typename: 'AccountBalance',
},
},
{
__typename: 'AccountEdge',
node: {
balance: '70007',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: 'dai-id',
symbol: 'tDAI',
name: 'tDAI TEST',
decimals: 5,
__typename: 'Asset',
},
__typename: 'AccountBalance',
},
},
],
},
__typename: 'Party',
},
};
return merge(defaultResult, override);
};
@@ -1,40 +0,0 @@
import type { PartyMarketDataQuery } from '@vegaprotocol/deal-ticket';
import { Schema as Types } from '@vegaprotocol/types';
export const generatePartyMarketData = (): PartyMarketDataQuery => {
return {
party: {
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
accountsConnection: {
__typename: 'AccountsConnection',
edges: [
{
__typename: 'AccountEdge',
node: {
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '1200000',
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
market: null,
__typename: 'AccountBalance',
},
},
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '0.000000001',
asset: {
__typename: 'Asset',
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
decimals: 0,
},
},
},
],
},
marginsConnection: { edges: null, __typename: 'MarginConnection' },
__typename: 'Party',
},
};
};
@@ -1,145 +0,0 @@
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
import type {
PositionsQuery,
PositionFieldsFragment,
MarginsQuery,
} from '@vegaprotocol/positions';
export const generatePositions = (
override?: PartialDeep<PositionsQuery>
): PositionsQuery => {
const nodes: PositionFieldsFragment[] = [
{
__typename: 'Position',
realisedPNL: '0',
openVolume: '6',
unrealisedPNL: '895000',
averageEntryPrice: '1129935',
updatedAt: '2022-07-28T15:09:34.441143Z',
market: {
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
__typename: 'Market',
},
},
{
__typename: 'Position',
realisedPNL: '100',
openVolume: '20',
unrealisedPNL: '895000',
averageEntryPrice: '8509338',
updatedAt: '2022-07-28T15:09:34.441143Z',
market: {
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
__typename: 'Market',
},
},
{
realisedPNL: '0',
openVolume: '1',
unrealisedPNL: '-22519',
averageEntryPrice: '84400088',
updatedAt: '2022-07-28T14:53:54.725477Z',
market: {
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
__typename: 'Market',
},
__typename: 'Position',
},
];
const defaultResult: PositionsQuery = {
party: {
__typename: 'Party',
id: Cypress.env('VEGA_PUBLIC_KEY'),
positionsConnection: {
__typename: 'PositionConnection',
edges: nodes.map((node) => {
return {
__typename: 'PositionEdge',
node,
};
}),
},
},
};
return merge(defaultResult, override);
};
export const emptyPositions = (): PositionsQuery => {
return {
party: {
id: Cypress.env('VEGA_PUBLIC_KEY'),
positionsConnection: { edges: null, __typename: 'PositionConnection' },
__typename: 'Party',
},
};
};
export const generateMargins = (): MarginsQuery => {
return {
party: {
id: Cypress.env('VEGA_PUBLIC_KEY'),
marginsConnection: {
edges: [
{
node: {
__typename: 'MarginLevels',
maintenanceLevel: '0',
searchLevel: '0',
initialLevel: '0',
collateralReleaseLevel: '0',
market: {
__typename: 'Market',
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
},
asset: {
__typename: 'Asset',
id: 'tDAI-id',
},
},
},
{
node: {
__typename: 'MarginLevels',
maintenanceLevel: '0',
searchLevel: '0',
initialLevel: '0',
collateralReleaseLevel: '0',
market: {
__typename: 'Market',
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
},
asset: {
__typename: 'Asset',
id: 'tDAI-id',
},
},
__typename: 'MarginEdge',
},
{
node: {
__typename: 'MarginLevels',
maintenanceLevel: '0',
searchLevel: '0',
initialLevel: '0',
collateralReleaseLevel: '0',
market: {
__typename: 'Market',
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
},
asset: {
__typename: 'Asset',
id: 'tEURO-id',
},
},
__typename: 'MarginEdge',
},
],
__typename: 'MarginConnection',
},
__typename: 'Party',
},
};
};
@@ -1,17 +0,0 @@
import type { StatisticsQuery } from '@vegaprotocol/environment';
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
export const generateStatistics = (
override?: PartialDeep<StatisticsQuery>
): StatisticsQuery => {
const defaultResult = {
statistics: {
__typename: 'Statistics',
chainId: Cypress.env('VEGA_ENV').toLowerCase() || 'test-chain-id',
blockHeight: '11',
},
};
return merge(defaultResult, override);
};
+18 -23
View File
@@ -1,7 +1,5 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { ThemeContext } from '@vegaprotocol/react-helpers';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
import {
VegaConnectDialog,
@@ -18,8 +16,7 @@ import useLocalValues from './hooks/use-local-values';
import type { InMemoryCacheConfig } from '@apollo/client';
function App() {
const [theme, toggleTheme] = useThemeSwitcher();
const localValues = useLocalValues(theme, toggleTheme);
const localValues = useLocalValues();
const {
vegaWalletDialog,
menu: { setMenuOpen },
@@ -56,25 +53,23 @@ function App() {
return (
<EnvironmentProvider>
<ThemeContext.Provider value={theme}>
<NetworkLoader cache={cacheConfig}>
<VegaWalletProvider>
<LocalContext.Provider value={localValues}>
<AppLoader>
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
<Header />
<Main />
<VegaConnectDialog connectors={Connectors} />
<VegaManageDialog
dialogOpen={vegaWalletDialog.manage}
setDialogOpen={vegaWalletDialog.setManage}
/>
</div>
</AppLoader>
</LocalContext.Provider>
</VegaWalletProvider>
</NetworkLoader>
</ThemeContext.Provider>
<NetworkLoader cache={cacheConfig}>
<VegaWalletProvider>
<LocalContext.Provider value={localValues}>
<AppLoader>
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
<Header />
<Main />
<VegaConnectDialog connectors={Connectors} />
<VegaManageDialog
dialogOpen={vegaWalletDialog.manage}
setDialogOpen={vegaWalletDialog.setManage}
/>
</div>
</AppLoader>
</LocalContext.Provider>
</VegaWalletProvider>
</NetworkLoader>
</EnvironmentProvider>
);
}
@@ -1,14 +1,11 @@
import React, {
forwardRef,
useCallback,
useContext,
useMemo,
useRef,
} from 'react';
import React, { forwardRef, useCallback, useMemo, useRef } from 'react';
import classNames from 'classnames';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
import { ThemeContext, useScreenDimensions } from '@vegaprotocol/react-helpers';
import {
useScreenDimensions,
useThemeSwitcher,
} from '@vegaprotocol/react-helpers';
import type {
GridOptions,
GetRowIdParams,
@@ -43,7 +40,7 @@ const ConsoleLiteGrid = <T extends { id?: string }>(
) => {
const { isMobile, screenSize } = useScreenDimensions();
const gridRef = useRef<AgGridReact | null>(null);
const theme = useContext(ThemeContext);
const { theme } = useThemeSwitcher();
const handleOnGridReady = useCallback(() => {
(
(ref as React.RefObject<AgGridReact>) || gridRef
@@ -1,18 +0,0 @@
query PartyBalanceQuery($partyId: ID!) {
party(id: $partyId) {
accountsConnection {
edges {
node {
type
balance
asset {
id
symbol
name
decimals
}
}
}
}
}
}
@@ -1,51 +1,54 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
import * as Types from '@vegaprotocol/types';
// ====================================================
// GraphQL query operation: MarketTags
// ====================================================
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 interface MarketTags_market_tradableInstrument_instrument_metadata {
__typename: "InstrumentMetadata";
/**
* An arbitrary list of tags to associated to associate to the Instrument (string list)
*/
tags: string[] | null;
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
}
}
}
}
}
`;
export interface MarketTags_market_tradableInstrument_instrument {
__typename: "Instrument";
/**
* Metadata for this instrument
*/
metadata: MarketTags_market_tradableInstrument_instrument_metadata;
}
export interface MarketTags_market_tradableInstrument {
__typename: "TradableInstrument";
/**
* An instance of, or reference to, a fully specified instrument.
*/
instrument: MarketTags_market_tradableInstrument_instrument;
}
export interface MarketTags_market {
__typename: "Market";
/**
* An instance of, or reference to, a tradable instrument.
*/
tradableInstrument: MarketTags_market_tradableInstrument;
}
export interface MarketTags {
/**
* An instrument that is trading on the Vega network
*/
market: MarketTags_market | null;
}
export interface MarketTagsVariables {
marketId: string;
}
/**
* __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>;
@@ -1,54 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type 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>;
@@ -1,61 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type PartyBalanceQueryQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } } } | null> | null } | null } | null };
export const PartyBalanceQueryDocument = gql`
query PartyBalanceQuery($partyId: ID!) {
party(id: $partyId) {
accountsConnection {
edges {
node {
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>;
@@ -1,9 +1,13 @@
import React from 'react';
import { render } from '@testing-library/react';
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
import { DealTicketBalance } from './deal-ticket-balance';
import { Schema } from '@vegaprotocol/types';
import { MockedProvider } from '@apollo/client/testing';
import type { MarketDealTicketAsset } from '@vegaprotocol/market-list';
import { DealTicketBalance } from './deal-ticket-balance';
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
}));
const tDAI: MarketDealTicketAsset = {
__typename: 'Asset',
@@ -13,23 +17,20 @@ const tDAI: MarketDealTicketAsset = {
decimals: 2,
};
const accounts: AccountFragment[] = [
{
__typename: 'AccountBalance',
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '1000000',
asset: tDAI,
},
];
let mockAccountBalance: {
accountBalance: string;
accountDecimals: number | null;
} = { accountBalance: '1000000', accountDecimals: 2 };
jest.mock('@vegaprotocol/accounts', () => ({
...jest.requireActual('@vegaprotocol/accounts'),
useAccountBalance: jest.fn(() => mockAccountBalance),
}));
describe('DealTicketBalance', function () {
it('should render the balance', () => {
const { getByText, getByRole } = render(
<DealTicketBalance
settlementAsset={tDAI}
accounts={accounts}
isWalletConnected
/>
<DealTicketBalance settlementAsset={tDAI} isWalletConnected />,
{ wrapper: MockedProvider }
);
expect(getByRole('complementary')).toHaveAccessibleName('tDAI Balance');
@@ -39,11 +40,8 @@ describe('DealTicketBalance', function () {
it('should prompt to connect wallet', () => {
const { getByText } = render(
<DealTicketBalance
settlementAsset={tDAI}
accounts={accounts}
isWalletConnected={false}
/>
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={false} />,
{ wrapper: MockedProvider }
);
expect(
@@ -52,12 +50,10 @@ describe('DealTicketBalance', function () {
});
it('should display zero balance', () => {
mockAccountBalance = { accountBalance: '', accountDecimals: null };
const { getByText } = render(
<DealTicketBalance
settlementAsset={tDAI}
accounts={[]}
isWalletConnected={true}
/>
<DealTicketBalance settlementAsset={tDAI} isWalletConnected={true} />,
{ wrapper: MockedProvider }
);
expect(getByText('No tDAI left to trade')).toBeInTheDocument();
@@ -1,41 +1,38 @@
import classNames from 'classnames';
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
import { Schema } from '@vegaprotocol/types';
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
import {
addDecimalsFormatNumber,
t,
toBigNum,
} from '@vegaprotocol/react-helpers';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
import { useAccountBalance } from '@vegaprotocol/accounts';
interface DealTicketBalanceProps {
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
accounts: AccountFragment[];
isWalletConnected: boolean;
className?: string;
}
export const DealTicketBalance = ({
settlementAsset,
accounts,
isWalletConnected,
className = '',
}: DealTicketBalanceProps) => {
const settlementAssetId = settlementAsset?.id;
const settlementAssetSymbol = settlementAsset?.symbol;
const settlementAccount = useSettlementAccount(
settlementAssetId,
accounts,
Schema.AccountType.ACCOUNT_TYPE_GENERAL
);
const { accountBalance, accountDecimals } =
useAccountBalance(settlementAssetId) || {};
const settlementBalance = toBigNum(accountBalance || 0, accountDecimals || 0);
const formattedNumber =
settlementAccount?.balance &&
settlementAccount.asset.decimals &&
addDecimalsFormatNumber(
settlementAccount.balance,
settlementAccount.asset.decimals
);
accountBalance &&
accountDecimals &&
addDecimalsFormatNumber(accountBalance, accountDecimals);
const balance = (
<p className="text-blue text-lg font-semibold">
{settlementAccount
{!settlementBalance.isZero()
? t(`${formattedNumber}`)
: `No ${settlementAssetSymbol} left to trade`}
</p>
@@ -1,14 +1,7 @@
import { useParams } from 'react-router-dom';
import {
DealTicketManager,
usePartyBalanceQuery,
} from '@vegaprotocol/deal-ticket';
import { DealTicketManager } from '@vegaprotocol/deal-ticket';
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
import {
t,
useDataProvider,
removePaginationWrapper,
} from '@vegaprotocol/react-helpers';
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { DealTicketSteps } from './deal-ticket-steps';
import { DealTicketBalance } from './deal-ticket-balance';
@@ -29,11 +22,6 @@ export const DealTicketContainer = () => {
const { marketId } = useParams<{ marketId: string }>();
const { pubKey } = useVegaWallet();
const { data: partyData } = usePartyBalanceQuery({
variables: { partyId: pubKey || '' },
skip: !pubKey,
});
const variables = useMemo(
() => ({
marketId: marketId || '',
@@ -49,10 +37,6 @@ export const DealTicketContainer = () => {
skip: !marketId,
});
const accounts = removePaginationWrapper(
partyData?.party?.accountsConnection?.edges
);
const loader = <Loader />;
if (marketId && data) {
const balance = (
@@ -61,7 +45,6 @@ export const DealTicketContainer = () => {
settlementAsset={
data.tradableInstrument.instrument.product?.settlementAsset
}
accounts={accounts || []}
isWalletConnected={!!pubKey}
/>
);
@@ -6,7 +6,6 @@ import {
getDefaultOrder,
useOrderCloseOut,
useOrderMargin,
usePartyBalanceQuery,
useMaximumPositionSize,
useCalculateSlippage,
validateAmount,
@@ -24,7 +23,6 @@ import {
addDecimalsFormatNumber,
addDecimal,
formatNumber,
removePaginationWrapper,
} from '@vegaprotocol/react-helpers';
import {
useOrderSubmit,
@@ -37,7 +35,7 @@ import { DealTicketSize } from './deal-ticket-size';
import MarketNameRenderer from '../simple-market-list/simple-market-renderer';
import SideSelector, { SIDE_NAMES } from './side-selector';
import ReviewTrade from './review-trade';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import { DealTicketSlippage } from './deal-ticket-slippage';
import { useOrderValidation } from './use-order-validation';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
@@ -77,17 +75,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
});
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
const { data: partyBalance } = usePartyBalanceQuery({
variables: { partyId: pubKey || '' },
skip: !pubKey,
});
const accounts = removePaginationWrapper(
partyBalance?.party?.accountsConnection?.edges
);
const maxTrade = useMaximumPositionSize({
partyId: pubKey || '',
accounts: accounts,
marketId: market.id,
settlementAssetId:
market.tradableInstrument.instrument.product.settlementAsset.id,
@@ -98,7 +86,6 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
const estCloseOut = useOrderCloseOut({
order,
market,
partyData: partyBalance,
});
const slippage = useCalculateSlippage({ marketId: market.id, order });
const [slippageValue, setSlippageValue] = useState(
@@ -8,28 +8,10 @@ import classNames from 'classnames';
import { DealTicketEstimates } from '@vegaprotocol/deal-ticket';
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
import { SIDE_NAMES } from './side-selector';
import { gql, useQuery } from '@apollo/client';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import { MarketExpires } from '@vegaprotocol/market-info';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
import type {
MarketTags,
MarketTagsVariables,
} from './__generated__/MarketTags';
export const MARKET_TAGS_QUERY = gql`
query MarketTags($marketId: ID!) {
market(id: $marketId) {
tradableInstrument {
instrument {
metadata {
tags
}
}
}
}
}
`;
import { useMarketTagsQuery } from './__generated__/MarketTags';
interface Props {
market: MarketDealTicket;
@@ -57,12 +39,9 @@ export default ({
notionalSize,
slippage,
}: Props) => {
const { data: tagsData } = useQuery<MarketTags, MarketTagsVariables>(
MARKET_TAGS_QUERY,
{
variables: { marketId: market.id },
}
);
const { data: tagsData } = useMarketTagsQuery({
variables: { marketId: market.id },
});
return (
<div className="mb-8 text-black dark:text-white" data-testid="review-trade">
@@ -2,7 +2,7 @@ import React from 'react';
import classNames from 'classnames';
import { FormGroup } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
interface SideSelectorProps {
value: Schema.Side;
@@ -3,11 +3,7 @@ import { renderHook } from '@testing-library/react';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { MockedProvider } from '@apollo/client/testing';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import {
MarketStateMapping,
Schema as Types,
Schema,
} from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import type { ValidationProps } from './use-order-validation';
import { marketTranslations, useOrderValidation } from './use-order-validation';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
@@ -78,7 +74,7 @@ const market: MarketDealTicket = {
bestBidPrice: '1605489971',
bestOfferPrice: '1606823730',
markPrice: '1606823730',
trigger: Types.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
staticMidPrice: '1606156850',
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
marketState: Schema.MarketState.STATE_ACTIVE,
@@ -245,7 +241,7 @@ describe('useOrderValidation', () => {
});
expect(result.current).toStrictEqual({
isDisabled: false,
message: `This market is ${MarketStateMapping[
message: `This market is ${Schema.MarketStateMapping[
state as Schema.MarketState
].toLowerCase()} and only accepting liquidity commitment orders`,
section: 'sec-summary',
@@ -3,7 +3,7 @@ import type { FieldErrors } from 'react-hook-form';
import { useMemo } from 'react';
import { t, toDecimal } from '@vegaprotocol/react-helpers';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { MarketStateMapping, Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
import { Tooltip } from '@vegaprotocol/ui-toolkit';
import {
@@ -39,7 +39,7 @@ export const marketTranslations = (marketState: Schema.MarketState) => {
case Schema.MarketState.STATE_TRADING_TERMINATED:
return t('terminated');
default:
return t(MarketStateMapping[marketState]).toLowerCase();
return t(Schema.MarketStateMapping[marketState]).toLowerCase();
}
};
@@ -11,8 +11,6 @@ const Header = () => {
}));
const {
vegaWalletDialog: { setManage },
theme,
toggleTheme,
} = useContext(LocalContext);
return (
<div
@@ -25,7 +23,7 @@ const Header = () => {
setConnectDialog={updateVegaWalletDialog}
setManageDialog={setManage}
/>
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
<ThemeSwitcher className="-my-4" />
</div>
</div>
);
@@ -12,7 +12,7 @@ import {
t,
} from '@vegaprotocol/react-helpers';
import BigNumber from 'bignumber.js';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
interface Props {
partyId: string;
@@ -14,20 +14,14 @@ import {
import type { OrderFieldsFragment, Order } from '@vegaprotocol/orders';
import type { OrderCancellationBody } from '@vegaprotocol/wallet';
import { isOrderActive } from '@vegaprotocol/orders';
import {
OrderRejectionReasonMapping,
OrderStatusMapping,
OrderTypeMapping,
Schema,
OrderTimeInForceMapping,
} from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import BigNumber from 'bignumber.js';
import { Button } from '@vegaprotocol/ui-toolkit';
type StatusKey = keyof typeof OrderStatusMapping;
type RejectReasonKey = keyof typeof OrderRejectionReasonMapping;
type OrderTimeKey = keyof typeof OrderTimeInForceMapping;
type StatusKey = keyof typeof Schema.OrderStatusMapping;
type RejectReasonKey = keyof typeof Schema.OrderRejectionReasonMapping;
type OrderTimeKey = keyof typeof Schema.OrderTimeInForceMapping;
interface Props {
setEditOrder: (order: Order) => void;
orderCancel: {
@@ -81,7 +75,7 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
value,
}: ValueFormatterParams & {
value?: OrderFieldsFragment['type'];
}) => OrderTypeMapping[value as Schema.OrderType],
}) => Schema.OrderTypeMapping[value as Schema.OrderType],
},
{
colId: 'status',
@@ -95,14 +89,14 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
}) => {
if (value && data && data.market) {
if (value === Schema.OrderStatus.STATUS_REJECTED) {
return `${OrderStatusMapping[value as StatusKey]}: ${
return `${Schema.OrderStatusMapping[value as StatusKey]}: ${
data.rejectionReason &&
OrderRejectionReasonMapping[
Schema.OrderRejectionReasonMapping[
data.rejectionReason as RejectReasonKey
]
}`;
}
return OrderStatusMapping[value as StatusKey] as string;
return Schema.OrderStatusMapping[value as StatusKey] as string;
}
return '-';
},
@@ -176,11 +170,11 @@ const useColumnDefinitions = ({ setEditOrder, orderCancel }: Props) => {
new Date(data.expiresAt)
);
return `${
OrderTimeInForceMapping[value as OrderTimeKey]
Schema.OrderTimeInForceMapping[value as OrderTimeKey]
}: ${expiry}`;
}
return OrderTimeInForceMapping[value as OrderTimeKey];
return Schema.OrderTimeInForceMapping[value as OrderTimeKey];
}
return '-';
},
@@ -16,7 +16,7 @@ import type {
GroupCellRendererParams,
ColDef,
} from 'ag-grid-community';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
import { Intent, ProgressBarCell } from '@vegaprotocol/ui-toolkit';
@@ -1,4 +1,4 @@
import { Schema as Types } from '@vegaprotocol/types';
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
@@ -1,6 +1,6 @@
import { t } from '@vegaprotocol/react-helpers';
import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import colors from 'tailwindcss/colors';
import type { Market } from '@vegaprotocol/market-list';
import { IS_MARKET_TRADABLE } from '../../constants';
@@ -9,7 +9,7 @@ import {
} from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { BrowserRouter } from 'react-router-dom';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import type { Market } from '@vegaprotocol/market-list';
import SimpleMarketList from './simple-market-list';
@@ -13,7 +13,7 @@ import SimpleMarketToolbar from './simple-market-toolbar';
import { IS_MARKET_TRADABLE } from '../../constants';
import { ConsoleLiteGrid } from '../console-lite-grid';
import type { Market } from '@vegaprotocol/market-list';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import { marketsWithCandlesProvider } from '@vegaprotocol/market-list';
export type MarketWithPercentChange = Market & {
@@ -4,7 +4,7 @@ import { InView } from 'react-intersection-observer';
import { useDataProvider, useYesterday } from '@vegaprotocol/react-helpers';
import type { Candle } from '@vegaprotocol/market-list';
import { marketCandlesProvider } from '@vegaprotocol/market-list';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
interface Props {
candles: (Candle | null)[] | null;
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import MarketNameRenderer from './simple-market-renderer';
import type { Market } from '@vegaprotocol/market-list';
@@ -14,7 +14,7 @@ import {
getAllByText,
} from '@testing-library/react';
import { MockedProvider } from '@apollo/react-testing';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import type { Market } from '@vegaprotocol/market-list';
import SimpleMarketToolbar from './simple-market-toolbar';
import { markets as filterData } from './mocks/market-filters.json';
@@ -13,7 +13,7 @@ import {
DropdownMenuItemIndicator,
Icon,
} from '@vegaprotocol/ui-toolkit';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import type { Market } from '@vegaprotocol/market-list';
import { HorizontalMenu } from '../horizontal-menu';
import type { HorizontalMenuItem } from '../horizontal-menu';
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import type { MarketWithCandles } from '@vegaprotocol/market-list';
import type { RouterParams } from './simple-market-list';
+1 -1
View File
@@ -1,4 +1,4 @@
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import { t } from '@vegaprotocol/react-helpers';
import type { Market } from '@vegaprotocol/market-list';
@@ -14,8 +14,6 @@ interface MenuState {
export interface LocalValues {
vegaWalletDialog: VegaWalletDialogState;
menu: MenuState;
theme: 'light' | 'dark';
toggleTheme: () => void;
}
const LocalContext = createContext<LocalValues>({} as LocalValues);
@@ -3,8 +3,7 @@ import useLocalValues from './use-local-values';
describe('local values hook', () => {
it('state of wallet dialog should be properly handled', () => {
const setTheme = jest.fn();
const { result } = renderHook(() => useLocalValues('light', setTheme));
const { result } = renderHook(() => useLocalValues());
expect(result.current.vegaWalletDialog).toBeDefined();
expect(result.current.vegaWalletDialog.manage).toBe(false);
act(() => {
@@ -1,17 +1,15 @@
import { useMemo, useState } from 'react';
import type { LocalValues } from '../context/local-context';
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
const useLocalValues = () => {
const [manage, setManage] = useState<boolean>(false);
const [menuOpen, setMenuOpen] = useState(false);
return useMemo<LocalValues>(
() => ({
vegaWalletDialog: { manage, setManage },
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
theme,
toggleTheme,
}),
[manage, theme, toggleTheme, menuOpen]
[manage, menuOpen]
);
};
+12 -21
View File
@@ -3,7 +3,6 @@ import { useState, useEffect } from 'react';
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';
import { useLocation } from 'react-router-dom';
import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
import {
EnvironmentProvider,
NetworkLoader,
@@ -19,7 +18,6 @@ import type { InMemoryCacheConfig } from '@apollo/client';
function App() {
const { VEGA_ENV } = useEnvironment();
const [theme, toggleTheme] = useThemeSwitcher();
const [menuOpen, setMenuOpen] = useState(false);
const location = useLocation();
@@ -57,25 +55,18 @@ function App() {
);
return (
<ThemeContext.Provider value={theme}>
<TendermintWebsocketProvider>
<NetworkLoader cache={cacheConfig}>
<div className={layoutClasses}>
<Header
theme={theme}
toggleTheme={toggleTheme}
menuOpen={menuOpen}
setMenuOpen={setMenuOpen}
/>
<Nav menuOpen={menuOpen} />
<Main />
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
<NetworkInfo />
</footer>
</div>
</NetworkLoader>
</TendermintWebsocketProvider>
</ThemeContext.Provider>
<TendermintWebsocketProvider>
<NetworkLoader cache={cacheConfig}>
<div className={layoutClasses}>
<Header menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
<Nav menuOpen={menuOpen} />
<Main />
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
<NetworkInfo />
</footer>
</div>
</NetworkLoader>
</TendermintWebsocketProvider>
);
}
@@ -0,0 +1,5 @@
query ExplorerGovernanceAsset {
networkParameter(key: "reward.asset") {
value
}
}
@@ -0,0 +1,45 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerGovernanceAssetQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ExplorerGovernanceAssetQuery = { __typename?: 'Query', networkParameter?: { __typename?: 'NetworkParameter', value: string } | null };
export const ExplorerGovernanceAssetDocument = gql`
query ExplorerGovernanceAsset {
networkParameter(key: "reward.asset") {
value
}
}
`;
/**
* __useExplorerGovernanceAssetQuery__
*
* To run a query within a React component, call `useExplorerGovernanceAssetQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerGovernanceAssetQuery` 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 } = useExplorerGovernanceAssetQuery({
* variables: {
* },
* });
*/
export function useExplorerGovernanceAssetQuery(baseOptions?: Apollo.QueryHookOptions<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>(ExplorerGovernanceAssetDocument, options);
}
export function useExplorerGovernanceAssetLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>(ExplorerGovernanceAssetDocument, options);
}
export type ExplorerGovernanceAssetQueryHookResult = ReturnType<typeof useExplorerGovernanceAssetQuery>;
export type ExplorerGovernanceAssetLazyQueryHookResult = ReturnType<typeof useExplorerGovernanceAssetLazyQuery>;
export type ExplorerGovernanceAssetQueryResult = Apollo.QueryResult<ExplorerGovernanceAssetQuery, ExplorerGovernanceAssetQueryVariables>;
@@ -0,0 +1,40 @@
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
import { AssetLink } from '../links';
import { useExplorerAssetQuery } from '../links/asset-link/__generated__/Asset';
export type AssetBalanceProps = {
assetId: string;
price: string;
showAssetLink?: boolean;
};
/**
* Given a market ID and a price it will fetch the market
* and format the price in that market's decimal places.
*/
const AssetBalance = ({
assetId,
price,
showAssetLink = true,
}: AssetBalanceProps) => {
const { data } = useExplorerAssetQuery({
fetchPolicy: 'cache-first',
variables: { id: assetId },
});
const label =
data && data.asset?.decimals
? addDecimalsFormatNumber(price, data.asset.decimals)
: price;
return (
<div className="inline-block">
<span>{label}</span>{' '}
{showAssetLink && data?.asset?.id ? (
<AssetLink id={data.asset.id} />
) : null}
</div>
);
};
export default AssetBalance;
@@ -0,0 +1,30 @@
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
import { useExplorerGovernanceAssetQuery } from './__generated__/Governance-asset';
import AssetBalance from './asset-balance';
export type GovernanceAssetBalanceProps = {
price: string;
};
const DEFAULT_DECIMALS = 18;
/**
* Effectively a wrapper around AssetBalance that does an extra query to fetch
* the governance asset first, which is set by a network parameter
*/
const GovernanceAssetBalance = ({ price }: GovernanceAssetBalanceProps) => {
const { data } = useExplorerGovernanceAssetQuery();
if (data && data.networkParameter?.value) {
const governanceAssetId = data.networkParameter.value;
return <AssetBalance price={price} assetId={governanceAssetId} />;
} else {
return (
<div className="inline-block">
<span>{addDecimalsFormatNumber(price, DEFAULT_DECIMALS)}</span>
</div>
);
}
};
export default GovernanceAssetBalance;
@@ -14,12 +14,7 @@ jest.mock('../search', () => ({
const renderComponent = () => (
<MemoryRouter>
<Header
theme="dark"
toggleTheme={jest.fn()}
menuOpen={false}
setMenuOpen={jest.fn()}
/>
<Header menuOpen={false} setMenuOpen={jest.fn()} />
</MemoryRouter>
);
@@ -8,18 +8,11 @@ import type { Dispatch, SetStateAction } from 'react';
import { NetworkSwitcher } from '@vegaprotocol/environment';
interface ThemeToggleProps {
theme: 'light' | 'dark';
toggleTheme: () => void;
menuOpen: boolean;
setMenuOpen: Dispatch<SetStateAction<boolean>>;
}
export const Header = ({
theme,
toggleTheme,
menuOpen,
setMenuOpen,
}: ThemeToggleProps) => {
export const Header = ({ menuOpen, setMenuOpen }: ThemeToggleProps) => {
const headerClasses = classnames(
'md:col-span-2',
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
@@ -48,7 +41,7 @@ export const Header = ({
<Icon name={menuOpen ? 'cross' : 'menu'} />
</button>
<Search />
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
<ThemeSwitcher className="-my-4" />
</header>
);
};
@@ -1,4 +1,4 @@
import { Schema as Types } from '@vegaprotocol/types';
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
@@ -16,6 +16,7 @@ export type AssetLinkProps = Partial<ComponentProps<typeof Link>> & {
*/
const AssetLink = ({ id, ...props }: AssetLinkProps) => {
const { data } = useExplorerAssetQuery({
fetchPolicy: 'cache-first',
variables: { id },
});
@@ -21,7 +21,7 @@ export const EthExplorerLink = ({
const link = `${DATA_SOURCES.ethExplorerUrl}/${type}/${id}`;
return (
<a
className="underline external"
className="underline external font-mono"
target="_blank"
rel="noopener noreferrer"
{...props}
@@ -1,4 +1,4 @@
import { Schema as Types } from '@vegaprotocol/types';
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
@@ -1,4 +1,4 @@
import { Schema as Types } from '@vegaprotocol/types';
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
@@ -88,7 +88,7 @@ describe('NestedDataList', () => {
for (let i = 0; i < 8; i++) {
const item = getByTestId(`T${i}`);
const expected = BORDER_COLOURS.dark[i % 5];
const expected = BORDER_COLOURS.light[i % 5];
expect(item.style.borderColor.toUpperCase()).toBe(expected);
}
});
@@ -1,7 +1,7 @@
import React, { useCallback, useContext, useMemo, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import classNames from 'classnames';
import isObject from 'lodash/isObject';
import { ThemeContext } from '@vegaprotocol/react-helpers';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { Icon } from '@vegaprotocol/ui-toolkit';
import { IconNames } from '@blueprintjs/icons';
import { VegaColours } from '@vegaprotocol/tailwindcss-config';
@@ -65,7 +65,7 @@ const NestedDataListItem = ({
);
const hasChildren = isObject(value) && !!Object.keys(value).length;
const title = useMemo(() => camelToTitle(label), [label]);
const theme = useContext(ThemeContext);
const { theme } = useThemeSwitcher();
const currentLevelBorder = useMemo(
() => getBorderColour(index, theme),
[index, theme]
@@ -1,4 +1,4 @@
import { Schema as Types } from '@vegaprotocol/types';
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
@@ -5,7 +5,7 @@ import { MemoryRouter } from 'react-router-dom';
import AmendOrderDetails from './amend-order-details';
import { ExplorerDeterministicOrderDocument } from './__generated__/Order';
import { render } from '@testing-library/react';
import { Schema } from '@vegaprotocol/types';
import * as Schema from '@vegaprotocol/types';
import { ExplorerMarketDocument } from '../links/market-link/__generated__/Market';
type Amend = components['schemas']['v1OrderAmendment'];
@@ -1,5 +1,5 @@
import { t } from '@vegaprotocol/react-helpers';
import type { Schema } from '@vegaprotocol/types';
import type * as Schema from '@vegaprotocol/types';
export interface DeterministicOrderDetailsProps {
id: string;
@@ -1,4 +1,4 @@
import { Schema as Types } from '@vegaprotocol/types';
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
@@ -1,4 +1,4 @@
import { Schema as Types } from '@vegaprotocol/types';
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
@@ -13,6 +13,7 @@ export const successCodes = new Set([0]);
interface ChainResponseCodeProps {
code: number;
hideLabel?: boolean;
error?: string;
}
/**
@@ -23,6 +24,7 @@ interface ChainResponseCodeProps {
export const ChainResponseCode = ({
code,
hideLabel = false,
error,
}: ChainResponseCodeProps) => {
const isSuccess = successCodes.has(code);
@@ -39,6 +41,9 @@ export const ChainResponseCode = ({
{icon}
</span>
{hideLabel ? null : <span>{label}</span>}
{!hideLabel && !!error ? (
<span className="ml-1">&mdash;&nbsp;{error}</span>
) : null}
</div>
);
};
@@ -73,7 +73,7 @@ export const TxDetailsShared = ({
<TableRow modifier="bordered">
<TableCell>{t('Response code')}</TableCell>
<TableCell>
<ChainResponseCode code={txData.code} />
<ChainResponseCode code={txData.code} error={txData.error} />
</TableCell>
</TableRow>
</>
@@ -0,0 +1,58 @@
import { t } from '@vegaprotocol/react-helpers';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table';
import { NodeLink } from '../../links';
import GovernanceAssetBalance from '../../asset-balance/governance-asset-balance';
import type { components } from '../../../../types/explorer';
interface TxDetailsDelegateProps {
txData: BlockExplorerTransactionResult | undefined;
pubKey: string | undefined;
blockData: TendermintBlocksResponse | undefined;
}
/**
* There aren't currently good APIs for exploring delegations or epochs so this
* view is currently a little basic - but it gives the key details.
*
* Future improvements could be:
* - Show if the delegation has taken effect or not, based on epoch
*
* The signature can be turned in to an id with txSignatureToDeterministicId but
* for now there are no details to fetch.
*/
export const TxDetailsDelegate = ({
txData,
pubKey,
blockData,
}: TxDetailsDelegateProps) => {
if (!txData || !txData.command.delegateSubmission) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const d: components['schemas']['v1DelegateSubmission'] =
txData.command.delegateSubmission;
return (
<TableWithTbody className="mb-8">
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
{d.nodeId ? (
<TableRow modifier="bordered">
<TableCell>{t('Node')}</TableCell>
<TableCell>
<NodeLink id={d.nodeId} />
</TableCell>
</TableRow>
) : null}
{d.amount ? (
<TableRow modifier="bordered">
<TableCell>{t('Amount')}</TableCell>
<TableCell>
<GovernanceAssetBalance price={d.amount} />
</TableCell>
</TableRow>
) : null}
</TableWithTbody>
);
};
@@ -14,6 +14,9 @@ import { TxDetailsNodeVote } from './tx-node-vote';
import { TxDetailsOrderCancel } from './tx-order-cancel';
import get from 'lodash/get';
import { TxDetailsOrderAmend } from './tx-order-amend';
import { TxDetailsWithdrawSubmission } from './tx-withdraw-submission';
import { TxDetailsDelegate } from './tx-delegation';
import { TxDetailsUndelegate } from './tx-undelegation';
interface TxDetailsWrapperProps {
txData: BlockExplorerTransactionResult | undefined;
@@ -88,6 +91,12 @@ function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
return TxDetailsChainEvent;
case 'Node Vote':
return TxDetailsNodeVote;
case 'Withdraw':
return TxDetailsWithdrawSubmission;
case 'Delegate':
return TxDetailsDelegate;
case 'Undelegate':
return TxDetailsUndelegate;
default:
return TxDetailsGeneric;
}
@@ -3,10 +3,14 @@ import type { BlockExplorerTransactionResult } from '../../../routes/types/block
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table';
import type { ExplorerNodeVoteQueryResult } from './__generated___/node-vote';
import { useExplorerNodeVoteQuery } from './__generated___/node-vote';
import type { ExplorerNodeVoteQueryResult } from './__generated__/Node-vote';
import { useExplorerNodeVoteQuery } from './__generated__/Node-vote';
import { PartyLink } from '../../links';
import { Time } from '../../time';
import {
EthExplorerLink,
EthExplorerLinkTypes,
} from '../../links/eth-explorer-link/eth-explorer-link';
interface TxDetailsNodeVoteProps {
txData: BlockExplorerTransactionResult | undefined;
@@ -80,10 +84,10 @@ export function TxDetailsNodeVoteDeposit({
<TableCell>
<Time date={deposit?.deposit?.creditedTimestamp} />
</TableCell>
{deposit?.deposit?.txHash ? (
<TxHash hash={deposit?.deposit?.txHash} />
) : null}
</TableRow>
{deposit?.deposit?.txHash ? (
<TxHash hash={deposit?.deposit?.txHash} />
) : null}
</>
);
}
@@ -119,10 +123,10 @@ export function TxDetailsNodeVoteWithdrawal({
<TableCell>
<Time date={withdrawal?.withdrawal?.withdrawnTimestamp} />
</TableCell>
{withdrawal?.withdrawal?.txHash ? (
<TxHash hash={withdrawal?.withdrawal?.txHash} />
) : null}
</TableRow>
{withdrawal?.withdrawal?.txHash ? (
<TxHash hash={withdrawal?.withdrawal?.txHash} />
) : null}
</>
);
}
@@ -138,7 +142,9 @@ export function TxHash({ hash }: TxDetailsEthTxHashProps) {
return (
<TableRow modifier="bordered">
<TableCell>Ethereum TX:</TableCell>
<TableCell>{hash}</TableCell>
<TableCell>
<EthExplorerLink id={hash} type={EthExplorerLinkTypes.tx} />
</TableCell>
</TableRow>
);
}
@@ -0,0 +1,77 @@
import { t } from '@vegaprotocol/react-helpers';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table';
import { NodeLink } from '../../links';
import GovernanceAssetBalance from '../../asset-balance/governance-asset-balance';
import type { components } from '../../../../types/explorer';
export const methodText: Record<
components['schemas']['UndelegateSubmissionMethod'],
string
> = {
METHOD_NOW: 'Immediate',
METHOD_UNSPECIFIED: 'Unspecified',
METHOD_AT_END_OF_EPOCH: 'End of epoch',
// This will be removed in a future release
METHOD_IN_ANGER: 'Immediate',
};
interface TxDetailsUndelegateProps {
txData: BlockExplorerTransactionResult | undefined;
pubKey: string | undefined;
blockData: TendermintBlocksResponse | undefined;
}
/**
* There aren't currently good APIs for exploring delegations or epochs so this
* view is currently a little basic - but it gives the key details.
*
* Future improvements could be:
* - Show if the undelegation has taken effect or not, based on epoch
* - Show the the total stake for the node after undelegation takes effect
*
* The signature can be turned in to an id with txSignatureToDeterministicId but
* for now there are no details to fetch.
*/
export const TxDetailsUndelegate = ({
txData,
pubKey,
blockData,
}: TxDetailsUndelegateProps) => {
if (!txData || !txData.command.undelegateSubmission) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const u: components['schemas']['v1UndelegateSubmission'] =
txData.command.undelegateSubmission;
return (
<TableWithTbody className="mb-8">
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
{u.nodeId ? (
<TableRow modifier="bordered">
<TableCell>{t('Node')}</TableCell>
<TableCell>
<NodeLink id={u.nodeId} />
</TableCell>
</TableRow>
) : null}
{u.amount ? (
<TableRow modifier="bordered">
<TableCell>{t('Amount')}</TableCell>
<TableCell>
<GovernanceAssetBalance price={u.amount} />
</TableCell>
</TableRow>
) : null}
{u.method ? (
<TableRow modifier="bordered">
<TableCell>{t('When')}</TableCell>
<TableCell>{methodText[u.method]}</TableCell>
</TableRow>
) : null}
</TableWithTbody>
);
};
@@ -0,0 +1,72 @@
import { t } from '@vegaprotocol/react-helpers';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table';
import {
EthExplorerLink,
EthExplorerLinkTypes,
} from '../../links/eth-explorer-link/eth-explorer-link';
import { txSignatureToDeterministicId } from '../lib/deterministic-ids';
import AssetBalance from '../../asset-balance/asset-balance';
import { useScrollToLocation } from '../../../hooks/scroll-to-location';
import { WithdrawalProgress } from '../../withdrawal/withdrawal-progress';
interface TxDetailsOrderCancelProps {
txData: BlockExplorerTransactionResult | undefined;
pubKey: string | undefined;
blockData: TendermintBlocksResponse | undefined;
}
/**
* The first part of a withdrawal. If the validators all approve this request (i.e. the user has the
* required funds), they will produce a multisig bundle that can be submitted to the ERC20 bridge to
* execute the withdrawal.
*/
export const TxDetailsWithdrawSubmission = ({
txData,
pubKey,
blockData,
}: TxDetailsOrderCancelProps) => {
useScrollToLocation();
if (!txData || !txData.command.withdrawSubmission) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const w = txData.command.withdrawSubmission;
const id = txData?.signature?.value
? txSignatureToDeterministicId(txData.signature.value)
: '-';
return (
<>
<TableWithTbody className="mb-8">
<TxDetailsShared
txData={txData}
pubKey={pubKey}
blockData={blockData}
/>
<TableRow modifier="bordered">
<TableCell>{t('Amount')}</TableCell>
<TableCell>
<AssetBalance price={w.amount} assetId={w.asset} />
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Recipient')}</TableCell>
<TableCell>
<EthExplorerLink
id={w.ext.erc20.receiverAddress}
type={EthExplorerLinkTypes.address}
/>
</TableCell>
</TableRow>
</TableWithTbody>
{id !== '-' ? (
<WithdrawalProgress id={id} txStatus={txData.code} />
) : null}
</>
);
};
@@ -2,8 +2,8 @@ import { t } from '@vegaprotocol/react-helpers';
import { useEffect } from 'react';
import { InfoBlock } from '../../components/info-block';
import { Panel } from '../../components/panel';
import { useExplorerStatsQuery } from './__generated__/explorer-stats';
import type { ExplorerStatsFieldsFragment } from './__generated__/explorer-stats';
import { useExplorerStatsQuery } from './__generated__/Explorer-stats';
import type { ExplorerStatsFieldsFragment } from './__generated__/Explorer-stats';
interface StatsMap {
field: keyof ExplorerStatsFieldsFragment;
@@ -0,0 +1,19 @@
fragment ExplorerWithdrawalProperties on Withdrawal {
id
status
createdTimestamp
withdrawnTimestamp
ref
txHash
details {
... on Erc20WithdrawalDetails {
receiverAddress
}
}
}
query ExplorerWithdrawal($id: ID!) {
withdrawal(id: $id) {
...ExplorerWithdrawalProperties
}
}
@@ -0,0 +1,64 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerWithdrawalPropertiesFragment = { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null };
export type ExplorerWithdrawalQueryVariables = Types.Exact<{
id: Types.Scalars['ID'];
}>;
export type ExplorerWithdrawalQuery = { __typename?: 'Query', withdrawal?: { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: any, withdrawnTimestamp?: any | null, ref: string, txHash?: string | null, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null } | null };
export const ExplorerWithdrawalPropertiesFragmentDoc = gql`
fragment ExplorerWithdrawalProperties on Withdrawal {
id
status
createdTimestamp
withdrawnTimestamp
ref
txHash
details {
... on Erc20WithdrawalDetails {
receiverAddress
}
}
}
`;
export const ExplorerWithdrawalDocument = gql`
query ExplorerWithdrawal($id: ID!) {
withdrawal(id: $id) {
...ExplorerWithdrawalProperties
}
}
${ExplorerWithdrawalPropertiesFragmentDoc}`;
/**
* __useExplorerWithdrawalQuery__
*
* To run a query within a React component, call `useExplorerWithdrawalQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerWithdrawalQuery` 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 } = useExplorerWithdrawalQuery({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useExplorerWithdrawalQuery(baseOptions: Apollo.QueryHookOptions<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>(ExplorerWithdrawalDocument, options);
}
export function useExplorerWithdrawalLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>(ExplorerWithdrawalDocument, options);
}
export type ExplorerWithdrawalQueryHookResult = ReturnType<typeof useExplorerWithdrawalQuery>;
export type ExplorerWithdrawalLazyQueryHookResult = ReturnType<typeof useExplorerWithdrawalLazyQuery>;
export type ExplorerWithdrawalQueryResult = Apollo.QueryResult<ExplorerWithdrawalQuery, ExplorerWithdrawalQueryVariables>;
@@ -0,0 +1,125 @@
import { MockedProvider } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing';
import { render } from '@testing-library/react';
import WithdrawalProgress from './withdrawal-progress';
import { ExplorerWithdrawalDocument } from './__generated__/Withdrawal';
import { ApolloError } from '@apollo/client';
function renderComponent(id: string, status: number, mock: MockedResponse[]) {
return (
<MockedProvider mocks={mock}>
<WithdrawalProgress id={id} txStatus={status} />
</MockedProvider>
);
}
describe('Withdrawal Progress component', () => {
it('Renders success for the first indicator if txStatus is 0', () => {
const res = render(renderComponent('123', 0, []));
expect(res.getByText('Requested')).toBeInTheDocument();
// Steps 2 and three should not be complete also
expect(res.getByText('Not prepared')).toBeInTheDocument();
expect(res.getByText('Not complete')).toBeInTheDocument();
});
it('Renders success for the first indicator if txStatus is anything except 0', () => {
const res = render(renderComponent('123', 20, []));
expect(res.getByText('Rejected')).toBeInTheDocument();
// Steps 2 and three should not be complete also
expect(res.getByText('Not prepared')).toBeInTheDocument();
expect(res.getByText('Not complete')).toBeInTheDocument();
});
it('Renders success for the second indicator if a date can be fetched', async () => {
const mock = {
request: {
query: ExplorerWithdrawalDocument,
variables: {
id: '123',
},
},
result: {
data: {
withdrawal: {
__typename: 'Withdrawal',
id: '123',
status: 'STATUS_OPEN',
createdTimestamp: '2022-03-24T11:03:40.026173466Z',
withdrawnTimestamp: null,
ref: 'irrelevant',
txHash: '0x123456890',
details: {
__typename: 'Erc20WithdrawalDetails',
receiverAddress: '0x5435345432342423',
},
},
},
},
};
const res = render(renderComponent('123', 0, [mock]));
// Step 1 should be filled in
expect(res.getByText('Requested')).toBeInTheDocument();
// Step 2
expect(await res.findByText('Prepared')).toBeInTheDocument();
// Step 3
expect(await res.findByText('Not complete')).toBeInTheDocument();
});
it('Renders success for the third indicator if the withdrawal has been executed', async () => {
const mock = {
request: {
query: ExplorerWithdrawalDocument,
variables: {
id: '123',
},
},
result: {
data: {
withdrawal: {
__typename: 'Withdrawal',
id: '123',
status: 'STATUS_FINALIZED',
createdTimestamp: '2022-03-24T11:03:40.026173466Z',
withdrawnTimestamp: '2022-03-24T11:03:40.026173466Z',
ref: 'irrelevant',
txHash: '0x123456890',
details: {
__typename: 'Erc20WithdrawalDetails',
receiverAddress: '0x5435345432342423',
},
},
},
},
};
const res = render(renderComponent('123', 0, [mock]));
// Step 1 should be filled in
expect(res.getByText('Requested')).toBeInTheDocument();
// Step 2
expect(await res.findByText('Prepared')).toBeInTheDocument();
// Step 3
expect(await res.findByText('Complete')).toBeInTheDocument();
});
it('Renders an error under step 2 if the tx status code is ok but there is a graphql error', async () => {
const mock = {
request: {
query: ExplorerWithdrawalDocument,
variables: {
id: '123',
},
},
error: new ApolloError({ errorMessage: 'No such withdrawal' }),
};
const res = render(renderComponent('123', 0, [mock]));
expect(await res.findByText('No such withdrawal')).toBeInTheDocument();
});
});
@@ -0,0 +1,149 @@
import { t } from '@vegaprotocol/react-helpers';
import type { ReactNode } from 'react';
import { Time } from '../time';
import { useExplorerWithdrawalQuery } from './__generated__/Withdrawal';
interface TxsStatsInfoProps {
id: string;
txStatus: number;
className?: string;
}
const OK = 0;
/**
* Shows a user the *current* state of a proposal. Which sound easy, but.. strap in
* 1. Step one is the submission and acceptance of the WithdrawalSubmission. If it is not rejected, it is accepted and we can mark it as complete
* 2. Is complete when there is a multisig bundle available to the user. This means that their funds have been moved to an account locked for
* withdrawal. To move out of this phase, the user (any user - but realistically the owner of the recipient address) needs to execute the withdrawal
* bundle on Ethereum, then we progress to.
* 3. The funds have left the ERC20 bridge and been sent to the user. This is complete.
*
* There could actually be some extra complexity:
* - If a deposit is above { asset { withdrawalThreshold } } then the multisig bundle is still produced (step 2) but cannot be submitted for a period
* of time. The period of time is defined on the ERC20 bridge. Attempts to submit the multisig bundle before that would be rejected.
* - The bridge could be paused, which would cause attempts to complete step three to be rejected
*
* Also:
* - 1 -> 2 is completed automatically by the system
* - 2 -> 3 requires action from the user
* - Any user with an Ethereum wallet can complete 2 -> 3 as above, but it will likely be the person who owns the vega public key of the source and
* the ethereum public key of the recipient. Whoever is looking at this page may be none of those people.
* - This renders fine if the useExplorerWithdrawalQuery fails or returns nothing. It will render an error under the rejection if it failed to fetch
*/
export const WithdrawalProgress = ({ id, txStatus }: TxsStatsInfoProps) => {
const { data, error } = useExplorerWithdrawalQuery({ variables: { id } });
const step2Date = data?.withdrawal?.createdTimestamp || undefined;
const step3Date = data?.withdrawal?.withdrawnTimestamp || undefined;
const isStep1Complete = txStatus === OK;
const isStep2Complete = isStep1Complete && !!step2Date;
const isStep3Complete = isStep2Complete && !!step3Date;
const hasApiError = !!error?.message;
return (
<div className="p-5 mb-12 max-w-xl">
<div className="mx-4 p-4">
<div className="flex items-center">
<WithdrawalProgressIndicator
step={isStep1Complete ? 1 : '✕'}
isComplete={isStep1Complete}
statusDescription={isStep1Complete ? t('Requested') : t('Rejected')}
/>
<WithdrawalProgressSeparator isComplete={isStep1Complete} />
<WithdrawalProgressIndicator
step={2}
isComplete={isStep2Complete}
statusDescription={
isStep2Complete ? t('Prepared') : t('Not prepared')
}
>
{isStep2Complete ? (
<Time date={step2Date} />
) : hasApiError ? (
<span>{error?.message}</span>
) : (
''
)}
</WithdrawalProgressIndicator>
<WithdrawalProgressSeparator isComplete={isStep3Complete} />
<WithdrawalProgressIndicator
step={3}
isComplete={isStep3Complete}
statusDescription={
isStep3Complete ? t('Complete') : t('Not complete')
}
>
{isStep3Complete ? <Time date={step3Date} /> : ''}
</WithdrawalProgressIndicator>
</div>
</div>
</div>
);
};
const classes = {
indicatorFailed:
'rounded-full transition duration-500 ease-in-out h-12 w-12 py-3 border-2 border-red-600 bg-red-600 text-center text-white font-bold leading-5',
textFailed:
'absolute top-0 -ml-10 text-center mt-16 w-32 text-xs font-medium uppercase text-vega-red',
indicatorComplete:
'rounded-full transition duration-500 ease-in-out h-12 w-12 py-3 border-2 border-vega-green-dark bg-vega-green-dark text-center text-white leading-5',
textComplete:
'absolute top-0 -ml-10 text-center mt-16 w-32 text-xs font-medium uppercase text-vega-green-dark',
indicatorIncomplete:
'rounded-full transition duration-500 ease-in-out h-12 w-12 py-3 border-2 border-gray-300 text-center leading-5',
textIncomplete:
'absolute top-0 -ml-10 text-center mt-16 w-32 text-xs font-medium uppercase text-gray-500',
};
interface WithdrawalProgressIndicatorProps {
step: string | number;
isComplete: boolean;
statusDescription: string;
children?: ReactNode;
}
export function WithdrawalProgressIndicator({
isComplete,
statusDescription,
step,
children,
}: WithdrawalProgressIndicatorProps) {
return (
<div className="flex items-center relative">
<div
className={
isComplete ? classes.indicatorComplete : classes.indicatorIncomplete
}
>
{step}
</div>
<div
className={isComplete ? classes.textComplete : classes.textIncomplete}
>
{statusDescription}
<br />
{children}
</div>
</div>
);
}
interface WithdrawalProgressSeparatorProps {
isComplete: boolean;
}
export function WithdrawalProgressSeparator({
isComplete,
}: WithdrawalProgressSeparatorProps) {
return (
<div
className={`flex-auto border-t-2 transition duration-500 ease-in-out ${
isComplete ? 'border-vega-green-dark' : 'border-gray-300'
}`}
></div>
);
}
export default WithdrawalProgress;
@@ -0,0 +1,27 @@
import React from 'react';
import { useLocation } from 'react-router-dom';
// Source: https://scribe.rip/scrolling-to-an-anchor-in-react-when-your-elements-are-rendered-asynchronously-8c64f77b5f34
export const useScrollToLocation = () => {
const scrolledRef = React.useRef(false);
const { hash } = useLocation();
const hashRef = React.useRef(hash);
React.useEffect(() => {
if (hash) {
// We want to reset if the hash has changed
if (hashRef.current !== hash) {
hashRef.current = hash;
scrolledRef.current = false;
}
const id = hash.replace('#', '');
const element = document.getElementById(id);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
scrolledRef.current = true;
}
}
});
};
@@ -0,0 +1,20 @@
import React from 'react';
/**
* Set the document title
* @param segments string array of segments. Will be reversed.
*/
export function useDocumentTitle(segments?: string[]) {
const base = 'VEGA explorer';
const split = ' | ';
React.useEffect(() => {
const segmentsOrdered = segments?.reverse() || [];
if (segments && segments.length > 0) {
document.title = `${segmentsOrdered.join(split)}${split}${base}`;
} else {
document.title = base;
}
}, [segments]);
}

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