Compare commits

...
Author SHA1 Message Date
Matthew Russell d353f24f01 chore: fix lint 2023-10-12 16:22:30 -07:00
Matthew Russell 5755347a31 feat: make animation delay negative so it starts immediately 2023-10-12 16:21:06 -07:00
Matthew Russell ade1dff30d chore: add ssr-loader component 2023-10-12 15:33:24 -07:00
Matthew Russell 5ca65260c9 chore: remove link of preloader styles 2023-10-12 15:21:59 -07:00
Matthew Russell c276106cfc chore: delete pre-loader styles and classes 2023-10-12 14:59:25 -07:00
Matthew Russell a1ec426a6e chore: rename app-loader to bootstrapper to avoid confusion 2023-10-12 14:53:35 -07:00
Matthew Russell e20202f895 feat: add app loader component 2023-10-12 14:51:46 -07:00
Joe Tsanganddaro-maj 58cc074538 test(governance): governance transfer proposal tests (#5011)
Co-authored-by: daro-maj <119658839+daro-maj@users.noreply.github.com>
2023-10-12 18:48:39 +02:00
Bartłomiej Głownia 852c9bb8f4 feat(trading): display fees discounts (#4800) 2023-10-12 16:58:57 +02:00
Maciek efe9b7a0e7 chore(trading): upgrade pennant version (#5023) 2023-10-12 13:18:17 +00:00
daro-maj 695a059dde test(trading): add funding spec (#5028) 2023-10-12 11:58:32 +01:00
Maciek 5d7e4d273a chore(trading): add timezone note to the ledger entries form (#5018) 2023-10-12 09:12:54 +00:00
Sam Keen b137e024c6 feat(governance): volume discount proposals (#5022) 2023-10-11 18:51:52 +00:00
Ben 6651ee52b4 chore(trading): oracle banner test (#5020) 2023-10-11 15:54:26 +01:00
m.rayandRado 0d14722c5d feat(trading): add risk factors leverage and update accordion panel (#5000)
Co-authored-by: Rado <szpiechrados@gmail.com>
2023-10-11 10:19:43 +01:00
Sam Keen 4968b537b8 feat(governance): referral proposals (#5013) 2023-10-11 09:11:35 +00:00
Bartłomiej Głownia 5f5c45f3b9 feat(trading): display empty values for funding and countdown if perp market is in auction (#4987) 2023-10-10 16:59:31 +01:00
MaciekandMatthew Russell 6b10df015d feat(trading): 4387 market terminate warning banner (#4912)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-10-10 17:50:49 +02:00
Ben 6d7e24732b chore(trading): transfer form test to jest (#5010) 2023-10-10 14:37:06 +01:00
Matthew Russell b33cf04e16 fix(trading): flickering of market loading (#5006) 2023-10-10 14:20:27 +01:00
Ben 66ebb26b0f chore(trading): deal ticket tif tests (#5009) 2023-10-10 13:05:02 +01:00
Ben 51c88d2fce chore(trading): move trades tests to jest (#5001) 2023-10-10 11:13:23 +01:00
daro-maj 2786a984b0 test(trading): remove portfolio test (#5007) 2023-10-10 10:02:09 +01:00
Maciek 39c53a7326 chore(trading): 4858 redesign market header (#4976) 2023-10-10 10:45:09 +02:00
Radosław Szpiech 3371e8e2cc Merge pull request #5004 from vegaprotocol/chore/fix-multiline-condition
chore(ci): merge main fixes to develop
2023-10-10 10:17:49 +02:00
Rado 5843a36851 Merge remote-tracking branch 'origin/main' into chore/fix-multiline-condition 2023-10-09 17:29:36 +02:00
Radosław Szpiech 68b4909dff chore(ci): fix badly written condition in workflow (#5002) 2023-10-09 17:24:18 +02:00
Bartłomiej Głownia da8e382454 feat(trading): add funding payment history (#4989) 2023-10-09 16:59:00 +02:00
81ebefc329 chore(trading): accounts test to jest (#4984)
Co-authored-by: daro-maj <119658839+daro-maj@users.noreply.github.com>
Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
Co-authored-by: Mikołaj Młodzikowski <mikolaj.mlodzikowski@gmail.com>
2023-10-09 10:09:10 +01:00
Bartłomiej Głownia 1ed7d6fda2 feat(positions): add closed markets filter to positions in portfolio (#4982) 2023-10-09 08:28:21 +02:00
Radosław Szpiech a2e4f34b0d Merge pull request #4996 from vegaprotocol/chore/update-develop
chore(ci): merge main changes to develop
2023-10-06 16:43:05 +02:00
Rado 3a1bb855aa Merge remote-tracking branch 'origin/main' into chore/update-develop 2023-10-06 16:14:09 +02:00
Radosław Szpiech b4ca0a8390 chore(ci): run console-test on PR again (#4995) 2023-10-06 16:12:13 +02:00
Radosław Szpiech 349c790ecc Merge pull request #4993 from vegaprotocol/chore/update-develop-with-main
chore(ci,governance): update develop with latest main changes
2023-10-06 13:52:19 +02:00
Rado 4c8a15cc01 chore(governance): merge main 2023-10-06 12:57:32 +02:00
Radosław Szpiech f433a030ff chore(ci): separate export docker image job in console-test workflow (#4980) 2023-10-06 10:47:38 +00:00
Joe Tsang 63a6e4ecbd chore(governance): fix failing link test (#4990) 2023-10-06 12:00:21 +02:00
Joe Tsang 555f6e2a6d chore(explorer): fix failing market test (#4992) 2023-10-06 11:20:12 +02:00
Matthew Russell c116762865 fix(trading,wallet): set version for vega snap (#4991) 2023-10-05 14:18:40 -04:00
Joe Tsang b47bd49e83 test(governance): skip staking test (#4974) 2023-10-05 14:22:08 +00:00
Ben 4b942cfb7d chore(ci): add release label on release (#4985) 2023-10-05 13:28:24 +01:00
Mikołaj Młodzikowski c27443fc13 feat(ci): add workflow to clean up caches on closed PRs (#4988) 2023-10-05 12:46:22 +02:00
Bartłomiej Głownia 6dbde76c84 chore(wallet): remove dependency on apollo from wallet lib (#4814) 2023-10-05 11:25:54 +02:00
daro-maj f4abd7cef5 test(trading): remove account test (#4983) 2023-10-05 10:05:02 +02:00
Bartłomiej Głownia 3b978118dc feat(deal-ticket): fix margin and fees alignment (#4956) 2023-10-05 07:40:25 +02:00
Ben bb4cc1e51d chore(trading): set default sort order (#4978) 2023-10-05 00:12:47 +01:00
Bartłomiej Głownia 797db6ee93 feat(ui-toolkit): increase checkbox and radio clickable area (#4906) 2023-10-04 12:50:02 +02:00
Radosław Szpiech 6e7b87d9ef Merge pull request #4972 from vegaprotocol/chore/merge-main-pull-requests
chore(trading): merge main to develop
2023-10-04 12:02:11 +02:00
Madalina Raicu 6965bdf0ca chore: remove closed markets 2023-10-03 18:40:36 +01:00
Madalina Raicu f4d46efff5 Merge branch 'main' of github.com:vegaprotocol/frontend-monorepo into chore/merge-main-pull-requests 2023-10-03 18:21:10 +01:00
Art d510330c6b feat(governance): governance transfers (#4411) 2023-10-03 15:35:17 +00:00
Ben 5b5765ef63 chore(trading): add accounts jest test (#4962) 2023-10-03 15:16:24 +00:00
Bartłomiej Głownia 283f654a4c chore(trading): upgrade pennant (#4967) 2023-10-03 13:00:35 +01:00
Radosław Szpiech 6945514b49 chore(ci): quotes and double brackets change (#4965) 2023-10-03 12:57:17 +01:00
Maciek f74687d30c chore(trading): 4947 cant view settled market main (#4964) 2023-10-03 12:31:05 +01:00
m.ray 2a7574bd8e fix(governance): add wallet connect project ID (#4966) 2023-10-03 12:30:24 +01:00
Matthew RussellandMadalina Raicu 872f1d300f fix(wallet): dont show error state if user rejects connection (#4901)
Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2023-10-03 12:21:19 +01:00
Mikołaj Młodzikowski 600ea0eeab Revert "Update Jenkinsfile"
This reverts commit 7c3f7a7ab1.
2023-10-03 12:30:39 +02:00
Mikołaj Młodzikowski 7c3f7a7ab1 Update Jenkinsfile
feat(ci): check jenkins execution
2023-10-03 12:15:03 +02:00
Maciek 539abce8af chore(trading): cant view settled market (#4958) 2023-10-03 11:08:30 +01:00
Bartłomiej Głownia 60ca6c2eb6 feat(trading): show fills for all markets (#4951) 2023-10-03 11:00:26 +01:00
Art eeff4ffcd4 fix(trading): missing wallet connect button (#4960) 2023-10-03 10:53:32 +01:00
Radosław Szpiech 73ae00f12c chore(ci): add missing quote marks that may have caused some workflow fails (#4963) 2023-10-03 10:44:12 +01:00
Art ee73e4d5e2 fix(trading): missing wallet connect button (#4959) 2023-10-03 10:38:37 +01:00
Joe Tsang 14928d318d chore(governance): add e2e tests for market update proposals (#4945) 2023-10-02 20:50:47 +01:00
m.ray a19ea1c939 fix(trading): update filter for market selector to include suspended via governance (#4957) 2023-10-02 18:00:49 +01:00
m.rayandMatthew Russell c65c296db2 feat(trading): ethereum oracle spec in oracle panels (#4914)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-10-02 17:48:12 +01:00
Maciek 6c5cd85d96 fix(deal-ticket): prevent empty call estimate position (#4950) 2023-10-02 18:26:10 +02:00
m.ray 8efadda98c fix(trading): remove market value proxy and formatting (#4916) 2023-10-02 16:00:55 +01:00
Maciek 0872a14f44 feat(positions): close position with max possible size (#4940) 2023-10-02 16:38:22 +02:00
Radosław Szpiech 8b249e1917 chore(ci): fix some minor issues in workflows (#4953) 2023-10-02 16:12:24 +02:00
Ben 13817e4d57 chore(trading): delete duplicate asset details test (#4954) 2023-10-02 13:57:54 +00:00
Radosław Szpiech abb771e2f9 chore(ci): add conditions to run e2e tests (#4946) 2023-10-02 14:29:59 +02:00
Edd acf1d50d0f chore(explorer): ignore errors on oracle page (#4944) 2023-09-29 17:29:16 +01:00
Matthew Russell 9da704c117 Merge pull request #4943 from vegaprotocol/chore/merge-main
chore(ci): merge main to develop
2023-09-29 12:11:25 -04:00
Rado d262650258 chore: merge main to develop 2023-09-29 17:46:20 +02:00
Radosław Szpiech 30da1663eb chore(ci): add main develop merge condition to runner (#4941) 2023-09-29 17:36:18 +02:00
Radosław Szpiech 79cbe62774 chore(ci): add mainnet compatible runner to release mainnet branch push actions (#4939) 2023-09-29 11:00:20 -04:00
Matthew Russell df11401b69 Merge pull request #4932 from vegaprotocol/main
chore(ci,trading): update develop with mainnet fixes
2023-09-29 10:33:42 -04:00
Maciek 2f0be0bf34 chore(trading): 4774 put connect dialog inside onboarding dialog - main branch (#4920) 2023-09-29 15:07:18 +02:00
Radosław Szpiech 5b5802104e chore(ci): trigger lint-pr on repoened and sync (#4937) 2023-09-29 15:03:58 +02:00
Radosław Szpiech 3a149ddfb2 chore(ci): add mainnet compatible runner to release mainnet branch push actions (#4936) 2023-09-29 14:01:04 +02:00
Sam Keen 0e519f4d0e feat(governance): market state update proposals (#4935) 2023-09-29 10:11:02 +01:00
Maciek ff2e2574f6 chore(trading): add handle of autosizing selected columns - main branch (#4888) 2023-09-28 15:14:32 -04:00
Joe Tsang 9b52cecf21 chore(governance): remove explorer market diff test (#4928) 2023-09-28 17:24:05 +01:00
Radosław Szpiech 478cc9e753 chore(ci): publish main image in dockerhub (#4930) 2023-09-28 17:38:00 +02:00
Ben 18f1fbd56d chore(trading): deal ticket order tests move (#4927) 2023-09-28 17:16:00 +02:00
Matthew Russell ccb22f02c3 chore(ci): fix conflict in vegacapsule genesis file 2023-09-28 10:44:22 -04:00
Radosław Szpiech 015d8f51c0 chore(ci): sync main to develop (#4924) 2023-09-28 14:43:02 +02:00
Radosław Szpiech e2a72cb395 chore(ci): separate lint pr (main) (#4917) 2023-09-28 14:01:36 +02:00
Radosław Szpiech 0669696b6f chore(ci): fix node version (develop) (#4910) 2023-09-28 13:30:50 +02:00
Joe Tsang 56c662e5ba test(governance): perpetual market e2e test (#4892) 2023-09-28 11:35:46 +02:00
Radosław Szpiech 7fe269fad6 chore(ci): fix node version (main) (#4911) 2023-09-28 11:26:15 +02:00
Radosław Szpiech b761023069 chore(ci): add logic for choosing correct runner for cypress tests depending on base branch (#4918) 2023-09-28 11:25:44 +02:00
Radosław Szpiech 7453acd632 chore(trading): separate workflow for lint-pr (#4904) 2023-09-27 14:44:57 -04:00
Sam Keen 1f507facba feat(governance): show perp or future pills (#4863) 2023-09-27 14:55:43 +01:00
Radosław Szpiech 9d6b34963a chore(trading): add possibility to manualy trigger console-test (#4899) (#4908) 2023-09-27 15:46:49 +02:00
Radosław Szpiech 7ac3a68ac9 chore(trading): add possibility to manualy trigger console-test (#4899) 2023-09-27 15:18:32 +02:00
Radosław Szpiech 2640ccb20a chore(trading): change runner for mainnet compatible vega version (#4907) 2023-09-27 14:42:12 +02:00
Matthew Russell 77c0894501 Merge pull request #4905 from vegaprotocol/chore/update-develop-with-mainnet-fixes
chore(trading,deal-ticket,market-depth,ci): update develop with mainnet fixes
2023-09-26 16:30:10 -04:00
Matthew Russell 60d7cf3029 Merge branch 'main' into chore/update-develop-with-mainnet-fixes 2023-09-26 15:06:07 -04:00
Matthew Russell 2b8abde938 Merge pull request #4880 from vegaprotocol/chore/update-develop-with-mainnet-fixes
chore(trading,governance): update develop with mainnet fixes
2023-09-26 14:06:20 -04:00
Matthew Russell 2005f19d50 fix(trading): prevent deposit sidebar showing on corresponding standalone page (#4840) 2023-09-26 13:47:47 -04:00
Maciek d78de10855 chore(trading): remove underlines on tooltips (#4884) 2023-09-26 13:45:33 -04:00
Matthew Russell bb402c02f6 chore(trading): make volume bars color match candle color (#4881) 2023-09-26 12:08:12 -04:00
Bartłomiej Głownia 8a9b1c7874 feat(deal-ticket): amend fee estimates for postOnly orders and when market is in auction (#4843) 2023-09-26 11:57:47 -04:00
Matthew Russell a7e8b0eb01 fix(market-depth): ensure scroll bar doesn't show on orderbook (#4882) 2023-09-26 11:54:42 -04:00
Bartłomiej Głownia 89b3c06107 feat(deal-ticket): show worst case instead of ranges in estimated values (#4870) 2023-09-26 11:53:45 -04:00
Radosław Szpiech cd5c73d3fd chore(trading): temporary disable console-test to unblock CI queue (#4885) 2023-09-26 10:45:27 +01:00
Joe Tsang b3a5ab022d chore(ci): update genesis file (#4887) 2023-09-26 10:44:55 +01:00
Matthew Russell ba438549bc Merge branch 'main' into chore/update-develop-with-mainnet-fixes 2023-09-25 21:30:40 -04:00
Mikołaj Młodzikowski 496d1f5c68 feat(ci): parse if there are any changes 2023-09-25 18:10:01 -04:00
Mikołaj Młodzikowski e914e7bb70 fix(ci): provide proper ipfs process 2023-09-25 18:09:31 -04:00
Matthew Russell 71a36c2382 fix(trading): remove upgrade banner [main] (#4877) 2023-09-25 17:27:01 -04:00
Matthew Russell 1c6a307bcd fix(wallet): reduce time to check for wallet running [main] (#4876) 2023-09-25 17:26:40 -04:00
Matthew Russell ef4a740b91 fix(trading): allotment breaking [main] (#4875) 2023-09-25 17:26:06 -04:00
a6303456c5 feat(trading): liquidity SLA in market info (#4649)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
Co-authored-by: candida-d <62548908+candida-d@users.noreply.github.com>
Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
Co-authored-by: Joe Tsang <30622993+jtsang586@users.noreply.github.com>
Co-authored-by: Joe <joe@vega.xyz>
2023-09-25 14:44:55 +01:00
Sam Keen 2d4be5fcb3 fix(governance): mainnet rewards query looping (#4865) 2023-09-25 09:59:38 +00:00
Sam Keen 9cbd6baccd fix(governance): removed loop caused by rewards epoch refresh (#4864) 2023-09-25 09:34:47 +00:00
Maciek 525773773a chore(trading): 4811 make market table columns resizable (#4856) 2023-09-25 10:14:18 +02:00
Ben 45d6f43e74 chore(trading): deal ticket test to jest (#4842) 2023-09-22 15:25:50 +01:00
Art 41760f2956 chore(trading): disable apply code when applied (#4855) 2023-09-22 12:06:02 +01:00
Maciek 3d2b171de7 chore(trading): 4774 put connect dialog inside onboarding dialog (#4845) 2023-09-22 11:04:02 +02:00
Joe Tsang 39a041332b chore(governance): fix failing proposal submission (#4835) 2023-09-22 09:40:35 +01:00
Bartłomiej Głownia 4c0d05844e feat(trading): improve funding rate formatting (#4847) 2023-09-22 09:39:56 +01:00
Matthew Russell bf8480fed4 chore(trading): remove upgrade banner (#4852) 2023-09-22 09:39:26 +01:00
ArtandMatthew Russell 44434a7d39 feat(trading): referrals (Mk1) (#4816)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-21 14:25:19 +01:00
m.ray b818e9b2a1 fix(trading): ignore conditions list empty (#4848) 2023-09-21 14:24:21 +01:00
Radosław Szpiech 775835c667 chore(trading): disable console-test run until CI fixed (#4846) 2023-09-21 14:32:17 +02:00
Matthew Russell 3e30f053ff chore(trading): routing and link changes (#4738) 2023-09-20 13:28:34 -07:00
Bartłomiej GłowniaandMatthew Russell 5db3453ba5 fix(accounts): hide no rows label when there is only pinned row (#4833)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-20 20:03:07 +00:00
Matthew Russell 0b1987d4ce chore(trading,governance,explorer): prevent jobs if PR is in draft (#4827) 2023-09-20 11:13:43 -07:00
290b7ae856 feat(trading): browse perpetuals [stagnet1] (#4590)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
Co-authored-by: Joe Tsang <30622993+jtsang586@users.noreply.github.com>
Co-authored-by: Joe <joe@vega.xyz>
2023-09-20 10:11:03 +01:00
m.rayandMatthew Russell 835f2b793f chore(trading): remove static assets console coming from vega.xyz (#4825)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-19 23:54:07 -07:00
Mikołaj Młodzikowski e1557f51ce feat(ci): parse if there are any changes 2023-09-19 10:05:00 +02:00
Mikołaj Młodzikowski c98e53a984 fix(ci): provide proper ipfs process 2023-09-19 09:55:21 +02:00
MaciekandMatthew Russell 95a51fd152 chore(withdraws): standalone pages for withdraw and transfer (#4728)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-19 08:15:36 +02:00
Matthew Russell d50b988b4a Merge branch 'release/mainnet-trading' of github.com:vegaprotocol/frontend-monorepo into release/mainnet-trading 2023-09-18 09:03:44 -07:00
m.ray 76ee58e473 chore(trading): update tag metamask snaps to true (#4815) 2023-09-18 15:19:48 +01:00
Madalina Raicu a6aec899c8 chore: update tag metamask snaps to true 2023-09-18 15:08:46 +01:00
Mikołaj Młodzikowski a6672d213f fix(ci): provide better endpoint 2023-09-18 13:17:37 +02:00
Radosław Szpiech 62f368da10 chore(trading): cache console test vega binaries (#4752) 2023-09-18 09:28:15 +00:00
daro-maj f3e2fe746d test(trading): fix test for release v0.21.2 (#4806) 2023-09-18 08:40:35 +02:00
Mikołaj Młodzikowski 8b19572dc9 feat(ci): proper run 2023-09-15 13:07:55 -07:00
Mikołaj Młodzikowski 80399d04f7 feat(ci): patch releasing to ipfs 2023-09-15 17:03:50 +02:00
m.ray 8322fc7edd chore: bump version (#4805) 2023-09-15 15:46:02 +01:00
46752816ec chore(trading): get started section for deposit (#4783)
Co-authored-by: maciek <maciek@vegaprotocol.io>
Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2023-09-15 15:10:38 +01:00
Sam Keen f99f78780c fix(markets): market info for liquidity is showing "added" tags (#4796) 2023-09-15 13:54:17 +01:00
Maciek f7037bca80 chore(deal-ticket): 4743 preserve estimate position cache in deal ticket (#4770) 2023-09-15 13:53:24 +01:00
Matthew RussellandMadalina Raicu ba39720f05 fix(trading,web3): prevent deposit toasts reappearing (#4797)
Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2023-09-15 13:51:28 +01:00
MaciekandMadalina Raicu 6d35f2b39d chore(trading): 4764 remember closed sidebar (#4799)
Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
2023-09-15 13:36:08 +01:00
Matthew Russell 78afecc2e5 chore(trading): layout adjustments to accomodate default 13 inch screens (#4798) 2023-09-15 13:24:47 +01:00
Bartłomiej Głownia 3de5b07495 fix(trading): add overflow hidden to candles tab container (#4803) 2023-09-15 13:13:05 +01:00
Matthew Russell e944d3e37c fix(trading): correct link for get started prompt (#4782) 2023-09-15 13:12:39 +01:00
Joe Tsang 5596392835 chore(governance): fix failing staking test (#4801) 2023-09-15 13:04:42 +01:00
Ben 5c57106c04 chore(trading): delete market info tests (#4804) 2023-09-15 14:45:52 +03:00
Ben 2fc688f477 chore(trading): fix wallet test (#4802) 2023-09-15 14:45:15 +03:00
Mikołaj Młodzikowski 9ea8c839db feat(ci): use ipfs daemon in dockerfiles (#4786) 2023-09-15 08:48:25 +02:00
Matthew Russell d7e2da7a54 fix(trading): missing styles for tooltip in positions table (#4780) 2023-09-14 14:00:59 -07:00
m.ray b29c268257 chore(trading): add oracle proofs url to all envs (#4793) 2023-09-14 13:57:28 -07:00
m.rayandMatthew Russell 01ca05a313 chore(trading): update governance variables (#4766)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-14 13:57:15 -07:00
Matthew Russell e3c6dd41c9 fix(trading): simplify onboarding and explore button to use top traded (#4781) 2023-09-14 12:10:33 -07:00
Bartłomiej GłowniaandMatthew Russell fbd01dc1bd fix(trading): use asset decimals to format liquidation price in posions table (#4787)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-14 11:18:58 -07:00
m.rayandMatthew Russell af6719cc9d chore(trading): add governance link to top level nav (#4765)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-13 14:25:31 -07:00
Sam KeenandJoe c433a4ee06 feat(governance): more mobile view improvements (#4751)
Co-authored-by: Joe <joe@vega.xyz>
2023-09-13 19:01:33 +01:00
Matthew Russell e3a00ada05 chore(trading,governance,explorer): update pr template to ensure issues get linked 2023-09-13 08:30:06 -07:00
Joe Tsang aa38e0c001 test(governance): add assert for numerical sort (#4742) 2023-09-13 13:02:47 +01:00
Joe Tsang 86da521da5 test(governance): flaky test fixes (#4760) 2023-09-13 11:53:22 +01:00
Matthew Russell c6df34fe95 chore(trading): bump app version and enable snaps 2023-09-12 13:40:08 -07:00
Matthew Russell c7d0803164 chore(trading): make closed market table rows the correct height 2023-09-12 12:47:47 -07:00
m.ray 250a654544 feat(trading): margin required progressive disclosure (#4755) 2023-09-12 12:06:47 -07:00
Matthew Russell 7f5e8ebb15 chore(trading): replace successor cols with market code cell (#4722) 2023-09-12 11:52:03 -07:00
Art ccbe34e172 chore(trading): make deal ticket open on market change (#4749) 2023-09-12 11:26:54 -07:00
Maciek 27e8ce88bf chore(trading): adjust onboarding experience (#4754) 2023-09-12 11:10:17 -07:00
ArtandMatthew Russell 41804d9869 chore(trading): market list tweaks (#4756)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-12 10:41:45 -07:00
Maciek 293288286b chore(trading): adjust gap between candles (#4753) 2023-09-12 09:59:13 -07:00
Matthew Russell a77765b1e9 feat(trading): store study sizes, reduce candles gap (#4708) 2023-09-12 09:56:43 -07:00
MaciekandMatthew Russell 2453d7841a chore(trading): open connect dialog from onboarding dialog (#4744)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-12 08:07:37 -07:00
Sam KeenandJoe a0945be721 fix(governance,environment): adjust proposal user journey (#4679)
Co-authored-by: Joe <joe@vega.xyz>
2023-09-11 22:04:30 +01:00
Maciek 84e40ccb2b chore(deal-ticket): make margin warning more subtle (#4732) 2023-09-11 16:46:16 +02:00
daro-maj a868f6d2f5 test(trading): update acs for deal ticket (#4739) 2023-09-11 11:17:07 +02:00
m.rayandMatthew Russell 8b83c51014 feat(trading): improve connect wallet description (#4726)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-11 08:48:27 +00:00
Maciek bf7aacf984 chore(trading): initial number of candles depended on pane width (#4737) 2023-09-11 10:27:03 +02:00
Matthew Russell 5183f2591b chore(trading,governance,explorer): add frontend-qa to codeowners (#4735) 2023-09-08 17:00:18 -07:00
Maciek b3308439bd chore(candles-chart): show more candles by default (#4734) 2023-09-08 15:15:36 -07:00
Bartłomiej Głownia 719d210219 chore(trading): remove target build from libs (#4725) 2023-09-08 13:43:54 -07:00
Edd f810a3a0b1 chore(trading): maintenance on ipfs build process (#4736) 2023-09-08 10:50:19 -07:00
Sam Keen db19ee80ac feat(governance): improve the display of Governance app on mobile (#4724) 2023-09-08 09:48:09 +00:00
Sam Keen 45623f33c5 fix(governance): corrected sorting of upgrade proposals by blockheight (#4729) 2023-09-08 09:19:59 +00:00
Joe Tsang 08e204fe31 test(explorer): test for network param grouping (#4710) 2023-09-07 15:15:41 +01:00
Joe Tsang 81f7b0595e chore(governance): update tests with vote changes (#4706) 2023-09-07 15:14:37 +01:00
Radosław Szpiech 4ed0e3a056 chore(trading): add console-test runner (#4711) 2023-09-07 13:22:01 +02:00
47a84b4dac feat(deal-ticket): show maximum number of active stop orders limit warning (#4687)
Co-authored-by: Maciek <maciek@vegaprotocol.io>
Co-authored-by: Edd <edd@vega.xyz>
Co-authored-by: Joe Tsang <30622993+jtsang586@users.noreply.github.com>
Co-authored-by: Sam Keen <samuel.kleinmann@gmail.com>
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
Co-authored-by: m.ray <16125548+MadalinaRaicu@users.noreply.github.com>
Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
2023-09-07 09:25:26 +00:00
Matthew Russell c540d4b17f chore(utils): bump utils version 2023-09-06 22:13:24 -07:00
Matthew Russell f1fa3250a4 chore(utils): remove externals from utils 2023-09-06 22:12:21 -07:00
Matthew Russell 707c00def2 fix(trading,governance,explorer): peer deps for published packages (#4721) 2023-09-06 17:04:52 -07:00
Matthew Russell 78aff54360 chore(trading): remove duplicate stylesheet and icon references (#4707) 2023-09-06 13:51:41 -07:00
Maciek 6160fd7638 chore(trading): 4594 ci optimisations (#4688) 2023-09-06 13:35:49 -07:00
Dexter Edwards c345623a06 feat: add marketCreationQuantumMultiple into tooltip (#3706) 2023-09-06 13:34:18 -07:00
Sam Keen e9173796f5 fix(governance,environment,proposals): network upgrade proposal urls include block height (#4704) 2023-09-06 10:56:18 +00:00
Sam Keen 2a0811863f feat(explorer): add headings and anchors to net params page (#4691) 2023-09-05 09:09:31 +01:00
Sam Keen 4f610bbd1b feat(governance): vote status improvements (#4654) 2023-09-05 09:43:37 +02:00
Matthew Russell 104b2d145d chore: release v0.21.0-core-0.72.14 2023-09-04 20:05:18 -07:00
Matthew Russell f75787562c chore(trading): minor style changes 2 (#4698) 2023-09-04 20:03:59 -07:00
Matthew Russell 678c9090c7 chore(trading): update flags for 0.72.14 (#4697) 2023-09-04 18:33:58 -07:00
Matthew Russell 21bb6a69c6 chore(trading): minor style tweaks (#4696) 2023-09-04 17:21:46 -07:00
Bartłomiej Głownia 467ed5d53d feat(deal-ticket): make margin values section expandable (#4664) 2023-09-04 17:05:53 -07:00
m.rayandMatthew Russell d268088e60 chore(trading): update dropdowns (#4694)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-09-04 20:25:24 +00:00
Matthew Russell 1208d3f2a8 feat(market-depth): additional orderbook grouping levels (#4658) 2023-09-04 07:47:27 -07:00
Sam Keen b5ba4f99d9 fix(governance,utils,react-helpers): token locale formatting issue (#4678) 2023-09-04 12:09:38 +01:00
Joe Tsang 66f25603d3 test(explorer): add e2e test for explorer oracles (#4657) 2023-09-04 09:41:04 +00:00
Edd 4afd469404 chore(explorer,trading,governance): reconfigure hooks (#4655) 2023-09-04 09:36:13 +00:00
Maciek 9e5bc9c8d1 chore(trading): handle negative decimals (#4659) 2023-09-04 09:46:02 +02:00
Matthew Russell e41aff88b1 chore(trading): make top traded default sort for market selector (#4637) 2023-09-03 11:15:41 -07:00
Matthew Russell 9209074332 chore(trading): change pane context buttons color (#4680) 2023-09-01 17:00:11 -07:00
Art 39e5836edb fix(wallet): check if snaps are supported (#4671) 2023-09-01 11:22:13 +00:00
Art 85a4981700 fix(proposals): protocol upgrade notification block querying (#4665) 2023-09-01 12:30:01 +02:00
Ben 247927e939 chore(trading): get started specs update (#4681) 2023-09-01 10:55:56 +01:00
Maciek 6523490d96 chore(trading): 4349 delayed telemetry opt in (#4642) 2023-09-01 09:00:20 +00:00
daro-maj 105a758e8d test(trading): add stop order oco spec (#4669) 2023-09-01 10:48:38 +02:00
Matthew Russell 559ef48d6d feat(trading): orderbook changes (#4652) 2023-08-31 13:34:13 -07:00
Bartłomiej Głownia 255c3752f2 feat(deal-ticket): fix flaky tests (#4667) 2023-08-31 10:41:58 -07:00
Joe Tsang 2bbf1e2b81 chore(ci): update config.hcl file (#4677) 2023-08-31 10:35:46 -07:00
Maciek 06d3ef8d73 fix: de-polish and fix links to mozilla (#4670) 2023-08-31 14:09:41 +00:00
ArtandDariusz Majcherczyk de4c7926c2 chore(deposits): formatting tweaks (#4648)
Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
2023-08-31 15:30:03 +02:00
Ben 50959b4c50 chore(trading): delete closed market tests (#4660) 2023-08-31 13:15:02 +01:00
Bartłomiej Głownia a8c2f4e025 feat(deal-ticket): update deal ticket submit buttons (#4635) 2023-08-31 11:54:52 +02:00
Matthew Russell 2cea73c567 chore(wallet): prepare wallet lib for publishing (#4638) 2023-08-30 19:40:04 -07:00
Edd b0a54be408 fix(explorer): format iceberg size according to market (#4612) 2023-08-30 09:39:49 +01:00
Matthew Russell d1a036e53c chore(trading,governance,explorer): update pr template to not close issues (#4645) 2023-08-29 08:54:09 -07:00
MaciekandMatthew Russell 9ac199f59a chore(ledger): remove ledger entries table, adjust download form (#4611)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-29 06:57:02 -07:00
Edd 332cc302c3 feat(explorer): add stop order view (#4418) 2023-08-29 12:24:22 +02:00
Edd 4da0e9c368 fix(explorer): correctly display data source matches (#4631) 2023-08-29 12:23:55 +02:00
Joe Tsang 13e1f99767 test(governance): successor market proposal changes (#4632) 2023-08-29 09:47:59 +01:00
ArtandMatthew Russell 5c18c898b0 feat(wallet): metamask snaps (#4621)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-28 18:51:58 -07:00
Matthew Russell 4fe81cc4aa fix(trading): update fonts for pennant (#4636) 2023-08-28 10:02:32 -07:00
Art 0fb8ee3abb fix(proposals): parsing block duration value (#4613) 2023-08-28 13:11:24 +00:00
Matthew Russell 3422b99491 feat(trading): change to system monospace font (#4634) 2023-08-25 15:24:57 -07:00
Radosław Szpiech 287e294281 chore(trading): remove market-all-cy.ts as it was moved to console-test (#4633) 2023-08-25 14:28:42 -07:00
Bartłomiej GłowniaandMatthew Russell dc959025c6 fix(deal-ticket): disable iceberg for IOC and FOK (#4629)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-25 14:27:55 -07:00
Ben 63bfcc8f65 chore(trading): remove deal ticket basic submit (#4628) 2023-08-25 10:57:09 -07:00
Bartłomiej Głownia 952e906eac fix(deal-ticket): show expiresAt field value from state only, add required validation (#4626) 2023-08-25 10:56:43 -07:00
Matthew Russell e765c247ef chore(trading): adjust the get started checkboxes slightly (#4622) 2023-08-25 10:52:52 -07:00
Sam KeenandJoe 52dea6d0dc feat(ui-toolkit,governance): description preview and read more pattern (#4599)
Co-authored-by: Joe <joe@vega.xyz>
2023-08-25 16:46:03 +01:00
Ben 97f243e5f7 chore(trading): show test run time (#4623) 2023-08-25 11:04:38 +01:00
daro-maj 9992d9f053 test(trading): remove markets proposed tests (#4618) 2023-08-25 12:00:04 +02:00
Sam Keen 3e26431e8f feat(governance): small UX improvements to successor market panels (#4562) 2023-08-25 09:58:01 +00:00
Bartłomiej Głownia 6a9f15f59e feat(deal-ticket): submit oco stop orders (#4539) 2023-08-25 08:37:14 +02:00
Edd 4684745382 fix(explorer): properly render issue signatures tx (#4610) 2023-08-24 18:51:55 +01:00
Joe Tsang 927e21b045 test(explorer): add e2e test for asset proposal on explorer (#4616) 2023-08-24 18:51:24 +01:00
ArtandMatthew Russell 570472b739 feat(trading): sort by top traded in market selector (#4574)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-24 11:05:09 +02:00
Maciek 28f7bd36e7 feat(trading): 4351 get started steps enhancement (#4565) 2023-08-24 10:03:56 +02:00
Radosław Szpiech 0f3e5595ba chore(trading): add dist loadfile to console-test run (#4609) 2023-08-23 13:13:33 +00:00
Bartłomiej Głownia d3dbdd2bd5 feat(trading): view stop order history (#4586) 2023-08-23 13:41:56 +02:00
daro-majandJoe Tsang 0767139712 test(trading): update cypress to version 12.17.0 (#4575)
Co-authored-by: Joe Tsang <30622993+jtsang586@users.noreply.github.com>
2023-08-23 13:34:10 +02:00
daro-maj 250492a02c test(trading): tests for distinguish between product types (#4589) 2023-08-23 11:06:16 +02:00
Maciek 29f3374c61 fix(trading): fix hidden sidebars on load (#4583) 2023-08-23 07:23:36 +00:00
Ciaran McGhie ba7b574a07 chore(ui-toolkit,react-helpers,announcements): bump versions add react react-dom to peer deps (#4602) 2023-08-22 18:51:13 +01:00
Art afd8650657 fix(proposals): error policy guard for proposal data provider (#4573) 2023-08-22 17:58:01 +01:00
Bartłomiej GłowniaandMatthew Russell 78414b4429 feat(ui-toolkit): form element design changes (#4525)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-22 17:39:52 +01:00
m.ray e0a91b3850 chore(trading): revert metadata update - viewport meta tags should not be used in _document.js's (#4591) 2023-08-22 17:23:24 +01:00
Joe Tsang 80f7a08765 test(governance): vote error test (#4588) 2023-08-22 16:15:33 +01:00
Edd 3e627ff849 fix(explorer): check linking type when summing stake (#4585) 2023-08-22 13:08:00 +00:00
Joe Tsang d2854b6e90 chore(governance): add acs for network nodes (#4577) 2023-08-22 12:06:41 +01:00
Matthew Russell 6d130c9cfc feat(positions): filter closed markets in positions table (#4569) 2023-08-22 10:17:10 +01:00
Ben ab4f4e9084 chore(trading): remove trading chart tests (#4582) 2023-08-22 08:29:47 +01:00
Ben fa1825ca64 chore(trading): remove settings test (#4580) 2023-08-22 08:29:13 +01:00
Edd 206c6c7207 fix(explorer): check linking type when summing stake 2023-08-21 18:38:32 +01:00
Sam Keen 5b0bd69710 fix(governance): better vote error handling (#4579) 2023-08-21 10:05:21 +01:00
daro-maj 546b710093 test(trading): split and skip deal ticket account tests (#4578) 2023-08-21 09:49:27 +02:00
Joe Tsang afbf62be84 chore(governance): add assertion for vote change (#4571) 2023-08-18 18:15:55 +03:00
MaciekandMatthew Russell ef26d03d36 chore(markets): distinguish between product types - add specs (#4564)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-17 17:27:15 +01:00
Ben 7471116ebf chore(trading): remove market selector test (#4572) 2023-08-17 17:08:27 +01:00
Matthew Russell 7142fc956c chore(positions): spec updates for positions table changes (#4568) 2023-08-17 13:07:14 +01:00
Matthew Russell 611f8d7491 feat(positions): table layout changes (#4558) 2023-08-17 11:07:48 +01:00
Sam Keen f3b72b894e feat(explorer): view 'Cancel Stop Order' Transactions (#4521) 2023-08-17 10:27:47 +01:00
daro-maj 140f16f637 test(trading): adjust tests edit and cancel orders (#4563) 2023-08-17 09:10:28 +01:00
Sam Keen cae1fc67a4 fix(governance): validators display fixes (#4547) 2023-08-16 22:58:14 +01:00
m.ray 35e25d9a8f chore(trading): metadata console updates (#4549) 2023-08-16 17:06:56 +01:00
Sam Keen 86e122389c fix(governance): proposal vote status header component (#4561) 2023-08-16 16:53:32 +01:00
Joe Tsang 6616aceebb test(governance): add timeout and fix withdrawal test (#4554) 2023-08-16 16:53:24 +01:00
ArtandMatthew Russell c937a9df0c feat(proposals): upgrade in progress notification (#4509)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-16 15:50:38 +01:00
MaciekandMatthew Russell 9fcf286e4b feat(trading): distinguish between product types (#4543)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-08-16 15:43:23 +01:00
m.ray e3ed71bec4 chore(trading): use action icon buttons (#4550) 2023-08-16 15:38:19 +01:00
daro-maj 809f149df9 test(trading): remove charts depth test (#4557) 2023-08-16 10:20:15 +02:00
Matthew Russell e4eedf5ccd feat(trading,datagrid): datagrid improvements (#4524) 2023-08-15 12:26:13 +01:00
Ben 20cbcb8302 chore(trading): remove home tests (#4551) 2023-08-14 18:06:36 +01:00
Joe Tsang cd3acf8ff9 test(explorer): successor market explorer (#4544) 2023-08-14 16:17:29 +01:00
Ben 30735388e8 chore(trading): remove asset tests (#4548) 2023-08-14 15:35:24 +01:00
Ben 478c4f83bb chore(trading): remove markets test (#4545) 2023-08-14 12:20:53 +01:00
JonRay15 431fab8824 chore(trading,governance): update feature-epic.md (#4528) 2023-08-14 09:43:00 +01:00
m.ray 83b6d3d295 feat(trading): metadata console (#4515) 2023-08-11 16:12:43 +00:00
Matthew Russell 98fd79bc35 fix(trading): prevent overflow in deal ticket if market fails to load (#4535) 2023-08-11 17:03:17 +01:00
Ben 39aa27f332 chore(trading): remove iceberg side order details (#4540) 2023-08-11 16:33:34 +01:00
Sam Keen bf4fb29fe6 fix(governance): fixes settlement oracle display in governance (#4534) 2023-08-11 10:08:31 +01:00
Maciek 5ed1befc53 fix(trading): remove redundant connect wallet button (#4538) 2023-08-11 10:34:32 +02:00
m.ray 1b311a8b36 fix(trading): order single view side (#4526) 2023-08-11 09:12:13 +01:00
Matthew Russell 70c3bc8128 chore(trading): remove floating buttons (#4512) 2023-08-10 16:02:46 +01:00
Joe Tsang 7e49836875 chore(governance): add e2e for successor market diff (#4519) 2023-08-10 15:03:23 +01:00
Maciek d624957e6d chore(trading): 4384 all markets in switcher (#4516) 2023-08-10 14:25:13 +01:00
Maciekandasiaznik 069b57d4ae feat(wallet): 4370 new connect wallet modal (#4492)
Co-authored-by: asiaznik <artur@vegaprotocol.io>
2023-08-10 13:03:53 +02:00
Mikołaj Młodzikowski 6894fe1264 fix(ci): hardcode env name 2023-08-10 12:53:35 +02:00
Edd 93e4b5fdb9 feat(explorer): successor markets (#4522) 2023-08-10 09:51:44 +01:00
Maciek 1566fc3984 chore: fulfill spec to 4323 (#4520) 2023-08-10 09:20:26 +02:00
Ben 39962a0246 chore(trading): update console-test runners (#4513) 2023-08-09 14:18:24 +01:00
Sam KeenandJoe 8d31510d5e feat(governance,markets,ui-toolkit): highlight successor market changes (#4449)
Co-authored-by: Joe <joe@vega.xyz>
2023-08-09 14:05:37 +01:00
Bartłomiej Głownia 26d5a67604 feat(trading): use custom toast content for stop order related transactions (#4476) 2023-08-09 14:47:10 +02:00
Bartłomiej Głownia 9cc8f5a377 feat(trading): use instrument code instead of name in positions, fills and accounts breakdown tables (#4478) 2023-08-09 12:12:07 +02:00
Matthew Russell 2e11cf4dfa fix(trading): fix persitance of resizable grid top section (#4508) 2023-08-09 11:04:32 +01:00
Bartłomiej Głownia 9e4ba9f275 feat(trading): merge deal ticket stores (#4494) 2023-08-09 11:54:16 +02:00
m.ray aac0c25d09 fix(trading): positions tooltips update (#4504) 2023-08-08 13:27:17 +01:00
Art d20c2a08ae chore(specs): succession line specs (#4505) 2023-08-08 11:23:28 +01:00
daro-maj 4e6ba5fe3d test(trading): update cypress tests (#4503) 2023-08-08 10:36:10 +02:00
Art 276d1d7c7b feat(governance): view as button (#4501) 2023-08-08 09:50:19 +02:00
m.ray 4990c5808d fix(trading): order iceberg fills (#4502) 2023-08-07 16:07:24 +00:00
Art cdd91c24f2 feat(markets): succession line (#4491) 2023-08-07 11:46:03 +00:00
Sam Keen e3eb13ca72 fix(explorer): footer visual tweaks (#4499) 2023-08-07 11:54:46 +01:00
Matthew Russell 3f0ebbf33d fix(trading): dont render get started if connected (#4490) 2023-08-07 11:35:55 +01:00
Matthew Russell 026aa3964b chore(trading): update pennant (#4493) 2023-08-07 11:06:49 +01:00
988 changed files with 32648 additions and 19569 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
---
name: Feature Epic
about: A template to capture and scope user requirements, high level process, and basic mockups for an upcoming feature as part of the initial core spec review process.
title: 'Epic: '
title: 'FEATURE EPIC: '
labels: feature-epic
---
@@ -82,3 +82,38 @@ jobs:
https://${{ env.IPFS_V1 }}.ipfs.dweb.link/
https://${{ env.IPFS_V1 }}.ipfs.cf-ipfs.com/
ipfs://${{ env.IPFS_V0 }}/
- name: Ensure 'Released' label exists
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
REPO="${{ github.repository }}"
LABEL_EXIST=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$REPO/labels/Released")
if [[ "$LABEL_EXIST" == *"Not Found"* ]]; then
curl -s -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-X POST "https://api.github.com/repos/$REPO/labels" \
-d '{"name": "Released", "color": "FFFFFF"}'
fi
- name: Extract issues from release notes
id: extract-issues
run: |
ISSUES=$(echo "${{ github.event.release.body }}" | grep -o -E '#[0-9]+' | tr -d '#' | jq -R . | jq -cs .)
echo "Issues to label: $ISSUES"
echo "::set-output name=issue_numbers::$ISSUES"
- name: Add 'Released' label to issues
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
ISSUE_NUMBERS="${{ steps.extract-issues.outputs.issue_numbers }}"
REPO="${{ github.repository }}"
for ISSUE in $(echo "$ISSUE_NUMBERS" | jq -r '.[]'); do
curl -s -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-X POST "https://api.github.com/repos/$REPO/issues/$ISSUE/labels" \
-d '{"labels": ["Released"]}'
done
+130 -57
View File
@@ -5,15 +5,17 @@ on:
branches:
- release/*
- develop
- main
pull_request:
types:
- opened
- ready_for_review
- reopened
- edited
- synchronize
jobs:
node-modules:
# All jobs depend on node_modules, so none should run if the PR is in draft
if: github.event.pull_request.draft == false
runs-on: ubuntu-22.04
name: 'Cache yarn modules'
steps:
@@ -21,7 +23,6 @@ jobs:
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Cache node modules
id: cache
uses: actions/cache@v3
@@ -39,23 +40,15 @@ jobs:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: yarn install
if: steps.cache.outputs.cache-hit != 'true'
run: yarn install --pure-lockfile
lint-pr-title:
needs: node-modules
if: ${{ github.event_name == 'pull_request' }}
name: Verify PR title
uses: ./.github/workflows/lint-pr.yml
secrets: inherit
lint-test-build:
timeout-minutes: 60
lint-format:
timeout-minutes: 20
needs: node-modules
runs-on: ubuntu-22.04
name: '(CI) lint + unit test + build'
name: '(CI) lint + format check'
steps:
- name: Checkout
uses: actions/checkout@v3
@@ -81,6 +74,76 @@ jobs:
with:
main-branch-name: develop
- name: Check formatting
run: yarn nx format:check
- name: Lint affected
run: yarn nx affected:lint --max-warnings=0
- name: Build affected spec
run: yarn nx affected --target=build-spec
test-affected:
timeout-minutes: 30
needs: build-sources
runs-on: ubuntu-22.04
name: 'run unit test of affected apps'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: yarn
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
- name: Derive appropriate SHAs for base and head for `nx affected` commands
uses: nrwl/nx-set-shas@v3
with:
main-branch-name: develop
- name: Test affected
run: yarn nx affected:test
build-sources:
timeout-minutes: 30
needs: lint-format
runs-on: ubuntu-22.04
name: 'Build sources of affected apps'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: yarn
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
- name: Derive appropriate SHAs for base and head for `nx affected` commands
uses: nrwl/nx-set-shas@v3
with:
main-branch-name: develop
# See affected apps
- name: See affected apps
run: |
@@ -97,21 +160,8 @@ jobs:
echo "preview_explorer: ${{ env.PREVIEW_EXPLORER }}"
echo "preview_tools: ${{ env.PREVIEW_TOOLS }}"
- name: Check formatting
run: yarn nx format:check
- name: Lint affected
run: yarn nx affected:lint --max-warnings=0
- name: Build affected spec
run: yarn nx affected --target=build-spec
- name: Test affected
run: yarn nx affected:test
- name: Build affected
run: yarn nx affected:build || (yarn install && yarn nx affected:build)
outputs:
projects: ${{ env.PROJECTS }}
projects-e2e: ${{ env.PROJECTS_E2E }}
@@ -120,39 +170,62 @@ jobs:
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
preview_tools: ${{ env.PREVIEW_TOOLS }}
console-e2e:
needs: lint-test-build
name: '(CI) console python'
uses: ./.github/workflows/console-test-run.yml
secrets: inherit
if: ${{ contains(fromJSON(needs.lint-test-build.outputs.projects), 'trading') && github.event_name == 'pull_request' }}
with:
github-sha: ${{ github.event.pull_request.head.sha || github.sha }}
check-e2e-needed:
runs-on: ubuntu-latest
needs: build-sources
name: '(CI) check if e2e needed'
outputs:
run-tests: ${{ steps.check-test.outputs.e2e-needed }}
steps:
- name: Check branch
id: check-test
run: |
if [[ "${{ github.base_ref }}" == "develop" ]]; then
echo "e2e-needed=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.base_ref }}" == "main" ]]; then
echo "e2e-needed=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/"* ]]; then
echo "e2e-needed=true" >> $GITHUB_OUTPUT
else
echo "e2e-needed=false" >> $GITHUB_OUTPUT
fi
- name: Print result
run: |
echo "e2e-needed: ${{ steps.check-test.outputs.e2e-needed }}"
cypress:
needs: lint-test-build
needs: [build-sources, check-e2e-needed]
name: '(CI) cypress'
# if: ${{ needs.lint-test-build.outputs.projects-e2e != '[]' }}
if: ${{ needs.check-e2e-needed.outputs.run-tests == 'true' }}
uses: ./.github/workflows/cypress-run.yml
secrets: inherit
with:
projects: ${{ needs.lint-test-build.outputs.projects-e2e }}
tags: '@smoke @regression'
projects: ${{ needs.build-sources.outputs.projects-e2e }}
tags: '@smoke'
console-e2e:
needs: [build-sources, check-e2e-needed]
name: '(CI) console python'
uses: ./.github/workflows/console-test-run.yml
secrets: inherit
if: needs.check-e2e-needed.outputs.run-tests == 'true' && contains(needs.build-sources.outputs.projects, 'trading')
with:
github-sha: ${{ github.event.pull_request.head.sha || github.sha }}
publish-dist:
needs: lint-test-build
needs: build-sources
name: '(CD) publish dist'
if: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo') || github.event_name == 'push' }}
uses: ./.github/workflows/publish-dist.yml
secrets: inherit
with:
projects: ${{ needs.lint-test-build.outputs.projects }}
projects: ${{ needs.build-sources.outputs.projects }}
dist-check:
runs-on: ubuntu-latest
needs:
- publish-dist
- lint-test-build
- build-sources
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo' }}
timeout-minutes: 60
name: '(CD) comment preview links'
@@ -168,27 +241,27 @@ jobs:
run: |
# https://stackoverflow.com/questions/3183444/check-for-valid-link-url
regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
if [[ "${{ needs.lint-test-build.outputs.preview_governance }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_governance }}"; do
echo "waiting for governance preview: ${{ needs.lint-test-build.outputs.preview_governance }}"
if [[ "${{ needs.build-sources.outputs.preview_governance }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_governance }}"; do
echo "waiting for governance preview: ${{ needs.build-sources.outputs.preview_governance }}"
sleep 5
done
fi
if [[ "${{ needs.lint-test-build.outputs.preview_explorer }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_explorer }}"; do
echo "waiting for explorer preview: ${{ needs.lint-test-build.outputs.preview_explorer }}"
if [[ "${{ needs.build-sources.outputs.preview_explorer }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_explorer }}"; do
echo "waiting for explorer preview: ${{ needs.build-sources.outputs.preview_explorer }}"
sleep 5
done
fi
if [[ "${{ needs.lint-test-build.outputs.preview_trading }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_trading }}"; do
echo "waiting for trading preview: ${{ needs.lint-test-build.outputs.preview_trading }}"
if [[ "${{ needs.build-sources.outputs.preview_trading }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_trading }}"; do
echo "waiting for trading preview: ${{ needs.build-sources.outputs.preview_trading }}"
sleep 5
done
fi
if [[ "${{ needs.lint-test-build.outputs.preview_tools }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.lint-test-build.outputs.preview_tools }}"; do
echo "waiting for tools preview: ${{ needs.lint-test-build.outputs.preview_tools }}"
if [[ "${{ needs.build-sources.outputs.preview_tools }}" =~ $regex ]]; then
until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_tools }}"; do
echo "waiting for tools preview: ${{ needs.build-sources.outputs.preview_tools }}"
sleep 5
done
fi
@@ -200,10 +273,10 @@ jobs:
issue-number: ${{ github.event.pull_request.number }}
body: |
Previews
* governance: ${{ needs.lint-test-build.outputs.preview_governance }}
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
* tools: ${{ needs.lint-test-build.outputs.preview_tools }}
* governance: ${{ needs.build-sources.outputs.preview_governance }}
* explorer: ${{ needs.build-sources.outputs.preview_explorer }}
* trading: ${{ needs.build-sources.outputs.preview_trading }}
* tools: ${{ needs.build-sources.outputs.preview_tools }}
# Report single result at the end, to avoid mess with required checks in PR
cypress-check:
+29
View File
@@ -0,0 +1,29 @@
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#managing-caches
name: cleanup caches by a branch
on:
pull_request:
types:
- closed
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache
echo "Fetching list of cache key"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
+143 -53
View File
@@ -6,23 +6,37 @@ on:
github-sha:
required: true
type: string
workflow_dispatch:
inputs:
console-test-branch:
type: choice
description: 'main: v0.72.14, develop: v0.73.0-preview7'
options:
- main
- develop
jobs:
run-tests:
name: run-tests
create-docker-image:
name: Create docker image for console-test
runs-on: ubuntu-22.04
timeout-minutes: 25
timeout-minutes: 20
steps:
#----------------------------------------------
# check-out frontend-monorepo
#----------------------------------------------
- name: Checkout console test repo
- name: Checkout frontend-monorepo
uses: actions/checkout@v3
with:
ref: ${{ inputs.github-sha }}
ref: ${{ inputs.github-sha || github.sha }}
#----------------------------------------------
# cache node modules
#----------------------------------------------
- name: setup node
uses: actions/setup-node@v3
with:
node-version: '16'
cache: yarn
- name: Cache node modules
id: cache
uses: actions/cache@v3
@@ -33,15 +47,6 @@ jobs:
restore-keys: |
${{ runner.os }}-cache-node-modules-
#----------------------------------------------
# setup node
#----------------------------------------------
- name: Setup node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
#----------------------------------------------
# install deps if cache missing
#----------------------------------------------
- name: yarn install
@@ -50,23 +55,105 @@ jobs:
#----------------------------------------------
# build trading
#----------------------------------------------
- name: Build affected spec
- name: Build trading app
run: |
yarn env-cmd -f ./apps/trading/.env.stagnet1 yarn nx export trading
DIST_LOCATION=dist/apps/trading/exported
mv $DIST_LOCATION dist-result
tree dist-result
#----------------------------------------------
# run trading server
# export trading app docker image
#----------------------------------------------
- name: Run trading server
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and export to local Docker
id: docker_build
uses: docker/build-push-action@v5
with:
context: .
file: docker/node-outside-docker.Dockerfile
load: true
build-args: |
APP=trading
ENV_NAME=stagnet1
tags: ci/trading:local
outputs: type=docker,dest=/tmp/console-image.tar
- name: Verify docker image created
run: |
docker run -d -p 80:4200 -v $PWD/docker/nginx.conf:/etc/nginx/conf.d/default.conf -v $PWD/dist/apps/trading/exported:/usr/share/nginx/html nginx:1.23-alpine@sha256:6318314189b40e73145a48060bff4783a116c34cc7241532d0d94198fb2c9629
sleep 5
docker ps
#----------------------------------------------
# check if container persists between runs
#----------------------------------------------
- name: Check server
echo ${{ steps.docker_build.outputs.digest }}
echo ${{ steps.docker_build.outputs.imageid }}
- name: Upload docker image for console-test usage
uses: actions/upload-artifact@v3
with:
name: console-image
path: /tmp/console-image.tar
console-test-branch:
name: Choose console-test branch to run on
runs-on: ubuntu-22.04
timeout-minutes: 5
outputs:
console-branch: ${{ steps.output-step.outputs.branch }}
steps:
- name: Workflow dispatch input
id: dispatch-step
if: github.event_name == 'workflow_dispatch'
run: echo "branch=${{ inputs.console-test-branch }}" >> $GITHUB_OUTPUT
- name: Print Workflow dispatch input
if: github.event_name == 'workflow_dispatch'
run: echo ${{ steps.dispatch-step.outputs.branch }}
- name: Workflow_call input
id: workflow_call-step
if: github.event_name != 'workflow_dispatch'
run: |
docker ps
if [[ "${{ github.base_ref }}" == "main" ]]; then
echo "branch=main" >> $GITHUB_OUTPUT
elif [[ "${{ github.base_ref }}" == "develop" && "${{ github.ref_name }}" == "main" ]]; then
echo "branch=main" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/mainnet"* ]]; then
echo "branch=main" >> $GITHUB_OUTPUT
else
echo "branch=develop" >> $GITHUB_OUTPUT
fi
- name: Print Workflow_call input
if: github.event_name != 'workflow_dispatch'
run: echo ${{ steps.workflow_call-step.outputs.branch }}
- name: Set output
id: output-step
run: echo "branch=${{ steps.dispatch-step.outputs.branch || steps.workflow_call-step.outputs.branch }}" >> $GITHUB_OUTPUT
- name: Print final output
run: echo ${{ steps.output-step.outputs.branch }}
run-tests:
name: run-tests
runs-on: 8-cores
needs: [create-docker-image, console-test-branch]
timeout-minutes: 20
steps:
#----------------------------------------------
# load docker image
#----------------------------------------------
- name: Download docker image from previous job
uses: actions/download-artifact@v3
with:
name: console-image
path: /tmp
- name: Load Docker image
run: |
docker load --input /tmp/console-image.tar
docker image ls -a
#----------------------------------------------
# check-out tests repo
#----------------------------------------------
@@ -74,15 +161,24 @@ jobs:
uses: actions/checkout@v3
with:
repository: vegaprotocol/console-test
path: './console-test'
ref: ${{ needs.console-test-branch.outputs.console-branch }}
- name: Load console test envs
id: console-test-env
uses: falti/dotenv-action@v1.0.4
with:
path: '.env.${{ needs.console-test-branch.outputs.console-branch }}'
export-variables: true
keys-case: upper
log-variables: true
#----------------------------------------------
# set-up python
# ----- Setup python -----
#----------------------------------------------
- name: Set up python
id: setup-python
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.10.11'
python-version: '3.10'
#----------------------------------------------
# ----- install & configure poetry -----
#----------------------------------------------
@@ -91,45 +187,29 @@ jobs:
with:
virtualenvs-create: true
virtualenvs-in-project: true
virtualenvs-path: console-test/.venv
virtualenvs-path: .venv
#----------------------------------------------
# load cached venv if cache exists
#----------------------------------------------
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v3
with:
path: console-test/.venv
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
#----------------------------------------------
# install dependencies if cache does not exist
# install python dependencies
#----------------------------------------------
- name: Install dependencies
working-directory: ./console-test
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root
#----------------------------------------------
# install vega binaries
#----------------------------------------------
- name: Install vega binaries
working-directory: ./console-test
run: poetry run python -m vega_sim.tools.load_binaries --force
run: poetry run python -m vega_sim.tools.load_binaries --force --version ${{ env.VEGA_VERSION }}
#----------------------------------------------
# install playwright
#----------------------------------------------
- name: install playwright
run: poetry run playwright install
working-directory: ./console-test
run: poetry run playwright install --with-deps chromium
#----------------------------------------------
# run tests
#----------------------------------------------
- name: Run tests
working-directory: ./console-test
run: poetry run pytest --numprocesses auto
- name: Check files
run: |
ls -al .
ls -al console-test
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 4 --dist loadfile --durations=15
#----------------------------------------------
# upload traces
#----------------------------------------------
@@ -140,3 +220,13 @@ jobs:
name: playwright-trace
path: ./traces/
retention-days: 15
#----------------------------------------------
# ----- upload logs -----
#----------------------------------------------
- name: Upload worker logs
uses: actions/upload-artifact@v3
if: always()
with:
name: worker-logs
path: ./logs/
retention-days: 15
+28 -3
View File
@@ -13,14 +13,36 @@ on:
type: string
jobs:
runner-choice:
runs-on: ubuntu-latest
outputs:
runner: ${{ steps.step.outputs.runner }}
steps:
- name: Check branch
id: step
run: |
if [[ "${{ github.base_ref }}" == "main" ]]; then
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
elif [[ "${{ github.base_ref }}" == "develop" && "${{ github.ref_name }}" == "main" ]]; then
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/mainnet"* ]]; then
echo "runner=mainnet-compatible-runner" >> $GITHUB_OUTPUT
else
echo "runner=self-hosted-runner" >> $GITHUB_OUTPUT
fi
- name: Print runner
run: echo ${{ steps.step.outputs.runner }}
e2e:
strategy:
fail-fast: false
matrix:
project: ${{ fromJSON(inputs.projects) }}
name: ${{ matrix.project }}
runs-on: self-hosted-runner
timeout-minutes: 100
needs: runner-choice
runs-on: ${{ needs.runner-choice.outputs.runner }}
timeout-minutes: 120
steps:
# Checks if skip cache was requested
- name: Set skip-nx-cache flag
@@ -37,6 +59,7 @@ jobs:
# Restore node_modules from cache if possible
- name: Restore node_modules from cache
id: cache-node-modules
uses: actions/cache@v3
with:
path: |
@@ -46,6 +69,7 @@ jobs:
# Install frontend dependencies
- name: Install root dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
working-directory: frontend-monorepo
@@ -61,13 +85,14 @@ jobs:
- name: Run Vegacapsule network and Vega wallet
id: setup-vega
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
timeout-minutes: 10
######
## Run some tests
######
- name: Run Cypress tests
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --browser chrome --env.grepTags="${{ inputs.tags }}"
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --browser chrome --env.grepTags="${{ inputs.tags }}"
working-directory: frontend-monorepo
env:
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
+11 -11
View File
@@ -2,7 +2,12 @@
name: Verify PR title
on:
workflow_call:
pull_request:
types:
- opened
- edited
- reopened
- synchronize
jobs:
lint_pr:
@@ -11,21 +16,16 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
node-version: 16
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
- name: Install dependencies
run: |
rm package.json
npm install --no-save @commitlint/cli @commitlint/config-conventional @commitlint/config-nx-scopes nx
- name: Check PR title
run: echo "${{ github.event.pull_request.title }}" | npx commitlint --config ./commitlint.config-ci.js
+20 -12
View File
@@ -30,12 +30,18 @@ jobs:
echo IS_IPFS_RELEASE=false >> $GITHUB_ENV
echo IS_S3_RELEASE=false >> $GITHUB_ENV
echo IS_DEV_IMAGE=false >> $GITHUB_ENV
echo IS_MAIN_IMAGE=false >> $GITHUB_ENV
- name: Is dev image
if: ${{ contains(github.ref, 'develop') && github.event_name == 'push' && matrix.app == 'trading' }}
if: ${{ github.ref_name == 'develop' && github.event_name == 'push' && matrix.app == 'trading' }}
run: |
echo IS_DEV_IMAGE=true >> $GITHUB_ENV
- name: Is main image
if: ${{ github.ref_name == 'main' && github.event_name == 'push' && matrix.app == 'trading' }}
run: |
echo IS_MAIN_IMAGE=true >> $GITHUB_ENV
- name: Is PR
if: ${{ github.event_name == 'pull_request' }}
run: |
@@ -57,7 +63,7 @@ jobs:
echo IS_IPFS_RELEASE=true >> $GITHUB_ENV
- name: Is S3 Release
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' }}
if: ${{ env.IS_IPFS_RELEASE == 'false' && github.event_name == 'push' && github.ref_name != 'main'}}
run: |
echo IS_S3_RELEASE=true >> $GITHUB_ENV
@@ -81,7 +87,7 @@ jobs:
- name: Log in to the Container registry (docker hub)
uses: docker/login-action@v2
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' }}
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' || env.IS_MAIN_IMAGE == 'true' }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -155,10 +161,10 @@ jobs:
- name: Sanity check docker image
run: |
echo "Check ipfs-hash"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matrix.app }}-ipfs-hash
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local /bin/sh -c 'cat /ipfs-hash'
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local /bin/sh -c 'cat /ipfs-hash' > ${{ matrix.app }}-ipfs-hash
echo "List html directory"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local /bin/sh -c 'apk add --update tree; tree /usr/share/nginx/html'
- name: Publish dist as docker image (ghcr)
uses: docker/build-push-action@v3
@@ -179,7 +185,7 @@ jobs:
uses: docker/build-push-action@v3
continue-on-error: true
id: dockerhub-push
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' }}
if: ${{ env.IS_IPFS_RELEASE == 'true' || env.IS_DEV_IMAGE == 'true' || env.IS_MAIN_IMAGE == 'true' }}
with:
context: .
file: docker/node-outside-docker.Dockerfile
@@ -189,7 +195,7 @@ jobs:
ENV_NAME=${{ env.ENV_NAME }}
tags: |
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || '' }}
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true' && 'main' || '' }}
- name: Publish dist as docker image (ghcr - retry)
uses: docker/build-push-action@v3
@@ -216,7 +222,7 @@ jobs:
ENV_NAME=${{ env.ENV_NAME }}
tags: |
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || '' }}
vegaprotocol/${{ matrix.app }}:${{ env.IS_MAINNET_RELEASE == 'true' && 'mainnet' || env.IS_TESTNET_RELEASE == 'true' && 'testnet' || env.IS_DEV_IMAGE == 'true' && 'develop' || env.IS_MAIN_IMAGE == 'true' && 'main' || '' }}
# bucket creation in github.com/vegaprotocol/terraform//frontend
- name: Publish dist to s3
@@ -329,7 +335,9 @@ jobs:
fi
# create commit
commit_msg="Automated hash update from ${{ github.ref }}"
git commit -m "$commit_msg"
git push -u origin "main"
if ! git diff --cached --exit-code; then
commit_msg="Automated hash update from ${{ github.ref }}"
git commit -m "$commit_msg"
git push -u origin "main"
fi
)
+1
View File
@@ -15,6 +15,7 @@ on:
- types
- utils
- i18n
- wallet
jobs:
publish:
-3
View File
@@ -3,6 +3,3 @@
# Lint commit messages to ensure they follow conventional commit standards
yarn commitlint --edit "${1}"
# Lint all staged files
yarn lint-staged
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Lint all staged files
yarn lint-staged
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Lint all staged files
yarn nx format:check
# Test all projects with changes
yarn nx affected -t test --exclude trading
+1 -1
View File
@@ -1 +1 @@
16.15.1
16.20.2
+1
View File
@@ -1,2 +1,3 @@
* @vegaprotocol/frontend
* @vegaprotocol/frontend-qa
*.graphql @vegaprotocol/core
+1 -1
View File
@@ -11,7 +11,7 @@ recalculate-ipfs:
echo "ipfs hash inside the image"
docker run --rm ${TAG} cat /ipfs-hash
echo "recalculating ipfs hash"
docker run --rm ${TAG} ipfs add -r /usr/share/nginx/html
docker run --rm ${TAG} ipfs add -rQ /usr/share/nginx/html
.PHONY: eject-ipfs-hash
unpack:
+39 -25
View File
@@ -113,13 +113,47 @@ In order to run a container on port 3000:
docker run -p 3000:80 [TAG]
```
On top of that there are two possible scenarios for running docker image - using nginx server (default) of ipfs daemon.
to run ipfs on port 3000:
```bash
docker run -p 3000:80 [TAG] /run-ipfs.sh
```
to run nginx on port 3000:
```bash
docker run -p 3000:80 [TAG]
```
## Build instructions
The [`docker`](./docker) subfolder has some docker configurations for easily setting up your own hosted version of console either for the web, or ready for pinning on IPFS
The [`docker`](./docker) subfolder has some docker configurations for easily setting up your own hosted version of Console either for the web, or ready for pinning on IPFS.
### nx build inside the docker
Using multistage dockerfile dist is compiled using [node](https://hub.docker.com/_/node) image and later packed to nginx as in [dist build](#dist-build). The multistage builds ensures consistent CPU architecture and build toolchains are used so that the result will be identical.
```bash
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=16.5.1 --build-arg ENV_NAME=mainnet -t [TAG] -f docker/node-inside-docker.Dockerfile .
```
### Computing ipfs-hash of the build
At the moment this feature is important only for Console releases.
Each docker build finishes with hash calculation for ` dist`` directory. Resulting hash is added to file named as `/ipfs-hash`. Once docker image is produced you can run following commad to display ipfs-hash:
```bash
make recalculate-ipfs TAG=vegaprotocol/trading:{YOUR_VERSION}
```
**updating hash:** recompiling dist directory (even if there are no changed to source code) results in different hash computed by ipfs command.
### nx build outside the docker
Packaging prepared dist into [`nginx`](https://hub.docker.com/_/nginx)([server configuration](./nginx/nginx.conf)) docker image involves building the application on docker host machine from source.
This Docker image packages a pre-built `dist` folder into an [`nginx`](https://hub.docker.com/_/nginx)([server configuration](./nginx/nginx.conf)) docker image. In this case, the application on docker host machine from source.
As a prerequisite you need to perform build of `dist` directory and move its content for specific application to `dist-result` directory. Use following script to do it with a single command:
@@ -130,41 +164,21 @@ As a prerequisite you need to perform build of `dist` directory and move its con
You can build any of the containers locally with the following command:
```bash
docker build --dockerfile docker/node-outside-docker.Dockerfile . --tag=[TAG]
docker build -f docker/node-outside-docker.Dockerfile . --tag=[TAG]
```
### nx build inside the docker
Using multistage dockerfile dist is compiled using [node](https://hub.docker.com/_/node) image and later packed to nginx as in [dist build](#dist-build) example.
```bash
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=$(cat .nvmrc) --build-arg ENV_NAME=mainnet -t [TAG] -f docker/node-inside-docker.Dockerfile .
```
### Computing ipfs-hash of the build
At the moment this feature is important only for `trading` (console) releases.
Each docker build finishes with hash calculation for dist directory. Resulting hash is added to file named as `/ipfs-hash`. Once docker image is produced you can run following commad to display ipfs-hash:
```bash
make recalculate-ipfs TAG=vegaprotocol/trading:{YOUR_VERSION}
```
**updating hash:** recompiling dist directory (even if there are no changed to source code) results in different hash computed by ipfs command.
### Verifying ipfs-hash of existing current application version
An IPFS CID will be attached to every [release](https://github.com/vegaprotocol/frontend-monorepo/releases). If you are intending to pin an application on IPFS, you can check that your build matches by running the following steps:
1. Show latest release by runnning: `make latest-release`. You need to configure [`gh`](https://cli.github.com/) for this step to work, otherwise please provide release manually from [github](https://github.com/vegaprotocol/frontend-monorepo/releases) or [dockerhub](https://hub.docker.com/r/vegaprotocol/trading)
1. Show latest release by running: `make latest-release`. You need to configure [`gh`](https://cli.github.com/) for this step to work, otherwise please provide release manually from [github](https://github.com/vegaprotocol/frontend-monorepo/releases) or [dockerhub](https://hub.docker.com/r/vegaprotocol/trading)
2. Set RELEASE environment variable to value that you want to validate: `export RELEASE=$(make latest-release)` or `export RELEASE=vXX.XX.XX`
3. Set TAG environment variable to image that you want to validate: `export TAG=vegaprotocol/trading:$RELEASE`
4. Download docker image with the desired release `docker pull $TAG`.
5. Recalculate hash: `make recalculate-ipfs`
6. You should see exactly same hash produced by ipfs command as one placed with the release notes: `make show-latest-release`
7. If you want to extract dist from docker image to your local filesystem you can run following command: `make unpack`
8. Now `dist` directory contains valid application build. **it is not possible to calculate same ipfs hash on files that are result of copy operation**
8. Now `dist` directory contains valid application build
## Config
+2
View File
@@ -4,6 +4,8 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
NX_VEGA_ENV=DEVNET
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
# App flags
NX_EXPLORER_ASSETS=1
+1
View File
@@ -4,6 +4,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocke
NX_VEGA_URL=https://api.vega.community/graphql
NX_VEGA_ENV=MAINNET
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
# App flags
NX_EXPLORER_ASSETS=1
+1
View File
@@ -4,6 +4,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
NX_VEGA_ENV=TESTNET
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
# App flags
NX_EXPLORER_ASSETS=1
+1
View File
@@ -23,6 +23,7 @@ module.exports = defineConfig({
viewportWidth: 1440,
viewportHeight: 900,
testIsolation: false,
experimentalMemoryManagement: true,
},
env: {
environment: 'CUSTOM',
@@ -0,0 +1,26 @@
{
"proposalSubmission": {
"rationale": {
"title": "Test new asset proposal",
"description": "E2E test for proposals"
},
"terms": {
"newAsset": {
"changes": {
"name": "USDT Coin",
"symbol": "USDT",
"decimals": "18",
"quantum": "1",
"erc20": {
"contractAddress": "0xb404c51bbc10dcbe948077f18a4b8e553d160084",
"withdrawThreshold": "10",
"lifetimeLimit": "10"
}
}
},
"closingTimestamp": 1724339572,
"enactmentTimestamp": 1724339572,
"validationTimestamp": 1692799617
}
}
}
+49 -10
View File
@@ -1,8 +1,8 @@
import { createSuccessorMarketProposal } from '../support/governance.functions';
context('Market page', { tags: '@regression' }, function () {
describe('Verify elements on page', function () {
const marketHeaders = 'markets-heading';
const createdMarketId =
'2eab0e66545a789047561bc5a2e5cbc3b19eb708da41104e3cac2474ee36c4d4';
before('Create market', function () {
cy.visit('/');
@@ -11,7 +11,7 @@ context('Market page', { tags: '@regression' }, function () {
beforeEach('Get market id', function () {
cy.navigate_to('markets');
cy.get('[col-id="id"]').eq(1).invoke('text').as('createdMarketId');
cy.get('[col-id="id"]').last().invoke('text').as('createdMarketId');
});
it('Market displayed on market page', function () {
@@ -36,7 +36,7 @@ context('Market page', { tags: '@regression' }, function () {
it('Able to go to market details page', function () {
cy.navigate_to('markets');
cy.get_element_by_col_id('actions').eq(1).click();
cy.contains('Test market 1').click();
cy.getByTestId(marketHeaders).should('have.text', 'Test market 1');
cy.validate_element_from_table('Name', 'Test market 1');
cy.validate_element_from_table('Market ID', this.createdMarketId);
@@ -87,15 +87,13 @@ context('Market page', { tags: '@regression' }, function () {
// Liquidity
cy.validate_element_from_table('Target Stake', '0.00 fUSDC');
cy.validate_element_from_table('Supplied Stake', '0.00 fUSDC');
cy.validate_element_from_table('Market Value Proxy', '0.00 fUSDC');
// Liquidity price range
cy.validate_element_from_table(
'Liquidity Price Range',
'1,000.00% of mid price'
'95.00% of mid price'
);
cy.validate_element_from_table('Lowest Price', '0.00 fUSDC');
cy.validate_element_from_table('Highest Price', '0.00 fUSDC');
cy.getByTestId('oracle-spec-links')
.should('have.attr', 'href')
.and(
@@ -106,6 +104,7 @@ context('Market page', { tags: '@regression' }, function () {
// Able to view Json
cy.contains('View JSON').click();
cy.get('.language-json').should('exist');
cy.getByTestId('icon-cross').click();
});
// Skipping due to resize observer loop limit error
@@ -113,17 +112,57 @@ context('Market page', { tags: '@regression' }, function () {
cy.common_switch_to_mobile_and_click_toggle();
cy.navigate_to('markets', true);
cy.getByTestId(marketHeaders).should('be.visible');
cy.get(`[row-id="${createdMarketId}"]`)
cy.get(`[row-id="${this.createdMarketId}"]`)
.should('be.visible')
.within(() => {
cy.get_element_by_col_id('code').should('have.text', 'TEST.24h');
cy.get_element_by_col_id('name').should('have.text', 'Test market 1');
cy.get_element_by_col_id('state').should('have.text', 'Pending');
cy.get_element_by_col_id('asset').should('have.text', 'fUSDC');
cy.get_element_by_col_id('id').should('have.text', createdMarketId);
cy.get_element_by_col_id('id').should(
'have.text',
this.createdMarketId
);
cy.get_element_by_col_id('actions')
.find('a')
.should('have.attr', 'href', `/markets/${createdMarketId}`);
.should('have.attr', 'href', `/markets/${this.createdMarketId}`);
});
});
it('Able to go to market details page for successor market', function () {
const successionLineItem = 'succession-line-item';
const successionLineMarketId = 'succession-line-item-market-id';
createSuccessorMarketProposal(this.createdMarketId);
cy.navigate_to('markets');
cy.reload();
cy.contains('Token test market', { timeout: 8000 }).should('be.visible');
cy.get('[row-index="0"]')
.invoke('attr', 'row-id')
.as('successorMarketId');
cy.contains('Token test market').click();
cy.getByTestId(marketHeaders).should('have.text', 'Token test market');
cy.validate_element_from_table('Triggering Ratio', '0.7');
cy.validate_element_from_table('Time Window', '3,600');
cy.validate_element_from_table('Scaling Factor', '10');
cy.getByTestId(successionLineItem)
.first()
.within(() => {
cy.contains('Test market 1');
cy.getByTestId(successionLineMarketId).should(
'have.text',
this.createdMarketId
);
});
cy.getByTestId(successionLineItem)
.eq(1)
.within(() => {
cy.contains('Token test market');
cy.getByTestId(successionLineMarketId).should(
'have.text',
this.successorMarketId
);
});
});
});
@@ -1,12 +1,9 @@
context('Network parameters page', { tags: '@smoke' }, function () {
before('navigate to network parameter page', function () {
cy.fixture('net_parameter_format_lookup').as('networkParameterFormat');
cy.visit('/network-parameters');
});
describe('Verify elements on page', function () {
beforeEach(() => {
cy.visit('/network-parameters');
});
const networkParametersHeader = '[data-testid="network-param-header"]';
const tableRows = '[data-testid="key-value-table-row"]';
@@ -16,6 +13,7 @@ context('Network parameters page', { tags: '@smoke' }, function () {
.and('be.visible');
});
// 0006-NETW-021
it('should list each of the network parameters available', function () {
cy.get_network_parameters().then((network_parameters) => {
const numberOfNetworkParametersInSystem =
@@ -198,6 +196,19 @@ context('Network parameters page', { tags: '@smoke' }, function () {
});
});
// 0006-NETW-022 0006-NETW-023
it('governance assets should be correctly grouped', function () {
cy.getByTestId('governance')
.should('exist')
.parent()
.should('have.attr', 'href', '/network-parameters#governance');
cy.get('[id="governance-proposal-asset"]')
.parent()
.within(() => {
cy.getByTestId('key-value-table-row').should('have.length', 8);
});
});
it('should be able to see network parameters - on mobile', function () {
cy.switchToMobile();
cy.get_network_parameters().then((network_parameters) => {
@@ -40,7 +40,7 @@ context.skip('Node switcher', { tags: '@regression' }, function () {
const errorTypeTxt = 'Error: invalid url';
const nodeErrorTxt = 'fakeUrl is not a valid url.';
cy.getByTestId('node-url-custom').click();
cy.getByTestId('node-url-custom').click({ force: true });
cy.getByTestId(customNodeBtn).within(() => {
cy.get('input').clear().type('fakeUrl');
@@ -0,0 +1,68 @@
context('Oracle page', { tags: '@smoke' }, () => {
describe('Verify elements on page', () => {
before('create market and navigate to oracle page', () => {
cy.createMarket();
cy.visit('/oracles');
});
it('should see oracle data', () => {
cy.getByTestId('oracle-details').should('have.length.at.least', 2);
cy.getByTestId('oracle-details')
.should('exist')
.eq(0)
.within(() => {
cy.get('tr')
.eq(0)
.within(() => {
cy.get('th').should('have.text', 'ID');
cy.get('a').invoke('text').should('have.length', 64);
cy.get('a')
.should('have.attr', 'href')
.and('contain', '/oracles/');
});
cy.get('tr')
.eq(1)
.within(() => {
cy.get('th').should('have.text', 'Type');
cy.get('td').should('have.text', 'External data');
});
cy.get('tr')
.eq(2)
.within(() => {
cy.get('th').should('have.text', 'Signer');
cy.getByTestId('keytype').should('have.text', 'Vega');
cy.get('a').invoke('text').should('have.length', 64);
cy.get('a')
.should('have.attr', 'href')
.and('contain', '/parties/');
});
cy.get('tr')
.eq(3)
.within(() => {
cy.get('th').should('have.text', 'Settlement for');
cy.get('a').invoke('text').should('have.length', 64);
cy.get('a')
.should('have.attr', 'href')
.and('contain', '/markets/');
});
cy.get('tr')
.eq(4)
.within(() => {
cy.get('th').should('have.text', 'Matched data');
cy.get('td').should('have.text', '❌');
});
cy.get('details')
.eq(0)
.within(() => {
cy.contains('Filter').click();
cy.get('.language-json').should('exist');
});
cy.get('details')
.eq(1)
.within(() => {
cy.contains('JSON').click();
cy.get('.language-json').should('exist');
});
});
});
});
});
@@ -1,9 +1,10 @@
import { getNewAssetTxBody } from '../support/governance.functions';
context('Proposal page', { tags: '@smoke' }, function () {
describe('Verify elements on page', function () {
const proposalHeading = 'proposals-heading';
const dateTimeRegex =
/(\d{1,2})\/(\d{1,2})\/(\d{4}), (\d{1,2}):(\d{1,2}):(\d{1,2})/gm;
const proposalTitle = 'Add Lorem Ipsum market';
before('Create market proposal', function () {
cy.visit('/');
@@ -11,30 +12,41 @@ context('Proposal page', { tags: '@smoke' }, function () {
});
it('Able to view proposal', function () {
const proposalTitle = 'Add Lorem Ipsum market';
cy.navigate_to('governanceProposals');
cy.getByTestId(proposalHeading).should('be.visible');
// get first proposal in list
cy.get('[row-index="0"]').within(() => {
cy.get_element_by_col_id('title').should('have.text', proposalTitle);
cy.get_element_by_col_id('type').should('have.text', 'NewMarket');
cy.get_element_by_col_id('state').should('have.text', 'Enacted');
cy.getByTestId('vote-progress').should('be.visible');
cy.get('[col-id="cDate"]')
.invoke('text')
.should('match', dateTimeRegex);
cy.get('[col-id="eDate"]')
.invoke('text')
.should('match', dateTimeRegex);
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and('contains', 'https://governance.fairground.wtf/proposals/');
cy.contains('View terms').should('exist').click();
});
cy.contains(proposalTitle)
.parent()
.parent()
.parent()
.within(() => {
cy.get_element_by_col_id('title').should('have.text', proposalTitle);
cy.get_element_by_col_id('type').should('have.text', 'NewMarket');
cy.get_element_by_col_id('state').should('have.text', 'Enacted');
cy.getByTestId('vote-progress').should('be.visible');
cy.getByTestId('vote-progress-bar-for')
.invoke('attr', 'style')
.should('eq', 'width: 100%;');
cy.get('[col-id="cDate"]')
.invoke('text')
.should('match', dateTimeRegex);
cy.get('[col-id="eDate"]')
.invoke('text')
.should('match', dateTimeRegex);
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and('contains', 'https://governance.fairground.wtf/proposals/');
cy.contains('View terms').should('exist').click();
});
cy.getByTestId('dialog-title').should('have.text', proposalTitle);
cy.get('.language-json').should('exist');
cy.getByTestId('icon-cross').click();
});
it('Proposal page displayed on mobile', function () {
it.skip('Proposal page displayed on mobile', function () {
const proposalTitle = 'Add Lorem Ipsum market';
cy.common_switch_to_mobile_and_click_toggle();
cy.navigate_to('governanceProposals', true);
cy.getByTestId(proposalHeading).should('be.visible');
@@ -42,5 +54,40 @@ context('Proposal page', { tags: '@smoke' }, function () {
cy.get_element_by_col_id('title').should('have.text', proposalTitle);
});
});
it('Able to view new asset proposal', function () {
const proposalTitle = 'Test new asset proposal';
const newAssetProposalBody = getNewAssetTxBody();
cy.VegaWalletSubmitProposal(newAssetProposalBody);
cy.visit('/');
cy.navigate_to('governanceProposals');
cy.contains(proposalTitle)
.parent()
.parent()
.parent()
.within(() => {
cy.get_element_by_col_id('title').should('have.text', proposalTitle);
cy.get_element_by_col_id('type').should('have.text', 'NewAsset');
cy.get_element_by_col_id('state').should(
'have.text',
'Waiting for Node Vote'
);
cy.getByTestId('vote-progress').should('be.visible');
cy.getByTestId('vote-progress-bar-against')
.invoke('attr', 'style')
.should('eq', 'width: 100%;');
cy.get('[col-id="cDate"]')
.invoke('text')
.should('match', dateTimeRegex);
cy.get('[col-id="eDate"]')
.invoke('text')
.should('match', dateTimeRegex);
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and('contains', 'https://governance.fairground.wtf/proposals/');
cy.contains('View terms').should('exist').click();
});
});
});
});
@@ -127,3 +127,10 @@ Cypress.Commands.add(
.should('have.text', tableRowValue);
}
);
Cypress.Commands.add(
'validate_proposal_change_type',
(tableRowName, changeType) => {
cy.contains(tableRowName).siblings().should('have.text', changeType);
}
);
@@ -0,0 +1,186 @@
import { addSeconds, millisecondsToSeconds } from 'date-fns';
export function createSuccessorMarketProposal(parentMarketId) {
cy.VegaWalletSubmitProposal(getSuccessorTxBody(parentMarketId));
}
function getSuccessorTxBody(parentMarketId) {
const MIN_CLOSE_SEC = 500;
const MIN_ENACT_SEC = 700;
const closingDate = addSeconds(new Date(), MIN_CLOSE_SEC);
const enactmentDate = addSeconds(closingDate, MIN_ENACT_SEC);
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
const enactmentTimestamp = millisecondsToSeconds(enactmentDate.getTime());
return {
proposalSubmission: {
rationale: {
title: 'Test successor market proposal details',
description: 'E2E test for successor market',
},
terms: {
newMarket: {
changes: {
decimalPlaces: '5',
positionDecimalPlaces: '5',
linearSlippageFactor: '0.001',
quadraticSlippageFactor: '0',
instrument: {
name: 'Token test market',
code: 'TEST.24h',
future: {
settlementAsset:
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc',
quoteName: 'fUSDC',
dataSourceSpecForSettlementData: {
external: {
oracle: {
signers: [
{
pubKey: {
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
},
},
],
filters: [
{
key: {
name: 'prices.BTC.value',
type: 'TYPE_INTEGER',
numberDecimalPlaces: '0',
},
conditions: [
{
operator: 'OPERATOR_GREATER_THAN',
value: '0',
},
],
},
],
},
},
},
dataSourceSpecForTradingTermination: {
external: {
oracle: {
signers: [
{
pubKey: {
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
},
},
],
filters: [
{
key: {
name: 'trading.terminated.ETH5',
type: 'TYPE_BOOLEAN',
},
conditions: [
{
operator: 'OPERATOR_EQUALS',
value: 'true',
},
],
},
],
},
},
},
dataSourceSpecBinding: {
settlementDataProperty: 'prices.BTC.value',
tradingTerminationProperty: 'trading.terminated.ETH5',
},
},
},
metadata: [
'sector:food',
'sector:materials',
'source:docs.vega.xyz',
],
priceMonitoringParameters: {
triggers: [
{
horizon: '43200',
probability: '0.9999999',
auctionExtension: '600',
},
],
},
liquidityMonitoringParameters: {
targetStakeParameters: {
timeWindow: '3600',
scalingFactor: 10,
},
triggeringRatio: '0.7',
auctionExtension: '1',
},
logNormal: {
tau: 0.0001140771161,
riskAversionParameter: 0.01,
params: {
mu: 0,
r: 0.016,
sigma: 0.5,
},
},
successor: {
parentMarketId: parentMarketId,
insurancePoolFraction: '0.75',
},
liquiditySlaParameters: {
priceRange: '0.95',
commitmentMinTimeFraction: '0.5',
performanceHysteresisEpochs: 2,
slaCompetitionFactor: '0.75',
},
},
},
closingTimestamp,
enactmentTimestamp,
},
},
};
}
export function getNewAssetTxBody() {
const MIN_CLOSE_SEC = 500;
const MIN_ENACT_SEC = 700;
const MIN_VALID_SEC = 60;
const closingDate = addSeconds(new Date(), MIN_CLOSE_SEC);
const enactmentDate = addSeconds(closingDate, MIN_ENACT_SEC);
const validationDate = addSeconds(new Date(), MIN_VALID_SEC);
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
const enactmentTimestamp = millisecondsToSeconds(enactmentDate.getTime());
const validationTimestamp = millisecondsToSeconds(validationDate.getTime());
return {
proposalSubmission: {
rationale: {
title: 'Test new asset proposal',
description: 'E2E test for proposals',
},
terms: {
newAsset: {
changes: {
name: 'USDT Coin',
symbol: 'USDT',
decimals: '18',
quantum: '1',
erc20: {
contractAddress: '0xb404c51bbc10dcbe948077f18a4b8e553d160084',
withdrawThreshold: '10',
lifetimeLimit: '10',
},
},
},
closingTimestamp,
enactmentTimestamp,
validationTimestamp,
},
},
};
}
+4 -2
View File
@@ -1,10 +1,12 @@
# App configuration variables
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
NX_VEGA_ENV=CUSTOM
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
NX_VEGA_EXPLORER_URL=/
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
# App flags
NX_EXPLORER_TXS_LIST=0
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
+4 -2
View File
@@ -1,6 +1,4 @@
# App configuration variables
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
NX_VEGA_ENV=DEVNET
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
@@ -10,3 +8,7 @@ NX_VEGA_URL=https://api.devnet1.vega.xyz/graphql
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_EXPLORER_URL=/
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
+4 -2
View File
@@ -1,6 +1,4 @@
# App configuration variables
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
NX_SENTRY_DSN=https://b3a56b03eda842faad731f3ea9dfd1bc@o286262.ingest.sentry.io/6242427
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
NX_VEGA_URL=https://api.vega.community/graphql
@@ -11,3 +9,7 @@ NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
+5 -3
View File
@@ -1,6 +1,4 @@
# App configuration variables
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/mainnet-mirror/vegawallet-mainnet-mirror.toml
NX_VEGA_URL=https://api.mainnet-mirror.vega.rocks/graphql
@@ -10,4 +8,8 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_VEGA_GOVERNANCE_URL=https://governance.mainnet-mirror.vega.rocks
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.mainnet-mirror.vega.rocks/
NX_VEGA_CONSOLE_URL=https://console.mainnet-mirror.vega.rocks
NX_VEGA_CONSOLE_URL=https://console.mainnet-mirror.vega.rocks
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
+1
View File
@@ -1,2 +1,3 @@
# .env is stagnet1, so there are no overrides required
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET1":"https://stagnet1.explorer.vega.xyz"}'
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
+4 -2
View File
@@ -1,7 +1,5 @@
# App configuration variables
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
NX_VEGA_ENV=TESTNET
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
@@ -11,3 +9,7 @@ NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
+4 -2
View File
@@ -7,9 +7,11 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
NX_VEGA_GOVERNANCE_URL=https://governance.validators-testnet.vega.rocks
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
+2 -1
View File
@@ -5,4 +5,5 @@ NX_VEGA_ENV=CUSTOM
NX_BLOCK_EXPLORER=
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
NX_VEGA_EXPLORER_URL=/
NX_VEGA_EXPLORER_URL=/
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
+1 -1
View File
@@ -77,7 +77,7 @@
"executor": "nx:run-commands",
"options": {
"commands": [
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/spec-update-v0.72.0-preview.2/specs/v0.72.0-preview.2/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.72.3/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
]
}
},
@@ -4,7 +4,7 @@ import { AssetTypeMapping, AssetStatusMapping } from '@vegaprotocol/assets';
import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGrid } from '@vegaprotocol/datagrid';
import type { VegaICellRendererParams } from '@vegaprotocol/datagrid';
import { useRef, useLayoutEffect } from 'react';
import { BREAKPOINT_MD } from '../../config/breakpoints';
@@ -23,7 +23,7 @@ export const Footer = () => {
);
return (
<footer className="grid grid-rows-2 lg:grid-cols-[1fr_auto] text-xs md:text-md lg:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
<footer className="grid grid-cols-[1fr_auto] items-center text-xs md:text-md lg:flex md:col-span-2 px-4 pt-2 pb-3 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
<div className="flex justify-between gap-2 align-middle">
{GIT_COMMIT_HASH && (
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
@@ -43,9 +43,12 @@ export const Footer = () => {
</div>
)}
<div className="content-center flex pl-2 md:border-r border-neutral-700 dark:border-neutral-300 pr-4">
{VEGA_URL && <NodeUrl url={VEGA_URL} />}
<Link className="ml-2" onClick={() => setNodeSwitcherOpen(true)}>
<div className="content-center flex pr-4 md:border-r border-neutral-700 dark:border-neutral-300">
<span className="pr-2">{VEGA_URL && <NodeUrl url={VEGA_URL} />}</span>
<Link
className="ml-2 underline-offset-4"
onClick={() => setNodeSwitcherOpen(true)}
>
{t('Change')}
</Link>
</div>
@@ -59,7 +62,10 @@ export const Footer = () => {
) : null}
</div>
<div className="pl-2 align-center lg:align-right lg:flex lg:justify-end gap-2 align-middle lg:max-w-xs lg:ml-auto">
<RouteLink to={`/${Routes.DISCLAIMER}`} className="underline">
<RouteLink
to={`/${Routes.DISCLAIMER}`}
className="underline underline-offset-4"
>
Disclaimer
</RouteLink>
</div>
@@ -13,6 +13,12 @@ query ExplorerMarket($id: ID!) {
decimals
}
}
... on Perpetual {
quoteName
settlementAsset {
decimals
}
}
}
}
}
@@ -8,7 +8,7 @@ export type ExplorerMarketQueryVariables = Types.Exact<{
}>;
export type ExplorerMarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', decimals: number } } } } } | null };
export type ExplorerMarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', decimals: number } } | { __typename?: 'Perpetual', quoteName: string, settlementAsset: { __typename?: 'Asset', decimals: number } } | { __typename?: 'Spot' } } } } | null };
export const ExplorerMarketDocument = gql`
@@ -27,6 +27,12 @@ export const ExplorerMarketDocument = gql`
decimals
}
}
... on Perpetual {
quoteName
settlementAsset {
decimals
}
}
}
}
}
@@ -61,6 +61,7 @@ describe('Market link component', () => {
instrument: {
name: 'test-label',
product: {
__typename: 'Future',
quoteName: 'dai',
},
},
@@ -1,34 +1,41 @@
import { t } from '@vegaprotocol/i18n';
import type { MarketInfoWithData } from '@vegaprotocol/markets';
import { PriceMonitoringBoundsInfoPanel } from '@vegaprotocol/markets';
import {
LiquidityPriceRangeInfoPanel,
LiquiditySLAParametersInfoPanel,
MarginScalingFactorsPanel,
PriceMonitoringBoundsInfoPanel,
SuccessionLineInfoPanel,
getDataSourceSpecForSettlementData,
getDataSourceSpecForTradingTermination,
} from '@vegaprotocol/markets';
import {
LiquidityInfoPanel,
LiquidityMonitoringParametersInfoPanel,
InstrumentInfoPanel,
KeyDetailsInfoPanel,
LiquidityPriceRangeInfoPanel,
MetadataInfoPanel,
OracleInfoPanel,
RiskFactorsInfoPanel,
RiskModelInfoPanel,
RiskParametersInfoPanel,
SettlementAssetInfoPanel,
} from '@vegaprotocol/markets';
import { MarketInfoTable } from '@vegaprotocol/markets';
import type { DataSourceDefinition } from '@vegaprotocol/types';
import type { DataSourceFragment } from '@vegaprotocol/markets';
import isEqual from 'lodash/isEqual';
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
if (!market) return null;
const { product } = market.tradableInstrument.instrument;
const settlementDataSource = getDataSourceSpecForSettlementData(product);
const terminationDataSource = getDataSourceSpecForTradingTermination(product);
const settlementData = market.tradableInstrument.instrument.product
.dataSourceSpecForSettlementData.data as DataSourceDefinition;
const terminationData = market.tradableInstrument.instrument.product
.dataSourceSpecForTradingTermination.data as DataSourceDefinition;
const getSigners = (data: DataSourceDefinition) => {
const getSigners = ({ data }: DataSourceFragment) => {
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
const signers = data.sourceType.sourceType.signers || [];
const signers =
('signers' in data.sourceType.sourceType &&
data.sourceType.sourceType.signers) ||
[];
return signers.map(({ signer }, i) => {
return (
@@ -40,10 +47,13 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
return [];
};
const showTwoOracles = isEqual(
getSigners(settlementData),
getSigners(terminationData)
);
const showTwoOracles =
settlementDataSource &&
terminationDataSource &&
isEqual(
getSigners(settlementDataSource),
getSigners(terminationDataSource)
);
const headerClassName = 'font-alpha calt text-xl mt-4 border-b-2 pb-2';
@@ -59,8 +69,8 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
<MetadataInfoPanel market={market} />
<h2 className={headerClassName}>{t('Risk model')}</h2>
<RiskModelInfoPanel market={market} />
<h2 className={headerClassName}>{t('Risk parameters')}</h2>
<RiskParametersInfoPanel market={market} />
<h2 className={headerClassName}>{t('Margin scaling factors')}</h2>
<MarginScalingFactorsPanel market={market} />
<h2 className={headerClassName}>{t('Risk factors')}</h2>
<RiskFactorsInfoPanel market={market} />
{(market.data?.priceMonitoringBounds || []).map((trigger, i) => (
@@ -86,10 +96,12 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
)}
<h2 className={headerClassName}>{t('Liquidity monitoring')}</h2>
<LiquidityMonitoringParametersInfoPanel market={market} />
<h2 className={headerClassName}>{t('Liquidity')}</h2>
<LiquidityInfoPanel market={market} />
<h2 className={headerClassName}>{t('Liquidity price range')}</h2>
<LiquidityPriceRangeInfoPanel market={market} />
<h2 className={headerClassName}>{t('Liquidity SLA protocol')}</h2>
<LiquiditySLAParametersInfoPanel market={market} />
<h2 className={headerClassName}>{t('Liquidity')}</h2>
<LiquidityInfoPanel market={market} />
{showTwoOracles ? (
<>
<h2 className={headerClassName}>{t('Settlement oracle')}</h2>
@@ -103,6 +115,8 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
<OracleInfoPanel market={market} type="settlementData" />
</>
)}
<h2 className={`${headerClassName} mb-4`}>{t('Succession line')}</h2>
<SuccessionLineInfoPanel market={market} />
</div>
);
};
@@ -1,10 +1,10 @@
import { useMemo } from 'react';
import type { MarketFieldsFragment } from '@vegaprotocol/markets';
import { getAsset, type MarketFieldsFragment } from '@vegaprotocol/markets';
import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import type { AgGridReact } from 'ag-grid-react';
import type { ColDef } from 'ag-grid-community';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGrid } from '@vegaprotocol/datagrid';
import type {
VegaICellRendererParams,
VegaValueGetterParams,
@@ -73,8 +73,7 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
MarketFieldsFragment,
'tradableInstrument.instrument.product.settlementAsset.symbol'
>) => {
const value =
data?.tradableInstrument.instrument.product.settlementAsset;
const value = data && getAsset(data);
return value ? (
<ButtonLink
onClick={(e) => {
@@ -31,6 +31,9 @@ fragment ExplorerDeterministicOrderFields on Order {
... on Future {
quoteName
}
... on Perpetual {
quoteName
}
}
}
}
@@ -0,0 +1,25 @@
fragment ExplorerStopOrderFields on StopOrder {
id
status
createdAt
trigger {
... on StopOrderPrice {
price
}
... on StopOrderTrailingPercentOffset {
trailingPercentOffset
}
}
createdAt
ocoLinkId
triggerDirection
order {
id
}
}
query ExplorerStopOrder($stopOrderId: ID!) {
stopOrder(id: $stopOrderId) {
...ExplorerStopOrderFields
}
}
@@ -3,7 +3,7 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerDeterministicOrderFieldsFragment = { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } };
export type ExplorerDeterministicOrderFieldsFragment = { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } | { __typename?: 'Perpetual', quoteName: string } | { __typename?: 'Spot' } } } } };
export type ExplorerDeterministicOrderQueryVariables = Types.Exact<{
orderId: Types.Scalars['ID'];
@@ -11,7 +11,7 @@ export type ExplorerDeterministicOrderQueryVariables = Types.Exact<{
}>;
export type ExplorerDeterministicOrderQuery = { __typename?: 'Query', orderByID: { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } } };
export type ExplorerDeterministicOrderQuery = { __typename?: 'Query', orderByID: { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } | { __typename?: 'Perpetual', quoteName: string } | { __typename?: 'Spot' } } } } } };
export const ExplorerDeterministicOrderFieldsFragmentDoc = gql`
fragment ExplorerDeterministicOrderFields on Order {
@@ -47,6 +47,9 @@ export const ExplorerDeterministicOrderFieldsFragmentDoc = gql`
... on Future {
quoteName
}
... on Perpetual {
quoteName
}
}
}
}
@@ -0,0 +1,70 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerStopOrderFieldsFragment = { __typename?: 'StopOrder', id: string, status: Types.StopOrderStatus, createdAt: any, ocoLinkId?: string | null, triggerDirection: Types.StopOrderTriggerDirection, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, order?: { __typename?: 'Order', id: string } | null };
export type ExplorerStopOrderQueryVariables = Types.Exact<{
stopOrderId: Types.Scalars['ID'];
}>;
export type ExplorerStopOrderQuery = { __typename?: 'Query', stopOrder?: { __typename?: 'StopOrder', id: string, status: Types.StopOrderStatus, createdAt: any, ocoLinkId?: string | null, triggerDirection: Types.StopOrderTriggerDirection, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, order?: { __typename?: 'Order', id: string } | null } | null };
export const ExplorerStopOrderFieldsFragmentDoc = gql`
fragment ExplorerStopOrderFields on StopOrder {
id
status
createdAt
trigger {
... on StopOrderPrice {
price
}
... on StopOrderTrailingPercentOffset {
trailingPercentOffset
}
}
createdAt
ocoLinkId
triggerDirection
order {
id
}
}
`;
export const ExplorerStopOrderDocument = gql`
query ExplorerStopOrder($stopOrderId: ID!) {
stopOrder(id: $stopOrderId) {
...ExplorerStopOrderFields
}
}
${ExplorerStopOrderFieldsFragmentDoc}`;
/**
* __useExplorerStopOrderQuery__
*
* To run a query within a React component, call `useExplorerStopOrderQuery` and pass it any options that fit your needs.
* When your component renders, `useExplorerStopOrderQuery` 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 } = useExplorerStopOrderQuery({
* variables: {
* stopOrderId: // value for 'stopOrderId'
* },
* });
*/
export function useExplorerStopOrderQuery(baseOptions: Apollo.QueryHookOptions<ExplorerStopOrderQuery, ExplorerStopOrderQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ExplorerStopOrderQuery, ExplorerStopOrderQueryVariables>(ExplorerStopOrderDocument, options);
}
export function useExplorerStopOrderLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerStopOrderQuery, ExplorerStopOrderQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ExplorerStopOrderQuery, ExplorerStopOrderQueryVariables>(ExplorerStopOrderDocument, options);
}
export type ExplorerStopOrderQueryHookResult = ReturnType<typeof useExplorerStopOrderQuery>;
export type ExplorerStopOrderLazyQueryHookResult = ReturnType<typeof useExplorerStopOrderLazyQuery>;
export type ExplorerStopOrderQueryResult = Apollo.QueryResult<ExplorerStopOrderQuery, ExplorerStopOrderQueryVariables>;
@@ -150,6 +150,7 @@ function renderExistingAmend(
instrument: {
name: 'test-label',
product: {
__typename: 'Future',
quoteName: 'dai',
},
},
@@ -33,7 +33,7 @@ describe('Order TX Summary component', () => {
expect(res.queryByTestId('order-summary')).not.toBeInTheDocument();
});
it('Renders nothing if the order passed lacks a price', () => {
it('Renders "Market Price" if the order passed lacks a price', () => {
const o: Order = {
marketId: '123',
side: 'SIDE_BUY',
@@ -41,7 +41,7 @@ describe('Order TX Summary component', () => {
size: '10',
};
const res = renderComponent(o);
expect(res.queryByTestId('order-summary')).not.toBeInTheDocument();
expect(res.queryByText('Market Price')).toBeInTheDocument();
});
it('Renders nothing if the order has an unspecified side', () => {
@@ -3,6 +3,7 @@ import type { components } from '../../../types/explorer';
import PriceInMarket from '../price-in-market/price-in-market';
import { sideText } from '../order-details/lib/order-labels';
import SizeInMarket from '../size-in-market/size-in-market';
import { t } from '@vegaprotocol/i18n';
export type OrderSummaryProps = {
order: components['schemas']['v1OrderSubmission'];
@@ -20,7 +21,6 @@ const OrderTxSummary = ({ order }: OrderSummaryProps) => {
if (
!order ||
!order.marketId ||
!order.price ||
!order.side ||
order.side === 'SIDE_UNSPECIFIED'
) {
@@ -36,10 +36,14 @@ const OrderTxSummary = ({ order }: OrderSummaryProps) => {
'-'
)}
&nbsp;<i className="text-xs">@</i>&nbsp;
<PriceInMarket
marketId={order.marketId}
price={order.price}
></PriceInMarket>
{order.price ? (
<PriceInMarket
marketId={order.marketId}
price={order.price}
></PriceInMarket>
) : (
t('Market Price')
)}
</div>
);
};
@@ -33,6 +33,8 @@ const PriceInMarket = ({
label = addDecimalsFormatNumber(price, data.market.decimalPlaces);
} else if (
decimalSource === 'SETTLEMENT_ASSET' &&
data.market &&
'settlementAsset' in data.market.tradableInstrument.instrument.product &&
data.market?.tradableInstrument.instrument.product.settlementAsset
) {
label = addDecimalsFormatNumber(
@@ -2,7 +2,7 @@ import type { ProposalListFieldsFragment } from '@vegaprotocol/proposals';
import { VoteProgress } from '@vegaprotocol/proposals';
import type { AgGridReact } from 'ag-grid-react';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGrid } from '@vegaprotocol/datagrid';
import type {
VegaICellRendererParams,
VegaValueFormatterParams,
@@ -33,7 +33,7 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
const { params } = useNetworkParams([
NetworkParams.governance_proposal_market_requiredMajority,
]);
const tokenLink = useLinks(DApp.Token);
const tokenLink = useLinks(DApp.Governance);
const requiredMajorityPercentage = useMemo(() => {
const requiredMajority =
params?.governance_proposal_market_requiredMajority ?? 1;
@@ -105,7 +105,7 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
? new BigNumber(0)
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
return (
<div className="uppercase flex h-full items-center justify-center pt-2">
<div className="flex items-center justify-center h-full pt-2 uppercase">
<VoteProgress
threshold={requiredMajorityPercentage}
progress={yesPercentage}
@@ -0,0 +1,139 @@
import { t } from '@vegaprotocol/i18n';
import type { components } from '../../../../../types/explorer';
import { formatNumberPercentage } from '@vegaprotocol/utils';
import BigNumber from 'bignumber.js';
import PriceInMarket from '../../../price-in-market/price-in-market';
import StopOrderTriggerSummary from './stop-order-trigger';
import { Tooltip } from '@vegaprotocol/ui-toolkit';
import fromUnixTime from 'date-fns/fromUnixTime';
const wrapperClasses =
'flex-1 max-w-xs items-center border border-vega-light-200 dark:border-vega-dark-150 rounded-md pv-2 ph-5 mb-5';
export type StopOrderType = 'RisesAbove' | 'FallsBelow' | 'OCO';
type V1OrderSetup = components['schemas']['v1StopOrderSetup'];
interface StopOrderSetupProps extends V1OrderSetup {
type: StopOrderType;
deterministicId: string;
}
export function getExpiryTypeLabel(
expiryStrategy: V1OrderSetup['expiryStrategy']
): string {
switch (expiryStrategy) {
case 'EXPIRY_STRATEGY_CANCELS':
return t('Cancels');
case 'EXPIRY_STRATEGY_SUBMIT':
return t('Submit');
}
return expiryStrategy || t('Unknown');
}
export interface ExpiryTriggerProps {
trailingPercentOffset?: string;
price?: string;
marketId?: string;
}
export function ExpiryTrigger({
trailingPercentOffset,
price,
marketId,
}: ExpiryTriggerProps) {
if (price && marketId) {
return <PriceInMarket price={price} marketId={marketId} />;
}
if (trailingPercentOffset) {
return (
<span>
{formatNumberPercentage(new BigNumber(trailingPercentOffset))}{' '}
(trailing)
</span>
);
}
return null;
}
export function getMovePrefix(
type: StopOrderType,
trailingPercentOffset?: string
): string {
if (type === 'RisesAbove') {
if (trailingPercentOffset) {
return '+';
} else {
return '>';
}
} else {
if (trailingPercentOffset) {
return '-';
} else {
return '<';
}
}
}
export const TypeLabel = {
RisesAbove: t('Rises above ↗'),
FallsBelow: t('Falls below ↘'),
OCO: '',
};
/**
*/
export const StopOrderSetup = ({
type,
price,
orderSubmission,
expiresAt,
expiryStrategy,
trailingPercentOffset,
deterministicId,
}: StopOrderSetupProps) => {
let d = 'Unknown';
try {
d = expiresAt
? fromUnixTime(parseInt(expiresAt) / 1000000000).toLocaleString()
: t('Unknown');
} catch (e) {
d = t('Unknown');
}
return (
<div className={wrapperClasses}>
<div className="mb-12 lg:mb-0">
<div className="bg-slate-100 text-slate-900 px-6 py-2 md:px-6 flex">
<div className="flex-1">
<strong className="font-bold mb-1">{TypeLabel[type]} </strong>
<p className=" font-xs mb-0">
{getMovePrefix(type, trailingPercentOffset)}
<ExpiryTrigger
trailingPercentOffset={trailingPercentOffset}
price={price}
marketId={orderSubmission?.marketId}
/>
</p>
</div>
{expiresAt && expiryStrategy ? (
<div className="flex-1">
<strong className="font-bold mb-1">{t('Expiry Type')}</strong>
<p className=" font-xs mb-0">
<Tooltip description={<span>{d}</span>}>
<span>{getExpiryTypeLabel(expiryStrategy)}</span>
</Tooltip>
</p>
</div>
) : null}
</div>
<StopOrderTriggerSummary
id={deterministicId}
orderSubmission={orderSubmission}
/>
</div>
</div>
);
};
@@ -0,0 +1,108 @@
import { StopOrderStatus } from '@vegaprotocol/types';
import { useExplorerStopOrderQuery } from '../../../order-details/__generated__/StopOrder';
import type { ExplorerStopOrderQuery } from '../../../order-details/__generated__/StopOrder';
import { t } from '@vegaprotocol/i18n';
import { Icon } from '@vegaprotocol/ui-toolkit';
import type { IconName } from '@vegaprotocol/ui-toolkit';
import OrderTxSummary from '../../../order-summary/order-tx-summary';
import type { components } from '../../../../../types/explorer';
import type { ApolloError } from '@apollo/client';
export const StatusLabel: Record<StopOrderStatus, string> = {
[StopOrderStatus.STATUS_CANCELLED]: t('Cancelled'),
[StopOrderStatus.STATUS_EXPIRED]: t('Expired'),
[StopOrderStatus.STATUS_PENDING]: t('Pending'),
[StopOrderStatus.STATUS_REJECTED]: t('Rejected'),
[StopOrderStatus.STATUS_STOPPED]: t('Stopped'),
[StopOrderStatus.STATUS_TRIGGERED]: t('Triggered'),
[StopOrderStatus.STATUS_UNSPECIFIED]: t('Status unknown'),
};
export const StatusIcon: Record<StopOrderStatus, IconName> = {
[StopOrderStatus.STATUS_CANCELLED]: 'disable',
[StopOrderStatus.STATUS_EXPIRED]: 'outdated',
[StopOrderStatus.STATUS_PENDING]: 'circle',
[StopOrderStatus.STATUS_REJECTED]: 'cross',
[StopOrderStatus.STATUS_STOPPED]: 'stop',
[StopOrderStatus.STATUS_TRIGGERED]: 'tick',
[StopOrderStatus.STATUS_UNSPECIFIED]: 'help',
};
export const StatusMidColor: Record<StopOrderStatus, string> = {
[StopOrderStatus.STATUS_CANCELLED]: 'bg-red-100 text-red-900',
[StopOrderStatus.STATUS_EXPIRED]: 'bg-red-100 text-red-900',
[StopOrderStatus.STATUS_PENDING]: 'bg-yellow-100 text-yellow-900',
[StopOrderStatus.STATUS_REJECTED]: 'bg-red-100 text-red-900',
[StopOrderStatus.STATUS_STOPPED]: 'bg-red-100 text-red-900',
[StopOrderStatus.STATUS_TRIGGERED]: 'bg-green-100 text-green-900',
[StopOrderStatus.STATUS_UNSPECIFIED]: 'bg-yellow-100 text-yellow-900',
};
export const StatusBottomColor: Record<StopOrderStatus, string> = {
[StopOrderStatus.STATUS_CANCELLED]: 'bg-red-50 text-red-900 line-through',
[StopOrderStatus.STATUS_EXPIRED]: 'bg-red-50 text-red-900 line-through',
[StopOrderStatus.STATUS_PENDING]: 'bg-yellow-50 text-yellow-900',
[StopOrderStatus.STATUS_REJECTED]: 'bg-red-50 text-red-900 line-through',
[StopOrderStatus.STATUS_STOPPED]: 'bg-red-50 text-red-900 line-through',
[StopOrderStatus.STATUS_TRIGGERED]: 'bg-green-50 text-green-900',
[StopOrderStatus.STATUS_UNSPECIFIED]:
'bg-yellow-50 text-yellow-900 line-through',
};
export function getStopOrderTriggerStatus(
data?: ExplorerStopOrderQuery,
error?: ApolloError
) {
if (data && data.stopOrder) {
return data.stopOrder.status;
}
return StopOrderStatus.STATUS_UNSPECIFIED;
}
export interface StopOrderTriggerSummaryProps {
id: string;
orderSubmission?: components['schemas']['v1OrderSubmission'];
}
/**
*/
const StopOrderTriggerSummary = ({
id,
orderSubmission,
}: StopOrderTriggerSummaryProps) => {
const { data, error } = useExplorerStopOrderQuery({
variables: { stopOrderId: id },
});
const status = getStopOrderTriggerStatus(data, error);
return (
<>
<div
className={`${StatusMidColor[status]} px-3 py-2 md:px-6 flex space-x-4`}
>
<p className="m-0 p-0 align-top">
<Icon
size={6}
name={StatusIcon[status]}
className="inline-block mr-2"
/>
<span className="align-top">{StatusLabel[status]}</span>
</p>
</div>
<div
className={`${StatusBottomColor[status]} px-3 py-2 md:px-6 flex space-x-4`}
>
{orderSubmission && (
<p className="text-vega-grey-400 strike">
<OrderTxSummary order={orderSubmission} />
</p>
)}
</div>
</>
);
};
export default StopOrderTriggerSummary;
@@ -1,10 +1,12 @@
import { t } from '@vegaprotocol/i18n';
import type { components } from '../../../../../types/explorer';
import { Tooltip } from '@vegaprotocol/ui-toolkit';
import SizeInMarket from '../../../size-in-market/size-in-market';
export interface TxDetailsOrderIcebergDetailsProps {
iceberg: components['schemas']['v1IcebergOpts'];
size: components['schemas']['v1OrderSubmission']['size'];
marketId?: string;
}
/**
@@ -28,6 +30,7 @@ export interface TxDetailsOrderIcebergDetailsProps {
export const TxOrderIcebergDetails = ({
iceberg,
size,
marketId,
}: TxDetailsOrderIcebergDetailsProps) => {
return (
<div
@@ -36,15 +39,28 @@ export const TxOrderIcebergDetails = ({
>
<Tooltip description={t('Iceberg: Minimum visible size')}>
<span className="align-bottom text-vega-orange-650">
{iceberg.minimumVisibleSize || '-'}
{marketId ? (
<SizeInMarket
size={iceberg.minimumVisibleSize}
marketId={marketId}
/>
) : (
iceberg.minimumVisibleSize
)}
</span>
</Tooltip>
<Tooltip description={t('Iceberg: Total size')}>
<span className="text-sm text-vega-blue-600 mx-3">{size}</span>
<span className="text-sm text-vega-blue-600 mx-3">
{marketId ? <SizeInMarket size={size} marketId={marketId} /> : size}
</span>
</Tooltip>
<Tooltip description={t('Iceberg: Visible peak')}>
<span className="align-top text-vega-yellow-600">
{iceberg.peakSize || '-'}
{marketId ? (
<SizeInMarket size={iceberg.peakSize} marketId={marketId} />
) : (
iceberg.peakSize
)}
</span>
</Tooltip>
</div>
@@ -35,7 +35,7 @@ export const BundleSigners = ({
tx,
id,
}: BundleSignersProps) => {
const tokenLink = useLinks(DApp.Token);
const tokenLink = useLinks(DApp.Governance);
const bridgeFunction: BridgeFunction =
tx?.changes?.erc20 && 'contractAddress' in tx.changes.erc20
@@ -26,6 +26,11 @@ export const sharedHeaderProps = {
className: 'align-top',
};
const Labels: Record<BlockExplorerTransactionResult['type'], string> = {
'Stop Orders Submission': 'Stop Order',
'Stop Orders Cancellation': 'Cancel Stop Order',
};
/**
* These rows are shown for every transaction type, providing a consistent set of rows for the top
* of a transaction details row. The order is relatively arbitrary but felt right - it might need to
@@ -44,12 +49,14 @@ export const TxDetailsShared = ({
const time: string = blockData?.result.block.header.time || '';
const height: string = blockData?.result.block.header.height || txData.block;
const type = Labels[txData.type] || txData.type;
return (
<>
{hideTypeRow === false ? (
<TableRow modifier="bordered">
<TableCell {...sharedHeaderProps}>{t('Type')}</TableCell>
<TableCell>{txData.type}</TableCell>
<TableCell>{type}</TableCell>
</TableRow>
) : null}
<TableRow modifier="bordered">
@@ -31,6 +31,8 @@ const AccountType: Record<AccountTypes, string> = {
ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES: 'LP Received Fees',
ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS: 'Market Proposers',
ACCOUNT_TYPE_HOLDING: 'Holding',
ACCOUNT_TYPE_LIQUIDITY_FEES_BONUS_DISTRIBUTION: 'Bonus Distribution',
ACCOUNT_TYPE_LP_LIQUIDITY_FEES: 'LP Liquidity Fees',
};
interface TransferParticipantsProps {
@@ -11,6 +11,7 @@ import { TxDetailsBatch } from './tx-batch';
import { TxDetailsChainEvent } from './tx-chain-event';
import { TxDetailsNodeVote } from './tx-node-vote';
import { TxDetailsOrderCancel } from './tx-order-cancel';
import { TxDetailsStopOrderCancel } from './tx-stop-order-cancel';
import { TxDetailsOrderAmend } from './tx-order-amend';
import { TxDetailsWithdrawSubmission } from './tx-withdraw-submission';
import { TxDetailsDelegate } from './tx-delegation';
@@ -26,6 +27,7 @@ import { TxDetailsNodeAnnounce } from './tx-node-announce';
import { TxDetailsStateVariable } from './tx-state-variable-proposal';
import { TxProposal } from './tx-proposal';
import { TxDetailsTransfer } from './tx-transfer';
import { TxDetailsStopOrderSubmission } from './tx-stop-order-submission';
interface TxDetailsWrapperProps {
txData: BlockExplorerTransactionResult | undefined;
@@ -85,6 +87,8 @@ function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
return TxDetailsProtocolUpgrade;
case 'Cancel Order':
return TxDetailsOrderCancel;
case 'Stop Orders Cancellation':
return TxDetailsStopOrderCancel;
case 'Amend Order':
return TxDetailsOrderAmend;
case 'Validator Heartbeat':
@@ -113,6 +117,8 @@ function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
return TxDetailsUndelegate;
case 'State Variable Proposal':
return TxDetailsStateVariable;
case 'Stop Orders Submission':
return TxDetailsStopOrderSubmission;
case 'Transfer Funds':
return TxDetailsTransfer;
default:
@@ -41,7 +41,7 @@ export const TxDetailsIssueSignatures = ({
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const cmd: Command = txData.command;
const cmd: Command = txData.command.issueSignatures;
const k = cmd.kind ? kind[cmd.kind] : null;
return (
@@ -81,7 +81,11 @@ export const TxDetailsOrder = ({
<TableRow modifier="bordered">
<TableCell>{t('Iceberg details')}</TableCell>
<TableCell>
<TxOrderIcebergDetails iceberg={iceberg} size={size} />
<TxOrderIcebergDetails
iceberg={iceberg}
size={size}
marketId={marketId}
/>
</TableCell>
</TableRow>
) : null}
@@ -10,6 +10,8 @@ import Hash from '../../links/hash';
import { t } from '@vegaprotocol/i18n';
import { ProposalSignatureBundleNewAsset } from './proposal/signature-bundle-new';
import { ProposalSignatureBundleUpdateAsset } from './proposal/signature-bundle-update';
import { MarketLink } from '../../links';
import { formatNumber } from '@vegaprotocol/utils';
export type Proposal = components['schemas']['v1ProposalSubmission'];
export type ProposalTerms = components['schemas']['vegaProposalTerms'];
@@ -53,7 +55,11 @@ export function proposalTypeLabel(terms?: ProposalTerms): string {
} else if (has(terms, 'updateAsset')) {
return t('Update asset proposal');
} else if (has(terms, 'newMarket')) {
return t('New market proposal');
if (terms?.newMarket?.changes?.successor) {
return t('Successor market proposal');
} else {
return t('New market proposal');
}
} else if (has(terms, 'updateMarket')) {
return t('Update market proposal');
} else if (has(terms, 'updateNetworkParameter')) {
@@ -85,6 +91,13 @@ export const TxProposal = ({ txData, pubKey, blockData }: TxProposalProps) => {
}
const tx = proposal.terms?.newAsset || proposal.terms?.updateAsset;
const isSuccessorMarketProposal =
proposal?.terms?.newMarket?.changes?.successor;
const parentMarketId =
isSuccessorMarketProposal &&
proposal?.terms.newMarket?.changes?.successor?.parentMarketId;
const insurancePoolFraction =
proposal?.terms?.newMarket?.changes?.successor?.insurancePoolFraction;
// This component is not rendered if no bundle is required
const SignatureBundleComponent = proposal.terms?.newAsset
@@ -111,6 +124,30 @@ export const TxProposal = ({ txData, pubKey, blockData }: TxProposalProps) => {
<Hash text={deterministicId} />
</TableCell>
</TableRow>
{isSuccessorMarketProposal ? (
<>
{parentMarketId ? (
<TableRow modifier="bordered">
<TableCell>{t('Previous market')}</TableCell>
<TableCell>
<MarketLink
id={
proposal.terms?.newMarket.changes.successor.parentMarketId
}
/>
</TableCell>
</TableRow>
) : null}
{insurancePoolFraction ? (
<TableRow modifier="bordered">
<TableCell>{t('Insurance pool fraction')}</TableCell>
<TableCell>
{formatNumber(Number(insurancePoolFraction) * 100, 0)}%
</TableCell>
</TableRow>
) : null}
</>
) : null}
</TableWithTbody>
<ProposalSummary
id={deterministicId}
@@ -0,0 +1,60 @@
import { t } from '@vegaprotocol/i18n';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import { MarketLink } from '../../links/';
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table';
import { CancelSummary } from '../../order-summary/order-cancellation';
import Hash from '../../links/hash';
import type { components } from '../../../../types/explorer';
export type StopOrderCancellationTransaction =
components['schemas']['v1StopOrdersCancellation'];
interface TxDetailsStopOrderCancelProps {
txData: BlockExplorerTransactionResult | undefined;
pubKey: string | undefined;
blockData: TendermintBlocksResponse | undefined;
}
/**
* Someone cancelled a stop order
*/
export const TxDetailsStopOrderCancel = ({
txData,
pubKey,
blockData,
}: TxDetailsStopOrderCancelProps) => {
if (!txData || !txData.command) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const command: StopOrderCancellationTransaction =
txData.command.stopOrdersCancellation;
const { marketId, stopOrderId } = command;
return (
<TableWithTbody className="mb-8" allowWrap={true}>
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
<TableRow modifier="bordered">
<TableCell>{t('Cancel stop order')}</TableCell>
<TableCell>
{stopOrderId ? (
<Hash text={stopOrderId} />
) : (
<CancelSummary orderId={stopOrderId} marketId={marketId} />
)}
</TableCell>
</TableRow>
{marketId ? (
<TableRow modifier="bordered">
<TableCell>{t('Market')}</TableCell>
<TableCell>
<MarketLink id={marketId} />
</TableCell>
</TableRow>
) : null}
</TableWithTbody>
);
};
@@ -0,0 +1,148 @@
import { t } from '@vegaprotocol/i18n';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import { MarketLink } from '../../links/';
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table';
import {
getStopOrderIds,
stopOrdersSignatureToDeterministicId,
} from '../lib/deterministic-ids';
import type { components } from '../../../../types/explorer';
import { StopOrderSetup } from './order/stop-order-setup';
type StopOrderSetup = components['schemas']['v1StopOrderSetup'];
interface TxDetailsOrderProps {
txData: BlockExplorerTransactionResult | undefined;
pubKey: string | undefined;
blockData: TendermintBlocksResponse | undefined;
}
export function getStopTypeLabel(
risesAbove: StopOrderSetup | undefined,
fallsBelow: StopOrderSetup | undefined
): string {
if (risesAbove && fallsBelow) {
return t('OCO (One Cancels Other)');
} else if (fallsBelow) {
return t('Falls Below ↘');
} else if (risesAbove) {
return t('Rises Above ↗');
} else {
return t('Stop Order');
}
}
export interface StopMarketIdProps {
risesAbove: StopOrderSetup | undefined;
fallsBelow: StopOrderSetup | undefined;
showMarketName?: boolean;
}
export function StopMarketId({
risesAbove,
fallsBelow,
showMarketName = false,
}: StopMarketIdProps) {
const raMarketId = risesAbove?.orderSubmission?.marketId;
const fbMarketId = fallsBelow?.orderSubmission?.marketId;
if (raMarketId && fbMarketId) {
if (raMarketId === fbMarketId) {
return <MarketLink id={raMarketId} showMarketName={showMarketName} />;
} else {
return (
<>
<MarketLink id={raMarketId} showMarketName={showMarketName} />,
<MarketLink id={fbMarketId} showMarketName={showMarketName} />
</>
);
}
} else if (raMarketId) {
return <MarketLink id={raMarketId} showMarketName={showMarketName} />;
} else if (fbMarketId) {
return <MarketLink id={fbMarketId} showMarketName={showMarketName} />;
} else {
return '-';
}
}
/**
*/
export const TxDetailsStopOrderSubmission = ({
txData,
pubKey,
blockData,
}: TxDetailsOrderProps) => {
if (!txData || !txData.command.stopOrdersSubmission) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const tx: components['schemas']['v1StopOrdersSubmission'] =
txData.command.stopOrdersSubmission;
const orderIds = stopOrdersSignatureToDeterministicId(
txData?.signature?.value
);
const { risesAboveId, fallsBelowId } = getStopOrderIds(
orderIds,
tx.risesAbove,
tx.fallsBelow
);
return (
<>
<TableWithTbody className="mb-8" allowWrap={true}>
<TxDetailsShared
txData={txData}
pubKey={pubKey}
blockData={blockData}
/>
<TableRow modifier="bordered">
<TableCell>{t('Market ID')}</TableCell>
<TableCell>
<StopMarketId
risesAbove={tx.risesAbove}
fallsBelow={tx.fallsBelow}
/>
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Market')}</TableCell>
<TableCell>
<StopMarketId
risesAbove={tx.risesAbove}
fallsBelow={tx.fallsBelow}
showMarketName={true}
/>
</TableCell>
</TableRow>
<TableRow modifier="bordered">
<TableCell>{t('Trigger')}</TableCell>
<TableCell>
{getStopTypeLabel(tx.risesAbove, tx.fallsBelow)}
</TableCell>
</TableRow>
</TableWithTbody>
<div className="flex gap-2">
{tx.fallsBelow && fallsBelowId && (
<StopOrderSetup
type={'FallsBelow'}
{...tx.fallsBelow}
deterministicId={fallsBelowId}
/>
)}
{tx.risesAbove && risesAboveId && (
<StopOrderSetup
type={'RisesAbove'}
{...tx.risesAbove}
deterministicId={risesAboveId}
/>
)}
</div>
</>
);
};
@@ -1,4 +1,8 @@
import { hexToString, txSignatureToDeterministicId } from './deterministic-ids';
import {
hexToString,
txSignatureToDeterministicId,
stopOrdersSignatureToDeterministicId,
} from './deterministic-ids';
it('txSignatureToDeterministicId Turns a known signature in to a known deterministic ID', () => {
const signature =
@@ -20,3 +24,24 @@ it('hexToString encodes a known good value as bytes', () => {
const res = hexToString(hex);
expect(res).toEqual([14, 221]);
});
describe('stopOrdersSignatureToDeterministicId', () => {
it('should return empty object if no signature is provided', () => {
const result = stopOrdersSignatureToDeterministicId();
expect(result.length).toEqual(0);
});
it('should return valid deterministic ids if a signature is provided', () => {
const signature = 'deadb33f';
const result = stopOrdersSignatureToDeterministicId(signature);
expect(result.length).toEqual(2);
expect(result[0]).toBe(
'4c45b67a8c08cbf1982883a75beaf309bf172461d04bd427623d6cd3d9ab0e91'
);
expect(result[1]).toBe(
'afe7509ff90d8f26339a0ab81e4d3e1fb6c4d44e94419aa5e13ae7659d894da1'
);
});
});
@@ -1,4 +1,6 @@
import type { components } from '../../../../types/explorer';
import { sha3_256 } from 'js-sha3';
type StopOrderSetup = components['schemas']['v1StopOrderSetup'];
/**
* Encodes a string as bytes
@@ -37,3 +39,58 @@ export function txSignatureToDeterministicId(signature: string): string {
return hash.hex();
}
/**
* Given a stop order signature string, returns the deterministic IDs of both potential
* Stop Orders. A stop order is not an order per se, but a trigger for an order. The order
* created by the stop order will have another ID based on the market event that hit the
* trigger, and as such is not deterministic.
*
* @param signature
* @returns string[]
*/
export function stopOrdersSignatureToDeterministicId(
signature?: string
): string[] {
if (!signature) {
return [];
}
const firstId = txSignatureToDeterministicId(signature);
return [firstId, txSignatureToDeterministicId(firstId)];
}
export type stopSignatures = {
risesAboveId: string | undefined;
fallsBelowId: string | undefined;
};
/**
* In 0.72.10 the way stop order IDs are determined is a little tricky. It will be stabilised
* in a future release.
* @param deterministicIds Output of stopORdersSignatureToDeterministicId
* @param risesAbove Stop order setup
* @param fallsBelow Stop order setup
* @returns Object containing the deterministic IDs of the stop orders
*/
export function getStopOrderIds(
deterministicIds: string[],
risesAbove: StopOrderSetup | undefined,
fallsBelow: StopOrderSetup | undefined
) {
if (risesAbove && fallsBelow) {
return {
risesAboveId: deterministicIds[0],
fallsBelowId: deterministicIds[1],
};
} else if (!fallsBelow && risesAbove) {
return {
risesAboveId: deterministicIds[0],
};
} else {
return {
fallsBelowId: deterministicIds[0] || undefined,
risesAboveId: deterministicIds[1] || undefined,
};
}
}
@@ -34,6 +34,8 @@ export type FilterOption =
| 'Protocol Upgrade'
| 'Register new Node'
| 'State Variable Proposal'
| 'Stop Orders Submission'
| 'Stop Orders Cancellation'
| 'Submit Oracle Data'
| 'Submit Order'
| 'Transfer Funds'
@@ -53,6 +55,8 @@ export const PrimaryFilterOptions: FilterOption[] = [
'Delegate',
'Liquidity Provision Order',
'Proposal',
'Stop Orders Submission',
'Stop Orders Cancellation',
'Submit Oracle Data',
'Submit Order',
'Transfer Funds',
@@ -50,6 +50,25 @@ const displayString: StringMap = {
'Stop Orders Cancellation': 'Cancel stop',
};
export function getLabelForStopOrderType(
orderType: string,
command: components['schemas']['v1InputData']
): string {
if (command.stopOrdersSubmission) {
if (
command.stopOrdersSubmission.risesAbove &&
command.stopOrdersSubmission.fallsBelow
) {
return 'Stop ⇅';
} else if (command.stopOrdersSubmission.risesAbove) {
return 'Stop ↗';
} else if (command.stopOrdersSubmission.fallsBelow) {
return 'Stop ↘';
}
}
return 'Stop';
}
export function getLabelForOrderType(
orderType: string,
command: components['schemas']['v1InputData']
@@ -78,7 +97,11 @@ export function getLabelForProposal(
} else if (proposal.terms?.updateAsset) {
return t('Proposal: Update asset');
} else if (proposal.terms?.newMarket) {
return t('Proposal: New market');
if (proposal.terms?.newMarket.changes?.successor) {
return t('Proposal: Successor market');
} else {
return t('Proposal: New market');
}
} else if (proposal.terms?.updateMarket) {
return t('Proposal: Update market');
} else if (proposal.terms?.updateNetworkParameter) {
@@ -181,6 +204,9 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
} else if (type === 'Order' && command) {
type = getLabelForOrderType(orderType, command);
colours = 'text-white dark-text-white bg-vega-blue dark:bg-vega-blue';
} else if (type === 'Stop' && command) {
type = getLabelForStopOrderType(orderType, command);
colours = 'text-white dark-text-white bg-vega-blue dark:bg-vega-blue';
}
if (type === 'Vote on Proposal') {
@@ -55,7 +55,7 @@ export const TxsInfiniteList = ({
}
return (
<div className="overflow-scroll">
<div>
<table className={className} data-testid="transactions-list">
<thead>
<tr className="w-full mb-3 text-vega-dark-300 uppercase text-left">
+9
View File
@@ -22,6 +22,11 @@ import { Footer } from '../components/footer/footer';
import { Header } from '../components/header';
import { Routes } from './route-names';
import { useExplorerNodeNamesLazyQuery } from './validators/__generated__/NodeNames';
import {
ProtocolUpgradeCountdownMode,
ProtocolUpgradeInProgressNotification,
ProtocolUpgradeProposalNotification,
} from '@vegaprotocol/proposals';
const DialogsContainer = () => {
const { isOpen, id, trigger, asJson, setOpen } = useAssetDetailsDialogStore();
@@ -62,6 +67,10 @@ export const Layout = () => {
/>
)}
<Header />
<ProtocolUpgradeProposalNotification
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
/>
<ProtocolUpgradeInProgressNotification />
</div>
<div className={fixedWidthClasses}>
<main className="p-4">
@@ -1 +1,2 @@
export * from './network-parameters';
export * from './structure-network-params';
@@ -1,82 +1,105 @@
import { render, screen } from '@testing-library/react';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { NetworkParametersTable } from './network-parameters';
import { MemoryRouter } from 'react-router-dom';
const renderComponent = (data: NetworkParamsQuery | undefined) => {
return render(
<MemoryRouter>
<NetworkParametersTable data={data} loading={false} />
</MemoryRouter>
);
};
const mockData = {
networkParametersConnection: {
edges: [
{
node: {
key: 'spam.protection.delegation.min.tokens',
value: '3',
},
},
{
node: {
key: 'spam.protection.voting.min.tokens',
value: '1',
},
},
{
node: {
key: 'reward.staking.delegation.minimumValidatorStake',
value: '2',
},
},
{
node: {
key: 'reward.asset',
value:
'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55',
},
},
],
},
};
describe('NetworkParametersTable', () => {
it('renders correctly when it has network params', () => {
const data: NetworkParamsQuery = {
networkParametersConnection: {
edges: [
{
node: {
__typename: 'NetworkParameter',
key: 'market.liquidityProvision.minLpStakeQuantumMultiple',
value: '1',
},
},
{
node: {
__typename: 'NetworkParameter',
key: 'market.fee.factors.infrastructureFee',
value: '0.0005',
},
},
],
it('renders headers correctly', () => {
renderComponent(mockData);
const allHeadings = screen.getAllByRole('heading');
expect(
allHeadings.map((h) => {
return {
text: h.textContent,
level: h.tagName,
testId: h.getAttribute('data-testid'),
};
})
).toEqual([
{
text: 'Network Parameters',
level: 'H1',
testId: 'network-param-header',
},
};
render(<NetworkParametersTable data={data} loading={false} />);
expect(screen.getByTestId('network-param-header')).toHaveTextContent(
'Network Parameters'
);
const rows = screen.getAllByTestId('key-value-table-row');
expect(rows[0].children[0]).toHaveTextContent(
'market.fee.factors.infrastructureFee'
);
expect(rows[1].children[0]).toHaveTextContent(
'market.liquidityProvision.minLpStakeQuantumMultiple'
);
expect(rows[0].children[1]).toHaveTextContent('0.0005');
expect(rows[1].children[1]).toHaveTextContent('1');
{ text: 'Spam', level: 'H1', testId: 'spam' },
{ text: 'Protection', level: 'H2', testId: 'spam-protection' },
{ text: 'Delegation', level: 'H3', testId: 'spam-protection-delegation' },
{ text: 'Min', level: 'H4', testId: 'spam-protection-delegation-min' },
{ text: 'Voting', level: 'H3', testId: 'spam-protection-voting' },
{ text: 'Min', level: 'H4', testId: 'spam-protection-voting-min' },
{ text: 'Reward', level: 'H1', testId: 'reward' },
{ text: 'Staking', level: 'H2', testId: 'reward-staking' },
{ text: 'Delegation', level: 'H3', testId: 'reward-staking-delegation' },
]);
});
it('renders the rows in ascending order', () => {
const data: NetworkParamsQuery = {
networkParametersConnection: {
edges: [
{
node: {
__typename: 'NetworkParameter',
key: 'market.fee.factors.infrastructureFee',
value: '0.0005',
},
},
{
node: {
__typename: 'NetworkParameter',
key: 'market.liquidityProvision.minLpStakeQuantumMultiple',
value: '1',
},
},
],
},
};
render(<NetworkParametersTable data={data} loading={false} />);
expect(screen.getByTestId('network-param-header')).toHaveTextContent(
'Network Parameters'
it('renders network params correctly', () => {
renderComponent(mockData);
const delegationMinTokensRow = screen.getByTestId(
'spam-protection-delegation-min-tokens'
);
const rows = screen.getAllByTestId('key-value-table-row');
expect(rows[0].children[0]).toHaveTextContent(
'market.fee.factors.infrastructureFee'
expect(delegationMinTokensRow).toHaveTextContent('0.000000000000000003');
const votingMinTokensRow = screen.getByTestId(
'spam-protection-voting-min-tokens'
);
expect(rows[1].children[0]).toHaveTextContent(
'market.liquidityProvision.minLpStakeQuantumMultiple'
expect(votingMinTokensRow).toHaveTextContent('0.000000000000000001');
const minimumValidatorStakeRow = screen.getByTestId(
'reward-staking-delegation-minimumValidatorStake'
);
expect(minimumValidatorStakeRow).toHaveTextContent('2');
const assetRow = screen.getByTestId('reward-asset');
expect(assetRow).toHaveTextContent(
'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55'
);
expect(rows[0].children[1]).toHaveTextContent('0.0005');
expect(rows[1].children[1]).toHaveTextContent('1');
});
it('does not render rows when is loading', () => {
render(<NetworkParametersTable data={undefined} loading={true} />);
renderComponent(undefined);
expect(screen.getByTestId('network-param-header')).toHaveTextContent(
'Network Parameters'
);
@@ -1,6 +1,8 @@
import startCase from 'lodash/startCase';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import {
AsyncRenderer,
KeyValueTable,
KeyValueTableRow,
SyntaxHighlighter,
} from '@vegaprotocol/ui-toolkit';
@@ -12,11 +14,12 @@ import {
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { RouteTitle } from '../../components/route-title';
import orderBy from 'lodash/orderBy';
import { useNetworkParamsQuery } from '@vegaprotocol/network-parameters';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { useScrollToLocation } from '../../hooks/scroll-to-location';
import { useDocumentTitle } from '../../hooks/use-document-title';
import { structureNetworkParams } from './structure-network-params';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import type { GroupedParams } from './structure-network-params';
const PERCENTAGE_PARAMS = [
'governance.proposal.asset.requiredMajority',
@@ -58,6 +61,54 @@ const BIG_NUMBER_PARAMS = [
'governance.proposal.updateAsset.minVoterBalance',
];
export const renderGroupedParams = (
group: GroupedParams,
level: number,
parentKeys: string[] = []
) => {
const Header = `h${level}` as keyof JSX.IntrinsicElements;
const headerStyles = classNames('uppercase font-semibold', {
'pt-6 text-3xl underline': level === 1,
'pt-3 text-2xl': level === 2,
'pt-2 text-lg': level === 3,
'pt-2 text-default': level === 4,
});
return Object.entries(group).map(([key, value]) => {
const fullPath = [...parentKeys, key].join('.');
const isLeafNode = typeof value !== 'object';
const id = parentKeys.concat([key]).join('-');
return (
<div key={key}>
{!isLeafNode && (
<div id={id}>
<Link to={`#${id}`}>
<Header className={headerStyles} data-testid={id}>
{startCase(key)}
</Header>
</Link>
</div>
)}
{isLeafNode ? (
typeof value === 'string' ? (
<div data-testid={id}>
<NetworkParameterRow
key={fullPath}
row={{ key: fullPath, value: value }}
/>
</div>
) : null
) : (
<div className="pb-1">
{renderGroupedParams(value, level + 1, [...parentKeys, key])}
</div>
)}
</div>
);
});
};
export const NetworkParameterRow = ({
row: { key, value },
}: {
@@ -77,7 +128,9 @@ export const NetworkParameterRow = ({
>
{key}
{isSyntaxRow ? (
<SyntaxHighlighter data={JSON.parse(value)} />
<div className="pb-2">
<SyntaxHighlighter data={JSON.parse(value)} />
</div>
) : isNaN(Number(value)) ? (
value
) : BIG_NUMBER_PARAMS.includes(key) ? (
@@ -113,17 +166,12 @@ export const NetworkParametersTable = ({
loading={loading}
error={error}
render={(data) => {
const ascParams = orderBy(
removePaginationWrapper(data.networkParametersConnection.edges),
(param) => param.key,
'asc'
const flatParams = removePaginationWrapper(
data.networkParametersConnection.edges
);
const groupedParams = structureNetworkParams(flatParams);
return (
<KeyValueTable data-testid="parameters">
{(ascParams || []).map((row) => (
<NetworkParameterRow key={row.key} row={row} />
))}
</KeyValueTable>
<div className="-mt-6">{renderGroupedParams(groupedParams, 1)}</div>
);
}}
/>
@@ -0,0 +1,109 @@
import type { GroupedParams } from './structure-network-params';
import {
structureParams,
sortGroupedParams,
structureNetworkParams,
} from './structure-network-params';
describe('structureParams', () => {
it('should correctly structure params', () => {
const input = [
{ key: 'spam.protection.delegation.min.tokens', value: '10' },
{ key: 'spam.protection.voting.min.tokens', value: '5' },
];
const output: GroupedParams = {
spam: {
protection: {
delegation: {
min: {
tokens: '10',
},
},
voting: {
min: {
tokens: '5',
},
},
},
},
};
expect(structureParams(input)).toEqual(output);
});
it('should handle top-level keys correctly', () => {
const input = [{ key: 'levelOne', value: '10' }];
const output = {
levelOne: '10',
};
expect(structureParams(input)).toEqual(output);
});
});
describe('sortGroupedParams', () => {
it('should correctly sort grouped params', () => {
const input: GroupedParams = {
spam: {
protection: {
delegation: {
min: {
tokens: '10',
},
},
},
},
reward: '50',
};
const output: GroupedParams = {
reward: '50',
spam: {
protection: {
delegation: {
min: {
tokens: '10',
},
},
},
},
};
expect(sortGroupedParams(input)).toEqual(output);
});
it('should handle already sorted keys', () => {
const input = {
a: '10',
b: {
c: '5',
d: '6',
},
};
expect(sortGroupedParams(input)).toEqual(input);
});
});
describe('structureNetworkParams', () => {
it('should structure and sort network params correctly', () => {
const input = [
{ key: 'spam.protection.delegation.min.tokens', value: '10' },
{ key: 'reward.asset', value: '50' },
];
const output: GroupedParams = {
reward: {
asset: '50',
},
spam: {
protection: {
delegation: {
min: {
tokens: '10',
},
},
},
},
};
expect(structureNetworkParams(input)).toEqual(output);
});
it('should return an empty object if no params are provided', () => {
expect(structureNetworkParams([])).toEqual({});
});
});
@@ -0,0 +1,107 @@
/**
* Categorizes and sorts an array of key-value pairs of network params into a nested object structure.
*
* The function takes an array of network params where keys are dot-delimited
* strings representing nested categories (e.g., 'spam.protection.delegation.min.tokens').
*
* Why this is necessary:
* A flat key-value structure wouldn't provide the hierarchical information needed.
* Organizing network parameters like this allows the rendering of nested headers
* and their corresponding network params.
*
* It also ensures that items with the minimum amount of nesting are ordered first. This
* allows us to render these items first, before more deeply nested items are rendered with
* subheaders. This creates a more intuitive UI.
*
* For example, given the input:
* [
* { key: 'spam.protection.delegation.min.tokens', value: '10' },
* { key: 'spam.protection.voting.min.tokens', value: '5' },
* { key: 'reward.staking.delegation.minimumValidatorStake', value: '2' }
* { key: 'reward.asset', value: 'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55' }
* ]
*
* The output will be:
* {
* spam: {
* protection: {
* delegation: {
* min: {
* tokens: '10'
* }
* },
* voting: {
* min: {
* tokens: '5'
* }
* }
* }
* },
* reward: {
* asset: 'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55',
* staking: {
* delegation: {
* minimumValidatorStake: '2'
* }
* }
* }
* }
*
* @param {Array} params - An array of key-value pairs to categorize and sort.
* @returns {GroupedParams} - A nested object that groups the key-value pairs.
*/
export type GroupedParams = {
[key: string]: string | GroupedParams;
};
export const structureParams = (
params: { key: string; value: string }[]
): GroupedParams => {
const grouped: GroupedParams = {};
params.forEach(({ key, value }) => {
const parts = key.split('.');
let node: GroupedParams = grouped;
parts.forEach((part, i) => {
if (typeof node[part] === 'undefined') {
node[part] = i === parts.length - 1 ? value : {};
}
if (typeof node[part] === 'object') {
node = node[part] as GroupedParams;
}
});
});
return grouped;
};
export const sortGroupedParams = (
groupedParams: GroupedParams
): GroupedParams => {
const sorted: GroupedParams = {};
// Sort top-level keys first
Object.entries(groupedParams).forEach(([key, value]) => {
if (typeof value === 'string') {
sorted[key] = value;
}
});
Object.entries(groupedParams).forEach(([key, value]) => {
if (typeof value === 'object') {
sorted[key] = sortGroupedParams(value);
}
});
return sorted;
};
export const structureNetworkParams = (
params: { key: string; value: string }[]
) => {
const grouped = structureParams(params);
return sortGroupedParams(grouped);
};
@@ -1,59 +1,5 @@
fragment ExplorerOracleDataSource on OracleSpec {
dataSourceSpec {
spec {
id
createdAt
updatedAt
status
data {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
value
operator
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
filters {
key {
name
type
}
conditions {
value
operator
}
}
}
}
}
}
}
}
}
}
fragment ExplorerOracleDataConnection on OracleSpec {
dataConnection {
pageInfo {
hasNextPage
}
edges {
node {
externalData {
@@ -81,6 +27,90 @@ fragment ExplorerOracleDataConnection on OracleSpec {
}
}
fragment ExplorerOracleDataSource on OracleSpec {
...ExplorerOracleDataConnection
dataSourceSpec {
spec {
id
createdAt
updatedAt
status
data {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
value
operator
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on EthCallSpec {
abi
args
method
requiredConfirmations
address
normalisers {
name
expression
}
trigger {
trigger {
... on EthTimeTrigger {
initial
every
until
}
}
}
filters {
key {
name
type
numberDecimalPlaces
}
conditions {
value
operator
}
}
}
... on DataSourceSpecConfiguration {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
filters {
key {
name
type
numberDecimalPlaces
}
conditions {
value
operator
}
}
}
}
}
}
}
}
}
}
query ExplorerOracleSpecs {
oracleSpecsConnection(pagination: { first: 50 }) {
pageInfo {
@@ -97,6 +127,5 @@ query ExplorerOracleSpecs {
query ExplorerOracleSpecById($id: ID!) {
oracleSpec(oracleSpecId: $id) {
...ExplorerOracleDataSource
...ExplorerOracleDataConnection
}
}
@@ -11,6 +11,14 @@ fragment ExplorerOracleForMarketsMarket on Market {
id
}
}
... on Perpetual {
dataSourceSpecForSettlementData {
id
}
dataSourceSpecForSettlementSchedule {
id
}
}
}
}
}
+90 -62
View File
@@ -3,80 +3,25 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerOracleDataSourceFragment = { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } } };
export type ExplorerOracleDataConnectionFragment = { __typename?: 'OracleSpec', dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } };
export type ExplorerOracleDataConnectionFragment = { __typename?: 'OracleSpec', dataConnection: { __typename?: 'OracleDataConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } };
export type ExplorerOracleDataSourceFragment = { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } };
export type ExplorerOracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ExplorerOracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } } } } | null> | null } | null };
export type ExplorerOracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } } | null> | null } | null };
export type ExplorerOracleSpecByIdQueryVariables = Types.Exact<{
id: Types.Scalars['ID'];
}>;
export type ExplorerOracleSpecByIdQuery = { __typename?: 'Query', oracleSpec?: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } | null };
export type ExplorerOracleSpecByIdQuery = { __typename?: 'Query', oracleSpec?: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger' } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } | null };
export const ExplorerOracleDataSourceFragmentDoc = gql`
fragment ExplorerOracleDataSource on OracleSpec {
dataSourceSpec {
spec {
id
createdAt
updatedAt
status
data {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
value
operator
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
filters {
key {
name
type
}
conditions {
value
operator
}
}
}
}
}
}
}
}
}
}
`;
export const ExplorerOracleDataConnectionFragmentDoc = gql`
fragment ExplorerOracleDataConnection on OracleSpec {
dataConnection {
pageInfo {
hasNextPage
}
edges {
node {
externalData {
@@ -104,6 +49,91 @@ export const ExplorerOracleDataConnectionFragmentDoc = gql`
}
}
`;
export const ExplorerOracleDataSourceFragmentDoc = gql`
fragment ExplorerOracleDataSource on OracleSpec {
...ExplorerOracleDataConnection
dataSourceSpec {
spec {
id
createdAt
updatedAt
status
data {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
value
operator
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on EthCallSpec {
abi
args
method
requiredConfirmations
address
normalisers {
name
expression
}
trigger {
trigger {
... on EthTimeTrigger {
initial
every
until
}
}
}
filters {
key {
name
type
numberDecimalPlaces
}
conditions {
value
operator
}
}
}
... on DataSourceSpecConfiguration {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
filters {
key {
name
type
numberDecimalPlaces
}
conditions {
value
operator
}
}
}
}
}
}
}
}
}
}
${ExplorerOracleDataConnectionFragmentDoc}`;
export const ExplorerOracleSpecsDocument = gql`
query ExplorerOracleSpecs {
oracleSpecsConnection(pagination: {first: 50}) {
@@ -149,11 +179,9 @@ export const ExplorerOracleSpecByIdDocument = gql`
query ExplorerOracleSpecById($id: ID!) {
oracleSpec(oracleSpecId: $id) {
...ExplorerOracleDataSource
...ExplorerOracleDataConnection
}
}
${ExplorerOracleDataSourceFragmentDoc}
${ExplorerOracleDataConnectionFragmentDoc}`;
${ExplorerOracleDataSourceFragmentDoc}`;
/**
* __useExplorerOracleSpecByIdQuery__
@@ -3,12 +3,12 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerOracleForMarketsMarketFragment = { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } } };
export type ExplorerOracleForMarketsMarketFragment = { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } | { __typename?: 'Perpetual', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForSettlementSchedule: { __typename?: 'DataSourceSpec', id: string } } | { __typename?: 'Spot' } } } };
export type ExplorerOracleFormMarketsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ExplorerOracleFormMarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } } } }> } | null };
export type ExplorerOracleFormMarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } | { __typename?: 'Perpetual', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForSettlementSchedule: { __typename?: 'DataSourceSpec', id: string } } | { __typename?: 'Spot' } } } } }> } | null };
export const ExplorerOracleForMarketsMarketFragmentDoc = gql`
fragment ExplorerOracleForMarketsMarket on Market {
@@ -24,6 +24,14 @@ export const ExplorerOracleForMarketsMarketFragmentDoc = gql`
id
}
}
... on Perpetual {
dataSourceSpecForSettlementData {
id
}
dataSourceSpecForSettlementSchedule {
id
}
}
}
}
}
@@ -1,23 +1,23 @@
import { render } from '@testing-library/react';
import { OracleData } from './oracle-data';
import type { ExplorerOracleDataConnectionFragment } from '../__generated__/Oracles';
import { type ExplorerOracleDataConnectionFragment } from '../__generated__/Oracles';
function renderComponent(data: ExplorerOracleDataConnectionFragment) {
type DataConnection = ExplorerOracleDataConnectionFragment['dataConnection'];
function renderComponent(
data: ExplorerOracleDataConnectionFragment['dataConnection']
) {
return <OracleData data={data} />;
}
describe('Oracle Data view', () => {
it('Renders nothing when data is null', () => {
const res = render(
renderComponent(null as unknown as ExplorerOracleDataConnectionFragment)
);
const res = render(renderComponent(null as unknown as DataConnection));
expect(res.container).toBeEmptyDOMElement();
});
it('Renders nothing when dataConnection is empty', () => {
const res = render(
renderComponent({} as ExplorerOracleDataConnectionFragment)
);
const res = render(renderComponent({} as DataConnection));
expect(res.container).toBeEmptyDOMElement();
});
it('Renders nothing when dataConnection has no edges', () => {
@@ -26,7 +26,7 @@ describe('Oracle Data view', () => {
dataConnection: {
edges: null,
},
} as ExplorerOracleDataConnectionFragment)
} as DataConnection)
);
expect(res.container).toBeEmptyDOMElement();
});
@@ -37,7 +37,7 @@ describe('Oracle Data view', () => {
dataConnection: {
edges: [],
},
} as unknown as ExplorerOracleDataConnectionFragment)
} as unknown as DataConnection)
);
expect(res.container).toBeEmptyDOMElement();
});
@@ -47,20 +47,18 @@ describe('Oracle Data view', () => {
it('Renders details component when there is data', () => {
const res = render(
renderComponent({
dataConnection: {
edges: [
{
node: {
externalData: {
data: {
broadcastAt: '2022-01-01',
},
edges: [
{
node: {
externalData: {
data: {
broadcastAt: '2022-01-01',
},
},
},
],
},
} as ExplorerOracleDataConnectionFragment)
},
],
} as DataConnection)
);
expect(res.getByText('Broadcast data')).toBeInTheDocument();
});
@@ -4,7 +4,7 @@ import filter from 'recursive-key-filter';
import type { ExplorerOracleDataConnectionFragment } from '../__generated__/Oracles';
interface OracleDataTypeProps {
data: ExplorerOracleDataConnectionFragment;
data: ExplorerOracleDataConnectionFragment['dataConnection'];
}
/**
@@ -14,12 +14,7 @@ interface OracleDataTypeProps {
* that Does The Job, rather than because it's good.
*/
export function OracleData({ data }: OracleDataTypeProps) {
if (
!data ||
!data.dataConnection ||
!data.dataConnection.edges?.length ||
data.dataConnection.edges.length > 1
) {
if (!data || !data.edges?.length || data.edges.length > 1) {
return null;
}
@@ -27,7 +22,7 @@ export function OracleData({ data }: OracleDataTypeProps) {
<details data-testid="oracle-data">
<summary>{t('Broadcast data')}</summary>
<ul>
{data.dataConnection.edges.map((d) => {
{data.edges.map((d) => {
if (!d) {
return null;
}
@@ -10,7 +10,7 @@ interface OracleMarketsProps {
}
/**
* Slightly misleadlingly names, OracleMarkets lists the market (almost always singular)
* Slightly misleading names, OracleMarkets lists the market (almost always singular)
* to which an oracle is attached. It also checks what it triggers, by checking on the
* market whether it is attached to the dataSourceSpecForSettlementData or ..TradingTermination
*/
@@ -27,8 +27,10 @@ export function OracleMarkets({ id }: OracleMarketsProps) {
const m = markets.find((m) => {
const p = m.tradableInstrument.instrument.product;
if (
p.dataSourceSpecForSettlementData.id === id ||
p.dataSourceSpecForTradingTermination.id === id
((p.__typename === 'Future' || p.__typename === 'Perpetual') &&
p.dataSourceSpecForSettlementData.id === id) ||
('dataSourceSpecForTradingTermination' in p &&
p.dataSourceSpecForTradingTermination.id === id)
) {
return true;
}
@@ -36,15 +38,9 @@ export function OracleMarkets({ id }: OracleMarketsProps) {
});
if (m && m.id) {
const type =
id ===
m.tradableInstrument.instrument.product.dataSourceSpecForSettlementData
.id
? 'Settlement for'
: 'Termination for';
return (
<TableRow modifier="bordered">
<TableHeader scope="row">{type}</TableHeader>
<TableHeader scope="row">{getLabel(id, m)}</TableHeader>
<TableCell modifier="bordered" data-testid={`m-${m.id}`}>
<MarketLink id={m.id} />
</TableCell>
@@ -61,3 +57,38 @@ export function OracleMarkets({ id }: OracleMarketsProps) {
</TableRow>
);
}
export function getLabel(
id: string,
m: ExplorerOracleForMarketsMarketFragment | null
): string {
const settlementId =
((m?.tradableInstrument?.instrument?.product?.__typename === 'Future' ||
m?.tradableInstrument?.instrument?.product?.__typename === 'Perpetual') &&
m?.tradableInstrument?.instrument?.product
?.dataSourceSpecForSettlementData?.id) ||
null;
const terminationId =
(m?.tradableInstrument?.instrument?.product?.__typename === 'Future' &&
m?.tradableInstrument?.instrument?.product
?.dataSourceSpecForTradingTermination?.id) ||
null;
const settlementScheduleId =
(m?.tradableInstrument?.instrument?.product?.__typename === 'Perpetual' &&
m?.tradableInstrument?.instrument?.product
?.dataSourceSpecForSettlementSchedule?.id) ||
null;
switch (id) {
case settlementId:
return 'Settlement for';
case terminationId:
return 'Termination for';
case settlementScheduleId:
return 'Settlement schedule for';
default:
return 'Unknown';
}
}
@@ -67,6 +67,9 @@ export function OracleSigners({ sourceType }: OracleDetailsSignersProps) {
if (sourceType.__typename !== 'DataSourceDefinitionExternal') {
return null;
}
if (!('signers' in sourceType.sourceType)) {
return null;
}
const signers = sourceType.sourceType.signers;
if (!signers || signers.length === 0) {
@@ -22,7 +22,7 @@ export type SourceType =
interface OracleDetailsProps {
id: string;
dataSource: ExplorerOracleDataSourceFragment;
dataConnection?: ExplorerOracleDataConnectionFragment;
dataConnection: ExplorerOracleDataConnectionFragment['dataConnection'];
// Defaults to false. Hides the count of 'broadcasts' this oracle has seen
showBroadcasts?: boolean;
}
@@ -41,8 +41,7 @@ export const OracleDetails = ({
showBroadcasts = false,
}: OracleDetailsProps) => {
const sourceType = dataSource.dataSourceSpec.spec.data.sourceType;
const reportsCount: number =
dataConnection?.dataConnection.edges?.length || 0;
const reportsCount: number = dataConnection.edges?.length || 0;
return (
<div>
@@ -8,7 +8,9 @@ import { useScrollToLocation } from '../../../hooks/scroll-to-location';
import filter from 'recursive-key-filter';
const Oracles = () => {
const { data, loading, error } = useExplorerOracleSpecsQuery();
const { data, loading, error } = useExplorerOracleSpecsQuery({
errorPolicy: 'ignore',
});
useDocumentTitle(['Oracles']);
useScrollToLocation();
@@ -34,11 +36,20 @@ const Oracles = () => {
if (!id) {
return null;
}
const dataConnection = o?.node.dataConnection;
return (
<div id={id} key={id} className="mb-10">
<div
id={id}
key={id}
className="mb-10"
data-testid="oracle-details"
>
<OracleDetails
id={id}
dataSource={o?.node}
dataConnection={dataConnection}
showBroadcasts={false}
/>
<details>
@@ -39,7 +39,7 @@ export const Oracle = () => {
<OracleDetails
id={id || ''}
dataSource={data?.oracleSpec}
dataConnection={data?.oracleSpec}
dataConnection={data?.oracleSpec.dataConnection}
showBroadcasts={true}
/>
<details>
@@ -23,6 +23,9 @@ fragment ExplorerPartyAssetsAccounts on AccountBalance {
... on Future {
quoteName
}
... on Perpetual {
quoteName
}
}
}
}
@@ -48,9 +51,11 @@ query ExplorerPartyAssets($partyId: ID!) {
}
stakingSummary {
currentStakeAvailable
linkings(pagination: { first: 100 }) {
linkings(pagination: { last: 100 }) {
edges {
node {
type
status
amount
}
}
@@ -3,14 +3,14 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ExplorerPartyAssetsAccountsFragment = { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } | null };
export type ExplorerPartyAssetsAccountsFragment = { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } | { __typename?: 'Perpetual', quoteName: string } | { __typename?: 'Spot' } } } } | null };
export type ExplorerPartyAssetsQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type ExplorerPartyAssetsQuery = { __typename?: 'Query', partiesConnection?: { __typename?: 'PartyConnection', edges: Array<{ __typename?: 'PartyEdge', node: { __typename?: 'Party', id: string, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string, linkings: { __typename?: 'StakesConnection', edges?: Array<{ __typename?: 'StakeLinkingEdge', node: { __typename?: 'StakeLinking', amount: string } } | null> | null } }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } | null } } | null> | null } | null } }> } | null };
export type ExplorerPartyAssetsQuery = { __typename?: 'Query', partiesConnection?: { __typename?: 'PartyConnection', edges: Array<{ __typename?: 'PartyEdge', node: { __typename?: 'Party', id: string, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } } } | null> | null } | null, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string, linkings: { __typename?: 'StakesConnection', edges?: Array<{ __typename?: 'StakeLinkingEdge', node: { __typename?: 'StakeLinking', type: Types.StakeLinkingType, status: Types.StakeLinkingStatus, amount: string } } | null> | null } }, accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } }, market?: { __typename?: 'Market', id: string, decimalPlaces: number, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } | { __typename?: 'Perpetual', quoteName: string } | { __typename?: 'Spot' } } } } | null } } | null> | null } | null } }> } | null };
export const ExplorerPartyAssetsAccountsFragmentDoc = gql`
fragment ExplorerPartyAssetsAccounts on AccountBalance {
@@ -38,6 +38,9 @@ export const ExplorerPartyAssetsAccountsFragmentDoc = gql`
... on Future {
quoteName
}
... on Perpetual {
quoteName
}
}
}
}
@@ -64,9 +67,11 @@ export const ExplorerPartyAssetsDocument = gql`
}
stakingSummary {
currentStakeAvailable
linkings(pagination: {first: 100}) {
linkings(pagination: {last: 100}) {
edges {
node {
type
status
amount
}
}
@@ -42,9 +42,15 @@ export const PartyBlockStake = ({
linkedLength && linkedLength > 0
? p?.stakingSummary?.linkings?.edges
?.reduce((total, e) => {
return new BigNumber(total).plus(
new BigNumber(e?.node.amount || 0)
);
const accumulator = new BigNumber(total);
const diff = new BigNumber(e?.node.amount || 0);
if (e?.node.type === 'TYPE_LINK') {
return accumulator.plus(diff);
} else if (e?.node.type === 'TYPE_UNLINK') {
return accumulator.minus(diff);
} else {
return accumulator;
}
}, new BigNumber(0))
.toString()
: '0';
@@ -139,7 +139,7 @@ export const ValidatorsPage = () => {
const [vegaDialog, setVegaDialog] = useState<boolean>(false);
const [tmDialog, setTmDialog] = useState<boolean>(false);
const tokenLink = useLinks(DApp.Token);
const tokenLink = useLinks(DApp.Governance);
return (
<>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+20
View File
@@ -0,0 +1,20 @@
{
"short_name": "Mainnet Stats",
"name": "Vega Mainnet statistics",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
+3
View File
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
+27 -11
View File
@@ -1,23 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Explorer</title>
<base href="/" />
<link
rel="preload"
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
as="font"
type="font/woff2"
crossorigin="anonymous"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="utf-8" />
<link
rel="icon"
type="image/x-icon"
href="https://static.vega.xyz/favicon.ico"
/>
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Vega Protocol - VEGA Explorer" />
<meta name="og:type" content="website" />
<meta name="og:url" content="https://explorer.vega.xyz/" />
<meta name="og:title" content="Vega Protocol - Explorer" />
<meta name="og:site_name" content="Vega Protocol - Explorer" />
<meta name="og:image" content="https://static.vega.xyz/favicon.ico" />
<meta name="twitter:card" content="https://static.vega.xyz/favicon.ico" />
<meta name="twitter:title" content="Vega Protocol - Explorer" />
<meta name="twitter:description" content="Vega Protocol - Explorer" />
<meta name="twitter:image" content="https://static.vega.xyz/favicon.ico" />
<meta name="twitter:image:alt" content="VEGA logo" />
<meta name="twitter:site" content="@vegaprotocol" />
<meta name="description" content="Vega Protocol - Explorer" />
<link rel="apple-touch-icon" href="assets/apple-touch-icon.png" />
<link rel="manifest" href="assets/manifest.json" />
<link
rel="preload"
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
as="font"
type="font/woff2"
/>
<title>VEGA Explorer</title>
<script src="./assets/env-config.js"></script>
</head>
<body class="dark:bg-black h-full w-full">
+5 -11
View File
@@ -920,6 +920,8 @@ export interface components {
* - ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES: Per asset reward account for fees received by liquidity providers
* - ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS: Per asset reward account for market proposers when the market goes above some trading threshold
* - ACCOUNT_TYPE_HOLDING: Per asset account for holding in-flight unfilled orders' funds
* - ACCOUNT_TYPE_LP_LIQUIDITY_FEES: Network controlled liquidity provider's account, per market, to hold accrued liquidity fees.
* - ACCOUNT_TYPE_LIQUIDITY_FEES_BONUS_DISTRIBUTION: Network controlled liquidity fees bonus distribution account, per market.
* @default ACCOUNT_TYPE_UNSPECIFIED
* @enum {string}
*/
@@ -941,7 +943,9 @@ export interface components {
| 'ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES'
| 'ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES'
| 'ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS'
| 'ACCOUNT_TYPE_HOLDING';
| 'ACCOUNT_TYPE_HOLDING'
| 'ACCOUNT_TYPE_LP_LIQUIDITY_FEES'
| 'ACCOUNT_TYPE_LIQUIDITY_FEES_BONUS_DISTRIBUTION';
/** Vega representation of an external asset */
readonly vegaAssetDetails: {
/** @description Vega built-in asset. */
@@ -1449,11 +1453,6 @@ export interface components {
readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters'];
/** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */
readonly logNormal?: components['schemas']['vegaLogNormalRiskModel'];
/**
* @description Percentage move up and down from the mid price which specifies the range of
* price levels over which automated liquidity provision orders will be deployed.
*/
readonly lpPriceRange?: string;
/** @description Optional new futures market metadata, tags. */
readonly metadata?: readonly string[];
/**
@@ -1849,11 +1848,6 @@ export interface components {
readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters'];
/** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */
readonly logNormal?: components['schemas']['vegaLogNormalRiskModel'];
/**
* @description Percentage move up and down from the mid price which specifies the range of
* price levels over which automated liquidity provision orders will be deployed.
*/
readonly lpPriceRange?: string;
/** @description Optional futures market metadata, tags. */
readonly metadata?: readonly string[];
/** @description Price monitoring parameters. */
+13
View File
@@ -14,10 +14,23 @@ NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
NX_SUCCESSOR_MARKETS=true
NX_PRODUCT_PERPETUALS=true
NX_REFERRALS=true
NX_UPDATE_MARKET_STATE=true
NX_GOVERNANCE_TRANSFERS=true
NX_VOLUME_DISCOUNTS=true
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/pl/firefox/addon/vega-wallet
#Test configuration variables
CYPRESS_FAIRGROUND=false
+5
View File
@@ -3,3 +3,8 @@ NX_VEGA_ENV=DEVNET
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
NX_VOLUME_DISCOUNTS=true

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