Compare commits
469
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b589ca1405 | ||
|
|
6362c022b5 | ||
|
|
a6118c14dd | ||
|
|
d384fb35f1 | ||
|
|
3ed3714e79 | ||
|
|
3893b26d30 | ||
|
|
1ba0ad234b | ||
|
|
9f6a5aac39 | ||
|
|
129274a8e6 | ||
|
|
3fadda15fd | ||
|
|
7ea7edc1e2 | ||
|
|
dad953b45b | ||
|
|
ed1363b035 | ||
|
|
b2ab4f49d9 | ||
|
|
a60379b40f | ||
|
|
7db2a58f9d | ||
|
|
7279556bf7 | ||
|
|
52cc2ef7df | ||
|
|
a218da93a6 | ||
|
|
10fe82dea8 | ||
|
|
b0de4dfbf3 | ||
|
|
cd0e2e41a8 | ||
|
|
dc3330d55e | ||
|
|
a016feab2a | ||
|
|
68446ccf65 | ||
|
|
c7aec5cfcb | ||
|
|
f58144d785 | ||
|
|
415b902f53 | ||
|
|
165b131b27 | ||
|
|
0cff5895c7 | ||
|
|
31881f8e5a | ||
|
|
346af6118d | ||
|
|
bcbc3bb146 | ||
|
|
d7440cfe54 | ||
|
|
801606e37f | ||
|
|
01e7b8caee | ||
|
|
e883ef5c5e | ||
|
|
2f391cde5b | ||
|
|
3620314dca | ||
|
|
9bdd1ed387 | ||
|
|
37dc8bf110 | ||
|
|
3754043f8b | ||
|
|
1ee45b6135 | ||
|
|
a51410c722 | ||
|
|
91173d2434 | ||
|
|
8dd33c285e | ||
|
|
6a7385823a | ||
|
|
9053b343d1 | ||
|
|
6562107578 | ||
|
|
8f5bedc12a | ||
|
|
3044f3bdf7 | ||
|
|
5eb8fb64c7 | ||
|
|
ae84e16b9b | ||
|
|
5e5cc1c587 | ||
|
|
a3aa84b983 | ||
|
|
49374c8e7c | ||
|
|
8f4eeba092 | ||
|
|
66cceb0f34 | ||
|
|
b34fc98c9c | ||
|
|
e4ada295e2 | ||
|
|
805e8fbee7 | ||
|
|
24fafe5a34 | ||
|
|
df4cea8e00 | ||
|
|
52b25b8b15 | ||
|
|
b65db3cdad | ||
|
|
020d2e4e68 | ||
|
|
5ccef2de5e | ||
|
|
4ce2924380 | ||
|
|
f5b345636c | ||
|
|
c533c584da | ||
|
|
c1ebda9274 | ||
|
|
1b2c0e8f8b | ||
|
|
df6b9023f1 | ||
|
|
0702a97b6d | ||
|
|
c552a22af8 | ||
|
|
fbdcd04096 | ||
|
|
89d0723eb3 | ||
|
|
f163a270d1 | ||
|
|
e04314608f | ||
|
|
61c91c3542 | ||
|
|
2a9f3c7568 | ||
|
|
2640b7d77d | ||
|
|
2b229cd1e7 | ||
|
|
d098ee671e | ||
|
|
2c3c685522 | ||
|
|
b96e6ee9ce | ||
|
|
1a6266e2ec | ||
|
|
c70ec7676e | ||
|
|
5e97391d53 | ||
|
|
8eebd814ae | ||
|
|
bd754d1103 | ||
|
|
e362d06b5a | ||
|
|
45a4dd7009 | ||
|
|
ff53e5e841 | ||
|
|
cd0ed05eb8 | ||
|
|
89f41a4500 | ||
|
|
38fdc91444 | ||
|
|
f8f523eb9c | ||
|
|
5a0da4e158 | ||
|
|
4f7b589cbd | ||
|
|
e5bf54ca02 | ||
|
|
866a11fd89 | ||
|
|
b10effa3c7 | ||
|
|
1f1ca510f4 | ||
|
|
06151c0592 | ||
|
|
12a799a2fd | ||
|
|
e91a37684a | ||
|
|
b4a0e74457 | ||
|
|
11ba5e733e | ||
|
|
315c463eec | ||
|
|
62bfbd6822 | ||
|
|
290c2e3d42 | ||
|
|
c67daf885c | ||
|
|
c3944128eb | ||
|
|
c63d2a9bc6 | ||
|
|
e00998f9e3 | ||
|
|
61a5098776 | ||
|
|
9203c81084 | ||
|
|
8864696783 | ||
|
|
99d338f50a | ||
|
|
2b28ff6c18 | ||
|
|
6d3795f1f4 | ||
|
|
c0b84a88d3 | ||
|
|
5b0d799a00 | ||
|
|
9e6ecbc558 | ||
|
|
c3de7f12f0 | ||
|
|
473fdf8466 | ||
|
|
47c0ec01eb | ||
|
|
6410cb54b6 | ||
|
|
b8ff3d3050 | ||
|
|
d474a502a8 | ||
|
|
06e1b3663d | ||
|
|
38ff2c24e4 | ||
|
|
2689bbdcd2 | ||
|
|
c7b4465adf | ||
|
|
3f6913ab39 | ||
|
|
31ffa306eb | ||
|
|
13ab03c459 | ||
|
|
dd2e3a6556 | ||
|
|
4608683bde | ||
|
|
1f96ccea68 | ||
|
|
c055be1146 | ||
|
|
a316eaae9d | ||
|
|
996c4ac4d5 | ||
|
|
560e4a4040 | ||
|
|
d98ce18f9e | ||
|
|
0fd1739ce5 | ||
|
|
cf43566bde | ||
|
|
24a9712e91 | ||
|
|
03f5b5e78b | ||
|
|
9552fbc033 | ||
|
|
74a4a60195 | ||
|
|
ef35999091 | ||
|
|
cba44d7eb1 | ||
|
|
c5b72e5a64 | ||
|
|
863c288e0d | ||
|
|
a97512cc7b | ||
|
|
0884654c1e | ||
|
|
5b4440f767 | ||
|
|
cfbea6e894 | ||
|
|
774a7d697f | ||
|
|
dbb08acba3 | ||
|
|
6db201c1de | ||
|
|
54cd8324ed | ||
|
|
562e2b5cb2 | ||
|
|
ca2647d4d9 | ||
|
|
bbdc64582a | ||
|
|
dabae31bfd | ||
|
|
5b42a6ad35 | ||
|
|
870ae13b4c | ||
|
|
4c32a21f28 | ||
|
|
2ea603e59e | ||
|
|
3e485e3841 | ||
|
|
7766b3f118 | ||
|
|
8db3b01284 | ||
|
|
4fbd2e5eba | ||
|
|
53d3d5ac1c | ||
|
|
35de756120 | ||
|
|
f89cf31982 | ||
|
|
8976a40dc8 | ||
|
|
7669aeb218 | ||
|
|
6e996221b2 | ||
|
|
117c0c1306 | ||
|
|
e56d7bc2d5 | ||
|
|
85ec66a9e2 | ||
|
|
ba14ead8fc | ||
|
|
1211d27011 | ||
|
|
904a1b7805 | ||
|
|
66a8c659b4 | ||
|
|
f1a437500e | ||
|
|
29ced0b460 | ||
|
|
e45265ac71 | ||
|
|
cc3c339cc3 | ||
|
|
6f95989569 | ||
|
|
14f0c5a5fb | ||
|
|
0167a42990 | ||
|
|
1d65c4791c | ||
|
|
8a1fe6e5b1 | ||
|
|
437f7ef807 | ||
|
|
2b3683d4a4 | ||
|
|
6c84153cdb | ||
|
|
ccce5a2848 | ||
|
|
5673620fbd | ||
|
|
41d6940b89 | ||
|
|
84150bec8c | ||
|
|
5a311d14c9 | ||
|
|
0f152a4b30 | ||
|
|
45d8b537a3 | ||
|
|
dc41be5715 | ||
|
|
a85cf66419 | ||
|
|
6e82e917ac | ||
|
|
8dfdccd4aa | ||
|
|
82833cc06a | ||
|
|
aac3799b14 | ||
|
|
0d1c9ff0f1 | ||
|
|
f8eec8a056 | ||
|
|
ee6f26d473 | ||
|
|
de62d2d972 | ||
|
|
955e233c46 | ||
|
|
0bafa4c7d5 | ||
|
|
045529dc38 | ||
|
|
5ca3e4d90f | ||
|
|
9048d41f72 | ||
|
|
d731c4797c | ||
|
|
4a931ca134 | ||
|
|
3398b15d8a | ||
|
|
1e98ecbd21 | ||
|
|
a9c7c2bb46 | ||
|
|
ba2c71de67 | ||
|
|
15d2aed343 | ||
|
|
0284eaf9a2 | ||
|
|
c9c240cb29 | ||
|
|
64aa39fe4b | ||
|
|
485c609791 | ||
|
|
61457bc24d | ||
|
|
2217925285 | ||
|
|
28fe7458ca | ||
|
|
2cb88624f3 | ||
|
|
d2ae780996 | ||
|
|
bd129f1229 | ||
|
|
f3cd2db1ce | ||
|
|
418ea41e22 | ||
|
|
bcc1c8a474 | ||
|
|
496fdee10e | ||
|
|
c8fc91a3bd | ||
|
|
48cccc2678 | ||
|
|
9d66eeae51 | ||
|
|
7ab20d07f9 | ||
|
|
b0aa1b8a3e | ||
|
|
13ffe8a8d0 | ||
|
|
01420c56ff | ||
|
|
15bb7b94ad | ||
|
|
d65ef297a9 | ||
|
|
4062c493cb | ||
|
|
786ab51bd1 | ||
|
|
6cb2e3a3cf | ||
|
|
cf0e0ce4b2 | ||
|
|
9c21a4481a | ||
|
|
7a6c69d773 | ||
|
|
4f10a75386 | ||
|
|
9c26f4d01b | ||
|
|
b3bbe260c6 | ||
|
|
69a4ecdbde | ||
|
|
dbba734672 | ||
|
|
1c57ec4df1 | ||
|
|
f4fa0bd25a | ||
|
|
c2595b533d | ||
|
|
65316075fa | ||
|
|
46955dd933 | ||
|
|
024ed575fc | ||
|
|
871d7068da | ||
|
|
efbb75ec01 | ||
|
|
57c9ea9471 | ||
|
|
448f8f4ba5 | ||
|
|
5a5cd1daeb | ||
|
|
d7365c4b66 | ||
|
|
b6c448b630 | ||
|
|
87e1f9998e | ||
|
|
bdff40b4bc | ||
|
|
0b4f918208 | ||
|
|
df609d442c | ||
|
|
5730e39b32 | ||
|
|
83e9bc8ff6 | ||
|
|
a830e4729f | ||
|
|
e3ff090915 | ||
|
|
c5b6032184 | ||
|
|
cb80c6d417 | ||
|
|
b9ff2388db | ||
|
|
07b766e4d2 | ||
|
|
d19ef2607d | ||
|
|
af0b7391c9 | ||
|
|
9ea980c603 | ||
|
|
2741551c18 | ||
|
|
b06003990c | ||
|
|
377d219220 | ||
|
|
0f20f79a5e | ||
|
|
f658ae4d64 | ||
|
|
4e7192264c | ||
|
|
69ecf00999 | ||
|
|
cbb7189328 | ||
|
|
a05ff9c41a | ||
|
|
62b80a6438 | ||
|
|
4f76724e3e | ||
|
|
e20061d921 | ||
|
|
f133200c7f | ||
|
|
98d01d7933 | ||
|
|
0a3509faad | ||
|
|
070f2a2045 | ||
|
|
7a56e1695d | ||
|
|
bbfef16889 | ||
|
|
ba0211698f | ||
|
|
9f9d44e87d | ||
|
|
349eba7053 | ||
|
|
b28d671975 | ||
|
|
7d5cc9b080 | ||
|
|
dce802d153 | ||
|
|
6d646e3baf | ||
|
|
05b07c2bfe | ||
|
|
e653ad328f | ||
|
|
6b7a04176b | ||
|
|
ac44f4c553 | ||
|
|
b52386622c | ||
|
|
b47caa7667 | ||
|
|
071a9ab34b | ||
|
|
e49ad9da6a | ||
|
|
b508d7b252 | ||
|
|
817521bb08 | ||
|
|
f60e8a2910 | ||
|
|
a557678513 | ||
|
|
9ff68ecba3 | ||
|
|
48e0cf0808 | ||
|
|
c14e57cfd5 | ||
|
|
01addaea7c | ||
|
|
9002e63961 | ||
|
|
098bdb5e3a | ||
|
|
2514a2342b | ||
|
|
4600d6e4ca | ||
|
|
c217741924 | ||
|
|
1180a5ff97 | ||
|
|
71399105ee | ||
|
|
3bca206e45 | ||
|
|
044e9639e9 | ||
|
|
2cde42971e | ||
|
|
c6c320a2ff | ||
|
|
757cbd0f49 | ||
|
|
d70ff8d3d6 | ||
|
|
7ba2acefda | ||
|
|
03a1d10fe4 | ||
|
|
39f55cee5d | ||
|
|
5227d118fc | ||
|
|
16e095104f | ||
|
|
e6531daa41 | ||
|
|
7bf753e6c2 | ||
|
|
22610c2d0a | ||
|
|
4b86b981b3 | ||
|
|
615748548b | ||
|
|
13c9dffc3d | ||
|
|
fa8868d42a | ||
|
|
d382887b95 | ||
|
|
74265b25d7 | ||
|
|
2211abbd72 | ||
|
|
e5fe6a3106 | ||
|
|
86e4280680 | ||
|
|
e4afa67cd0 | ||
|
|
19c1f2f8c6 | ||
|
|
088c399b9f | ||
|
|
f1f775268f | ||
|
|
09af8db1fe | ||
|
|
def34a329d | ||
|
|
97a264d0b8 | ||
|
|
cbbec5c688 | ||
|
|
8880d7c5d7 | ||
|
|
ce04dd9ff2 | ||
|
|
e37185223f | ||
|
|
1bb3233fb2 | ||
|
|
0a11831ab0 | ||
|
|
9f1a1d7a1b | ||
|
|
c0566a91b2 | ||
|
|
827cdbecc7 | ||
|
|
d1e0af0dbf | ||
|
|
46a85b8e65 | ||
|
|
5db3b9c0b9 | ||
|
|
8f182a5877 | ||
|
|
8d88d2cea0 | ||
|
|
4ebb30c957 | ||
|
|
3486244137 | ||
|
|
7c15ee6c01 | ||
|
|
a4dd3cc49b | ||
|
|
ca5c3bc21d | ||
|
|
5cd6bf3d46 | ||
|
|
f1d4aa1862 | ||
|
|
75db3b3cbd | ||
|
|
777d330f8e | ||
|
|
8697561ed6 | ||
|
|
aafa3d7256 | ||
|
|
5531566e2f | ||
|
|
5da5c202f5 | ||
|
|
e2d7b1ee59 | ||
|
|
9d6a709fae | ||
|
|
639b586e85 | ||
|
|
bed81eed76 | ||
|
|
2d19796250 | ||
|
|
55b4279709 | ||
|
|
dfb04b4971 | ||
|
|
14632bae15 | ||
|
|
71c419a818 | ||
|
|
d5fef8729a | ||
|
|
8b74e63195 | ||
|
|
8639cf0ff6 | ||
|
|
3d760b8f15 | ||
|
|
8d08ede22d | ||
|
|
6352400598 | ||
|
|
30c440439e | ||
|
|
9ddedd0b78 | ||
|
|
9b356e53b4 | ||
|
|
4db5d37578 | ||
|
|
65564f1afc | ||
|
|
13d4c463cd | ||
|
|
7ba90904d8 | ||
|
|
3e75d64e0d | ||
|
|
3baad78bb7 | ||
|
|
a30f2227c4 | ||
|
|
cf2cfad746 | ||
|
|
972325b04a | ||
|
|
17736cc985 | ||
|
|
910a3e7a7f | ||
|
|
ac17bc4b64 | ||
|
|
399a3daa4c | ||
|
|
afd42f8a9a | ||
|
|
5d3a3a6f11 | ||
|
|
077700910b | ||
|
|
84814f3476 | ||
|
|
c450f57e8d | ||
|
|
6ba7ce5e7f | ||
|
|
d823daeea4 | ||
|
|
7c8a54b35a | ||
|
|
5bc861b5ec | ||
|
|
2f600207f7 | ||
|
|
b67bc33c49 | ||
|
|
03f659ebb3 | ||
|
|
96843cd2be | ||
|
|
af7a5630ac | ||
|
|
512149e491 | ||
|
|
aada0a805a | ||
|
|
9e935449ae | ||
|
|
d5b4ae7e53 | ||
|
|
995f1f1eaf | ||
|
|
02410df2d7 | ||
|
|
0d8f14e050 | ||
|
|
c2d2985e92 | ||
|
|
02f56dd0ec | ||
|
|
88263df9c2 | ||
|
|
71890d662a | ||
|
|
081c9f44ae | ||
|
|
c60e5841f7 | ||
|
|
96e082cb5d | ||
|
|
152574ebb3 | ||
|
|
b5f42ad715 | ||
|
|
86b0c6db3e | ||
|
|
3aed0b2e5f | ||
|
|
9c228c082f | ||
|
|
aa7bed137b | ||
|
|
1b4ffb6f1f | ||
|
|
e2e6ec40b7 | ||
|
|
8a9fa1efdc | ||
|
|
60d1434c40 | ||
|
|
d5efae6419 | ||
|
|
8489d50024 | ||
|
|
7af2580512 |
@@ -1,28 +0,0 @@
|
|||||||
inputs:
|
|
||||||
all:
|
|
||||||
description: 'Install all binaries'
|
|
||||||
default: false
|
|
||||||
version:
|
|
||||||
description: 'Vega version'
|
|
||||||
gobin:
|
|
||||||
description: 'GOBIN path'
|
|
||||||
default: '/home/runner/go/bin'
|
|
||||||
runs:
|
|
||||||
using: 'composite'
|
|
||||||
steps:
|
|
||||||
- name: Install Vega binaries
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ inputs.version }}/vega-linux-amd64.zip' -q
|
|
||||||
unzip vega-linux-amd64.zip -d ${{ inputs.gobin }}
|
|
||||||
|
|
||||||
- name: Checkout vegawallet-dummy
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
repository: 'vegaprotocol/vegawallet-dummy'
|
|
||||||
path: './dummy'
|
|
||||||
|
|
||||||
- name: Install vegawallet-dummy binaries
|
|
||||||
shell: bash
|
|
||||||
run: go install
|
|
||||||
working-directory: ./dummy
|
|
||||||
@@ -1,25 +1,17 @@
|
|||||||
inputs:
|
outputs:
|
||||||
github-token:
|
token:
|
||||||
description: 'github token'
|
description: 'api-token of wallet'
|
||||||
|
value: ${{ steps.generate-api-token.outputs.api-token }}
|
||||||
runs:
|
runs:
|
||||||
using: 'composite'
|
using: 'composite'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout capsule
|
- name: Vegacapsule version
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: vegaprotocol/vegacapsule
|
|
||||||
ref: main
|
|
||||||
token: ${{ inputs.github-token }}
|
|
||||||
path: './capsule'
|
|
||||||
|
|
||||||
- name: Build capsule
|
|
||||||
run: go install
|
|
||||||
shell: bash
|
shell: bash
|
||||||
working-directory: capsule
|
run: vegacapsule version
|
||||||
|
|
||||||
- name: Login to docker
|
- name: Vega wallet version
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo -n ${{ inputs.github-token }} | docker login https://ghcr.io -u vega-ci-bot --password-stdin
|
run: vega wallet software version
|
||||||
|
|
||||||
- name: Start nomad
|
- name: Start nomad
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -28,3 +20,32 @@ runs:
|
|||||||
- name: Bootstrap network
|
- name: Bootstrap network
|
||||||
shell: bash
|
shell: bash
|
||||||
run: vegacapsule network bootstrap --config-path=./frontend-monorepo/vegacapsule/config.hcl --force
|
run: vegacapsule network bootstrap --config-path=./frontend-monorepo/vegacapsule/config.hcl --force
|
||||||
|
|
||||||
|
- name: Initialize wallet
|
||||||
|
shell: bash
|
||||||
|
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
|
||||||
|
|
||||||
|
- name: Import wallet
|
||||||
|
shell: bash
|
||||||
|
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||||
|
|
||||||
|
- name: Generate second public key
|
||||||
|
shell: bash
|
||||||
|
run: vega wallet key generate -w capsule_wallet -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||||
|
|
||||||
|
- name: Import network
|
||||||
|
shell: bash
|
||||||
|
run: vega wallet network import --force --from-file ./frontend-monorepo/vegacapsule/wallet-config.toml --home ~/.vegacapsule/testnet/wallet
|
||||||
|
|
||||||
|
- name: Init api-token
|
||||||
|
shell: bash
|
||||||
|
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file ./frontend-monorepo/vegacapsule/passphrase
|
||||||
|
|
||||||
|
- name: Generate api-token
|
||||||
|
id: generate-api-token
|
||||||
|
shell: bash
|
||||||
|
run: echo api-token=$(vega wallet api-token generate --wallet-name capsule_wallet --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --wallet-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Start service using capsule network
|
||||||
|
shell: bash
|
||||||
|
run: vega wallet service run -n DV --load-tokens --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
inputs:
|
|
||||||
passphrase:
|
|
||||||
description: 'Wallet password'
|
|
||||||
runs:
|
|
||||||
using: 'composite'
|
|
||||||
steps:
|
|
||||||
- name: Create passphrase
|
|
||||||
shell: bash
|
|
||||||
run: echo "${{ inputs.passphrase }}" > ./passphrase
|
|
||||||
|
|
||||||
- name: Initialize wallet
|
|
||||||
shell: bash
|
|
||||||
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
|
|
||||||
|
|
||||||
- name: Import wallet
|
|
||||||
shell: bash
|
|
||||||
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
|
|
||||||
|
|
||||||
- name: Import network
|
|
||||||
shell: bash
|
|
||||||
run: vega wallet network import --force --from-file ./frontend-monorepo/vegacapsule/wallet-config.toml --home ~/.vegacapsule/testnet/wallet
|
|
||||||
|
|
||||||
- name: Start service using capsule network
|
|
||||||
shell: bash
|
|
||||||
run: vegawallet-dummy service run --network DV --wallet capsule_wallet --passphrase-file ./passphrase --home ~/.vegacapsule/testnet/wallet &
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
inputs:
|
|
||||||
recovery:
|
|
||||||
description: 'Recovery phrase'
|
|
||||||
passphrase:
|
|
||||||
description: 'Wallet password'
|
|
||||||
runs:
|
|
||||||
using: 'composite'
|
|
||||||
steps:
|
|
||||||
- name: Create passphrase
|
|
||||||
shell: bash
|
|
||||||
run: echo "${{ inputs.passphrase }}" > ./passphrase
|
|
||||||
|
|
||||||
- name: Create recovery
|
|
||||||
shell: bash
|
|
||||||
run: echo "${{ inputs.recovery }}" > ./recovery
|
|
||||||
|
|
||||||
- name: Initialize wallet
|
|
||||||
shell: bash
|
|
||||||
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
|
|
||||||
|
|
||||||
- name: Import wallet
|
|
||||||
shell: bash
|
|
||||||
run: vega wallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
|
|
||||||
|
|
||||||
- name: Create public key 2
|
|
||||||
shell: bash
|
|
||||||
run: vega wallet key generate -w UI_Trading_Test -p ./passphrase --home ~/.vegacapsule/testnet/wallet
|
|
||||||
|
|
||||||
- name: Import network
|
|
||||||
shell: bash
|
|
||||||
run: vega wallet network import --from-url="https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet3/vegawallet-stagnet3.toml" --force --home ~/.vegacapsule/testnet/wallet
|
|
||||||
|
|
||||||
- name: Start service using stagnet3 network
|
|
||||||
shell: bash
|
|
||||||
run: vegawallet-dummy service run --network stagnet3 --wallet UI_Trading_Test --passphrase-file ./passphrase --home ~/.vegacapsule/testnet/wallet &
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
name: Cypress tests -- manual trigger
|
|
||||||
|
|
||||||
# This workflow runs the frontend tests against chosen branch
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
project:
|
|
||||||
description: 'Project'
|
|
||||||
required: true
|
|
||||||
type: choice
|
|
||||||
options:
|
|
||||||
- console-lite-e2e
|
|
||||||
- explorer-e2e
|
|
||||||
- liquidity-provision-dashboard-e2e
|
|
||||||
- stats-e2e
|
|
||||||
- token-e2e
|
|
||||||
- trading-e2e
|
|
||||||
tags:
|
|
||||||
description: 'Test tags to run'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
default: '@smoke, @regression, @slow'
|
|
||||||
skip-nx-cache:
|
|
||||||
description: 'Add --skip-nx-cache to cypress test'
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
env:
|
|
||||||
GOBIN: /home/runner/go/bin
|
|
||||||
VEGA_VERSION: 'v0.62.1'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
manual:
|
|
||||||
name: Run Cypress tests -- manual trigger
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Set tags
|
|
||||||
run: echo TAGS="--env.grepTags '[ ${{ github.event.inputs.tags }} ]'" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set --skip-nx-cache flag
|
|
||||||
if: ${{ github.event.inputs.skip-nx-cache == 'true' }}
|
|
||||||
run: echo SKIP_NX_CACHE="--skip-nx-cache" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
vega-version: ${{env.VEGA_VERSION}}
|
|
||||||
gobin: ${{env.GOBIN}}
|
|
||||||
skip-cache: ${{env.SKIP_NX_CACHE}}
|
|
||||||
tags: ${{env.TAGS}}
|
|
||||||
|
|
||||||
dispatch:
|
|
||||||
needs: manual
|
|
||||||
uses: ./.github/workflows/tests-dispatcher.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
project: ${{ inputs.project }}
|
|
||||||
vega-version: ${{needs.manual.outputs.vega-version}}
|
|
||||||
gobin: ${{needs.manual.outputs.gobin}}
|
|
||||||
skip-cache: ${{needs.manual.outputs.skip-cache}}
|
|
||||||
tags: ${{needs.manual.outputs.tags}}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
name: Cypress tests -- night run
|
|
||||||
|
|
||||||
# This workflow runs the frontend tests against latest develop of the core to preempt breaking changes
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 4 * * *'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
nightly:
|
|
||||||
uses: ./.github/workflows/tests-dispatcher.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
project: '[console-lite-e2e, explorer-e2e, liquidity-provision-dashboard-e2e, stats-e2e, token-e2e, trading-e2e]'
|
|
||||||
vega-version: 'v0.62.1'
|
|
||||||
gobin: /home/runner/go/bin
|
|
||||||
tags: --env.grepTags '[ @smoke, @regression, @slow ]'
|
|
||||||
night-run: true
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
name: Cypress tests - PR
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- reopened
|
|
||||||
- synchronize
|
|
||||||
- ready_for_review
|
|
||||||
|
|
||||||
env:
|
|
||||||
GOBIN: /home/runner/go/bin
|
|
||||||
VEGA_VERSION: 'v0.62.1'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pr:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Checkout front ends
|
|
||||||
- name: Checkout frontend mono repo
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
path: './frontend-monorepo'
|
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
|
||||||
- name: Restore node_modules from cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
frontend-monorepo/node_modules
|
|
||||||
/home/runner/.cache/Cypress
|
|
||||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
- name: Install root dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
# Check SHAs
|
|
||||||
- name: Derive appropriate SHAs for base and head for `nx affected` commands
|
|
||||||
uses: nrwl/nx-set-shas@v2
|
|
||||||
with:
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
main-branch-name: ${{ github.base_ref || github.ref_name }}
|
|
||||||
set-environment-variables-for-job: true
|
|
||||||
|
|
||||||
# See affected projects
|
|
||||||
- name: See affected apps
|
|
||||||
run: echo AFFECTED=$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects) >> $GITHUB_ENV
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
projects: ${{ env.AFFECTED }}
|
|
||||||
vega-version: ${{ env.VEGA_VERSION }}
|
|
||||||
gobin: ${{ env.GOBIN }}
|
|
||||||
|
|
||||||
dispatch:
|
|
||||||
needs: pr
|
|
||||||
uses: ./.github/workflows/tests-dispatcher.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
project: ${{ needs.pr.outputs.projects }}
|
|
||||||
vega-version: ${{needs.pr.outputs.vega-version}}
|
|
||||||
gobin: ${{needs.pr.outputs.gobin}}
|
|
||||||
tags: "--env.grepTags='@smoke'"
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
name: Cypress - console-lite
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
trigger:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
default: 'false'
|
|
||||||
vega-version:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
gobin:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: /home/runner/go/bin
|
|
||||||
skip-cache:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
tags:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
console-lite-e2e:
|
|
||||||
if: ${{ inputs.trigger == 'true' }}
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
# Add GOBIN to PATH
|
|
||||||
- name: Add GOBIN to PATH
|
|
||||||
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
|
|
||||||
|
|
||||||
# Checkout front ends
|
|
||||||
- name: Checkout frontend mono repo
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
path: './frontend-monorepo'
|
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
|
||||||
- name: Restore node_modules from cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
frontend-monorepo/node_modules
|
|
||||||
/home/runner/.cache/Cypress
|
|
||||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
- name: Install root dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
#######
|
|
||||||
## Build and run Vegacapsule network
|
|
||||||
#######
|
|
||||||
|
|
||||||
- name: Install Vega binaries
|
|
||||||
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
|
|
||||||
with:
|
|
||||||
version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Setup a Vega wallet for our user
|
|
||||||
######
|
|
||||||
|
|
||||||
- name: Set up Vegawallet
|
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
|
|
||||||
with:
|
|
||||||
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
|
||||||
- name: Install cypress bins
|
|
||||||
run: yarn cypress install
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
- name: Run Cypress tests
|
|
||||||
run: npx nx run console-lite-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
env:
|
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
name: Cypress - explorer
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
trigger:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
default: 'false'
|
|
||||||
vega-version:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
gobin:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: /home/runner/go/bin
|
|
||||||
skip-cache:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
tags:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
night-run:
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
explorer-e2e:
|
|
||||||
if: ${{ inputs.trigger == 'true' }}
|
|
||||||
runs-on: self-hosted
|
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
|
||||||
# Add GOBIN to PATH
|
|
||||||
- name: Add GOBIN to PATH
|
|
||||||
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
|
|
||||||
|
|
||||||
# Checkout front ends
|
|
||||||
- name: Checkout frontend mono repo
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
path: './frontend-monorepo'
|
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
|
||||||
- name: Restore node_modules from cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
frontend-monorepo/node_modules
|
|
||||||
/home/runner/.cache/Cypress
|
|
||||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
- name: Install root dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
#######
|
|
||||||
## Build and run Vegacapsule network
|
|
||||||
#######
|
|
||||||
|
|
||||||
- name: Install Vega binaries
|
|
||||||
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
|
|
||||||
with:
|
|
||||||
version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
|
|
||||||
- name: Build and run Vegacapsule network
|
|
||||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Setup a Vega wallet for our user
|
|
||||||
######
|
|
||||||
|
|
||||||
- name: Set up Vegawallet for docker
|
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
|
||||||
with:
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Run some tests
|
|
||||||
######
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
|
||||||
- name: Install cypress bins
|
|
||||||
run: yarn cypress install
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
- name: Run Cypress tests
|
|
||||||
run: npx nx run explorer-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
env:
|
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
|
||||||
CYPRESS_NIGHTLY_RUN: ${{ inputs.night-run }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Upload logs
|
|
||||||
######
|
|
||||||
|
|
||||||
- name: Logs
|
|
||||||
run: vegacapsule network logs > vega-capsule-logs.txt
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: logs
|
|
||||||
path: ./vega-capsule-logs.txt
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
name: Cypress - liquidity provision dashboard
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
trigger:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
default: 'false'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
liquidity-provision-dashboard-e2e:
|
|
||||||
timeout-minutes: 10
|
|
||||||
if: ${{ inputs.trigger == 'true' }}
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
# Checkout front ends
|
|
||||||
- name: Checkout frontend mono repo
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
path: './frontend-monorepo'
|
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
|
||||||
- name: Restore node_modules from cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
frontend-monorepo/node_modules
|
|
||||||
/home/runner/.cache/Cypress
|
|
||||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
- name: Install root dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
|
||||||
- name: Install cypress bins
|
|
||||||
run: yarn cypress install
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
- name: Run Cypress tests
|
|
||||||
run: npx nx run liquidity-provision-dashboard-e2e:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
env:
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
name: Cypress tests -- manual trigger
|
||||||
|
|
||||||
|
# This workflow runs the frontend tests against chosen branch
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
project:
|
||||||
|
description: 'Project'
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- explorer-e2e
|
||||||
|
- token-e2e
|
||||||
|
- trading-e2e
|
||||||
|
tags:
|
||||||
|
description: 'Test tags to run'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: '@smoke @regression @slow'
|
||||||
|
skip-nx-cache:
|
||||||
|
description: 'Skip NX cache'
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
jobs:
|
||||||
|
manual:
|
||||||
|
uses: ./.github/workflows/cypress-run.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
projects: '["${{inputs.project}}"]'
|
||||||
|
skip-cache: ${{inputs.skip-nx-cache}}
|
||||||
|
tags: ${{inputs.tags}}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
name: Cypress tests -- night run
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 4 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
nightly:
|
||||||
|
uses: ./.github/workflows/cypress-run.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
projects: '["explorer-e2e","token-e2e","trading-e2e"]'
|
||||||
|
tags: '@smoke @regression @slow'
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
name: Cypress tests - PR
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- reopened
|
||||||
|
- synchronize
|
||||||
|
- ready_for_review
|
||||||
|
jobs:
|
||||||
|
pr:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout frontend mono repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Setup node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
|
||||||
|
- name: Remove package.json & yarn.lock to avoid installing everything
|
||||||
|
run: rm package.json yarn.lock
|
||||||
|
|
||||||
|
- name: Install nx
|
||||||
|
run: yarn add nx
|
||||||
|
|
||||||
|
# Check SHAs
|
||||||
|
- name: Derive appropriate SHAs for base and head for `nx affected` commands
|
||||||
|
uses: nrwl/nx-set-shas@v2
|
||||||
|
with:
|
||||||
|
main-branch-name: ${{ github.base_ref || github.ref_name }}
|
||||||
|
set-environment-variables-for-job: true
|
||||||
|
|
||||||
|
# See affected apps
|
||||||
|
- name: See affected apps
|
||||||
|
run: |
|
||||||
|
affected=$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)
|
||||||
|
echo -n "Affected projects: $affected"
|
||||||
|
projects=""
|
||||||
|
if [[ $affected == *"token"* ]]; then projects+='"token-e2e" '; fi
|
||||||
|
if [[ $affected == *"trading"* ]]; then projects+='"trading-e2e" '; fi
|
||||||
|
if [[ $affected == *"explorer"* ]]; then projects+='"explorer-e2e" '; fi
|
||||||
|
if [[ -z "$projects" ]]; then projects+='"token-e2e" "trading-e2e" "explorer-e2e" '; fi
|
||||||
|
projects=${projects%?}
|
||||||
|
projects=[${projects// /,}]
|
||||||
|
echo PROJECTS=$projects >> $GITHUB_ENV
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
projects: ${{ env.PROJECTS }}
|
||||||
|
|
||||||
|
run:
|
||||||
|
needs: pr
|
||||||
|
if: ${{ needs.pr.outputs.projects != '[]' }}
|
||||||
|
uses: ./.github/workflows/cypress-run.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
projects: ${{ needs.pr.outputs.projects }}
|
||||||
|
tags: '@smoke @regression'
|
||||||
|
|
||||||
|
# Report single result at the end, to avoid mess with required checks in PR
|
||||||
|
result:
|
||||||
|
if: ${{ always() }}
|
||||||
|
needs: run
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Cypress result
|
||||||
|
steps:
|
||||||
|
- run: |
|
||||||
|
result="${{ needs.run.result }}"
|
||||||
|
if [[ $result == "success" || $result == "skipped" ]]; then
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
projects:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
skip-cache:
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
tags:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
e2e:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
project: ${{ fromJSON(inputs.projects) }}
|
||||||
|
runs-on: self-hosted-runner
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
# Checks if skip cache was requested
|
||||||
|
- name: Set skip-nx-cache flag
|
||||||
|
if: ${{ inputs.skip-cache == true }}
|
||||||
|
run: echo "SKIP_CACHE=--skip-nx-cache" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Checkout front ends
|
||||||
|
- name: Checkout frontend mono repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
path: './frontend-monorepo'
|
||||||
|
|
||||||
|
# Restore node_modules from cache if possible
|
||||||
|
- name: Restore node_modules from cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
frontend-monorepo/node_modules
|
||||||
|
/home/runner/.cache/Cypress
|
||||||
|
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock', 'frontend-monorepo/package.json') }}
|
||||||
|
|
||||||
|
# Install frontend dependencies
|
||||||
|
- name: Install root dependencies
|
||||||
|
run: yarn install --frozen-lockfile
|
||||||
|
working-directory: frontend-monorepo
|
||||||
|
|
||||||
|
# Make sure that all Cypress binaries are installed properly
|
||||||
|
- name: Install cypress bins
|
||||||
|
run: yarn cypress install
|
||||||
|
working-directory: frontend-monorepo
|
||||||
|
|
||||||
|
######
|
||||||
|
## Setup Vegacapsule and Vega wallet
|
||||||
|
######
|
||||||
|
|
||||||
|
- name: Run Vegacapsule network and Vega wallet
|
||||||
|
id: setup-vega
|
||||||
|
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||||
|
|
||||||
|
######
|
||||||
|
## Run some tests
|
||||||
|
######
|
||||||
|
|
||||||
|
- name: Run Cypress tests
|
||||||
|
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
||||||
|
working-directory: frontend-monorepo
|
||||||
|
env:
|
||||||
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
|
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||||
|
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||||
|
CYPRESS_grepTags: ${{ inputs.tags }}
|
||||||
|
|
||||||
|
######
|
||||||
|
## Upload logs
|
||||||
|
######
|
||||||
|
|
||||||
|
# Artifact path is not valid: /ganache-1/capsule-logscolletor.stderr-2022-12-22T10:20:30Z.log. Contains the following character: Colon :
|
||||||
|
- name: Rename files to allow archive
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: |
|
||||||
|
while read -r file; do
|
||||||
|
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||||
|
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: ${{ always() }}
|
||||||
|
with:
|
||||||
|
name: logs-${{ matrix.project }}
|
||||||
|
path: /home/runner/.vegacapsule/testnet/logs
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
name: Cypress - stats
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
trigger:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
default: 'false'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stats-e2e:
|
|
||||||
runs-on: self-hosted
|
|
||||||
if: ${{ inputs.trigger == 'true' }}
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
# Checkout front ends
|
|
||||||
- name: Checkout frontend mono repo
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
path: './frontend-monorepo'
|
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
|
||||||
- name: Restore node_modules from cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
frontend-monorepo/node_modules
|
|
||||||
/home/runner/.cache/Cypress
|
|
||||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
- name: Install root dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
|
||||||
- name: Install cypress bins
|
|
||||||
run: yarn cypress install
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
- name: Run Cypress tests
|
|
||||||
run: npx nx run stats-e2e:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
env:
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
name: Cypress - token
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
trigger:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
default: 'false'
|
|
||||||
vega-version:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
gobin:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: /home/runner/go/bin
|
|
||||||
skip-cache:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
tags:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
token-e2e:
|
|
||||||
if: ${{ inputs.trigger == 'true' }}
|
|
||||||
runs-on: self-hosted
|
|
||||||
timeout-minutes: 60
|
|
||||||
steps:
|
|
||||||
# Add GOBIN to PATH
|
|
||||||
- name: Add GOBIN to PATH
|
|
||||||
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
|
|
||||||
|
|
||||||
# Checkout front ends
|
|
||||||
- name: Checkout frontend mono repo
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
path: './frontend-monorepo'
|
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
|
||||||
- name: Restore node_modules from cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
frontend-monorepo/node_modules
|
|
||||||
/home/runner/.cache/Cypress
|
|
||||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
- name: Install root dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
#######
|
|
||||||
## Build and run Vegacapsule network
|
|
||||||
#######
|
|
||||||
|
|
||||||
- name: Install Vega binaries
|
|
||||||
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
|
|
||||||
with:
|
|
||||||
version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
|
|
||||||
- name: Build and run Vegacapsule network
|
|
||||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Setup a Vega wallet for our user
|
|
||||||
######
|
|
||||||
|
|
||||||
- name: Set up Vegawallet for docker
|
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
|
||||||
with:
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Run some tests
|
|
||||||
######
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
|
||||||
- name: Install cypress bins
|
|
||||||
run: yarn cypress install
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
- name: Run Cypress tests
|
|
||||||
run: npx nx run token-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
env:
|
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Upload logs
|
|
||||||
######
|
|
||||||
|
|
||||||
- name: Logs
|
|
||||||
run: vegacapsule network logs > vega-capsule-logs.txt
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: logs
|
|
||||||
path: ./vega-capsule-logs.txt
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
name: Cypress - trading
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
trigger:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
default: 'false'
|
|
||||||
vega-version:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
gobin:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: /home/runner/go/bin
|
|
||||||
skip-cache:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
tags:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
trading-e2e:
|
|
||||||
if: ${{ inputs.trigger == 'true' }}
|
|
||||||
timeout-minutes: 30
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
# Add GOBIN to PATH
|
|
||||||
- name: Add GOBIN to PATH
|
|
||||||
run: echo ${{ inputs.gobin }} >> $GITHUB_PATH
|
|
||||||
|
|
||||||
# Checkout front ends
|
|
||||||
- name: Checkout frontend mono repo
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
path: './frontend-monorepo'
|
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
|
||||||
- name: Restore node_modules from cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
frontend-monorepo/node_modules
|
|
||||||
/home/runner/.cache/Cypress
|
|
||||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
- name: Install root dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
#######
|
|
||||||
## Build and run Vegacapsule network
|
|
||||||
#######
|
|
||||||
|
|
||||||
- name: Install Vega binaries
|
|
||||||
uses: ./frontend-monorepo/.github/actions/install-vega-binaries
|
|
||||||
with:
|
|
||||||
version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
|
|
||||||
######
|
|
||||||
## Setup a Vega wallet for our user
|
|
||||||
######
|
|
||||||
|
|
||||||
- name: Set up Vegawallet
|
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
|
|
||||||
with:
|
|
||||||
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
|
||||||
- name: Install cypress bins
|
|
||||||
run: yarn cypress install
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
|
|
||||||
- name: Run Cypress tests
|
|
||||||
run: npx nx run trading-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
|
||||||
working-directory: frontend-monorepo
|
|
||||||
env:
|
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
|
||||||
@@ -4,7 +4,7 @@ name: Publish docker containers
|
|||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
- 'v[0-9]+.[0-9]+.[0-9]+-pre[0-9]+'
|
- 'v[0-9]+.[0-9]+.[0-9]+-*'
|
||||||
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
project:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
vega-version:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
gobin:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: /home/runner/go/bin
|
|
||||||
skip-cache:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
tags:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
night-run:
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
run-console-lite-e2e:
|
|
||||||
uses: ./.github/workflows/cypress-console-lite-e2e.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
trigger: ${{ contains(inputs.project, 'console-lite-e2e') || contains(inputs.project, 'console-lite') }}
|
|
||||||
vega-version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
skip-cache: ${{ inputs.skip-cache }}
|
|
||||||
tags: ${{ inputs.tags }}
|
|
||||||
|
|
||||||
run-explorer-e2e:
|
|
||||||
uses: ./.github/workflows/cypress-explorer-e2e.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
trigger: ${{ contains(inputs.project, 'explorer-e2e') || contains(inputs.project, 'explorer') }}
|
|
||||||
vega-version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
skip-cache: ${{ inputs.skip-cache }}
|
|
||||||
tags: ${{ inputs.tags }}
|
|
||||||
night-run: ${{ inputs.night-run }}
|
|
||||||
|
|
||||||
run-liquidity-e2e:
|
|
||||||
uses: ./.github/workflows/cypress-liquidity-provision-dashboard-e2e.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
trigger: ${{ contains(inputs.project, 'liquidity-provision-dashboard-e2e') || contains(inputs.project, 'liquidity-provision-dashboard') }}
|
|
||||||
|
|
||||||
run-stats-e2e:
|
|
||||||
uses: ./.github/workflows/cypress-stats-e2e.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
trigger: ${{ contains(inputs.project, 'stats-e2e') || contains(inputs.project, 'stats') }}
|
|
||||||
|
|
||||||
run-token-e2e:
|
|
||||||
uses: ./.github/workflows/cypress-token-e2e.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
trigger: ${{ contains(inputs.project, 'token-e2e') || contains(inputs.project, 'token') }}
|
|
||||||
vega-version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
skip-cache: ${{ inputs.skip-cache }}
|
|
||||||
tags: ${{ inputs.tags }}
|
|
||||||
|
|
||||||
run-trading-e2e:
|
|
||||||
uses: ./.github/workflows/cypress-trading-e2e.yml
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
trigger: ${{ contains(inputs.project, 'trading-e2e') || contains(inputs.project, 'trading') }}
|
|
||||||
vega-version: ${{ inputs.vega-version }}
|
|
||||||
gobin: ${{ inputs.gobin }}
|
|
||||||
skip-cache: ${{ inputs.skip-cache }}
|
|
||||||
tags: ${{ inputs.tags }}
|
|
||||||
@@ -1 +1,2 @@
|
|||||||
* @vegaprotocol/frontend
|
* @vegaprotocol/frontend
|
||||||
|
*.graphql @vegaprotocol/core
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ The utility dApp for interacting with the Vega token and using its' utility. Thi
|
|||||||
|
|
||||||
The block explorer for the Vega network, showing details of raw chain states and the state of markets on the Vega network.
|
The block explorer for the Vega network, showing details of raw chain states and the state of markets on the Vega network.
|
||||||
|
|
||||||
### [Stats](./apps/stats)
|
|
||||||
|
|
||||||
An application for the status of the Vega network. Showing block height and other network activity.
|
|
||||||
|
|
||||||
### [Static](./apps/static)
|
### [Static](./apps/static)
|
||||||
|
|
||||||
Hosting for static content being shared across apps, for example fonts.
|
Hosting for static content being shared across apps, for example fonts.
|
||||||
@@ -88,12 +84,12 @@ Run `nx test my-app` to execute the unit tests with [Jest](https://jestjs.io), o
|
|||||||
|
|
||||||
### Using wallet
|
### Using wallet
|
||||||
|
|
||||||
To run tests locally using your own wallets you can add the following environment variables to `cypress.json`
|
To run tests locally using your own wallets make sure you have generated at least two public keys and update the following environment variables in `cypress.config.js` to match your wallet.
|
||||||
|
|
||||||
1. Change `TRADING_TEST_VEGA_WALLET_NAME` to your Vega wallet name
|
1. Set `VEGA_PUBLIC_KEY` and `TRUNCATED_VEGA_PUBLIC_KEY` to your first public key.
|
||||||
2. Add `TRADING_TEST_VEGA_WALLET_PASSPHRASE` as your wallet passphrase
|
2. Set `VEGA_PUBLIC_KEY2` and `TRUNCATED_VEGA_PUBLIC_KEY2` to your second public key.
|
||||||
3. Add `ETH_WALLET_MNEMONIC` as your Ethereum wallet mnemonic
|
3. Set `TRADING_TEST_VEGA_WALLET_PASSPHRASE` as your wallet passphrase
|
||||||
4. Use [vegawallet-dummy](https://github.com/vegaprotocol/vegawallet-dummy) to avoid being prompted in CLI during test execution.
|
4. Add `ETH_WALLET_MNEMONIC` as your Ethereum wallet mnemonic
|
||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
|
|
||||||
@@ -156,6 +152,23 @@ In order to run the bootstrap command to generate and start a new network, we mu
|
|||||||
vegacapsule network bootstrap --config-path=../frontend-monorepo/vegacapsule/config.hcl
|
vegacapsule network bootstrap --config-path=../frontend-monorepo/vegacapsule/config.hcl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
In order to setup and run vegawallet for e2e capsule tests, in a separate terminal window:
|
||||||
|
|
||||||
|
1. cd into `./vegacapsule`
|
||||||
|
2. run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash setup-vegawallet.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. copy generated `api-token` and paste the token into `CYPRESS_VEGA_WALLET_API_TOKEN` environment variable in either `apps/token-e2e/.env` or `apps/explorer-e2e/.env` depending on which project needs testing.
|
||||||
|
|
||||||
|
Note: The script is only needed if capsule was built for first time or fresh. To run existing wallet service for capsule:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vega wallet service run -n DV --load-tokens --tokens-passphrase-file passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet
|
||||||
|
```
|
||||||
|
|
||||||
# 📑 License
|
# 📑 License
|
||||||
|
|
||||||
[MIT](./LICENSE)
|
[MIT](./LICENSE)
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
# App configuration variables
|
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
|
||||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
|
||||||
NX_VEGA_ENV=STAGNET3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|
||||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
|
||||||
CYPRESS_VEGA_ENV=STAGNET3
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
|
||||||
"ignorePatterns": ["!**/*"],
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
||||||
"rules": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
const { defineConfig } = require('cypress');
|
|
||||||
module.exports = defineConfig({
|
|
||||||
projectId: 'et4snf',
|
|
||||||
|
|
||||||
e2e: {
|
|
||||||
setupNodeEvents(on, config) {
|
|
||||||
require('cypress-grep/src/plugin')(config);
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
baseUrl: 'http://localhost:4200',
|
|
||||||
fileServerFolder: '.',
|
|
||||||
fixturesFolder: false,
|
|
||||||
specPattern: './src/integration/*.ts',
|
|
||||||
excludeSpecPattern: '**/*.js',
|
|
||||||
modifyObstructiveCode: false,
|
|
||||||
supportFile: './src/support/index.js',
|
|
||||||
video: false,
|
|
||||||
videoUploadOnPasses: false,
|
|
||||||
videosFolder: '../../dist/cypress/apps/console-lite-e2e/videos',
|
|
||||||
screenshotsFolder: '../../dist/cypress/apps/console-lite-e2e/screenshots',
|
|
||||||
chromeWebSecurity: false,
|
|
||||||
viewportWidth: 1440,
|
|
||||||
viewportHeight: 900,
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
TRADING_TEST_VEGA_WALLET_NAME: 'UI_Trading_Test',
|
|
||||||
ETHEREUM_PROVIDER_URL:
|
|
||||||
'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
|
|
||||||
VEGA_PUBLIC_KEY:
|
|
||||||
'47836c253520d2661bf5bed6339c0de08fd02cf5d4db0efee3b4373f20c7d278',
|
|
||||||
VEGA_PUBLIC_KEY2:
|
|
||||||
'1a18cdcaaa4f44a57b35a4e9b77e0701c17a476f2b407620f8c17371740cf2e4',
|
|
||||||
TRUNCATED_VEGA_PUBLIC_KEY: '47836c…c7d278',
|
|
||||||
TRUNCATED_VEGA_PUBLIC_KEY2: '1a18cd…0cf2e4',
|
|
||||||
ETHEREUM_WALLET_ADDRESS: '0x265Cc6d39a1B53d0d92068443009eE7410807158',
|
|
||||||
ETHERSCAN_URL: 'https://sepolia.etherscan.io',
|
|
||||||
tsConfig: 'tsconfig.json',
|
|
||||||
TAGS: 'not @todo and not @ignore and not @manual',
|
|
||||||
TRADING_TEST_VEGA_WALLET_PASSPHRASE: '123',
|
|
||||||
ETH_WALLET_MNEMONIC:
|
|
||||||
'ugly gallery notice network true range brave clarify flat logic someone chunk',
|
|
||||||
grepTags: '@regression @smoke @slow',
|
|
||||||
grepFilterSpecs: true,
|
|
||||||
grepOmitFiltered: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
declare module '*.scss';
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
||||||
"sourceRoot": "apps/console-lite-e2e/src",
|
|
||||||
"projectType": "application",
|
|
||||||
"targets": {
|
|
||||||
"e2e": {
|
|
||||||
"executor": "@nrwl/cypress:cypress",
|
|
||||||
"options": {
|
|
||||||
"cypressConfig": "apps/console-lite-e2e/cypress.config.js",
|
|
||||||
"devServerTarget": "console-lite:serve"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "console-lite:serve:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"executor": "@nrwl/linter:eslint",
|
|
||||||
"outputs": ["{options.outputFile}"],
|
|
||||||
"options": {
|
|
||||||
"lintFilePatterns": ["apps/console-lite-e2e/**/*.{js,ts}"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"executor": "@nrwl/workspace:run-commands",
|
|
||||||
"outputs": [],
|
|
||||||
"options": {
|
|
||||||
"command": "yarn tsc --project ./apps/console-lite-e2e/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [],
|
|
||||||
"implicitDependencies": ["console-lite"]
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
|
||||||
import {
|
|
||||||
generateSimpleMarkets,
|
|
||||||
generateMarketsCandles,
|
|
||||||
} from '../support/mocks/generate-markets';
|
|
||||||
|
|
||||||
describe('simple trading app', { tags: '@smoke' }, () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
|
||||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
|
||||||
});
|
|
||||||
cy.visit('/');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('render', () => {
|
|
||||||
cy.get('#root').should('exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
describe('console lite header', { tags: '@smoke' }, () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
window.localStorage.setItem('theme', 'dark');
|
|
||||||
cy.visit('/');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('logo should linked home', () => {
|
|
||||||
cy.get('span').contains('Markets').click();
|
|
||||||
cy.location('pathname').should('eq', '/markets');
|
|
||||||
cy.getByTestId('header').find('a').click();
|
|
||||||
cy.location('pathname').should('eq', '/');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('theme switcher should switch theme', () => {
|
|
||||||
cy.get('#root').children().eq(0).as('Container');
|
|
||||||
cy.get('@Container').should('have.css', 'background-color', 'rgb(8, 8, 8)');
|
|
||||||
cy.getByTestId('theme-switcher').click();
|
|
||||||
cy.get('@Container').should(
|
|
||||||
'have.css',
|
|
||||||
'background-color',
|
|
||||||
'rgb(255, 255, 255)'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('wallet connector should open a dialog', () => {
|
|
||||||
cy.get('[role="dialog"]').should('not.exist');
|
|
||||||
cy.getByTestId('connect-vega-wallet').click();
|
|
||||||
cy.get('[role="dialog"]').should('be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
|
||||||
import type { MarketsQuery } from '@vegaprotocol/market-list';
|
|
||||||
import {
|
|
||||||
generateLongListMarkets,
|
|
||||||
generateSimpleMarkets,
|
|
||||||
generateMarketsCandles,
|
|
||||||
} from '../support/mocks/generate-markets';
|
|
||||||
|
|
||||||
describe('market list', { tags: '@smoke' }, () => {
|
|
||||||
describe('simple url', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
|
||||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
|
||||||
});
|
|
||||||
cy.visit('/markets');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('selects menus', () => {
|
|
||||||
cy.get('[aria-label="Sidebar Navigation Menu"] [aria-current]').should(
|
|
||||||
'have.text',
|
|
||||||
'Markets'
|
|
||||||
);
|
|
||||||
cy.getByTestId('state-trigger').should('have.text', 'Active');
|
|
||||||
cy.get('[aria-label="Future"]').click();
|
|
||||||
cy.get('[data-testid="market-assets-menu"] a.active').should(
|
|
||||||
'have.text',
|
|
||||||
'All'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('navigation should make possibly shortest url', () => {
|
|
||||||
cy.location('pathname').should('equal', '/markets');
|
|
||||||
|
|
||||||
cy.getByTestId('state-trigger').click();
|
|
||||||
cy.get('[role=menuitemcheckbox]').contains('All').click();
|
|
||||||
cy.location('pathname').should('equal', '/markets/all');
|
|
||||||
|
|
||||||
cy.get('[aria-label="Future"]').click();
|
|
||||||
cy.location('pathname').should('eq', '/markets/all/Future');
|
|
||||||
let asset = '';
|
|
||||||
cy.getByTestId('market-assets-menu')
|
|
||||||
.children()
|
|
||||||
.then((children) => {
|
|
||||||
if (children.length > 1) {
|
|
||||||
asset = children[1].innerText;
|
|
||||||
if (asset) {
|
|
||||||
cy.wrap(children[1]).click();
|
|
||||||
cy.location('pathname').should(
|
|
||||||
'match',
|
|
||||||
new RegExp(`/markets/all/Future/${asset}`, 'i')
|
|
||||||
);
|
|
||||||
cy.get('a').contains('All Markets').click();
|
|
||||||
cy.location('pathname').should('eq', '/markets/all');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.getByTestId('state-trigger').click();
|
|
||||||
cy.get('[role=menuitemcheckbox]').contains('Active').click();
|
|
||||||
cy.location('pathname').should('equal', '/markets');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('url params should select filters', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
|
||||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('suspended status', () => {
|
|
||||||
cy.visit('/markets/Suspended');
|
|
||||||
cy.getByTestId('state-trigger').should('have.text', 'Suspended');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('last asset (if exists)', () => {
|
|
||||||
cy.visit('/markets');
|
|
||||||
cy.wait('@Markets').then((filters) => {
|
|
||||||
const data: MarketsQuery | undefined = filters?.response?.body?.data;
|
|
||||||
if (data?.marketsConnection?.edges.length) {
|
|
||||||
const asset =
|
|
||||||
data?.marketsConnection?.edges[0].node.tradableInstrument.instrument
|
|
||||||
.product.settlementAsset.symbol;
|
|
||||||
cy.visit(`/markets/Suspended/Future/${asset}`);
|
|
||||||
cy.getByTestId('market-assets-menu')
|
|
||||||
.find('a.active')
|
|
||||||
.should('have.text', asset);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Future product', () => {
|
|
||||||
cy.visit('/markets/Suspended/Future');
|
|
||||||
cy.getByTestId('market-products-menu')
|
|
||||||
.find('a.active')
|
|
||||||
.should('have.text', 'Future');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('long list of results should be handled properly', () => {
|
|
||||||
it('handles 1000 markets', () => {
|
|
||||||
cy.viewport(1440, 900);
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'Markets', generateLongListMarkets(1000));
|
|
||||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
|
||||||
});
|
|
||||||
performance.mark('start-1k');
|
|
||||||
cy.visit('/markets');
|
|
||||||
cy.get('.ag-center-cols-container', { timeout: 50000 }).then(() => {
|
|
||||||
performance.mark('end-1k');
|
|
||||||
performance.measure('load-1k', 'start-1k', 'end-1k');
|
|
||||||
const measure = performance.getEntriesByName('load-1k')[0];
|
|
||||||
expect(measure.duration).lte(20000);
|
|
||||||
cy.log(`Ag-grid 1k load took ${measure.duration} milliseconds.`);
|
|
||||||
|
|
||||||
cy.get('.ag-root').should('have.attr', 'aria-rowcount', '1001');
|
|
||||||
cy.get('.ag-center-cols-container')
|
|
||||||
.find('[role="row"]')
|
|
||||||
.its('length')
|
|
||||||
.then((length) => expect(length).to.be.closeTo(20, 3));
|
|
||||||
cy.get('.ag-cell-label-container').eq(4).click();
|
|
||||||
cy.get('body').then(($body) => {
|
|
||||||
for (let i = 0; i < 15; i++) {
|
|
||||||
cy.wrap($body).realPress('Tab', { pressDelay: 100 });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cy.focused().parent('.ag-row').should('have.attr', 'row-index', '14');
|
|
||||||
cy.get('.ag-center-cols-container')
|
|
||||||
.find('[role="row"]')
|
|
||||||
.its('length')
|
|
||||||
.then((length) => expect(length).to.be.closeTo(26, 2));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
import { connectVegaWallet } from '../support/vega-wallet';
|
|
||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
|
||||||
import {
|
|
||||||
generateMarket,
|
|
||||||
generateMarketData,
|
|
||||||
generateMarketsCandles,
|
|
||||||
generateMarketsData,
|
|
||||||
generateSimpleMarkets,
|
|
||||||
} from '../support/mocks/generate-markets';
|
|
||||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
|
||||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
|
||||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
|
||||||
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
|
|
||||||
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
|
||||||
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
|
||||||
import { generateMarketNames } from '../support/mocks/generate-market-names';
|
|
||||||
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
|
||||||
import type { Market, MarketsQuery } from '@vegaprotocol/market-list';
|
|
||||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
|
||||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
|
||||||
|
|
||||||
describe('market selector', { tags: '@smoke' }, () => {
|
|
||||||
let markets: Market[];
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
|
||||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
|
||||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
|
||||||
aliasQuery(req, 'MarketData', generateMarketData());
|
|
||||||
aliasQuery(req, 'Market', generateMarket());
|
|
||||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
|
||||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
|
||||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
|
||||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
|
||||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
|
||||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
|
||||||
aliasQuery(req, 'MarketNames', generateMarketNames());
|
|
||||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/markets');
|
|
||||||
cy.wait('@Markets').then((response) => {
|
|
||||||
const data: MarketsQuery | undefined = response?.response?.body?.data;
|
|
||||||
if (data?.marketsConnection?.edges.length) {
|
|
||||||
markets = data?.marketsConnection?.edges.map((edge) => edge.node);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be properly rendered', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('input[placeholder="Search"]').should(
|
|
||||||
'have.value',
|
|
||||||
markets[0].tradableInstrument.instrument.name
|
|
||||||
);
|
|
||||||
cy.getByTestId('arrow-button').click();
|
|
||||||
cy.getByTestId('market-pane').should('be.visible');
|
|
||||||
cy.getByTestId('market-pane')
|
|
||||||
.children()
|
|
||||||
.find('[role="button"]')
|
|
||||||
.first()
|
|
||||||
.should('contain.text', markets[0].tradableInstrument.instrument.name);
|
|
||||||
cy.getByTestId('market-pane')
|
|
||||||
.children()
|
|
||||||
.find('[role="button"]')
|
|
||||||
.first()
|
|
||||||
.click();
|
|
||||||
cy.getByTestId('market-pane').should('not.be.visible');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('typing should change list', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
|
||||||
cy.getByTestId('market-pane')
|
|
||||||
.children()
|
|
||||||
.find('[role="button"]')
|
|
||||||
.should('have.length.at.least', 1);
|
|
||||||
cy.get('input[placeholder="Search"]').clear();
|
|
||||||
cy.get('input[placeholder="Search"]').type('aa');
|
|
||||||
const filtered = markets.filter(
|
|
||||||
(market) =>
|
|
||||||
market.state === 'STATE_ACTIVE' &&
|
|
||||||
market.tradableInstrument.instrument.name.match(/aa/i)
|
|
||||||
);
|
|
||||||
cy.getByTestId('market-pane')
|
|
||||||
.children()
|
|
||||||
.find('[role="button"]')
|
|
||||||
.should('have.length', filtered.length);
|
|
||||||
cy.getByTestId('market-pane')
|
|
||||||
.children()
|
|
||||||
.find('[role="button"]')
|
|
||||||
.last()
|
|
||||||
.click();
|
|
||||||
cy.location('pathname').should(
|
|
||||||
'eq',
|
|
||||||
`/trading/${filtered[filtered.length - 1].id}`
|
|
||||||
);
|
|
||||||
cy.get('input[placeholder="Search"]').should(
|
|
||||||
'have.value',
|
|
||||||
filtered[filtered.length - 1].tradableInstrument.instrument.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// constantly failing on ci
|
|
||||||
it.skip('keyboard navigation should work well', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
|
||||||
cy.get('input[placeholder="Search"]').clear();
|
|
||||||
cy.focused().realPress('ArrowDown');
|
|
||||||
cy.focused().should('contain.text', 'AAVEDAI Monthly');
|
|
||||||
cy.focused().realPress('ArrowDown');
|
|
||||||
cy.focused().should('contain.text', 'ETHBTC').realPress('Enter');
|
|
||||||
cy.location('pathname').should('eq', '/trading/ethbtc-quaterly');
|
|
||||||
|
|
||||||
cy.get('input[placeholder="Search"]').type('{backspace}');
|
|
||||||
cy.get('input[placeholder="Search"]').clear();
|
|
||||||
cy.getByTestId('market-pane').should('be.visible');
|
|
||||||
cy.get('body').realPress('ArrowDown');
|
|
||||||
cy.get('body').realPress('Tab');
|
|
||||||
cy.getByTestId('market-pane').should('not.be.visible');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('mobile view', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.viewport('iphone-xr');
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('[role="dialog"]').should('not.exist');
|
|
||||||
cy.getByTestId('arrow-button').click();
|
|
||||||
cy.get('[role="dialog"]').should('be.visible');
|
|
||||||
cy.get('input[placeholder="Search"]').then((search) => {
|
|
||||||
cy.wrap(search).clear();
|
|
||||||
});
|
|
||||||
cy.getByTestId('market-pane')
|
|
||||||
.children()
|
|
||||||
.find('[role="button"]')
|
|
||||||
.should('have.length', 9);
|
|
||||||
cy.get('div[role="dialog"]').should('have.class', 'w-screen');
|
|
||||||
cy.getByTestId('dialog-close').click();
|
|
||||||
cy.get('input[placeholder="Search"]').should(
|
|
||||||
'have.value',
|
|
||||||
markets[0].tradableInstrument.instrument.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,331 +0,0 @@
|
|||||||
import { connectVegaWallet } from '../support/vega-wallet';
|
|
||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
|
||||||
import {
|
|
||||||
generateSimpleMarkets,
|
|
||||||
generateMarketsCandles,
|
|
||||||
generateMarketsData,
|
|
||||||
generateMarket,
|
|
||||||
generateMarketData,
|
|
||||||
} from '../support/mocks/generate-markets';
|
|
||||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
|
||||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
|
||||||
import { generateEstimateOrder } from '../support/mocks/generate-estimate-order';
|
|
||||||
import { generatePartyBalance } from '../support/mocks/generate-party-balance';
|
|
||||||
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
|
||||||
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
|
||||||
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
|
||||||
import type { MarketsQuery, Market } from '@vegaprotocol/market-list';
|
|
||||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
|
||||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
|
||||||
|
|
||||||
describe('Market trade', { tags: '@smoke' }, () => {
|
|
||||||
let markets: Market[];
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
|
||||||
aliasQuery(req, 'MarketsCandles', generateMarketsCandles());
|
|
||||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
|
||||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
|
||||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
|
||||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
|
||||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
|
||||||
aliasQuery(req, 'PartyBalance', generatePartyBalance());
|
|
||||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
|
||||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
|
||||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
|
||||||
aliasQuery(req, 'Market', generateMarket());
|
|
||||||
aliasQuery(req, 'MarketData', generateMarketData());
|
|
||||||
});
|
|
||||||
cy.visit('/markets');
|
|
||||||
cy.wait('@Markets').then((response) => {
|
|
||||||
const data: MarketsQuery | undefined = response?.response?.body?.data;
|
|
||||||
if (data?.marketsConnection?.edges.length) {
|
|
||||||
markets = data?.marketsConnection?.edges.map((edge) => edge.node);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not display steps if wallet is disconnected', () => {
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
cy.getByTestId('trading-connect-wallet')
|
|
||||||
.find('h3')
|
|
||||||
.should('have.text', 'Please connect your Vega wallet to make a trade');
|
|
||||||
cy.getByTestId('trading-connect-wallet')
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', 'Connect Vega wallet');
|
|
||||||
cy.getByTestId('trading-connect-wallet')
|
|
||||||
.find('a')
|
|
||||||
.should('have.text', 'https://vega.xyz/wallet');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('side selector should work well', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').should(
|
|
||||||
'have.text',
|
|
||||||
'Long'
|
|
||||||
);
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').should(
|
|
||||||
'have.text',
|
|
||||||
'Short'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('side selector mobile view should work well', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.viewport('iphone-xr');
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.getByTestId('next-button').scrollIntoView().click();
|
|
||||||
|
|
||||||
cy.get('button[aria-label="Open long position"]').should(
|
|
||||||
'have.class',
|
|
||||||
'selected'
|
|
||||||
);
|
|
||||||
cy.get('button[aria-label="Open short position"]').should(
|
|
||||||
'not.have.class',
|
|
||||||
'selected'
|
|
||||||
);
|
|
||||||
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('button[aria-label="Open long position"]').should(
|
|
||||||
'not.have.class',
|
|
||||||
'selected'
|
|
||||||
);
|
|
||||||
cy.get('button[aria-label="Open short position"]').should(
|
|
||||||
'have.class',
|
|
||||||
'selected'
|
|
||||||
);
|
|
||||||
cy.getByTestId('next-button').scrollIntoView().click();
|
|
||||||
cy.get('#step-1-control').should(
|
|
||||||
'contain.html',
|
|
||||||
'aria-label="Selected value Short"'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('size slider should work well', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[1].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', '1');
|
|
||||||
cy.get('#step-2-panel').find('[role="slider"]').type('{rightarrow}');
|
|
||||||
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', '2');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('percentage selection should work well', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[1].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', '1');
|
|
||||||
|
|
||||||
cy.getByTestId('max-label').should('have.text', '21');
|
|
||||||
|
|
||||||
cy.getByTestId('percentage-selector')
|
|
||||||
.find('button')
|
|
||||||
.contains('Max')
|
|
||||||
.click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', '21');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('size input should work well', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[1].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', '1');
|
|
||||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('input')
|
|
||||||
.type('{backspace}2');
|
|
||||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', '2');
|
|
||||||
cy.get('button').contains('Max').click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('slippage value should be displayed', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[1].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('button').contains('Max').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dl')
|
|
||||||
.eq(2)
|
|
||||||
.find('dd')
|
|
||||||
.should('have.text', '0.02%');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('allow slippage value to be adjusted', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[1].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('button').contains('Max').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dl')
|
|
||||||
.eq(2)
|
|
||||||
.find('dd')
|
|
||||||
.should('have.text', '0.02%');
|
|
||||||
cy.get('#step-2-panel').find('dl').eq(2).find('button').click();
|
|
||||||
cy.get('#input-order-slippage')
|
|
||||||
.focus()
|
|
||||||
.type('{backspace}{backspace}{backspace}1');
|
|
||||||
|
|
||||||
cy.getByTestId('slippage-dialog').find('button').click();
|
|
||||||
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dl')
|
|
||||||
.eq(2)
|
|
||||||
.find('dd')
|
|
||||||
.should('have.text', '1%');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('notional position size should be present', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[1].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('button')
|
|
||||||
.should('have.text', '1');
|
|
||||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(0)
|
|
||||||
.find('input')
|
|
||||||
.type('{backspace}2');
|
|
||||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dt')
|
|
||||||
.eq(2)
|
|
||||||
.should('have.text', 'Est. Position Size (tDAI)');
|
|
||||||
cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('total fees should be displayed', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[1].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
|
||||||
cy.get('button[aria-label="Open short position"]').click();
|
|
||||||
cy.get('#step-2-control').click();
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dt')
|
|
||||||
.eq(3)
|
|
||||||
.should('have.text', 'Est. Fees (tDAI)');
|
|
||||||
cy.get('#step-2-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(3)
|
|
||||||
.should('have.text', '3.00 (3.03%)');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('order review should display proper calculations', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-3-control').click();
|
|
||||||
|
|
||||||
cy.getByTestId('review-trade')
|
|
||||||
.get('#contracts_tooltip_trigger')
|
|
||||||
.trigger('click')
|
|
||||||
.realTouch();
|
|
||||||
|
|
||||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
|
||||||
'The number of contracts determines'
|
|
||||||
);
|
|
||||||
cy.get('#step-3-panel').find('dd').eq(1).should('have.text', '1');
|
|
||||||
|
|
||||||
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
|
|
||||||
|
|
||||||
cy.get('#step-3-panel')
|
|
||||||
.find('dd')
|
|
||||||
.eq(3)
|
|
||||||
.should('have.text', '3.00 (3.03%)');
|
|
||||||
|
|
||||||
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
|
|
||||||
|
|
||||||
cy.getByTestId('place-order').should('be.enabled').click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('info tooltip on mobile view should work well', () => {
|
|
||||||
if (markets?.length) {
|
|
||||||
cy.viewport('iphone-xr');
|
|
||||||
cy.visit(`/trading/${markets[0].id}`);
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.get('#step-3-control').click();
|
|
||||||
|
|
||||||
// Start from the bottom tooltip to ensure the tooltip above
|
|
||||||
// can be interacted with
|
|
||||||
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
|
|
||||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
|
||||||
'The notional size represents the position size'
|
|
||||||
);
|
|
||||||
|
|
||||||
cy.getByTestId('review-trade')
|
|
||||||
.get('#contracts_tooltip_trigger')
|
|
||||||
.realTouch();
|
|
||||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
|
||||||
'The number of contracts determines'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
import { connectVegaWallet } from '../support/vega-wallet';
|
|
||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
|
||||||
import {
|
|
||||||
generatePositions,
|
|
||||||
emptyPositions,
|
|
||||||
generateMargins,
|
|
||||||
} from '../support/mocks/generate-positions';
|
|
||||||
import { generateAccounts } from '../support/mocks/generate-accounts';
|
|
||||||
import { generateAssets } from '../support/mocks/generate-assets';
|
|
||||||
import { generateOrders } from '../support/mocks/generate-orders';
|
|
||||||
import { generateFills } from '../support/mocks/generate-fills';
|
|
||||||
import {
|
|
||||||
generateFillsMarkets,
|
|
||||||
generateMarketsData,
|
|
||||||
generatePositionsMarkets,
|
|
||||||
} from '../support/mocks/generate-markets';
|
|
||||||
import { generateChainId } from '../support/mocks/generate-chain-id';
|
|
||||||
import { generateStatistics } from '../support/mocks/generate-statistics';
|
|
||||||
|
|
||||||
describe('Portfolio page - wallet', { tags: '@smoke' }, () => {
|
|
||||||
it('button for wallet connect should work', () => {
|
|
||||||
cy.visit('/');
|
|
||||||
cy.get('[href="/portfolio"]').eq(0).click();
|
|
||||||
cy.getByTestId('trading-connect-wallet').should('be.visible');
|
|
||||||
connectVegaWallet();
|
|
||||||
cy.getByTestId('trading-connect-wallet').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Portfolio page tabs', { tags: '@smoke' }, () => {
|
|
||||||
before(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Positions', generatePositions());
|
|
||||||
aliasQuery(req, 'Margins', generateMargins());
|
|
||||||
aliasQuery(req, 'Markets', generatePositionsMarkets());
|
|
||||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
|
||||||
aliasQuery(req, 'Accounts', generateAccounts());
|
|
||||||
aliasQuery(req, 'Assets', generateAssets());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('certain tabs should exist', () => {
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
connectVegaWallet();
|
|
||||||
|
|
||||||
cy.getByTestId('assets').click();
|
|
||||||
cy.location('pathname').should('eq', '/portfolio/assets');
|
|
||||||
|
|
||||||
cy.getByTestId('positions').click();
|
|
||||||
cy.location('pathname').should('eq', '/portfolio/positions');
|
|
||||||
|
|
||||||
cy.getByTestId('orders').click();
|
|
||||||
cy.location('pathname').should('eq', '/portfolio/orders');
|
|
||||||
|
|
||||||
cy.getByTestId('fills').click();
|
|
||||||
cy.location('pathname').should('eq', '/portfolio/fills');
|
|
||||||
|
|
||||||
cy.getByTestId('deposits').click();
|
|
||||||
cy.location('pathname').should('eq', '/portfolio/deposits');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Assets view', () => {
|
|
||||||
before(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Positions', generatePositions());
|
|
||||||
aliasQuery(req, 'Margins', generateMargins());
|
|
||||||
aliasQuery(req, 'Markets', generatePositionsMarkets());
|
|
||||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
|
||||||
aliasQuery(req, 'Accounts', generateAccounts());
|
|
||||||
aliasQuery(req, 'Assets', generateAssets());
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio/assets');
|
|
||||||
connectVegaWallet();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('data should be properly rendered', () => {
|
|
||||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 3);
|
|
||||||
cy.get(
|
|
||||||
'.ag-center-cols-container [row-id="ACCOUNT_TYPE_GENERAL-asset-id-null"]'
|
|
||||||
)
|
|
||||||
.find('button')
|
|
||||||
.click();
|
|
||||||
cy.getByTestId('dialog-title').should(
|
|
||||||
'have.text',
|
|
||||||
'Asset details - tEURO'
|
|
||||||
);
|
|
||||||
cy.getByTestId('dialog-close').click();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Positions view', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Positions', generatePositions());
|
|
||||||
aliasQuery(req, 'Accounts', generateAccounts());
|
|
||||||
aliasQuery(req, 'Margins', generateMargins());
|
|
||||||
aliasQuery(req, 'Markets', generatePositionsMarkets());
|
|
||||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
|
||||||
aliasQuery(req, 'Assets', generateAssets());
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio/positions');
|
|
||||||
connectVegaWallet();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('data should be properly rendered', () => {
|
|
||||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Orders view', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Orders', generateOrders());
|
|
||||||
aliasQuery(req, 'Markets', generateFillsMarkets());
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio/orders');
|
|
||||||
connectVegaWallet();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('data should be properly rendered', () => {
|
|
||||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 5);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Fills view', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Fills', generateFills());
|
|
||||||
aliasQuery(req, 'Markets', generateFillsMarkets());
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio/fills');
|
|
||||||
connectVegaWallet();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('data should be properly rendered', () => {
|
|
||||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 4);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Empty views', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', generateChainId());
|
|
||||||
aliasQuery(req, 'Statistics', generateStatistics());
|
|
||||||
aliasQuery(req, 'Positions', emptyPositions());
|
|
||||||
aliasQuery(req, 'Accounts', { party: null });
|
|
||||||
aliasQuery(req, 'Orders', { party: null });
|
|
||||||
aliasQuery(req, 'Fills', { party: null });
|
|
||||||
aliasQuery(req, 'Markets', {
|
|
||||||
marketsConnection: { edges: [], __typename: 'MarketConnection' },
|
|
||||||
});
|
|
||||||
aliasQuery(req, 'Assets', {
|
|
||||||
assetsConnection: { edges: null, __typename: 'AssetsConnection' },
|
|
||||||
});
|
|
||||||
aliasQuery(req, 'Margins', generateMargins());
|
|
||||||
aliasQuery(req, 'MarketsData', generateMarketsData());
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
connectVegaWallet();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('"No data to display" should be always displayed', () => {
|
|
||||||
cy.getByTestId('assets').click();
|
|
||||||
cy.get('div.flex.items-center.justify-center').should(
|
|
||||||
'contain.text',
|
|
||||||
'No data to display'
|
|
||||||
);
|
|
||||||
|
|
||||||
cy.getByTestId('positions').click();
|
|
||||||
cy.get('div.flex.items-center.justify-center').should(
|
|
||||||
'contain.text',
|
|
||||||
'No data to display'
|
|
||||||
);
|
|
||||||
|
|
||||||
cy.getByTestId('orders').click();
|
|
||||||
cy.get('div.flex.items-center.justify-center').should(
|
|
||||||
'contain.text',
|
|
||||||
'No data to display'
|
|
||||||
);
|
|
||||||
|
|
||||||
cy.getByTestId('fills').click();
|
|
||||||
cy.get('div.flex.items-center.justify-center').should(
|
|
||||||
'contain.text',
|
|
||||||
'No data to display'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// ***********************************************
|
|
||||||
// This example commands.js shows you how to
|
|
||||||
// create various custom commands and overwrite
|
|
||||||
// existing commands.
|
|
||||||
//
|
|
||||||
// For more comprehensive examples of custom
|
|
||||||
// commands please read more here:
|
|
||||||
// https://on.cypress.io/custom-commands
|
|
||||||
// ***********************************************
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
// ***********************************************************
|
|
||||||
// This example support/index.js is processed and
|
|
||||||
// loaded automatically before your test files.
|
|
||||||
//
|
|
||||||
// This is a great place to put global configuration and
|
|
||||||
// behavior that modifies Cypress.
|
|
||||||
//
|
|
||||||
// You can change the location of this file or turn off
|
|
||||||
// automatically serving support files with the
|
|
||||||
// 'supportFile' configuration option.
|
|
||||||
//
|
|
||||||
// You can read more here:
|
|
||||||
// https://on.cypress.io/configuration
|
|
||||||
// ***********************************************************
|
|
||||||
|
|
||||||
import '@vegaprotocol/cypress';
|
|
||||||
import 'cypress-real-events/support';
|
|
||||||
// Import commands.js using ES2015 syntax:
|
|
||||||
import './commands';
|
|
||||||
import registerCypressGrep from 'cypress-grep';
|
|
||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
|
||||||
registerCypressGrep();
|
|
||||||
|
|
||||||
before(() => {
|
|
||||||
// Mock chainId fetch which happens on every page for wallet connection
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
aliasQuery(req, 'ChainId', {
|
|
||||||
statistics: {
|
|
||||||
__typename: 'Statistics',
|
|
||||||
chainId:
|
|
||||||
Cypress.env('VEGA_ENV').toLowerCase() ||
|
|
||||||
'vega-fairground-202210041151',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
import type { Market } from '@vegaprotocol/market-list';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
export const protoCandles = [
|
|
||||||
{ open: '9556163', close: '9587028', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9587028',
|
|
||||||
close: '9769899',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9769899', close: '9586292', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9586292',
|
|
||||||
close: '9261774',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9261773', close: '9236369', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9236369',
|
|
||||||
close: '9226070',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9226077', close: '9233252', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9249854',
|
|
||||||
close: '9333038',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9333038', close: '9410371', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9410371',
|
|
||||||
close: '9626249',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9626247', close: '9493253', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9493253',
|
|
||||||
close: '9309054',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9309054', close: '9378428', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9378428',
|
|
||||||
close: '9352996',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9352996', close: '9451142', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9451142',
|
|
||||||
close: '9691070',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9691071', close: '9622031', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9622034',
|
|
||||||
close: '9519285',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9528904', close: '9671275', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9671275',
|
|
||||||
close: '9988454',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9982457', close: '10085537', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '10085537',
|
|
||||||
close: '9967390',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9967390', close: '9974844', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9974844',
|
|
||||||
close: '9940706',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const protoMarket: Market = {
|
|
||||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
state: Schema.MarketState.STATE_ACTIVE,
|
|
||||||
decimalPlaces: 5,
|
|
||||||
positionDecimalPlaces: 0,
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
close: '',
|
|
||||||
open: '',
|
|
||||||
},
|
|
||||||
fees: {
|
|
||||||
__typename: 'Fees',
|
|
||||||
factors: {
|
|
||||||
__typename: 'FeeFactors',
|
|
||||||
makerFee: '',
|
|
||||||
infrastructureFee: '',
|
|
||||||
liquidityFee: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
id: '',
|
|
||||||
code: 'AAVEDAI.MF21',
|
|
||||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:2839D9B2329C9E70',
|
|
||||||
'base:AAVE',
|
|
||||||
'quote:DAI',
|
|
||||||
'class:fx/crypto',
|
|
||||||
'monthly',
|
|
||||||
'sector:defi',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
quoteName: 'DAI',
|
|
||||||
settlementAsset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'asset-id',
|
|
||||||
symbol: 'tDAI',
|
|
||||||
decimals: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const singleMarket: SingleMarketFieldsFragment = {
|
|
||||||
...protoMarket,
|
|
||||||
tradableInstrument: {
|
|
||||||
...protoMarket.tradableInstrument,
|
|
||||||
instrument: {
|
|
||||||
...protoMarket.tradableInstrument.instrument,
|
|
||||||
product: {
|
|
||||||
...protoMarket.tradableInstrument.instrument.product,
|
|
||||||
settlementAsset: {
|
|
||||||
...protoMarket.tradableInstrument.instrument.product.settlementAsset,
|
|
||||||
id: 'dai-id',
|
|
||||||
name: 'DAI Name',
|
|
||||||
},
|
|
||||||
dataSourceSpecForTradingTermination: {
|
|
||||||
id: 'oid',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
depth: {
|
|
||||||
__typename: 'MarketDepth',
|
|
||||||
lastTrade: { price: '9893006', __typename: 'Trade' },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
import merge from 'lodash/merge';
|
|
||||||
import type { AccountsQuery } from '@vegaprotocol/accounts';
|
|
||||||
import { Schema as Types } from '@vegaprotocol/types';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
|
|
||||||
export const generateAccounts = (
|
|
||||||
override?: PartialDeep<AccountsQuery>
|
|
||||||
): AccountsQuery => {
|
|
||||||
const defaultAccounts: AccountsQuery = {
|
|
||||||
party: {
|
|
||||||
__typename: 'Party',
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
accountsConnection: {
|
|
||||||
__typename: 'AccountsConnection',
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
balance: '100000000',
|
|
||||||
market: null,
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'asset-id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
balance: '100000000',
|
|
||||||
market: {
|
|
||||||
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'asset-id-2',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
|
||||||
balance: '1000',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
|
||||||
},
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'asset-id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
|
||||||
balance: '1000',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
|
||||||
},
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'asset-id-2',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
balance: '100000000',
|
|
||||||
market: null,
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'asset-0',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return merge(defaultAccounts, override);
|
|
||||||
};
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
import merge from 'lodash/merge';
|
|
||||||
import type { AssetsQuery } from '@vegaprotocol/assets';
|
|
||||||
import { Schema as Types } from '@vegaprotocol/types';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
|
|
||||||
export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
|
||||||
const defaultAssets: AssetsQuery = {
|
|
||||||
assetsConnection: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'asset-id',
|
|
||||||
symbol: 'tEURO',
|
|
||||||
decimals: 5,
|
|
||||||
name: 'Euro',
|
|
||||||
source: {
|
|
||||||
__typename: 'ERC20',
|
|
||||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
|
||||||
lifetimeLimit: '1',
|
|
||||||
withdrawThreshold: '2',
|
|
||||||
},
|
|
||||||
quantum: '',
|
|
||||||
status: Types.AssetStatus.STATUS_ENABLED,
|
|
||||||
infrastructureFeeAccount: {
|
|
||||||
balance: '1',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
globalRewardPoolAccount: {
|
|
||||||
balance: '2',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
takerFeeRewardAccount: {
|
|
||||||
balance: '3',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
makerFeeRewardAccount: {
|
|
||||||
balance: '4',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
lpFeeRewardAccount: {
|
|
||||||
balance: '5',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
marketProposerRewardAccount: {
|
|
||||||
balance: '6',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'asset-id-2',
|
|
||||||
symbol: 'tDAI',
|
|
||||||
decimals: 5,
|
|
||||||
name: 'DAI',
|
|
||||||
source: {
|
|
||||||
__typename: 'ERC20',
|
|
||||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
|
||||||
lifetimeLimit: '1',
|
|
||||||
withdrawThreshold: '2',
|
|
||||||
},
|
|
||||||
quantum: '',
|
|
||||||
status: Types.AssetStatus.STATUS_ENABLED,
|
|
||||||
infrastructureFeeAccount: {
|
|
||||||
balance: '1',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
globalRewardPoolAccount: {
|
|
||||||
balance: '2',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
takerFeeRewardAccount: {
|
|
||||||
balance: '3',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
makerFeeRewardAccount: {
|
|
||||||
balance: '4',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
lpFeeRewardAccount: {
|
|
||||||
balance: '5',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
marketProposerRewardAccount: {
|
|
||||||
balance: '6',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'asset-0',
|
|
||||||
symbol: 'AST0',
|
|
||||||
decimals: 5,
|
|
||||||
name: 'Asto',
|
|
||||||
source: {
|
|
||||||
__typename: 'BuiltinAsset',
|
|
||||||
maxFaucetAmountMint: '3',
|
|
||||||
},
|
|
||||||
quantum: '',
|
|
||||||
status: Types.AssetStatus.STATUS_ENABLED,
|
|
||||||
infrastructureFeeAccount: {
|
|
||||||
balance: '0',
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
globalRewardPoolAccount: null,
|
|
||||||
takerFeeRewardAccount: null,
|
|
||||||
makerFeeRewardAccount: null,
|
|
||||||
lpFeeRewardAccount: null,
|
|
||||||
marketProposerRewardAccount: null,
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return merge(defaultAssets, override);
|
|
||||||
};
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import type { ChainIdQuery } from '@vegaprotocol/react-helpers';
|
|
||||||
import merge from 'lodash/merge';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
|
|
||||||
export const generateChainId = (
|
|
||||||
override?: PartialDeep<ChainIdQuery>
|
|
||||||
): ChainIdQuery => {
|
|
||||||
const defaultResult = {
|
|
||||||
statistics: {
|
|
||||||
__typename: 'Statistics',
|
|
||||||
chainId: Cypress.env('VEGA_ENV').toLowerCase() || 'test-chain-id',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return merge(defaultResult, override);
|
|
||||||
};
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
export const generateEstimateOrder = () => {
|
|
||||||
return {
|
|
||||||
estimateOrder: {
|
|
||||||
fee: {
|
|
||||||
__typename: 'TradeFee',
|
|
||||||
makerFee: '100000',
|
|
||||||
liquidityFee: '100000',
|
|
||||||
infrastructureFee: '100000',
|
|
||||||
},
|
|
||||||
marginLevels: {
|
|
||||||
initialLevel: '2844054.80937741220203',
|
|
||||||
__typename: 'MarginLevels',
|
|
||||||
},
|
|
||||||
__typename: 'OrderEstimate',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
import type { FillsQuery, FillFieldsFragment } from '@vegaprotocol/fills';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
import merge from 'lodash/merge';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
|
|
||||||
export const generateFills = (
|
|
||||||
override?: PartialDeep<FillsQuery>
|
|
||||||
): FillsQuery => {
|
|
||||||
const fills: FillFieldsFragment[] = [
|
|
||||||
generateFill({
|
|
||||||
buyer: {
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
generateFill({
|
|
||||||
id: '1',
|
|
||||||
seller: {
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
},
|
|
||||||
aggressor: Schema.Side.SIDE_SELL,
|
|
||||||
buyerFee: {
|
|
||||||
infrastructureFee: '5000',
|
|
||||||
},
|
|
||||||
market: {
|
|
||||||
id: 'market-1',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
generateFill({
|
|
||||||
id: '2',
|
|
||||||
seller: {
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
},
|
|
||||||
aggressor: Schema.Side.SIDE_BUY,
|
|
||||||
}),
|
|
||||||
generateFill({
|
|
||||||
id: '3',
|
|
||||||
aggressor: Schema.Side.SIDE_SELL,
|
|
||||||
market: {
|
|
||||||
id: 'market-2',
|
|
||||||
},
|
|
||||||
buyer: {
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
|
|
||||||
const defaultResult: FillsQuery = {
|
|
||||||
party: {
|
|
||||||
id: 'buyer-id',
|
|
||||||
tradesConnection: {
|
|
||||||
__typename: 'TradeConnection',
|
|
||||||
edges: fills.map((f) => {
|
|
||||||
return {
|
|
||||||
__typename: 'TradeEdge',
|
|
||||||
node: f,
|
|
||||||
cursor: '3',
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
pageInfo: {
|
|
||||||
__typename: 'PageInfo',
|
|
||||||
startCursor: '1',
|
|
||||||
endCursor: '2',
|
|
||||||
hasNextPage: false,
|
|
||||||
hasPreviousPage: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return merge(defaultResult, override);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const generateFill = (override?: PartialDeep<FillFieldsFragment>) => {
|
|
||||||
const defaultFill: FillFieldsFragment = {
|
|
||||||
__typename: 'Trade',
|
|
||||||
id: '0',
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
price: '10000000',
|
|
||||||
size: '50000',
|
|
||||||
buyOrder: 'buy-order',
|
|
||||||
sellOrder: 'sell-order',
|
|
||||||
aggressor: Schema.Side.SIDE_BUY,
|
|
||||||
buyer: {
|
|
||||||
__typename: 'Party',
|
|
||||||
id: 'buyer-id',
|
|
||||||
},
|
|
||||||
seller: {
|
|
||||||
__typename: 'Party',
|
|
||||||
id: 'seller-id',
|
|
||||||
},
|
|
||||||
buyerFee: {
|
|
||||||
__typename: 'TradeFee',
|
|
||||||
makerFee: '100',
|
|
||||||
infrastructureFee: '100',
|
|
||||||
liquidityFee: '100',
|
|
||||||
},
|
|
||||||
sellerFee: {
|
|
||||||
__typename: 'TradeFee',
|
|
||||||
makerFee: '200',
|
|
||||||
infrastructureFee: '200',
|
|
||||||
liquidityFee: '200',
|
|
||||||
},
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-0',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return merge(defaultFill, override);
|
|
||||||
};
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
import merge from 'lodash/merge';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
|
||||||
import type { MarketDepthQuery } from '../../../../../libs/market-depth/src/lib/__generated___/MarketDepth';
|
|
||||||
|
|
||||||
export const generateMarketDepth = (
|
|
||||||
override?: PartialDeep<MarketDepthQuery>
|
|
||||||
): MarketDepthQuery => {
|
|
||||||
const defaultResult: MarketDepthQuery = {
|
|
||||||
market: {
|
|
||||||
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
|
|
||||||
depth: {
|
|
||||||
sell: [
|
|
||||||
{
|
|
||||||
price: '9893007',
|
|
||||||
volume: '3',
|
|
||||||
numberOfOrders: '3',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893010',
|
|
||||||
volume: '4',
|
|
||||||
numberOfOrders: '4',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893012',
|
|
||||||
volume: '1',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893015',
|
|
||||||
volume: '1',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893017',
|
|
||||||
volume: '2',
|
|
||||||
numberOfOrders: '2',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893021',
|
|
||||||
volume: '4',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893025',
|
|
||||||
volume: '5',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893125',
|
|
||||||
volume: '4',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893135',
|
|
||||||
volume: '2',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893165',
|
|
||||||
volume: '5',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893175',
|
|
||||||
volume: '3',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893185',
|
|
||||||
volume: '3',
|
|
||||||
numberOfOrders: '3',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9894185',
|
|
||||||
volume: '1',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9894585',
|
|
||||||
volume: '1',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9895585',
|
|
||||||
volume: '4',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9896585',
|
|
||||||
volume: '2',
|
|
||||||
numberOfOrders: '2',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
buy: [
|
|
||||||
{
|
|
||||||
price: '9893005',
|
|
||||||
volume: '4',
|
|
||||||
numberOfOrders: '3',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893003',
|
|
||||||
volume: '2',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9893001',
|
|
||||||
volume: '1',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9892006',
|
|
||||||
volume: '3',
|
|
||||||
numberOfOrders: '2',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9891006',
|
|
||||||
volume: '2',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9891001',
|
|
||||||
volume: '1',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890101',
|
|
||||||
volume: '2',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890091',
|
|
||||||
volume: '5',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890081',
|
|
||||||
volume: '4',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890050',
|
|
||||||
volume: '2',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890040',
|
|
||||||
volume: '6',
|
|
||||||
numberOfOrders: '3',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890030',
|
|
||||||
volume: '6',
|
|
||||||
numberOfOrders: '2',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890021',
|
|
||||||
volume: '3',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890011',
|
|
||||||
volume: '1',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9890001',
|
|
||||||
volume: '11',
|
|
||||||
numberOfOrders: '1',
|
|
||||||
__typename: 'PriceLevel',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sequenceNumber: '1661773865550746910',
|
|
||||||
__typename: 'MarketDepth',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return merge(defaultResult, override);
|
|
||||||
};
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
export const generateMarketMarkPrice = () => {
|
|
||||||
return {
|
|
||||||
market: {
|
|
||||||
decimalPlaces: 5,
|
|
||||||
data: { markPrice: '692748', __typename: 'MarketData' },
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
import { protoMarket } from './commons';
|
|
||||||
|
|
||||||
export const generateMarketNames = () => {
|
|
||||||
return {
|
|
||||||
markets: [
|
|
||||||
{ ...protoMarket },
|
|
||||||
{
|
|
||||||
id: '1d7ddf67dac4924db03f5bf58571a7bcb1908d70c66580467717aabc5345b68a',
|
|
||||||
state: 'STATE_SUSPENDED',
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
code: 'AAPL.MF21',
|
|
||||||
name: 'Apple Monthly (30 Jun 2022)',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:4899E01009F1A721',
|
|
||||||
'quote:USD',
|
|
||||||
'ticker:AAPL',
|
|
||||||
'class:equities/single-stock-futures',
|
|
||||||
'sector:tech',
|
|
||||||
'listing_venue:NASDAQ',
|
|
||||||
'country:US',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: { quoteName: 'USD', __typename: 'Future' },
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '87ae87cd3244fc1fab4b0e2dad2437879864192bb969f3109b69293421644c8b',
|
|
||||||
state: 'STATE_SUSPENDED',
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
code: 'TSLA.QM21',
|
|
||||||
name: 'Tesla Quarterly (30 Jun 2022)',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:5A86B190C384997F',
|
|
||||||
'quote:EURO',
|
|
||||||
'ticker:TSLA',
|
|
||||||
'class:equities/single-stock-futures',
|
|
||||||
'sector:tech',
|
|
||||||
'listing_venue:NASDAQ',
|
|
||||||
'country:US',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: { quoteName: 'EURO', __typename: 'Future' },
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '69205712a854f1bbfb69fa3d11b60e01a1e249bafb5ece88115e7451e8ef07b3',
|
|
||||||
state: 'STATE_SUSPENDED',
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
code: 'BTCUSD.MF21',
|
|
||||||
name: 'BTCUSD Monthly (30 Jun 2022)',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:076BB86A5AA41E3E',
|
|
||||||
'base:BTC',
|
|
||||||
'quote:USD',
|
|
||||||
'class:fx/crypto',
|
|
||||||
'monthly',
|
|
||||||
'sector:crypto',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: { quoteName: 'USD', __typename: 'Future' },
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'ethbtc-quaterly',
|
|
||||||
state: 'STATE_ACTIVE',
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
code: 'ETHBTC.QM21',
|
|
||||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:1F0BB6EB5703B099',
|
|
||||||
'base:ETH',
|
|
||||||
'quote:BTC',
|
|
||||||
'class:fx/crypto',
|
|
||||||
'quarterly',
|
|
||||||
'sector:crypto',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: { quoteName: 'BTC', __typename: 'Future' },
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3c62b2714c4332d1a689a5352bff090e6aabccfd6bd87ce018936b38372530c9',
|
|
||||||
state: 'STATE_ACTIVE',
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
code: 'UNIDAI.MF21',
|
|
||||||
name: 'UNIDAI Monthly (30 Jun 2022)',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:3C58ED2A4A6C5D7E',
|
|
||||||
'base:UNI',
|
|
||||||
'quote:DAI',
|
|
||||||
'class:fx/crypto',
|
|
||||||
'monthly',
|
|
||||||
'sector:defi',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: { quoteName: 'DAI', __typename: 'Future' },
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
import type { MarketPositionsQuery } from '@vegaprotocol/deal-ticket';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
export const generateMarketPositions = (): MarketPositionsQuery => {
|
|
||||||
return {
|
|
||||||
party: {
|
|
||||||
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
|
||||||
accountsConnection: {
|
|
||||||
__typename: 'AccountsConnection',
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
asset: {
|
|
||||||
decimals: 5,
|
|
||||||
},
|
|
||||||
balance: '400000000000000000000',
|
|
||||||
market: {
|
|
||||||
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
type: Schema.AccountType.ACCOUNT_TYPE_MARGIN,
|
|
||||||
asset: {
|
|
||||||
decimals: 5,
|
|
||||||
},
|
|
||||||
balance: '265329',
|
|
||||||
market: {
|
|
||||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
positionsConnection: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
openVolume: '3',
|
|
||||||
market: {
|
|
||||||
id: '2751c508f9759761f912890f37fb3f97a00300bf7685c02a56a86e05facfe221',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
__typename: 'Position',
|
|
||||||
},
|
|
||||||
__typename: 'PositionEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
openVolume: '12',
|
|
||||||
market: {
|
|
||||||
id: 'ca7768f6de84bf86a21bbb6b0109d9659c81917b0e0339b2c262566c9b581a15',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
__typename: 'Position',
|
|
||||||
},
|
|
||||||
__typename: 'PositionEdge',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
__typename: 'PositionConnection',
|
|
||||||
},
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
export const generateMarketTags = () => {
|
|
||||||
return {
|
|
||||||
market: {
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:2839D9B2329C9E70',
|
|
||||||
'base:AAVE',
|
|
||||||
'quote:DAI',
|
|
||||||
'class:fx/crypto',
|
|
||||||
'monthly',
|
|
||||||
'sector:defi',
|
|
||||||
'settlement:2022-08-01',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,143 +0,0 @@
|
|||||||
import merge from 'lodash/merge';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
import type { OrdersQuery, OrderFieldsFragment } from '@vegaprotocol/orders';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
export const generateOrders = (
|
|
||||||
override?: PartialDeep<OrdersQuery>
|
|
||||||
): OrdersQuery => {
|
|
||||||
const orders: OrderFieldsFragment[] = [
|
|
||||||
{
|
|
||||||
__typename: 'Order',
|
|
||||||
id: '066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-0',
|
|
||||||
},
|
|
||||||
size: '10',
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
status: Schema.OrderStatus.STATUS_FILLED,
|
|
||||||
side: Schema.Side.SIDE_BUY,
|
|
||||||
remaining: '0',
|
|
||||||
price: '20000000',
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
|
||||||
createdAt: new Date(2020, 1, 30).toISOString(),
|
|
||||||
updatedAt: null,
|
|
||||||
expiresAt: null,
|
|
||||||
rejectionReason: null,
|
|
||||||
liquidityProvision: null,
|
|
||||||
peggedOrder: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Order',
|
|
||||||
id: '48DB6767E4E4E0F649C5A13ABFADE39F8451C27DA828DAF14B7A1E8E5EBDAD99',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-1',
|
|
||||||
},
|
|
||||||
size: '1',
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
status: Schema.OrderStatus.STATUS_FILLED,
|
|
||||||
side: Schema.Side.SIDE_BUY,
|
|
||||||
remaining: '0',
|
|
||||||
price: '100',
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
|
||||||
createdAt: new Date(2020, 1, 29).toISOString(),
|
|
||||||
updatedAt: null,
|
|
||||||
expiresAt: null,
|
|
||||||
rejectionReason: null,
|
|
||||||
liquidityProvision: null,
|
|
||||||
peggedOrder: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Order',
|
|
||||||
id: '4e93702990712c41f6995fcbbd94f60bb372ad12d64dfa7d96d205c49f790336',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-2',
|
|
||||||
},
|
|
||||||
size: '1',
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
status: Schema.OrderStatus.STATUS_FILLED,
|
|
||||||
side: Schema.Side.SIDE_BUY,
|
|
||||||
remaining: '0',
|
|
||||||
price: '20000',
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
|
||||||
createdAt: new Date(2020, 1, 28).toISOString(),
|
|
||||||
updatedAt: null,
|
|
||||||
expiresAt: null,
|
|
||||||
rejectionReason: null,
|
|
||||||
liquidityProvision: null,
|
|
||||||
peggedOrder: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Order',
|
|
||||||
id: '94737d2bafafa4bc3b80a56ef084ae52a983b91aa067c31e243c61a0f962a836',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-3',
|
|
||||||
},
|
|
||||||
size: '1',
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
status: Schema.OrderStatus.STATUS_ACTIVE,
|
|
||||||
side: Schema.Side.SIDE_BUY,
|
|
||||||
remaining: '0',
|
|
||||||
price: '100000',
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
|
||||||
createdAt: new Date(2020, 1, 27).toISOString(),
|
|
||||||
updatedAt: null,
|
|
||||||
expiresAt: null,
|
|
||||||
rejectionReason: null,
|
|
||||||
liquidityProvision: null,
|
|
||||||
peggedOrder: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Order',
|
|
||||||
id: '94aead3ca92dc932efcb503631b03a410e2a5d4606cae6083e2406dc38e52f78',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-3',
|
|
||||||
},
|
|
||||||
size: '10',
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
status: Schema.OrderStatus.STATUS_PARTIALLY_FILLED,
|
|
||||||
side: Schema.Side.SIDE_SELL,
|
|
||||||
remaining: '3',
|
|
||||||
price: '100000',
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
|
||||||
createdAt: new Date(2020, 1, 27).toISOString(),
|
|
||||||
updatedAt: null,
|
|
||||||
expiresAt: null,
|
|
||||||
liquidityProvision: null,
|
|
||||||
peggedOrder: null,
|
|
||||||
rejectionReason: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const defaultResult: OrdersQuery = {
|
|
||||||
party: {
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
ordersConnection: {
|
|
||||||
__typename: 'OrderConnection',
|
|
||||||
edges: orders.map((f) => {
|
|
||||||
return {
|
|
||||||
__typename: 'OrderEdge',
|
|
||||||
node: f,
|
|
||||||
cursor: f.id,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
pageInfo: {
|
|
||||||
__typename: 'PageInfo',
|
|
||||||
startCursor:
|
|
||||||
'066468C06549101DAF7BC51099E1412A0067DC08C246B7D8013C9D0CBF1E8EE7',
|
|
||||||
endCursor:
|
|
||||||
'94737d2bafafa4bc3b80a56ef084ae52a983b91aa067c31e243c61a0f962a836',
|
|
||||||
hasNextPage: false,
|
|
||||||
hasPreviousPage: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return merge(defaultResult, override);
|
|
||||||
};
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
import merge from 'lodash/merge';
|
|
||||||
import type { PartyBalanceQuery } from '@vegaprotocol/deal-ticket';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
import { Schema as Types } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
export const generatePartyBalance = (
|
|
||||||
override?: PartialDeep<PartyBalanceQuery>
|
|
||||||
): PartyBalanceQuery => {
|
|
||||||
const defaultResult: PartyBalanceQuery = {
|
|
||||||
party: {
|
|
||||||
accountsConnection: {
|
|
||||||
__typename: 'AccountsConnection',
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
balance: '88474051',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
asset: {
|
|
||||||
id: 'dai-id',
|
|
||||||
symbol: 'tDAI',
|
|
||||||
name: 'tDAI TEST',
|
|
||||||
decimals: 5,
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
balance: '100000000',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
asset: {
|
|
||||||
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
|
|
||||||
symbol: 'tEURO',
|
|
||||||
name: 'tEURO TEST',
|
|
||||||
decimals: 5,
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
balance: '3412867',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
asset: {
|
|
||||||
id: 'dai-id',
|
|
||||||
symbol: 'tDAI',
|
|
||||||
name: 'tDAI TEST',
|
|
||||||
decimals: 5,
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
balance: '70007',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
asset: {
|
|
||||||
id: 'dai-id',
|
|
||||||
symbol: 'tDAI',
|
|
||||||
name: 'tDAI TEST',
|
|
||||||
decimals: 5,
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return merge(defaultResult, override);
|
|
||||||
};
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import type { PartyMarketDataQuery } from '@vegaprotocol/deal-ticket';
|
|
||||||
import { Schema as Types } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
export const generatePartyMarketData = (): PartyMarketDataQuery => {
|
|
||||||
return {
|
|
||||||
party: {
|
|
||||||
id: '2e1ef32e5804e14232406aebaad719087d326afa5c648b7824d0823d8a46c8d1',
|
|
||||||
accountsConnection: {
|
|
||||||
__typename: 'AccountsConnection',
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
balance: '1200000',
|
|
||||||
asset: { id: 'fBTC', decimals: 5, __typename: 'Asset' },
|
|
||||||
market: null,
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'AccountEdge',
|
|
||||||
node: {
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
balance: '0.000000001',
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
|
||||||
decimals: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
marginsConnection: { edges: null, __typename: 'MarginConnection' },
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
import merge from 'lodash/merge';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
import type {
|
|
||||||
PositionsQuery,
|
|
||||||
PositionFieldsFragment,
|
|
||||||
MarginsQuery,
|
|
||||||
} from '@vegaprotocol/positions';
|
|
||||||
|
|
||||||
export const generatePositions = (
|
|
||||||
override?: PartialDeep<PositionsQuery>
|
|
||||||
): PositionsQuery => {
|
|
||||||
const nodes: PositionFieldsFragment[] = [
|
|
||||||
{
|
|
||||||
__typename: 'Position',
|
|
||||||
realisedPNL: '0',
|
|
||||||
openVolume: '6',
|
|
||||||
unrealisedPNL: '895000',
|
|
||||||
averageEntryPrice: '1129935',
|
|
||||||
updatedAt: '2022-07-28T15:09:34.441143Z',
|
|
||||||
market: {
|
|
||||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Position',
|
|
||||||
realisedPNL: '100',
|
|
||||||
openVolume: '20',
|
|
||||||
unrealisedPNL: '895000',
|
|
||||||
averageEntryPrice: '8509338',
|
|
||||||
updatedAt: '2022-07-28T15:09:34.441143Z',
|
|
||||||
market: {
|
|
||||||
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
realisedPNL: '0',
|
|
||||||
openVolume: '1',
|
|
||||||
unrealisedPNL: '-22519',
|
|
||||||
averageEntryPrice: '84400088',
|
|
||||||
updatedAt: '2022-07-28T14:53:54.725477Z',
|
|
||||||
market: {
|
|
||||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
__typename: 'Position',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const defaultResult: PositionsQuery = {
|
|
||||||
party: {
|
|
||||||
__typename: 'Party',
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
positionsConnection: {
|
|
||||||
__typename: 'PositionConnection',
|
|
||||||
edges: nodes.map((node) => {
|
|
||||||
return {
|
|
||||||
__typename: 'PositionEdge',
|
|
||||||
node,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return merge(defaultResult, override);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const emptyPositions = (): PositionsQuery => {
|
|
||||||
return {
|
|
||||||
party: {
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
positionsConnection: { edges: null, __typename: 'PositionConnection' },
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const generateMargins = (): MarginsQuery => {
|
|
||||||
return {
|
|
||||||
party: {
|
|
||||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
marginsConnection: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
__typename: 'MarginLevels',
|
|
||||||
maintenanceLevel: '0',
|
|
||||||
searchLevel: '0',
|
|
||||||
initialLevel: '0',
|
|
||||||
collateralReleaseLevel: '0',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
|
|
||||||
},
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'tDAI-id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
__typename: 'MarginLevels',
|
|
||||||
maintenanceLevel: '0',
|
|
||||||
searchLevel: '0',
|
|
||||||
initialLevel: '0',
|
|
||||||
collateralReleaseLevel: '0',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '0604e8c918655474525e1a95367902266ade70d318c2c908f0cca6e3d11dcb13',
|
|
||||||
},
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'tDAI-id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
__typename: 'MarginEdge',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
__typename: 'MarginLevels',
|
|
||||||
maintenanceLevel: '0',
|
|
||||||
searchLevel: '0',
|
|
||||||
initialLevel: '0',
|
|
||||||
collateralReleaseLevel: '0',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
|
|
||||||
},
|
|
||||||
asset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'tEURO-id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
__typename: 'MarginEdge',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
__typename: 'MarginConnection',
|
|
||||||
},
|
|
||||||
__typename: 'Party',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import type { StatisticsQuery } from '@vegaprotocol/environment';
|
|
||||||
import merge from 'lodash/merge';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
|
|
||||||
export const generateStatistics = (
|
|
||||||
override?: PartialDeep<StatisticsQuery>
|
|
||||||
): StatisticsQuery => {
|
|
||||||
const defaultResult = {
|
|
||||||
statistics: {
|
|
||||||
__typename: 'Statistics',
|
|
||||||
chainId: Cypress.env('VEGA_ENV').toLowerCase() || 'test-chain-id',
|
|
||||||
blockHeight: '11',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return merge(defaultResult, override);
|
|
||||||
};
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
export const connectVegaWallet = () => {
|
|
||||||
const form = 'rest-connector-form';
|
|
||||||
const walletName = Cypress.env('TRADING_TEST_VEGA_WALLET_NAME');
|
|
||||||
const walletPassphrase = Cypress.env('TRADING_TEST_VEGA_WALLET_PASSPHRASE');
|
|
||||||
cy.getByTestId('connect-vega-wallet').click();
|
|
||||||
cy.getByTestId('connectors-list')
|
|
||||||
.find('[data-testid="connector-gui"]')
|
|
||||||
.click();
|
|
||||||
cy.getByTestId(form).find('#wallet').click().type(walletName);
|
|
||||||
cy.getByTestId(form).find('#passphrase').click().type(walletPassphrase);
|
|
||||||
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
|
|
||||||
};
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"sourceMap": false,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"outDir": "../../dist/out-tsc",
|
|
||||||
"allowJs": true,
|
|
||||||
"types": ["cypress", "node", "cypress-real-events", "cypress-grep"]
|
|
||||||
},
|
|
||||||
"include": ["src/**/*.ts", "src/**/*.js", "./declaration.d.ts"]
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
[
|
|
||||||
"@nrwl/react/babel",
|
|
||||||
{
|
|
||||||
"runtime": "automatic"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"plugins": []
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# This file is used by:
|
|
||||||
# 1. autoprefixer to adjust CSS to support the below specified browsers
|
|
||||||
# 2. babel preset-env to adjust included polyfills
|
|
||||||
#
|
|
||||||
# For additional information regarding the format and rule options, please see:
|
|
||||||
# https://github.com/browserslist/browserslist#queries
|
|
||||||
#
|
|
||||||
# If you need to support different browsers in production, you may tweak the list below.
|
|
||||||
|
|
||||||
last 1 Chrome version
|
|
||||||
last 1 Firefox version
|
|
||||||
last 2 Edge major versions
|
|
||||||
last 2 Safari major version
|
|
||||||
last 2 iOS major versions
|
|
||||||
Firefox ESR
|
|
||||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/stagnet3-network.json"
|
|
||||||
NX_VEGA_ENV=STAGNET3
|
|
||||||
NX_VEGA_URL="https://api.stagnet3.vega.xyz/graphql"
|
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|
||||||
NX_VEGA_NETWORKS={"MAINNET":"https://alpha.console.vega.xyz"}
|
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# App configuration variables
|
|
||||||
NX_VEGA_URL=http://localhost:3028/query
|
|
||||||
NX_VEGA_ENV=LOCAL
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# App configuration variables
|
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json
|
|
||||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
|
||||||
NX_VEGA_ENV=DEVNET
|
|
||||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\"}
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|
||||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# App configuration variables
|
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
|
|
||||||
NX_VEGA_URL=https://api.vega.xyz/query
|
|
||||||
NX_VEGA_ENV=MAINNET
|
|
||||||
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
|
|
||||||
NX_VEGA_URL=https://api.sandbox.vega.xyz/graphql
|
|
||||||
NX_VEGA_ENV=SANDBOX
|
|
||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","STAGNET1":"https://stagnet1.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
|
|
||||||
NX_VEGA_EXPLORER_URL=https://sandbox.explorer.vega.xyz
|
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# App configuration variables
|
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
|
||||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
|
||||||
NX_VEGA_ENV=STAGNET3
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|
||||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# App configuration variables
|
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
|
||||||
NX_VEGA_URL=https://api.n12.testnet.vega.xyz/graphql
|
|
||||||
NX_VEGA_ENV=TESTNET
|
|
||||||
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
|
||||||
"ignorePatterns": ["!**/*", "__generated__", "__generated___"],
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
||||||
"rules": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": ["*.ts", "*.tsx"],
|
|
||||||
"rules": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": ["*.js", "*.jsx"],
|
|
||||||
"rules": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
export default {
|
|
||||||
displayName: 'console-lite',
|
|
||||||
preset: '../../jest.preset.js',
|
|
||||||
transform: {
|
|
||||||
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
|
|
||||||
'^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/next/babel'] }],
|
|
||||||
},
|
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
|
||||||
coverageDirectory: '../../coverage/apps/console-lite',
|
|
||||||
setupFilesAfterEnv: ['./setup-tests.ts'],
|
|
||||||
};
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
[[redirects]]
|
|
||||||
from = "/*"
|
|
||||||
to = "/index.html"
|
|
||||||
status = 200
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
const { join } = require('path');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {
|
|
||||||
config: join(__dirname, 'tailwind.config.js'),
|
|
||||||
},
|
|
||||||
autoprefixer: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
||||||
"sourceRoot": "apps/console-lite/src",
|
|
||||||
"projectType": "application",
|
|
||||||
"targets": {
|
|
||||||
"build": {
|
|
||||||
"executor": "./tools/executors/webpack:build",
|
|
||||||
"outputs": ["{options.outputPath}"],
|
|
||||||
"defaultConfiguration": "production",
|
|
||||||
"options": {
|
|
||||||
"compiler": "babel",
|
|
||||||
"outputPath": "dist/apps/console-lite",
|
|
||||||
"index": "apps/console-lite/src/index.html",
|
|
||||||
"baseHref": "/",
|
|
||||||
"main": "apps/console-lite/src/main.tsx",
|
|
||||||
"polyfills": "apps/console-lite/src/polyfills.ts",
|
|
||||||
"tsConfig": "apps/console-lite/tsconfig.app.json",
|
|
||||||
"assets": [
|
|
||||||
"apps/console-lite/src/favicon.ico",
|
|
||||||
"apps/console-lite/src/assets"
|
|
||||||
],
|
|
||||||
"styles": ["apps/console-lite/src/styles.scss"],
|
|
||||||
"scripts": [],
|
|
||||||
"webpackConfig": "@nrwl/react/plugins/webpack"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "apps/console-lite/src/environments/environment.ts",
|
|
||||||
"with": "apps/console-lite/src/environments/environment.prod.ts"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"optimization": true,
|
|
||||||
"outputHashing": "all",
|
|
||||||
"sourceMap": false,
|
|
||||||
"namedChunks": false,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"vendorChunk": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"serve": {
|
|
||||||
"executor": "./tools/executors/webpack:serve",
|
|
||||||
"options": {
|
|
||||||
"buildTarget": "console-lite:build:development",
|
|
||||||
"hmr": true,
|
|
||||||
"port": 4001
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"buildTarget": "console-lite:build:production",
|
|
||||||
"hmr": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"executor": "@nrwl/linter:eslint",
|
|
||||||
"outputs": ["{options.outputFile}"],
|
|
||||||
"options": {
|
|
||||||
"lintFilePatterns": ["apps/console-lite/**/*.{ts,tsx,js,jsx}"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"executor": "@nrwl/jest:jest",
|
|
||||||
"outputs": ["coverage/apps/console-lite"],
|
|
||||||
"options": {
|
|
||||||
"jestConfig": "apps/console-lite/jest.config.ts",
|
|
||||||
"passWithNoTests": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"build-netlify": {
|
|
||||||
"executor": "@nrwl/workspace:run-commands",
|
|
||||||
"options": {
|
|
||||||
"commands": [
|
|
||||||
"cp apps/console-lite/netlify.toml netlify.toml",
|
|
||||||
"nx build console-lite"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"build-spec": {
|
|
||||||
"executor": "@nrwl/workspace:run-commands",
|
|
||||||
"outputs": [],
|
|
||||||
"options": {
|
|
||||||
"command": "yarn tsc --project ./apps/console-lite/tsconfig.spec.json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": []
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { useLocation } from 'react-router-dom';
|
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
|
||||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
|
||||||
import {
|
|
||||||
VegaConnectDialog,
|
|
||||||
VegaManageDialog,
|
|
||||||
VegaWalletProvider,
|
|
||||||
} from '@vegaprotocol/wallet';
|
|
||||||
import { Connectors } from './lib/vega-connectors';
|
|
||||||
import '../styles.scss';
|
|
||||||
import { AppLoader } from './components/app-loader';
|
|
||||||
import Header from './components/header';
|
|
||||||
import { Main } from './components/main';
|
|
||||||
import LocalContext from './context/local-context';
|
|
||||||
import useLocalValues from './hooks/use-local-values';
|
|
||||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
|
||||||
const localValues = useLocalValues(theme, toggleTheme);
|
|
||||||
const {
|
|
||||||
vegaWalletDialog,
|
|
||||||
menu: { setMenuOpen },
|
|
||||||
} = localValues;
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setMenuOpen(false);
|
|
||||||
}, [location, setMenuOpen]);
|
|
||||||
|
|
||||||
const cacheConfig: InMemoryCacheConfig = {
|
|
||||||
typePolicies: {
|
|
||||||
Market: {
|
|
||||||
merge: true,
|
|
||||||
},
|
|
||||||
Party: {
|
|
||||||
merge: true,
|
|
||||||
},
|
|
||||||
Query: {},
|
|
||||||
Account: {
|
|
||||||
keyFields: false,
|
|
||||||
fields: {
|
|
||||||
balanceFormatted: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Node: {
|
|
||||||
keyFields: false,
|
|
||||||
},
|
|
||||||
Instrument: {
|
|
||||||
keyFields: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EnvironmentProvider>
|
|
||||||
<ThemeContext.Provider value={theme}>
|
|
||||||
<NetworkLoader cache={cacheConfig}>
|
|
||||||
<VegaWalletProvider>
|
|
||||||
<LocalContext.Provider value={localValues}>
|
|
||||||
<AppLoader>
|
|
||||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
|
||||||
<Header />
|
|
||||||
<Main />
|
|
||||||
<VegaConnectDialog connectors={Connectors} />
|
|
||||||
<VegaManageDialog
|
|
||||||
dialogOpen={vegaWalletDialog.manage}
|
|
||||||
setDialogOpen={vegaWalletDialog.setManage}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AppLoader>
|
|
||||||
</LocalContext.Provider>
|
|
||||||
</VegaWalletProvider>
|
|
||||||
</NetworkLoader>
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
</EnvironmentProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import { useEagerConnect } from '@vegaprotocol/wallet';
|
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import { Connectors } from '../../lib/vega-connectors';
|
|
||||||
|
|
||||||
interface AppLoaderProps {
|
|
||||||
children: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component to handle any app initialization, startup querys and other things
|
|
||||||
* that must happen for it can be used
|
|
||||||
*/
|
|
||||||
export function AppLoader({ children }: AppLoaderProps) {
|
|
||||||
// Get keys from vega wallet immediately
|
|
||||||
useEagerConnect(Connectors);
|
|
||||||
|
|
||||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
||||||
return <>{children}</>;
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
import React, {
|
|
||||||
forwardRef,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
} from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { ThemeContext, useScreenDimensions } from '@vegaprotocol/react-helpers';
|
|
||||||
import type {
|
|
||||||
GridOptions,
|
|
||||||
GetRowIdParams,
|
|
||||||
TabToNextCellParams,
|
|
||||||
CellKeyDownEvent,
|
|
||||||
FullWidthCellKeyDownEvent,
|
|
||||||
IGetRowsParams,
|
|
||||||
IDatasource,
|
|
||||||
} from 'ag-grid-community';
|
|
||||||
import { NO_DATA_MESSAGE } from '../../constants';
|
|
||||||
import * as constants from '../simple-market-list/constants';
|
|
||||||
|
|
||||||
export interface GetRowsParams<T>
|
|
||||||
extends Omit<IGetRowsParams, 'successCallback'> {
|
|
||||||
successCallback(rowsThisBlock: T[], lastRow?: number): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Datasource<T> extends IDatasource {
|
|
||||||
getRows(params: GetRowsParams<T>): void;
|
|
||||||
}
|
|
||||||
interface Props<T> extends GridOptions {
|
|
||||||
rowData?: T[];
|
|
||||||
datasource?: Datasource<T>;
|
|
||||||
handleRowClicked?: (event: { data: T }) => void;
|
|
||||||
components?: Record<string, unknown>;
|
|
||||||
classNamesParam?: string | string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConsoleLiteGrid = <T extends { id?: string }>(
|
|
||||||
{ handleRowClicked, getRowId, classNamesParam, ...props }: Props<T>,
|
|
||||||
ref?: React.Ref<AgGridReact>
|
|
||||||
) => {
|
|
||||||
const { isMobile, screenSize } = useScreenDimensions();
|
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const theme = useContext(ThemeContext);
|
|
||||||
const handleOnGridReady = useCallback(() => {
|
|
||||||
(
|
|
||||||
(ref as React.RefObject<AgGridReact>) || gridRef
|
|
||||||
).current?.api?.sizeColumnsToFit();
|
|
||||||
}, [gridRef, ref]);
|
|
||||||
const onTabToNextCell = useCallback((params: TabToNextCellParams) => {
|
|
||||||
const {
|
|
||||||
api,
|
|
||||||
previousCellPosition: { rowIndex },
|
|
||||||
} = params;
|
|
||||||
const rowCount = api.getDisplayedRowCount();
|
|
||||||
if (rowCount <= rowIndex + 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return { ...params.previousCellPosition, rowIndex: rowIndex + 1 };
|
|
||||||
}, []);
|
|
||||||
const getRowIdLocal = useCallback(({ data }: GetRowIdParams) => data.id, []);
|
|
||||||
const onCellKeyDown = useCallback(
|
|
||||||
(
|
|
||||||
params: (CellKeyDownEvent | FullWidthCellKeyDownEvent) & {
|
|
||||||
event: KeyboardEvent;
|
|
||||||
}
|
|
||||||
) => {
|
|
||||||
const { event: { key = '' } = {}, data } = params;
|
|
||||||
if (key === 'Enter') {
|
|
||||||
handleRowClicked?.({ data });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[handleRowClicked]
|
|
||||||
);
|
|
||||||
const shouldSuppressHorizontalScroll = useMemo(() => {
|
|
||||||
return !isMobile && constants.LARGE_SCREENS.includes(screenSize);
|
|
||||||
}, [isMobile, screenSize]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AgGrid
|
|
||||||
className={classNames(classNamesParam)}
|
|
||||||
rowHeight={60}
|
|
||||||
customThemeParams={
|
|
||||||
theme === 'dark'
|
|
||||||
? constants.agGridDarkVariables
|
|
||||||
: constants.agGridLightVariables
|
|
||||||
}
|
|
||||||
onGridReady={handleOnGridReady}
|
|
||||||
onRowClicked={handleRowClicked}
|
|
||||||
rowClass={isMobile ? 'mobile' : ''}
|
|
||||||
rowClassRules={constants.ROW_CLASS_RULES}
|
|
||||||
ref={ref || gridRef}
|
|
||||||
overlayNoRowsTemplate={NO_DATA_MESSAGE}
|
|
||||||
suppressContextMenu
|
|
||||||
getRowId={getRowId || getRowIdLocal}
|
|
||||||
suppressMovableColumns
|
|
||||||
suppressRowTransform
|
|
||||||
onCellKeyDown={onCellKeyDown}
|
|
||||||
tabToNextCell={onTabToNextCell}
|
|
||||||
suppressHorizontalScroll={shouldSuppressHorizontalScroll}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ConsoleLiteGridForwarder = forwardRef(ConsoleLiteGrid) as <T>(
|
|
||||||
p: Props<T> & { ref?: React.Ref<AgGridReact> }
|
|
||||||
) => React.ReactElement;
|
|
||||||
|
|
||||||
export default ConsoleLiteGridForwarder;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default as ConsoleLiteGrid } from './console-lite-grid';
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
query MarketTags($marketId: ID!) {
|
|
||||||
market(id: $marketId) {
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
query PartyBalanceQuery($partyId: ID!) {
|
|
||||||
party(id: $partyId) {
|
|
||||||
accountsConnection {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
type
|
|
||||||
balance
|
|
||||||
asset {
|
|
||||||
id
|
|
||||||
symbol
|
|
||||||
name
|
|
||||||
decimals
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-51
@@ -1,51 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
// @generated
|
|
||||||
// This file was automatically generated and should not be edited.
|
|
||||||
|
|
||||||
// ====================================================
|
|
||||||
// GraphQL query operation: MarketTags
|
|
||||||
// ====================================================
|
|
||||||
|
|
||||||
export interface MarketTags_market_tradableInstrument_instrument_metadata {
|
|
||||||
__typename: "InstrumentMetadata";
|
|
||||||
/**
|
|
||||||
* An arbitrary list of tags to associated to associate to the Instrument (string list)
|
|
||||||
*/
|
|
||||||
tags: string[] | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketTags_market_tradableInstrument_instrument {
|
|
||||||
__typename: "Instrument";
|
|
||||||
/**
|
|
||||||
* Metadata for this instrument
|
|
||||||
*/
|
|
||||||
metadata: MarketTags_market_tradableInstrument_instrument_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketTags_market_tradableInstrument {
|
|
||||||
__typename: "TradableInstrument";
|
|
||||||
/**
|
|
||||||
* An instance of, or reference to, a fully specified instrument.
|
|
||||||
*/
|
|
||||||
instrument: MarketTags_market_tradableInstrument_instrument;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketTags_market {
|
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* An instance of, or reference to, a tradable instrument.
|
|
||||||
*/
|
|
||||||
tradableInstrument: MarketTags_market_tradableInstrument;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketTags {
|
|
||||||
/**
|
|
||||||
* An instrument that is trading on the Vega network
|
|
||||||
*/
|
|
||||||
market: MarketTags_market | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketTagsVariables {
|
|
||||||
marketId: string;
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import { Schema as Types } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
import { gql } from '@apollo/client';
|
|
||||||
import * as Apollo from '@apollo/client';
|
|
||||||
const defaultOptions = {} as const;
|
|
||||||
export type MarketTagsQueryVariables = Types.Exact<{
|
|
||||||
marketId: Types.Scalars['ID'];
|
|
||||||
}>;
|
|
||||||
|
|
||||||
|
|
||||||
export type MarketTagsQuery = { __typename?: 'Query', market?: { __typename?: 'Market', tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null } } } } | null };
|
|
||||||
|
|
||||||
|
|
||||||
export const MarketTagsDocument = gql`
|
|
||||||
query MarketTags($marketId: ID!) {
|
|
||||||
market(id: $marketId) {
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useMarketTagsQuery__
|
|
||||||
*
|
|
||||||
* To run a query within a React component, call `useMarketTagsQuery` and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useMarketTagsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
|
||||||
* you can use to render your UI.
|
|
||||||
*
|
|
||||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const { data, loading, error } = useMarketTagsQuery({
|
|
||||||
* variables: {
|
|
||||||
* marketId: // value for 'marketId'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useMarketTagsQuery(baseOptions: Apollo.QueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
|
|
||||||
}
|
|
||||||
export function useMarketTagsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketTagsQuery, MarketTagsQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useLazyQuery<MarketTagsQuery, MarketTagsQueryVariables>(MarketTagsDocument, options);
|
|
||||||
}
|
|
||||||
export type MarketTagsQueryHookResult = ReturnType<typeof useMarketTagsQuery>;
|
|
||||||
export type MarketTagsLazyQueryHookResult = ReturnType<typeof useMarketTagsLazyQuery>;
|
|
||||||
export type MarketTagsQueryResult = Apollo.QueryResult<MarketTagsQuery, MarketTagsQueryVariables>;
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
import { Schema as Types } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
import { gql } from '@apollo/client';
|
|
||||||
import * as Apollo from '@apollo/client';
|
|
||||||
const defaultOptions = {} as const;
|
|
||||||
export type PartyBalanceQueryQueryVariables = Types.Exact<{
|
|
||||||
partyId: Types.Scalars['ID'];
|
|
||||||
}>;
|
|
||||||
|
|
||||||
|
|
||||||
export type PartyBalanceQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', accountsConnection?: { __typename?: 'AccountsConnection', edges?: Array<{ __typename?: 'AccountEdge', node: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } } } | null> | null } | null } | null };
|
|
||||||
|
|
||||||
|
|
||||||
export const PartyBalanceQueryDocument = gql`
|
|
||||||
query PartyBalanceQuery($partyId: ID!) {
|
|
||||||
party(id: $partyId) {
|
|
||||||
accountsConnection {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
type
|
|
||||||
balance
|
|
||||||
asset {
|
|
||||||
id
|
|
||||||
symbol
|
|
||||||
name
|
|
||||||
decimals
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __usePartyBalanceQueryQuery__
|
|
||||||
*
|
|
||||||
* To run a query within a React component, call `usePartyBalanceQueryQuery` and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `usePartyBalanceQueryQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
|
||||||
* you can use to render your UI.
|
|
||||||
*
|
|
||||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const { data, loading, error } = usePartyBalanceQueryQuery({
|
|
||||||
* variables: {
|
|
||||||
* partyId: // value for 'partyId'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function usePartyBalanceQueryQuery(baseOptions: Apollo.QueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
|
|
||||||
}
|
|
||||||
export function usePartyBalanceQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useLazyQuery<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>(PartyBalanceQueryDocument, options);
|
|
||||||
}
|
|
||||||
export type PartyBalanceQueryQueryHookResult = ReturnType<typeof usePartyBalanceQueryQuery>;
|
|
||||||
export type PartyBalanceQueryLazyQueryHookResult = ReturnType<typeof usePartyBalanceQueryLazyQuery>;
|
|
||||||
export type PartyBalanceQueryQueryResult = Apollo.QueryResult<PartyBalanceQueryQuery, PartyBalanceQueryQueryVariables>;
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import Video from '../header/video';
|
|
||||||
import Comet from '../header/comet';
|
|
||||||
import Star from '../icons/star';
|
|
||||||
|
|
||||||
const Baubles = () => {
|
|
||||||
return (
|
|
||||||
<aside className="relative right-0 top-0 h-[700px] hidden md:block md:w-1/2 overflow-hidden">
|
|
||||||
<div className="absolute top-[100px] w-[393px] left-[19%] h-[517px]">
|
|
||||||
<div className="absolute top-[82px] right-[34px] w-[100px] h-[100px] clip-path-rounded">
|
|
||||||
<Video />
|
|
||||||
</div>
|
|
||||||
<div className="absolute bottom-[100px] left-[59px] w-[200px] h-[200px] clip-path-rounded">
|
|
||||||
<Video />
|
|
||||||
</div>
|
|
||||||
<div className="absolute w-[118px] h-[85px] right-0 bottom-[178px]">
|
|
||||||
<Comet />
|
|
||||||
</div>
|
|
||||||
<div className="absolute w-[118px] h-[82px] left-0 bottom-[120px]">
|
|
||||||
<Comet />
|
|
||||||
</div>
|
|
||||||
<div className="absolute w-[20px] h-[20px] top-0 left-[49px]">
|
|
||||||
<Star />
|
|
||||||
</div>
|
|
||||||
<div className="absolute w-[20px] h-[20px] top-[89px] left-[184px]">
|
|
||||||
<Star />
|
|
||||||
</div>
|
|
||||||
<div className="absolute w-[10px] h-[10px] bottom-0 right-[137px]">
|
|
||||||
<Star />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Baubles;
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { render } from '@testing-library/react';
|
|
||||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
|
||||||
import { DealTicketBalance } from './deal-ticket-balance';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
import type { MarketDealTicketAsset } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
const tDAI: MarketDealTicketAsset = {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: '1',
|
|
||||||
symbol: 'tDAI',
|
|
||||||
name: 'TDAI',
|
|
||||||
decimals: 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
const accounts: AccountFragment[] = [
|
|
||||||
{
|
|
||||||
__typename: 'AccountBalance',
|
|
||||||
type: Schema.AccountType.ACCOUNT_TYPE_GENERAL,
|
|
||||||
balance: '1000000',
|
|
||||||
asset: tDAI,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
describe('DealTicketBalance', function () {
|
|
||||||
it('should render the balance', () => {
|
|
||||||
const { getByText, getByRole } = render(
|
|
||||||
<DealTicketBalance
|
|
||||||
settlementAsset={tDAI}
|
|
||||||
accounts={accounts}
|
|
||||||
isWalletConnected
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(getByRole('complementary')).toHaveAccessibleName('tDAI Balance');
|
|
||||||
expect(getByText('10,000.00')).toBeInTheDocument();
|
|
||||||
expect(getByText('tDAI')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prompt to connect wallet', () => {
|
|
||||||
const { getByText } = render(
|
|
||||||
<DealTicketBalance
|
|
||||||
settlementAsset={tDAI}
|
|
||||||
accounts={accounts}
|
|
||||||
isWalletConnected={false}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
getByText('Please connect your Vega wallet to see your balance')
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display zero balance', () => {
|
|
||||||
const { getByText } = render(
|
|
||||||
<DealTicketBalance
|
|
||||||
settlementAsset={tDAI}
|
|
||||||
accounts={[]}
|
|
||||||
isWalletConnected={true}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(getByText('No tDAI left to trade')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
import classNames from 'classnames';
|
|
||||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
import type { AccountFragment } from '@vegaprotocol/deal-ticket';
|
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
import { useSettlementAccount } from '@vegaprotocol/deal-ticket';
|
|
||||||
|
|
||||||
interface DealTicketBalanceProps {
|
|
||||||
settlementAsset: MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
|
||||||
accounts: AccountFragment[];
|
|
||||||
isWalletConnected: boolean;
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DealTicketBalance = ({
|
|
||||||
settlementAsset,
|
|
||||||
accounts,
|
|
||||||
isWalletConnected,
|
|
||||||
className = '',
|
|
||||||
}: DealTicketBalanceProps) => {
|
|
||||||
const settlementAssetId = settlementAsset?.id;
|
|
||||||
const settlementAssetSymbol = settlementAsset?.symbol;
|
|
||||||
const settlementAccount = useSettlementAccount(
|
|
||||||
settlementAssetId,
|
|
||||||
accounts,
|
|
||||||
Schema.AccountType.ACCOUNT_TYPE_GENERAL
|
|
||||||
);
|
|
||||||
const formattedNumber =
|
|
||||||
settlementAccount?.balance &&
|
|
||||||
settlementAccount.asset.decimals &&
|
|
||||||
addDecimalsFormatNumber(
|
|
||||||
settlementAccount.balance,
|
|
||||||
settlementAccount.asset.decimals
|
|
||||||
);
|
|
||||||
|
|
||||||
const balance = (
|
|
||||||
<p className="text-blue text-lg font-semibold">
|
|
||||||
{settlementAccount
|
|
||||||
? t(`${formattedNumber}`)
|
|
||||||
: `No ${settlementAssetSymbol} left to trade`}
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
|
|
||||||
const connectWallet = (
|
|
||||||
<p>{t('Please connect your Vega wallet to see your balance')}</p>
|
|
||||||
);
|
|
||||||
|
|
||||||
const ariaLabel = t(`${settlementAssetSymbol} Balance`);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<aside
|
|
||||||
aria-label={ariaLabel}
|
|
||||||
className={classNames('text-right', className)}
|
|
||||||
>
|
|
||||||
<div className="inline-block">
|
|
||||||
<span className="text-blue">{settlementAssetSymbol}</span>
|
|
||||||
{isWalletConnected ? balance : connectWallet}
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
import { useParams } from 'react-router-dom';
|
|
||||||
import compact from 'lodash/compact';
|
|
||||||
import {
|
|
||||||
DealTicketManager,
|
|
||||||
usePartyBalanceQuery,
|
|
||||||
} from '@vegaprotocol/deal-ticket';
|
|
||||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
|
||||||
import { DealTicketSteps } from './deal-ticket-steps';
|
|
||||||
import { DealTicketBalance } from './deal-ticket-balance';
|
|
||||||
import Baubles from './baubles-decor';
|
|
||||||
import ConnectWallet from '../wallet-connector';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import type {
|
|
||||||
MarketDataUpdateFieldsFragment,
|
|
||||||
MarketDealTicket,
|
|
||||||
} from '@vegaprotocol/market-list';
|
|
||||||
import { marketDealTicketProvider } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
const tempEmptyText = (
|
|
||||||
<p>{t('Please select a market from the markets page')}</p>
|
|
||||||
);
|
|
||||||
|
|
||||||
export const DealTicketContainer = () => {
|
|
||||||
const { marketId } = useParams<{ marketId: string }>();
|
|
||||||
const { pubKey } = useVegaWallet();
|
|
||||||
|
|
||||||
const { data: partyData } = usePartyBalanceQuery({
|
|
||||||
variables: { partyId: pubKey || '' },
|
|
||||||
skip: !pubKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
const variables = useMemo(
|
|
||||||
() => ({
|
|
||||||
marketId: marketId || '',
|
|
||||||
}),
|
|
||||||
[marketId]
|
|
||||||
);
|
|
||||||
const { data, loading } = useDataProvider<
|
|
||||||
MarketDealTicket,
|
|
||||||
MarketDataUpdateFieldsFragment
|
|
||||||
>({
|
|
||||||
dataProvider: marketDealTicketProvider,
|
|
||||||
variables,
|
|
||||||
skip: !marketId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const accounts = compact(partyData?.party?.accountsConnection?.edges).map(
|
|
||||||
(e) => e.node
|
|
||||||
);
|
|
||||||
|
|
||||||
const loader = <Loader />;
|
|
||||||
if (marketId && data) {
|
|
||||||
const balance = (
|
|
||||||
<DealTicketBalance
|
|
||||||
className="mb-4"
|
|
||||||
settlementAsset={
|
|
||||||
data.tradableInstrument.instrument.product?.settlementAsset
|
|
||||||
}
|
|
||||||
accounts={accounts || []}
|
|
||||||
isWalletConnected={!!pubKey}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const container = (
|
|
||||||
<DealTicketManager market={data}>
|
|
||||||
{loading ? loader : balance}
|
|
||||||
<DealTicketSteps market={data} />
|
|
||||||
</DealTicketManager>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className="flex p-4 md:p-6">
|
|
||||||
<section className="w-full md:w-1/2 md:min-w-[500px]">
|
|
||||||
{pubKey ? container : <ConnectWallet />}
|
|
||||||
</section>
|
|
||||||
<Baubles />
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return marketId ? (
|
|
||||||
<Splash>
|
|
||||||
<p>{t('Could not load market')}</p>
|
|
||||||
</Splash>
|
|
||||||
) : (
|
|
||||||
tempEmptyText
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
|
||||||
import { BigNumber } from 'bignumber.js';
|
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
|
||||||
import {
|
|
||||||
SliderRoot,
|
|
||||||
SliderThumb,
|
|
||||||
SliderTrack,
|
|
||||||
SliderRange,
|
|
||||||
FormGroup,
|
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { InputSetter } from '../input-setter';
|
|
||||||
|
|
||||||
interface DealTicketSizeInputProps {
|
|
||||||
step: number;
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
value: number;
|
|
||||||
onValueChange: (value: number) => void;
|
|
||||||
positionDecimalPlaces: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSizeLabel = (value: number): string => {
|
|
||||||
const MIN_LABEL = 'Min';
|
|
||||||
const MAX_LABEL = 'Max';
|
|
||||||
if (value === 0) {
|
|
||||||
return MIN_LABEL;
|
|
||||||
} else if (value === 100) {
|
|
||||||
return MAX_LABEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${value}%`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DealTicketSizeInput = ({
|
|
||||||
value,
|
|
||||||
step,
|
|
||||||
min,
|
|
||||||
max,
|
|
||||||
onValueChange,
|
|
||||||
positionDecimalPlaces,
|
|
||||||
}: DealTicketSizeInputProps) => {
|
|
||||||
const sizeRatios = [0, 25, 50, 75, 100];
|
|
||||||
const [inputValue, setInputValue] = useState(value);
|
|
||||||
|
|
||||||
const onInputValueChange = useCallback(
|
|
||||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
let value = parseFloat(event.target.value);
|
|
||||||
const isLessThanMin = value < min;
|
|
||||||
const isMoreThanMax = value > max;
|
|
||||||
if (isLessThanMin) {
|
|
||||||
value = min;
|
|
||||||
} else if (isMoreThanMax) {
|
|
||||||
value = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
onValueChange(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
setInputValue(value);
|
|
||||||
},
|
|
||||||
[min, max, onValueChange, setInputValue]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onButtonValueChange = (size: number) => {
|
|
||||||
const newVal = new BigNumber(size)
|
|
||||||
.decimalPlaces(positionDecimalPlaces)
|
|
||||||
.toNumber();
|
|
||||||
onValueChange(newVal);
|
|
||||||
setInputValue(newVal);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSliderValueChange = useCallback(
|
|
||||||
(value: number[]) => {
|
|
||||||
const val = value[0];
|
|
||||||
setInputValue(val);
|
|
||||||
onValueChange(val);
|
|
||||||
},
|
|
||||||
[onValueChange]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className="flex justify-between text-black dark:text-white mb-2">
|
|
||||||
<span data-testid="min-label">{min}</span>
|
|
||||||
<span data-testid="max-label">{max}</span>
|
|
||||||
</div>
|
|
||||||
<SliderRoot
|
|
||||||
className="mb-2"
|
|
||||||
value={[value]}
|
|
||||||
onValueChange={onSliderValueChange}
|
|
||||||
step={step}
|
|
||||||
min={min}
|
|
||||||
max={max}
|
|
||||||
>
|
|
||||||
<SliderTrack className="bg-lightGrey dark:bg-offBlack">
|
|
||||||
<SliderRange className="!bg-black dark:!bg-white" />
|
|
||||||
</SliderTrack>
|
|
||||||
<SliderThumb />
|
|
||||||
</SliderRoot>
|
|
||||||
|
|
||||||
<div
|
|
||||||
data-testid="percentage-selector"
|
|
||||||
className="flex w-full justify-between text-black dark:text-white mb-6"
|
|
||||||
>
|
|
||||||
{sizeRatios.map((size, index) => {
|
|
||||||
const proportionalSize = size ? (size / 100) * max : min;
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
className="no-underline hover:underline text-blue"
|
|
||||||
onClick={() => onButtonValueChange(proportionalSize)}
|
|
||||||
type="button"
|
|
||||||
key={index}
|
|
||||||
>
|
|
||||||
{getSizeLabel(size)}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<dl className="text-black dark:text-white">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<dt>{t('Contracts')}</dt>
|
|
||||||
<dd className="flex justify-end w-full">
|
|
||||||
<FormGroup
|
|
||||||
hideLabel={true}
|
|
||||||
label="Enter Size"
|
|
||||||
labelFor="trade-size-input"
|
|
||||||
className="mb-1"
|
|
||||||
>
|
|
||||||
<InputSetter
|
|
||||||
id="input-order-size-market"
|
|
||||||
type="number"
|
|
||||||
step={step}
|
|
||||||
min={min}
|
|
||||||
max={max}
|
|
||||||
className="w-full"
|
|
||||||
value={inputValue}
|
|
||||||
onChange={onInputValueChange}
|
|
||||||
>
|
|
||||||
{inputValue}
|
|
||||||
</InputSetter>
|
|
||||||
</FormGroup>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import { DealTicketEstimates } from '@vegaprotocol/deal-ticket';
|
|
||||||
import { DealTicketSizeInput } from './deal-ticket-size-input';
|
|
||||||
|
|
||||||
interface DealTicketSizeProps {
|
|
||||||
step: number;
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
size: number;
|
|
||||||
onSizeChange: (value: number) => void;
|
|
||||||
name: string;
|
|
||||||
quoteName: string;
|
|
||||||
price: string;
|
|
||||||
estCloseOut: string;
|
|
||||||
estMargin: string;
|
|
||||||
fees: string;
|
|
||||||
positionDecimalPlaces: number;
|
|
||||||
notionalSize: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DealTicketSize = ({
|
|
||||||
step,
|
|
||||||
min,
|
|
||||||
max,
|
|
||||||
price,
|
|
||||||
quoteName,
|
|
||||||
size,
|
|
||||||
onSizeChange,
|
|
||||||
estCloseOut,
|
|
||||||
positionDecimalPlaces,
|
|
||||||
fees,
|
|
||||||
notionalSize,
|
|
||||||
}: DealTicketSizeProps) => {
|
|
||||||
return max === 0 ? (
|
|
||||||
<p>Not enough balance to trade</p>
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
<DealTicketSizeInput
|
|
||||||
step={step}
|
|
||||||
min={min}
|
|
||||||
max={max}
|
|
||||||
value={size}
|
|
||||||
onValueChange={onSizeChange}
|
|
||||||
positionDecimalPlaces={positionDecimalPlaces}
|
|
||||||
/>
|
|
||||||
<DealTicketEstimates
|
|
||||||
quoteName={quoteName}
|
|
||||||
fees={fees}
|
|
||||||
estCloseOut={estCloseOut}
|
|
||||||
price={price}
|
|
||||||
notionalSize={notionalSize}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
Icon,
|
|
||||||
Intent,
|
|
||||||
Tooltip,
|
|
||||||
TrafficLight,
|
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { InputSetter } from '../../components/input-setter';
|
|
||||||
import { IconNames } from '@blueprintjs/icons';
|
|
||||||
import {
|
|
||||||
DataTitle,
|
|
||||||
ValueTooltipRow,
|
|
||||||
EST_SLIPPAGE,
|
|
||||||
} from '@vegaprotocol/deal-ticket';
|
|
||||||
|
|
||||||
interface DealTicketSlippageProps {
|
|
||||||
step?: number;
|
|
||||||
min?: number;
|
|
||||||
max?: number;
|
|
||||||
value: number;
|
|
||||||
onValueChange(value: number): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DealTicketSlippage = ({
|
|
||||||
value,
|
|
||||||
step = 0.01,
|
|
||||||
min = 0,
|
|
||||||
max = 50,
|
|
||||||
onValueChange,
|
|
||||||
}: DealTicketSlippageProps) => {
|
|
||||||
const [isDialogVisible, setIsDialogVisible] = useState(false);
|
|
||||||
|
|
||||||
const onChange = useCallback(
|
|
||||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
const value = event.target.value;
|
|
||||||
const numericValue = parseFloat(value);
|
|
||||||
onValueChange(numericValue);
|
|
||||||
},
|
|
||||||
[onValueChange]
|
|
||||||
);
|
|
||||||
|
|
||||||
const toggleDialog = useCallback(() => {
|
|
||||||
setIsDialogVisible(!isDialogVisible);
|
|
||||||
}, [isDialogVisible]);
|
|
||||||
|
|
||||||
const formLabel = (
|
|
||||||
<label className="flex items-center mb-1">
|
|
||||||
<span className="mr-1">{t('Adjust slippage tolerance')}</span>
|
|
||||||
<Tooltip align="center" description={EST_SLIPPAGE}>
|
|
||||||
<div className="cursor-help" tabIndex={-1}>
|
|
||||||
<Icon
|
|
||||||
name={IconNames.ISSUE}
|
|
||||||
className="block rotate-180"
|
|
||||||
ariaLabel={EST_SLIPPAGE}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</label>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Dialog
|
|
||||||
open={isDialogVisible}
|
|
||||||
onChange={toggleDialog}
|
|
||||||
intent={Intent.None}
|
|
||||||
title={t('Transaction Settings')}
|
|
||||||
>
|
|
||||||
<div data-testid="slippage-dialog">
|
|
||||||
{formLabel}
|
|
||||||
<InputSetter
|
|
||||||
id="input-order-slippage"
|
|
||||||
isInputVisible
|
|
||||||
hasError={!value}
|
|
||||||
type="number"
|
|
||||||
step={step}
|
|
||||||
min={min}
|
|
||||||
max={max}
|
|
||||||
className="w-full"
|
|
||||||
value={value}
|
|
||||||
onChange={onChange}
|
|
||||||
>
|
|
||||||
{value}%
|
|
||||||
</InputSetter>
|
|
||||||
</div>
|
|
||||||
</Dialog>
|
|
||||||
<dl className="text-black dark:text-white">
|
|
||||||
<div className="flex justify-between mb-2">
|
|
||||||
<DataTitle>{t('Est. Price Impact / Slippage')}</DataTitle>
|
|
||||||
<div className="flex">
|
|
||||||
<div className="mr-1">
|
|
||||||
<ValueTooltipRow description={EST_SLIPPAGE}>
|
|
||||||
<TrafficLight value={value} q1={1} q2={5}>
|
|
||||||
{value}%
|
|
||||||
</TrafficLight>
|
|
||||||
</ValueTooltipRow>
|
|
||||||
</div>
|
|
||||||
<button type="button" onClick={toggleDialog}>
|
|
||||||
<Icon
|
|
||||||
name={IconNames.COG}
|
|
||||||
className="block rotate-180"
|
|
||||||
ariaLabel={t('Override slippage value')}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,355 +0,0 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
|
||||||
import compact from 'lodash/compact';
|
|
||||||
import { Stepper } from '../stepper';
|
|
||||||
import {
|
|
||||||
getDefaultOrder,
|
|
||||||
useOrderCloseOut,
|
|
||||||
useOrderMargin,
|
|
||||||
usePartyBalanceQuery,
|
|
||||||
useMaximumPositionSize,
|
|
||||||
useCalculateSlippage,
|
|
||||||
validateAmount,
|
|
||||||
} from '@vegaprotocol/deal-ticket';
|
|
||||||
import { InputError } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { BigNumber } from 'bignumber.js';
|
|
||||||
import { MarketSelector } from '@vegaprotocol/deal-ticket';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
|
||||||
import { VegaTxStatus } from '@vegaprotocol/wallet';
|
|
||||||
import {
|
|
||||||
t,
|
|
||||||
toDecimal,
|
|
||||||
removeDecimal,
|
|
||||||
addDecimalsFormatNumber,
|
|
||||||
addDecimal,
|
|
||||||
formatNumber,
|
|
||||||
} from '@vegaprotocol/react-helpers';
|
|
||||||
import {
|
|
||||||
useOrderSubmit,
|
|
||||||
getOrderDialogTitle,
|
|
||||||
getOrderDialogIntent,
|
|
||||||
getOrderDialogIcon,
|
|
||||||
OrderFeedback,
|
|
||||||
} from '@vegaprotocol/orders';
|
|
||||||
import { DealTicketSize } from './deal-ticket-size';
|
|
||||||
import MarketNameRenderer from '../simple-market-list/simple-market-renderer';
|
|
||||||
import SideSelector, { SIDE_NAMES } from './side-selector';
|
|
||||||
import ReviewTrade from './review-trade';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
import { DealTicketSlippage } from './deal-ticket-slippage';
|
|
||||||
import { useOrderValidation } from './use-order-validation';
|
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
interface DealTicketMarketProps {
|
|
||||||
market: MarketDealTicket;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const setMarket = useCallback(
|
|
||||||
(marketId: string) => {
|
|
||||||
navigate(`/trading/${marketId}`);
|
|
||||||
},
|
|
||||||
[navigate]
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
|
||||||
control,
|
|
||||||
handleSubmit,
|
|
||||||
watch,
|
|
||||||
setValue,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm<OrderSubmissionBody['orderSubmission']>({
|
|
||||||
mode: 'onChange',
|
|
||||||
defaultValues: getDefaultOrder(market),
|
|
||||||
});
|
|
||||||
|
|
||||||
const emptyString = ' - ';
|
|
||||||
const step = toDecimal(market.positionDecimalPlaces);
|
|
||||||
const order = watch();
|
|
||||||
const { pubKey } = useVegaWallet();
|
|
||||||
const { message: invalidText, isDisabled } = useOrderValidation({
|
|
||||||
market,
|
|
||||||
order,
|
|
||||||
fieldErrors: errors,
|
|
||||||
});
|
|
||||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
|
||||||
|
|
||||||
const { data: partyBalance } = usePartyBalanceQuery({
|
|
||||||
variables: { partyId: pubKey || '' },
|
|
||||||
skip: !pubKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
const accounts = compact(partyBalance?.party?.accountsConnection?.edges).map(
|
|
||||||
(e) => e.node
|
|
||||||
);
|
|
||||||
const maxTrade = useMaximumPositionSize({
|
|
||||||
partyId: pubKey || '',
|
|
||||||
accounts: accounts,
|
|
||||||
marketId: market.id,
|
|
||||||
settlementAssetId:
|
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.id,
|
|
||||||
price: market?.depth?.lastTrade?.price,
|
|
||||||
order,
|
|
||||||
});
|
|
||||||
|
|
||||||
const estCloseOut = useOrderCloseOut({
|
|
||||||
order,
|
|
||||||
market,
|
|
||||||
partyData: partyBalance,
|
|
||||||
});
|
|
||||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
|
||||||
const [slippageValue, setSlippageValue] = useState(
|
|
||||||
slippage ? parseFloat(slippage) : 0
|
|
||||||
);
|
|
||||||
const transactionStatus =
|
|
||||||
transaction.status === VegaTxStatus.Requested ||
|
|
||||||
transaction.status === VegaTxStatus.Pending
|
|
||||||
? 'pending'
|
|
||||||
: 'default';
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setSlippageValue(slippage ? parseFloat(slippage) : 0);
|
|
||||||
}, [slippage]);
|
|
||||||
|
|
||||||
const price = useMemo(() => {
|
|
||||||
if (slippage && market?.depth?.lastTrade?.price) {
|
|
||||||
const isLong = order.side === Schema.Side.SIDE_BUY;
|
|
||||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
|
||||||
parseFloat(slippage) / 100
|
|
||||||
);
|
|
||||||
return new BigNumber(market?.depth?.lastTrade?.price)
|
|
||||||
.multipliedBy(multiplier)
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}, [market?.depth?.lastTrade?.price, order.side, slippage]);
|
|
||||||
|
|
||||||
const estMargin = useOrderMargin({
|
|
||||||
order,
|
|
||||||
market,
|
|
||||||
partyId: pubKey || '',
|
|
||||||
derivedPrice: price,
|
|
||||||
});
|
|
||||||
|
|
||||||
const formattedPrice =
|
|
||||||
price && addDecimalsFormatNumber(price, market.decimalPlaces);
|
|
||||||
|
|
||||||
const notionalSize = useMemo(() => {
|
|
||||||
if (price) {
|
|
||||||
const size = new BigNumber(price).multipliedBy(order.size).toNumber();
|
|
||||||
|
|
||||||
return addDecimalsFormatNumber(size, market.decimalPlaces);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}, [market.decimalPlaces, order.size, price]);
|
|
||||||
|
|
||||||
const assetDecimals =
|
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.decimals;
|
|
||||||
|
|
||||||
const fees = useMemo(() => {
|
|
||||||
if (estMargin?.totalFees && notionalSize) {
|
|
||||||
const percentage = new BigNumber(estMargin?.totalFees)
|
|
||||||
.dividedBy(notionalSize)
|
|
||||||
.multipliedBy(100)
|
|
||||||
.decimalPlaces(2)
|
|
||||||
.toString();
|
|
||||||
|
|
||||||
return `${addDecimalsFormatNumber(
|
|
||||||
estMargin.totalFees,
|
|
||||||
assetDecimals
|
|
||||||
)} (${formatNumber(addDecimal(percentage, assetDecimals), 2)}%)`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}, [assetDecimals, estMargin?.totalFees, notionalSize]);
|
|
||||||
|
|
||||||
const max = useMemo(() => {
|
|
||||||
return new BigNumber(maxTrade)
|
|
||||||
.decimalPlaces(market.positionDecimalPlaces)
|
|
||||||
.toNumber();
|
|
||||||
}, [market.positionDecimalPlaces, maxTrade]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setSlippageValue(slippage ? parseFloat(slippage) : 0);
|
|
||||||
}, [slippage]);
|
|
||||||
|
|
||||||
const onSizeChange = useCallback(
|
|
||||||
(value: number) => {
|
|
||||||
const newVal = new BigNumber(value)
|
|
||||||
.decimalPlaces(market.positionDecimalPlaces)
|
|
||||||
.toString();
|
|
||||||
const isValid = validateAmount(step, 'Size')(newVal);
|
|
||||||
if (isValid !== 'step') {
|
|
||||||
setValue('size', newVal);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[market.positionDecimalPlaces, setValue, step]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onSlippageChange = useCallback(
|
|
||||||
(value: number) => {
|
|
||||||
if (market?.depth?.lastTrade?.price) {
|
|
||||||
if (value) {
|
|
||||||
const isLong = order.side === Schema.Side.SIDE_BUY;
|
|
||||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
|
||||||
value / 100
|
|
||||||
);
|
|
||||||
const bestAskPrice = new BigNumber(market?.depth?.lastTrade?.price)
|
|
||||||
.multipliedBy(multiplier)
|
|
||||||
.decimalPlaces(market.decimalPlaces)
|
|
||||||
.toString();
|
|
||||||
|
|
||||||
setValue('price', bestAskPrice);
|
|
||||||
|
|
||||||
if (order.type === Schema.OrderType.TYPE_MARKET) {
|
|
||||||
setValue('type', Schema.OrderType.TYPE_LIMIT);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setValue('type', Schema.OrderType.TYPE_MARKET);
|
|
||||||
setValue('price', market?.depth?.lastTrade?.price);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setSlippageValue(value);
|
|
||||||
},
|
|
||||||
[
|
|
||||||
market.decimalPlaces,
|
|
||||||
market?.depth?.lastTrade?.price,
|
|
||||||
order.side,
|
|
||||||
order.type,
|
|
||||||
setSlippageValue,
|
|
||||||
setValue,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onSubmit = useCallback(
|
|
||||||
(order: OrderSubmissionBody['orderSubmission']) => {
|
|
||||||
if (transactionStatus !== 'pending') {
|
|
||||||
submit({
|
|
||||||
...order,
|
|
||||||
price:
|
|
||||||
order.price && removeDecimal(order.price, market.decimalPlaces),
|
|
||||||
size: removeDecimal(order.size, market.positionDecimalPlaces),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
transactionStatus,
|
|
||||||
submit,
|
|
||||||
market.decimalPlaces,
|
|
||||||
market.positionDecimalPlaces,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
const steps = [
|
|
||||||
{
|
|
||||||
label: t('Select Market'),
|
|
||||||
component: (
|
|
||||||
<MarketSelector
|
|
||||||
market={market}
|
|
||||||
setMarket={setMarket}
|
|
||||||
ItemRenderer={MarketNameRenderer}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
value: market.tradableInstrument.instrument.name,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Select Direction'),
|
|
||||||
component: (
|
|
||||||
<Controller
|
|
||||||
name="side"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<SideSelector value={field.value} onSelect={field.onChange} />
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
value: SIDE_NAMES[order.side] || '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Choose Position Size'),
|
|
||||||
component:
|
|
||||||
max !== null ? (
|
|
||||||
<>
|
|
||||||
<DealTicketSize
|
|
||||||
step={step}
|
|
||||||
min={step}
|
|
||||||
max={max}
|
|
||||||
onSizeChange={onSizeChange}
|
|
||||||
size={new BigNumber(order.size).toNumber()}
|
|
||||||
name="size"
|
|
||||||
price={formattedPrice || emptyString}
|
|
||||||
positionDecimalPlaces={market.positionDecimalPlaces}
|
|
||||||
quoteName={
|
|
||||||
market.tradableInstrument.instrument.product.settlementAsset
|
|
||||||
.symbol
|
|
||||||
}
|
|
||||||
notionalSize={notionalSize || emptyString}
|
|
||||||
estCloseOut={estCloseOut || emptyString}
|
|
||||||
fees={fees || emptyString}
|
|
||||||
estMargin={estMargin?.margin || emptyString}
|
|
||||||
/>
|
|
||||||
<DealTicketSlippage
|
|
||||||
value={slippageValue}
|
|
||||||
onValueChange={onSlippageChange}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
t('Loading...')
|
|
||||||
),
|
|
||||||
value: order.size,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Review Trade'),
|
|
||||||
component: (
|
|
||||||
<div className="mb-8">
|
|
||||||
{invalidText && (
|
|
||||||
<div className="mb-2">
|
|
||||||
<InputError data-testid="dealticket-error-message">
|
|
||||||
{invalidText}
|
|
||||||
</InputError>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<ReviewTrade
|
|
||||||
market={market}
|
|
||||||
isDisabled={isDisabled}
|
|
||||||
transactionStatus={transactionStatus}
|
|
||||||
order={order}
|
|
||||||
estCloseOut={estCloseOut || emptyString}
|
|
||||||
estMargin={estMargin?.margin || emptyString}
|
|
||||||
price={formattedPrice || emptyString}
|
|
||||||
quoteName={
|
|
||||||
market.tradableInstrument.instrument.product.settlementAsset
|
|
||||||
.symbol
|
|
||||||
}
|
|
||||||
notionalSize={notionalSize || emptyString}
|
|
||||||
fees={fees || emptyString}
|
|
||||||
slippage={slippageValue}
|
|
||||||
/>
|
|
||||||
<Dialog
|
|
||||||
title={getOrderDialogTitle(finalizedOrder?.status)}
|
|
||||||
intent={getOrderDialogIntent(finalizedOrder?.status)}
|
|
||||||
icon={getOrderDialogIcon(finalizedOrder?.status)}
|
|
||||||
content={{
|
|
||||||
Complete: (
|
|
||||||
<OrderFeedback
|
|
||||||
transaction={transaction}
|
|
||||||
order={finalizedOrder}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="px-2 py-4">
|
|
||||||
<Stepper steps={steps} />
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export * from './deal-ticket-container';
|
|
||||||
export * from './deal-ticket-size';
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/react-helpers';
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
KeyValueTable,
|
|
||||||
KeyValueTableRow,
|
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { DealTicketEstimates } from '@vegaprotocol/deal-ticket';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { SIDE_NAMES } from './side-selector';
|
|
||||||
import { gql, useQuery } from '@apollo/client';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
import { MarketExpires } from '@vegaprotocol/market-info';
|
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
import type {
|
|
||||||
MarketTags,
|
|
||||||
MarketTagsVariables,
|
|
||||||
} from './__generated__/MarketTags';
|
|
||||||
|
|
||||||
export const MARKET_TAGS_QUERY = gql`
|
|
||||||
query MarketTags($marketId: ID!) {
|
|
||||||
market(id: $marketId) {
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
market: MarketDealTicket;
|
|
||||||
isDisabled: boolean;
|
|
||||||
transactionStatus?: string;
|
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
|
||||||
estCloseOut: string;
|
|
||||||
estMargin: string;
|
|
||||||
quoteName: string;
|
|
||||||
price: string;
|
|
||||||
fees: string;
|
|
||||||
notionalSize: string;
|
|
||||||
slippage: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
isDisabled,
|
|
||||||
market,
|
|
||||||
order,
|
|
||||||
transactionStatus,
|
|
||||||
estCloseOut,
|
|
||||||
quoteName,
|
|
||||||
fees,
|
|
||||||
price,
|
|
||||||
notionalSize,
|
|
||||||
slippage,
|
|
||||||
}: Props) => {
|
|
||||||
const { data: tagsData } = useQuery<MarketTags, MarketTagsVariables>(
|
|
||||||
MARKET_TAGS_QUERY,
|
|
||||||
{
|
|
||||||
variables: { marketId: market.id },
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mb-8 text-black dark:text-white" data-testid="review-trade">
|
|
||||||
<KeyValueTable>
|
|
||||||
<KeyValueTableRow noBorder>
|
|
||||||
<div className="flex flex-none gap-x-2 items-center">
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
{
|
|
||||||
'buyButton dark:buyButtonDark':
|
|
||||||
order.side === Schema.Side.SIDE_BUY,
|
|
||||||
'sellButton dark:sellButtonDark':
|
|
||||||
order.side === Schema.Side.SIDE_SELL,
|
|
||||||
},
|
|
||||||
'px-2 py-1 inline text-ui-small'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{SIDE_NAMES[order.side]}
|
|
||||||
</div>
|
|
||||||
<div>{market.tradableInstrument.instrument.product.quoteName}</div>
|
|
||||||
<div>
|
|
||||||
{tagsData?.market?.tradableInstrument.instrument.metadata
|
|
||||||
.tags && (
|
|
||||||
<MarketExpires
|
|
||||||
tags={
|
|
||||||
tagsData?.market.tradableInstrument.instrument.metadata.tags
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="text-blue">
|
|
||||||
{`@ ${price} `}
|
|
||||||
<span className="text-ui-small inline">(EST)</span>
|
|
||||||
</div>
|
|
||||||
</KeyValueTableRow>
|
|
||||||
</KeyValueTable>
|
|
||||||
|
|
||||||
<DealTicketEstimates
|
|
||||||
size={order.size}
|
|
||||||
quoteName={quoteName}
|
|
||||||
fees={fees}
|
|
||||||
estCloseOut={estCloseOut}
|
|
||||||
notionalSize={notionalSize}
|
|
||||||
slippage={slippage.toString()}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="mt-12 max-w-sm">
|
|
||||||
<Button
|
|
||||||
fill={true}
|
|
||||||
type="submit"
|
|
||||||
disabled={transactionStatus === 'pending' || isDisabled}
|
|
||||||
data-testid="place-order"
|
|
||||||
rightIcon="arrow-top-right"
|
|
||||||
>
|
|
||||||
{transactionStatus === 'pending' ? t('Pending...') : t('Submit')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
interface SideSelectorProps {
|
|
||||||
value: Schema.Side;
|
|
||||||
onSelect: (side: Schema.Side) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SIDE_NAMES: Record<Schema.Side, string> = {
|
|
||||||
[Schema.Side.SIDE_BUY]: t('Long'),
|
|
||||||
[Schema.Side.SIDE_SELL]: t('Short'),
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ({ value, onSelect }: SideSelectorProps) => {
|
|
||||||
return (
|
|
||||||
<FormGroup
|
|
||||||
label={t('Direction')}
|
|
||||||
labelFor="order-side-toggle"
|
|
||||||
hideLabel={true}
|
|
||||||
>
|
|
||||||
<fieldset
|
|
||||||
className="w-full grid md:grid-cols-2 gap-4"
|
|
||||||
id="order-side-toggle"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
aria-label={t('Open long position')}
|
|
||||||
type="button"
|
|
||||||
className={classNames(
|
|
||||||
'px-8 py-2',
|
|
||||||
'buyButton hover:buyButton dark:buyButtonDark dark:hover:buyButtonDark',
|
|
||||||
{ selected: value === Schema.Side.SIDE_BUY }
|
|
||||||
)}
|
|
||||||
onClick={() => onSelect(Schema.Side.SIDE_BUY)}
|
|
||||||
>
|
|
||||||
{t('Long')}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label={t('Open short position')}
|
|
||||||
type="button"
|
|
||||||
className={classNames(
|
|
||||||
'px-8 py-2',
|
|
||||||
'sellButton hover:sellButton dark:sellButtonDark dark:hover:sellButtonDark',
|
|
||||||
{ selected: value === Schema.Side.SIDE_SELL }
|
|
||||||
)}
|
|
||||||
onClick={() => onSelect(Schema.Side.SIDE_SELL)}
|
|
||||||
>
|
|
||||||
{t('Short')}
|
|
||||||
</button>
|
|
||||||
<div className="md:col-span-2 text-black dark:text-white text-ui-small">
|
|
||||||
{t(
|
|
||||||
'Trading derivatives allows you to make a profit or loss regardless of whether the market you are trading goes up or down. If you open a "long" position, you will make a profit if the price of your chosen market goes up, and you will make a profit for "short" positions when the price goes down.'
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</FormGroup>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,396 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import { renderHook } from '@testing-library/react';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
|
||||||
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
|
||||||
import {
|
|
||||||
MarketStateMapping,
|
|
||||||
Schema as Types,
|
|
||||||
Schema,
|
|
||||||
} from '@vegaprotocol/types';
|
|
||||||
import type { ValidationProps } from './use-order-validation';
|
|
||||||
import { marketTranslations, useOrderValidation } from './use-order-validation';
|
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
import * as DealTicket from '@vegaprotocol/deal-ticket';
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/wallet');
|
|
||||||
jest.mock('@vegaprotocol/deal-ticket', () => {
|
|
||||||
return {
|
|
||||||
...jest.requireActual('@vegaprotocol/deal-ticket'),
|
|
||||||
useOrderMarginValidation: jest.fn(),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
type SettlementAsset =
|
|
||||||
MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
|
||||||
const asset: SettlementAsset = {
|
|
||||||
__typename: 'Asset',
|
|
||||||
id: 'asset-id',
|
|
||||||
symbol: 'asset-symbol',
|
|
||||||
name: 'asset-name',
|
|
||||||
decimals: 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
const market: MarketDealTicket = {
|
|
||||||
id: 'market-id',
|
|
||||||
decimalPlaces: 2,
|
|
||||||
positionDecimalPlaces: 1,
|
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
state: Schema.MarketState.STATE_ACTIVE,
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
id: 'instrument-id',
|
|
||||||
name: 'instrument-name',
|
|
||||||
code: 'instriment-code',
|
|
||||||
metadata: {
|
|
||||||
tags: [],
|
|
||||||
},
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
quoteName: 'quote-name',
|
|
||||||
settlementAsset: asset,
|
|
||||||
dataSourceSpecForTradingTermination: {
|
|
||||||
id: 'dataSource-id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
depth: {
|
|
||||||
__typename: 'MarketDepth',
|
|
||||||
lastTrade: {
|
|
||||||
__typename: 'Trade',
|
|
||||||
price: '100',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fees: {
|
|
||||||
__typename: 'Fees',
|
|
||||||
factors: {
|
|
||||||
__typename: 'FeeFactors',
|
|
||||||
makerFee: '1',
|
|
||||||
infrastructureFee: '2',
|
|
||||||
liquidityFee: '3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
__typename: 'MarketData',
|
|
||||||
bestBidPrice: '1605489971',
|
|
||||||
bestOfferPrice: '1606823730',
|
|
||||||
markPrice: '1606823730',
|
|
||||||
trigger: Types.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
|
||||||
staticMidPrice: '1606156850',
|
|
||||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
indicativeVolume: '0',
|
|
||||||
indicativePrice: '0',
|
|
||||||
bestStaticBidPrice: '1605489971',
|
|
||||||
bestStaticOfferPrice: '1606823730',
|
|
||||||
targetStake: '8561302732',
|
|
||||||
suppliedStake: '727654170336',
|
|
||||||
auctionStart: null,
|
|
||||||
auctionEnd: null,
|
|
||||||
market: { __typename: 'Market', id: 'market-id' },
|
|
||||||
},
|
|
||||||
marketTimestamps: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultWalletContext = {
|
|
||||||
pubKey: '111111__111111',
|
|
||||||
pubKeys: [],
|
|
||||||
sendTx: jest.fn().mockReturnValue(Promise.resolve(null)),
|
|
||||||
connect: jest.fn(),
|
|
||||||
disconnect: jest.fn(),
|
|
||||||
selectPubKey: jest.fn(),
|
|
||||||
connector: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const order = {
|
|
||||||
type: Schema.OrderType.TYPE_MARKET,
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
|
||||||
marketId: 'market-id',
|
|
||||||
side: Schema.Side.SIDE_BUY,
|
|
||||||
size: '0.1',
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultOrder = {
|
|
||||||
market: { ...market },
|
|
||||||
step: 0.1,
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const ERROR = {
|
|
||||||
KEY_MISSING: 'No public key selected',
|
|
||||||
KEY_TAINTED: 'Selected public key has been tainted',
|
|
||||||
MARKET_SUSPENDED: 'Market is currently suspended',
|
|
||||||
MARKET_INACTIVE: 'Market is no longer active',
|
|
||||||
MARKET_WAITING: 'Market is not active yet',
|
|
||||||
MARKET_CONTINUOUS_LIMIT:
|
|
||||||
'Only limit orders are permitted when market is in auction',
|
|
||||||
MARKET_CONTINUOUS_TIF:
|
|
||||||
'Until the auction ends, you can only place GFA, GTT, or GTC limit orders',
|
|
||||||
FIELD_SIZE_REQ: 'You need to provide a size',
|
|
||||||
FIELD_SIZE_MIN: `Size cannot be lower than "${defaultOrder.step}"`,
|
|
||||||
FIELD_PRICE_REQ: 'You need to provide a price',
|
|
||||||
FIELD_PRICE_MIN: 'The price cannot be negative',
|
|
||||||
FIELD_PRICE_STEP_NULL: 'Order sizes must be in whole numbers for this market',
|
|
||||||
FIELD_PRICE_STEP_DECIMAL: `The size field accepts up to ${market.positionDecimalPlaces} decimal places`,
|
|
||||||
};
|
|
||||||
|
|
||||||
function setup(
|
|
||||||
props?: Partial<ValidationProps>,
|
|
||||||
context?: Partial<VegaWalletContextShape>
|
|
||||||
) {
|
|
||||||
const mockUseVegaWallet = useVegaWallet as jest.Mock;
|
|
||||||
mockUseVegaWallet.mockReturnValue({ ...defaultWalletContext, context });
|
|
||||||
return renderHook(() => useOrderValidation({ ...defaultOrder, ...props }), {
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('useOrderValidation', () => {
|
|
||||||
afterEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Returns empty string when given valid data', () => {
|
|
||||||
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
|
|
||||||
balance: '0',
|
|
||||||
margin: '100',
|
|
||||||
balanceError: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { result } = setup();
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: false,
|
|
||||||
message: ``,
|
|
||||||
section: '',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Returns an error message when no keypair found', () => {
|
|
||||||
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
|
|
||||||
balance: '0',
|
|
||||||
margin: '100',
|
|
||||||
balanceError: false,
|
|
||||||
});
|
|
||||||
const { result } = setup(defaultOrder, { pubKey: null });
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: false,
|
|
||||||
message: ``,
|
|
||||||
section: '',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each`
|
|
||||||
state
|
|
||||||
${Schema.MarketState.STATE_SETTLED}
|
|
||||||
${Schema.MarketState.STATE_REJECTED}
|
|
||||||
${Schema.MarketState.STATE_TRADING_TERMINATED}
|
|
||||||
${Schema.MarketState.STATE_CLOSED}
|
|
||||||
${Schema.MarketState.STATE_CANCELLED}
|
|
||||||
`(
|
|
||||||
'Returns an error message for market state when not accepting orders',
|
|
||||||
({ state }) => {
|
|
||||||
const { result } = setup({ market: { ...defaultOrder.market, state } });
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: true,
|
|
||||||
message: `This market is ${marketTranslations(
|
|
||||||
state
|
|
||||||
)} and not accepting orders`,
|
|
||||||
section: 'sec-summary',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it.each`
|
|
||||||
state
|
|
||||||
${Schema.MarketState.STATE_PENDING}
|
|
||||||
${Schema.MarketState.STATE_PROPOSED}
|
|
||||||
`(
|
|
||||||
'Returns an error message for market state suspended or pending',
|
|
||||||
({ state }) => {
|
|
||||||
jest.spyOn(DealTicket, 'useOrderMarginValidation').mockReturnValue({
|
|
||||||
balance: '0',
|
|
||||||
margin: '100',
|
|
||||||
balanceError: false,
|
|
||||||
// asset,
|
|
||||||
});
|
|
||||||
const { result } = setup({
|
|
||||||
market: {
|
|
||||||
...defaultOrder.market,
|
|
||||||
state,
|
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
|
||||||
},
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTT,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: false,
|
|
||||||
message: `This market is ${MarketStateMapping[
|
|
||||||
state as Schema.MarketState
|
|
||||||
].toLowerCase()} and only accepting liquidity commitment orders`,
|
|
||||||
section: 'sec-summary',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it.each`
|
|
||||||
tradingMode | errorMessage
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${ERROR.MARKET_CONTINUOUS_LIMIT}
|
|
||||||
`(
|
|
||||||
`Returns an error message when trying to submit a non-limit order for a "$tradingMode" market`,
|
|
||||||
({ tradingMode, errorMessage }) => {
|
|
||||||
const { result } = setup({
|
|
||||||
market: { ...defaultOrder.market, tradingMode },
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
type: Schema.OrderType.TYPE_MARKET,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(result.current.isDisabled).toBeTruthy();
|
|
||||||
expect(result.current.message).toBe(errorMessage);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it.each`
|
|
||||||
tradingMode | orderTimeInForce | errorMessage
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_FOK} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_IOC} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
${Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION} | ${Schema.OrderTimeInForce.TIME_IN_FORCE_GFN} | ${ERROR.MARKET_CONTINUOUS_TIF}
|
|
||||||
`(
|
|
||||||
`Returns an error message when submitting a limit order with a "$orderTimeInForce" value to a "$tradingMode" market`,
|
|
||||||
({ tradingMode, orderTimeInForce, errorMessage }) => {
|
|
||||||
const { result } = setup({
|
|
||||||
market: { ...defaultOrder.market, tradingMode },
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
timeInForce: orderTimeInForce,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: true,
|
|
||||||
message: errorMessage,
|
|
||||||
section: 'sec-force',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it.each`
|
|
||||||
fieldName | errorType | section | errorMessage
|
|
||||||
${`size`} | ${`required`} | ${'sec-size'} | ${ERROR.FIELD_SIZE_REQ}
|
|
||||||
${`size`} | ${`min`} | ${'sec-size'} | ${ERROR.FIELD_SIZE_MIN}
|
|
||||||
${`price`} | ${`required`} | ${'sec-price'} | ${ERROR.FIELD_PRICE_REQ}
|
|
||||||
${`price`} | ${`min`} | ${'sec-price'} | ${ERROR.FIELD_PRICE_MIN}
|
|
||||||
`(
|
|
||||||
`Returns an error message when the order $fieldName "$errorType" validation fails`,
|
|
||||||
({ fieldName, errorType, section, errorMessage }) => {
|
|
||||||
const { result } = setup({
|
|
||||||
fieldErrors: { [fieldName]: { type: errorType } },
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: true,
|
|
||||||
message: errorMessage,
|
|
||||||
section,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it('Returns an error message when the order size incorrectly has decimal values', () => {
|
|
||||||
const { result } = setup({
|
|
||||||
market: { ...market, positionDecimalPlaces: 0 },
|
|
||||||
fieldErrors: {
|
|
||||||
size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: true,
|
|
||||||
message: ERROR.FIELD_PRICE_STEP_NULL,
|
|
||||||
section: 'sec-size',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Returns an error message when the order size has more decimals than allowed', () => {
|
|
||||||
const { result } = setup({
|
|
||||||
fieldErrors: {
|
|
||||||
size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: true,
|
|
||||||
message: ERROR.FIELD_PRICE_STEP_DECIMAL,
|
|
||||||
section: 'sec-size',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Returns an error message when the estimated margin is higher than collateral', async () => {
|
|
||||||
const invalidatedMockValue = {
|
|
||||||
balance: '100',
|
|
||||||
margin: '200',
|
|
||||||
balanceError: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
jest
|
|
||||||
.spyOn(DealTicket, 'useOrderMarginValidation')
|
|
||||||
.mockReturnValue(invalidatedMockValue);
|
|
||||||
|
|
||||||
const { result } = setup({});
|
|
||||||
|
|
||||||
expect(result.current.isDisabled).toBe(false);
|
|
||||||
|
|
||||||
const testElement = (
|
|
||||||
<DealTicket.MarginWarning
|
|
||||||
margin={invalidatedMockValue.margin}
|
|
||||||
balance={invalidatedMockValue.balance}
|
|
||||||
asset={asset}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
expect((result.current.message as React.ReactElement)?.props).toEqual(
|
|
||||||
testElement.props
|
|
||||||
);
|
|
||||||
expect((result.current.message as React.ReactElement)?.type).toEqual(
|
|
||||||
testElement.type
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each`
|
|
||||||
state
|
|
||||||
${Schema.MarketState.STATE_PENDING}
|
|
||||||
${Schema.MarketState.STATE_PROPOSED}
|
|
||||||
`(
|
|
||||||
'Returns error when market state is pending and size is wrong',
|
|
||||||
({ state }) => {
|
|
||||||
const { result } = setup({
|
|
||||||
fieldErrors: {
|
|
||||||
size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL },
|
|
||||||
},
|
|
||||||
market: {
|
|
||||||
...market,
|
|
||||||
state,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(result.current).toStrictEqual({
|
|
||||||
isDisabled: true,
|
|
||||||
message: ERROR.FIELD_PRICE_STEP_DECIMAL,
|
|
||||||
section: 'sec-size',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
@@ -1,384 +0,0 @@
|
|||||||
import type { ReactNode } from 'react';
|
|
||||||
import type { FieldErrors } from 'react-hook-form';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { t, toDecimal } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
|
||||||
import { MarketStateMapping, Schema } from '@vegaprotocol/types';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import {
|
|
||||||
MarketDataGrid,
|
|
||||||
compileGridData,
|
|
||||||
MarginWarning,
|
|
||||||
isMarketInAuction,
|
|
||||||
ERROR_SIZE_DECIMAL,
|
|
||||||
useOrderMarginValidation,
|
|
||||||
} from '@vegaprotocol/deal-ticket';
|
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
export const DEAL_TICKET_SECTION = {
|
|
||||||
TYPE: 'sec-type',
|
|
||||||
SIZE: 'sec-size',
|
|
||||||
PRICE: 'sec-price',
|
|
||||||
FORCE: 'sec-force',
|
|
||||||
EXPIRY: 'sec-expiry',
|
|
||||||
SUMMARY: 'sec-summary',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ERROR_EXPIRATION_IN_THE_PAST = 'ERROR_EXPIRATION_IN_THE_PAST';
|
|
||||||
|
|
||||||
export type ValidationProps = {
|
|
||||||
step?: number;
|
|
||||||
market: MarketDealTicket;
|
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
|
||||||
fieldErrors?: FieldErrors<OrderSubmissionBody['orderSubmission']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const marketTranslations = (marketState: Schema.MarketState) => {
|
|
||||||
switch (marketState) {
|
|
||||||
case Schema.MarketState.STATE_TRADING_TERMINATED:
|
|
||||||
return t('terminated');
|
|
||||||
default:
|
|
||||||
return t(MarketStateMapping[marketState]).toLowerCase();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DealTicketSection =
|
|
||||||
| ''
|
|
||||||
| typeof DEAL_TICKET_SECTION[keyof typeof DEAL_TICKET_SECTION];
|
|
||||||
|
|
||||||
export const useOrderValidation = ({
|
|
||||||
market,
|
|
||||||
fieldErrors,
|
|
||||||
order,
|
|
||||||
}: ValidationProps): {
|
|
||||||
message: ReactNode | string;
|
|
||||||
isDisabled: boolean;
|
|
||||||
section: DealTicketSection;
|
|
||||||
} => {
|
|
||||||
const { pubKey } = useVegaWallet();
|
|
||||||
const minSize = toDecimal(market.positionDecimalPlaces);
|
|
||||||
const isInvalidOrderMargin = useOrderMarginValidation({ market, order });
|
|
||||||
|
|
||||||
const fieldErrorChecking = useMemo<{
|
|
||||||
message: ReactNode | string;
|
|
||||||
isDisabled: boolean;
|
|
||||||
section: DealTicketSection;
|
|
||||||
} | null>(() => {
|
|
||||||
if (fieldErrors?.size?.type || fieldErrors?.price?.type) {
|
|
||||||
if (fieldErrors?.size?.type === 'required') {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t('You need to provide a size'),
|
|
||||||
section: DEAL_TICKET_SECTION.SIZE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldErrors?.size?.type === 'min') {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t(`Size cannot be lower than "${minSize}"`),
|
|
||||||
section: DEAL_TICKET_SECTION.SIZE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
fieldErrors?.price?.type === 'required' &&
|
|
||||||
order.type !== Schema.OrderType.TYPE_MARKET
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t('You need to provide a price'),
|
|
||||||
section: DEAL_TICKET_SECTION.PRICE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
fieldErrors?.price?.type === 'min' &&
|
|
||||||
order.type !== Schema.OrderType.TYPE_MARKET
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t(`The price cannot be negative`),
|
|
||||||
section: DEAL_TICKET_SECTION.PRICE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
fieldErrors?.size?.type === 'validate' &&
|
|
||||||
fieldErrors?.size?.message === ERROR_SIZE_DECIMAL
|
|
||||||
) {
|
|
||||||
if (market.positionDecimalPlaces === 0) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t('Order sizes must be in whole numbers for this market'),
|
|
||||||
section: DEAL_TICKET_SECTION.SIZE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t(
|
|
||||||
`The size field accepts up to ${market.positionDecimalPlaces} decimal places`
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.SIZE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
fieldErrors?.expiresAt?.type === 'validate' &&
|
|
||||||
fieldErrors?.expiresAt.message === ERROR_EXPIRATION_IN_THE_PAST
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: false,
|
|
||||||
message: t(
|
|
||||||
'The expiry date that you have entered appears to be in the past'
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.EXPIRY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}, [
|
|
||||||
fieldErrors?.size?.type,
|
|
||||||
fieldErrors?.size?.message,
|
|
||||||
fieldErrors?.price?.type,
|
|
||||||
fieldErrors?.expiresAt?.type,
|
|
||||||
fieldErrors?.expiresAt?.message,
|
|
||||||
order.type,
|
|
||||||
minSize,
|
|
||||||
market.positionDecimalPlaces,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const { message, isDisabled, section } = useMemo<{
|
|
||||||
message: ReactNode | string;
|
|
||||||
isDisabled: boolean;
|
|
||||||
section: DealTicketSection;
|
|
||||||
}>(() => {
|
|
||||||
if (!pubKey) {
|
|
||||||
return {
|
|
||||||
message: t('No public key selected'),
|
|
||||||
isDisabled: true,
|
|
||||||
section: DEAL_TICKET_SECTION.SUMMARY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
[
|
|
||||||
Schema.MarketState.STATE_SETTLED,
|
|
||||||
Schema.MarketState.STATE_REJECTED,
|
|
||||||
Schema.MarketState.STATE_TRADING_TERMINATED,
|
|
||||||
Schema.MarketState.STATE_CANCELLED,
|
|
||||||
Schema.MarketState.STATE_CLOSED,
|
|
||||||
].includes(market.state)
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t(
|
|
||||||
`This market is ${marketTranslations(
|
|
||||||
market.state
|
|
||||||
)} and not accepting orders`
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.SUMMARY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
[
|
|
||||||
Schema.MarketState.STATE_PROPOSED,
|
|
||||||
Schema.MarketState.STATE_PENDING,
|
|
||||||
].includes(market.state)
|
|
||||||
) {
|
|
||||||
if (fieldErrorChecking) {
|
|
||||||
return fieldErrorChecking;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
isDisabled: false,
|
|
||||||
message: t(
|
|
||||||
`This market is ${marketTranslations(
|
|
||||||
market.state
|
|
||||||
)} and only accepting liquidity commitment orders`
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.SUMMARY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMarketInAuction(market)) {
|
|
||||||
if (order.type === Schema.OrderType.TYPE_MARKET) {
|
|
||||||
if (
|
|
||||||
market.tradingMode ===
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
|
||||||
market.data?.trigger ===
|
|
||||||
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: (
|
|
||||||
<span>
|
|
||||||
{t('This market is in auction until it reaches')}{' '}
|
|
||||||
<Tooltip
|
|
||||||
description={
|
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>{t('sufficient liquidity')}</span>
|
|
||||||
</Tooltip>
|
|
||||||
{'. '}
|
|
||||||
{t('Only limit orders are permitted when market is in auction')}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.TYPE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
market.tradingMode ===
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
|
||||||
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: (
|
|
||||||
<span>
|
|
||||||
{t('This market is in auction due to')}{' '}
|
|
||||||
<Tooltip
|
|
||||||
description={
|
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>{t('high price volatility')}</span>
|
|
||||||
</Tooltip>
|
|
||||||
{'. '}
|
|
||||||
{t('Only limit orders are permitted when market is in auction')}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.TYPE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t(
|
|
||||||
'Only limit orders are permitted when market is in auction'
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.SUMMARY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
order.type === Schema.OrderType.TYPE_LIMIT &&
|
|
||||||
[
|
|
||||||
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
|
||||||
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC,
|
|
||||||
Schema.OrderTimeInForce.TIME_IN_FORCE_GFN,
|
|
||||||
].includes(order.timeInForce)
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
market.tradingMode ===
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
|
||||||
market.data?.trigger ===
|
|
||||||
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: (
|
|
||||||
<span>
|
|
||||||
{t('This market is in auction until it reaches')}{' '}
|
|
||||||
<Tooltip
|
|
||||||
description={
|
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>{t('sufficient liquidity')}</span>
|
|
||||||
</Tooltip>
|
|
||||||
{'. '}
|
|
||||||
{t(
|
|
||||||
`Until the auction ends, you can only place GFA, GTT, or GTC limit orders`
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.FORCE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
market.tradingMode ===
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
|
||||||
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: (
|
|
||||||
<span>
|
|
||||||
{t('This market is in auction due to')}{' '}
|
|
||||||
<Tooltip
|
|
||||||
description={
|
|
||||||
<MarketDataGrid grid={compileGridData(market)} />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>{t('high price volatility')}</span>
|
|
||||||
</Tooltip>
|
|
||||||
{'. '}
|
|
||||||
{t(
|
|
||||||
`Until the auction ends, you can only place GFA, GTT, or GTC limit orders`
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.FORCE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
isDisabled: true,
|
|
||||||
message: t(
|
|
||||||
`Until the auction ends, you can only place GFA, GTT, or GTC limit orders`
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.FORCE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldErrorChecking) {
|
|
||||||
return fieldErrorChecking;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isInvalidOrderMargin.balanceError) {
|
|
||||||
return {
|
|
||||||
isDisabled: false,
|
|
||||||
message: (
|
|
||||||
<MarginWarning
|
|
||||||
margin={isInvalidOrderMargin.margin}
|
|
||||||
balance={isInvalidOrderMargin.balance}
|
|
||||||
asset={market.tradableInstrument.instrument.product.settlementAsset}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.PRICE,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
[
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
|
||||||
].includes(market.tradingMode)
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
isDisabled: false,
|
|
||||||
message: t(
|
|
||||||
'Any orders placed now will not trade until the auction ends'
|
|
||||||
),
|
|
||||||
section: DEAL_TICKET_SECTION.SUMMARY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
isDisabled: false,
|
|
||||||
message: '',
|
|
||||||
section: '',
|
|
||||||
};
|
|
||||||
}, [
|
|
||||||
pubKey,
|
|
||||||
market,
|
|
||||||
fieldErrorChecking,
|
|
||||||
isInvalidOrderMargin,
|
|
||||||
order.type,
|
|
||||||
order.timeInForce,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return { message, isDisabled, section };
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/react-helpers';
|
|
||||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { DepositDialog, useDepositDialog } from '@vegaprotocol/deposits';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches data required for the Deposit page
|
|
||||||
*/
|
|
||||||
export const DepositContainer = () => {
|
|
||||||
const openDepositDialog = useDepositDialog((state) => state.open);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<DepositDialog />
|
|
||||||
<Button size="sm" onClick={() => openDepositDialog()}>
|
|
||||||
{t('Make deposit')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export * from './deposits';
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import type { ReactElement } from 'react';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children: ReactElement | ReactElement[];
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DrawerContent = ({ children, className = '' }: Props) => {
|
|
||||||
const classes = classNames(
|
|
||||||
'w-full sm:w-full grow-1 overflow-hidden',
|
|
||||||
className
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<main aria-label="Page Content" className={classes}>
|
|
||||||
{children}
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { ButtonLink, Icon } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { IconNames } from '@blueprintjs/icons';
|
|
||||||
import type { IconName } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
export const enum DRAWER_TOGGLE_VARIANTS {
|
|
||||||
OPEN = 'open',
|
|
||||||
CLOSE = 'close',
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
onToggle: React.MouseEventHandler<HTMLButtonElement>;
|
|
||||||
variant: DRAWER_TOGGLE_VARIANTS.OPEN | DRAWER_TOGGLE_VARIANTS.CLOSE;
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DrawerToggle = ({
|
|
||||||
onToggle,
|
|
||||||
variant = DRAWER_TOGGLE_VARIANTS.CLOSE,
|
|
||||||
className = '',
|
|
||||||
}: Props) => {
|
|
||||||
const [iconName, setIconName] = useState(IconNames.MENU);
|
|
||||||
const classes = classNames('md:hidden', className);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (variant === DRAWER_TOGGLE_VARIANTS.OPEN) {
|
|
||||||
setIconName(IconNames.MENU);
|
|
||||||
} else {
|
|
||||||
setIconName(IconNames.CROSS);
|
|
||||||
}
|
|
||||||
}, [variant]);
|
|
||||||
|
|
||||||
const ariaLabel = `${
|
|
||||||
variant === DRAWER_TOGGLE_VARIANTS.OPEN ? 'Open' : 'Close'
|
|
||||||
} Sidebar Navigation Menu`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span className={classes}>
|
|
||||||
<ButtonLink aria-label={ariaLabel} onClick={onToggle}>
|
|
||||||
<Icon name={iconName as IconName} />
|
|
||||||
</ButtonLink>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import type { ReactElement } from 'react';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children: ReactElement | ReactElement[];
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DrawerWrapper = ({ children, className = '' }: Props) => {
|
|
||||||
const classes = classNames('flex dark:bg-lite-black md:flex-row', className);
|
|
||||||
return <div className={classes}>{children}</div>;
|
|
||||||
};
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import type { ReactElement } from 'react';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children?: ReactElement | ReactElement[];
|
|
||||||
isMenuOpen?: boolean;
|
|
||||||
onToggle(): void;
|
|
||||||
rtl?: boolean;
|
|
||||||
outerClasses?: string;
|
|
||||||
innerClasses?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NavigationDrawer = ({
|
|
||||||
isMenuOpen = false,
|
|
||||||
onToggle,
|
|
||||||
children,
|
|
||||||
rtl,
|
|
||||||
outerClasses = '',
|
|
||||||
innerClasses = '',
|
|
||||||
}: Props) => {
|
|
||||||
const width = 'w-full md:w-auto md:min-w-[15%] shrink-0';
|
|
||||||
const position = 'absolute inset-0 h-full z-10 md:static';
|
|
||||||
const background = 'bg-black/50 dark:bg-white/50';
|
|
||||||
const flex = 'flex justify-end overflow-hidden';
|
|
||||||
const joinedClasses = [flex, width, position, background].join(' ');
|
|
||||||
|
|
||||||
const outerStyles = classNames(joinedClasses, {
|
|
||||||
visible: isMenuOpen,
|
|
||||||
'invisible md:visible': !isMenuOpen,
|
|
||||||
'flex-row-reverse': !rtl,
|
|
||||||
[outerClasses]: outerClasses,
|
|
||||||
});
|
|
||||||
|
|
||||||
const translateClose = rtl ? 'translate-x-full' : '-translate-x-full';
|
|
||||||
|
|
||||||
const innerStyles = classNames(
|
|
||||||
'w-3/4 md:w-full bg-white dark:bg-lite-black',
|
|
||||||
{
|
|
||||||
'translate-x-0 transition-transform md:transform-none': isMenuOpen,
|
|
||||||
[`${translateClose} md:transform-none`]: !isMenuOpen,
|
|
||||||
[innerClasses]: innerClasses,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<aside aria-label="Sidebar Navigation Menu" className={outerStyles}>
|
|
||||||
<div
|
|
||||||
role="presentation"
|
|
||||||
aria-label="Content Overlay - Click To Close Sidebar Navigation"
|
|
||||||
className="md:hidden grow h-full"
|
|
||||||
onClick={onToggle}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
role="group"
|
|
||||||
aria-label="Sidebar Navigation Grouped Content"
|
|
||||||
className={innerStyles}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export * from './drawer';
|
|
||||||
export * from './drawer-toggle';
|
|
||||||
export * from './drawer-content';
|
|
||||||
export * from './drawer-wrapper';
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
const Comet = () => {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 118 82"
|
|
||||||
fill="currentColor"
|
|
||||||
className="max-w-[7.5rem] mx-auto"
|
|
||||||
>
|
|
||||||
<g className="fill-black dark:fill-white">
|
|
||||||
<path d="M44.3791 67.5864H41.5859V70.3796H44.3791V67.5864Z"></path>
|
|
||||||
<path d="M47.173 64.7932V62H44.3799V64.7932V67.5863H47.173V64.7932Z"></path>
|
|
||||||
<path d="M41.5863 70.3794H36V73.1726H41.5863V70.3794Z"></path>
|
|
||||||
<path d="M44.3791 73.1719H41.5859V75.965H44.3791V73.1719Z"></path>
|
|
||||||
<path d="M47.173 75.9658H44.3799V81.5521H47.173V75.9658Z"></path>
|
|
||||||
<path d="M49.966 73.1719H47.1729V75.965H49.966V73.1719Z"></path>
|
|
||||||
<path d="M55.5521 70.3794H49.9658V73.1726H55.5521V70.3794Z"></path>
|
|
||||||
<path d="M49.966 67.5864H47.1729V70.3796H49.966V67.5864Z"></path>
|
|
||||||
<path d="M57.1876 60.564H54V63.7515H57.1876V60.564Z"></path>
|
|
||||||
<path d="M60.3751 57.3765H57.1875V60.564H60.3751V57.3765Z"></path>
|
|
||||||
<path d="M63.5626 54.1885H60.375V57.3761H63.5626V54.1885Z"></path>
|
|
||||||
<path d="M66.7501 51.001H63.5625V54.1886H66.7501V51.001Z"></path>
|
|
||||||
<path d="M69.9376 47.8135H66.75V51.0011H69.9376V47.8135Z"></path>
|
|
||||||
<path d="M73.1251 44.626H69.9375V47.8136H73.1251V44.626Z"></path>
|
|
||||||
<path d="M76.3126 41.4385H73.125V44.6261H76.3126V41.4385Z"></path>
|
|
||||||
<path d="M79.5001 38.251H76.3125V41.4386H79.5001V38.251Z"></path>
|
|
||||||
<path d="M82.6886 35.0635H79.501V38.2511H82.6886V35.0635Z"></path>
|
|
||||||
<path d="M85.8761 31.876H82.6885V35.0636H85.8761V31.876Z"></path>
|
|
||||||
<path d="M89.0636 28.688H85.876V31.8756H89.0636V28.688Z"></path>
|
|
||||||
<path d="M92.2511 25.5005H89.0635V28.6881H92.2511V25.5005Z"></path>
|
|
||||||
<path d="M95.4386 22.313H92.251V25.5006H95.4386V22.313Z"></path>
|
|
||||||
<path d="M98.6261 19.1255H95.4385V22.3131H98.6261V19.1255Z"></path>
|
|
||||||
<path d="M101.814 15.938H98.626V19.1256H101.814V15.938Z"></path>
|
|
||||||
<path d="M105.001 12.7505H101.813V15.9381H105.001V12.7505Z"></path>
|
|
||||||
<path d="M108.189 9.5625H105.001V12.7501H108.189V9.5625Z"></path>
|
|
||||||
<path d="M111.376 6.375H108.188V9.56258H111.376V6.375Z"></path>
|
|
||||||
<path d="M114.565 3.1875H111.377V6.37508H114.565V3.1875Z"></path>
|
|
||||||
<path d="M117.752 0H114.564V3.18758H117.752V0Z"></path>
|
|
||||||
<path d="M2.79316 20.793H0V23.5861H2.79316V20.793Z"></path>
|
|
||||||
<path d="M5.58612 18H2.79297V20.7932H5.58612V18Z"></path>
|
|
||||||
<path d="M5.58612 23.5859H2.79297V26.3791H5.58612V23.5859Z"></path>
|
|
||||||
<path d="M8.37909 20.793H5.58594V23.5861H8.37909V20.793Z"></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Comet;
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import React, { useContext } from 'react';
|
|
||||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
|
||||||
import Logo from './logo';
|
|
||||||
import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
|
|
||||||
import LocalContext from '../../context/local-context';
|
|
||||||
|
|
||||||
const Header = () => {
|
|
||||||
const { updateVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
|
||||||
updateVegaWalletDialog: store.updateVegaWalletDialog,
|
|
||||||
}));
|
|
||||||
const {
|
|
||||||
vegaWalletDialog: { setManage },
|
|
||||||
theme,
|
|
||||||
toggleTheme,
|
|
||||||
} = useContext(LocalContext);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="dark flex items-stretch pr-6 py-6 bg-black text-neutral-400"
|
|
||||||
data-testid="header"
|
|
||||||
>
|
|
||||||
<Logo />
|
|
||||||
<div className="flex items-center gap-2 ml-auto relative z-10">
|
|
||||||
<VegaWalletConnectButton
|
|
||||||
setConnectDialog={updateVegaWalletDialog}
|
|
||||||
setManageDialog={setManage}
|
|
||||||
/>
|
|
||||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Header;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default } from './header';
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { NavLink } from 'react-router-dom';
|
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
|
||||||
import { VLogo } from '@vegaprotocol/ui-toolkit';
|
|
||||||
|
|
||||||
const Logo = () => {
|
|
||||||
return (
|
|
||||||
<NavLink
|
|
||||||
className="mx-6 text-white"
|
|
||||||
aria-label={t('Go to home page')}
|
|
||||||
to="/"
|
|
||||||
>
|
|
||||||
<VLogo className="mx-6 my-2" />
|
|
||||||
</NavLink>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Logo;
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user