Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb4aeb6d8d | ||
|
|
e5bcc1dc96 | ||
|
|
2a8094ed6d |
@@ -2761,7 +2761,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "86666.297",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "68263.0045351688904193975",
|
||||
"locked_amount": "69212.7941588870528164928",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "86666.297",
|
||||
@@ -2827,7 +2827,7 @@
|
||||
"tranche_end": "2023-06-01T00:00:00.000Z",
|
||||
"total_added": "2500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "1380.40515618640625",
|
||||
"locked_amount": "1435.351483007733",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "2500",
|
||||
@@ -3214,8 +3214,8 @@
|
||||
"tranche_start": "2023-02-01T00:00:00.000Z",
|
||||
"tranche_end": "2023-08-01T00:00:00.000Z",
|
||||
"total_added": "37500",
|
||||
"total_removed": "3009.936598125",
|
||||
"locked_amount": "33458.597107120935",
|
||||
"total_removed": "2836.415649675",
|
||||
"locked_amount": "34287.34557243708",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -3244,11 +3244,6 @@
|
||||
"user": "0x0B4e6fcE839B01ef43DA6F890FAC7B1Afb004600",
|
||||
"tx": "0x78fd0cf1ca8de93d15eee1424146bcd70b84cc168b4c1ea1ac50020b8d67bcc1"
|
||||
},
|
||||
{
|
||||
"amount": "173.52094845",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x6f125819654942fd6c08c0929e7f9e9629eb65c2cfa92acae0f8db9685a43537"
|
||||
},
|
||||
{
|
||||
"amount": "183.137181525",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -3284,12 +3279,6 @@
|
||||
"tranche_id": 34,
|
||||
"tx": "0x5bfef799be13741d89872cc604df1f35b41069397e681577fc15c039866d8707"
|
||||
},
|
||||
{
|
||||
"amount": "173.52094845",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 34,
|
||||
"tx": "0x6f125819654942fd6c08c0929e7f9e9629eb65c2cfa92acae0f8db9685a43537"
|
||||
},
|
||||
{
|
||||
"amount": "183.137181525",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -3304,8 +3293,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "7500",
|
||||
"withdrawn_tokens": "734.823415425",
|
||||
"remaining_tokens": "6765.176584575"
|
||||
"withdrawn_tokens": "561.302466975",
|
||||
"remaining_tokens": "6938.697533025"
|
||||
},
|
||||
{
|
||||
"address": "0x0B4e6fcE839B01ef43DA6F890FAC7B1Afb004600",
|
||||
@@ -3337,7 +3326,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "129999.45",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "68200.723132711121161125",
|
||||
"locked_amount": "69149.646192904764493335",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129999.45",
|
||||
@@ -3403,7 +3392,7 @@
|
||||
"tranche_end": "2023-09-03T00:00:00.000Z",
|
||||
"total_added": "62600",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "33356.96660324707972",
|
||||
"locked_amount": "34043.00988077117846",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10000",
|
||||
@@ -3596,7 +3585,7 @@
|
||||
"tranche_end": "2023-09-17T00:00:00.000Z",
|
||||
"total_added": "5000",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "2856.0752790461695",
|
||||
"locked_amount": "2910.871067985794",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "5000",
|
||||
@@ -3807,7 +3796,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "97499.58",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "10120.7578313676737285694",
|
||||
"locked_amount": "11051.5629572361427967976",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "97499.58",
|
||||
@@ -3840,7 +3829,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "135173.4239508",
|
||||
"total_removed": "98230.390980249184455396",
|
||||
"locked_amount": "13833.328679532308285265754872",
|
||||
"locked_amount": "15105.57858979342307160273426",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "135173.4239508",
|
||||
@@ -3886,7 +3875,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "32499.86",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "4257.628043517122507983",
|
||||
"locked_amount": "4649.201685825244862006",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "32499.86",
|
||||
@@ -3919,7 +3908,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "10833.29",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "1385.816613120234447893",
|
||||
"locked_amount": "1513.2700339508446292286",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10833.29",
|
||||
@@ -3952,7 +3941,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "22749.93",
|
||||
"total_removed": "4720.860935375",
|
||||
"locked_amount": "5180.4920163939779224332",
|
||||
"locked_amount": "5656.9413696662315119734",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "6500",
|
||||
@@ -4103,8 +4092,8 @@
|
||||
"tranche_start": "2022-11-01T00:00:00.000Z",
|
||||
"tranche_end": "2023-05-01T00:00:00.000Z",
|
||||
"total_added": "22500",
|
||||
"total_removed": "4546.97235645",
|
||||
"locked_amount": "8638.69417587477",
|
||||
"total_removed": "4373.451408",
|
||||
"locked_amount": "9135.943255064457",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -4128,11 +4117,6 @@
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x4a7c7462e3bb6abe2d33dfe5a1bf1e4211e52e5e03239c02554988f7d3635523"
|
||||
},
|
||||
{
|
||||
"amount": "173.52094845",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0xb40f1c9a538e1998da74acd7fceea8a718e97b2af8e903277e16a4b729628a52"
|
||||
},
|
||||
{
|
||||
"amount": "167.6680479",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -4228,12 +4212,6 @@
|
||||
"tranche_id": 33,
|
||||
"tx": "0x4a7c7462e3bb6abe2d33dfe5a1bf1e4211e52e5e03239c02554988f7d3635523"
|
||||
},
|
||||
{
|
||||
"amount": "173.52094845",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 33,
|
||||
"tx": "0xb40f1c9a538e1998da74acd7fceea8a718e97b2af8e903277e16a4b729628a52"
|
||||
},
|
||||
{
|
||||
"amount": "167.6680479",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -4320,8 +4298,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "7500",
|
||||
"withdrawn_tokens": "4546.97235645",
|
||||
"remaining_tokens": "2953.02764355"
|
||||
"withdrawn_tokens": "4373.451408",
|
||||
"remaining_tokens": "3126.548592"
|
||||
},
|
||||
{
|
||||
"address": "0x2539b51EbDE65a75672aBcfE9439a706a99D18D1",
|
||||
@@ -4346,7 +4324,7 @@
|
||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||
"total_added": "1939928.38",
|
||||
"total_removed": "928642.9598472029154",
|
||||
"locked_amount": "539424.9645325482335879628",
|
||||
"locked_amount": "560684.945746241749007341",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1852091.69",
|
||||
@@ -7320,15 +7298,10 @@
|
||||
"tranche_id": 10,
|
||||
"tranche_start": "2021-07-15T23:37:11.000Z",
|
||||
"tranche_end": "2021-07-15T23:37:11.000Z",
|
||||
"total_added": "6259302.299000000000000001",
|
||||
"total_removed": "6213483.280000000000000001",
|
||||
"total_added": "6159302.299000000000000001",
|
||||
"total_removed": "6113483.280000000000000001",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tx": "0xa4417547c32fb4936e0dd6ee338ba31b2fd622388fe8a3906d9e7020d5e8371b"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -7851,11 +7824,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tx": "0xa4417547c32fb4936e0dd6ee338ba31b2fd622388fe8a3906d9e7020d5e8371b"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -8321,12 +8289,6 @@
|
||||
{
|
||||
"address": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tranche_id": 10,
|
||||
"tx": "0xa4417547c32fb4936e0dd6ee338ba31b2fd622388fe8a3906d9e7020d5e8371b"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -8509,12 +8471,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
"tranche_id": 10,
|
||||
"tx": "0xa4417547c32fb4936e0dd6ee338ba31b2fd622388fe8a3906d9e7020d5e8371b"
|
||||
},
|
||||
{
|
||||
"amount": "100000",
|
||||
"user": "0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f",
|
||||
@@ -8690,8 +8646,8 @@
|
||||
"tx": "0xac16a4ce688d40a482a59914d68c3a676592f8804ee8f0781b66a4ba5ccfbdfc"
|
||||
}
|
||||
],
|
||||
"total_tokens": "3056651",
|
||||
"withdrawn_tokens": "3056651",
|
||||
"total_tokens": "2956651",
|
||||
"withdrawn_tokens": "2956651",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
@@ -36637,8 +36593,8 @@
|
||||
"tranche_start": "2022-03-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "3732368.4671",
|
||||
"total_removed": "609657.626547646980493",
|
||||
"locked_amount": "853409.68739043787138149417",
|
||||
"total_removed": "592998.0503546212334",
|
||||
"locked_amount": "886078.876576593193858643006",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1998.95815",
|
||||
@@ -36807,11 +36763,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "16659.576193025747093",
|
||||
"user": "0xB523235B6c7C74DDB26b10E78bFb2d0Cb63Ae289",
|
||||
"tx": "0x2c5cfeee95fba21323fdbfde219501aeafe8d7f236d1283b4f8f7c7760e4401c"
|
||||
},
|
||||
{
|
||||
"amount": "144779.049152",
|
||||
"user": "0x1da69E9C22d77Ef8Ccbf5a1F2d83eDBc5Dcc20fA",
|
||||
@@ -37911,17 +37862,10 @@
|
||||
"tx": "0x8cc5159f3d665dd33a2bdac6e990cf1b65dc18b6b5e37a07b37dd54495a8d33c"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "16659.576193025747093",
|
||||
"user": "0xB523235B6c7C74DDB26b10E78bFb2d0Cb63Ae289",
|
||||
"tranche_id": 1,
|
||||
"tx": "0x2c5cfeee95fba21323fdbfde219501aeafe8d7f236d1283b4f8f7c7760e4401c"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"total_tokens": "21666.5743",
|
||||
"withdrawn_tokens": "16659.576193025747093",
|
||||
"remaining_tokens": "5006.998106974252907"
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "21666.5743"
|
||||
},
|
||||
{
|
||||
"address": "0x7227e17101E6C70F4dAfC7DDB77BB7D83DdfC1C8",
|
||||
@@ -37975,8 +37919,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "15870102.715470999700000001",
|
||||
"total_removed": "572499.39869964008974952",
|
||||
"locked_amount": "8325823.5429882556378904209318474167342525",
|
||||
"total_removed": "567626.84057226362274952",
|
||||
"locked_amount": "8441666.3902799341022910153716735157718303",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "16249.93",
|
||||
@@ -38510,26 +38454,6 @@
|
||||
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
|
||||
"tx": "0x4870598253a2a664d9c96af37904f08ac772ee9620b5975560ef7e7fb51c9a7f"
|
||||
},
|
||||
{
|
||||
"amount": "2820.55961",
|
||||
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
|
||||
"tx": "0x039c7d1eb6b18a13c3fb91589403d43710e12b319e7d40936280a576502f80fe"
|
||||
},
|
||||
{
|
||||
"amount": "1073.5102073953235",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x75d6ba37c5621a2bfd39153fdeb79265a5fd36872774966fff58a7a0c476b99b"
|
||||
},
|
||||
{
|
||||
"amount": "404.073696023421875",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0xa0d7984104142e0bfbd90d11fbb3006941b04976943427b1e248514e0d6dbcce"
|
||||
},
|
||||
{
|
||||
"amount": "574.414613957721625",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x702ab149d41128eefe14cffbca4297575ef4b88a30a15c864af13bf9621e000f"
|
||||
},
|
||||
{
|
||||
"amount": "856.08784586478614",
|
||||
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
|
||||
@@ -40238,24 +40162,6 @@
|
||||
"tranche_id": 2,
|
||||
"tx": "0x307e498402679f0f8ee11dcd3dfc684db5558203469f07ce58e98a4f87f0fa62"
|
||||
},
|
||||
{
|
||||
"amount": "1073.5102073953235",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x75d6ba37c5621a2bfd39153fdeb79265a5fd36872774966fff58a7a0c476b99b"
|
||||
},
|
||||
{
|
||||
"amount": "404.073696023421875",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 2,
|
||||
"tx": "0xa0d7984104142e0bfbd90d11fbb3006941b04976943427b1e248514e0d6dbcce"
|
||||
},
|
||||
{
|
||||
"amount": "574.414613957721625",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x702ab149d41128eefe14cffbca4297575ef4b88a30a15c864af13bf9621e000f"
|
||||
},
|
||||
{
|
||||
"amount": "966.75883976995675",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -41398,8 +41304,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "259998.8875",
|
||||
"withdrawn_tokens": "123330.640757104133375",
|
||||
"remaining_tokens": "136668.246742895866625"
|
||||
"withdrawn_tokens": "121278.642239727666375",
|
||||
"remaining_tokens": "138720.245260272333625"
|
||||
},
|
||||
{
|
||||
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
||||
@@ -42059,12 +41965,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "2820.55961",
|
||||
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
|
||||
"tranche_id": 2,
|
||||
"tx": "0x039c7d1eb6b18a13c3fb91589403d43710e12b319e7d40936280a576502f80fe"
|
||||
},
|
||||
{
|
||||
"amount": "1412.763584",
|
||||
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
|
||||
@@ -42265,8 +42165,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200000",
|
||||
"withdrawn_tokens": "93634.576066",
|
||||
"remaining_tokens": "106365.423934"
|
||||
"withdrawn_tokens": "90814.016456",
|
||||
"remaining_tokens": "109185.983544"
|
||||
},
|
||||
{
|
||||
"address": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
|
||||
@@ -43618,8 +43518,8 @@
|
||||
"tranche_start": "2021-11-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||
"total_added": "14597706.0446472999",
|
||||
"total_removed": "3929814.620647104804508532",
|
||||
"locked_amount": "1964901.907711197956979028434298527",
|
||||
"total_removed": "3926967.723059737571037032",
|
||||
"locked_amount": "2071847.284667310624156645942280506",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129284.449",
|
||||
@@ -43853,21 +43753,6 @@
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0x532c270b8a50b8e2923a96b038129a203e01eba1b84faf238dd9b48aeceb1c91"
|
||||
},
|
||||
{
|
||||
"amount": "1488.49150551791738425",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0x6bacc9b91153b8977b9cabc510975f9d249be098bf8dc841ca72408513d9fbb1"
|
||||
},
|
||||
{
|
||||
"amount": "560.9020402316959745",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0x6dfd5e6e697a6db058ed45cd16d19ee2bb68b5e3dfecdc52b7829d85e9adbaa0"
|
||||
},
|
||||
{
|
||||
"amount": "797.50404161762011275",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tx": "0xa7b60b86ca0234d8bcfeac24131315f65b0f041aebd74593e73a86c75ea2cce4"
|
||||
},
|
||||
{
|
||||
"amount": "1333.9237119810715295",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
@@ -46764,24 +46649,6 @@
|
||||
"tranche_id": 3,
|
||||
"tx": "0x532c270b8a50b8e2923a96b038129a203e01eba1b84faf238dd9b48aeceb1c91"
|
||||
},
|
||||
{
|
||||
"amount": "1488.49150551791738425",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x6bacc9b91153b8977b9cabc510975f9d249be098bf8dc841ca72408513d9fbb1"
|
||||
},
|
||||
{
|
||||
"amount": "560.9020402316959745",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tranche_id": 3,
|
||||
"tx": "0x6dfd5e6e697a6db058ed45cd16d19ee2bb68b5e3dfecdc52b7829d85e9adbaa0"
|
||||
},
|
||||
{
|
||||
"amount": "797.50404161762011275",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
"tranche_id": 3,
|
||||
"tx": "0xa7b60b86ca0234d8bcfeac24131315f65b0f041aebd74593e73a86c75ea2cce4"
|
||||
},
|
||||
{
|
||||
"amount": "1333.9237119810715295",
|
||||
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
|
||||
@@ -49226,8 +49093,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "359123.469575",
|
||||
"withdrawn_tokens": "310416.427876556103908",
|
||||
"remaining_tokens": "48707.041698443896092"
|
||||
"withdrawn_tokens": "307569.5302891888704365",
|
||||
"remaining_tokens": "51553.9392858111295635"
|
||||
},
|
||||
{
|
||||
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
|
||||
@@ -50565,7 +50432,7 @@
|
||||
"tranche_end": "2023-04-05T00:00:00.000Z",
|
||||
"total_added": "5778205.3912159303",
|
||||
"total_removed": "2749067.463242913023296295",
|
||||
"locked_amount": "459441.223824313146555414584474726",
|
||||
"locked_amount": "501695.989059927736982047096440314",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "552496.6455",
|
||||
@@ -52591,8 +52458,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "472355.6199999996",
|
||||
"total_removed": "34093.0379154332685",
|
||||
"locked_amount": "135227.64326476268541023641603248",
|
||||
"total_removed": "33643.6376997992685",
|
||||
"locked_amount": "140404.26303635577567951130086252",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "3000",
|
||||
@@ -59276,41 +59143,6 @@
|
||||
"user": "0x4F4A140E9B4a8403792970C6b5535ed0AA32c8A4",
|
||||
"tx": "0x181a9afe9b3592427f1ee10f205e01f34ae7be383294e8d93e397766092bf6df"
|
||||
},
|
||||
{
|
||||
"amount": "18.399238968",
|
||||
"user": "0xD3ec605d078326B0a636ca90d496Ebb5Eb457a27",
|
||||
"tx": "0xa82e451753cbced76b064af62868d3170dff7afca557680e657c27ebba5c7beb"
|
||||
},
|
||||
{
|
||||
"amount": "141.230663368",
|
||||
"user": "0xb7df334217A208B5B35a3824D1CDdBCa85BD352B",
|
||||
"tx": "0x41e9fa9b5003c1d6edf1e9423bd6ae7ce6e4e48fcbce0b47ba17968a67da4d48"
|
||||
},
|
||||
{
|
||||
"amount": "12.107001524",
|
||||
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
|
||||
"tx": "0xa2e745ec65b1caad05b18aa7c730d0550a263df2208ba10cecee5a30f815447b"
|
||||
},
|
||||
{
|
||||
"amount": "24.023287672",
|
||||
"user": "0xcB555C5602cC0b2434A27d277e14Cb5C7bF4Ead1",
|
||||
"tx": "0xbb25fa75431a6463909c9efde31d110e1aa5c945d0363fcc4bd5c46f869cabac"
|
||||
},
|
||||
{
|
||||
"amount": "94.45296804",
|
||||
"user": "0x7345AaA0D0e4C4A46d921fA9323973956F2b7392",
|
||||
"tx": "0x10a149356dc25da53994746b06fc8922faa23be9fb781541e91357d7d4f4d36a"
|
||||
},
|
||||
{
|
||||
"amount": "142.126249364",
|
||||
"user": "0x289047e767D23561A2035cd3fdc60c94ed1bBA3B",
|
||||
"tx": "0x61b2f8e5f4efb5049e418ede94fd54dfc1ed8d0f1165ff31517f4f748ef14899"
|
||||
},
|
||||
{
|
||||
"amount": "17.060806698",
|
||||
"user": "0x28FC83947F02f59Cb36b40f97f2D32BBC5D00585",
|
||||
"tx": "0x9d1ced8d04e8d58af92b1434bcb269487a3f6ddf4305c0739ab0f158f5401ec6"
|
||||
},
|
||||
{
|
||||
"amount": "13.1116203702",
|
||||
"user": "0x4cBC0C88d8FE503f62823B42f30a4900292C13bE",
|
||||
@@ -63926,17 +63758,10 @@
|
||||
"tx": "0x1c2c084e3efafb2ffa09c0b259bd229cce0d6da04dd092d911c7e6136a7ac8a9"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "141.230663368",
|
||||
"user": "0xb7df334217A208B5B35a3824D1CDdBCa85BD352B",
|
||||
"tranche_id": 5,
|
||||
"tx": "0x41e9fa9b5003c1d6edf1e9423bd6ae7ce6e4e48fcbce0b47ba17968a67da4d48"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"total_tokens": "200",
|
||||
"withdrawn_tokens": "141.230663368",
|
||||
"remaining_tokens": "58.769336632"
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "200"
|
||||
},
|
||||
{
|
||||
"address": "0x287a34EB03418ad55c2e93d0E4FB1e18DCE607ED",
|
||||
@@ -65949,17 +65774,10 @@
|
||||
"tx": "0x75de6ca47e0da361181d14aceb5d08e572754861465caa67a12b528886d55307"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "142.126249364",
|
||||
"user": "0x289047e767D23561A2035cd3fdc60c94ed1bBA3B",
|
||||
"tranche_id": 5,
|
||||
"tx": "0x61b2f8e5f4efb5049e418ede94fd54dfc1ed8d0f1165ff31517f4f748ef14899"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"total_tokens": "200",
|
||||
"withdrawn_tokens": "142.126249364",
|
||||
"remaining_tokens": "57.873750636"
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "200"
|
||||
},
|
||||
{
|
||||
"address": "0x45bAfA40E9e8099cCd9Ed0e3112A11E7a1d37beb",
|
||||
@@ -67483,12 +67301,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "18.399238968",
|
||||
"user": "0xD3ec605d078326B0a636ca90d496Ebb5Eb457a27",
|
||||
"tranche_id": 5,
|
||||
"tx": "0xa82e451753cbced76b064af62868d3170dff7afca557680e657c27ebba5c7beb"
|
||||
},
|
||||
{
|
||||
"amount": "262.76406646",
|
||||
"user": "0xD3ec605d078326B0a636ca90d496Ebb5Eb457a27",
|
||||
@@ -67497,8 +67309,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "400",
|
||||
"withdrawn_tokens": "281.163305428",
|
||||
"remaining_tokens": "118.836694572"
|
||||
"withdrawn_tokens": "262.76406646",
|
||||
"remaining_tokens": "137.23593354"
|
||||
},
|
||||
{
|
||||
"address": "0x7f6aba7563Cb5d31980D440337D3d1A6e3dB58F3",
|
||||
@@ -72745,12 +72557,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "12.107001524",
|
||||
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
|
||||
"tranche_id": 5,
|
||||
"tx": "0xa2e745ec65b1caad05b18aa7c730d0550a263df2208ba10cecee5a30f815447b"
|
||||
},
|
||||
{
|
||||
"amount": "15.80745814",
|
||||
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
|
||||
@@ -72831,8 +72637,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "400",
|
||||
"withdrawn_tokens": "282.749759004",
|
||||
"remaining_tokens": "117.250240996"
|
||||
"withdrawn_tokens": "270.64275748",
|
||||
"remaining_tokens": "129.35724252"
|
||||
},
|
||||
{
|
||||
"address": "0x5c90765F50629570738fEe7b7FA82ae118f81Ed1",
|
||||
@@ -77102,12 +76908,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "94.45296804",
|
||||
"user": "0x7345AaA0D0e4C4A46d921fA9323973956F2b7392",
|
||||
"tranche_id": 5,
|
||||
"tx": "0x10a149356dc25da53994746b06fc8922faa23be9fb781541e91357d7d4f4d36a"
|
||||
},
|
||||
{
|
||||
"amount": "119.5173516",
|
||||
"user": "0x7345AaA0D0e4C4A46d921fA9323973956F2b7392",
|
||||
@@ -77152,8 +76952,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "1200",
|
||||
"withdrawn_tokens": "850.0164003",
|
||||
"remaining_tokens": "349.9835997"
|
||||
"withdrawn_tokens": "755.56343226",
|
||||
"remaining_tokens": "444.43656774"
|
||||
},
|
||||
{
|
||||
"address": "0x47181cf36aDFb0b5dB7EfDB123f403D890607841",
|
||||
@@ -77345,12 +77145,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "24.023287672",
|
||||
"user": "0xcB555C5602cC0b2434A27d277e14Cb5C7bF4Ead1",
|
||||
"tranche_id": 5,
|
||||
"tx": "0xbb25fa75431a6463909c9efde31d110e1aa5c945d0363fcc4bd5c46f869cabac"
|
||||
},
|
||||
{
|
||||
"amount": "37.881582952",
|
||||
"user": "0xcB555C5602cC0b2434A27d277e14Cb5C7bF4Ead1",
|
||||
@@ -77371,8 +77165,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "400",
|
||||
"withdrawn_tokens": "283.113077116",
|
||||
"remaining_tokens": "116.886922884"
|
||||
"withdrawn_tokens": "259.089789444",
|
||||
"remaining_tokens": "140.910210556"
|
||||
},
|
||||
{
|
||||
"address": "0x3738bec36216eA2F11B954891C65AAd1Bc852156",
|
||||
@@ -80196,12 +79990,6 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "17.060806698",
|
||||
"user": "0x28FC83947F02f59Cb36b40f97f2D32BBC5D00585",
|
||||
"tranche_id": 5,
|
||||
"tx": "0x9d1ced8d04e8d58af92b1434bcb269487a3f6ddf4305c0739ab0f158f5401ec6"
|
||||
},
|
||||
{
|
||||
"amount": "15.872983256",
|
||||
"user": "0x28FC83947F02f59Cb36b40f97f2D32BBC5D00585",
|
||||
@@ -80228,8 +80016,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "200",
|
||||
"withdrawn_tokens": "142.641089548",
|
||||
"remaining_tokens": "57.358910452"
|
||||
"withdrawn_tokens": "125.58028285",
|
||||
"remaining_tokens": "74.41971715"
|
||||
},
|
||||
{
|
||||
"address": "0xBef628af8547cE5264835F32487055a7e3dF393D",
|
||||
@@ -81430,7 +81218,7 @@
|
||||
"tranche_start": "2021-12-05T00:00:00.000Z",
|
||||
"tranche_end": "2022-06-05T00:00:00.000Z",
|
||||
"total_added": "171288.42",
|
||||
"total_removed": "66601.1049690697989",
|
||||
"total_removed": "66301.1049690697989",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -85675,16 +85463,6 @@
|
||||
"user": "0x217254578EFd323CF93b1E0FC900A2f4C97A2e6e",
|
||||
"tx": "0xbed9954657a0b981080f8b66187ee3ce27ba8b18dc7419f430624cda2d4e435a"
|
||||
},
|
||||
{
|
||||
"amount": "50",
|
||||
"user": "0xa40284F5359954E1a0c024132940375FD480C640",
|
||||
"tx": "0x2d1ecfd5ecefe61fa80d8c7d20b9e4afac178554d364c8796eec0d7fdc8f0942"
|
||||
},
|
||||
{
|
||||
"amount": "250",
|
||||
"user": "0xc0A603F3B555ba1622B80CF54EAFE6fb717f3Cd7",
|
||||
"tx": "0xcb9db64f3df7fb6f1addc0073e2a8a5e285618b07d955d4435ff674327cec8e5"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0x4A13d4dC5e06ACdA81C011D55a7DaAc332bC5Dbf",
|
||||
@@ -95659,17 +95437,10 @@
|
||||
"tx": "0xadc25e73736cd85e84fee16f2d7ee41f16f7deb83a52ceb82b327974063964f7"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "50",
|
||||
"user": "0xa40284F5359954E1a0c024132940375FD480C640",
|
||||
"tranche_id": 6,
|
||||
"tx": "0x2d1ecfd5ecefe61fa80d8c7d20b9e4afac178554d364c8796eec0d7fdc8f0942"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"total_tokens": "50",
|
||||
"withdrawn_tokens": "50",
|
||||
"remaining_tokens": "0"
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "50"
|
||||
},
|
||||
{
|
||||
"address": "0x9603B92De110066121E9D7218482A672bd8afbD9",
|
||||
@@ -100407,17 +100178,10 @@
|
||||
"tx": "0x3a0390dffa4280c286016566b29c62e4cec36c6504f7ac3d1de80d22b2903008"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "250",
|
||||
"user": "0xc0A603F3B555ba1622B80CF54EAFE6fb717f3Cd7",
|
||||
"tranche_id": 6,
|
||||
"tx": "0xcb9db64f3df7fb6f1addc0073e2a8a5e285618b07d955d4435ff674327cec8e5"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"total_tokens": "250",
|
||||
"withdrawn_tokens": "250",
|
||||
"remaining_tokens": "0"
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "250"
|
||||
},
|
||||
{
|
||||
"address": "0xE9e7C70a1e2A5F4A612349871aE18eDCEbB253d9",
|
||||
|
||||
-2
@@ -1,5 +1,4 @@
|
||||
/// <reference types="cypress" />
|
||||
import { associateTokenStartOfTests } from '../../support/governance.functions';
|
||||
|
||||
import {
|
||||
createUpdateNetworkProposalTxBody,
|
||||
@@ -22,7 +21,6 @@ context(
|
||||
before('Connect wallets and set approval', function () {
|
||||
cy.visit('/');
|
||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||
associateTokenStartOfTests();
|
||||
cy.connectVegaWallet();
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(1);
|
||||
@@ -0,0 +1,849 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
const vegaWalletUnstakedBalance =
|
||||
'[data-testid="vega-wallet-balance-unstaked"]';
|
||||
const vegaWalletStakedBalances =
|
||||
'[data-testid="vega-wallet-balance-staked-validators"]';
|
||||
const vegaWalletAssociatedBalance = '[data-testid="currency-value"]';
|
||||
const vegaWalletNameElement = '[data-testid="wallet-name"]';
|
||||
const vegaWallet = '[data-testid="vega-wallet"]';
|
||||
const connectToVegaWalletButton = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||
const dialogCloseButton = '[data-testid="dialog-close"]';
|
||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||
const openProposals = '[data-testid="open-proposals"]';
|
||||
const proposalVoteProgressForPercentage =
|
||||
'[data-testid="vote-progress-indicator-percentage-for"]';
|
||||
const proposalVoteProgressAgainstPercentage =
|
||||
'[data-testid="vote-progress-indicator-percentage-against"]';
|
||||
const proposalVoteProgressForTokens =
|
||||
'[data-testid="vote-progress-indicator-tokens-for"]';
|
||||
const proposalVoteProgressAgainstTokens =
|
||||
'[data-testid="vote-progress-indicator-tokens-against"]';
|
||||
const changeVoteButton = '[data-testid="change-vote-button"]';
|
||||
const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
||||
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
||||
const rawProposalData = '[data-testid="proposal-data"]';
|
||||
const minVoteButton = '[data-testid="min-vote"]';
|
||||
const maxVoteButton = '[data-testid="max-vote"]';
|
||||
const voteButtons = '[data-testid="vote-buttons"]';
|
||||
const votingDate = '[data-testid="voting-date"]';
|
||||
const voteTwoMinExtraNote = '[data-testid="voting-2-mins-extra"]';
|
||||
const voteStatus = '[data-testid="vote-status"]';
|
||||
const rejectProposalsLink = '[href="/proposals/rejected"]';
|
||||
const feedbackError = '[data-testid="Error"]';
|
||||
const noOpenProposals = '[data-testid="no-open-proposals"]';
|
||||
const noClosedProposals = '[data-testid="no-closed-proposals"]';
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
const epochTimeout = Cypress.env('epochTimeout');
|
||||
const proposalTimeout = { timeout: 14000 };
|
||||
|
||||
const minCloseDays = 2;
|
||||
const maxCloseDays = 3;
|
||||
const requiredParticipation = 0.001;
|
||||
|
||||
const governanceProposalType = {
|
||||
NETWORK_PARAMETER: 'Network parameter',
|
||||
NEW_MARKET: 'New market',
|
||||
UPDATE_MARKET: 'Update market',
|
||||
NEW_ASSET: 'New asset',
|
||||
FREEFORM: 'Freeform',
|
||||
RAW: 'raw proposal',
|
||||
};
|
||||
|
||||
context(
|
||||
'Governance flow - with eth and vega wallets connected',
|
||||
{ tags: '@slow' },
|
||||
function () {
|
||||
before('connect wallets and set approval limit', function () {
|
||||
cy.visit('/');
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
cy.wrap(
|
||||
network_parameters['spam.protection.proposal.min.tokens'] /
|
||||
1000000000000000000
|
||||
).as('minProposerBalance');
|
||||
cy.wrap(
|
||||
network_parameters['spam.protection.voting.min.tokens'] /
|
||||
1000000000000000000
|
||||
).as('minVoterBalance');
|
||||
cy.wrap(
|
||||
network_parameters['governance.proposal.freeform.requiredMajority'] *
|
||||
100
|
||||
).as('requiredMajority');
|
||||
cy.wrap(
|
||||
network_parameters['governance.proposal.freeform.minClose'].split(
|
||||
'h'
|
||||
)[0]
|
||||
).as('minCloseHours');
|
||||
cy.wrap(
|
||||
network_parameters['governance.proposal.freeform.maxClose'].split(
|
||||
'h'
|
||||
)[0]
|
||||
).as('maxCloseHours');
|
||||
});
|
||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||
});
|
||||
|
||||
describe('Eth wallet - contains VEGA tokens', function () {
|
||||
before(
|
||||
'checking network parameters (therefore environment) is fit for test',
|
||||
function () {
|
||||
assert.isAtLeast(
|
||||
parseInt(this.minProposerBalance),
|
||||
0.00001,
|
||||
'Asserting that value is at least 0.00001 for network parameter minProposerBalance'
|
||||
);
|
||||
assert.isAtLeast(
|
||||
parseInt(this.minVoterBalance),
|
||||
0.00001,
|
||||
'Asserting that value is at least 0.00001 for network parameter minVoterBalance'
|
||||
);
|
||||
// workaround for first eth tx hanging
|
||||
associateTokenStartOfTests();
|
||||
}
|
||||
);
|
||||
|
||||
beforeEach('visit governance tab', function () {
|
||||
cy.reload();
|
||||
cy.wait_for_spinner();
|
||||
cy.connectVegaWallet();
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.navigate_to('proposals');
|
||||
});
|
||||
|
||||
it('Should be able to see that no proposals exist', function () {
|
||||
// 3001-VOTE-003
|
||||
cy.get(noOpenProposals)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'There are no open or yet to enact proposals');
|
||||
cy.get(noClosedProposals)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'There are no enacted or rejected proposals');
|
||||
});
|
||||
|
||||
// 3002-PROP-002
|
||||
// 3002-PROP-003
|
||||
it('Submit a proposal form - shows how many vega tokens are required to make a proposal', function () {
|
||||
// 3002-PROP-005
|
||||
cy.go_to_make_new_proposal(governanceProposalType.NEW_MARKET);
|
||||
cy.contains(
|
||||
`You must have at least ${this.minProposerBalance} VEGA associated to make a proposal`
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
// 3002-PROP-011
|
||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.get(minVoteButton).should('be.visible'); // 3002-PROP-008
|
||||
cy.get(maxVoteButton).should('be.visible');
|
||||
cy.get(votingDate).should('not.be.empty');
|
||||
cy.get(voteTwoMinExtraNote).should(
|
||||
'contain.text',
|
||||
'we add 2 minutes of extra time'
|
||||
);
|
||||
cy.enter_unique_freeform_proposal_body('50', generateProposalTitle());
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
// 3002-PROP-012
|
||||
// 3002-PROP-016
|
||||
cy.wait_for_proposal_submitted();
|
||||
});
|
||||
|
||||
it('Newly created proposals list - proposals closest to closing date appear higher in list', function () {
|
||||
// 3001-VOTE-005
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
let proposalDays = [
|
||||
minCloseDays + 1,
|
||||
maxCloseDays,
|
||||
minCloseDays + 3,
|
||||
minCloseDays + 2,
|
||||
];
|
||||
for (var index = 0; index < proposalDays.length; index++) {
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days(
|
||||
proposalDays[index]
|
||||
).then((closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp);
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains('Proposal submitted', proposalTimeout).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
cy.wait_for_proposal_sync();
|
||||
}
|
||||
|
||||
let arrayOfProposals = [];
|
||||
|
||||
cy.navigate_to('proposals');
|
||||
cy.get(proposalDetailsTitle)
|
||||
.each((proposalTitleElement) => {
|
||||
arrayOfProposals.push(proposalTitleElement.text());
|
||||
})
|
||||
.then(() => {
|
||||
cy.get_sort_order_of_supplied_array(arrayOfProposals).should(
|
||||
'equal',
|
||||
'descending'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated - but also staked', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated('2');
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', '2');
|
||||
cy.navigate_to('validators');
|
||||
cy.click_on_validator_from_list(0);
|
||||
cy.staking_validator_page_add_stake('2');
|
||||
cy.close_staking_dialog();
|
||||
|
||||
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
||||
|
||||
cy.navigate_to('proposals');
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body('50', generateProposalTitle());
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.wait_for_proposal_submitted();
|
||||
});
|
||||
|
||||
it('Newly created proposals list - able to filter by proposerID to show it in list', function () {
|
||||
const proposerId = Cypress.env('vegaWalletPublicKey');
|
||||
const proposalTitle = generateProposalTitle();
|
||||
|
||||
createFreeformProposal(this.minProposerBalance, proposalTitle);
|
||||
cy.get_proposal_id_from_list(proposalTitle);
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
||||
cy.get('[data-testid="filter-input"]').type(proposerId);
|
||||
cy.get(`#${proposalId}`).should('contain', proposalId);
|
||||
});
|
||||
});
|
||||
|
||||
it('Newly created proposals list - shows title and portion of summary', function () {
|
||||
createRawProposal(this.minProposerBalance); // 3001-VOTE-052
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_proposal_id_from_list(rawProposal.rationale.title);
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get(openProposals).within(() => {
|
||||
// 3001-VOTE-008
|
||||
// 3001-VOTE-034
|
||||
cy.get(`#${proposalId}`)
|
||||
// 3001-VOTE-097
|
||||
.should('contain', rawProposal.rationale.title)
|
||||
.and('be.visible');
|
||||
cy.get(`#${proposalId}`)
|
||||
.should(
|
||||
'contain',
|
||||
rawProposal.rationale.description.substring(0, 59)
|
||||
)
|
||||
.and('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Newly created proposals list - shows open proposals in an open state', function () {
|
||||
// 3001-VOTE-004
|
||||
// 3001-VOTE-035
|
||||
createRawProposal(this.minProposerBalance);
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => {
|
||||
cy.get(viewProposalButton).should('be.visible').click();
|
||||
});
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get_proposal_information_from_table('ID')
|
||||
.contains(proposalId)
|
||||
.and('be.visible');
|
||||
});
|
||||
cy.get_proposal_information_from_table('State')
|
||||
.contains('Open')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Type')
|
||||
.contains('Freeform')
|
||||
.and('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
// 3001-VOTE-071
|
||||
it('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
||||
const proposalTitle = generateProposalTitle();
|
||||
createFreeformProposal(this.minProposerBalance, proposalTitle);
|
||||
|
||||
cy.get_submitted_proposal_from_proposal_list(proposalTitle)
|
||||
.as('submittedProposal')
|
||||
.within(() => {
|
||||
// 3001-VOTE-039
|
||||
cy.get(voteStatus).should('have.text', 'Participation not reached');
|
||||
cy.get(viewProposalButton).click();
|
||||
});
|
||||
cy.vote_for_proposal('for');
|
||||
cy.get_proposal_information_from_table('Total Supply')
|
||||
.invoke('text')
|
||||
.then((totalSupply) => {
|
||||
let tokensRequiredToAchieveResult = parseFloat(
|
||||
(totalSupply.replace(/,/g, '') * requiredParticipation) / 100
|
||||
).toFixed(2);
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
tokensRequiredToAchieveResult
|
||||
);
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
cy.get('@submittedProposal').within(() =>
|
||||
cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.get_proposal_information_from_table('Token participation met')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
cy.navigate_to('proposals');
|
||||
cy.get('@submittedProposal').within(() =>
|
||||
cy.get(voteStatus).should('have.text', 'Set to pass')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// 3001-VOTE-055
|
||||
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
||||
createRawProposal(this.minProposerBalance);
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_proposal_id_from_list(rawProposal.rationale.title);
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get(openProposals).within(() => {
|
||||
cy.get(`#${proposalId}`).within(() => {
|
||||
cy.get(viewProposalButton).should('be.visible').click();
|
||||
});
|
||||
});
|
||||
});
|
||||
cy.get(proposalDetailsTitle)
|
||||
.should('contain', rawProposal.rationale.title)
|
||||
.and('be.visible');
|
||||
cy.get(proposalDetailsDescription)
|
||||
.should('contain', rawProposal.rationale.description)
|
||||
.and('be.visible');
|
||||
});
|
||||
// 3001-VOTE-052
|
||||
cy.get('code.language-json')
|
||||
.should('exist')
|
||||
.within(() => {
|
||||
cy.get('.hljs-string').eq(0).should('have.text', '"ProposalTerms"');
|
||||
});
|
||||
});
|
||||
|
||||
// 3001-VOTE-043
|
||||
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
||||
const closingVoteHrs = '72';
|
||||
const proposalTitle = generateProposalTitle();
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('3').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_unique_freeform_proposal_body(
|
||||
closingVoteHrs,
|
||||
proposalTitle
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.navigate_to('proposals');
|
||||
cy.get_submitted_proposal_from_proposal_list(proposalTitle).within(
|
||||
() => cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.convert_unix_timestamp_to_governance_data_table_date_format(
|
||||
closingDateTimestamp
|
||||
).then((closingDate) => {
|
||||
cy.get_proposal_information_from_table('Closes on')
|
||||
.contains(closingDate)
|
||||
.should('be.visible');
|
||||
});
|
||||
}
|
||||
);
|
||||
cy.get_governance_proposal_date_format_for_specified_days('0').then(
|
||||
(proposalDate) => {
|
||||
cy.get_proposal_information_from_table('Proposed on')
|
||||
.contains(proposalDate)
|
||||
.should('be.visible');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('Newly created proposal details - shows default status set to fail', function () {
|
||||
// 3001-VOTE-037
|
||||
// 3001-VOTE-040
|
||||
// 3001-VOTE-067
|
||||
createRawProposal(this.minProposerBalance);
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.get_proposal_information_from_table('Expected to pass')
|
||||
.contains('👎')
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-062
|
||||
// 3001-VOTE-040
|
||||
// 3001-VOTE-070
|
||||
cy.get_proposal_information_from_table('Token majority met')
|
||||
.contains('👎')
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-068
|
||||
cy.get_proposal_information_from_table('Token participation met')
|
||||
.contains('👎')
|
||||
.should('be.visible');
|
||||
});
|
||||
|
||||
// 3001-VOTE-080 3001-VOTE-090 3001-VOTE-069 3001-VOTE-072 3001-VOTE-073
|
||||
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
||||
createRawProposal(this.minProposerBalance);
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
// 3001-VOTE-080
|
||||
cy.get(voteButtons).contains('against').should('be.visible');
|
||||
cy.get(voteButtons).contains('for').should('be.visible');
|
||||
cy.vote_for_proposal('for');
|
||||
cy.get_governance_proposal_date_format_for_specified_days(
|
||||
'0',
|
||||
'shortMonth'
|
||||
).then((votedDate) => {
|
||||
// 3001-VOTE-051
|
||||
// 3001-VOTE-093
|
||||
cy.contains('You voted:')
|
||||
.siblings()
|
||||
.contains('For')
|
||||
.siblings()
|
||||
.contains(votedDate)
|
||||
.should('be.visible');
|
||||
});
|
||||
cy.get(proposalVoteProgressForPercentage) // 3001-VOTE-072
|
||||
.contains('100.00%')
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstPercentage)
|
||||
.contains('0.00%')
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressForTokens)
|
||||
.contains('1.00')
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstTokens)
|
||||
.contains('0.00')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.should('have.text', parseFloat(this.minProposerBalance).toFixed(2))
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens against proposal')
|
||||
.should('have.text', '0.00')
|
||||
.and('be.visible');
|
||||
// 3001-VOTE-061
|
||||
cy.get_proposal_information_from_table('Participation required')
|
||||
.contains(`${requiredParticipation}%`)
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-066
|
||||
cy.get_proposal_information_from_table('Majority Required') // 3001-VOTE-073
|
||||
.contains(`${parseFloat(this.requiredMajority).toFixed(2)}%`)
|
||||
.should('be.visible');
|
||||
cy.get_proposal_information_from_table('Number of voting parties')
|
||||
.should('have.text', '1')
|
||||
.and('be.visible');
|
||||
cy.get(changeVoteButton).should('be.visible').click();
|
||||
cy.vote_for_proposal('for');
|
||||
// 3001-VOTE-064
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.should('have.text', parseFloat(this.minProposerBalance).toFixed(2))
|
||||
.and('be.visible');
|
||||
cy.get(changeVoteButton).should('be.visible').click();
|
||||
cy.vote_for_proposal('against');
|
||||
cy.get(proposalVoteProgressAgainstPercentage)
|
||||
.contains('100.00%')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens against proposal')
|
||||
.should('have.text', parseFloat(this.minProposerBalance).toFixed(2))
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Number of voting parties')
|
||||
.should('have.text', '1')
|
||||
.and('be.visible');
|
||||
});
|
||||
|
||||
// 3001-VOTE-042, 3001-VOTE-057, 3001-VOTE-058, 3001-VOTE-059, 3001-VOTE-060
|
||||
it('Newly created proposal details - ability to increase associated tokens - by voting again after association', function () {
|
||||
createRawProposal(this.minProposerBalance);
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
)
|
||||
.as('submittedProposal')
|
||||
.within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
cy.vote_for_proposal('for');
|
||||
// 3001-VOTE-079
|
||||
cy.contains('You voted: For').should('be.visible');
|
||||
cy.get(proposalVoteProgressForTokens).contains('1').and('be.visible');
|
||||
cy.get_proposal_information_from_table('Total Supply')
|
||||
.invoke('text')
|
||||
.then((totalSupply) => {
|
||||
let tokensRequiredToAchieveResult = parseFloat(
|
||||
(totalSupply.replace(/,/g, '') * requiredParticipation) / 100
|
||||
).toFixed(2);
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
tokensRequiredToAchieveResult
|
||||
);
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
cy.get('@submittedProposal').within(() =>
|
||||
cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.get(proposalVoteProgressForPercentage)
|
||||
.contains('100.00%')
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstPercentage)
|
||||
.contains('0.00%')
|
||||
.and('be.visible');
|
||||
// 3001-VOTE-065
|
||||
cy.get(changeVoteButton).should('be.visible').click();
|
||||
cy.vote_for_proposal('for');
|
||||
cy.get(proposalVoteProgressForTokens)
|
||||
.contains(tokensRequiredToAchieveResult)
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstTokens)
|
||||
.contains('0.00')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table(
|
||||
'Total tokens voted percentage'
|
||||
)
|
||||
.should('have.text', '0.00%')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.should('have.text', tokensRequiredToAchieveResult)
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens against proposal')
|
||||
.should('have.text', '0.00')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Number of voting parties')
|
||||
.should('have.text', '1')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Expected to pass')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-062
|
||||
cy.get_proposal_information_from_table('Token majority met')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
cy.get_proposal_information_from_table('Token participation met')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.contains(tokensRequiredToAchieveResult)
|
||||
.and('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('Creating a proposal - proposal rejected - when closing time sooner than system default', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body('40', generateProposalTitle());
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
|
||||
it('Creating a proposal - proposal rejected - when closing time later than system default', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body(
|
||||
'100000',
|
||||
generateProposalTitle()
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
|
||||
// 3001-VOTE-006
|
||||
it('Creating a proposal - proposal rejected - able to access rejected proposals', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('1000').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp).as('rawProposal');
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||
cy.get(dialogCloseButton).click();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.navigate_to('proposals');
|
||||
cy.get(rejectProposalsLink).click();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => {
|
||||
cy.contains('Rejected').should('be.visible');
|
||||
cy.contains('Close time too late').should('be.visible');
|
||||
cy.get(viewProposalButton).click();
|
||||
});
|
||||
});
|
||||
cy.get_proposal_information_from_table('State')
|
||||
.contains('Rejected')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Rejection reason')
|
||||
.contains('PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Error details')
|
||||
.contains('proposal closing time too late')
|
||||
.and('be.visible');
|
||||
});
|
||||
|
||||
// 0005-ETXN-004
|
||||
it('Unable to create a proposal - when no tokens are associated', function () {
|
||||
cy.vega_wallet_teardown();
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||
'0.00',
|
||||
txTimeout
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp).as;
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Network error: the network blocked the transaction through the spam protection'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
// 3002-PROP-009
|
||||
it('Unable to create a proposal - when some but not enough tokens are associated', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance - 0.000001
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp);
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Network error: the network blocked the transaction through the spam protection'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
it('Unable to create a freeform proposal - when json parent section contains unexpected field', function () {
|
||||
// 3001-VOTE-038 3002-PROP-013 3002-PROP-014
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.fixture('/proposals/raw.json').then((freeformProposal) => {
|
||||
freeformProposal.terms.closingTimestamp = closingDateTimestamp;
|
||||
freeformProposal.unexpected = `i shouldn't be here`;
|
||||
let proposalPayload = JSON.stringify(freeformProposal);
|
||||
cy.get(rawProposalData).type(proposalPayload, {
|
||||
parseSpecialCharSequences: false,
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Invalid params: the transaction is malformed'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
cy.get(rawProposalData)
|
||||
.invoke('val')
|
||||
.should('contain', "i shouldn't be here");
|
||||
});
|
||||
|
||||
it('Unable to create a freeform proposal - when json terms section contains unexpected field', function () {
|
||||
// 3001-VOTE-038
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.fixture('/proposals/raw.json').then((rawProposal) => {
|
||||
rawProposal.terms.closingTimestamp = closingDateTimestamp;
|
||||
rawProposal.terms.unexpectedField = `i shouldn't be here`;
|
||||
let proposalPayload = JSON.stringify(rawProposal);
|
||||
|
||||
cy.get(rawProposalData).type(proposalPayload, {
|
||||
parseSpecialCharSequences: false,
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Invalid params: the transaction is malformed'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
// 1005-PROP-009
|
||||
it.skip(
|
||||
'Unable to vote on a freeform proposal - when some but not enough vega associated',
|
||||
{ tags: '@smoke' },
|
||||
function () {
|
||||
const proposalTitle = generateProposalTitle();
|
||||
|
||||
cy.vega_wallet_teardown();
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
this.minProposerBalance
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body('50', proposalTitle);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.staking_page_disassociate_tokens('0.0001');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'0.9999'
|
||||
);
|
||||
});
|
||||
cy.navigate_to('proposals');
|
||||
cy.get_submitted_proposal_from_proposal_list(proposalTitle).within(
|
||||
() => cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.contains('Vote breakdown').should('be.visible', {
|
||||
timeout: 10000,
|
||||
});
|
||||
cy.get(voteButtons).should('not.exist');
|
||||
cy.getByTestId('min-proposal-requirements').should(
|
||||
'have.text',
|
||||
`You must have at least ${this.minVoterBalance} VEGA associated to vote on this proposal`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
it('Unable to vote on a proposal - when vega wallet disconnected - option to connect from within', function () {
|
||||
createRawProposal(this.minProposerBalance);
|
||||
cy.get('[data-testid="manage-vega-wallet"]').click();
|
||||
cy.get('[data-testid="disconnect"]').click();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
// 3001-VOTE-075
|
||||
// 3001-VOTE-076
|
||||
cy.get(connectToVegaWalletButton)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Connect Vega wallet')
|
||||
.click();
|
||||
cy.getByTestId('connector-jsonRpc').click();
|
||||
cy.get(vegaWalletNameElement).should('be.visible');
|
||||
cy.get(connectToVegaWalletButton).should('not.exist');
|
||||
// 3001-VOTE-100
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||
'1.00',
|
||||
txTimeout
|
||||
);
|
||||
cy.vote_for_proposal('against');
|
||||
// 3001-VOTE-079
|
||||
cy.contains('You voted: Against').should('be.visible');
|
||||
});
|
||||
|
||||
function createRawProposal(proposerBalance) {
|
||||
if (proposerBalance)
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(proposerBalance);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp).as('rawProposal');
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.navigate_to('proposals');
|
||||
}
|
||||
|
||||
function createFreeformProposal(proposerBalance, proposalTitle) {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(proposerBalance);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body('50', proposalTitle);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.get(proposalDetailsTitle).invoke('text').as('proposalTitle');
|
||||
cy.navigate_to('proposals');
|
||||
}
|
||||
|
||||
function generateProposalTitle() {
|
||||
const randomNum = Math.floor(Math.random() * 1000) + 1;
|
||||
return randomNum + ': Freeform e2e proposal';
|
||||
}
|
||||
|
||||
// This is a workaround function to begin tests with associating tokens without failing
|
||||
// Should be removed when eth transaction bug is fixed
|
||||
function associateTokenStartOfTests() {
|
||||
cy.highlight(`Associating tokens for first time`);
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.connectVegaWallet();
|
||||
cy.get('[href="/token/associate"]').first().click();
|
||||
cy.getByTestId('associate-radio-wallet', { timeout: 30000 }).click();
|
||||
cy.getByTestId('token-amount-input', epochTimeout).type('1');
|
||||
cy.getByTestId('token-input-submit-button', txTimeout)
|
||||
.should('be.enabled')
|
||||
.click();
|
||||
cy.contains(
|
||||
`Associating with Vega key. Waiting for ${Cypress.env(
|
||||
'blockConfirmations'
|
||||
)} more confirmations..`,
|
||||
txTimeout
|
||||
).should('be.visible');
|
||||
cy.getByTestId('associated-amount', txTimeout).should(
|
||||
'contain.text',
|
||||
'1'
|
||||
);
|
||||
// Wait is needed to allow time for transaction to complete
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(10000);
|
||||
cy.vega_wallet_teardown();
|
||||
cy.clearLocalStorage();
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
+1
-1
@@ -54,11 +54,11 @@ context(
|
||||
cy.wait_for_spinner();
|
||||
cy.connectVegaWallet();
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.ensure_specified_unstaked_tokens_are_associated('1');
|
||||
cy.navigate_to('proposals');
|
||||
});
|
||||
|
||||
it('Able to submit valid update network parameter proposal', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated('1');
|
||||
cy.go_to_make_new_proposal(governanceProposalType.NETWORK_PARAMETER);
|
||||
// 3002-PROP-006
|
||||
cy.get(newProposalTitle).type('Test update network parameter proposal');
|
||||
@@ -1,273 +0,0 @@
|
||||
import { associateTokenStartOfTests } from '../../support/common.functions';
|
||||
import {
|
||||
createRawProposal,
|
||||
generateFreeFormProposalTitle,
|
||||
governanceProposalType,
|
||||
} from '../../support/governance.functions';
|
||||
|
||||
const proposalVoteProgressForPercentage =
|
||||
'[data-testid="vote-progress-indicator-percentage-for"]';
|
||||
const proposalVoteProgressAgainstPercentage =
|
||||
'[data-testid="vote-progress-indicator-percentage-against"]';
|
||||
const proposalVoteProgressForTokens =
|
||||
'[data-testid="vote-progress-indicator-tokens-for"]';
|
||||
const proposalVoteProgressAgainstTokens =
|
||||
'[data-testid="vote-progress-indicator-tokens-against"]';
|
||||
const changeVoteButton = '[data-testid="change-vote-button"]';
|
||||
const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
||||
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
||||
const openProposals = '[data-testid="open-proposals"]';
|
||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||
|
||||
describe(
|
||||
'Governance flow for proposal details',
|
||||
{ tags: '@slow' },
|
||||
function () {
|
||||
before('connect wallets and set approval limit', function () {
|
||||
cy.visit('/');
|
||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||
associateTokenStartOfTests();
|
||||
});
|
||||
|
||||
beforeEach('visit proposals tab', function () {
|
||||
cy.reload();
|
||||
cy.wait_for_spinner();
|
||||
cy.connectVegaWallet();
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(1);
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
});
|
||||
|
||||
// 3001-VOTE-055
|
||||
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
||||
createRawProposal();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_proposal_id_from_list(rawProposal.rationale.title);
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get(openProposals).within(() => {
|
||||
cy.get(`#${proposalId}`).within(() => {
|
||||
cy.get(viewProposalButton).should('be.visible').click();
|
||||
});
|
||||
});
|
||||
});
|
||||
cy.get(proposalDetailsTitle)
|
||||
.should('contain', rawProposal.rationale.title)
|
||||
.and('be.visible');
|
||||
cy.get(proposalDetailsDescription)
|
||||
.should('contain', rawProposal.rationale.description)
|
||||
.and('be.visible');
|
||||
});
|
||||
// 3001-VOTE-052
|
||||
cy.get('code.language-json')
|
||||
.should('exist')
|
||||
.within(() => {
|
||||
cy.get('.hljs-string').eq(0).should('have.text', '"ProposalTerms"');
|
||||
});
|
||||
});
|
||||
|
||||
// 3001-VOTE-043
|
||||
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
||||
const closingVoteHrs = '72';
|
||||
const proposalTitle = generateFreeFormProposalTitle();
|
||||
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('3').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_unique_freeform_proposal_body(closingVoteHrs, proposalTitle);
|
||||
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.navigate_to('proposals');
|
||||
cy.get_submitted_proposal_from_proposal_list(proposalTitle).within(
|
||||
() => cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.convert_unix_timestamp_to_governance_data_table_date_format(
|
||||
closingDateTimestamp
|
||||
).then((closingDate) => {
|
||||
cy.get_proposal_information_from_table('Closes on')
|
||||
.contains(closingDate)
|
||||
.should('be.visible');
|
||||
});
|
||||
}
|
||||
);
|
||||
cy.get_governance_proposal_date_format_for_specified_days('0').then(
|
||||
(proposalDate) => {
|
||||
cy.get_proposal_information_from_table('Proposed on')
|
||||
.contains(proposalDate)
|
||||
.should('be.visible');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('Newly created proposal details - shows default status set to fail', function () {
|
||||
// 3001-VOTE-037
|
||||
// 3001-VOTE-040
|
||||
// 3001-VOTE-067
|
||||
createRawProposal();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.get_proposal_information_from_table('Expected to pass')
|
||||
.contains('👎')
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-062
|
||||
// 3001-VOTE-040
|
||||
// 3001-VOTE-070
|
||||
cy.get_proposal_information_from_table('Token majority met')
|
||||
.contains('👎')
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-068
|
||||
cy.get_proposal_information_from_table('Token participation met')
|
||||
.contains('👎')
|
||||
.should('be.visible');
|
||||
});
|
||||
|
||||
// 3001-VOTE-080 3001-VOTE-090 3001-VOTE-069 3001-VOTE-072 3001-VOTE-073
|
||||
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
||||
createRawProposal();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
// 3001-VOTE-080
|
||||
cy.getByTestId('vote-buttons').contains('against').should('be.visible');
|
||||
cy.getByTestId('vote-buttons').contains('for').should('be.visible');
|
||||
cy.vote_for_proposal('for');
|
||||
cy.get_governance_proposal_date_format_for_specified_days(
|
||||
'0',
|
||||
'shortMonth'
|
||||
).then((votedDate) => {
|
||||
// 3001-VOTE-051
|
||||
// 3001-VOTE-093
|
||||
cy.contains('You voted:')
|
||||
.siblings()
|
||||
.contains('For')
|
||||
.siblings()
|
||||
.contains(votedDate)
|
||||
.should('be.visible');
|
||||
});
|
||||
cy.get(proposalVoteProgressForPercentage) // 3001-VOTE-072
|
||||
.contains('100.00%')
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstPercentage)
|
||||
.contains('0.00%')
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressForTokens).contains('1.00').and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstTokens)
|
||||
.contains('0.00')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.should('have.text', parseFloat(1).toFixed(2))
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens against proposal')
|
||||
.should('have.text', '0.00')
|
||||
.and('be.visible');
|
||||
// 3001-VOTE-061
|
||||
cy.get_proposal_information_from_table('Participation required')
|
||||
.contains(0.001)
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-066
|
||||
cy.get_proposal_information_from_table('Majority Required') // 3001-VOTE-073
|
||||
.contains(`${parseFloat(100).toFixed(2)}%`)
|
||||
.should('be.visible');
|
||||
cy.get_proposal_information_from_table('Number of voting parties')
|
||||
.should('have.text', '1')
|
||||
.and('be.visible');
|
||||
cy.get(changeVoteButton).should('be.visible').click();
|
||||
cy.vote_for_proposal('for');
|
||||
// 3001-VOTE-064
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.should('have.text', parseFloat(1).toFixed(2))
|
||||
.and('be.visible');
|
||||
cy.get(changeVoteButton).should('be.visible').click();
|
||||
cy.vote_for_proposal('against');
|
||||
cy.get(proposalVoteProgressAgainstPercentage)
|
||||
.contains('100.00%')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens against proposal')
|
||||
.should('have.text', parseFloat(1).toFixed(2))
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Number of voting parties')
|
||||
.should('have.text', '1')
|
||||
.and('be.visible');
|
||||
});
|
||||
|
||||
// 3001-VOTE-042, 3001-VOTE-057, 3001-VOTE-058, 3001-VOTE-059, 3001-VOTE-060
|
||||
it('Newly created proposal details - ability to increase associated tokens - by voting again after association', function () {
|
||||
createRawProposal();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
)
|
||||
.as('submittedProposal')
|
||||
.within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
cy.vote_for_proposal('for');
|
||||
// 3001-VOTE-079
|
||||
cy.contains('You voted: For').should('be.visible');
|
||||
cy.get(proposalVoteProgressForTokens).contains('1').and('be.visible');
|
||||
cy.get_proposal_information_from_table('Total Supply')
|
||||
.invoke('text')
|
||||
.then((totalSupply) => {
|
||||
let tokensRequiredToAchieveResult = parseFloat(
|
||||
(totalSupply.replace(/,/g, '') * 0.001) / 100
|
||||
).toFixed(2);
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
tokensRequiredToAchieveResult
|
||||
);
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
cy.get('@submittedProposal').within(() =>
|
||||
cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.get(proposalVoteProgressForPercentage)
|
||||
.contains('100.00%')
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstPercentage)
|
||||
.contains('0.00%')
|
||||
.and('be.visible');
|
||||
// 3001-VOTE-065
|
||||
cy.get(changeVoteButton).should('be.visible').click();
|
||||
cy.vote_for_proposal('for');
|
||||
cy.get(proposalVoteProgressForTokens)
|
||||
.contains(tokensRequiredToAchieveResult)
|
||||
.and('be.visible');
|
||||
cy.get(proposalVoteProgressAgainstTokens)
|
||||
.contains('0.00')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table(
|
||||
'Total tokens voted percentage'
|
||||
)
|
||||
.should('have.text', '0.00%')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.should('have.text', tokensRequiredToAchieveResult)
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens against proposal')
|
||||
.should('have.text', '0.00')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Number of voting parties')
|
||||
.should('have.text', '1')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Expected to pass')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
// 3001-VOTE-062
|
||||
cy.get_proposal_information_from_table('Token majority met')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
cy.get_proposal_information_from_table('Token participation met')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||
.contains(tokensRequiredToAchieveResult)
|
||||
.and('be.visible');
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -1,347 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
import {
|
||||
createRawProposal,
|
||||
generateFreeFormProposalTitle,
|
||||
governanceProposalType,
|
||||
} from '../../support/governance.functions';
|
||||
|
||||
import { associateTokenStartOfTests } from '../../support/common.functions';
|
||||
|
||||
const vegaWalletUnstakedBalance =
|
||||
'[data-testid="vega-wallet-balance-unstaked"]';
|
||||
const vegaWalletStakedBalances =
|
||||
'[data-testid="vega-wallet-balance-staked-validators"]';
|
||||
const vegaWalletAssociatedBalance = '[data-testid="currency-value"]';
|
||||
const vegaWalletNameElement = '[data-testid="wallet-name"]';
|
||||
const vegaWallet = '[data-testid="vega-wallet"]';
|
||||
const connectToVegaWalletButton = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||
const dialogCloseButton = '[data-testid="dialog-close"]';
|
||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||
const rawProposalData = '[data-testid="proposal-data"]';
|
||||
const minVoteButton = '[data-testid="min-vote"]';
|
||||
const maxVoteButton = '[data-testid="max-vote"]';
|
||||
const voteButtons = '[data-testid="vote-buttons"]';
|
||||
const votingDate = '[data-testid="voting-date"]';
|
||||
const voteTwoMinExtraNote = '[data-testid="voting-2-mins-extra"]';
|
||||
const rejectProposalsLink = '[href="/proposals/rejected"]';
|
||||
const feedbackError = '[data-testid="Error"]';
|
||||
const noOpenProposals = '[data-testid="no-open-proposals"]';
|
||||
const noClosedProposals = '[data-testid="no-closed-proposals"]';
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
const epochTimeout = Cypress.env('epochTimeout');
|
||||
const proposalTimeout = { timeout: 14000 };
|
||||
|
||||
context(
|
||||
'Governance flow - with eth and vega wallets connected',
|
||||
{ tags: '@slow' },
|
||||
function () {
|
||||
before('connect wallets and set approval limit', function () {
|
||||
cy.visit('/');
|
||||
cy.get_network_parameters().then((network_parameters) => {
|
||||
cy.wrap(
|
||||
network_parameters['spam.protection.proposal.min.tokens'] /
|
||||
1000000000000000000
|
||||
).as('minProposerBalance');
|
||||
cy.wrap(
|
||||
network_parameters['spam.protection.voting.min.tokens'] /
|
||||
1000000000000000000
|
||||
).as('minVoterBalance');
|
||||
cy.wrap(
|
||||
network_parameters['governance.proposal.freeform.requiredMajority'] *
|
||||
100
|
||||
).as('requiredMajority');
|
||||
});
|
||||
|
||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||
associateTokenStartOfTests();
|
||||
});
|
||||
|
||||
beforeEach('visit governance tab', function () {
|
||||
cy.reload();
|
||||
cy.wait_for_spinner();
|
||||
cy.connectVegaWallet();
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(1);
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
});
|
||||
|
||||
it('Should be able to see that no proposals exist', function () {
|
||||
// 3001-VOTE-003
|
||||
cy.get(noOpenProposals)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'There are no open or yet to enact proposals');
|
||||
cy.get(noClosedProposals)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'There are no enacted or rejected proposals');
|
||||
});
|
||||
|
||||
// 3002-PROP-002
|
||||
// 3002-PROP-003
|
||||
it('Submit a proposal form - shows how many vega tokens are required to make a proposal', function () {
|
||||
// 3002-PROP-005
|
||||
cy.go_to_make_new_proposal(governanceProposalType.NEW_MARKET);
|
||||
cy.contains(
|
||||
`You must have at least 1 VEGA associated to make a proposal`
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
// 3002-PROP-011
|
||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.get(minVoteButton).should('be.visible'); // 3002-PROP-008
|
||||
cy.get(maxVoteButton).should('be.visible');
|
||||
cy.get(votingDate).should('not.be.empty');
|
||||
cy.get(voteTwoMinExtraNote).should(
|
||||
'contain.text',
|
||||
'we add 2 minutes of extra time'
|
||||
);
|
||||
cy.enter_unique_freeform_proposal_body(
|
||||
'50',
|
||||
generateFreeFormProposalTitle()
|
||||
);
|
||||
// 3002-PROP-012
|
||||
// 3002-PROP-016
|
||||
cy.wait_for_proposal_submitted();
|
||||
});
|
||||
|
||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated - but also staked', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated('2');
|
||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', '2');
|
||||
cy.navigate_to('validators');
|
||||
cy.click_on_validator_from_list(0);
|
||||
cy.staking_validator_page_add_stake('2');
|
||||
cy.close_staking_dialog();
|
||||
|
||||
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
||||
|
||||
cy.navigate_to('proposals');
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body(
|
||||
'50',
|
||||
generateFreeFormProposalTitle()
|
||||
);
|
||||
cy.wait_for_proposal_submitted();
|
||||
});
|
||||
|
||||
it('Creating a proposal - proposal rejected - when closing time sooner than system default', function () {
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body(
|
||||
'0.1',
|
||||
generateFreeFormProposalTitle()
|
||||
);
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
cy.get('input:invalid')
|
||||
.invoke('prop', 'validationMessage')
|
||||
.should('equal', 'Value must be greater than or equal to 1.');
|
||||
});
|
||||
|
||||
it('Creating a proposal - proposal rejected - when closing time later than system default', function () {
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body(
|
||||
'100000',
|
||||
generateFreeFormProposalTitle()
|
||||
);
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
cy.get('input:invalid')
|
||||
.invoke('prop', 'validationMessage')
|
||||
.should('equal', 'Value must be less than or equal to 8760.');
|
||||
});
|
||||
|
||||
// 3001-VOTE-006
|
||||
it('Creating a proposal - proposal rejected - able to access rejected proposals', function () {
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('1000').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp).as('rawProposal');
|
||||
}
|
||||
);
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||
cy.get(dialogCloseButton).click();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.navigate_to('proposals');
|
||||
cy.get(rejectProposalsLink).click();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => {
|
||||
cy.contains('Rejected').should('be.visible');
|
||||
cy.contains('Close time too late').should('be.visible');
|
||||
cy.get(viewProposalButton).click();
|
||||
});
|
||||
});
|
||||
cy.get_proposal_information_from_table('State')
|
||||
.contains('Rejected')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Rejection reason')
|
||||
.contains('PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Error details')
|
||||
.contains('proposal closing time too late')
|
||||
.and('be.visible');
|
||||
});
|
||||
|
||||
// 0005-ETXN-004
|
||||
it('Unable to create a proposal - when no tokens are associated', function () {
|
||||
cy.vega_wallet_teardown();
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||
'0.00',
|
||||
txTimeout
|
||||
);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp).as;
|
||||
}
|
||||
);
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Network error: the network blocked the transaction through the spam protection'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
// 3002-PROP-009
|
||||
it('Unable to create a proposal - when some but not enough tokens are associated', function () {
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(0.000001);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp);
|
||||
}
|
||||
);
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Network error: the network blocked the transaction through the spam protection'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
it('Unable to create a freeform proposal - when json parent section contains unexpected field', function () {
|
||||
// 3001-VOTE-038 3002-PROP-013 3002-PROP-014
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.fixture('/proposals/raw.json').then((freeformProposal) => {
|
||||
freeformProposal.terms.closingTimestamp = closingDateTimestamp;
|
||||
freeformProposal.unexpected = `i shouldn't be here`;
|
||||
let proposalPayload = JSON.stringify(freeformProposal);
|
||||
cy.get(rawProposalData).type(proposalPayload, {
|
||||
parseSpecialCharSequences: false,
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Invalid params: the transaction is malformed'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
cy.get(rawProposalData)
|
||||
.invoke('val')
|
||||
.should('contain', "i shouldn't be here");
|
||||
});
|
||||
|
||||
it('Unable to create a freeform proposal - when json terms section contains unexpected field', function () {
|
||||
// 3001-VOTE-038
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.fixture('/proposals/raw.json').then((rawProposal) => {
|
||||
rawProposal.terms.closingTimestamp = closingDateTimestamp;
|
||||
rawProposal.terms.unexpectedField = `i shouldn't be here`;
|
||||
let proposalPayload = JSON.stringify(rawProposal);
|
||||
|
||||
cy.get(rawProposalData).type(proposalPayload, {
|
||||
parseSpecialCharSequences: false,
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
'Invalid params: the transaction is malformed'
|
||||
);
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
// 1005-PROP-009
|
||||
it.skip(
|
||||
'Unable to vote on a freeform proposal - when some but not enough vega associated',
|
||||
{ tags: '@smoke' },
|
||||
function () {
|
||||
const proposalTitle = generateFreeFormProposalTitle();
|
||||
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(1);
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body('50', proposalTitle);
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.staking_page_disassociate_tokens('0.0001');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance).should('have.length', 1);
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'0.9999'
|
||||
);
|
||||
});
|
||||
cy.navigate_to('proposals');
|
||||
cy.get_submitted_proposal_from_proposal_list(proposalTitle).within(() =>
|
||||
cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.contains('Vote breakdown').should('be.visible', {
|
||||
timeout: 10000,
|
||||
});
|
||||
cy.get(voteButtons).should('not.exist');
|
||||
cy.getByTestId('min-proposal-requirements').should(
|
||||
'have.text',
|
||||
`You must have at least ${this.minVoterBalance} VEGA associated to vote on this proposal`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
it('Unable to vote on a proposal - when vega wallet disconnected - option to connect from within', function () {
|
||||
createRawProposal();
|
||||
cy.get('[data-testid="manage-vega-wallet"]').click();
|
||||
cy.get('[data-testid="disconnect"]').click();
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
// 3001-VOTE-075
|
||||
// 3001-VOTE-076
|
||||
cy.get(connectToVegaWalletButton)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Connect Vega wallet')
|
||||
.click();
|
||||
cy.getByTestId('connector-jsonRpc').click();
|
||||
cy.get(vegaWalletNameElement).should('be.visible');
|
||||
cy.get(connectToVegaWalletButton).should('not.exist');
|
||||
// 3001-VOTE-100
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).contains(
|
||||
'1.00',
|
||||
txTimeout
|
||||
);
|
||||
cy.vote_for_proposal('against');
|
||||
// 3001-VOTE-079
|
||||
cy.contains('You voted: Against').should('be.visible');
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -1,162 +0,0 @@
|
||||
import {
|
||||
createFreeformProposal,
|
||||
createRawProposal,
|
||||
generateFreeFormProposalTitle,
|
||||
governanceProposalType,
|
||||
} from '../../support/governance.functions';
|
||||
|
||||
const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
||||
const openProposals = '[data-testid="open-proposals"]';
|
||||
const voteStatus = '[data-testid="vote-status"]';
|
||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||
|
||||
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||
before('connect wallets and set approval limit', function () {
|
||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
beforeEach('visit proposals tab', function () {
|
||||
cy.reload();
|
||||
cy.wait_for_spinner();
|
||||
cy.connectVegaWallet();
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(1);
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
});
|
||||
|
||||
it('Newly created proposals list - proposals closest to closing date appear higher in list', function () {
|
||||
const minCloseDays = 2;
|
||||
const maxCloseDays = 3;
|
||||
|
||||
// 3001-VOTE-005
|
||||
let proposalDays = [
|
||||
minCloseDays + 1,
|
||||
maxCloseDays,
|
||||
minCloseDays + 3,
|
||||
minCloseDays + 2,
|
||||
];
|
||||
for (var index = 0; index < proposalDays.length; index++) {
|
||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days(
|
||||
proposalDays[index]
|
||||
).then((closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp);
|
||||
});
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.wait_for_proposal_sync();
|
||||
}
|
||||
|
||||
let arrayOfProposals = [];
|
||||
|
||||
cy.navigate_to('proposals');
|
||||
cy.get(proposalDetailsTitle)
|
||||
.each((proposalTitleElement) => {
|
||||
arrayOfProposals.push(proposalTitleElement.text());
|
||||
})
|
||||
.then(() => {
|
||||
cy.get_sort_order_of_supplied_array(arrayOfProposals).should(
|
||||
'equal',
|
||||
'descending'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Newly created proposals list - able to filter by proposerID to show it in list', function () {
|
||||
const proposerId = Cypress.env('vegaWalletPublicKey');
|
||||
const proposalTitle = generateFreeFormProposalTitle();
|
||||
|
||||
createFreeformProposal(proposalTitle);
|
||||
cy.get_proposal_id_from_list(proposalTitle);
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
||||
cy.get('[data-testid="filter-input"]').type(proposerId);
|
||||
cy.get(`#${proposalId}`).should('contain', proposalId);
|
||||
});
|
||||
});
|
||||
|
||||
it('Newly created proposals list - shows title and portion of summary', function () {
|
||||
createRawProposal(this.minProposerBalance); // 3001-VOTE-052
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_proposal_id_from_list(rawProposal.rationale.title);
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get(openProposals).within(() => {
|
||||
// 3001-VOTE-008
|
||||
// 3001-VOTE-034
|
||||
cy.get(`#${proposalId}`)
|
||||
// 3001-VOTE-097
|
||||
.should('contain', rawProposal.rationale.title)
|
||||
.and('be.visible');
|
||||
cy.get(`#${proposalId}`)
|
||||
.should(
|
||||
'contain',
|
||||
rawProposal.rationale.description.substring(0, 59)
|
||||
)
|
||||
.and('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Newly created proposals list - shows open proposals in an open state', function () {
|
||||
// 3001-VOTE-004
|
||||
// 3001-VOTE-035
|
||||
createRawProposal(this.minProposerBalance);
|
||||
cy.get('@rawProposal').then((rawProposal) => {
|
||||
cy.get_submitted_proposal_from_proposal_list(
|
||||
rawProposal.rationale.title
|
||||
).within(() => {
|
||||
cy.get(viewProposalButton).should('be.visible').click();
|
||||
});
|
||||
cy.get('@proposalIdText').then((proposalId) => {
|
||||
cy.get_proposal_information_from_table('ID')
|
||||
.contains(proposalId)
|
||||
.and('be.visible');
|
||||
});
|
||||
cy.get_proposal_information_from_table('State')
|
||||
.contains('Open')
|
||||
.and('be.visible');
|
||||
cy.get_proposal_information_from_table('Type')
|
||||
.contains('Freeform')
|
||||
.and('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
// 3001-VOTE-071
|
||||
it('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
||||
const proposalTitle = generateFreeFormProposalTitle();
|
||||
const requiredParticipation = 0.001;
|
||||
|
||||
createFreeformProposal(proposalTitle);
|
||||
|
||||
cy.get_submitted_proposal_from_proposal_list(proposalTitle)
|
||||
.as('submittedProposal')
|
||||
.within(() => {
|
||||
// 3001-VOTE-039
|
||||
cy.get(voteStatus).should('have.text', 'Participation not reached');
|
||||
cy.get(viewProposalButton).click();
|
||||
});
|
||||
cy.vote_for_proposal('for');
|
||||
cy.get_proposal_information_from_table('Total Supply')
|
||||
.invoke('text')
|
||||
.then((totalSupply) => {
|
||||
let tokensRequiredToAchieveResult = parseFloat(
|
||||
(totalSupply.replace(/,/g, '') * requiredParticipation) / 100
|
||||
).toFixed(2);
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||
tokensRequiredToAchieveResult
|
||||
);
|
||||
cy.navigate_to_page_if_not_already_loaded('proposals');
|
||||
cy.get('@submittedProposal').within(() =>
|
||||
cy.get(viewProposalButton).click()
|
||||
);
|
||||
cy.get_proposal_information_from_table('Token participation met')
|
||||
.contains('👍')
|
||||
.should('be.visible');
|
||||
cy.navigate_to('proposals');
|
||||
cy.get('@submittedProposal').within(() =>
|
||||
cy.get(voteStatus).should('have.text', 'Set to pass')
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -63,39 +63,6 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
|
||||
.and('have.text', 'Browse, vote, and propose');
|
||||
});
|
||||
});
|
||||
it('should show open or enacted proposals with proposal summary', function () {
|
||||
cy.get('body').then(($body) => {
|
||||
if (!$body.find('[data-testid="proposals-list-item"]').length) {
|
||||
cy.createMarket();
|
||||
cy.reload();
|
||||
cy.wait_for_spinner();
|
||||
}
|
||||
});
|
||||
cy.getByTestId('proposals-list-item')
|
||||
.should('have.length.at.least', 1)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.getByTestId('proposal-title')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('proposal-type')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('proposal-description')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('proposal-details')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('proposal-status')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('vote-details')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('view-proposal-btn').should('be.visible');
|
||||
});
|
||||
});
|
||||
it('should have external link for governance', function () {
|
||||
cy.getByTestId('home-proposals').within(() => {
|
||||
cy.getByTestId('external-link')
|
||||
|
||||
@@ -38,6 +38,7 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
|
||||
cy.navigate_to('proposals');
|
||||
cy.go_to_make_new_proposal('Freeform');
|
||||
cy.enter_unique_freeform_proposal_body('50', 'pub key proposal test');
|
||||
cy.getByTestId('proposal-submit').should('be.visible').click();
|
||||
cy.getByTestId('dialog-content').within(() => {
|
||||
cy.get('h1').should('have.text', 'Transaction failed');
|
||||
cy.getByTestId('Error').should('have.text', expectedErrorTxt);
|
||||
|
||||
+2
-2
@@ -30,11 +30,11 @@ context('Staking Page - verify elements on page', function () {
|
||||
|
||||
describe('with wallets disconnected', { tags: '@smoke' }, function () {
|
||||
describe('description section', function () {
|
||||
it('Should have validators tab highlighted', function () {
|
||||
it('Should have staking tab highlighted', function () {
|
||||
cy.verify_tab_highlighted('validators');
|
||||
});
|
||||
|
||||
it('Should have validators ON VEGA header visible', function () {
|
||||
it('Should have STAKING ON VEGA header visible', function () {
|
||||
cy.verify_page_header('Validators');
|
||||
});
|
||||
|
||||
@@ -338,8 +338,8 @@ context(
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
.within(() => cy.contains_exactly('10.00').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
const epochTimeout = Cypress.env('epochTimeout');
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
|
||||
Cypress.Commands.add(
|
||||
'convert_token_value_to_number',
|
||||
{ prevSubject: true },
|
||||
@@ -52,29 +49,3 @@ Cypress.Commands.add('wait_for_spinner', () => {
|
||||
cy.get(navigation.pageSpinner, Cypress.env('epochTimeout')).should('exist');
|
||||
cy.get(navigation.pageSpinner, { timeout: 20000 }).should('not.exist');
|
||||
});
|
||||
|
||||
// This is a workaround function to begin tests with associating tokens without failing
|
||||
// Should be removed when eth transaction bug is fixed
|
||||
export function associateTokenStartOfTests() {
|
||||
cy.highlight(`Associating tokens for first time`);
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.connectVegaWallet();
|
||||
cy.get('[href="/token/associate"]').first().click();
|
||||
cy.getByTestId('associate-radio-wallet', { timeout: 30000 }).click();
|
||||
cy.getByTestId('token-amount-input', epochTimeout).type('1');
|
||||
cy.getByTestId('token-input-submit-button', txTimeout)
|
||||
.should('be.enabled')
|
||||
.click();
|
||||
cy.contains(
|
||||
`Associating with Vega key. Waiting for ${Cypress.env(
|
||||
'blockConfirmations'
|
||||
)} more confirmations..`,
|
||||
txTimeout
|
||||
).should('be.visible');
|
||||
cy.getByTestId('associated-amount', txTimeout).should('contain.text', '1');
|
||||
// Wait is needed to allow time for transaction to complete
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(10000);
|
||||
cy.vega_wallet_teardown();
|
||||
cy.clearLocalStorage();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ const rawProposalData = '[data-testid="proposal-data"]';
|
||||
const voteButtons = '[data-testid="vote-buttons"]';
|
||||
const dialogTitle = '[data-testid="dialog-title"]';
|
||||
const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]';
|
||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||
const dialogCloseButton = '[data-testid="dialog-close"]';
|
||||
const epochTimeout = Cypress.env('epochTimeout');
|
||||
const proposalTimeout = { timeout: 14000 };
|
||||
@@ -62,7 +61,6 @@ Cypress.Commands.add('enter_raw_proposal_body', (timestamp) => {
|
||||
parseSpecialCharSequences: false,
|
||||
delay: 2,
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.wrap(rawProposal);
|
||||
});
|
||||
});
|
||||
@@ -75,7 +73,6 @@ Cypress.Commands.add(
|
||||
'this is a e2e freeform proposal description'
|
||||
);
|
||||
cy.get(proposalVoteDeadline).clear().click().type(timestamp);
|
||||
cy.getByTestId('proposal-submit').should('be.visible').click();
|
||||
}
|
||||
);
|
||||
|
||||
@@ -188,40 +185,3 @@ Cypress.Commands.add('wait_for_proposal_submitted', () => {
|
||||
cy.contains('Proposal submitted', proposalTimeout).should('be.visible');
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
export function createRawProposal(proposerBalance) {
|
||||
if (proposerBalance)
|
||||
cy.ensure_specified_unstaked_tokens_are_associated(proposerBalance);
|
||||
cy.go_to_make_new_proposal('raw proposal');
|
||||
cy.create_ten_digit_unix_timestamp_for_specified_days('8').then(
|
||||
(closingDateTimestamp) => {
|
||||
cy.enter_raw_proposal_body(closingDateTimestamp).as('rawProposal');
|
||||
}
|
||||
);
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.navigate_to('proposals');
|
||||
}
|
||||
|
||||
export function generateFreeFormProposalTitle() {
|
||||
const randomNum = Math.floor(Math.random() * 1000) + 1;
|
||||
return randomNum + ': Freeform e2e proposal';
|
||||
}
|
||||
|
||||
export function createFreeformProposal(proposalTitle) {
|
||||
cy.go_to_make_new_proposal(governanceProposalType.FREEFORM);
|
||||
cy.enter_unique_freeform_proposal_body('50', proposalTitle);
|
||||
cy.wait_for_proposal_submitted();
|
||||
cy.wait_for_proposal_sync();
|
||||
cy.getByTestId('proposal-title').invoke('text').as('proposalTitle');
|
||||
cy.navigate_to('proposals');
|
||||
}
|
||||
|
||||
export const governanceProposalType = {
|
||||
NETWORK_PARAMETER: 'Network parameter',
|
||||
NEW_MARKET: 'New market',
|
||||
UPDATE_MARKET: 'Update market',
|
||||
NEW_ASSET: 'New asset',
|
||||
FREEFORM: 'Freeform',
|
||||
RAW: 'raw proposal',
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ export const NavDropDown = ({ navbarTheme }: { navbarTheme: NavbarTheme }) => {
|
||||
<AppNavLink
|
||||
name={
|
||||
<NavDropdownMenuTrigger
|
||||
className="w-auto flex items-center -m-3 p-3 cursor-pointer"
|
||||
className="w-auto flex items-center"
|
||||
data-testid="state-trigger"
|
||||
onClick={() => setOpen(!isOpen)}
|
||||
>
|
||||
|
||||
+89
-111
@@ -50,117 +50,101 @@ export const StandbyPendingValidatorsTable = ({
|
||||
const nodes = useMemo(() => {
|
||||
if (!data) return [];
|
||||
|
||||
return data
|
||||
.sort((a, b) => {
|
||||
const aVotingPower = new BigNumber(a.rankingScore.votingPower);
|
||||
const bVotingPower = new BigNumber(b.rankingScore.votingPower);
|
||||
return bVotingPower.minus(aVotingPower).toNumber();
|
||||
})
|
||||
.map((node, index) => {
|
||||
const votingPowerRanking = index + 1;
|
||||
return data.map(
|
||||
({
|
||||
id,
|
||||
name,
|
||||
avatarUrl,
|
||||
stakedByDelegates,
|
||||
stakedByOperator,
|
||||
stakedTotal,
|
||||
rankingScore: { stakeScore },
|
||||
pendingStake,
|
||||
}) => {
|
||||
const { rawValidatorScore, performanceScore } =
|
||||
getLastEpochScoreAndPerformance(previousEpochData, id);
|
||||
|
||||
const overstakedAmount = getOverstakedAmount(
|
||||
rawValidatorScore,
|
||||
stakedTotal,
|
||||
totalStake
|
||||
);
|
||||
let individualStakeNeededForPromotion,
|
||||
individualStakeNeededForPromotionDescription;
|
||||
|
||||
if (stakeNeededForPromotion && performanceScore) {
|
||||
const stakedTotalBigNum = new BigNumber(stakedTotal);
|
||||
const stakeNeededBigNum = new BigNumber(stakeNeededForPromotion);
|
||||
const performanceScoreBigNum = new BigNumber(performanceScore);
|
||||
|
||||
const calc = stakeNeededBigNum
|
||||
.dividedBy(performanceScoreBigNum)
|
||||
.minus(stakedTotalBigNum);
|
||||
|
||||
if (calc.isGreaterThan(0)) {
|
||||
individualStakeNeededForPromotion = calc.toString();
|
||||
individualStakeNeededForPromotionDescription = t(
|
||||
stakeNeededForPromotionDescription,
|
||||
{
|
||||
prefix: formatNumber(calc, 2).toString(),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
individualStakeNeededForPromotion = '0';
|
||||
individualStakeNeededForPromotionDescription = t(
|
||||
stakeNeededForPromotionDescription,
|
||||
{
|
||||
prefix: formatNumber(0, 2).toString(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...node,
|
||||
votingPowerRanking,
|
||||
};
|
||||
})
|
||||
.map(
|
||||
({
|
||||
id,
|
||||
name,
|
||||
avatarUrl,
|
||||
stakedByDelegates,
|
||||
stakedByOperator,
|
||||
stakedTotal,
|
||||
rankingScore: { stakeScore },
|
||||
pendingStake,
|
||||
votingPowerRanking,
|
||||
}) => {
|
||||
const { rawValidatorScore, performanceScore } =
|
||||
getLastEpochScoreAndPerformance(previousEpochData, id);
|
||||
|
||||
const overstakedAmount = getOverstakedAmount(
|
||||
[ValidatorFields.VALIDATOR]: {
|
||||
avatarUrl,
|
||||
name,
|
||||
},
|
||||
[ValidatorFields.STAKE]: formatNumber(
|
||||
toBigNum(stakedTotal, decimals),
|
||||
2
|
||||
),
|
||||
[ValidatorFields.STAKE_NEEDED_FOR_PROMOTION]:
|
||||
individualStakeNeededForPromotion || null,
|
||||
[ValidatorFields.STAKE_NEEDED_FOR_PROMOTION_DESCRIPTION]:
|
||||
individualStakeNeededForPromotionDescription || t('n/a'),
|
||||
[ValidatorFields.STAKE_SHARE]: stakedTotalPercentage(stakeScore),
|
||||
[ValidatorFields.STAKED_BY_DELEGATES]: formatNumber(
|
||||
toBigNum(stakedByDelegates, decimals),
|
||||
2
|
||||
),
|
||||
[ValidatorFields.STAKED_BY_OPERATOR]: formatNumber(
|
||||
toBigNum(stakedByOperator, decimals),
|
||||
2
|
||||
),
|
||||
[ValidatorFields.PERFORMANCE_SCORE]:
|
||||
getFormattedPerformanceScore(performanceScore).toString(),
|
||||
[ValidatorFields.PERFORMANCE_PENALTY]:
|
||||
getPerformancePenalty(performanceScore),
|
||||
[ValidatorFields.OVERSTAKED_AMOUNT]: overstakedAmount.toString(),
|
||||
[ValidatorFields.OVERSTAKING_PENALTY]: getOverstakingPenalty(
|
||||
overstakedAmount,
|
||||
totalStake
|
||||
),
|
||||
[ValidatorFields.TOTAL_PENALTIES]: getTotalPenalties(
|
||||
rawValidatorScore,
|
||||
performanceScore,
|
||||
stakedTotal,
|
||||
totalStake
|
||||
);
|
||||
let individualStakeNeededForPromotion,
|
||||
individualStakeNeededForPromotionDescription;
|
||||
|
||||
if (stakeNeededForPromotion && performanceScore) {
|
||||
const stakedTotalBigNum = new BigNumber(stakedTotal);
|
||||
const stakeNeededBigNum = new BigNumber(stakeNeededForPromotion);
|
||||
const performanceScoreBigNum = new BigNumber(performanceScore);
|
||||
|
||||
const calc = stakeNeededBigNum
|
||||
.dividedBy(performanceScoreBigNum)
|
||||
.minus(stakedTotalBigNum);
|
||||
|
||||
if (calc.isGreaterThan(0)) {
|
||||
individualStakeNeededForPromotion = calc.toString();
|
||||
individualStakeNeededForPromotionDescription = t(
|
||||
stakeNeededForPromotionDescription,
|
||||
{
|
||||
prefix: formatNumber(calc, 2).toString(),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
individualStakeNeededForPromotion = '0';
|
||||
individualStakeNeededForPromotionDescription = t(
|
||||
stakeNeededForPromotionDescription,
|
||||
{
|
||||
prefix: formatNumber(0, 2).toString(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
|
||||
[ValidatorFields.VALIDATOR]: {
|
||||
avatarUrl,
|
||||
name,
|
||||
},
|
||||
[ValidatorFields.STAKE]: formatNumber(
|
||||
toBigNum(stakedTotal, decimals),
|
||||
2
|
||||
),
|
||||
[ValidatorFields.STAKE_NEEDED_FOR_PROMOTION]:
|
||||
individualStakeNeededForPromotion || null,
|
||||
[ValidatorFields.STAKE_NEEDED_FOR_PROMOTION_DESCRIPTION]:
|
||||
individualStakeNeededForPromotionDescription || t('n/a'),
|
||||
[ValidatorFields.STAKE_SHARE]: stakedTotalPercentage(stakeScore),
|
||||
[ValidatorFields.STAKED_BY_DELEGATES]: formatNumber(
|
||||
toBigNum(stakedByDelegates, decimals),
|
||||
2
|
||||
),
|
||||
[ValidatorFields.STAKED_BY_OPERATOR]: formatNumber(
|
||||
toBigNum(stakedByOperator, decimals),
|
||||
2
|
||||
),
|
||||
[ValidatorFields.PERFORMANCE_SCORE]:
|
||||
getFormattedPerformanceScore(performanceScore).toString(),
|
||||
[ValidatorFields.PERFORMANCE_PENALTY]:
|
||||
getPerformancePenalty(performanceScore),
|
||||
[ValidatorFields.OVERSTAKED_AMOUNT]: overstakedAmount.toString(),
|
||||
[ValidatorFields.OVERSTAKING_PENALTY]: getOverstakingPenalty(
|
||||
overstakedAmount,
|
||||
totalStake
|
||||
),
|
||||
[ValidatorFields.TOTAL_PENALTIES]: getTotalPenalties(
|
||||
rawValidatorScore,
|
||||
performanceScore,
|
||||
stakedTotal,
|
||||
totalStake
|
||||
),
|
||||
[ValidatorFields.PENDING_STAKE]: formatNumber(
|
||||
toBigNum(pendingStake, decimals),
|
||||
2
|
||||
),
|
||||
};
|
||||
}
|
||||
);
|
||||
),
|
||||
[ValidatorFields.PENDING_STAKE]: formatNumber(
|
||||
toBigNum(pendingStake, decimals),
|
||||
2
|
||||
),
|
||||
};
|
||||
}
|
||||
);
|
||||
}, [
|
||||
data,
|
||||
decimals,
|
||||
@@ -174,12 +158,6 @@ export const StandbyPendingValidatorsTable = ({
|
||||
const StandbyPendingTable = forwardRef<AgGridReact>((_, gridRef) => {
|
||||
const colDefs = useMemo<ColDef[]>(
|
||||
() => [
|
||||
{
|
||||
field: ValidatorFields.RANKING_INDEX,
|
||||
headerName: '#',
|
||||
width: 60,
|
||||
pinned: 'left',
|
||||
},
|
||||
{
|
||||
field: ValidatorFields.VALIDATOR,
|
||||
headerName: t(ValidatorFields.VALIDATOR).toString(),
|
||||
|
||||
@@ -59,17 +59,11 @@ export const getOverstakedAmount = (
|
||||
export const getOverstakingPenalty = (
|
||||
overstakedAmount: BigNumber,
|
||||
stakedOnNode: string
|
||||
) => {
|
||||
// avoid division by zero
|
||||
if (new BigNumber(stakedOnNode).isZero() || overstakedAmount.isZero()) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
return formatNumberPercentage(
|
||||
) =>
|
||||
formatNumberPercentage(
|
||||
overstakedAmount.dividedBy(new BigNumber(stakedOnNode)).times(100),
|
||||
2
|
||||
);
|
||||
};
|
||||
|
||||
export const getTotalPenalties = (
|
||||
rawValidatorScore: string | null | undefined,
|
||||
|
||||
@@ -3,8 +3,6 @@ import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import { marketsQuery } from '@vegaprotocol/mock';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const dialogCloseBtn = 'dialog-close';
|
||||
|
||||
describe('markets table', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage().then(() => {
|
||||
@@ -149,7 +147,7 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
});
|
||||
cy.visit('#/markets/market-0');
|
||||
cy.url().should('contain', 'market-0');
|
||||
cy.getByTestId(dialogCloseBtn).click();
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.getByTestId('item-value').contains('Opening auction').realHover();
|
||||
cy.getByTestId('opening-auction-sub-status').should(
|
||||
'contain.text',
|
||||
@@ -173,8 +171,7 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
function openMarketDropDown() {
|
||||
cy.getByTestId(dialogCloseBtn).should('be.visible');
|
||||
cy.getByTestId(dialogCloseBtn).click();
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.getByTestId('popover-trigger').click();
|
||||
cy.contains('Loading market data...').should('not.exist');
|
||||
}
|
||||
|
||||
@@ -96,15 +96,7 @@ export const MarketPage = () => {
|
||||
|
||||
const tradeView = useMemo(() => {
|
||||
if (w > 960) {
|
||||
return (
|
||||
<TradeGrid
|
||||
market={data}
|
||||
onSelect={onSelect}
|
||||
pinnedAsset={
|
||||
data?.tradableInstrument.instrument.product.settlementAsset
|
||||
}
|
||||
/>
|
||||
);
|
||||
return <TradeGrid market={data} onSelect={onSelect} />;
|
||||
}
|
||||
return (
|
||||
<TradePanels
|
||||
|
||||
@@ -28,7 +28,6 @@ import { NO_MARKET } from './constants';
|
||||
import { LiquidityContainer } from '../liquidity/liquidity';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import type { PinnedAsset } from '@vegaprotocol/accounts';
|
||||
|
||||
type MarketDependantView =
|
||||
| typeof CandlesChartContainer
|
||||
@@ -66,17 +65,14 @@ type TradingView = keyof typeof TradingViews;
|
||||
interface TradeGridProps {
|
||||
market: Market | null;
|
||||
onSelect: (marketId: string) => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}
|
||||
|
||||
const MainGrid = ({
|
||||
marketId,
|
||||
onSelect,
|
||||
pinnedAsset,
|
||||
}: {
|
||||
marketId: string;
|
||||
onSelect?: (marketId: string) => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const onMarketClick = (marketId: string) => {
|
||||
@@ -179,7 +175,7 @@ const MainGrid = ({
|
||||
</Tab>
|
||||
<Tab id="accounts" name={t('Collateral')}>
|
||||
<VegaWalletContainer>
|
||||
<TradingViews.Collateral pinnedAsset={pinnedAsset} />
|
||||
<TradingViews.Collateral />
|
||||
</VegaWalletContainer>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -190,19 +186,11 @@ const MainGrid = ({
|
||||
};
|
||||
const MainGridWrapped = memo(MainGrid);
|
||||
|
||||
export const TradeGrid = ({
|
||||
market,
|
||||
onSelect,
|
||||
pinnedAsset,
|
||||
}: TradeGridProps) => {
|
||||
export const TradeGrid = ({ market, onSelect }: TradeGridProps) => {
|
||||
return (
|
||||
<div className="h-full grid grid-rows-[min-content_1fr]">
|
||||
<TradeMarketHeader market={market} onSelect={onSelect} />
|
||||
<MainGridWrapped
|
||||
marketId={market?.id || ''}
|
||||
onSelect={onSelect}
|
||||
pinnedAsset={pinnedAsset}
|
||||
/>
|
||||
<MainGridWrapped marketId={market?.id || ''} onSelect={onSelect} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -226,14 +214,12 @@ interface TradePanelsProps {
|
||||
onSelect: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onClickCollateral: () => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}
|
||||
|
||||
export const TradePanels = ({
|
||||
market,
|
||||
onSelect,
|
||||
onClickCollateral,
|
||||
pinnedAsset,
|
||||
}: TradePanelsProps) => {
|
||||
const [view, setView] = useState<TradingView>('Candles');
|
||||
const renderView = () => {
|
||||
@@ -242,7 +228,6 @@ export const TradePanels = ({
|
||||
onSelect: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onClickCollateral: () => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}>(TradingViews[view]);
|
||||
|
||||
if (!Component) {
|
||||
@@ -256,7 +241,6 @@ export const TradePanels = ({
|
||||
marketId={market?.id}
|
||||
onSelect={onSelect}
|
||||
onClickCollateral={onClickCollateral}
|
||||
pinnedAsset={pinnedAsset}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
|
||||
export const DepositsContainer = () => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { data, loading, error, reload } = useDataProvider({
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: depositsProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
@@ -27,7 +27,6 @@ export const DepositsContainer = () => {
|
||||
error={error}
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
noDataMessage={t('No deposits')}
|
||||
reload={reload}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { VegaWalletContainer } from '../../components/vega-wallet-container';
|
||||
|
||||
export const WithdrawalsContainer = () => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { data, loading, error, reload } = useDataProvider({
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: withdrawalProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey,
|
||||
@@ -33,7 +33,6 @@ export const WithdrawalsContainer = () => {
|
||||
error={error}
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
noDataMessage={t('No withdrawals')}
|
||||
reload={reload}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,15 +5,10 @@ import { useWithdrawalDialog } from '@vegaprotocol/withdraws';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import type { PinnedAsset } from '@vegaprotocol/accounts';
|
||||
import { AccountManager, useTransferDialog } from '@vegaprotocol/accounts';
|
||||
import { useDepositDialog } from '@vegaprotocol/deposits';
|
||||
|
||||
export const AccountsContainer = ({
|
||||
pinnedAsset,
|
||||
}: {
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}) => {
|
||||
export const AccountsContainer = () => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
const openWithdrawalDialog = useWithdrawalDialog((store) => store.open);
|
||||
@@ -44,7 +39,6 @@ export const AccountsContainer = ({
|
||||
onClickWithdraw={openWithdrawalDialog}
|
||||
onClickDeposit={openDepositDialog}
|
||||
isReadOnly={isReadOnly}
|
||||
pinnedAsset={pinnedAsset}
|
||||
/>
|
||||
</div>
|
||||
{!isReadOnly && (
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { AgGridReact } from 'ag-grid-react';
|
||||
import { useRef, useMemo, memo } from 'react';
|
||||
import type { AccountFields } from './accounts-data-provider';
|
||||
import { aggregatedAccountsDataProvider } from './accounts-data-provider';
|
||||
import type { PinnedAsset } from './accounts-table';
|
||||
import { AccountTable } from './accounts-table';
|
||||
|
||||
interface AccountManagerProps {
|
||||
@@ -13,7 +12,6 @@ interface AccountManagerProps {
|
||||
onClickWithdraw?: (assetId?: string) => void;
|
||||
onClickDeposit?: (assetId?: string) => void;
|
||||
isReadOnly: boolean;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}
|
||||
|
||||
export const AccountManager = ({
|
||||
@@ -22,15 +20,11 @@ export const AccountManager = ({
|
||||
onClickDeposit,
|
||||
partyId,
|
||||
isReadOnly,
|
||||
pinnedAsset,
|
||||
}: AccountManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
|
||||
const { data, loading, error, reload } = useDataProvider<
|
||||
AccountFields[],
|
||||
never
|
||||
>({
|
||||
const { data, loading, error } = useDataProvider<AccountFields[], never>({
|
||||
dataProvider: aggregatedAccountsDataProvider,
|
||||
variables,
|
||||
});
|
||||
@@ -38,13 +32,12 @@ export const AccountManager = ({
|
||||
<div className="relative h-full">
|
||||
<AccountTable
|
||||
ref={gridRef}
|
||||
rowData={error ? [] : data}
|
||||
rowData={data}
|
||||
onClickAsset={onClickAsset}
|
||||
onClickDeposit={onClickDeposit}
|
||||
onClickWithdraw={onClickWithdraw}
|
||||
isReadOnly={isReadOnly}
|
||||
noRowsOverlayComponent={() => null}
|
||||
pinnedAsset={pinnedAsset}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
@@ -52,8 +45,7 @@ export const AccountManager = ({
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
error={error}
|
||||
loading={loading}
|
||||
noDataMessage={pinnedAsset ? ' ' : t('No accounts')}
|
||||
reload={reload}
|
||||
noDataMessage={t('No accounts')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -72,74 +72,52 @@ describe('AccountsTable', () => {
|
||||
cells.forEach((cell, i) => {
|
||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||
});
|
||||
const rows = await screen.findAllByRole('row');
|
||||
expect(rows.length).toBe(6);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not add first asset as pinned', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<AccountTable
|
||||
rowData={singleRowData}
|
||||
onClickAsset={() => null}
|
||||
isReadOnly={false}
|
||||
pinnedAsset={{
|
||||
it('should get correct account data', () => {
|
||||
const result = getAccountData([singleRow]);
|
||||
const expected = [
|
||||
{
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
decimals: 5,
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
},
|
||||
available: '0',
|
||||
balance: '0',
|
||||
breakdown: [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
decimals: 5,
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
name: 'tBTC',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const rows = await screen.findAllByRole('row');
|
||||
expect(rows.length).toBe(6);
|
||||
});
|
||||
|
||||
it('should get correct account data', () => {
|
||||
const result = getAccountData([singleRow]);
|
||||
const expected = [
|
||||
{
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
decimals: 5,
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
},
|
||||
available: '0',
|
||||
balance: '0',
|
||||
breakdown: [
|
||||
{
|
||||
__typename: 'AccountBalance',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
decimals: 5,
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
},
|
||||
available: '0',
|
||||
balance: '125600000',
|
||||
deposited: '125600000',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
|
||||
tradableInstrument: {
|
||||
__typename: 'TradableInstrument',
|
||||
instrument: {
|
||||
__typename: 'Instrument',
|
||||
name: 'BTCUSD Monthly (30 Jun 2022)',
|
||||
},
|
||||
},
|
||||
available: '0',
|
||||
balance: '125600000',
|
||||
deposited: '125600000',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
|
||||
tradableInstrument: {
|
||||
__typename: 'TradableInstrument',
|
||||
instrument: {
|
||||
__typename: 'Instrument',
|
||||
name: 'BTCUSD Monthly (30 Jun 2022)',
|
||||
},
|
||||
},
|
||||
type: 'ACCOUNT_TYPE_MARGIN',
|
||||
used: '125600000',
|
||||
},
|
||||
],
|
||||
deposited: '125600000',
|
||||
type: 'ACCOUNT_TYPE_GENERAL',
|
||||
used: '125600000',
|
||||
},
|
||||
];
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
type: 'ACCOUNT_TYPE_MARGIN',
|
||||
used: '125600000',
|
||||
},
|
||||
],
|
||||
deposited: '125600000',
|
||||
type: 'ACCOUNT_TYPE_GENERAL',
|
||||
used: '125600000',
|
||||
},
|
||||
];
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { forwardRef, useMemo, useState } from 'react';
|
||||
import { forwardRef, useState } from 'react';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
isNumeric,
|
||||
@@ -14,8 +14,6 @@ import type { AgGridReact, AgGridReactProps } from 'ag-grid-react';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
|
||||
import BreakdownTable from './breakdown-table';
|
||||
import type { AccountFields } from './accounts-data-provider';
|
||||
import type { Asset } from '@vegaprotocol/types';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
export interface GetRowsParams extends Omit<IGetRowsParams, 'successCallback'> {
|
||||
successCallback(rowsThisBlock: AccountFields[], lastRow?: number): void;
|
||||
@@ -25,8 +23,6 @@ export interface Datasource extends IDatasource {
|
||||
getRows(params: GetRowsParams): void;
|
||||
}
|
||||
|
||||
export type PinnedAsset = Pick<Asset, 'symbol' | 'name' | 'id' | 'decimals'>;
|
||||
|
||||
export interface AccountTableProps extends AgGridReactProps {
|
||||
rowData?: AccountFields[] | null;
|
||||
datasource?: Datasource;
|
||||
@@ -34,33 +30,12 @@ export interface AccountTableProps extends AgGridReactProps {
|
||||
onClickWithdraw?: (assetId: string) => void;
|
||||
onClickDeposit?: (assetId: string) => void;
|
||||
isReadOnly: boolean;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}
|
||||
|
||||
export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
({ onClickAsset, onClickWithdraw, onClickDeposit, ...props }, ref) => {
|
||||
const [openBreakdown, setOpenBreakdown] = useState(false);
|
||||
const [breakdown, setBreakdown] = useState<AccountFields[] | null>(null);
|
||||
const pinnedAssetId = props.pinnedAsset?.id;
|
||||
|
||||
const pinnedAssetRow = useMemo(() => {
|
||||
const currentPinnedAssetRow = props.rowData?.find(
|
||||
(row) => row.asset.id === pinnedAssetId
|
||||
);
|
||||
if (!currentPinnedAssetRow) {
|
||||
if (props.pinnedAsset) {
|
||||
return {
|
||||
asset: props.pinnedAsset,
|
||||
available: '0',
|
||||
used: '0',
|
||||
deposited: '0',
|
||||
balance: '0',
|
||||
};
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}, [pinnedAssetId, props.pinnedAsset, props.rowData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AgGrid
|
||||
@@ -76,7 +51,6 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
sortable: true,
|
||||
}}
|
||||
{...props}
|
||||
pinnedTopRowData={pinnedAssetRow ? [pinnedAssetRow] : undefined}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Asset')}
|
||||
@@ -164,55 +138,37 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
cellRenderer={({
|
||||
data,
|
||||
}: VegaICellRendererParams<AccountFields>) => {
|
||||
if (!data) return null;
|
||||
else {
|
||||
if (
|
||||
data.asset.id === pinnedAssetId &&
|
||||
new BigNumber(data.deposited).isLessThanOrEqualTo(0)
|
||||
) {
|
||||
return (
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit to trade')}
|
||||
</ButtonLink>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="breakdown"
|
||||
onClick={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setBreakdown(data.breakdown || null);
|
||||
}}
|
||||
>
|
||||
{t('Breakdown')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return data ? (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="breakdown"
|
||||
onClick={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setBreakdown(data.breakdown || null);
|
||||
}}
|
||||
>
|
||||
{t('Breakdown')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
) : null;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -25,7 +25,6 @@ export const DealTicketContainer = ({
|
||||
data: marketData,
|
||||
error: marketDataError,
|
||||
loading: marketDataLoading,
|
||||
reload,
|
||||
} = useThrottledDataProvider(
|
||||
{
|
||||
dataProvider: marketDataProvider,
|
||||
@@ -40,7 +39,6 @@ export const DealTicketContainer = ({
|
||||
data={market && marketData}
|
||||
loading={marketLoading || marketDataLoading}
|
||||
error={marketError || marketDataError}
|
||||
reload={reload}
|
||||
>
|
||||
{market && marketData ? (
|
||||
<DealTicket
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FormGroup, Input, InputError } from '@vegaprotocol/ui-toolkit';
|
||||
import { FormGroup, Input, NotificationError } from '@vegaprotocol/ui-toolkit';
|
||||
import { t, toDecimal, validateAmount } from '@vegaprotocol/react-helpers';
|
||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||
|
||||
@@ -20,17 +20,17 @@ export const DealTicketLimitAmount = ({
|
||||
const renderError = () => {
|
||||
if (sizeError) {
|
||||
return (
|
||||
<InputError testId="dealticket-error-message-size-limit">
|
||||
<NotificationError testId="dealticket-error-message-size-limit">
|
||||
{sizeError}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
);
|
||||
}
|
||||
|
||||
if (priceError) {
|
||||
return (
|
||||
<InputError testId="dealticket-error-message-price-limit">
|
||||
<NotificationError testId="dealticket-error-message-price-limit">
|
||||
{priceError}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
toDecimal,
|
||||
validateAmount,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { Input, InputError, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { Input, NotificationError, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { isMarketInAuction } from '../../utils';
|
||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||
import { getMarketPrice } from '../../utils/get-price';
|
||||
@@ -77,12 +77,12 @@ export const DealTicketMarketAmount = ({
|
||||
</div>
|
||||
</div>
|
||||
{sizeError && (
|
||||
<InputError
|
||||
<NotificationError
|
||||
intent="danger"
|
||||
testId="dealticket-error-message-size-market"
|
||||
>
|
||||
{sizeError}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ import { normalizeOrderSubmission } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
ExternalLink,
|
||||
InputError,
|
||||
NotificationError,
|
||||
Intent,
|
||||
Notification,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
@@ -308,11 +308,11 @@ const SummaryMessage = memo(
|
||||
if (isReadOnly) {
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<InputError testId="dealticket-error-message-summary">
|
||||
<NotificationError testId="dealticket-error-message-summary">
|
||||
{
|
||||
'You need to connect your own wallet to start trading on this market'
|
||||
}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -353,9 +353,9 @@ const SummaryMessage = memo(
|
||||
if (errorMessage) {
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<InputError testId="dealticket-error-message-summary">
|
||||
<NotificationError testId="dealticket-error-message-summary">
|
||||
{errorMessage}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FormGroup, Input, InputError } from '@vegaprotocol/ui-toolkit';
|
||||
import { FormGroup, Input, NotificationError } from '@vegaprotocol/ui-toolkit';
|
||||
import { formatForInput } from '@vegaprotocol/react-helpers';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { UseFormRegister } from 'react-hook-form';
|
||||
@@ -35,9 +35,9 @@ export const ExpirySelector = ({
|
||||
})}
|
||||
/>
|
||||
{errorMessage && (
|
||||
<InputError testId="dealticket-error-message-expiry">
|
||||
<NotificationError testId="dealticket-error-message-expiry">
|
||||
{errorMessage}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
)}
|
||||
</FormGroup>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import {
|
||||
FormGroup,
|
||||
InputError,
|
||||
NotificationError,
|
||||
Select,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
@@ -139,9 +139,9 @@ export const TimeInForceSelector = ({
|
||||
))}
|
||||
</Select>
|
||||
{errorMessage && (
|
||||
<InputError testId="dealticket-error-message-tif">
|
||||
<NotificationError testId="dealticket-error-message-tif">
|
||||
{renderError(errorMessage)}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
)}
|
||||
</FormGroup>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { FormGroup, InputError, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
FormGroup,
|
||||
NotificationError,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
||||
@@ -78,9 +82,9 @@ export const TypeSelector = ({
|
||||
onChange={(e) => onSelect(e.target.value as Schema.OrderType)}
|
||||
/>
|
||||
{errorMessage && (
|
||||
<InputError testId="dealticket-error-message-type">
|
||||
<NotificationError testId="dealticket-error-message-type">
|
||||
{renderError(errorMessage as MarketModeValidationType)}
|
||||
</InputError>
|
||||
</NotificationError>
|
||||
)}
|
||||
</FormGroup>
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@ export const FillsManager = ({
|
||||
}: FillsManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const scrolledToTop = useRef(true);
|
||||
const { data, error, loading, addNewRows, getRows, reload } = useFillsList({
|
||||
const { data, error, loading, addNewRows, getRows } = useFillsList({
|
||||
partyId,
|
||||
marketId,
|
||||
gridRef,
|
||||
@@ -55,7 +55,6 @@ export const FillsManager = ({
|
||||
data={data}
|
||||
noDataMessage={t('No fills')}
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
reload={reload}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -78,7 +78,7 @@ export const useFillsList = ({
|
||||
|
||||
const variables = useMemo(() => ({ partyId, marketId }), [partyId, marketId]);
|
||||
|
||||
const { data, error, loading, load, totalCount, reload } = useDataProvider<
|
||||
const { data, error, loading, load, totalCount } = useDataProvider<
|
||||
(TradeEdge | null)[],
|
||||
Trade[]
|
||||
>({
|
||||
@@ -95,5 +95,5 @@ export const useFillsList = ({
|
||||
load,
|
||||
newRows
|
||||
);
|
||||
return { data, error, loading, addNewRows, getRows, reload };
|
||||
return { data, error, loading, addNewRows, getRows };
|
||||
};
|
||||
|
||||
@@ -29,19 +29,14 @@ export const ProposalsList = () => {
|
||||
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
|
||||
};
|
||||
}, []);
|
||||
const { data, loading, error, reload } = useDataProvider({
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: proposalsListDataProvider,
|
||||
variables,
|
||||
});
|
||||
const filteredData = getNewMarketProposals(data || []);
|
||||
const { columnDefs, defaultColDef } = useColumnDefs();
|
||||
return (
|
||||
<AsyncRenderer
|
||||
loading={loading}
|
||||
error={error}
|
||||
data={filteredData}
|
||||
reload={reload}
|
||||
>
|
||||
<AsyncRenderer loading={loading} error={error} data={filteredData}>
|
||||
<AgGrid
|
||||
ref={gridRef}
|
||||
domLayout="autoHeight"
|
||||
|
||||
@@ -35,7 +35,6 @@ query LedgerEntries(
|
||||
node {
|
||||
...LedgerEntry
|
||||
}
|
||||
cursor
|
||||
}
|
||||
pageInfo {
|
||||
startCursor
|
||||
|
||||
+1
-2
@@ -14,7 +14,7 @@ export type LedgerEntriesQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type LedgerEntriesQuery = { __typename?: 'Query', ledgerEntries: { __typename?: 'AggregatedLedgerEntriesConnection', edges: Array<{ __typename?: 'AggregatedLedgerEntriesEdge', cursor: string, node: { __typename?: 'AggregatedLedgerEntry', vegaTime: any, quantity: string, assetId?: string | null, transferType?: Types.TransferType | null, toAccountType?: Types.AccountType | null, toAccountMarketId?: string | null, toAccountPartyId?: string | null, toAccountBalance: string, fromAccountType?: Types.AccountType | null, fromAccountMarketId?: string | null, fromAccountPartyId?: string | null, fromAccountBalance: string } } | null>, pageInfo: { __typename?: 'PageInfo', startCursor: string, endCursor: string, hasNextPage: boolean, hasPreviousPage: boolean } } };
|
||||
export type LedgerEntriesQuery = { __typename?: 'Query', ledgerEntries: { __typename?: 'AggregatedLedgerEntriesConnection', edges: Array<{ __typename?: 'AggregatedLedgerEntriesEdge', node: { __typename?: 'AggregatedLedgerEntry', vegaTime: any, quantity: string, assetId?: string | null, transferType?: Types.TransferType | null, toAccountType?: Types.AccountType | null, toAccountMarketId?: string | null, toAccountPartyId?: string | null, toAccountBalance: string, fromAccountType?: Types.AccountType | null, fromAccountMarketId?: string | null, fromAccountPartyId?: string | null, fromAccountBalance: string } } | null>, pageInfo: { __typename?: 'PageInfo', startCursor: string, endCursor: string, hasNextPage: boolean, hasPreviousPage: boolean } } };
|
||||
|
||||
export const LedgerEntryFragmentDoc = gql`
|
||||
fragment LedgerEntry on AggregatedLedgerEntry {
|
||||
@@ -43,7 +43,6 @@ export const LedgerEntriesDocument = gql`
|
||||
node {
|
||||
...LedgerEntry
|
||||
}
|
||||
cursor
|
||||
}
|
||||
pageInfo {
|
||||
startCursor
|
||||
|
||||
@@ -128,11 +128,7 @@ export const ledgerEntriesProvider = makeDerivedDataProvider<
|
||||
const marketReceiver = markets.find(
|
||||
(market: Market) => market.id === entry.toAccountMarketId
|
||||
);
|
||||
const cursor = edge?.cursor;
|
||||
return {
|
||||
node: { ...entry, asset, marketSender, marketReceiver },
|
||||
cursor,
|
||||
};
|
||||
return { node: { ...entry, asset, marketSender, marketReceiver } };
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -176,13 +172,14 @@ export const useLedgerEntriesDataProvider = ({
|
||||
data: (AggregatedLedgerEntriesEdge | null)[] | null;
|
||||
totalCount?: number;
|
||||
}) => {
|
||||
dataRef.current = data;
|
||||
totalCountRef.current = totalCount;
|
||||
return updateGridData(dataRef, data, gridRef);
|
||||
},
|
||||
[gridRef]
|
||||
);
|
||||
|
||||
const { data, error, loading, load, totalCount, reload } = useDataProvider({
|
||||
const { data, error, loading, load, totalCount } = useDataProvider({
|
||||
dataProvider: ledgerEntriesProvider,
|
||||
update,
|
||||
insert,
|
||||
@@ -196,5 +193,5 @@ export const useLedgerEntriesDataProvider = ({
|
||||
totalCountRef,
|
||||
load
|
||||
);
|
||||
return { loading, error, data, getRows, reload };
|
||||
return { loading, error, data, getRows };
|
||||
};
|
||||
|
||||
@@ -16,7 +16,6 @@ export const ledgerEntriesQuery = (
|
||||
edges: ledgerEntries.map((node) => ({
|
||||
__typename: 'AggregatedLedgerEntriesEdge',
|
||||
node,
|
||||
cursor: 'cursor-1',
|
||||
})),
|
||||
pageInfo: {
|
||||
startCursor:
|
||||
|
||||
@@ -21,12 +21,11 @@ export const LedgerManager = ({ partyId }: LedgerManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const [filter, setFilter] = useState<Filter | undefined>();
|
||||
|
||||
const { data, error, loading, getRows, reload } =
|
||||
useLedgerEntriesDataProvider({
|
||||
partyId,
|
||||
filter,
|
||||
gridRef,
|
||||
});
|
||||
const { data, error, loading, getRows } = useLedgerEntriesDataProvider({
|
||||
partyId,
|
||||
filter,
|
||||
gridRef,
|
||||
});
|
||||
|
||||
const onFilterChanged = useCallback(
|
||||
(event: FilterChangedEvent) => {
|
||||
@@ -39,11 +38,7 @@ export const LedgerManager = ({ partyId }: LedgerManagerProps) => {
|
||||
},
|
||||
[filter]
|
||||
);
|
||||
const getRowId = useCallback(
|
||||
({ data }: { data: Types.AggregatedLedgerEntry }) =>
|
||||
`${data.vegaTime}-${data.fromAccountPartyId}-${data.toAccountPartyId}`,
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="h-full relative">
|
||||
<LedgerTable
|
||||
@@ -51,7 +46,6 @@ export const LedgerManager = ({ partyId }: LedgerManagerProps) => {
|
||||
rowModelType="infinite"
|
||||
datasource={{ getRows }}
|
||||
onFilterChanged={onFilterChanged}
|
||||
getRowId={getRowId}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
@@ -60,7 +54,6 @@ export const LedgerManager = ({ partyId }: LedgerManagerProps) => {
|
||||
data={data}
|
||||
noDataMessage={t('No entries')}
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
reload={reload}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -85,7 +85,7 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
||||
[marketId, updateOrderbookData]
|
||||
);
|
||||
|
||||
const { data, error, loading, flush, reload } = useDataProvider({
|
||||
const { data, error, loading, flush } = useDataProvider({
|
||||
dataProvider: marketDepthProvider,
|
||||
update,
|
||||
variables,
|
||||
@@ -156,7 +156,6 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
||||
loading={loading || marketDataLoading || marketLoading}
|
||||
error={error || marketDataError || marketError}
|
||||
data={data}
|
||||
reload={reload}
|
||||
>
|
||||
<Orderbook
|
||||
{...orderbookData}
|
||||
|
||||
@@ -69,14 +69,14 @@ export const MarketInfoContainer = ({
|
||||
[marketId, yTimestamp]
|
||||
);
|
||||
|
||||
const { data, loading, error, reload } = useDataProvider({
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: marketInfoDataProvider,
|
||||
skipUpdates: true,
|
||||
variables,
|
||||
});
|
||||
|
||||
return (
|
||||
<AsyncRenderer data={data} loading={loading} error={error} reload={reload}>
|
||||
<AsyncRenderer data={data} loading={loading} error={error}>
|
||||
{data && data.market ? (
|
||||
<Info market={data.market} onSelect={(id) => onSelect?.(id)} />
|
||||
) : (
|
||||
|
||||
@@ -10,7 +10,7 @@ interface MarketsContainerProps {
|
||||
}
|
||||
|
||||
export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||
const { data, error, loading, reload } = useDataProvider({
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider,
|
||||
skipUpdates: true,
|
||||
});
|
||||
@@ -18,8 +18,7 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||
return (
|
||||
<div className="h-full relative">
|
||||
<MarketListTable
|
||||
rowData={error ? [] : data}
|
||||
noRowsOverlayComponent={() => null}
|
||||
rowData={data}
|
||||
onRowClicked={(rowEvent: RowClickedEvent) => {
|
||||
const { data, event } = rowEvent;
|
||||
// filters out clicks on the symbol column because it should display asset details
|
||||
@@ -37,7 +36,6 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||
error={error}
|
||||
data={data}
|
||||
noDataMessage={t('No markets')}
|
||||
reload={reload}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -155,7 +155,6 @@ export const ordersProvider = makeDataProvider({
|
||||
append,
|
||||
first: 100,
|
||||
},
|
||||
additionalContext: { isEnlargedTimeout: true },
|
||||
});
|
||||
|
||||
export const ordersWithMarketProvider = makeDerivedDataProvider<
|
||||
|
||||
@@ -83,15 +83,14 @@ export const OrderListManager = ({
|
||||
const create = useVegaTransactionStore((state) => state.create);
|
||||
const hasActiveOrder = useHasActiveOrder(marketId);
|
||||
|
||||
const { data, error, loading, addNewRows, getRows, reload } =
|
||||
useOrderListData({
|
||||
partyId,
|
||||
marketId,
|
||||
sort,
|
||||
filter,
|
||||
gridRef,
|
||||
scrolledToTop,
|
||||
});
|
||||
const { data, error, loading, addNewRows, getRows } = useOrderListData({
|
||||
partyId,
|
||||
marketId,
|
||||
sort,
|
||||
filter,
|
||||
gridRef,
|
||||
scrolledToTop,
|
||||
});
|
||||
|
||||
const onBodyScrollEnd = (event: BodyScrollEndEvent) => {
|
||||
if (event.top === 0) {
|
||||
@@ -129,7 +128,7 @@ export const OrderListManager = ({
|
||||
return (
|
||||
<>
|
||||
<div className="h-full relative grid grid-rows-[1fr,min-content]">
|
||||
<div className="relative">
|
||||
<div className="h-full relative">
|
||||
<OrderListTable
|
||||
ref={gridRef}
|
||||
rowModelType="infinite"
|
||||
@@ -150,8 +149,6 @@ export const OrderListManager = ({
|
||||
setEditOrder={setEditOrder}
|
||||
onMarketClick={onMarketClick}
|
||||
isReadOnly={isReadOnly}
|
||||
hasActiveOrder={hasActiveOrder}
|
||||
blockLoadDebounceMillis={100}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
@@ -160,7 +157,6 @@ export const OrderListManager = ({
|
||||
data={data}
|
||||
noDataMessage={t('No orders')}
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
reload={reload}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -119,7 +119,7 @@ export const useOrderListData = ({
|
||||
[gridRef]
|
||||
);
|
||||
|
||||
const { data, error, loading, load, totalCount, reload } = useDataProvider({
|
||||
const { data, error, loading, load, totalCount } = useDataProvider({
|
||||
dataProvider: ordersWithMarketProvider,
|
||||
update,
|
||||
insert,
|
||||
@@ -133,5 +133,5 @@ export const useOrderListData = ({
|
||||
load,
|
||||
newRows
|
||||
);
|
||||
return { loading, error, data, addNewRows, getRows, reload };
|
||||
return { loading, error, data, addNewRows, getRows };
|
||||
};
|
||||
|
||||
@@ -33,24 +33,20 @@ export type OrderListTableProps = OrderListProps & {
|
||||
setEditOrder: (order: Order) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
isReadOnly: boolean;
|
||||
hasActiveOrder?: boolean;
|
||||
};
|
||||
|
||||
export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
({ cancel, setEditOrder, onMarketClick, hasActiveOrder, ...props }, ref) => {
|
||||
({ cancel, setEditOrder, onMarketClick, ...props }, ref) => {
|
||||
return (
|
||||
<AgGrid
|
||||
ref={ref}
|
||||
overlayNoRowsTemplate={t('No orders')}
|
||||
overlayNoRowsTemplate="No orders"
|
||||
defaultColDef={{
|
||||
flex: 1,
|
||||
resizable: true,
|
||||
filterParams: { buttons: ['reset'] },
|
||||
}}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: hasActiveOrder ? 'calc(100% - 46px)' : '100%',
|
||||
}}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
getRowId={({ data }) => data.id}
|
||||
{...props}
|
||||
>
|
||||
|
||||
@@ -18,11 +18,7 @@ export const PositionsManager = ({
|
||||
isReadOnly,
|
||||
}: PositionsManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const { data, error, loading, reload } = usePositionsData(
|
||||
partyId,
|
||||
gridRef,
|
||||
true
|
||||
);
|
||||
const { data, error, loading } = usePositionsData(partyId, gridRef, true);
|
||||
const create = useVegaTransactionStore((store) => store.create);
|
||||
const onClose = ({
|
||||
marketId,
|
||||
@@ -55,7 +51,7 @@ export const PositionsManager = ({
|
||||
return (
|
||||
<div className="h-full relative">
|
||||
<PositionsTable
|
||||
rowData={error ? [] : data}
|
||||
rowData={data}
|
||||
ref={gridRef}
|
||||
onMarketClick={onMarketClick}
|
||||
onClose={onClose}
|
||||
@@ -69,7 +65,6 @@ export const PositionsManager = ({
|
||||
data={data}
|
||||
noDataMessage={t('No positions')}
|
||||
noDataCondition={(data) => !(data && data.length)}
|
||||
reload={reload}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,7 @@ export const usePositionsData = (
|
||||
},
|
||||
[gridRef, clientSideModel]
|
||||
);
|
||||
const { data, error, loading, reload } = useDataProvider({
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider: positionsMetricsProvider,
|
||||
update,
|
||||
variables,
|
||||
@@ -45,6 +45,5 @@ export const usePositionsData = (
|
||||
error,
|
||||
loading,
|
||||
getRows,
|
||||
reload,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -80,7 +80,6 @@ export const useDataProvider = <
|
||||
}
|
||||
}, []);
|
||||
const reload = useCallback((force = false) => {
|
||||
initialized.current = false;
|
||||
if (reloadRef.current) {
|
||||
reloadRef.current(force);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ const getLastRow = (
|
||||
lastRow = totalCount;
|
||||
}
|
||||
} else if (blockLength < endRow - startRow) {
|
||||
lastRow = blockLength + startRow;
|
||||
lastRow = blockLength;
|
||||
}
|
||||
return lastRow;
|
||||
};
|
||||
|
||||
@@ -82,7 +82,7 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
||||
[]
|
||||
);
|
||||
|
||||
const { data, error, loading, load, totalCount, reload } = useDataProvider({
|
||||
const { data, error, loading, load, totalCount } = useDataProvider({
|
||||
dataProvider: tradesWithMarketProvider,
|
||||
update,
|
||||
insert,
|
||||
@@ -107,7 +107,7 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data} reload={reload}>
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
<TradesTable
|
||||
ref={gridRef}
|
||||
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { render, act, screen } from '@testing-library/react';
|
||||
import { AsyncRenderer } from './async-renderer';
|
||||
|
||||
describe('AsyncRenderer', () => {
|
||||
it('timeout error should render button', async () => {
|
||||
const reload = jest.fn();
|
||||
await act(() => {
|
||||
render(
|
||||
<AsyncRenderer
|
||||
reload={reload}
|
||||
error={new Error('Timeout exceeded')}
|
||||
loading={false}
|
||||
data={undefined}
|
||||
/>
|
||||
);
|
||||
});
|
||||
expect(screen.getByRole('button')).toBeInTheDocument();
|
||||
await act(() => {
|
||||
screen.getByRole('button').click();
|
||||
});
|
||||
expect(reload).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Splash } from '../splash';
|
||||
import type { ReactNode } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Button } from '../button';
|
||||
|
||||
interface AsyncRendererProps<T> {
|
||||
loading: boolean;
|
||||
@@ -13,7 +12,6 @@ interface AsyncRendererProps<T> {
|
||||
children?: ReactNode | null;
|
||||
render?: (data: T) => ReactNode;
|
||||
noDataCondition?(data?: T): boolean;
|
||||
reload?: () => void;
|
||||
}
|
||||
|
||||
export function AsyncRenderer<T = object>({
|
||||
@@ -26,30 +24,15 @@ export function AsyncRenderer<T = object>({
|
||||
noDataCondition,
|
||||
children,
|
||||
render,
|
||||
reload,
|
||||
}: AsyncRendererProps<T>) {
|
||||
if (error) {
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="h-full flex items-center justify-center">
|
||||
<div className="h-12 flex flex-col items-center">
|
||||
<Splash>
|
||||
{errorMessage
|
||||
? errorMessage
|
||||
: t(`Something went wrong: ${error.message}`)}
|
||||
</Splash>
|
||||
{reload && error.message === 'Timeout exceeded' && (
|
||||
<Button
|
||||
size="sm"
|
||||
className="pointer-events-auto"
|
||||
type="button"
|
||||
onClick={reload}
|
||||
>
|
||||
{t('Try again')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Splash>
|
||||
{errorMessage
|
||||
? errorMessage
|
||||
: t(`Something went wrong: ${error.message}`)}
|
||||
</Splash>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,52 @@
|
||||
import classNames from 'classnames';
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import { Intent } from '../../utils/intent';
|
||||
import { Notification } from '../notification';
|
||||
|
||||
interface InputErrorProps extends HTMLAttributes<HTMLDivElement> {
|
||||
children?: React.ReactNode;
|
||||
intent?: 'danger' | 'warning';
|
||||
forInput?: string;
|
||||
}
|
||||
|
||||
interface NotificationErrorProps extends HTMLAttributes<HTMLDivElement> {
|
||||
children?: React.ReactNode;
|
||||
intent?: Intent | 'danger' | 'warning';
|
||||
forInput?: string;
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
const getIntent = (intent: Intent | 'danger' | 'warning') => {
|
||||
switch (intent) {
|
||||
case 'danger':
|
||||
return Intent.Danger;
|
||||
case 'warning':
|
||||
return Intent.Warning;
|
||||
default:
|
||||
return intent;
|
||||
}
|
||||
};
|
||||
|
||||
export const NotificationError = ({
|
||||
intent = Intent.Danger,
|
||||
children,
|
||||
forInput,
|
||||
testId,
|
||||
}: NotificationErrorProps) => {
|
||||
return (
|
||||
<Notification
|
||||
intent={getIntent(intent)}
|
||||
testId={testId || 'input-error-text'}
|
||||
message={<div className="role">{children}</div>}
|
||||
aria-describedby={forInput}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const InputError = ({
|
||||
intent = 'danger',
|
||||
children,
|
||||
forInput,
|
||||
testId,
|
||||
...props
|
||||
}: InputErrorProps) => {
|
||||
const effectiveClassName = classNames(
|
||||
@@ -29,7 +63,7 @@ export const InputError = ({
|
||||
);
|
||||
return (
|
||||
<div
|
||||
data-testid={testId || 'input-error-text'}
|
||||
data-testid="input-error-text"
|
||||
aria-describedby={forInput}
|
||||
className={effectiveClassName}
|
||||
{...props}
|
||||
|
||||
@@ -53,7 +53,7 @@ export const NavDropdownMenuContent = forwardRef<
|
||||
<DropdownMenuPrimitive.Content
|
||||
{...contentProps}
|
||||
ref={forwardedRef}
|
||||
className="z-10 bg-vega-dark-100 mt-4 py-4 rounded-xl border border-vega-dark-200 text-white"
|
||||
className="bg-vega-dark-100 mt-4 py-4 rounded-xl border border-vega-dark-200 text-white"
|
||||
align="start"
|
||||
sideOffset={10}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user