genlayer 0.18.3 → 0.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +7 -12
- package/package.json +1 -1
- package/src/lib/actions/BaseAction.ts +8 -15
- package/templates/default/README.md +5 -5
- package/templates/default/contracts/football_bets.py +9 -9
- package/templates/default/deploy/deployScript.ts +6 -1
- package/templates/default/requirements.txt +4 -5
- package/templates/default/test/football_bets_get_contract_schema_for_code.py +7 -7
- package/templates/default/test/test_football_bet.py +140 -0
- package/tests/libs/baseAction.test.ts +44 -53
- package/templates/default/test/test_football_bet_success_draw.py +0 -108
- package/templates/default/test/test_football_bet_success_win.py +0 -106
- package/templates/default/test/test_football_bet_unsuccess.py +0 -107
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.18.5 (2025-07-09)
|
|
4
|
+
|
|
5
|
+
## 0.18.4 (2025-06-27)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* refactor log output formatting and address spinner display ([#228](https://github.com/yeagerai/genlayer-cli/issues/228)) ([ea0ac10](https://github.com/yeagerai/genlayer-cli/commit/ea0ac100cdbed0cf184ae1eaf1d9c0fd580fc92c))
|
|
10
|
+
|
|
3
11
|
## 0.18.3 (2025-05-29)
|
|
4
12
|
|
|
5
13
|
## 0.18.2 (2025-05-29)
|
package/dist/index.js
CHANGED
|
@@ -17723,7 +17723,7 @@ var require_semver2 = __commonJS({
|
|
|
17723
17723
|
import { program } from "commander";
|
|
17724
17724
|
|
|
17725
17725
|
// package.json
|
|
17726
|
-
var version = "0.18.
|
|
17726
|
+
var version = "0.18.5";
|
|
17727
17727
|
var package_default = {
|
|
17728
17728
|
name: "genlayer",
|
|
17729
17729
|
version,
|
|
@@ -20658,6 +20658,7 @@ function ora(options) {
|
|
|
20658
20658
|
|
|
20659
20659
|
// src/lib/actions/BaseAction.ts
|
|
20660
20660
|
import inquirer from "inquirer";
|
|
20661
|
+
import { inspect } from "util";
|
|
20661
20662
|
|
|
20662
20663
|
// src/lib/accounts/KeypairManager.ts
|
|
20663
20664
|
import { writeFileSync, existsSync, readFileSync } from "fs";
|
|
@@ -40979,18 +40980,10 @@ var BaseAction = class extends ConfigFileManager {
|
|
|
40979
40980
|
}
|
|
40980
40981
|
}
|
|
40981
40982
|
formatOutput(data) {
|
|
40982
|
-
if (data
|
|
40983
|
-
|
|
40984
|
-
name: data.name,
|
|
40985
|
-
message: data.message,
|
|
40986
|
-
...Object.keys(data).length ? data : {}
|
|
40987
|
-
};
|
|
40988
|
-
return JSON.stringify(errorDetails, null, 2);
|
|
40989
|
-
}
|
|
40990
|
-
if (data instanceof Map) {
|
|
40991
|
-
data = Object.fromEntries(data);
|
|
40983
|
+
if (typeof data === "string") {
|
|
40984
|
+
return data;
|
|
40992
40985
|
}
|
|
40993
|
-
return
|
|
40986
|
+
return inspect(data, { depth: null, colors: false });
|
|
40994
40987
|
}
|
|
40995
40988
|
log(message, data) {
|
|
40996
40989
|
console.log(source_default.white(`
|
|
@@ -41023,10 +41016,12 @@ ${message}`));
|
|
|
41023
41016
|
}
|
|
41024
41017
|
succeedSpinner(message, data) {
|
|
41025
41018
|
if (data !== void 0) this.log("Result:", data);
|
|
41019
|
+
console.log("");
|
|
41026
41020
|
this.spinner.succeed(source_default.green(message));
|
|
41027
41021
|
}
|
|
41028
41022
|
failSpinner(message, error) {
|
|
41029
41023
|
if (error) this.log("Error:", error);
|
|
41024
|
+
console.log("");
|
|
41030
41025
|
this.spinner.fail(source_default.red(message));
|
|
41031
41026
|
}
|
|
41032
41027
|
stopSpinner() {
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@ import {ConfigFileManager} from "../../lib/config/ConfigFileManager";
|
|
|
2
2
|
import ora, {Ora} from "ora";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import inquirer from "inquirer";
|
|
5
|
+
import { inspect } from "util";
|
|
5
6
|
import {KeypairManager} from "../accounts/KeypairManager";
|
|
6
7
|
import {createClient, createAccount} from "genlayer-js";
|
|
7
8
|
import {localnet} from "genlayer-js/chains";
|
|
@@ -58,20 +59,10 @@ export class BaseAction extends ConfigFileManager {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
private formatOutput(data: any): string {
|
|
61
|
-
if (data
|
|
62
|
-
|
|
63
|
-
name: data.name,
|
|
64
|
-
message: data.message,
|
|
65
|
-
...(Object.keys(data).length ? data : {}),
|
|
66
|
-
};
|
|
67
|
-
return JSON.stringify(errorDetails, null, 2);
|
|
62
|
+
if (typeof data === "string") {
|
|
63
|
+
return data;
|
|
68
64
|
}
|
|
69
|
-
|
|
70
|
-
if (data instanceof Map) {
|
|
71
|
-
data = Object.fromEntries(data);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return typeof data === "object" ? JSON.stringify(data, null, 2) : String(data);
|
|
65
|
+
return inspect(data, { depth: null, colors: false });
|
|
75
66
|
}
|
|
76
67
|
|
|
77
68
|
protected log(message: string, data?: any): void {
|
|
@@ -106,11 +97,13 @@ export class BaseAction extends ConfigFileManager {
|
|
|
106
97
|
|
|
107
98
|
protected succeedSpinner(message: string, data?: any): void {
|
|
108
99
|
if (data !== undefined) this.log("Result:", data);
|
|
100
|
+
console.log('');
|
|
109
101
|
this.spinner.succeed(chalk.green(message));
|
|
110
102
|
}
|
|
111
103
|
|
|
112
|
-
protected failSpinner(message: string, error?:
|
|
104
|
+
protected failSpinner(message: string, error?:any): void {
|
|
113
105
|
if (error) this.log("Error:", error);
|
|
106
|
+
console.log('');
|
|
114
107
|
this.spinner.fail(chalk.red(message));
|
|
115
108
|
}
|
|
116
109
|
|
|
@@ -121,4 +114,4 @@ export class BaseAction extends ConfigFileManager {
|
|
|
121
114
|
protected setSpinnerText(message: string): void {
|
|
122
115
|
this.spinner.text = chalk.blue(message);
|
|
123
116
|
}
|
|
124
|
-
}
|
|
117
|
+
}
|
|
@@ -45,12 +45,12 @@ This project includes the boilerplate code for a GenLayer use case implementatio
|
|
|
45
45
|
The terminal should display a link to access your frontend app (usually at http://localhost:5173/).
|
|
46
46
|
For more information on the code see [GenLayerJS](https://github.com/yeagerai/genlayer-js).
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
### 5. Test contracts
|
|
49
49
|
1. Install the Python packages listed in the `requirements.txt` file in a virtual environment.
|
|
50
50
|
2. Make sure your GenLayer Studio is running. Then execute the following command in your terminal:
|
|
51
51
|
```shell
|
|
52
|
-
|
|
53
|
-
```
|
|
52
|
+
gltest
|
|
53
|
+
```
|
|
54
54
|
|
|
55
55
|
## ⚽ How the Football Bets Contract Works
|
|
56
56
|
|
|
@@ -73,7 +73,7 @@ The Football Bets contract allows users to create bets for football matches, res
|
|
|
73
73
|
- Points are awarded for correct bets.
|
|
74
74
|
- Users can check their total points or the points of any player.
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
## 🧪 Tests
|
|
77
77
|
|
|
78
78
|
This project includes integration tests that interact with the contract deployed in the Studio. These tests cover the main functionalities of the Football Bets contract:
|
|
79
79
|
|
|
@@ -84,7 +84,7 @@ This project includes integration tests that interact with the contract deployed
|
|
|
84
84
|
|
|
85
85
|
The tests simulate real-world interactions with the contract, ensuring that it behaves correctly under various scenarios. They use the GenLayer Studio to deploy and interact with the contract, providing a comprehensive check of the contract's functionality in a controlled environment.
|
|
86
86
|
|
|
87
|
-
To run the tests, use the `
|
|
87
|
+
To run the tests, use the `gltest` command as mentioned in the "Steps to run this example" section.
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
## 💬 Community
|
|
@@ -5,6 +5,7 @@ from dataclasses import dataclass
|
|
|
5
5
|
from genlayer import *
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
@allow_storage
|
|
8
9
|
@dataclass
|
|
9
10
|
class Bet:
|
|
10
11
|
id: str
|
|
@@ -18,8 +19,7 @@ class Bet:
|
|
|
18
19
|
real_score: str
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
class FootballBets:
|
|
22
|
+
class FootballBets(gl.Contract):
|
|
23
23
|
bets: TreeMap[Address, TreeMap[str, Bet]]
|
|
24
24
|
points: TreeMap[Address, u256]
|
|
25
25
|
|
|
@@ -67,7 +67,7 @@ This result should be perfectly parsable by a JSON parser without errors.
|
|
|
67
67
|
# if int(match_status["winner"]) > -1:
|
|
68
68
|
# raise Exception("Game already finished")
|
|
69
69
|
|
|
70
|
-
sender_address = gl.message.
|
|
70
|
+
sender_address = gl.message.sender_address
|
|
71
71
|
|
|
72
72
|
bet_id = f"{game_date}_{team1}_{team2}".lower()
|
|
73
73
|
if sender_address in self.bets and bet_id in self.bets[sender_address]:
|
|
@@ -88,10 +88,10 @@ This result should be perfectly parsable by a JSON parser without errors.
|
|
|
88
88
|
|
|
89
89
|
@gl.public.write
|
|
90
90
|
def resolve_bet(self, bet_id: str) -> None:
|
|
91
|
-
if self.bets[gl.message.
|
|
91
|
+
if self.bets[gl.message.sender_address][bet_id].has_resolved:
|
|
92
92
|
raise Exception("Bet already resolved")
|
|
93
93
|
|
|
94
|
-
bet = self.bets[gl.message.
|
|
94
|
+
bet = self.bets[gl.message.sender_address][bet_id]
|
|
95
95
|
bet_status = self._check_match(bet.resolution_url, bet.team1, bet.team2)
|
|
96
96
|
|
|
97
97
|
if int(bet_status["winner"]) < 0:
|
|
@@ -102,9 +102,9 @@ This result should be perfectly parsable by a JSON parser without errors.
|
|
|
102
102
|
bet.real_score = bet_status["score"]
|
|
103
103
|
|
|
104
104
|
if bet.real_winner == bet.predicted_winner:
|
|
105
|
-
if gl.message.
|
|
106
|
-
self.points[gl.message.
|
|
107
|
-
self.points[gl.message.
|
|
105
|
+
if gl.message.sender_address not in self.points:
|
|
106
|
+
self.points[gl.message.sender_address] = 0
|
|
107
|
+
self.points[gl.message.sender_address] += 1
|
|
108
108
|
|
|
109
109
|
@gl.public.view
|
|
110
110
|
def get_bets(self) -> dict:
|
|
@@ -116,4 +116,4 @@ This result should be perfectly parsable by a JSON parser without errors.
|
|
|
116
116
|
|
|
117
117
|
@gl.public.view
|
|
118
118
|
def get_player_points(self, player_address: str) -> int:
|
|
119
|
-
return self.points.get(Address(player_address), 0)
|
|
119
|
+
return self.points.get(Address(player_address), 0)
|
|
@@ -22,9 +22,14 @@ export default async function main(client: GenLayerClient<any>) {
|
|
|
22
22
|
retries: 200,
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
if (receipt.consensus_data?.leader_receipt?.execution_result !== "SUCCESS") {
|
|
25
|
+
if (receipt.consensus_data?.leader_receipt[0]?.execution_result !== "SUCCESS") {
|
|
26
26
|
throw new Error(`Deployment failed. Receipt: ${JSON.stringify(receipt)}`);
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
console.log("\n Contract deployed successfully.", {
|
|
30
|
+
"Transaction Hash": deployTransaction,
|
|
31
|
+
"Contract Address": receipt.data?.contract_address,
|
|
32
|
+
});
|
|
28
33
|
} catch (error) {
|
|
29
34
|
throw new Error((`Error during deployment:, ${error}`));
|
|
30
35
|
}
|
|
@@ -45,8 +45,8 @@ test_football_bets_win_unresolved = {
|
|
|
45
45
|
"has_resolved": False,
|
|
46
46
|
"id": "2024-06-20_spain_italy",
|
|
47
47
|
"predicted_winner": "1",
|
|
48
|
-
"real_score":
|
|
49
|
-
"real_winner":
|
|
48
|
+
"real_score": '',
|
|
49
|
+
"real_winner": '',
|
|
50
50
|
"resolution_url": "https://www.bbc.com/sport/football/scores-fixtures/2024-06-20",
|
|
51
51
|
"team1": "Spain",
|
|
52
52
|
"team2": "Italy",
|
|
@@ -73,8 +73,8 @@ test_football_bets_draw_unresolved = {
|
|
|
73
73
|
"has_resolved": False,
|
|
74
74
|
"id": "2024-06-20_denmark_england",
|
|
75
75
|
"predicted_winner": "0",
|
|
76
|
-
"real_score":
|
|
77
|
-
"real_winner":
|
|
76
|
+
"real_score": '',
|
|
77
|
+
"real_winner": '',
|
|
78
78
|
"resolution_url": "https://www.bbc.com/sport/football/scores-fixtures/2024-06-20",
|
|
79
79
|
"team1": "Denmark",
|
|
80
80
|
"team2": "England",
|
|
@@ -101,8 +101,8 @@ test_football_bets_unsuccess_unresolved = {
|
|
|
101
101
|
"has_resolved": False,
|
|
102
102
|
"id": "2024-06-20_spain_italy",
|
|
103
103
|
"predicted_winner": "2",
|
|
104
|
-
"real_score":
|
|
105
|
-
"real_winner":
|
|
104
|
+
"real_score": '',
|
|
105
|
+
"real_winner": '',
|
|
106
106
|
"resolution_url": "https://www.bbc.com/sport/football/scores-fixtures/2024-06-20",
|
|
107
107
|
"team1": "Spain",
|
|
108
108
|
"team2": "Italy",
|
|
@@ -121,4 +121,4 @@ test_football_bets_unsuccess_resolved = {
|
|
|
121
121
|
"team1": "Spain",
|
|
122
122
|
"team2": "Italy",
|
|
123
123
|
}
|
|
124
|
-
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from gltest import get_contract_factory, default_account
|
|
2
|
+
from gltest.helpers import load_fixture
|
|
3
|
+
from gltest.assertions import tx_execution_succeeded
|
|
4
|
+
from test.football_bets_get_contract_schema_for_code import (
|
|
5
|
+
test_football_bets_win_resolved,
|
|
6
|
+
test_football_bets_win_unresolved,
|
|
7
|
+
test_football_bets_draw_unresolved,
|
|
8
|
+
test_football_bets_draw_resolved,
|
|
9
|
+
test_football_bets_unsuccess_unresolved,
|
|
10
|
+
test_football_bets_unsuccess_resolved,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def deploy_contract():
|
|
15
|
+
factory = get_contract_factory("FootballBets")
|
|
16
|
+
contract = factory.deploy()
|
|
17
|
+
|
|
18
|
+
# Get Initial State
|
|
19
|
+
contract_all_points_state = contract.get_points(args=[])
|
|
20
|
+
assert contract_all_points_state == {}
|
|
21
|
+
|
|
22
|
+
contract_all_bets_state = contract.get_bets(args=[])
|
|
23
|
+
assert contract_all_bets_state == {}
|
|
24
|
+
return contract
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_football_bets_success_win():
|
|
28
|
+
# Contract Deploy
|
|
29
|
+
|
|
30
|
+
contract = load_fixture(deploy_contract)
|
|
31
|
+
|
|
32
|
+
# Create Successful Bet
|
|
33
|
+
create_bet_result = contract.create_bet(args=["2024-06-20", "Spain", "Italy", "1"])
|
|
34
|
+
assert tx_execution_succeeded(create_bet_result)
|
|
35
|
+
|
|
36
|
+
# Get Bets
|
|
37
|
+
get_bet_result = contract.get_bets(args=[])
|
|
38
|
+
assert get_bet_result == {
|
|
39
|
+
default_account.address: test_football_bets_win_unresolved
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# Resolve Successful Bet
|
|
43
|
+
resolve_successful_bet_result = contract.resolve_bet(
|
|
44
|
+
args=["2024-06-20_spain_italy"],
|
|
45
|
+
wait_interval=10000, # 10000 ms = 10 seconds
|
|
46
|
+
wait_retries=15,
|
|
47
|
+
)
|
|
48
|
+
assert tx_execution_succeeded(resolve_successful_bet_result)
|
|
49
|
+
|
|
50
|
+
# Get Bets
|
|
51
|
+
get_bet_result = contract.get_bets(args=[])
|
|
52
|
+
assert get_bet_result == {default_account.address: test_football_bets_win_resolved}
|
|
53
|
+
|
|
54
|
+
# Get Points
|
|
55
|
+
get_points_result = contract.get_points(args=[])
|
|
56
|
+
assert get_points_result == {default_account.address: 1}
|
|
57
|
+
|
|
58
|
+
# Get Player Points
|
|
59
|
+
get_player_points_result = contract.get_player_points(
|
|
60
|
+
args=[default_account.address]
|
|
61
|
+
)
|
|
62
|
+
assert get_player_points_result == 1
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_football_bets_draw_success():
|
|
66
|
+
# Contract Deploy
|
|
67
|
+
contract = load_fixture(deploy_contract)
|
|
68
|
+
|
|
69
|
+
# Create Successful Bet
|
|
70
|
+
create_bet_result = contract.create_bet(
|
|
71
|
+
args=["2024-06-20", "Denmark", "England", "0"]
|
|
72
|
+
)
|
|
73
|
+
assert tx_execution_succeeded(create_bet_result)
|
|
74
|
+
|
|
75
|
+
# Get Bets
|
|
76
|
+
get_bet_result = contract.get_bets(args=[])
|
|
77
|
+
assert get_bet_result == {
|
|
78
|
+
default_account.address: test_football_bets_draw_unresolved
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Resolve Successful Bet
|
|
82
|
+
resolve_successful_bet_result = contract.resolve_bet(
|
|
83
|
+
args=["2024-06-20_denmark_england"],
|
|
84
|
+
wait_interval=10000, # 10000 ms = 10 seconds
|
|
85
|
+
wait_retries=15,
|
|
86
|
+
)
|
|
87
|
+
assert tx_execution_succeeded(resolve_successful_bet_result)
|
|
88
|
+
|
|
89
|
+
# Get Bets
|
|
90
|
+
get_bet_result = contract.get_bets(args=[])
|
|
91
|
+
assert get_bet_result == {default_account.address: test_football_bets_draw_resolved}
|
|
92
|
+
|
|
93
|
+
# Get Points
|
|
94
|
+
get_points_result = contract.get_points(args=[])
|
|
95
|
+
assert get_points_result == {default_account.address: 1}
|
|
96
|
+
|
|
97
|
+
# Get Player Points
|
|
98
|
+
get_player_points_result = contract.get_player_points(
|
|
99
|
+
args=[default_account.address]
|
|
100
|
+
)
|
|
101
|
+
assert get_player_points_result == 1
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_football_bets_unsuccess():
|
|
105
|
+
# Contract Deploy
|
|
106
|
+
contract = load_fixture(deploy_contract)
|
|
107
|
+
|
|
108
|
+
# Create Successful Bet
|
|
109
|
+
create_bet_result = contract.create_bet(args=["2024-06-20", "Spain", "Italy", "2"])
|
|
110
|
+
assert tx_execution_succeeded(create_bet_result)
|
|
111
|
+
|
|
112
|
+
# Get Bets
|
|
113
|
+
get_bet_result = contract.get_bets(args=[])
|
|
114
|
+
assert get_bet_result == {
|
|
115
|
+
default_account.address: test_football_bets_unsuccess_unresolved
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Resolve Successful Bet
|
|
119
|
+
resolve_successful_bet_result = contract.resolve_bet(
|
|
120
|
+
args=["2024-06-20_spain_italy"],
|
|
121
|
+
wait_interval=10000, # 10000 ms = 10 seconds
|
|
122
|
+
wait_retries=15,
|
|
123
|
+
)
|
|
124
|
+
assert tx_execution_succeeded(resolve_successful_bet_result)
|
|
125
|
+
|
|
126
|
+
# Get Bets
|
|
127
|
+
get_bet_result = contract.get_bets(args=[])
|
|
128
|
+
assert get_bet_result == {
|
|
129
|
+
default_account.address: test_football_bets_unsuccess_resolved
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
# Get Points
|
|
133
|
+
get_points_result = contract.get_points(args=[])
|
|
134
|
+
assert get_points_result == {}
|
|
135
|
+
|
|
136
|
+
# Get Player Points
|
|
137
|
+
get_player_points_result = contract.get_player_points(
|
|
138
|
+
args=[default_account.address]
|
|
139
|
+
)
|
|
140
|
+
assert get_player_points_result == 0
|
|
@@ -3,6 +3,7 @@ import {BaseAction} from "../../src/lib/actions/BaseAction";
|
|
|
3
3
|
import inquirer from "inquirer";
|
|
4
4
|
import ora, {Ora} from "ora";
|
|
5
5
|
import chalk from "chalk";
|
|
6
|
+
import {inspect} from "util";
|
|
6
7
|
|
|
7
8
|
vi.mock("inquirer");
|
|
8
9
|
vi.mock("ora");
|
|
@@ -42,11 +43,17 @@ describe("BaseAction", () => {
|
|
|
42
43
|
|
|
43
44
|
test("should succeed the spinner with a message", () => {
|
|
44
45
|
baseAction["succeedSpinner"]("Success");
|
|
46
|
+
expect(consoleSpy).toHaveBeenCalledWith("");
|
|
45
47
|
expect(mockSpinner.succeed).toHaveBeenCalledWith(expect.stringContaining("Success"));
|
|
46
48
|
});
|
|
47
49
|
|
|
48
50
|
test("should fail the spinner with an error message", () => {
|
|
49
|
-
|
|
51
|
+
const error = new Error("Something went wrong");
|
|
52
|
+
baseAction["failSpinner"]("Failure", error);
|
|
53
|
+
|
|
54
|
+
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
|
|
55
|
+
expect(consoleSpy).toHaveBeenCalledWith(inspect(error, {depth: null, colors: false}));
|
|
56
|
+
expect(consoleSpy).toHaveBeenCalledWith("");
|
|
50
57
|
expect(mockSpinner.fail).toHaveBeenCalledWith(expect.stringContaining("Failure"));
|
|
51
58
|
});
|
|
52
59
|
|
|
@@ -108,7 +115,7 @@ describe("BaseAction", () => {
|
|
|
108
115
|
baseAction["logSuccess"]("Success message", data);
|
|
109
116
|
|
|
110
117
|
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("✔ Success message"));
|
|
111
|
-
expect(consoleSpy).toHaveBeenCalledWith(chalk.green(
|
|
118
|
+
expect(consoleSpy).toHaveBeenCalledWith(chalk.green(inspect(data, {depth: null, colors: false})));
|
|
112
119
|
});
|
|
113
120
|
|
|
114
121
|
test("should log an error message with error details", () => {
|
|
@@ -117,18 +124,7 @@ describe("BaseAction", () => {
|
|
|
117
124
|
baseAction["logError"]("Error message", error);
|
|
118
125
|
|
|
119
126
|
expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("✖ Error message"));
|
|
120
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
121
|
-
chalk.red(
|
|
122
|
-
JSON.stringify(
|
|
123
|
-
{
|
|
124
|
-
name: error.name,
|
|
125
|
-
message: error.message,
|
|
126
|
-
},
|
|
127
|
-
null,
|
|
128
|
-
2,
|
|
129
|
-
),
|
|
130
|
-
),
|
|
131
|
-
);
|
|
127
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(chalk.red(inspect(error, {depth: null, colors: false})));
|
|
132
128
|
});
|
|
133
129
|
|
|
134
130
|
test("should log an info message with data", () => {
|
|
@@ -137,7 +133,7 @@ describe("BaseAction", () => {
|
|
|
137
133
|
baseAction["logInfo"]("Info message", data);
|
|
138
134
|
|
|
139
135
|
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("ℹ Info message"));
|
|
140
|
-
expect(consoleSpy).toHaveBeenCalledWith(chalk.blue(
|
|
136
|
+
expect(consoleSpy).toHaveBeenCalledWith(chalk.blue(inspect(data, {depth: null, colors: false})));
|
|
141
137
|
});
|
|
142
138
|
|
|
143
139
|
test("should log a warning message with data", () => {
|
|
@@ -146,7 +142,7 @@ describe("BaseAction", () => {
|
|
|
146
142
|
baseAction["logWarning"]("Warning message", data);
|
|
147
143
|
|
|
148
144
|
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("⚠ Warning message"));
|
|
149
|
-
expect(consoleSpy).toHaveBeenCalledWith(chalk.yellow(
|
|
145
|
+
expect(consoleSpy).toHaveBeenCalledWith(chalk.yellow(inspect(data, {depth: null, colors: false})));
|
|
150
146
|
});
|
|
151
147
|
|
|
152
148
|
test("should succeed the spinner with a message and log result if data is provided", () => {
|
|
@@ -155,52 +151,17 @@ describe("BaseAction", () => {
|
|
|
155
151
|
baseAction["succeedSpinner"]("Success", mockData);
|
|
156
152
|
|
|
157
153
|
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Result:"));
|
|
158
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
154
|
+
expect(consoleSpy).toHaveBeenCalledWith(inspect(mockData, {depth: null, colors: false}));
|
|
155
|
+
expect(consoleSpy).toHaveBeenCalledWith("");
|
|
159
156
|
expect(mockSpinner.succeed).toHaveBeenCalledWith(expect.stringContaining("Success"));
|
|
160
157
|
});
|
|
161
158
|
|
|
162
|
-
test("should format an Error instance with name, message, and additional properties", () => {
|
|
163
|
-
const error = new Error("Something went wrong");
|
|
164
|
-
(error as any).code = 500;
|
|
165
|
-
|
|
166
|
-
const result = (baseAction as any).formatOutput(error);
|
|
167
|
-
expect(result).toBe(JSON.stringify({name: "Error", message: "Something went wrong", code: 500}, null, 2));
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
test("should format an object as JSON string", () => {
|
|
171
|
-
const data = {key: "value", num: 42};
|
|
172
|
-
const result = (baseAction as any).formatOutput(data);
|
|
173
|
-
|
|
174
|
-
expect(result).toBe(JSON.stringify(data, null, 2));
|
|
175
|
-
});
|
|
176
|
-
|
|
177
159
|
test("should return a string representation of a primitive", () => {
|
|
178
160
|
expect((baseAction as any).formatOutput("Hello")).toBe("Hello");
|
|
179
161
|
expect((baseAction as any).formatOutput(42)).toBe("42");
|
|
180
162
|
expect((baseAction as any).formatOutput(true)).toBe("true");
|
|
181
163
|
});
|
|
182
164
|
|
|
183
|
-
test("should format a Map object correctly", () => {
|
|
184
|
-
const testMap = new Map<string, any>([
|
|
185
|
-
["key1", "value1"],
|
|
186
|
-
["key2", 42],
|
|
187
|
-
["key3", {nested: "object"}],
|
|
188
|
-
]);
|
|
189
|
-
|
|
190
|
-
const result = (baseAction as any).formatOutput(testMap);
|
|
191
|
-
const expected = JSON.stringify(
|
|
192
|
-
{
|
|
193
|
-
key1: "value1",
|
|
194
|
-
key2: 42,
|
|
195
|
-
key3: {nested: "object"},
|
|
196
|
-
},
|
|
197
|
-
null,
|
|
198
|
-
2,
|
|
199
|
-
);
|
|
200
|
-
|
|
201
|
-
expect(result).toBe(expected);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
165
|
const mockPrivateKey = "mocked_private_key";
|
|
205
166
|
|
|
206
167
|
beforeEach(() => {
|
|
@@ -240,4 +201,34 @@ describe("BaseAction", () => {
|
|
|
240
201
|
|
|
241
202
|
await expect(baseAction["getPrivateKey"]()).rejects.toThrow("process exited");
|
|
242
203
|
});
|
|
204
|
+
|
|
205
|
+
describe("formatOutput", () => {
|
|
206
|
+
test("should return string as is", () => {
|
|
207
|
+
expect((baseAction as any).formatOutput("Hello")).toBe("Hello");
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("should format an object", () => {
|
|
211
|
+
const data = {key: "value", num: 42};
|
|
212
|
+
const result = (baseAction as any).formatOutput(data);
|
|
213
|
+
expect(result).toBe("{ key: 'value', num: 42 }");
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("should format an error object", () => {
|
|
217
|
+
const error = new Error("Test Error");
|
|
218
|
+
const result = (baseAction as any).formatOutput(error);
|
|
219
|
+
expect(result).toContain("Error: Test Error");
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("should format a Map object", () => {
|
|
223
|
+
const testMap = new Map([["key1", "value1"]]);
|
|
224
|
+
const result = (baseAction as any).formatOutput(testMap);
|
|
225
|
+
expect(result).toBe("Map(1) { 'key1' => 'value1' }");
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("should format a BigInt object", () => {
|
|
229
|
+
const bigIntValue = BigInt(9007199254740991);
|
|
230
|
+
const result = (baseAction as any).formatOutput(bigIntValue);
|
|
231
|
+
expect(result).toBe("9007199254740991n");
|
|
232
|
+
});
|
|
233
|
+
});
|
|
243
234
|
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# tests/e2e/test_wizard_of_coin.py
|
|
2
|
-
|
|
3
|
-
from tools.accounts import create_new_account
|
|
4
|
-
from tools.request import (
|
|
5
|
-
deploy_intelligent_contract,
|
|
6
|
-
send_transaction,
|
|
7
|
-
call_contract_method,
|
|
8
|
-
payload,
|
|
9
|
-
post_request,
|
|
10
|
-
)
|
|
11
|
-
from tools.structure import execute_icontract_function_response_structure
|
|
12
|
-
from tools.response import (
|
|
13
|
-
assert_dict_struct,
|
|
14
|
-
assert_dict_exact,
|
|
15
|
-
has_success_status,
|
|
16
|
-
)
|
|
17
|
-
from test.football_bets_get_contract_schema_for_code import (
|
|
18
|
-
football_bets_contract_schema,
|
|
19
|
-
test_football_bets_win_resolved,
|
|
20
|
-
test_football_bets_win_unresolved,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def test_football_bets_success():
|
|
25
|
-
# Account
|
|
26
|
-
account_1 = create_new_account()
|
|
27
|
-
# Validators - not needed for studio.genlayer.com
|
|
28
|
-
# result = post_request(
|
|
29
|
-
# payload("sim_createRandomValidators", 5, 8, 12, ["openai"], ["gpt-4o"])
|
|
30
|
-
# ).json()
|
|
31
|
-
# assert has_success_status(result)
|
|
32
|
-
|
|
33
|
-
# Contract Schema
|
|
34
|
-
contract_code = open("contracts/football_bets.py", "r").read()
|
|
35
|
-
result_schema = post_request(
|
|
36
|
-
payload("gen_getContractSchemaForCode", contract_code)
|
|
37
|
-
).json()
|
|
38
|
-
assert has_success_status(result_schema)
|
|
39
|
-
assert_dict_exact(result_schema, football_bets_contract_schema)
|
|
40
|
-
|
|
41
|
-
# Contract Deploy
|
|
42
|
-
contract_address, transaction_response_deploy = deploy_intelligent_contract(
|
|
43
|
-
account_1,
|
|
44
|
-
contract_code,
|
|
45
|
-
"{}",
|
|
46
|
-
)
|
|
47
|
-
assert has_success_status(transaction_response_deploy)
|
|
48
|
-
|
|
49
|
-
# Get Initial State
|
|
50
|
-
contract_all_points_state = call_contract_method(
|
|
51
|
-
contract_address, account_1, "get_points", []
|
|
52
|
-
)
|
|
53
|
-
assert contract_all_points_state == {}
|
|
54
|
-
|
|
55
|
-
contract_all_bets_state = call_contract_method(
|
|
56
|
-
contract_address, account_1, "get_bets", []
|
|
57
|
-
)
|
|
58
|
-
assert contract_all_bets_state == {}
|
|
59
|
-
|
|
60
|
-
# Create Successful Bet
|
|
61
|
-
create_successful_bet_result = send_transaction(
|
|
62
|
-
account_1,
|
|
63
|
-
contract_address,
|
|
64
|
-
"create_bet",
|
|
65
|
-
["2024-06-20", "Denmark", "England", "0"],
|
|
66
|
-
)
|
|
67
|
-
assert has_success_status(create_successful_bet_result)
|
|
68
|
-
assert_dict_struct(
|
|
69
|
-
create_successful_bet_result,
|
|
70
|
-
execute_icontract_function_response_structure,
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
# Get Bets
|
|
74
|
-
get_bet_result = call_contract_method(contract_address, account_1, "get_bets", [])
|
|
75
|
-
assert get_bet_result == {account_1.address: test_football_bets_win_unresolved}
|
|
76
|
-
|
|
77
|
-
# Resolve Successful Bet
|
|
78
|
-
resolve_successful_bet_result = send_transaction(
|
|
79
|
-
account_1,
|
|
80
|
-
contract_address,
|
|
81
|
-
"resolve_bet",
|
|
82
|
-
["2024-06-20_denmark_england"],
|
|
83
|
-
)
|
|
84
|
-
assert has_success_status(resolve_successful_bet_result)
|
|
85
|
-
assert_dict_struct(
|
|
86
|
-
resolve_successful_bet_result,
|
|
87
|
-
execute_icontract_function_response_structure,
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
# Get Bets
|
|
91
|
-
get_bet_result = call_contract_method(contract_address, account_1, "get_bets", [])
|
|
92
|
-
assert get_bet_result == {account_1.address: test_football_bets_win_resolved}
|
|
93
|
-
|
|
94
|
-
# Get Points
|
|
95
|
-
get_points_result = call_contract_method(
|
|
96
|
-
contract_address, account_1, "get_points", []
|
|
97
|
-
)
|
|
98
|
-
assert get_points_result == {account_1.address: 1}
|
|
99
|
-
|
|
100
|
-
# Get Player Points
|
|
101
|
-
get_player_points_result = call_contract_method(
|
|
102
|
-
contract_address, account_1, "get_player_points", [account_1.address]
|
|
103
|
-
)
|
|
104
|
-
assert get_player_points_result == 1
|
|
105
|
-
|
|
106
|
-
# Delete Validators - not needed for studio.genlayer.com
|
|
107
|
-
# delete_validators_result = post_request(payload("sim_deleteAllValidators")).json()
|
|
108
|
-
# assert has_success_status(delete_validators_result)
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# tests/e2e/test_wizard_of_coin.py
|
|
2
|
-
|
|
3
|
-
from tools.accounts import create_new_account
|
|
4
|
-
from tools.request import (
|
|
5
|
-
deploy_intelligent_contract,
|
|
6
|
-
send_transaction,
|
|
7
|
-
call_contract_method,
|
|
8
|
-
payload,
|
|
9
|
-
post_request,
|
|
10
|
-
)
|
|
11
|
-
from tools.structure import execute_icontract_function_response_structure
|
|
12
|
-
from tools.response import (
|
|
13
|
-
assert_dict_struct,
|
|
14
|
-
assert_dict_exact,
|
|
15
|
-
has_success_status,
|
|
16
|
-
)
|
|
17
|
-
from test.football_bets_get_contract_schema_for_code import (
|
|
18
|
-
football_bets_contract_schema,
|
|
19
|
-
test_football_bets_win_unresolved,
|
|
20
|
-
test_football_bets_win_resolved,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def test_football_bets_success():
|
|
25
|
-
# Account
|
|
26
|
-
account_1 = create_new_account()
|
|
27
|
-
# Validators - not needed for studio.genlayer.com
|
|
28
|
-
# result = post_request(
|
|
29
|
-
# payload("sim_createRandomValidators", 5, 8, 12, ["openai"], ["gpt-4o"])
|
|
30
|
-
# ).json()
|
|
31
|
-
# assert has_success_status(result)
|
|
32
|
-
|
|
33
|
-
# Contract Schema
|
|
34
|
-
contract_code = open("contracts/football_bet_market.py", "r").read()
|
|
35
|
-
result_schema = post_request(
|
|
36
|
-
payload("gen_getContractSchemaForCode", contract_code)
|
|
37
|
-
).json()
|
|
38
|
-
assert has_success_status(result_schema)
|
|
39
|
-
assert_dict_exact(result_schema, football_bets_contract_schema)
|
|
40
|
-
|
|
41
|
-
# Contract Deploy
|
|
42
|
-
contract_address, transaction_response_deploy = deploy_intelligent_contract(
|
|
43
|
-
account_1,
|
|
44
|
-
contract_code,
|
|
45
|
-
"{}",
|
|
46
|
-
)
|
|
47
|
-
assert has_success_status(transaction_response_deploy)
|
|
48
|
-
|
|
49
|
-
# Get Initial State
|
|
50
|
-
contract_all_points_state = call_contract_method(
|
|
51
|
-
contract_address, account_1, "get_points", []
|
|
52
|
-
)
|
|
53
|
-
assert contract_all_points_state == {}
|
|
54
|
-
|
|
55
|
-
contract_all_bets_state = call_contract_method(
|
|
56
|
-
contract_address, account_1, "get_bets", []
|
|
57
|
-
)
|
|
58
|
-
assert contract_all_bets_state == {}
|
|
59
|
-
|
|
60
|
-
# Create Successful Bet
|
|
61
|
-
create_successful_bet_result = send_transaction(
|
|
62
|
-
account_1,
|
|
63
|
-
contract_address,
|
|
64
|
-
"create_bet",
|
|
65
|
-
["2024-06-20", "Spain", "Italy", "1"],
|
|
66
|
-
)
|
|
67
|
-
assert has_success_status(create_successful_bet_result)
|
|
68
|
-
assert_dict_struct(
|
|
69
|
-
create_successful_bet_result,
|
|
70
|
-
execute_icontract_function_response_structure,
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
# Get Bets
|
|
74
|
-
get_bet_result = call_contract_method(contract_address, account_1, "get_bets", [])
|
|
75
|
-
print("~ ~ ~ ~ ~ get_bet_result", get_bet_result)
|
|
76
|
-
assert get_bet_result == {account_1.address: test_football_bets_win_unresolved}
|
|
77
|
-
|
|
78
|
-
# Resolve Successful Bet
|
|
79
|
-
resolve_successful_bet_result = send_transaction(
|
|
80
|
-
account_1, contract_address, "resolve_bet", ["2024-06-20_spain_italy"]
|
|
81
|
-
)
|
|
82
|
-
assert has_success_status(resolve_successful_bet_result)
|
|
83
|
-
assert_dict_struct(
|
|
84
|
-
resolve_successful_bet_result,
|
|
85
|
-
execute_icontract_function_response_structure,
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
# Get Bets
|
|
89
|
-
get_bet_result = call_contract_method(contract_address, account_1, "get_bets", [])
|
|
90
|
-
assert get_bet_result == {account_1.address: test_football_bets_win_resolved}
|
|
91
|
-
|
|
92
|
-
# Get Points
|
|
93
|
-
get_points_result = call_contract_method(
|
|
94
|
-
contract_address, account_1, "get_points", []
|
|
95
|
-
)
|
|
96
|
-
assert get_points_result == {account_1.address: 1}
|
|
97
|
-
|
|
98
|
-
# Get Player Points
|
|
99
|
-
get_player_points_result = call_contract_method(
|
|
100
|
-
contract_address, account_1, "get_player_points", [account_1.address]
|
|
101
|
-
)
|
|
102
|
-
assert get_player_points_result == 1
|
|
103
|
-
|
|
104
|
-
# Delete Validators - not needed for studio.genlayer.com
|
|
105
|
-
# delete_validators_result = post_request(payload("sim_deleteAllValidators")).json()
|
|
106
|
-
# assert has_success_status(delete_validators_result)
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# tests/e2e/test_wizard_of_coin.py
|
|
2
|
-
|
|
3
|
-
from tools.accounts import create_new_account
|
|
4
|
-
from tools.request import (
|
|
5
|
-
deploy_intelligent_contract,
|
|
6
|
-
send_transaction,
|
|
7
|
-
call_contract_method,
|
|
8
|
-
payload,
|
|
9
|
-
post_request,
|
|
10
|
-
)
|
|
11
|
-
from tools.structure import execute_icontract_function_response_structure
|
|
12
|
-
from tools.response import (
|
|
13
|
-
assert_dict_struct,
|
|
14
|
-
assert_dict_exact,
|
|
15
|
-
has_success_status,
|
|
16
|
-
)
|
|
17
|
-
from test.football_bets_get_contract_schema_for_code import (
|
|
18
|
-
football_bets_contract_schema,
|
|
19
|
-
test_football_bets_unsuccess_unresolved,
|
|
20
|
-
test_football_bets_unsuccess_resolved,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def test_football_bets_unsuccess():
|
|
25
|
-
# Account
|
|
26
|
-
account_1 = create_new_account()
|
|
27
|
-
# Validators - not needed for studio.genlayer.com
|
|
28
|
-
# result = post_request(
|
|
29
|
-
# payload("sim_createRandomValidators", 5, 8, 12, ["openai"], ["gpt-4o"])
|
|
30
|
-
# ).json()
|
|
31
|
-
# assert has_success_status(result)
|
|
32
|
-
|
|
33
|
-
# Contract Schema
|
|
34
|
-
contract_code = open("contracts/football_bet_market.py", "r").read()
|
|
35
|
-
result_schema = post_request(
|
|
36
|
-
payload("gen_getContractSchemaForCode", contract_code)
|
|
37
|
-
).json()
|
|
38
|
-
assert has_success_status(result_schema)
|
|
39
|
-
assert_dict_exact(result_schema, football_bets_contract_schema)
|
|
40
|
-
|
|
41
|
-
# Contract Deploy
|
|
42
|
-
contract_address, transaction_response_deploy = deploy_intelligent_contract(
|
|
43
|
-
account_1,
|
|
44
|
-
contract_code,
|
|
45
|
-
"{}",
|
|
46
|
-
)
|
|
47
|
-
assert has_success_status(transaction_response_deploy)
|
|
48
|
-
|
|
49
|
-
# Get Initial State
|
|
50
|
-
contract_all_points_state = call_contract_method(
|
|
51
|
-
contract_address, account_1, "get_points", []
|
|
52
|
-
)
|
|
53
|
-
assert contract_all_points_state == {}
|
|
54
|
-
|
|
55
|
-
contract_all_bets_state = call_contract_method(
|
|
56
|
-
contract_address, account_1, "get_bets", []
|
|
57
|
-
)
|
|
58
|
-
assert contract_all_bets_state == {}
|
|
59
|
-
|
|
60
|
-
# Create Successful Bet
|
|
61
|
-
create_successful_bet_result = send_transaction(
|
|
62
|
-
account_1,
|
|
63
|
-
contract_address,
|
|
64
|
-
"create_bet",
|
|
65
|
-
["2024-06-20", "Spain", "Italy", "2"],
|
|
66
|
-
)
|
|
67
|
-
assert has_success_status(create_successful_bet_result)
|
|
68
|
-
assert_dict_struct(
|
|
69
|
-
create_successful_bet_result,
|
|
70
|
-
execute_icontract_function_response_structure,
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
# Get Bets
|
|
74
|
-
get_bet_result = call_contract_method(contract_address, account_1, "get_bets", [])
|
|
75
|
-
assert get_bet_result == {
|
|
76
|
-
account_1.address: test_football_bets_unsuccess_unresolved
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
# Resolve Successful Bet
|
|
80
|
-
resolve_successful_bet_result = send_transaction(
|
|
81
|
-
account_1, contract_address, "resolve_bet", ["2024-06-20_spain_italy"]
|
|
82
|
-
)
|
|
83
|
-
assert has_success_status(resolve_successful_bet_result)
|
|
84
|
-
assert_dict_struct(
|
|
85
|
-
resolve_successful_bet_result,
|
|
86
|
-
execute_icontract_function_response_structure,
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
# Get Bets
|
|
90
|
-
get_bet_result = call_contract_method(contract_address, account_1, "get_bets", [])
|
|
91
|
-
assert get_bet_result == {account_1.address: test_football_bets_unsuccess_resolved}
|
|
92
|
-
|
|
93
|
-
# Get Points
|
|
94
|
-
get_points_result = call_contract_method(
|
|
95
|
-
contract_address, account_1, "get_points", []
|
|
96
|
-
)
|
|
97
|
-
assert get_points_result == {}
|
|
98
|
-
|
|
99
|
-
# Get Player Points
|
|
100
|
-
get_player_points_result = call_contract_method(
|
|
101
|
-
contract_address, account_1, "get_player_points", [account_1.address]
|
|
102
|
-
)
|
|
103
|
-
assert get_player_points_result == 0
|
|
104
|
-
|
|
105
|
-
# Delete Validators - not needed for studio.genlayer.com
|
|
106
|
-
# delete_validators_result = post_request(payload("sim_deleteAllValidators")).json()
|
|
107
|
-
# assert has_success_status(delete_validators_result)
|