Compare commits

...
Author SHA1 Message Date
Edd cf6d6e70bc fix(explorer): cache more appropriately 2022-11-25 19:19:36 +00:00
Edd 9e2dc19426 fix(explorer): fix wss urls 2022-11-25 18:54:46 +00:00
Edd 344971d5a9 fix(explorer): remove old urls from default env 2022-11-25 16:57:08 +00:00
macqbatandMadalina Raicu de1f8b5895 chore(2170): console update ledger entries columns (#2221)
* chore: update ledger entries columns

* chore: update ledger entries columns - remove labels from sender and receiver

* chore: update ledger entries columns - remove labels from sender and receiver

* chore: update ledger entries columns - remove labels from sender and receiver

Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2022-11-25 17:17:21 +01:00
Joe Tsang 5b826f89d8 chore: tests passing (#2231) 2022-11-25 15:10:57 +00:00
Art 246c07f355 feat: view proposed market change (#2189) 2022-11-25 15:10:22 +00:00
macqbat 642bc8072b chore: fix removing closed positions (#2230) 2022-11-25 14:56:59 +00:00
m.ray de8e543bf4 fix(#2171): remove user's pubkey from LP query (#2188)
* fix(#2171): remove user's pubkey from LP query

* fix(#2171): add LP partyID in account events

* fix(#2171): add LP partyID in account events

* fix(#2200): handle NotFound GraphQL errors in async renderer

* fix(#2200): data provider filter apollo graphQL not found error

* fix(#2200): update apollo-client to not report not found error link

* fix(#2200): fix log on not found error link

* fix(#2200): fix set error in data provider

* fix(#2200): extensions type access via index signature

* fix: accounts-data-provider.spec.ts had missing partyId

* fix: revert not found error commit

* fix: revert and set error in data prov
2022-11-25 14:38:02 +00:00
m.ray 787a8ea1b3 fix: deal ticket set market price (#2228) 2022-11-25 08:39:14 -05:00
mattrussell36 d28ff4cfe7 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-25 12:07:00 +00:00
mattrussell36 71e1a116c7 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-25 06:06:10 +00:00
mattrussell36 f0fc737e58 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-25 00:10:25 +00:00
m.ray fe447167ca fix(#2200): handle NotFound GraphQL errors in async renderer (#2204)
* fix(#2200): handle NotFound GraphQL errors in async renderer

* fix(#2200): data provider filter apollo graphQL not found error

* fix(#2200): update apollo-client to not report not found error link

* fix(#2200): fix log on not found error link

* fix(#2200): fix set error in data provider

* fix(#2200): extensions type access via index signature

* fix(#2200): log gql errors that are not NotFound and still throw error in data provider

* fix: remove unused import
2022-11-24 15:52:46 -08:00
m.ray 02a8a8d9ec chore: update explorer stagnet3 links (#2227) 2022-11-24 15:48:39 -08:00
mattrussell36 f7bee22ba6 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-24 18:06:14 +00:00
mattrussell36 df6ae6e8fa chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-24 12:06:15 +00:00
mattrussell36 e25391a18c chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-24 06:05:59 +00:00
mattrussell36 c9b71af830 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-24 00:13:58 +00:00
Matthew Russell 9dfce9e723 fix(#2209): make asset dialog use asset id rather than symbol (#2217)
* fix: make asset dialog use asset id rather than symbol

* fix: tests that relied on asset symbol rather than id

* chore: add missing asset id to mocks

* chore: add asset id to mocks for e2e tests

* chore: add missing asset id for orders mock

* chore: fix console-lite build

* chore: add missing asset ids to mocks
2022-11-23 23:42:22 +00:00
mattrussell36 ad7f263811 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-23 18:07:39 +00:00
Edd 2afd182f03 fix(explorer): use getnodes to avoid nesting (#2198) 2022-11-23 14:47:53 +00:00
Dexter Edwards 6134ac9015 fix: withdrawals dialog broken (#2203) 2022-11-23 14:47:47 +00:00
Matthew Russell 0ccf564ee7 fix(#2137,#2197): correct price for estimate order query (#2159)
* fix: correct price for estimate order query

* chore: remove unnecessary optional chaining, accidental added test file

* chore: dont prevent orders for pending market state

* chore: estimate order query so that expiration is set as timestamp otherwise query fails

* chore: add test helper for market, fix tests and add type for order margin
2022-11-23 14:33:37 +00:00
Joe Tsang f212f5bb28 test(1872): add test for validator status (#2193)
* test: add test for validator status

* chore: fix lint
2022-11-23 14:16:51 +00:00
Edd 22c1a4ad6a fix: remove validatingnodes from all queries (#2199)
* fix: remove validatingnodes from all queries

* fix(explorer-e2e): remove assertion on validatingnodes
2022-11-23 13:36:18 +00:00
mattrussell36 0a0d74dcbd chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-23 12:08:45 +00:00
Edd 031cd9258e feat(explorer): add chain event details pages (#2194)
* feat(explorer): chain event views
2022-11-23 11:07:45 +00:00
mattrussell36 be39008b42 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-23 06:06:17 +00:00
mattrussell36 20b663a092 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-23 00:10:24 +00:00
m.rayandMatthew Russell 41646086e4 chore(#2179): update number formatters across frontend-monorepo (#2182)
* chore: update stagnet3 urls

* chore(#2179): remove normalized number formatter functions and update getNumberFormat

* fix(#2179): fix unit tests on all formatters

* fix(#2179): fix some cypress tests

* fix: fix  trading-accounts.cy.ts

* fix: update staking and wallet teardown tests

* chore: add e2e run-all command

* fix: wallet-eth test

* fix: fix tests in explorer and token

* fix: fix common.functions.js

* fix: fix common.functions.js in explorer

* fix(#2179): fix common.functions.js in explorer

* fix(#2179): fix common.functions.js in explorer

* fix(#2179): fix common.functions.js in explorer

Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2022-11-22 18:14:16 +00:00
Bartłomiej Głownia 7c0bed2f14 fix(#2153): improve positions table updates (#2187) 2022-11-22 19:03:09 +01:00
Ciaran McGhie ce62342d9a feat: add tooltips to headers on the LP dashboard and add some new data points (#2064)
* feat: add tooltips to headers on the details view

* feat: add header tooltips to liqudity dashboard markets page

* feat: add fee level and target stake to market summary list

These two data points are already in our health bar, but we want to call
them out more visibly so you don't have to hover to see them.

* feat: add % Target stake column to market list page

Adds a column which calculates what percentage of the target stake is
currently being supplied. We _trim_ this number to the whole percentage
value, so some precision may be lost, which we can add later if we want.

* chore: remove the estimated return/APY column while we dont use it

We can revert this commit later if we want it to return.

* feat: wrap the status pill with a tooltip

Uses the ui-toolkit tooltip to wrap the status pill, providing a bit
more information for what the statuses mean.

* chore: wrap getTooltipDescription in t() translate fn
2022-11-22 15:50:49 +00:00
mattrussell36 9aa672968f chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-22 12:07:15 +00:00
Art 4b7a513e98 feat: propose network parameter change link (578) (#2174)
* feat: propose network parameter change link (578)

* changeg stagnet3 url in trading e2e
2022-11-22 11:52:31 +01:00
Dexter Edwards 1aff7b1437 feat(2056): pending balances (#2185)
* chore: create store

* chore: migrate logic to use new store

* test: fix test typings
2022-11-22 10:13:39 +00:00
macqbat b749a05736 chore(2071): deal ticket data update fixing (#2169)
* chore: update of deal ticket data

* chore: update of deal ticket data

* chore: update of deal ticket data - fix re-render loop

* chore: update of deal ticket data - add marketDealTicketProvider

* chore: update of deal ticket data - add marketDealTicketProvider

* chore: update of deal ticket data - adjust console-lite to the changes

* chore: update of deal ticket data - fix failing unit tests

* chore: update of deal ticket data - fix failing unit tests

* chore: update of deal ticket data - fix linter failings

* chore: update of deal ticket data - adjust console-lite-e2e

* chore: update of deal ticket data - fix build-spec failings

* chore: update of deal ticket data - fix failing e2e tests

* chore: update of deal ticket data - fix failing e2e tests

* chore: update of deal ticket data - fix failing e2e tests

* chore: update of deal ticket data - remove unnecessary gqls

* chore: update of deal ticket data - remove unnecessary gqls

* chore: update of deal ticket data - remove unnecessary gqls

* chore: update of deal ticket data - fix failings build

* chore: update of deal ticket data - remove redundant data provider

* chore: update of deal ticket data - remove redundant data provider

* chore: update of deal ticket data - fix some types
2022-11-22 09:31:26 +01:00
mattrussell36 a5aed85b43 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-22 06:07:52 +00:00
mattrussell36 2c5a4e479b chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-22 00:12:01 +00:00
Matthew Russell d84612028e chore: update stagnet3 urls (#2180) 2022-11-21 15:55:07 -08:00
mattrussell36 fd8bf74cff chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-21 18:06:15 +00:00
Dexter Edwards 6ecf4d419d chore(2015): remove client fields (#2065)
* chore: remove client fields

* chore: remove type policies

* chore: remove client fields

* test: fix tests

* chore: kill now unused file

* style: lint

* test: adjust test

* style: lint

* Update apps/token/src/routes/staking/home/node-list.tsx

* chore: rebase and fix conflicts

* test: fix failing test

* style: lint
2022-11-21 15:10:43 +00:00
Joe Tsang e4babe42c2 chore: update toml url (#2184) 2022-11-21 12:05:14 +00:00
m.ray 6dffe9c019 chore(#2151): rename market valuation entry and change tooltips on LP table (#2181)
* chore(#2151): rename market valuation entry and change tooltips on LP table

* chore(#2159): rename to Market valuation at entry
2022-11-21 11:30:38 +01:00
mattrussell36 dbf30fc5c9 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-21 06:06:00 +00:00
mattrussell36 5e5dffecfa chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-21 00:12:45 +00:00
mattrussell36 91a065f90e chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-20 18:06:48 +00:00
mattrussell36 7392edc73a chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-20 12:06:16 +00:00
mattrussell36 cf14db9227 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-20 06:08:11 +00:00
mattrussell36 132e3c1be1 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-20 00:11:29 +00:00
mattrussell36 f1e8b81d46 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-19 18:06:47 +00:00
mattrussell36 164bd72a47 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-19 12:07:15 +00:00
mattrussell36 e351d7c8f9 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-19 06:08:17 +00:00
mattrussell36 faa13f32bc chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-19 00:11:50 +00:00
m.ray 0189b9c94e fix: fixes around formatting numbers and arrange edit order dialog (#2178)
* fix: update size and order edit dialog

* 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

* fix: positions formatting in select market and format account numbers

* fix: remove import

* fix: remove redundant comment

* fix: fix unit tests

* fix: fix cypress tests
2022-11-18 19:00:38 +00:00
mattrussell36 c7a0b126ad chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-18 18:06:34 +00:00
Edd 8f8a727b4d feat(explorer): add specific link types, start specific tx views (#2152)
* feat(explorer): add specific link types, start specific tx views

* feat(explorer): add raw tx view

* chore(explorer): remove default nx vega url

* fix(explorer): improve prop typing for link components

* fix(explorer): remove console log

* fix(explorer): remove unused import

* fix(explorer): refactor txdetails component selection
2022-11-18 17:10:57 +00:00
Art 8e5012891c feat: no markets (#2097)
* feat: no markets

* feat: no markets

* feat: no markets

* feat: no markets

* feat: no markets
2022-11-18 17:08:48 +00:00
Bartłomiej Głownia 98a3d2267b fix(#2153): use correct decimal places for marginLevels (#2163) 2022-11-18 17:07:51 +00:00
Sam Keen 87df790fd1 feat(1872): validator info table now using better status query (#2067)
* feat(1872): validator info table now using better status query

* feat(1872): removed redundant import

* feat(1872): removed unnecessary useMemo dependency for node-list.tsx

* feat(1872) Status translations as map, with error capture

* feat(1872) status function now returns key to be translated rather than doing the translating
2022-11-18 14:57:43 +00:00
Dexter Edwards 4dc0e7fd56 fix: multisig app (#2173) 2022-11-18 13:43:44 +00:00
Dexter Edwards 1abd1d0ebf chore(2161): migrate queries (#2162)
* chore: migrate home page

* chore: migrate vote buttons

* chore: migrate stake linkings

* chore: add missing GQL files and run generate

* chore: fix broken typings

* chore: migrate proposal market update query

* test: fix tests

* fix: remove dead type and replace with new one
2022-11-18 13:36:24 +00:00
mattrussell36 7d2a3af358 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-18 12:07:54 +00:00
Sam Keen ba4a5f104c feat(1824): update docs links to new URL structure (remove '/docs') (#2140)
* feat(1824): Update docs links to new URL structure (remove '/docs')

* feat(1824): Updated proposals doc links to use new helper

* feat(1824): ensuring custom url string added to link in proposal-form-terms.tsx
2022-11-18 10:32:34 +00:00
Sam Keen 5922994a26 fix(2165): spacing tweak to expected proposal outcome text (#2166) 2022-11-18 10:05:06 +00:00
Matthew Russell 72cec2ebcb fix: allow error message data from wallet to be displayed (#2157) 2022-11-18 08:24:04 +00:00
mattrussell36 5a4c5d800e chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-18 06:08:30 +00:00
mattrussell36 954e8f7cc2 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-18 00:13:55 +00:00
m.ray b1fe10e6d4 fix(#2144): fix positions table notional value and remove total row (#2155) 2022-11-17 21:35:29 +00:00
Matthew Russell 19d0df8b1e chore: convert type mappings to objects with typed keys based on schema (#2103) 2022-11-17 19:19:11 +00:00
Joe Tsang 6b6c05f04d test(2061): token vegawallet v2 (#2150)
* test: use vega wallet v2 connect flow

* test: update tests using wallet v2

* test: fix failing token test

* test: add wait for spinner

* chore: purge capsule teardown
2022-11-17 18:22:51 +00:00
mattrussell36 f77fc9e131 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-17 18:08:12 +00:00
Sam Keen e2f5645a90 feat(2141): explorer footer should be at the bottom of the page (#2143)
* feat(2141): Explorer footer should be at the bottom of the page
2022-11-17 14:49:28 +00:00
mattrussell36 2375b14781 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-17 12:07:25 +00:00
macqbat 61f171dfbd chore: market proposal selector - small view improvements (#2106)
* chore: market proposal selector - small view improvements

* chore: market proposal selector - small view improvements
2022-11-17 09:49:29 +01:00
mattrussell36 74527d9ae3 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-17 06:07:31 +00:00
mattrussell36 1be0aa3dad chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-17 00:13:12 +00:00
Matthew Russell 5fe994521f chore(#1909): remove deprecated apis (#2081)
* chore: update queries using deprecated fields

* chore: regen generated files

* fix: account for new data shape as a result of PartyBalance.graphql changes

* fix: accounts data resulting from  MarketInfo.graphql changes

* fix: accounts data resulting from  PartyMarketData.graphql changes

* fix: accounts data resulting from  MarketPositions.graphql changes

* fix: accounts data resulting from  Accounts.graphql changes

* chore: update generate functions to return the correct shape

* chore: fix deal ticket tests

* chore: add missing fields too generateMarketInfoQuery mock

* chore: remove tsignore now object is properly typed

* fix: add missing mock for trading page

* chore: fix import path for validation hook

* chore: fix no data display for console lite assets
2022-11-16 12:31:23 -08:00
m.ray 53609bf93c feat(#2039): add tooltips for transfer types in ledger entries (#2100) 2022-11-16 19:42:53 +00:00
mattrussell36 b9202237b4 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-16 18:05:50 +00:00
Joe Tsang 6ad470fcb3 chore(2027): update smoke tests (#2099)
* chore: update smoke tests

* chore: remove tag from test
2022-11-16 17:38:20 +00:00
Radosław Szpiech 0bad181334 chore: remove unnecessary import vega wallet (#2098) 2022-11-16 16:33:23 +01:00
Radosław Szpiech 9f4f54af6d chore: separate running vegawallet service out of vegacapsule (#2095) 2022-11-16 16:04:33 +01:00
macqbat 52e1757d33 feat(577): view new market proposals (#2078)
* feat: market proposal selector

* feat: market proposal selector

* feat: market proposal selector

* feat: market proposal selector

* feat: market proposal selector - fix linters

* feat: market proposal selector - add some int tests

* feat: market proposal selector - add some unit tests

* feat: market proposal selector - improve union type extracting

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests
2022-11-16 15:36:03 +01:00
Bartłomiej Głowniaandmaciek d1b45a65a0 feat(#1812): do not require Ethereum connection to display collateral (#2028)
* feat(#1812): don not require ethereum connection to display collateral

* feat(#1812): amend trading-account e2e tests

* feat(#1812): move Web3ConnectDialog to dialogs container, fix Web3Container childrenOnly option

* feat(#1812): fix withdraw e2e tests

* feat(#1812): reverse DialogsContainer changes, add Web3ConnectUncontrolledDialog

* feat(#1812): wrap WithdrawalDialog with  Web3Container

* feat(#1812): fix deposit dialog handling in ZeroBalanceError

* feat(#1812): fix deposit and withdraw dialog e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

* feat: market proposal selector - fix failing on develop e2e tests

Co-authored-by: maciek <maciek@vegaprotocol.io>
2022-11-16 15:10:17 +01:00
mattrussell36 3b2750dd6d chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-16 12:08:08 +00:00
mattrussell36 315ab428e4 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-16 06:07:53 +00:00
John Walley 06ea58555e fix: update callback when market changes (#1934) 2022-11-15 20:08:39 -08:00
mattrussell36 178d4d50ba chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-16 00:12:11 +00:00
Matthew Russell 3077a634d1 fix(#1691,#2040): deal ticket validation (#2045)
* feat: update validation for size and price so they are reported simultaneously

* feat: adjust styles so error messages for price/size are rendered on one line

* fix: missing key in map error

* feat: split validation out on a field by field basis

* refactor: remove unnecessary price setting and just use props to calc market price

* refactor: rename setOrder func and add a comment

* chore: add type for form fields to allow for summary field

* fix: layout of market order size and price

* fix: casing of size/price in validation message

* refactor: fix type errors for summary react nodes and for tif and type validation

* feat: break out functions for testing market.state and market.tradingmode on submit

* fix: deal ticket test for last price value

* chore: remove unused files and move hooks and utils to correct dirs

* chore: tidy up constants

* fix: const before enum invalid syntax

* feat: dont block submission if not enough margin but do if zero balance

* chore: remove duplicated margin warning message

* feat: dont allow margin warning and error message to render at the same time

* feat: make trading mode check just a warning rather than error message

* test: make markets active so they are tradable, renaming describe blocks for clarity

* test: adjust test ids and disabled state and fix tests

* test: include AC codes in tests

* chore: remove click of in test as form is already dirty

* fix: lint errors, only show margin warning if you have balance

* chore: add ts ignore

* chore: re add use-order-validation hook for console-lite specifically

* chore: update use-order-validation test after consumed margin check hook changed

* fix: circular deps issue in console-lite

* chore: update use order validation hook to use Schema rather than direct import
2022-11-15 16:00:14 -08:00
mattrussell36 d70bc0fdd5 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-15 18:06:06 +00:00
Radosław Szpiech 16e4c4465a chore: add vega_docs_url to all trading envs (#2079) 2022-11-15 14:47:49 +00:00
Art a3df65952d feat: toast component (1677) (#1998) 2022-11-15 15:26:13 +01:00
Edd e598cd1247 chore: update explorer to use v2 queries (#2049)
* fix: migrate queries to latest apis
* fix: remove oracles section for now
* fix: dive in to fields correctly
* fix: update queries
* fix: fragment for stats fields
* fix: rename triple underscore generated
* chore: refactor types that have moved
* chore(explorer): disable e2e test that asserts json structure
2022-11-15 12:31:25 +00:00
mattrussell36 34f3efb5c5 chore: update tranches
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-15 12:04:52 +00:00
Joe Tsang c50efe02a6 test(2072): proposal deadline changes (#2073)
* test: mostly passing

* test: more fixes
2022-11-15 12:56:41 +01:00
555 changed files with 17308 additions and 7608 deletions
@@ -0,0 +1,25 @@
inputs:
passphrase:
description: 'Wallet password'
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
- name: Import network
shell: bash
run: vega wallet network import --force --from-file ./frontend-monorepo/vegacapsule/wallet-config.toml --home ~/.vegacapsule/testnet/wallet
- name: Start service using capsule network
shell: bash
run: vegawallet-dummy service run --network DV --wallet capsule_wallet --passphrase-file ./passphrase --home ~/.vegacapsule/testnet/wallet &
+2 -14
View File
@@ -3,9 +3,6 @@ inputs:
description: 'Recovery phrase'
passphrase:
description: 'Wallet password'
capsule:
description: 'Is Capsule network used'
default: 'false'
runs:
using: 'composite'
steps:
@@ -23,25 +20,16 @@ runs:
- name: Import wallet
shell: bash
if: ${{ inputs.capsule=='false' }}
run: vega wallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
- name: Create public key 2
shell: bash
if: ${{ inputs.capsule=='false' }}
run: vega wallet key generate -w UI_Trading_Test -p ./passphrase --home ~/.vegacapsule/testnet/wallet
- name: Import network
shell: bash
if: ${{ inputs.capsule=='false' }}
run: vega wallet network import --from-url="https://raw.githubusercontent.com/vegaprotocol/networks-internal/master/stagnet3/stagnet3.toml" --force --home ~/.vegacapsule/testnet/wallet
run: vega wallet network import --from-url="https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet3/vegawallet-stagnet3.toml" --force --home ~/.vegacapsule/testnet/wallet
- name: Start service using fairground network
- name: Start service using stagnet3 network
shell: bash
if: ${{ inputs.capsule=='false' }}
run: vegawallet-dummy service run --network stagnet3 --wallet UI_Trading_Test --passphrase-file ./passphrase --home ~/.vegacapsule/testnet/wallet &
- name: Start service using capsule network
shell: bash
if: ${{ inputs.capsule=='true' }}
run: vegawallet-dummy service run --network DV --wallet capsule_wallet --passphrase-file ./passphrase --home ~/.vegacapsule/testnet/wallet &
@@ -58,4 +58,3 @@ jobs:
gobin: ${{needs.manual.outputs.gobin}}
skip-cache: ${{needs.manual.outputs.skip-cache}}
tags: ${{needs.manual.outputs.tags}}
capsule-teardown: false
@@ -17,4 +17,3 @@ jobs:
gobin: /home/runner/go/bin
tags: --env.grepTags '[ @smoke, @regression, @slow ]'
night-run: true
capsule-teardown: false
@@ -70,7 +70,6 @@ jobs:
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: false
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
+2 -9
View File
@@ -24,10 +24,6 @@ on:
required: false
type: boolean
default: false
capsule-teardown:
required: false
type: boolean
default: false
jobs:
explorer-e2e:
@@ -79,12 +75,10 @@ jobs:
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
- name: Set up Vegawallet for docker
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: true
######
## Run some tests
@@ -102,7 +96,6 @@ jobs:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: ${{ inputs.capsule-teardown }}
CYPRESS_NIGHTLY_RUN: ${{ inputs.night-run }}
######
+2 -9
View File
@@ -20,10 +20,6 @@ on:
tags:
required: false
type: string
capsule-teardown:
required: false
type: boolean
default: false
jobs:
token-e2e:
@@ -75,12 +71,10 @@ jobs:
## Setup a Vega wallet for our user
######
- name: Set up Vegawallet
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
- name: Set up Vegawallet for docker
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: true
######
## Run some tests
@@ -98,7 +92,6 @@ jobs:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: ${{ inputs.capsule-teardown }}
######
## Upload logs
@@ -71,7 +71,6 @@ jobs:
with:
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
capsule: false
# To make sure that all Cypress binaries are installed properly
- name: Install cypress bins
-5
View File
@@ -20,9 +20,6 @@ on:
night-run:
required: false
type: boolean
capsule-teardown:
required: false
type: boolean
jobs:
run-console-lite-e2e:
@@ -45,7 +42,6 @@ jobs:
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
night-run: ${{ inputs.night-run }}
capsule-teardown: ${{ inputs.capsule-teardown }}
run-liquidity-e2e:
uses: ./.github/workflows/cypress-liquidity-provision-dashboard-e2e.yml
@@ -68,7 +64,6 @@ jobs:
gobin: ${{ inputs.gobin }}
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
capsule-teardown: ${{ inputs.capsule-teardown }}
run-trading-e2e:
uses: ./.github/workflows/cypress-trading-e2e.yml
+19 -1
View File
@@ -1,6 +1,24 @@
module.exports = {
stories: [],
addons: ['@storybook/addon-essentials', '@storybook/addon-a11y'],
addons: [
'@storybook/addon-actions',
'@storybook/addon-viewport',
{
name: '@storybook/addon-docs',
options: {
configureJSX: true,
babelOptions: {},
sourceLoaderOptions: null,
transcludeMarkdown: true,
},
},
'@storybook/addon-controls',
'@storybook/addon-backgrounds',
'@storybook/addon-toolbars',
'@storybook/addon-measure',
'@storybook/addon-outline',
'@storybook/addon-a11y',
],
// uncomment the property below if you want to apply some webpack config globally
// webpackFinal: async (config, { configType }) => {
// // Make whatever fine-grained changes you need that should apply to all storybook configs
+1 -1
View File
@@ -1,6 +1,6 @@
# App configuration variables
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
NX_VEGA_ENV=STAGNET3
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
@@ -1,10 +1,12 @@
import { connectVegaWallet } from '../support/vega-wallet';
import { aliasQuery } from '@vegaprotocol/cypress';
import {
generateMarket,
generateMarketData,
generateMarketsCandles,
generateMarketsData,
generateSimpleMarkets,
} from '../support/mocks/generate-markets';
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
import { generateMarketTags } from '../support/mocks/generate-market-tags';
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
@@ -14,15 +16,20 @@ import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-p
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';
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, 'DealTicket', generateDealTicket());
aliasQuery(req, 'MarketData', generateMarketData());
aliasQuery(req, 'Market', generateMarket());
aliasQuery(req, 'MarketTags', generateMarketTags());
aliasQuery(req, 'MarketPositions', generateMarketPositions());
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
@@ -45,7 +52,7 @@ describe('market selector', { tags: '@smoke' }, () => {
it('should be properly rendered', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
connectVegaWallet();
cy.get('input[placeholder="Search"]').should(
'have.value',
markets[0].tradableInstrument.instrument.name
@@ -69,7 +76,7 @@ describe('market selector', { tags: '@smoke' }, () => {
it('typing should change list', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
connectVegaWallet();
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.getByTestId('market-pane')
.children()
@@ -105,7 +112,7 @@ describe('market selector', { tags: '@smoke' }, () => {
it.skip('keyboard navigation should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
connectVegaWallet();
cy.get('input[placeholder="Search"]').type('{backspace}');
cy.get('input[placeholder="Search"]').clear();
cy.focused().realPress('ArrowDown');
@@ -127,11 +134,13 @@ describe('market selector', { tags: '@smoke' }, () => {
if (markets?.length) {
cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
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"]').clear();
cy.get('input[placeholder="Search"]').then((search) => {
cy.wrap(search).clear();
});
cy.getByTestId('market-pane')
.children()
.find('[role="button"]')
@@ -1,11 +1,12 @@
import { connectVegaWallet } from '../support/vega-wallet';
import { aliasQuery } from '@vegaprotocol/cypress';
import {
generateSimpleMarkets,
generateMarketsCandles,
generateMarketsData,
generateMarket,
generateMarketData,
} from '../support/mocks/generate-markets';
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
import { generateMarketTags } from '../support/mocks/generate-market-tags';
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
@@ -14,16 +15,19 @@ import { generatePartyMarketData } from '../support/mocks/generate-party-market-
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';
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, 'DealTicket', generateDealTicket());
aliasQuery(req, 'MarketTags', generateMarketTags());
aliasQuery(req, 'MarketPositions', generateMarketPositions());
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
@@ -32,6 +36,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
aliasQuery(req, 'MarketDepth', generateMarketDepth());
aliasQuery(req, 'Market', generateMarket());
aliasQuery(req, 'MarketData', generateMarketData());
});
cy.visit('/markets');
cy.wait('@Markets').then((response) => {
@@ -58,7 +63,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('side selector should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
connectVegaWallet();
cy.get('#step-1-control [aria-label^="Selected value"]').should(
'have.text',
'Long'
@@ -77,7 +82,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
if (markets?.length) {
cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
connectVegaWallet();
cy.getByTestId('next-button').scrollIntoView().click();
cy.get('button[aria-label="Open long position"]').should(
@@ -109,7 +114,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('size slider should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet();
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();
@@ -131,7 +136,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('percentage selection should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet();
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();
@@ -158,7 +163,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('size input should work well', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet();
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();
@@ -186,7 +191,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('slippage value should be displayed', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet();
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();
@@ -202,7 +207,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('allow slippage value to be adjusted', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet();
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();
@@ -230,7 +235,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('notional position size should be present', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet();
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();
@@ -257,7 +262,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
it('total fees should be displayed', () => {
if (markets?.length) {
cy.visit(`/trading/${markets[1].id}`);
cy.connectVegaWallet();
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();
@@ -265,14 +270,17 @@ describe('Market trade', { tags: '@smoke' }, () => {
.find('dt')
.eq(3)
.should('have.text', 'Est. Fees (tDAI)');
cy.get('#step-2-panel').find('dd').eq(3).should('have.text', '3 (3.03%)');
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();
connectVegaWallet();
cy.get('#step-3-control').click();
cy.getByTestId('review-trade')
@@ -287,7 +295,10 @@ describe('Market trade', { tags: '@smoke' }, () => {
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
cy.get('#step-3-panel').find('dd').eq(3).should('have.text', '3 (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', ' - ');
@@ -299,7 +310,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
if (markets?.length) {
cy.viewport('iphone-xr');
cy.visit(`/trading/${markets[0].id}`);
cy.connectVegaWallet();
connectVegaWallet();
cy.get('#step-3-control').click();
// Start from the bottom tooltip to ensure the tooltip above
@@ -1,3 +1,4 @@
import { connectVegaWallet } from '../support/vega-wallet';
import { aliasQuery } from '@vegaprotocol/cypress';
import {
generatePositions,
@@ -13,13 +14,15 @@ import {
generateMarketsData,
generatePositionsMarkets,
} from '../support/mocks/generate-markets';
import { generateChainId } from '../support/mocks/generate-chain-id';
import { generateStatistics } from '../support/mocks/generate-statistics';
describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
it('button for wallet connect should work', () => {
cy.visit('/');
cy.get('[href="/portfolio"]').eq(0).click();
cy.getByTestId('trading-connect-wallet').should('be.visible');
cy.connectVegaWallet();
connectVegaWallet();
cy.getByTestId('trading-connect-wallet').should('not.exist');
});
});
@@ -27,6 +30,8 @@ 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());
@@ -38,7 +43,7 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
it('certain tabs should exist', () => {
cy.visit('/portfolio');
cy.connectVegaWallet();
connectVegaWallet();
cy.getByTestId('assets').click();
cy.location('pathname').should('eq', '/portfolio/assets');
@@ -59,6 +64,8 @@ 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());
@@ -67,7 +74,7 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
aliasQuery(req, 'Assets', generateAssets());
});
cy.visit('/portfolio/assets');
cy.connectVegaWallet();
connectVegaWallet();
});
it('data should be properly rendered', () => {
@@ -88,6 +95,8 @@ 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());
@@ -96,7 +105,7 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
aliasQuery(req, 'Assets', generateAssets());
});
cy.visit('/portfolio/positions');
cy.connectVegaWallet();
connectVegaWallet();
});
it('data should be properly rendered', () => {
@@ -107,11 +116,13 @@ 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());
});
cy.visit('/portfolio/orders');
cy.connectVegaWallet();
connectVegaWallet();
});
it('data should be properly rendered', () => {
@@ -122,11 +133,13 @@ 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());
});
cy.visit('/portfolio/fills');
cy.connectVegaWallet();
connectVegaWallet();
});
it('data should be properly rendered', () => {
@@ -137,6 +150,8 @@ 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 });
@@ -147,9 +162,11 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
aliasQuery(req, 'Assets', {
assetsConnection: { edges: null, __typename: 'AssetsConnection' },
});
aliasQuery(req, 'Margins', generateMargins());
aliasQuery(req, 'MarketsData', generateMarketsData());
});
cy.visit('/portfolio');
cy.connectVegaWallet();
connectVegaWallet();
});
it('"No data to display" should be always displayed', () => {
@@ -1,5 +1,5 @@
import type { Market } from '@vegaprotocol/market-list';
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
export const protoCandles = [
@@ -79,8 +79,8 @@ export const protoCandles = [
export const protoMarket: Market = {
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
state: MarketState.STATE_ACTIVE,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
state: Schema.MarketState.STATE_ACTIVE,
decimalPlaces: 5,
positionDecimalPlaces: 0,
marketTimestamps: {
@@ -116,7 +116,12 @@ export const protoMarket: Market = {
product: {
__typename: 'Future',
quoteName: 'DAI',
settlementAsset: { symbol: 'tDAI', __typename: 'Asset', decimals: 5 },
settlementAsset: {
__typename: 'Asset',
id: 'asset-id',
symbol: 'tDAI',
decimals: 5,
},
},
__typename: 'Instrument',
},
@@ -144,4 +149,8 @@ export const singleMarket: SingleMarketFieldsFragment = {
},
},
},
depth: {
__typename: 'MarketDepth',
lastTrade: { price: '9893006', __typename: 'Trade' },
},
};
@@ -1,6 +1,6 @@
import merge from 'lodash/merge';
import type { AccountsQuery } from '@vegaprotocol/accounts';
import { AccountType } from '@vegaprotocol/types';
import { Schema as Types } from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest';
export const generateAccounts = (
@@ -10,67 +10,85 @@ export const generateAccounts = (
party: {
__typename: 'Party',
id: Cypress.env('VEGA_PUBLIC_KEY'),
accounts: [
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '100000000',
market: null,
asset: {
__typename: 'Asset',
id: 'asset-id',
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: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '100000000',
market: {
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
__typename: 'Market',
{
__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',
},
},
},
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: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_MARGIN,
balance: '1000',
market: {
__typename: 'Market',
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
{
__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',
},
},
},
asset: {
__typename: 'Asset',
id: 'asset-id',
{
__typename: 'AccountEdge',
node: {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '100000000',
market: null,
asset: {
__typename: 'Asset',
id: 'asset-0',
},
},
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_MARGIN,
balance: '1000',
market: {
__typename: 'Market',
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
},
asset: {
__typename: 'Asset',
id: 'asset-id-2',
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '100000000',
market: null,
asset: {
__typename: 'Asset',
id: 'asset-0',
},
},
],
],
},
},
};
return merge(defaultAccounts, override);
@@ -0,0 +1,16 @@
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,52 +0,0 @@
import type { DealTicketQuery } from '@vegaprotocol/deal-ticket';
import { MarketTradingMode, MarketState } from '@vegaprotocol/types';
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
export const generateDealTicket = (
override?: PartialDeep<DealTicketQuery>
): DealTicketQuery => {
const defaultResult: DealTicketQuery = {
market: {
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
decimalPlaces: 5,
positionDecimalPlaces: 0,
state: MarketState.STATE_ACTIVE,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
tradableInstrument: {
instrument: {
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
name: 'AAVEDAI Monthly (30 Jun 2022)',
product: {
quoteName: 'DAI',
settlementAsset: {
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
name: 'tDAI TEST',
decimals: 5,
__typename: 'Asset',
},
__typename: 'Future',
},
__typename: 'Instrument',
},
__typename: 'TradableInstrument',
},
depth: {
lastTrade: { price: '9893006', __typename: 'Trade' },
__typename: 'MarketDepth',
},
fees: {
factors: {
makerFee: '0.0002',
infrastructureFee: '0.0005',
liquidityFee: '0.001',
__typename: 'FeeFactors',
},
__typename: 'Fees',
},
__typename: 'Market',
},
};
return merge(defaultResult, override);
};
@@ -1,31 +1,44 @@
export const generateMarketPositions = () => {
import type { MarketPositionsQuery } from '@vegaprotocol/deal-ticket';
import { Schema } from '@vegaprotocol/types';
export const generateMarketPositions = (): MarketPositionsQuery => {
return {
party: {
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
accounts: [
{
type: 'General',
asset: {
decimals: 5,
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',
},
},
},
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',
},
},
},
},
{
type: 'Margin',
asset: {
decimals: 5,
},
balance: '265329',
market: {
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
__typename: 'Market',
},
},
],
],
},
positionsConnection: {
edges: [
{
@@ -1,9 +1,5 @@
import merge from 'lodash/merge';
import {
AuctionTrigger,
MarketState,
MarketTradingMode,
} from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import type {
MarketsQuery,
Market,
@@ -15,6 +11,7 @@ import type {
import { protoMarket, protoCandles, singleMarket } from './commons';
import type { PartialDeep } from 'type-fest';
import type { MarketQuery } from '@vegaprotocol/market-list';
import type { MarketDataQuery } from '@vegaprotocol/market-list';
export const generateSimpleMarkets = (): MarketsQuery => {
const markets: Market[] = [
@@ -22,7 +19,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -42,8 +39,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'XYZalpha',
__typename: 'Asset',
id: 'asset-XYZalpha',
symbol: 'XYZalpha',
decimals: 5,
},
},
@@ -56,7 +54,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: 'ccf2f04865e5951ac3405da6e16b7cbdb535a0ad32df4df2dbed4262cf473255',
state: MarketState.STATE_SUSPENDED,
state: Schema.MarketState.STATE_SUSPENDED,
tradableInstrument: {
instrument: {
id: '',
@@ -76,8 +74,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'XYZbeta',
__typename: 'Asset',
id: 'asset-XYZbeta',
symbol: 'XYZbeta',
decimals: 5,
},
},
@@ -90,7 +89,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '6030e5b4e0ca3297a26081e5af4d453f97f96baab2d74bf56f84efcffc4c382f',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -111,8 +110,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'DAI',
settlementAsset: {
symbol: 'tDAI',
__typename: 'Asset',
id: 'asset-tDAI',
symbol: 'tDAI',
decimals: 5,
},
},
@@ -125,7 +125,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: 'de74a5572045b300e8ec50d136896912ec76e7d7ec135bc305dfd4854d9363a4',
state: MarketState.STATE_PENDING,
state: Schema.MarketState.STATE_PENDING,
tradableInstrument: {
instrument: {
id: '',
@@ -145,8 +145,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'XYZbeta',
__typename: 'Asset',
id: 'asset-XYZbeta',
symbol: 'XYZbeta',
decimals: 5,
},
},
@@ -159,7 +160,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '31ea96284611771e486c820acb26a325a99664f9854b5a7e7ad99023efa8f9e6',
state: MarketState.STATE_CLOSED,
state: Schema.MarketState.STATE_CLOSED,
tradableInstrument: {
instrument: {
id: '',
@@ -178,8 +179,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'tUSDC',
__typename: 'Asset',
id: 'asset-tUSDC',
symbol: 'tUSDC',
decimals: 5,
},
},
@@ -192,7 +194,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '34cff959cdc2ffdb0f167820d701fe8b51cc6b8588e650d93369aaa22d6f8b74',
state: MarketState.STATE_SETTLED,
state: Schema.MarketState.STATE_SETTLED,
tradableInstrument: {
instrument: {
id: '',
@@ -213,8 +215,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'tBTC',
__typename: 'Asset',
id: 'asset-tBTC',
symbol: 'tBTC',
decimals: 5,
},
},
@@ -227,7 +230,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '87b0bbb3c171baa5d97dfc3852332829c91e5c5dc9f7c8fb584c6d8ac75aaaf2',
state: MarketState.STATE_SETTLED,
state: Schema.MarketState.STATE_SETTLED,
tradableInstrument: {
instrument: {
id: '',
@@ -247,8 +250,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'XYZgamma',
__typename: 'Asset',
id: 'asset-XYZgamma',
symbol: 'XYZgamma',
decimals: 5,
},
},
@@ -261,7 +265,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '45266143c6e9b58f4cff9b8906e971c531bb29ea7af01066973f9b77e8134823',
state: MarketState.STATE_PENDING,
state: Schema.MarketState.STATE_PENDING,
tradableInstrument: {
instrument: {
id: '',
@@ -282,8 +286,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'tBTC',
__typename: 'Asset',
id: 'asset-tBTC',
symbol: 'tBTC',
decimals: 5,
},
},
@@ -296,7 +301,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '65663ebdc96161162769c4d5c5508137416748178d7cb28e2cb0d07a151a2bc6',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -317,8 +322,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'BTC',
settlementAsset: {
symbol: 'tBTC',
__typename: 'Asset',
id: 'asset-tBTC',
symbol: 'tBTC',
decimals: 5,
},
},
@@ -331,7 +337,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '234afabd27e3bce1a879039c041f9f00f915d98459935ddafd0169d38dd13850',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -353,8 +359,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'tUSDC',
__typename: 'Asset',
id: 'asset-tUSDC',
symbol: 'tUSDC',
decimals: 5,
},
},
@@ -367,7 +374,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '9f2a3c1caa67bb0773ec18d908d32b55b129b9ec2d106a8e9a87f6aa5c0375a6',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -389,8 +396,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'EURO',
settlementAsset: {
symbol: 'tEURO',
__typename: 'Asset',
id: 'asset-tEURO',
symbol: 'tEURO',
decimals: 5,
},
},
@@ -403,7 +411,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '8a45ee934d3ddac4b036f9884df1064a5353c620a56f775ba36597d0edef9a7a',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -423,8 +431,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'XYZgamma',
__typename: 'Asset',
id: 'asset-XYZgamma',
symbol: 'XYZgamma',
decimals: 5,
},
},
@@ -437,7 +446,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: 'aede7b9ac0c3b225004929c5455160a00f59864aad32ec366e8a2bff1b30fd0f',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -458,8 +467,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'tBTC',
__typename: 'Asset',
id: 'asset-tBTC',
symbol: 'tBTC',
decimals: 5,
},
},
@@ -472,7 +482,7 @@ export const generateSimpleMarkets = (): MarketsQuery => {
{
...protoMarket,
id: '9398707e01daa1a1f1ca6ff87cf8d6c03fe7373ce31121ce81b99a129e6bda47',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
id: '',
@@ -493,8 +503,9 @@ export const generateSimpleMarkets = (): MarketsQuery => {
__typename: 'Future',
quoteName: 'USD',
settlementAsset: {
symbol: 'tBTC',
__typename: 'Asset',
id: 'asset-tBTC',
symbol: 'tBTC',
decimals: 5,
},
},
@@ -1143,52 +1154,51 @@ export const generateFillsMarkets = () => {
};
};
const markets = [
{
data: {
market: {
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
__typename: 'Market',
},
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
staticMidPrice: '0',
indicativePrice: '0',
bestStaticBidPrice: '0',
bestStaticOfferPrice: '0',
indicativeVolume: '0',
bestBidPrice: '0',
bestOfferPrice: '0',
markPrice: '17588787',
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
__typename: 'MarketData',
},
__typename: 'Market',
},
{
data: {
market: {
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
__typename: 'Market',
},
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
staticMidPrice: '0',
indicativePrice: '0',
bestStaticBidPrice: '0',
bestStaticOfferPrice: '0',
indicativeVolume: '0',
bestBidPrice: '0',
bestOfferPrice: '0',
markPrice: '84377569',
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
__typename: 'MarketData',
},
__typename: 'Market',
},
];
export const generateMarketsData = (
override?: PartialDeep<MarketsDataQuery>
): MarketsDataQuery => {
const markets = [
{
data: {
market: {
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
__typename: 'Market',
},
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
staticMidPrice: '0',
indicativePrice: '0',
bestStaticBidPrice: '0',
bestStaticOfferPrice: '0',
indicativeVolume: '0',
bestBidPrice: '0',
bestOfferPrice: '0',
markPrice: '17588787',
trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
__typename: 'MarketData',
},
__typename: 'Market',
},
{
data: {
market: {
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
__typename: 'Market',
},
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
staticMidPrice: '0',
indicativePrice: '0',
bestStaticBidPrice: '0',
bestStaticOfferPrice: '0',
indicativeVolume: '0',
bestBidPrice: '0',
bestOfferPrice: '0',
markPrice: '84377569',
trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
__typename: 'MarketData',
},
__typename: 'Market',
},
];
const defaultResult: MarketsDataQuery = {
marketsConnection: {
__typename: 'MarketConnection',
@@ -1215,7 +1225,7 @@ export const generatePositionsMarkets = () => {
decimalPlaces: 5,
positionDecimalPlaces: 0,
state: 'STATE_ACTIVE',
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
fees: {
factors: {
makerFee: '0.0002',
@@ -1244,9 +1254,10 @@ export const generatePositionsMarkets = () => {
},
product: {
settlementAsset: {
__typename: 'Asset',
id: 'asset-tDAI',
symbol: 'tDAI',
decimals: 5,
__typename: 'Asset',
},
quoteName: 'DAI',
__typename: 'Future',
@@ -1298,9 +1309,10 @@ export const generatePositionsMarkets = () => {
},
product: {
settlementAsset: {
__typename: 'Asset',
id: 'asset-tDAI',
symbol: 'tDAI',
decimals: 5,
__typename: 'Asset',
},
quoteName: 'DAI',
__typename: 'Future',
@@ -1353,9 +1365,10 @@ export const generatePositionsMarkets = () => {
},
product: {
settlementAsset: {
__typename: 'Asset',
id: 'asset-tEURO',
symbol: 'tEURO',
decimals: 5,
__typename: 'Asset',
},
quoteName: 'EURO',
__typename: 'Future',
@@ -1386,3 +1399,34 @@ export const generateMarket = (): MarketQuery => {
},
};
};
export const generateMarketData = (): MarketDataQuery => {
return {
marketsConnection: {
edges: [
{
node: {
data: {
market: {
id: protoMarket.id,
__typename: 'Market',
},
marketTradingMode:
Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
staticMidPrice: '0',
indicativePrice: '0',
bestStaticBidPrice: '0',
bestStaticOfferPrice: '0',
indicativeVolume: '0',
bestBidPrice: '0',
bestOfferPrice: '0',
markPrice: '17588787',
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
__typename: 'MarketData',
},
},
},
],
},
};
};
@@ -1,63 +1,78 @@
import merge from 'lodash/merge';
import type { PartyBalanceQuery } from '@vegaprotocol/deal-ticket';
import type { PartialDeep } from 'type-fest';
import { AccountType } from '@vegaprotocol/types';
import { Schema as Types } from '@vegaprotocol/types';
export const generatePartyBalance = (
override?: PartialDeep<PartyBalanceQuery>
): PartyBalanceQuery => {
const defaultResult: PartyBalanceQuery = {
party: {
accounts: [
{
balance: '88474051',
type: AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
name: 'tDAI TEST',
decimals: 5,
__typename: 'Asset',
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: 'AccountBalance',
},
{
balance: '100000000',
type: AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
name: 'tEURO TEST',
decimals: 5,
__typename: 'Asset',
{
__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: 'AccountBalance',
},
{
balance: '3412867',
type: AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
name: 'tDAI TEST',
decimals: 5,
__typename: 'Asset',
{
__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: 'AccountBalance',
},
{
balance: '70007',
type: AccountType.ACCOUNT_TYPE_GENERAL,
asset: {
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
name: 'tDAI TEST',
decimals: 5,
__typename: 'Asset',
{
__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: 'AccountBalance',
},
],
],
},
__typename: 'Party',
},
};
@@ -1,32 +1,39 @@
import type { PartyMarketDataQuery } from '@vegaprotocol/deal-ticket';
import { Schema as Types } from '@vegaprotocol/types';
export const generatePartyMarketData = () => {
export const generatePartyMarketData = (): PartyMarketDataQuery => {
return {
party: {
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
accounts: [
{
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '1200000',
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
market: null,
__typename: 'AccountBalance',
},
{
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '0.000000001',
asset: {
__typename: 'Asset',
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tUSD',
name: 'usd',
decimals: 0,
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' },
positionsConnection: { edges: null, __typename: 'PositionConnection' },
__typename: 'Party',
},
};
@@ -0,0 +1,17 @@
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);
};
@@ -0,0 +1,12 @@
export const connectVegaWallet = () => {
const form = 'rest-connector-form';
const walletName = Cypress.env('TRADING_TEST_VEGA_WALLET_NAME');
const walletPassphrase = Cypress.env('TRADING_TEST_VEGA_WALLET_PASSPHRASE');
cy.getByTestId('connect-vega-wallet').click();
cy.getByTestId('connectors-list')
.find('[data-testid="connector-gui"]')
.click();
cy.getByTestId(form).find('#wallet').click().type(walletName);
cy.getByTestId(form).find('#passphrase').click().type(walletPassphrase);
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
};
+1 -1
View File
@@ -19,7 +19,7 @@ NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/stagnet3-network.json"
NX_VEGA_ENV=STAGNET3
NX_VEGA_URL="https://api.n01.stagnet3.vega.xyz/graphql"
NX_VEGA_URL="https://api.stagnet3.vega.xyz/graphql"
NX_VEGA_WALLET_URL=http://localhost:1789
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+1 -1
View File
@@ -1,6 +1,6 @@
# App configuration variables
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
NX_VEGA_ENV=STAGNET3
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
@@ -1,13 +1,17 @@
query PartyBalanceQuery($partyId: ID!) {
party(id: $partyId) {
accounts {
type
balance
asset {
id
symbol
name
decimals
accountsConnection {
edges {
node {
type
balance
asset {
id
symbol
name
decimals
}
}
}
}
}
@@ -8,20 +8,24 @@ export type PartyBalanceQueryQueryVariables = Types.Exact<{
}>;
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accounts?: Array<{ __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } }> | null } | null };
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) {
accounts {
type
balance
asset {
id
symbol
name
decimals
accountsConnection {
edges {
node {
type
balance
asset {
id
symbol
name
decimals
}
}
}
}
}
@@ -1,25 +1,22 @@
import React from 'react';
import { render } from '@testing-library/react';
import type {
AccountFragment,
DealTicketMarketFragment,
} from '@vegaprotocol/deal-ticket';
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
import { DealTicketBalance } from './deal-ticket-balance';
import { AccountType } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import type { MarketDealTicketAsset } from '@vegaprotocol/market-list';
const tDAI: DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'] =
{
__typename: 'Asset',
id: '1',
symbol: 'tDAI',
name: 'TDAI',
decimals: 2,
};
const tDAI: MarketDealTicketAsset = {
__typename: 'Asset',
id: '1',
symbol: 'tDAI',
name: 'TDAI',
decimals: 2,
};
const accounts: AccountFragment[] = [
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
balance: '1000000',
asset: tDAI,
},
@@ -1,14 +1,12 @@
import classNames from 'classnames';
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
import { AccountType } from '@vegaprotocol/types';
import type {
AccountFragment,
DealTicketMarketFragment,
} from '@vegaprotocol/deal-ticket';
import { Schema } from '@vegaprotocol/types';
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
interface DealTicketBalanceProps {
settlementAsset: DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'];
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
accounts: AccountFragment[];
isWalletConnected: boolean;
className?: string;
@@ -25,7 +23,7 @@ export const DealTicketBalance = ({
const settlementAccount = useSettlementAccount(
settlementAssetId,
accounts,
AccountType.ACCOUNT_TYPE_GENERAL
Schema.AccountType.ACCOUNT_TYPE_GENERAL
);
const formattedNumber =
settlementAccount?.balance &&
@@ -1,16 +1,22 @@
import { useParams } from 'react-router-dom';
import compact from 'lodash/compact';
import {
DealTicketManager,
DealTicketContainer as Container,
usePartyBalanceQuery,
} from '@vegaprotocol/deal-ticket';
import { Loader } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { DealTicketSteps } from './deal-ticket-steps';
import { DealTicketBalance } from './deal-ticket-balance';
import Baubles from './baubles-decor';
import ConnectWallet from '../wallet-connector';
import { useMemo } from 'react';
import type {
MarketDataUpdateFieldsFragment,
MarketDealTicket,
} from '@vegaprotocol/market-list';
import { marketDealTicketProvider } from '@vegaprotocol/market-list';
const tempEmptyText = (
<p>{t('Please select a market from the markets page')}</p>
@@ -20,49 +26,64 @@ export const DealTicketContainer = () => {
const { marketId } = useParams<{ marketId: string }>();
const { pubKey } = useVegaWallet();
const { data: partyData, loading } = usePartyBalanceQuery({
const { data: partyData } = usePartyBalanceQuery({
variables: { partyId: pubKey || '' },
skip: !pubKey,
});
const variables = useMemo(
() => ({
marketId: marketId || '',
}),
[marketId]
);
const { data, loading } = useDataProvider<
MarketDealTicket,
MarketDataUpdateFieldsFragment
>({
dataProvider: marketDealTicketProvider,
variables,
skip: !marketId,
});
const accounts = compact(partyData?.party?.accountsConnection?.edges).map(
(e) => e.node
);
const loader = <Loader />;
const container = marketId ? (
<Container marketId={marketId}>
{(data) => {
if (!data.market) {
return null as unknown as JSX.Element;
if (marketId && data) {
const balance = (
<DealTicketBalance
className="mb-4"
settlementAsset={
data.tradableInstrument.instrument.product?.settlementAsset
}
accounts={accounts || []}
isWalletConnected={!!pubKey}
/>
);
const balance = (
<DealTicketBalance
className="mb-4"
settlementAsset={
data.market.tradableInstrument.instrument.product?.settlementAsset
}
accounts={partyData?.party?.accounts || []}
isWalletConnected={!!pubKey}
/>
);
const container = (
<DealTicketManager market={data}>
{loading ? loader : balance}
<DealTicketSteps market={data} />
</DealTicketManager>
);
return (
<DealTicketManager market={data.market}>
{loading ? loader : balance}
<DealTicketSteps market={data.market} />
</DealTicketManager>
);
}}
</Container>
return (
<section className="flex p-4 md:p-6">
<section className="w-full md:w-1/2 md:min-w-[500px]">
{pubKey ? container : <ConnectWallet />}
</section>
<Baubles />
</section>
);
}
return marketId ? (
<Splash>
<p>{t('Could not load market')}</p>
</Splash>
) : (
tempEmptyText
);
return (
<section className="flex p-4 md:p-6">
<section className="w-full md:w-1/2 md:min-w-[500px]">
{pubKey ? container : <ConnectWallet />}
</section>
<Baubles />
</section>
);
};
@@ -11,8 +11,8 @@ import { InputSetter } from '../../components/input-setter';
import { IconNames } from '@blueprintjs/icons';
import {
DataTitle,
EST_SLIPPAGE,
ValueTooltipRow,
EST_SLIPPAGE,
} from '@vegaprotocol/deal-ticket';
interface DealTicketSlippageProps {
@@ -1,19 +1,16 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useForm, Controller } from 'react-hook-form';
import compact from 'lodash/compact';
import { Stepper } from '../stepper';
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
import {
getDefaultOrder,
useOrderCloseOut,
useOrderMargin,
usePartyBalanceQuery,
useMaximumPositionSize,
useCalculateSlippage,
} from '@vegaprotocol/deal-ticket';
import {
getDefaultOrder,
useOrderValidation,
validateSize,
validateAmount,
} from '@vegaprotocol/deal-ticket';
import { InputError } from '@vegaprotocol/ui-toolkit';
import { BigNumber } from 'bignumber.js';
@@ -26,7 +23,6 @@ import {
toDecimal,
removeDecimal,
addDecimalsFormatNumber,
addDecimalsNormalizeNumber,
addDecimal,
formatNumber,
} from '@vegaprotocol/react-helpers';
@@ -43,9 +39,11 @@ import SideSelector, { SIDE_NAMES } from './side-selector';
import ReviewTrade from './review-trade';
import { Schema } from '@vegaprotocol/types';
import { DealTicketSlippage } from './deal-ticket-slippage';
import { useOrderValidation } from './use-order-validation';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
interface DealTicketMarketProps {
market: DealTicketMarketFragment;
market: MarketDealTicket;
}
export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
@@ -72,17 +70,10 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
const step = toDecimal(market.positionDecimalPlaces);
const order = watch();
const { pubKey } = useVegaWallet();
const estMargin = useOrderMargin({
order,
market,
partyId: pubKey || '',
});
const { message: invalidText, isDisabled } = useOrderValidation({
market,
orderType: order.type,
orderTimeInForce: order.timeInForce,
order,
fieldErrors: errors,
estMargin,
});
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
@@ -91,9 +82,12 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
skip: !pubKey,
});
const accounts = compact(partyBalance?.party?.accountsConnection?.edges).map(
(e) => e.node
);
const maxTrade = useMaximumPositionSize({
partyId: pubKey || '',
accounts: partyBalance?.party?.accounts || [],
accounts: accounts,
marketId: market.id,
settlementAssetId:
market.tradableInstrument.instrument.product.settlementAsset.id,
@@ -128,11 +122,18 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
);
return new BigNumber(market?.depth?.lastTrade?.price)
.multipliedBy(multiplier)
.toNumber();
.toString();
}
return null;
return undefined;
}, [market?.depth?.lastTrade?.price, order.side, slippage]);
const estMargin = useOrderMargin({
order,
market,
partyId: pubKey || '',
derivedPrice: price,
});
const formattedPrice =
price && addDecimalsFormatNumber(price, market.decimalPlaces);
@@ -156,7 +157,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
.decimalPlaces(2)
.toString();
return `${addDecimalsNormalizeNumber(
return `${addDecimalsFormatNumber(
estMargin.totalFees,
assetDecimals
)} (${formatNumber(addDecimal(percentage, assetDecimals), 2)}%)`;
@@ -180,7 +181,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
const newVal = new BigNumber(value)
.decimalPlaces(market.positionDecimalPlaces)
.toString();
const isValid = validateSize(step)(newVal);
const isValid = validateAmount(step, 'Size')(newVal);
if (isValid !== 'step') {
setValue('size', newVal);
}
@@ -5,17 +5,17 @@ import {
KeyValueTableRow,
} from '@vegaprotocol/ui-toolkit';
import classNames from 'classnames';
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
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 { MarketExpires } from '@vegaprotocol/market-info';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
import type {
MarketTags,
MarketTagsVariables,
} from './__generated__/MarketTags';
import { Schema } from '@vegaprotocol/types';
import { MarketExpires } from '@vegaprotocol/market-info';
export const MARKET_TAGS_QUERY = gql`
query MarketTags($marketId: ID!) {
@@ -32,7 +32,7 @@ export const MARKET_TAGS_QUERY = gql`
`;
interface Props {
market: DealTicketMarketFragment;
market: MarketDealTicket;
isDisabled: boolean;
transactionStatus?: string;
order: OrderSubmissionBody['orderSubmission'];
@@ -4,41 +4,55 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
import { MockedProvider } from '@apollo/client/testing';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import {
MarketState,
MarketStateMapping,
MarketTradingMode,
Schema as Types,
Schema,
} from '@vegaprotocol/types';
import type { ValidationProps } from './use-order-validation';
import { marketTranslations, useOrderValidation } from './use-order-validation';
import type { DealTicketMarketFragment } from '../deal-ticket/__generated__/DealTicket';
import * as OrderMarginValidation from './use-order-margin-validation';
import { ValidateMargin } from './validate-margin';
import { ERROR_SIZE_DECIMAL } from '../constants';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
import * as DealTicket from '@vegaprotocol/deal-ticket';
jest.mock('@vegaprotocol/wallet');
jest.mock('@vegaprotocol/deal-ticket', () => {
return {
...jest.requireActual('@vegaprotocol/deal-ticket'),
useOrderMarginValidation: jest.fn(),
};
});
const market: DealTicketMarketFragment = {
type SettlementAsset =
MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
const asset: SettlementAsset = {
__typename: 'Asset',
id: 'asset-id',
symbol: 'asset-symbol',
name: 'asset-name',
decimals: 2,
};
const market: MarketDealTicket = {
id: 'market-id',
decimalPlaces: 2,
positionDecimalPlaces: 1,
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
state: MarketState.STATE_ACTIVE,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
id: 'instrument-id',
name: 'instrument-name',
code: 'instriment-code',
metadata: {
tags: [],
},
product: {
__typename: 'Future',
quoteName: 'quote-name',
settlementAsset: {
__typename: 'Asset',
id: 'asset-id',
symbol: 'asset-symbol',
name: 'asset-name',
decimals: 2,
settlementAsset: asset,
dataSourceSpecForTradingTermination: {
id: 'dataSource-id',
},
},
},
@@ -59,6 +73,25 @@ const market: DealTicketMarketFragment = {
liquidityFee: '3',
},
},
data: {
__typename: 'MarketData',
bestBidPrice: '1605489971',
bestOfferPrice: '1606823730',
markPrice: '1606823730',
trigger: Types.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
staticMidPrice: '1606156850',
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
indicativeVolume: '0',
indicativePrice: '0',
bestStaticBidPrice: '1605489971',
bestStaticOfferPrice: '1606823730',
targetStake: '8561302732',
suppliedStake: '727654170336',
auctionStart: null,
auctionEnd: null,
market: { __typename: 'Market', id: 'market-id' },
},
marketTimestamps: {},
};
const defaultWalletContext = {
@@ -71,19 +104,19 @@ const defaultWalletContext = {
connector: null,
};
const order = {
type: Schema.OrderType.TYPE_MARKET,
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
marketId: 'market-id',
side: Schema.Side.SIDE_BUY,
size: '0.1',
};
const defaultOrder = {
market,
market: { ...market },
step: 0.1,
orderType: Schema.OrderType.TYPE_MARKET,
orderTimeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
estMargin: {
margin: '0,000001',
totalFees: '0,000006',
fees: {
makerFee: '0,000003',
liquidityFee: '0,000002',
infrastructureFee: '0,000001',
},
order: {
...order,
},
};
@@ -122,9 +155,11 @@ describe('useOrderValidation', () => {
});
it('Returns empty string when given valid data', () => {
jest
.spyOn(OrderMarginValidation, 'useOrderMarginValidation')
.mockReturnValue(false);
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
balance: '0',
margin: '100',
balanceError: false,
});
const { result } = setup();
expect(result.current).toStrictEqual({
@@ -135,9 +170,11 @@ describe('useOrderValidation', () => {
});
it('Returns an error message when no keypair found', () => {
jest
.spyOn(OrderMarginValidation, 'useOrderMarginValidation')
.mockReturnValue(false);
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
balance: '0',
margin: '100',
balanceError: false,
});
const { result } = setup(defaultOrder, { pubKey: null });
expect(result.current).toStrictEqual({
isDisabled: false,
@@ -148,11 +185,11 @@ describe('useOrderValidation', () => {
it.each`
state
${MarketState.STATE_SETTLED}
${MarketState.STATE_REJECTED}
${MarketState.STATE_TRADING_TERMINATED}
${MarketState.STATE_CLOSED}
${MarketState.STATE_CANCELLED}
${Schema.MarketState.STATE_SETTLED}
${Schema.MarketState.STATE_REJECTED}
${Schema.MarketState.STATE_TRADING_TERMINATED}
${Schema.MarketState.STATE_CLOSED}
${Schema.MarketState.STATE_CANCELLED}
`(
'Returns an error message for market state when not accepting orders',
({ state }) => {
@@ -169,27 +206,33 @@ describe('useOrderValidation', () => {
it.each`
state
${MarketState.STATE_PENDING}
${MarketState.STATE_PROPOSED}
${Schema.MarketState.STATE_PENDING}
${Schema.MarketState.STATE_PROPOSED}
`(
'Returns an error message for market state suspended or pending',
({ state }) => {
jest
.spyOn(OrderMarginValidation, 'useOrderMarginValidation')
.mockReturnValue(false);
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
balance: '0',
margin: '100',
balanceError: false,
// asset,
});
const { result } = setup({
market: {
...defaultOrder.market,
state,
tradingMode: MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
},
order: {
...order,
type: Schema.OrderType.TYPE_LIMIT,
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTT,
},
orderType: Schema.OrderType.TYPE_LIMIT,
orderTimeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTT,
});
expect(result.current).toStrictEqual({
isDisabled: false,
message: `This market is ${MarketStateMapping[
state as MarketState
state as Schema.MarketState
].toLowerCase()} and only accepting liquidity commitment orders`,
section: 'sec-summary',
});
@@ -197,16 +240,19 @@ describe('useOrderValidation', () => {
);
it.each`
tradingMode | errorMessage
${MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
${MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
${MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
tradingMode | errorMessage
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
`(
`Returns an error message when trying to submit a non-limit order for a "$tradingMode" market`,
({ tradingMode, errorMessage }) => {
const { result } = setup({
market: { ...defaultOrder.market, tradingMode },
orderType: Schema.OrderType.TYPE_MARKET,
order: {
...order,
type: Schema.OrderType.TYPE_MARKET,
},
});
expect(result.current.isDisabled).toBeTruthy();
expect(result.current.message).toBe(errorMessage);
@@ -214,23 +260,26 @@ describe('useOrderValidation', () => {
);
it.each`
tradingMode | orderTimeInForce | errorMessage
${MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
${MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
tradingMode | orderTimeInForce | errorMessage
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
`(
`Returns an error message when submitting a limit order with a "$orderTimeInForce" value to a "$tradingMode" market`,
({ tradingMode, orderTimeInForce, errorMessage }) => {
const { result } = setup({
market: { ...defaultOrder.market, tradingMode },
orderType: Schema.OrderType.TYPE_LIMIT,
orderTimeInForce,
order: {
...order,
type: Schema.OrderType.TYPE_LIMIT,
timeInForce: orderTimeInForce,
},
});
expect(result.current).toStrictEqual({
isDisabled: true,
@@ -251,7 +300,10 @@ describe('useOrderValidation', () => {
({ fieldName, errorType, section, errorMessage }) => {
const { result } = setup({
fieldErrors: { [fieldName]: { type: errorType } },
orderType: Schema.OrderType.TYPE_LIMIT,
order: {
...order,
type: Schema.OrderType.TYPE_LIMIT,
},
});
expect(result.current).toStrictEqual({
isDisabled: true,
@@ -264,7 +316,9 @@ describe('useOrderValidation', () => {
it('Returns an error message when the order size incorrectly has decimal values', () => {
const { result } = setup({
market: { ...market, positionDecimalPlaces: 0 },
fieldErrors: { size: { type: `validate`, message: ERROR_SIZE_DECIMAL } },
fieldErrors: {
size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL },
},
});
expect(result.current).toStrictEqual({
isDisabled: true,
@@ -275,7 +329,9 @@ describe('useOrderValidation', () => {
it('Returns an error message when the order size has more decimals than allowed', () => {
const { result } = setup({
fieldErrors: { size: { type: `validate`, message: ERROR_SIZE_DECIMAL } },
fieldErrors: {
size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL },
},
});
expect(result.current).toStrictEqual({
isDisabled: true,
@@ -286,20 +342,26 @@ describe('useOrderValidation', () => {
it('Returns an error message when the estimated margin is higher than collateral', async () => {
const invalidatedMockValue = {
balance: '0000000,1',
margin: '000,1',
id: 'instrument-id',
symbol: 'asset-symbol',
decimals: 5,
balance: '100',
margin: '200',
balanceError: true,
};
jest
.spyOn(OrderMarginValidation, 'useOrderMarginValidation')
.spyOn(DealTicket, 'useOrderMarginValidation')
.mockReturnValue(invalidatedMockValue);
const { result } = setup({});
expect(result.current.isDisabled).toBe(true);
expect(result.current.isDisabled).toBe(false);
const testElement = <ValidateMargin {...invalidatedMockValue} />;
const testElement = (
<DealTicket.MarginWarning
margin={invalidatedMockValue.margin}
balance={invalidatedMockValue.balance}
asset={asset}
/>
);
expect((result.current.message as React.ReactElement)?.props).toEqual(
testElement.props
);
@@ -310,14 +372,14 @@ describe('useOrderValidation', () => {
it.each`
state
${MarketState.STATE_PENDING}
${MarketState.STATE_PROPOSED}
${Schema.MarketState.STATE_PENDING}
${Schema.MarketState.STATE_PROPOSED}
`(
'Returns error when market state is pending and size is wrong',
({ state }) => {
const { result } = setup({
fieldErrors: {
size: { type: `validate`, message: ERROR_SIZE_DECIMAL },
size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL },
},
market: {
...market,
@@ -3,44 +3,40 @@ import type { FieldErrors } from 'react-hook-form';
import { useMemo } from 'react';
import { t, toDecimal } from '@vegaprotocol/react-helpers';
import { useVegaWallet } from '@vegaprotocol/wallet';
import {
AuctionTrigger,
MarketState,
MarketStateMapping,
MarketTradingMode,
Schema,
} from '@vegaprotocol/types';
import { MarketStateMapping, Schema } from '@vegaprotocol/types';
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
import { Tooltip } from '@vegaprotocol/ui-toolkit';
import { MarketDataGrid } from '../trading-mode-tooltip';
import { compileGridData } from '../trading-mode-tooltip/compile-grid-data';
import type { DealTicketMarketFragment } from '../deal-ticket/__generated__/DealTicket';
import { ValidateMargin } from './validate-margin';
import type { OrderMargin } from '../../hooks/use-order-margin';
import { useOrderMarginValidation } from './use-order-margin-validation';
import { ERROR_EXPIRATION_IN_THE_PAST } from './validate-expiration';
import { DEAL_TICKET_SECTION, ERROR_SIZE_DECIMAL } from '../constants';
import {
MarketDataGrid,
compileGridData,
MarginWarning,
isMarketInAuction,
ERROR_SIZE_DECIMAL,
useOrderMarginValidation,
} from '@vegaprotocol/deal-ticket';
import type { MarketDealTicket } from '@vegaprotocol/market-list';
export const isMarketInAuction = (market: DealTicketMarketFragment) => {
return [
MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
].includes(market.tradingMode);
export const DEAL_TICKET_SECTION = {
TYPE: 'sec-type',
SIZE: 'sec-size',
PRICE: 'sec-price',
FORCE: 'sec-force',
EXPIRY: 'sec-expiry',
SUMMARY: 'sec-summary',
};
export const ERROR_EXPIRATION_IN_THE_PAST = 'ERROR_EXPIRATION_IN_THE_PAST';
export type ValidationProps = {
step?: number;
market: DealTicketMarketFragment;
orderType: Schema.OrderType;
orderTimeInForce: Schema.OrderTimeInForce;
market: MarketDealTicket;
order: OrderSubmissionBody['orderSubmission'];
fieldErrors?: FieldErrors<OrderSubmissionBody['orderSubmission']>;
estMargin: OrderMargin | null;
};
export const marketTranslations = (marketState: MarketState) => {
export const marketTranslations = (marketState: Schema.MarketState) => {
switch (marketState) {
case MarketState.STATE_TRADING_TERMINATED:
case Schema.MarketState.STATE_TRADING_TERMINATED:
return t('terminated');
default:
return t(MarketStateMapping[marketState]).toLowerCase();
@@ -54,9 +50,7 @@ export type DealTicketSection =
export const useOrderValidation = ({
market,
fieldErrors,
orderType,
orderTimeInForce,
estMargin,
order,
}: ValidationProps): {
message: ReactNode | string;
isDisabled: boolean;
@@ -64,7 +58,7 @@ export const useOrderValidation = ({
} => {
const { pubKey } = useVegaWallet();
const minSize = toDecimal(market.positionDecimalPlaces);
const isInvalidOrderMargin = useOrderMarginValidation({ market, estMargin });
const isInvalidOrderMargin = useOrderMarginValidation({ market, order });
const fieldErrorChecking = useMemo<{
message: ReactNode | string;
@@ -90,7 +84,7 @@ export const useOrderValidation = ({
if (
fieldErrors?.price?.type === 'required' &&
orderType !== Schema.OrderType.TYPE_MARKET
order.type !== Schema.OrderType.TYPE_MARKET
) {
return {
isDisabled: true,
@@ -101,7 +95,7 @@ export const useOrderValidation = ({
if (
fieldErrors?.price?.type === 'min' &&
orderType !== Schema.OrderType.TYPE_MARKET
order.type !== Schema.OrderType.TYPE_MARKET
) {
return {
isDisabled: true,
@@ -150,7 +144,7 @@ export const useOrderValidation = ({
fieldErrors?.price?.type,
fieldErrors?.expiresAt?.type,
fieldErrors?.expiresAt?.message,
orderType,
order.type,
minSize,
market.positionDecimalPlaces,
]);
@@ -170,11 +164,11 @@ export const useOrderValidation = ({
if (
[
MarketState.STATE_SETTLED,
MarketState.STATE_REJECTED,
MarketState.STATE_TRADING_TERMINATED,
MarketState.STATE_CANCELLED,
MarketState.STATE_CLOSED,
Schema.MarketState.STATE_SETTLED,
Schema.MarketState.STATE_REJECTED,
Schema.MarketState.STATE_TRADING_TERMINATED,
Schema.MarketState.STATE_CANCELLED,
Schema.MarketState.STATE_CLOSED,
].includes(market.state)
) {
return {
@@ -189,9 +183,10 @@ export const useOrderValidation = ({
}
if (
[MarketState.STATE_PROPOSED, MarketState.STATE_PENDING].includes(
market.state
)
[
Schema.MarketState.STATE_PROPOSED,
Schema.MarketState.STATE_PENDING,
].includes(market.state)
) {
if (fieldErrorChecking) {
return fieldErrorChecking;
@@ -208,11 +203,12 @@ export const useOrderValidation = ({
}
if (isMarketInAuction(market)) {
if (orderType === Schema.OrderType.TYPE_MARKET) {
if (order.type === Schema.OrderType.TYPE_MARKET) {
if (
market.tradingMode ===
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger ===
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
) {
return {
isDisabled: true,
@@ -235,8 +231,8 @@ export const useOrderValidation = ({
}
if (
market.tradingMode ===
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === AuctionTrigger.AUCTION_TRIGGER_PRICE
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE
) {
return {
isDisabled: true,
@@ -266,17 +262,18 @@ export const useOrderValidation = ({
};
}
if (
orderType === Schema.OrderType.TYPE_LIMIT &&
order.type === Schema.OrderType.TYPE_LIMIT &&
[
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC,
Schema.OrderTimeInForce.TIME_IN_FORCE_GFN,
].includes(orderTimeInForce)
].includes(order.timeInForce)
) {
if (
market.tradingMode ===
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger ===
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
) {
return {
isDisabled: true,
@@ -301,8 +298,8 @@ export const useOrderValidation = ({
}
if (
market.tradingMode ===
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === AuctionTrigger.AUCTION_TRIGGER_PRICE
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE
) {
return {
isDisabled: true,
@@ -339,19 +336,25 @@ export const useOrderValidation = ({
return fieldErrorChecking;
}
if (isInvalidOrderMargin) {
if (isInvalidOrderMargin.balanceError) {
return {
isDisabled: true,
message: <ValidateMargin {...isInvalidOrderMargin} />,
isDisabled: false,
message: (
<MarginWarning
margin={isInvalidOrderMargin.margin}
balance={isInvalidOrderMargin.balance}
asset={market.tradableInstrument.instrument.product.settlementAsset}
/>
),
section: DEAL_TICKET_SECTION.PRICE,
};
}
if (
[
MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
].includes(market.tradingMode)
) {
return {
@@ -373,8 +376,8 @@ export const useOrderValidation = ({
market,
fieldErrorChecking,
isInvalidOrderMargin,
orderType,
orderTimeInForce,
order.type,
order.timeInForce,
]);
return { message, isDisabled, section };
@@ -1,20 +1,16 @@
import { useState } from 'react';
import { t } from '@vegaprotocol/react-helpers';
import { Button } from '@vegaprotocol/ui-toolkit';
import { DepositDialog } from '@vegaprotocol/deposits';
import { DepositDialog, useDepositDialog } from '@vegaprotocol/deposits';
/**
* Fetches data required for the Deposit page
*/
export const DepositContainer = () => {
const [depositDialog, setDepositDialog] = useState(false);
const openDepositDialog = useDepositDialog((state) => state.open);
return (
<div>
<DepositDialog
depositDialog={depositDialog}
setDepositDialog={setDepositDialog}
/>
<Button size="sm" onClick={() => setDepositDialog(true)}>
<DepositDialog />
<Button size="sm" onClick={() => openDepositDialog()}>
{t('Make deposit')}
</Button>
</div>
@@ -16,7 +16,7 @@ import { useAccountColumnDefinitions } from '.';
const AccountsManager = () => {
const { partyId = '' } = useOutletContext<{ partyId: string }>();
const { isOpen, symbol, setOpen } = useAssetDetailsDialogStore();
const { isOpen, id, setOpen } = useAssetDetailsDialogStore();
const gridRef = useRef<AgGridReact | null>(null);
const dataRef = useRef<AccountFields[] | null>(null);
const variables = useMemo(() => ({ partyId }), [partyId]);
@@ -45,12 +45,13 @@ const AccountsManager = () => {
successCallback(rowsThisBlock, lastRow);
};
const { columnDefs, defaultColDef } = useAccountColumnDefinitions();
console.log(data, loading);
return (
<>
<AsyncRenderer
loading={loading}
error={error}
data={data}
data={data?.length ? data : null}
noDataMessage={NO_DATA_MESSAGE}
>
<ConsoleLiteGrid<AccountFields>
@@ -65,7 +66,7 @@ const AccountsManager = () => {
/>
</AsyncRenderer>
<AssetDetailsDialog
assetSymbol={symbol}
assetId={id}
open={isOpen}
onChange={(open) => setOpen(open)}
/>
@@ -15,14 +15,14 @@ const useAccountColumnDefinitions = () => {
field: 'asset.symbol',
headerClass: 'uppercase justify-start',
cellClass: 'uppercase flex h-full items-center md:pl-4',
cellRenderer: ({ value }: GroupCellRendererParams) =>
cellRenderer: ({ value, data }: GroupCellRendererParams) =>
value && value.length > 0 ? (
<div className="md:pl-4 grid h-full items-center" title={value}>
<div className="truncate min-w-0">
<button
className="hover:underline"
onClick={() => {
open(value);
open(data.asset.id);
}}
>
{value}
@@ -16,7 +16,7 @@ import type {
GroupCellRendererParams,
ColDef,
} from 'ag-grid-community';
import { MarketTradingMode } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
import { Intent, ProgressBarCell } from '@vegaprotocol/ui-toolkit';
@@ -109,7 +109,7 @@ const useColumnDefinitions = () => {
value &&
node?.rowPinned &&
data.marketTradingMode ===
MarketTradingMode.TRADING_MODE_OPENING_AUCTION
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
) {
return addDecimalsFormatNumber(
value.toString(),
@@ -1,21 +1,24 @@
import { t } from '@vegaprotocol/react-helpers';
import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
import { MarketState } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import colors from 'tailwindcss/colors';
import type { Market } from '@vegaprotocol/market-list';
import { IS_MARKET_TRADABLE } from '../../constants';
export const STATES_FILTER = [
{ value: 'all', text: t('All') },
{ value: MarketState.STATE_ACTIVE, text: t('Active') },
{ value: MarketState.STATE_CANCELLED, text: t('Cancelled') },
{ value: MarketState.STATE_CLOSED, text: t('Closed') },
{ value: MarketState.STATE_PENDING, text: t('Pending') },
{ value: MarketState.STATE_PROPOSED, text: t('Proposed') },
{ value: MarketState.STATE_REJECTED, text: t('Rejected') },
{ value: MarketState.STATE_SETTLED, text: t('Settled') },
{ value: MarketState.STATE_SUSPENDED, text: t('Suspended') },
{ value: MarketState.STATE_TRADING_TERMINATED, text: t('TradingTerminated') },
{ value: Schema.MarketState.STATE_ACTIVE, text: t('Active') },
{ value: Schema.MarketState.STATE_CANCELLED, text: t('Cancelled') },
{ value: Schema.MarketState.STATE_CLOSED, text: t('Closed') },
{ value: Schema.MarketState.STATE_PENDING, text: t('Pending') },
{ value: Schema.MarketState.STATE_PROPOSED, text: t('Proposed') },
{ value: Schema.MarketState.STATE_REJECTED, text: t('Rejected') },
{ value: Schema.MarketState.STATE_SETTLED, text: t('Settled') },
{ value: Schema.MarketState.STATE_SUSPENDED, text: t('Suspended') },
{
value: Schema.MarketState.STATE_TRADING_TERMINATED,
text: t('TradingTerminated'),
},
];
export const agGridLightVariables = `
@@ -9,7 +9,7 @@ import {
} from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { BrowserRouter } from 'react-router-dom';
import { MarketState } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import type { Market } from '@vegaprotocol/market-list';
import SimpleMarketList from './simple-market-list';
@@ -26,7 +26,7 @@ jest.mock('./simple-market-percent-change', () => jest.fn());
let marketsMock = [
{
id: 'MARKET_A',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
product: {
@@ -42,7 +42,7 @@ let marketsMock = [
},
{
id: 'MARKET_B',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
product: {
@@ -121,7 +121,7 @@ describe('SimpleMarketList', () => {
expect(mockIsTradable).toHaveBeenCalledWith(
expect.objectContaining({
id: marketsMock[0].id,
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
})
);
expect(mockedNavigate).toHaveBeenCalledWith(
@@ -7,7 +7,6 @@ import {
useYesterday,
} from '@vegaprotocol/react-helpers';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import type { MarketState } from '@vegaprotocol/types';
import useMarketsFilterData from './use-markets-filter-data';
import useColumnDefinitions from './use-column-definitions';
import SimpleMarketToolbar from './simple-market-toolbar';
@@ -31,7 +30,7 @@ const SimpleMarketList = () => {
const { isMobile } = useScreenDimensions();
const navigate = useNavigate();
const params = useParams<RouterParams>();
const statusesRef = useRef<Record<string, MarketState | ''>>({});
const statusesRef = useRef<Record<string, Schema.MarketState | ''>>({});
const gridRef = useRef<AgGridReact | null>(null);
const yesterday = useYesterday();
@@ -53,7 +52,7 @@ const SimpleMarketList = () => {
}, [gridRef]);
useEffect(() => {
const statuses: Record<string, MarketState | ''> = {};
const statuses: Record<string, Schema.MarketState | ''> = {};
data?.forEach((market) => {
statuses[market.id] = market.state || '';
});
@@ -1,13 +1,13 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { MarketState } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import MarketNameRenderer from './simple-market-renderer';
import type { Market } from '@vegaprotocol/market-list';
describe('SimpleMarketRenderer', () => {
const market = {
id: 'MARKET_A',
state: MarketState.STATE_ACTIVE,
state: Schema.MarketState.STATE_ACTIVE,
tradableInstrument: {
instrument: {
code: 'MARKET_A_CODE',
@@ -14,7 +14,7 @@ import {
getAllByText,
} from '@testing-library/react';
import { MockedProvider } from '@apollo/react-testing';
import { MarketState } from '@vegaprotocol/types';
import { 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';
@@ -113,7 +113,7 @@ describe('SimpleMarketToolbar', () => {
await waitFor(() => {
expect(screen.getByTestId('location-display')).toHaveTextContent(
`/markets/${MarketState.STATE_ACTIVE}/Future`
`/markets/${Schema.MarketState.STATE_ACTIVE}/Future`
);
});
@@ -124,7 +124,7 @@ describe('SimpleMarketToolbar', () => {
);
await waitFor(() => {
expect(screen.getByTestId('location-display')).toHaveTextContent(
`/markets/${MarketState.STATE_ACTIVE}/Future/tEURO`
`/markets/${Schema.MarketState.STATE_ACTIVE}/Future/tEURO`
);
});
@@ -139,7 +139,7 @@ describe('SimpleMarketToolbar', () => {
});
await waitFor(() => {
expect(mockedNavigate).toHaveBeenCalledWith(
`/markets/${MarketState.STATE_PENDING}/Future/tEURO`
`/markets/${Schema.MarketState.STATE_PENDING}/Future/tEURO`
);
});
});
@@ -165,7 +165,7 @@ describe('SimpleMarketToolbar', () => {
fireEvent.click(suspended);
expect(mockedNavigate).toHaveBeenCalledWith(
`/markets/${MarketState.STATE_SUSPENDED}/product1/asset1`
`/markets/${Schema.MarketState.STATE_SUSPENDED}/product1/asset1`
);
});
@@ -186,7 +186,7 @@ describe('SimpleMarketToolbar', () => {
fireEvent.click(closed);
expect(mockedNavigate).toHaveBeenCalledWith(
`/markets/${MarketState.STATE_CLOSED}`
`/markets/${Schema.MarketState.STATE_CLOSED}`
);
});
@@ -13,7 +13,7 @@ import {
DropdownMenuItemIndicator,
Icon,
} from '@vegaprotocol/ui-toolkit';
import { MarketState } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import type { Market } from '@vegaprotocol/market-list';
import { HorizontalMenu } from '../horizontal-menu';
import type { HorizontalMenuItem } from '../horizontal-menu';
@@ -36,7 +36,7 @@ const SimpleMarketToolbar = ({ data }: Props) => {
params.asset && params.asset !== 'all' ? `/${params.asset}` : '';
const product = params.product ? `/${params.product}` : '';
const state =
activeState !== MarketState.STATE_ACTIVE || product
activeState !== Schema.MarketState.STATE_ACTIVE || product
? `/${activeState}`
: '';
navigate(`/markets${state}${product}${asset}`);
@@ -45,8 +45,8 @@ const SimpleMarketToolbar = ({ data }: Props) => {
);
const productItems = useMemo(() => {
const currentState = params.state || MarketState.STATE_ACTIVE;
const noStateSkip = currentState !== MarketState.STATE_ACTIVE;
const currentState = params.state || Schema.MarketState.STATE_ACTIVE;
const noStateSkip = currentState !== Schema.MarketState.STATE_ACTIVE;
const items: HorizontalMenuItem[] = [
{
...constants.ALL_PRODUCTS_ITEM,
@@ -83,7 +83,8 @@ const SimpleMarketToolbar = ({ data }: Props) => {
{constants.STATES_FILTER.find(
(state) =>
state.value === params.state ||
(!params.state && state.value === MarketState.STATE_ACTIVE)
(!params.state &&
state.value === Schema.MarketState.STATE_ACTIVE)
)?.text || params.state}
<Icon
name={IconNames.ARROW_DOWN}
@@ -103,7 +104,7 @@ const SimpleMarketToolbar = ({ data }: Props) => {
key={value}
checked={
value === params.state ||
(!params.state && value === MarketState.STATE_ACTIVE)
(!params.state && value === Schema.MarketState.STATE_ACTIVE)
}
onCheckedChange={() => onStateChange(value)}
>
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { MarketState } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import type { MarketWithCandles } from '@vegaprotocol/market-list';
import type { RouterParams } from './simple-market-list';
@@ -30,7 +30,7 @@ const useMarketsFilterData = (
? ''
: params.state
? params.state
: MarketState.STATE_ACTIVE;
: Schema.MarketState.STATE_ACTIVE;
if (state && state !== item.state) {
return false;
}
+12 -12
View File
@@ -1,26 +1,26 @@
import { MarketState } from '@vegaprotocol/types';
import { Schema } from '@vegaprotocol/types';
import { t } from '@vegaprotocol/react-helpers';
import type { Market } from '@vegaprotocol/market-list';
export const DATE_FORMAT = 'dd MMMM yyyy HH:mm';
export const TRADABLE_STATES = {
[MarketState.STATE_ACTIVE]: true,
[Schema.MarketState.STATE_ACTIVE]: true,
};
export const IS_MARKET_TRADABLE = (market: Market) =>
Boolean((market.state ?? '') in TRADABLE_STATES && market?.id);
export const MARKET_STATES_MAP: Record<MarketState | '', string> = {
[MarketState.STATE_ACTIVE]: t('Active'),
[MarketState.STATE_CANCELLED]: t('Cancelled'),
[MarketState.STATE_CLOSED]: t('Closed'),
[MarketState.STATE_PENDING]: t('Pending'),
[MarketState.STATE_PROPOSED]: t('Proposed'),
[MarketState.STATE_REJECTED]: t('Rejected'),
[MarketState.STATE_SETTLED]: t('Settled'),
[MarketState.STATE_SUSPENDED]: t('Suspended'),
[MarketState.STATE_TRADING_TERMINATED]: t('TradingTerminated'),
export const MARKET_STATES_MAP: Record<Schema.MarketState | '', string> = {
[Schema.MarketState.STATE_ACTIVE]: t('Active'),
[Schema.MarketState.STATE_CANCELLED]: t('Cancelled'),
[Schema.MarketState.STATE_CLOSED]: t('Closed'),
[Schema.MarketState.STATE_PENDING]: t('Pending'),
[Schema.MarketState.STATE_PROPOSED]: t('Proposed'),
[Schema.MarketState.STATE_REJECTED]: t('Rejected'),
[Schema.MarketState.STATE_SETTLED]: t('Settled'),
[Schema.MarketState.STATE_SUSPENDED]: t('Suspended'),
[Schema.MarketState.STATE_TRADING_TERMINATED]: t('TradingTerminated'),
'': t('Unknown'),
};
-1
View File
@@ -12,7 +12,6 @@
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
@@ -1,3 +0,0 @@
{
"stepDefinitions": "src/support/step_definitions"
}
+3 -3
View File
@@ -1,8 +1,8 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n00.stagnet3.vega.xyz/websocket
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
NX_VEGA_ENV=STAGNET3
# App flags
+25 -27
View File
@@ -18,22 +18,21 @@ context('Home Page', function () {
const statTitles = {
0: 'Status',
1: 'Height',
2: 'Validating nodes',
3: 'Uptime',
4: 'Total nodes',
5: 'Inactive nodes',
6: 'Total staked',
7: 'Backlog',
8: 'Trades / second',
9: 'Orders / block',
10: 'Orders / second',
11: 'Transactions / block',
12: 'Block time',
13: 'Time',
14: 'App',
15: 'Tendermint',
16: 'Up since',
17: 'Chain ID',
2: 'Uptime',
3: 'Total nodes',
4: 'Inactive nodes',
5: 'Total staked',
6: 'Backlog',
7: 'Trades / second',
8: 'Orders / block',
9: 'Orders / second',
10: 'Transactions / block',
11: 'Block time',
12: 'Time',
13: 'App',
14: 'Tendermint',
15: 'Up since',
16: 'Chain ID',
};
cy.get('[data-testid="stats-title"]')
@@ -41,41 +40,40 @@ context('Home Page', function () {
cy.wrap($list).should('have.text', statTitles[index]);
})
.then(($list) => {
cy.wrap($list).should('have.length', 18);
cy.wrap($list).should('have.length', 17);
});
cy.get(statsValue).eq(0).should('have.text', 'CONNECTED');
cy.get(statsValue).eq(1).should('not.be.empty');
cy.get(statsValue).eq(2).should('have.text', '2');
cy.get(statsValue)
.eq(3)
.eq(2)
.invoke('text')
.should('match', /\d+d \d+h \d+m \d+s/i);
cy.get(statsValue).eq(4).should('have.text', '2');
cy.get(statsValue).eq(5).should('have.text', '0');
cy.get(statsValue).eq(3).should('have.text', '2');
cy.get(statsValue).eq(4).should('have.text', '0');
cy.get(statsValue)
.eq(6)
.eq(5)
.invoke('text')
.should('match', /\d+\.\d\d(?!\d)/i);
cy.get(statsValue).eq(6).should('have.text', '0');
cy.get(statsValue).eq(7).should('have.text', '0');
cy.get(statsValue).eq(8).should('have.text', '0');
cy.get(statsValue).eq(9).should('have.text', '0');
cy.get(statsValue).eq(10).should('have.text', '0');
cy.get(statsValue).eq(10).should('not.be.empty');
cy.get(statsValue).eq(11).should('not.be.empty');
cy.get(statsValue).eq(12).should('not.be.empty');
cy.get(statsValue).eq(13).should('not.be.empty');
if (Cypress.env('NIGHTLY_RUN') != true) {
cy.get(statsValue)
.eq(14)
.eq(13)
.invoke('text')
.should('match', /v\d+\.\d+\.\d+/i);
}
cy.get(statsValue)
.eq(15)
.eq(14)
.invoke('text')
.should('match', /\d+\.\d+\.\d+/i);
cy.get(statsValue).eq(15).should('not.be.empty');
cy.get(statsValue).eq(16).should('not.be.empty');
cy.get(statsValue).eq(17).should('not.be.empty');
});
it('Block height should be updating', function () {
@@ -148,7 +148,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
const parameterName = network_parameter[0];
const parameterValue = network_parameter[1];
if (this.networkParameterFormat.fiveDecimal.includes(parameterName)) {
cy.convert_number_to_four_decimal(parameterValue)
cy.convert_number_to_max_four_decimal(parameterValue)
.add_commas_to_number_if_large_enough()
.then((parameterValueFormatted) => {
cy.get(tableRows)
@@ -179,7 +179,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
if (
this.networkParameterFormat.eighteenDecimal.includes(parameterName)
) {
cy.convert_number_to_eighteen_decimal(parameterValue)
cy.convert_number_to_max_eighteen_decimal(parameterValue)
.add_commas_to_number_if_large_enough()
.then((parameterValueFormatted) => {
cy.get(tableRows)
@@ -212,7 +212,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
const jsonFields = '.hljs';
const sideMenuBackground = '.absolute';
// Engage dark mode if not allready set
// Engage dark mode if not already set
cy.get(sideMenuBackground)
.should('have.css', 'background-color')
.then((background_color) => {
@@ -16,7 +16,6 @@ const assetsInTest = Object.keys(assetData);
context('Parties page', { tags: '@regression' }, function () {
before('send-faucet assets to connected vega wallet', function () {
cy.vega_wallet_import();
assetsInTest.forEach((asset) => {
cy.vega_wallet_receive_fauceted_asset(
assetData[asset].name,
@@ -203,15 +202,6 @@ context('Parties page', { tags: '@regression' }, function () {
.and('include', darkThemeSideMenuBackgroundColor);
});
after(
'teardown environment to prevent test data bleeding into other tests',
function () {
if (Cypress.env('TEARDOWN_NETWORK_AFTER_FLOWS')) {
cy.restart_vegacapsule_network();
}
}
);
Cypress.Commands.add('get_asset_decimals', (assetID) => {
cy.get_asset_information().then((assetsInfo) => {
const assetDecimals = assetsInfo[assetData[assetID].name].decimals;
@@ -87,7 +87,10 @@ context('Validator page', { tags: '@smoke' }, function () {
});
});
it('should be able to see relevant node information in vega data section', function () {
// Test disabled 2022/11/15 during the 0.62.1 upgrade. The JSON structure changed, and
// this test failed. Rather than fix it, it will be replaced when the validator view displays
// something useful rather than just dumping out the JSON.
xit('should be able to see relevant node information in vega data section', function () {
cy.get(vegaDataHeader)
.contains('Vega data')
.next()
@@ -97,7 +100,7 @@ context('Validator page', { tags: '@smoke' }, function () {
.convert_string_json_to_js_object()
.then((nodesInJson) => {
this.nodes.forEach((node, index) => {
const nodeInJson = nodesInJson.nodes[index];
const nodeInJson = nodesInJson.edges[index].node;
// Vegacapsule shows no info or null for following fields:
// name, infoURL, avatarUrl, location, epoch data
@@ -68,12 +68,19 @@ Cypress.Commands.add(
}
);
Cypress.Commands.add('convert_number_to_eighteen_decimal', (number) => {
// this will take a number like this : 700000000000000000000
// and convert it to a number like this: 700.000000000000000000
return BigNumber((number / 1000000000000000000).toString()).toFixed(18);
Cypress.Commands.add('convert_number_to_max_eighteen_decimal', (number) => {
// this will take a number like this : 700000000000000000001
// and convert it to a number like this: 700.000000000000000001
const value = BigNumber(number / 1000000000000000000).toString();
return parseFloat(value).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 18,
});
});
Cypress.Commands.add('convert_number_to_four_decimal', (number) => {
return parseFloat(number).toFixed(4);
Cypress.Commands.add('convert_number_to_max_four_decimal', (number) => {
return parseFloat(number).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 4,
});
});
+5 -3
View File
@@ -1,12 +1,14 @@
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
NX_TENDERMINT_URL=https://tm.be.stagnet3.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet3.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=STAGNET3
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_BLOCK_EXPLORER=
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
# App flags
NX_EXPLORER_ASSETS=1
+1 -1
View File
@@ -2,10 +2,10 @@
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=CUSTOM
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
# App flags
NX_EXPLORER_ASSETS=1
+1 -1
View File
@@ -3,8 +3,8 @@ NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-exp
NX_TENDERMINT_URL=https://n04.d.vega.xyz/tm
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=DEVNET
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+2 -2
View File
@@ -1,10 +1,10 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://be.explorer.vega.xyz
NX_TENDERMINT_URL=https://be.explorer.vega.xyz/websocket
NX_TENDERMINT_WEBSOCKET_URL=wss://be.explorer.vega.xyz
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
NX_VEGA_URL=https://api.vega.xyz/query
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=MAINNET
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest/
NX_ETHERSCAN_URL=https://etherscan.io
+1 -1
View File
@@ -1,5 +1,4 @@
# App configuration variables
NX_VEGA_URL=https://api.sandbox.vega.xyz/graphql
NX_VEGA_ENV=SANDBOX
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
NX_VEGA_EXPLORER_URL=https://sandbox.explorer.vega.xyz
@@ -9,3 +8,4 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_TENDERMINT_URL=https://tm.n01.sandbox.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.sandbox.vega.xyz/websocket
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+3 -3
View File
@@ -6,8 +6,8 @@ NX_VEGA_ENV=STAGNET1
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
NX_VEGA_WALLET_URL=http://localhost:1789
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
NX_TENDERMINT_URL=https://tm.be.stagnet1.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet1.vega.xyz/websocket
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+3 -5
View File
@@ -1,10 +1,8 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://n01.stagnet3.vega.xyz/tm
NX_TENDERMINT_WEBSOCKET_URL=wss://n01.stagnet3.vega.xyz/tm/websocket
NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.stagnet3.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=STAGNET3
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_BLOCK_EXPLORER=https://blockexplorer.n01.stagnet3.vega.xyz/rest
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
+5 -3
View File
@@ -1,11 +1,13 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://tm.n07.testnet.vega.xyz
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.testnet.vega.xyz/websocket
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n07.testnet.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=TESTNET
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_URL=https://api.n09.testnet.vega.xyz/graphql
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_NETWORKS={}
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+1 -1
View File
@@ -2,7 +2,7 @@
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=http://localhost:26607/
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26607/websocket
NX_VEGA_URL=http://localhost:3003/query
NX_VEGA_ENV=CUSTOM
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_BLOCK_EXPLORER=
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+15 -16
View File
@@ -45,22 +45,21 @@ yarn nx run explorer:serve --env={env} # e.g. stagnet3
There are a few different configuration options offered for this app:
| **Flag** | **Purpose** |
| -------------------------------- | ---------------------------------------------------------------------------------------------------- | --- |
| `NX_CHAIN_EXPLORER_URL` | The URL of the chain explorer service for decoding transactions |
| `NX_TENDERMINT_URL` | The Tendermint REST URL for the Vega consesus engine |
| `NX_TENDERMINT_WEBSOCKET_URL` | The Tendermint Websocket URL for the Vega consensus engine |
| `NX_VEGA_URL` | The GraphQl query endpoint of a [Vega data node](https://github.com/vegaprotocol/networks#data-node) |
| `NX_VEGA_ENV` | The name of the currently connected vega environment | |
| `NX_EXPLORER_ASSETS` | Enable the assets page for the explorer |
| `NX_EXPLORER_GENESIS` | Enable the genesis page for the explorer |
| `NX_EXPLORER_GOVERNANCE` | Enable the governance page for the explorer |
| `NX_EXPLORER_MARKETS` | Enable the markets page for the explorer |
| `NX_EXPLORER_ORACLES` | Enable the oracles page for the explorer |
| `NX_EXPLORER_TXS_LIST` | Enable the transactions list page for the explorer |
| `NX_EXPLORER_NETWORK_PARAMETERS` | Enable the network parameters page for the explorer |
| `NX_EXPLORER_PARTIES` | Enable the parties page for the explorer |
| `NX_EXPLORER_VALIDATORS` | Enable the validators page for the explorer |
| **Flag** | **Purpose** |
| -------------------------------- | --------------------------------------------------------------- | --- |
| `NX_CHAIN_EXPLORER_URL` | The URL of the chain explorer service for decoding transactions |
| `NX_TENDERMINT_URL` | The Tendermint REST URL for the Vega consesus engine |
| `NX_TENDERMINT_WEBSOCKET_URL` | The Tendermint Websocket URL for the Vega consensus engine |
| `NX_VEGA_ENV` | The name of the currently connected vega environment | |
| `NX_EXPLORER_ASSETS` | Enable the assets page for the explorer |
| `NX_EXPLORER_GENESIS` | Enable the genesis page for the explorer |
| `NX_EXPLORER_GOVERNANCE` | Enable the governance page for the explorer |
| `NX_EXPLORER_MARKETS` | Enable the markets page for the explorer |
| `NX_EXPLORER_ORACLES` | Enable the oracles page for the explorer |
| `NX_EXPLORER_TXS_LIST` | Enable the transactions list page for the explorer |
| `NX_EXPLORER_NETWORK_PARAMETERS` | Enable the network parameters page for the explorer |
| `NX_EXPLORER_PARTIES` | Enable the parties page for the explorer |
| `NX_EXPLORER_VALIDATORS` | Enable the validators page for the explorer |
## Testing
+8
View File
@@ -66,6 +66,14 @@
"passWithNoTests": true
}
},
"generate-types": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.62.1/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
]
}
},
"build-netlify": {
"executor": "@nrwl/workspace:run-commands",
"options": {
+24 -18
View File
@@ -1,3 +1,4 @@
import classnames from 'classnames';
import { useState, useEffect } from 'react';
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';
@@ -44,28 +45,33 @@ function App() {
},
};
const layoutClasses = classnames(
'grid grid-rows-[auto_1fr_auto] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)_auto] md:grid-cols-[300px_1fr]',
'min-h-[100vh] mx-auto my-0',
'border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r',
'bg-white dark:bg-black',
'antialiased text-black dark:text-white',
{
'h-[100vh] min-h-auto overflow-hidden': menuOpen,
}
);
return (
<ThemeContext.Provider value={theme}>
<TendermintWebsocketProvider>
<NetworkLoader cache={cacheConfig}>
<div
className={`${
menuOpen && 'h-[100vh] overflow-hidden'
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
>
<div className="grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
<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>
<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>
@@ -0,0 +1,8 @@
query ExplorerAsset($id: ID!) {
asset(id: $id) {
id
name
status
decimals
}
}
@@ -0,0 +1,51 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerAssetQueryVariables = Types.Exact<{
id: Types.Scalars['ID'];
}>;
export type ExplorerAssetQuery = { __typename?: 'Query', asset?: { __typename?: 'Asset', id: string, name: string, status: Types.AssetStatus, decimals: number } | null };
export const ExplorerAssetDocument = gql`
query ExplorerAsset($id: ID!) {
asset(id: $id) {
id
name
status
decimals
}
}
`;
/**
* __useExplorerAssetQuery__
*
* To run a query within a React component, call `useExplorerAssetQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerAssetQuery` 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 } = useExplorerAssetQuery({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useExplorerAssetQuery(baseOptions: Apollo.QueryHookOptions<ExplorerAssetQuery, ExplorerAssetQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerAssetQuery, ExplorerAssetQueryVariables>(ExplorerAssetDocument, options);
}
export function useExplorerAssetLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerAssetQuery, ExplorerAssetQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerAssetQuery, ExplorerAssetQueryVariables>(ExplorerAssetDocument, options);
}
export type ExplorerAssetQueryHookResult = ReturnType<typeof useExplorerAssetQuery>;
export type ExplorerAssetLazyQueryHookResult = ReturnType<typeof useExplorerAssetLazyQuery>;
export type ExplorerAssetQueryResult = Apollo.QueryResult<ExplorerAssetQuery, ExplorerAssetQueryVariables>;
@@ -0,0 +1,63 @@
import { MemoryRouter } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing';
import { render } from '@testing-library/react';
import AssetLink from './asset-link';
import { ExplorerAssetDocument } from './__generated__/Asset';
function renderComponent(id: string, mock: MockedResponse[]) {
return (
<MockedProvider mocks={mock}>
<MemoryRouter>
<AssetLink id={id} />
</MemoryRouter>
</MockedProvider>
);
}
describe('Asset link component', () => {
it('Renders the ID at first', () => {
const res = render(renderComponent('123', []));
expect(res.getByText('123')).toBeInTheDocument();
});
it('Renders the asset name when the query returns a result', async () => {
const mock = {
request: {
query: ExplorerAssetDocument,
variables: {
id: '123',
},
},
result: {
data: {
asset: {
id: '123',
name: 'test-label',
status: 'irrelevant-test-data',
decimals: 18,
},
},
},
};
const res = render(renderComponent('123', [mock]));
expect(res.getByText('123')).toBeInTheDocument();
expect(await res.findByText('test-label')).toBeInTheDocument();
});
it('Leaves the asset id when the asset is not found', async () => {
const mock = {
request: {
query: ExplorerAssetDocument,
variables: {
id: '123',
},
},
error: new Error('No such asset'),
};
const res = render(renderComponent('123', [mock]));
expect(await res.findByText('123')).toBeInTheDocument();
});
});
@@ -0,0 +1,35 @@
import React from 'react';
import { Routes } from '../../../routes/route-names';
import { useExplorerAssetQuery } from './__generated__/Asset';
import { Link } from 'react-router-dom';
import type { ComponentProps } from 'react';
export type AssetLinkProps = Partial<ComponentProps<typeof Link>> & {
id: string;
};
/**
* Given an asset ID, it will fetch the asset name and show that,
* with a link to the assets list. If the name does not come back
* it will use the ID instead.
*/
const AssetLink = ({ id, ...props }: AssetLinkProps) => {
const { data } = useExplorerAssetQuery({
variables: { id },
});
let label: string = id;
if (data?.asset?.name) {
label = data.asset.name;
}
return (
<Link className="underline" {...props} to={`/${Routes.ASSETS}#${id}`}>
{label}
</Link>
);
};
export default AssetLink;
@@ -0,0 +1,19 @@
import React from 'react';
import { Routes } from '../../../routes/route-names';
import { Link } from 'react-router-dom';
import type { ComponentProps } from 'react';
export type BlockLinkProps = Partial<ComponentProps<typeof Link>> & {
height: string;
};
const BlockLink = ({ height, ...props }: BlockLinkProps) => {
return (
<Link className="underline" {...props} to={`/${Routes.BLOCKS}/${height}`}>
{height}
</Link>
);
};
export default BlockLink;
@@ -0,0 +1,33 @@
import React from 'react';
import { DATA_SOURCES } from '../../../config';
export enum EthExplorerLinkTypes {
block = 'block',
address = 'address',
tx = 'tx',
}
export type EthExplorerLinkProps = Partial<typeof HTMLAnchorElement> & {
id: string;
type: EthExplorerLinkTypes;
};
export const EthExplorerLink = ({
id,
type,
...props
}: EthExplorerLinkProps) => {
const link = `${DATA_SOURCES.ethExplorerUrl}/${type}/${id}`;
return (
<a
className="underline external"
target="_blank"
rel="noopener noreferrer"
{...props}
href={link}
>
{id}
</a>
);
};
@@ -0,0 +1,5 @@
export { default as BlockLink } from './block-link/block-link';
export { default as PartyLink } from './party-link/party-link';
export { default as NodeLink } from './node-link/node-link';
export { default as MarketLink } from './market-link/market-link';
export { default as AssetLink } from './asset-link/asset-link';
@@ -0,0 +1,11 @@
query ExplorerMarket($id: ID!) {
market(id: $id) {
id
tradableInstrument {
instrument {
name
}
}
state
}
}
@@ -0,0 +1,54 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerMarketQueryVariables = Types.Exact<{
id: Types.Scalars['ID'];
}>;
export type ExplorerMarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string } } } | null };
export const ExplorerMarketDocument = gql`
query ExplorerMarket($id: ID!) {
market(id: $id) {
id
tradableInstrument {
instrument {
name
}
}
state
}
}
`;
/**
* __useExplorerMarketQuery__
*
* To run a query within a React component, call `useExplorerMarketQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerMarketQuery` 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 } = useExplorerMarketQuery({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useExplorerMarketQuery(baseOptions: Apollo.QueryHookOptions<ExplorerMarketQuery, ExplorerMarketQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerMarketQuery, ExplorerMarketQueryVariables>(ExplorerMarketDocument, options);
}
export function useExplorerMarketLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerMarketQuery, ExplorerMarketQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerMarketQuery, ExplorerMarketQueryVariables>(ExplorerMarketDocument, options);
}
export type ExplorerMarketQueryHookResult = ReturnType<typeof useExplorerMarketQuery>;
export type ExplorerMarketLazyQueryHookResult = ReturnType<typeof useExplorerMarketLazyQuery>;
export type ExplorerMarketQueryResult = Apollo.QueryResult<ExplorerMarketQuery, ExplorerMarketQueryVariables>;
@@ -0,0 +1,66 @@
import { MemoryRouter } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing';
import { render } from '@testing-library/react';
import MarketLink from './market-link';
import { ExplorerMarketDocument } from './__generated__/Market';
function renderComponent(id: string, mock: MockedResponse[]) {
return (
<MockedProvider mocks={mock}>
<MemoryRouter>
<MarketLink id={id} />
</MemoryRouter>
</MockedProvider>
);
}
describe('Market link component', () => {
it('Renders the ID at first', () => {
const res = render(renderComponent('123', []));
expect(res.getByText('123')).toBeInTheDocument();
});
it('Renders the market name when the query returns a result', async () => {
const mock = {
request: {
query: ExplorerMarketDocument,
variables: {
id: '123',
},
},
result: {
data: {
market: {
id: '123',
state: 'irrelevant-test-data',
tradableInstrument: {
instrument: {
name: 'test-label',
},
},
},
},
},
};
const res = render(renderComponent('123', [mock]));
expect(res.getByText('123')).toBeInTheDocument();
expect(await res.findByText('test-label')).toBeInTheDocument();
});
it('Leaves the market id when the market is not found', async () => {
const mock = {
request: {
query: ExplorerMarketDocument,
variables: {
id: '123',
},
},
error: new Error('No such market'),
};
const res = render(renderComponent('123', [mock]));
expect(await res.findByText('123')).toBeInTheDocument();
});
});
@@ -0,0 +1,35 @@
import React from 'react';
import { Routes } from '../../../routes/route-names';
import { useExplorerMarketQuery } from './__generated__/Market';
import { Link } from 'react-router-dom';
import type { ComponentProps } from 'react';
export type MarketLinkProps = Partial<ComponentProps<typeof Link>> & {
id: string;
};
/**
* Given a market ID, it will fetch the market name and show that,
* with a link to the markets list. If the name does not come back
* it will use the ID instead
*/
const MarketLink = ({ id, ...props }: MarketLinkProps) => {
const { data } = useExplorerMarketQuery({
variables: { id },
});
let label = id;
if (data?.market?.tradableInstrument.instrument.name) {
label = data.market.tradableInstrument.instrument.name;
}
return (
<Link className="underline" {...props} to={`/${Routes.MARKETS}#${id}`}>
{label}
</Link>
);
};
export default MarketLink;
@@ -0,0 +1,7 @@
query ExplorerNode($id: ID!) {
node(id: $id) {
id
name
status
}
}
@@ -0,0 +1,50 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerNodeQueryVariables = Types.Exact<{
id: Types.Scalars['ID'];
}>;
export type ExplorerNodeQuery = { __typename?: 'Query', node?: { __typename?: 'Node', id: string, name: string, status: Types.NodeStatus } | null };
export const ExplorerNodeDocument = gql`
query ExplorerNode($id: ID!) {
node(id: $id) {
id
name
status
}
}
`;
/**
* __useExplorerNodeQuery__
*
* To run a query within a React component, call `useExplorerNodeQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerNodeQuery` 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 } = useExplorerNodeQuery({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useExplorerNodeQuery(baseOptions: Apollo.QueryHookOptions<ExplorerNodeQuery, ExplorerNodeQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerNodeQuery, ExplorerNodeQueryVariables>(ExplorerNodeDocument, options);
}
export function useExplorerNodeLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerNodeQuery, ExplorerNodeQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerNodeQuery, ExplorerNodeQueryVariables>(ExplorerNodeDocument, options);
}
export type ExplorerNodeQueryHookResult = ReturnType<typeof useExplorerNodeQuery>;
export type ExplorerNodeLazyQueryHookResult = ReturnType<typeof useExplorerNodeLazyQuery>;
export type ExplorerNodeQueryResult = Apollo.QueryResult<ExplorerNodeQuery, ExplorerNodeQueryVariables>;
@@ -0,0 +1,62 @@
import { MemoryRouter } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing';
import { render } from '@testing-library/react';
import NodeLink from './node-link';
import { ExplorerNodeDocument } from './__generated__/Node';
function renderComponent(id: string, mock: MockedResponse[]) {
return (
<MockedProvider mocks={mock}>
<MemoryRouter>
<NodeLink id={id} />
</MemoryRouter>
</MockedProvider>
);
}
describe('Node link component', () => {
it('Renders the ID at first', () => {
const res = render(renderComponent('123', []));
expect(res.getByText('123')).toBeInTheDocument();
});
it('Renders the node name when the query returns a result', async () => {
const mock = {
request: {
query: ExplorerNodeDocument,
variables: {
id: '123',
},
},
result: {
data: {
node: {
id: '123',
status: 'irrelevant-test-data',
name: 'test-label',
},
},
},
};
const res = render(renderComponent('123', [mock]));
expect(res.getByText('123')).toBeInTheDocument();
expect(await res.findByText('test-label')).toBeInTheDocument();
});
it('Leaves the node id when the node is not found', async () => {
const mock = {
request: {
query: ExplorerNodeDocument,
variables: {
id: '123',
},
},
error: new Error('No such node'),
};
const res = render(renderComponent('123', [mock]));
expect(await res.findByText('123')).toBeInTheDocument();
});
});
@@ -0,0 +1,30 @@
import React from 'react';
import { Routes } from '../../../routes/route-names';
import { useExplorerNodeQuery } from './__generated__/Node';
import { Link } from 'react-router-dom';
import type { ComponentProps } from 'react';
export type NodeLinkProps = Partial<ComponentProps<typeof Link>> & {
id: string;
};
const NodeLink = ({ id, ...props }: NodeLinkProps) => {
const { data } = useExplorerNodeQuery({
variables: { id },
});
let label: string = id;
if (data?.node?.name) {
label = data.node.name;
}
return (
<Link className="underline" {...props} to={`/${Routes.VALIDATORS}#${id}`}>
{label}
</Link>
);
};
export default NodeLink;
@@ -0,0 +1,19 @@
import React from 'react';
import { Routes } from '../../../routes/route-names';
import { Link } from 'react-router-dom';
import type { ComponentProps } from 'react';
export type PartyLinkProps = Partial<ComponentProps<typeof Link>> & {
id: string;
};
const PartyLink = ({ id, ...props }: PartyLinkProps) => {
return (
<Link className="underline" {...props} to={`/${Routes.PARTIES}/${id}`}>
{id}
</Link>
);
};
export default PartyLink;
@@ -2,7 +2,7 @@ import { AppRouter } from '../../routes';
export const Main = () => {
return (
<main className="p-4 overflow-hidden">
<main className="p-4 overflow-scroll">
<AppRouter />
</main>
);
@@ -41,10 +41,10 @@ describe('NestedDataList', () => {
const parent = getAllByRole('listitem', { name: 'Validator Heartbeat' });
const nestedContainer = parent[0].querySelector('[aria-hidden]');
const expandBtn = parent[0].querySelector('button');
expect(nestedContainer).toHaveAttribute('aria-hidden', 'true');
expect(nestedContainer).toHaveAttribute('aria-hidden', 'false');
await user.click(expandBtn as HTMLButtonElement);
await waitFor(() => nestedContainer);
expect(nestedContainer).toHaveAttribute('aria-hidden', 'false');
expect(nestedContainer).toHaveAttribute('aria-hidden', 'true');
});
it('add border to the title of the parent', () => {
@@ -55,7 +55,7 @@ const NestedDataListItem = ({
value,
index,
}: NestedDataListItemProps) => {
const [isCollapsed, setCollapsed] = useState(true);
const [isCollapsed, setCollapsed] = useState(false);
const toggleVisible = useCallback(
(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.stopPropagation();
@@ -0,0 +1,14 @@
import { t } from '@vegaprotocol/react-helpers';
interface TimeProps {
date: string | null | undefined;
}
export const Time = ({ date }: TimeProps) => {
if (!date) {
return <>{t('Date unknown')}</>;
}
const timeFormatted = new Date(date).toLocaleString();
return <span>{timeFormatted}</span>;
};
@@ -1,35 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: TxsStats
// ====================================================
export interface TxsStats_statistics {
__typename: "Statistics";
/**
* Average number of orders added per blocks
*/
averageOrdersPerBlock: string;
/**
* Number of orders per seconds
*/
ordersPerSecond: string;
/**
* Number of transaction processed per block
*/
txPerBlock: string;
/**
* Number of the trades per seconds
*/
tradesPerSecond: string;
}
export interface TxsStats {
/**
* Get statistics about the Vega node
*/
statistics: TxsStats_statistics;
}
@@ -0,0 +1,54 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerStatsFieldsFragment = { __typename?: 'Statistics', averageOrdersPerBlock: string, ordersPerSecond: string, txPerBlock: string, tradesPerSecond: string };
export type ExplorerStatsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ExplorerStatsQuery = { __typename?: 'Query', statistics: { __typename?: 'Statistics', averageOrdersPerBlock: string, ordersPerSecond: string, txPerBlock: string, tradesPerSecond: string } };
export const ExplorerStatsFieldsFragmentDoc = gql`
fragment ExplorerStatsFields on Statistics {
averageOrdersPerBlock
ordersPerSecond
txPerBlock
tradesPerSecond
}
`;
export const ExplorerStatsDocument = gql`
query ExplorerStats {
statistics {
...ExplorerStatsFields
}
}
${ExplorerStatsFieldsFragmentDoc}`;
/**
* __useExplorerStatsQuery__
*
* To run a query within a React component, call `useExplorerStatsQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerStatsQuery` 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 } = useExplorerStatsQuery({
* variables: {
* },
* });
*/
export function useExplorerStatsQuery(baseOptions?: Apollo.QueryHookOptions<ExplorerStatsQuery, ExplorerStatsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerStatsQuery, ExplorerStatsQueryVariables>(ExplorerStatsDocument, options);
}
export function useExplorerStatsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerStatsQuery, ExplorerStatsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerStatsQuery, ExplorerStatsQueryVariables>(ExplorerStatsDocument, options);
}
export type ExplorerStatsQueryHookResult = ReturnType<typeof useExplorerStatsQuery>;
export type ExplorerStatsLazyQueryHookResult = ReturnType<typeof useExplorerStatsLazyQuery>;
export type ExplorerStatsQueryResult = Apollo.QueryResult<ExplorerStatsQuery, ExplorerStatsQueryVariables>;
@@ -0,0 +1,75 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerNodeVoteQueryVariables = Types.Exact<{
id: Types.Scalars['ID'];
}>;
export type ExplorerNodeVoteQuery = { __typename?: 'Query', withdrawal?: { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, createdTimestamp: string, withdrawnTimestamp?: string | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string } } | null, deposit?: { __typename?: 'Deposit', id: string, status: Types.DepositStatus, createdTimestamp: string, creditedTimestamp?: string | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string } } | null };
export const ExplorerNodeVoteDocument = gql`
query ExplorerNodeVote($id: ID!) {
withdrawal(id: $id) {
id
status
createdTimestamp
withdrawnTimestamp
txHash
asset {
id
name
decimals
}
party {
id
}
}
deposit(id: $id) {
id
status
createdTimestamp
creditedTimestamp
txHash
asset {
id
name
decimals
}
party {
id
}
}
}
`;
/**
* __useExplorerNodeVoteQuery__
*
* To run a query within a React component, call `useExplorerNodeVoteQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerNodeVoteQuery` 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 } = useExplorerNodeVoteQuery({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useExplorerNodeVoteQuery(baseOptions: Apollo.QueryHookOptions<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>(ExplorerNodeVoteDocument, options);
}
export function useExplorerNodeVoteLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>(ExplorerNodeVoteDocument, options);
}
export type ExplorerNodeVoteQueryHookResult = ReturnType<typeof useExplorerNodeVoteQuery>;
export type ExplorerNodeVoteLazyQueryHookResult = ReturnType<typeof useExplorerNodeVoteLazyQuery>;
export type ExplorerNodeVoteQueryResult = Apollo.QueryResult<ExplorerNodeVoteQuery, ExplorerNodeVoteQueryVariables>;
@@ -0,0 +1,139 @@
import { TxDetailsChainMultisigThreshold } from './tx-multisig-threshold';
import { TxDetailsChainMultisigSigner } from './tx-multisig-signer';
import { TxDetailsChainEventBuiltinDeposit } from './tx-builtin-deposit';
import { TxDetailsChainEventStakeDeposit } from './tx-stake-deposit';
import { TxDetailsChainEventStakeRemove } from './tx-stake-remove';
import { TxDetailsChainEventStakeTotalSupply } from './tx-stake-totalsupply';
import { TxDetailsChainEventBuiltinWithdrawal } from './tx-builtin-withdrawal';
import { TxDetailsChainEventErc20AssetList } from './tx-erc20-asset-list';
import { TxDetailsChainEventErc20AssetLimitsUpdated } from './tx-erc20-asset-limits-updated';
import { TxDetailsChainEventErc20BridgePause } from './tx-erc20-bridge-pause';
import { TxDetailsChainEventDeposit } from './tx-erc20-deposit';
import isUndefined from 'lodash/isUndefined';
import type { BlockExplorerTransactionResult } from '../../../../routes/types/block-explorer-response';
interface ChainEventProps {
txData: BlockExplorerTransactionResult | undefined;
}
/**
* Inspects the chain event to determine which details view to show. The list of types
* comes from the Swagger document that Block Explorer provides, which can be viewed at
* https://docs.vega.xyz/testnet/api/rest/explorer/block-explorer-list-transactions
*
* This component should have one entry per chain event type, however if there isn't
* a bespoke view for an event the tx-details-shared will still render some basic
* overview and the transaction viewer will still let people view the raw TX.
*
* Most chain events simply render more table rows for the header table
*
* @returns React.JSXElement
*/
export const ChainEvent = ({ txData }: ChainEventProps) => {
const e = txData?.command.chainEvent;
if (!e) {
return null;
}
// Builtin Asset events
if (e.builtin) {
if (e.builtin.deposit) {
return <TxDetailsChainEventBuiltinDeposit deposit={e.builtin.deposit} />;
}
if (e.builtin?.withdrawal) {
return (
<TxDetailsChainEventBuiltinWithdrawal
withdrawal={e.builtin?.withdrawal}
/>
);
}
}
// ERC20 asset events
if (e.erc20) {
if (e.erc20.deposit) {
return <TxDetailsChainEventDeposit deposit={e.erc20.deposit} />;
}
if (e.erc20.withdrawal) {
return (
<TxDetailsChainEventBuiltinWithdrawal withdrawal={e.erc20.withdrawal} />
);
}
if (e.erc20.assetList) {
return (
<TxDetailsChainEventErc20AssetList assetList={e.erc20.assetList} />
);
}
if (e.erc20.assetLimitsUpdated) {
return (
<TxDetailsChainEventErc20AssetLimitsUpdated
assetLimitsUpdated={e.erc20.assetLimitsUpdated}
/>
);
}
const bridgeStopped = e.erc20.bridgeStopped;
const bridgeResumed = e.erc20.bridgeResumed;
if (!isUndefined(bridgeStopped) || !isUndefined(bridgeResumed)) {
const isPaused = bridgeStopped === false || bridgeResumed === true;
return <TxDetailsChainEventErc20BridgePause isPaused={isPaused} />;
}
}
// ERC20 multisig events
if (e.erc20Multisig) {
if (e.erc20Multisig.thresholdSet) {
return (
<TxDetailsChainMultisigThreshold
thresholdSet={e.erc20Multisig.thresholdSet}
/>
);
}
if (e.erc20Multisig.signerAdded) {
return (
<TxDetailsChainMultisigSigner signer={e.erc20Multisig.signerAdded} />
);
}
if (e.erc20Multisig.signerRemoved) {
return (
<TxDetailsChainMultisigSigner signer={e.erc20Multisig.signerRemoved} />
);
}
}
// Staking events
if (e.stakingEvent) {
if (e.stakingEvent.stakeDeposited) {
return (
<TxDetailsChainEventStakeDeposit
deposit={e.stakingEvent.stakeDeposited}
/>
);
}
if (e.stakingEvent.stakeRemoved) {
return (
<TxDetailsChainEventStakeRemove remove={e.stakingEvent.stakeRemoved} />
);
}
if (e.stakingEvent.totalSupply) {
return (
<TxDetailsChainEventStakeTotalSupply
update={e.stakingEvent.totalSupply}
/>
);
}
}
// If we hit this return, tx-shared-details should give a basic overview
return null;
};
@@ -0,0 +1,16 @@
/**
* Returns a reasonably formatted time from unix timestamp of block height
*
* @param date String or null date
* @returns String date in locale time
*/
export function getBlockTime(date?: string) {
if (!date) {
return '-';
}
const timeInSeconds = parseInt(date, 10);
const timeInMs = timeInSeconds * 1000;
return new Date(timeInMs).toLocaleString();
}
@@ -0,0 +1,46 @@
import { t } from '@vegaprotocol/react-helpers';
import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer';
import { AssetLink, PartyLink } from '../../../links';
interface TxDetailsChainEventBuiltinDepositProps {
deposit: components['schemas']['vegaBuiltinAssetDeposit'];
}
/**
* Someone deposited some of a builtin asset. Builtin assets
* have no value outside the Vega chain and should appear only
* on Test networks.
*/
export const TxDetailsChainEventBuiltinDeposit = ({
deposit,
}: TxDetailsChainEventBuiltinDepositProps) => {
if (!deposit) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
return (
<>
<TableRow modifier="bordered">
<TableCell>{t('Chain Event type')}</TableCell>
<TableCell>{t('Built-in asset deposit')}</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Recipient')}</TableCell>
<TableCell>
<PartyLink id={deposit.partyId || ''} />
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Asset')}</TableCell>
<TableCell>
<AssetLink id={deposit.vegaAssetId || ''} /> ({t('built in asset')})
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Amount')}</TableCell>
<TableCell>{deposit.amount}</TableCell>
</TableRow>
</>
);
};
@@ -0,0 +1,47 @@
import { t } from '@vegaprotocol/react-helpers';
import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer';
import { AssetLink, PartyLink } from '../../../links';
interface TxDetailsChainEventBuiltinDepositProps {
withdrawal: components['schemas']['vegaBuiltinAssetWithdrawal'];
}
/**
* Someone withdrew some of a builtin asset. Builtin assets
* have no value outside the Vega chain and should appear only
* on Test networks, so someone withdrawing it is pretty rare
*/
export const TxDetailsChainEventBuiltinWithdrawal = ({
withdrawal,
}: TxDetailsChainEventBuiltinDepositProps) => {
if (!withdrawal) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
return (
<>
<TableRow modifier="bordered">
<TableCell>{t('Chain Event type')}</TableCell>
<TableCell>{t('Built-in asset withdrawal')}</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Recipient')}</TableCell>
<TableCell>
<PartyLink id={withdrawal.partyId || ''} />
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Asset')}</TableCell>
<TableCell>
<AssetLink id={withdrawal.vegaAssetId || ''} /> ({t('built in asset')}
)
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Amount')}</TableCell>
<TableCell>{withdrawal.amount}</TableCell>
</TableRow>
</>
);
};
@@ -0,0 +1,37 @@
import { t } from '@vegaprotocol/react-helpers';
import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer';
import { AssetLink } from '../../../links';
interface TxDetailsChainEventErc20AssetDelistProps {
assetDelist: components['schemas']['vegaERC20AssetDelist'];
}
/**
* An ERC20 asset was removed from the bridge,
* The link should link to an asset that doesn't exist. Which feels odd
* but I think is better than having no link - in case something
* weird is up and it still exists
*/
export const TxDetailsChainEventErc20AssetDelist = ({
assetDelist,
}: TxDetailsChainEventErc20AssetDelistProps) => {
if (!assetDelist) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
return (
<>
<TableRow modifier="bordered">
<TableCell>{t('Chain event type')}</TableCell>
<TableCell>{t('ERC20 asset removed')}</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Removed Vega asset')}</TableCell>
<TableCell>
<AssetLink id={assetDelist.vegaAssetId || ''} />
</TableCell>
</TableRow>
</>
);
};
@@ -0,0 +1,65 @@
import { t } from '@vegaprotocol/react-helpers';
import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer';
import { AssetLink } from '../../../links';
import {
EthExplorerLink,
EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link';
interface TxDetailsChainEventErc20AssetLimitsUpdatedProps {
assetLimitsUpdated: components['schemas']['vegaERC20AssetLimitsUpdated'];
}
/**
* An ERC20 asset was had its limits changed. The limits are in place
* at first to prevent users depositing large sums while the network
* is still new, as a safety measure.
* - Lifetime limit is how much can be withdrawn of this asset to a
* single ethereum address
* - Withdraw threshold is the size of a withdrawal that will incur
* a delay in processing. The delay is set by a network parameter
*/
export const TxDetailsChainEventErc20AssetLimitsUpdated = ({
assetLimitsUpdated,
}: TxDetailsChainEventErc20AssetLimitsUpdatedProps) => {
if (!assetLimitsUpdated) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
return (
<>
<TableRow modifier="bordered">
<TableCell>{t('Chain event type')}</TableCell>
<TableCell>{t('ERC20 asset limits updated')}</TableCell>
</TableRow>
{assetLimitsUpdated.sourceEthereumAddress ? (
<TableRow modifier="bordered">
<TableCell>{t('ERC20 asset')}</TableCell>
<TableCell>
<EthExplorerLink
id={assetLimitsUpdated.sourceEthereumAddress}
type={EthExplorerLinkTypes.address}
/>
</TableCell>
</TableRow>
) : null}
<TableRow modifier="bordered">
<TableCell>{t('Vega asset')}</TableCell>
<TableCell>
<AssetLink id={assetLimitsUpdated.vegaAssetId || ''} />
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Total lifetime limit')}</TableCell>
<TableCell>{assetLimitsUpdated.lifetimeLimits}</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Asset withdrawal threshold')}</TableCell>
<TableCell>{assetLimitsUpdated.withdrawThreshold}</TableCell>
</TableRow>
</>
);
};
@@ -0,0 +1,51 @@
import { t } from '@vegaprotocol/react-helpers';
import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer';
import { AssetLink } from '../../../links';
import {
EthExplorerLink,
EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link';
interface TxDetailsChainEventErc20AssetListProps {
assetList: components['schemas']['vegaERC20AssetList'];
}
/**
* An ERC20 asset was proposed and then enacted on the bridge,
* a Asset List event will be emitted that tells the core to
* create the asset. That's this event - it's very basic
*/
export const TxDetailsChainEventErc20AssetList = ({
assetList,
}: TxDetailsChainEventErc20AssetListProps) => {
if (!assetList) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
return (
<>
<TableRow modifier="bordered">
<TableCell>{t('Chain event type')}</TableCell>
<TableCell>{t('ERC20 asset added')}</TableCell>
</TableRow>
{assetList.assetSource ? (
<TableRow modifier="bordered">
<TableCell>{t('Source')}</TableCell>
<TableCell>
<EthExplorerLink
id={assetList.assetSource}
type={EthExplorerLinkTypes.address}
/>
</TableCell>
</TableRow>
) : null}
<TableRow modifier="bordered">
<TableCell>{t('Added Vega asset')}</TableCell>
<TableCell>
<AssetLink id={assetList.vegaAssetId || ''} />
</TableCell>
</TableRow>
</>
);
};
@@ -0,0 +1,24 @@
import { t } from '@vegaprotocol/react-helpers';
import { TableRow, TableCell } from '../../../table';
interface TxDetailsChainEventErc20BridgePauseProps {
isPaused: boolean;
}
/**
* The bridge was either paused or unpaused, preventing withdrawals
* or deposits from being enacted. This will only happen if the
* validators have signed a multisig bundle requiring it to happen
*/
export const TxDetailsChainEventErc20BridgePause = ({
isPaused,
}: TxDetailsChainEventErc20BridgePauseProps) => {
const event = isPaused ? 'pause' : 'unpaused';
return (
<TableRow modifier="bordered">
<TableCell>{t('Chain event type')}</TableCell>
<TableCell>{t(`ERC20 bridge ${event}`)}</TableCell>
</TableRow>
);
};
@@ -0,0 +1,59 @@
import { t } from '@vegaprotocol/react-helpers';
import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer';
import { AssetLink, PartyLink } from '../../../links';
import {
EthExplorerLink,
EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link';
interface TxDetailsChainEventProps {
deposit: components['schemas']['vegaERC20Deposit'];
}
/**
* Someone deposited some erc20
*/
export const TxDetailsChainEventDeposit = ({
deposit,
}: TxDetailsChainEventProps) => {
if (!deposit) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
return (
<>
<TableRow modifier="bordered">
<TableCell>{t('Chain event type')}</TableCell>
<TableCell>{t('ERC20 deposit')}</TableCell>
</TableRow>
{deposit.sourceEthereumAddress ? (
<TableRow modifier="bordered">
<TableCell>{t('Source')}</TableCell>
<TableCell>
<EthExplorerLink
id={deposit.sourceEthereumAddress}
type={EthExplorerLinkTypes.address}
/>
</TableCell>
</TableRow>
) : null}
<TableRow modifier="bordered">
<TableCell>{t('Recipient')}</TableCell>
<TableCell>
<PartyLink id={deposit.targetPartyId || ''} />
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Asset')}</TableCell>
<TableCell>
<AssetLink id={deposit.vegaAssetId || ''} />
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Amount')}</TableCell>
<TableCell>{deposit.amount}</TableCell>
</TableRow>
</>
);
};

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