Skip to content

Commit c514b4d

Browse files
authored
Merge pull request #9 from ElrondNetwork/legolas-addons
Add-ons for internal tests / legolas
2 parents c772676 + a6adc73 commit c514b4d

12 files changed

Lines changed: 118 additions & 44 deletions

File tree

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22
dist
33
__pycache__
44
*.egg-info
5+
*.py[cod]
6+
*$py.class
7+
.pytest_cache/
8+
9+
# mypy
10+
.mypy_cache/
11+
12+
# Tags generated by ctags
13+
tags

erdpy/contracts.py

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
import base64
22
import logging
3-
from typing import Any, List
3+
from typing import Any, List, Optional
44

55
from Cryptodome.Hash import keccak
66

77
from erdpy import config, constants, errors, utils
8-
from erdpy.accounts import Address
8+
from erdpy.accounts import Account, Address
9+
from erdpy.interfaces import IElrondProxy
910
from erdpy.transactions import Transaction
1011

1112
logger = logging.getLogger("contracts")
1213

1314

1415
class SmartContract:
15-
def __init__(self, address=None, bytecode=None, metadata=None):
16+
def __init__(self, address: Optional[Address] = None, bytecode=None, metadata=None):
1617
self.address = Address(address)
1718
self.bytecode = bytecode
1819
self.metadata = metadata or CodeMetadata()
1920

20-
def deploy(self, owner, arguments, gas_price, gas_limit, value, chain, version) -> Transaction:
21+
def deploy(self, owner: Account, arguments: List[Any], gas_price: int, gas_limit: int, value: int, chain: str, version: int) -> Transaction:
2122
self.owner = owner
2223
self.compute_address()
2324

2425
arguments = arguments or []
2526
gas_price = int(gas_price)
2627
gas_limit = int(gas_limit)
27-
value = str(value or "0")
28+
value = value or 0
2829

2930
tx = Transaction()
3031
tx.nonce = owner.nonce
31-
tx.value = value
32+
tx.value = str(value)
3233
tx.sender = owner.address.bech32()
3334
tx.receiver = Address.zero().bech32()
3435
tx.gasPrice = gas_price
@@ -40,7 +41,7 @@ def deploy(self, owner, arguments, gas_price, gas_limit, value, chain, version)
4041
tx.sign(owner)
4142
return tx
4243

43-
def prepare_deploy_transaction_data(self, arguments):
44+
def prepare_deploy_transaction_data(self, arguments: List[Any]):
4445
tx_data = f"{self.bytecode}@{constants.VM_TYPE_ARWEN}@{self.metadata.to_hex()}"
4546

4647
for arg in arguments:
@@ -59,17 +60,17 @@ def compute_address(self):
5960
address = bytes([0] * 8) + bytes([5, 0]) + address[10:30] + owner_bytes[30:]
6061
self.address = Address(address)
6162

62-
def execute(self, caller, function, arguments, gas_price, gas_limit, value, chain, version) -> Transaction:
63+
def execute(self, caller: Account, function: str, arguments: List[str], gas_price: int, gas_limit: int, value: int, chain: str, version: int) -> Transaction:
6364
self.caller = caller
6465

6566
arguments = arguments or []
6667
gas_price = int(gas_price)
6768
gas_limit = int(gas_limit)
68-
value = str(value or "0")
69+
value = value or 0
6970

7071
tx = Transaction()
7172
tx.nonce = caller.nonce
72-
tx.value = value
73+
tx.value = str(value)
7374
tx.sender = caller.address.bech32()
7475
tx.receiver = self.address.bech32()
7576
tx.gasPrice = gas_price
@@ -81,25 +82,25 @@ def execute(self, caller, function, arguments, gas_price, gas_limit, value, chai
8182
tx.sign(caller)
8283
return tx
8384

84-
def prepare_execute_transaction_data(self, function, arguments):
85+
def prepare_execute_transaction_data(self, function: str, arguments: List[Any]):
8586
tx_data = function
8687

8788
for arg in arguments:
8889
tx_data += f"@{_prepare_argument(arg)}"
8990

9091
return tx_data
9192

92-
def upgrade(self, owner, arguments, gas_price, gas_limit, value, chain, version) -> Transaction:
93+
def upgrade(self, owner: Account, arguments: List[Any], gas_price: int, gas_limit: int, value: int, chain: str, version: int) -> Transaction:
9394
self.owner = owner
9495

9596
arguments = arguments or []
9697
gas_price = int(gas_price or config.DEFAULT_GAS_PRICE)
9798
gas_limit = int(gas_limit)
98-
value = str(value or "0")
99+
value = value or 0
99100

100101
tx = Transaction()
101102
tx.nonce = owner.nonce
102-
tx.value = value
103+
tx.value = str(value)
103104
tx.sender = owner.address.bech32()
104105
tx.receiver = self.address.bech32()
105106
tx.gasPrice = gas_price
@@ -111,30 +112,38 @@ def upgrade(self, owner, arguments, gas_price, gas_limit, value, chain, version)
111112
tx.sign(owner)
112113
return tx
113114

114-
def prepare_upgrade_transaction_data(self, arguments):
115+
def prepare_upgrade_transaction_data(self, arguments: List[Any]):
115116
tx_data = f"upgradeContract@{self.bytecode}@{self.metadata.to_hex()}"
116117

117118
for arg in arguments:
118119
tx_data += f"@{_prepare_argument(arg)}"
119120

120121
return tx_data
121122

122-
def query(self, proxy, function, arguments) -> List[Any]:
123+
def query(self, proxy: IElrondProxy, function: str, arguments: List[Any], value: int = 0, caller: Optional[Address] = None) -> List[Any]:
124+
response_data = self.query_detailed(proxy, function, arguments, value, caller)
125+
return_data = response_data.get("returnData", []) or response_data.get("ReturnData", [])
126+
return [self._interpret_return_data(data) for data in return_data]
127+
128+
def query_detailed(self, proxy: IElrondProxy, function: str, arguments: List[Any], value: int = 0, caller: Optional[Address] = None) -> Any:
123129
arguments = arguments or []
124130
prepared_arguments = [_prepare_argument(argument) for argument in arguments]
125131

126132
payload = {
127-
"ScAddress": self.address.bech32(),
128-
"FuncName": function,
129-
"Args": prepared_arguments
133+
"scAddress": self.address.bech32(),
134+
"funcName": function,
135+
"args": prepared_arguments,
136+
"value": str(value)
130137
}
131138

139+
if caller:
140+
payload["caller"] = caller.bech32()
141+
132142
response = proxy.query_contract(payload)
133143
response_data = response.get("data", {})
134-
return_data = response_data.get("returnData", response_data.get("ReturnData")) or []
135-
return [self._interpret_return_data(data) for data in return_data]
144+
return response_data
136145

137-
def _interpret_return_data(self, data):
146+
def _interpret_return_data(self, data: Any) -> Any:
138147
if not data:
139148
return data
140149

@@ -153,7 +162,7 @@ def _interpret_return_data(self, data):
153162
return None
154163

155164

156-
def _prepare_argument(argument):
165+
def _prepare_argument(argument: Any):
157166
hex_prefix = "0X"
158167
as_string = str(argument).upper()
159168

@@ -172,7 +181,7 @@ def _prepare_argument(argument):
172181

173182

174183
class CodeMetadata:
175-
def __init__(self, upgradeable=True, payable=False):
184+
def __init__(self, upgradeable: bool = True, payable: bool = False):
176185
self.upgradeable = upgradeable
177186
self.payable = payable
178187

erdpy/interfaces.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,8 @@ def send_transaction(self, payload: Any) -> str:
3939
def send_transactions(self, payload: List[Any]) -> Tuple[int, List[str]]:
4040
return 0, []
4141

42-
def send_transaction_and_wait_for_result(self, payload: Any, num_seconds_timeout) -> str:
42+
def send_transaction_and_wait_for_result(self, payload: Any, num_seconds_timeout: int) -> str:
4343
return ""
44+
45+
def query_contract(self, payload: Any) -> Any:
46+
return dict()

erdpy/projects/project_base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import shutil
44
from os import path
55
from pathlib import Path
6-
from typing import List, cast
6+
from typing import Any, Dict, List, Union, cast
77

88
from erdpy import dependencies, errors, myprocess, utils
99
from erdpy.dependencies.modules import StandaloneModule
@@ -14,11 +14,11 @@
1414
# TODO use pathlib.Path everywhere
1515
class Project:
1616

17-
def __init__(self, directory):
17+
def __init__(self, directory: Union[Path, str]):
1818
self.path = Path(directory).expanduser().resolve()
1919
self.directory = str(self.path)
2020

21-
def build(self, options=None):
21+
def build(self, options: Union[Dict[str, Any], None] = None):
2222
self.options = options or dict()
2323
self.debug = self.options.get("debug", False)
2424
self._ensure_dependencies_installed()

erdpy/projects/templates.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import logging
33
import os
44
from os import path
5+
from pathlib import Path
6+
from typing import Union
57

68
from erdpy import errors, utils
79
from erdpy.projects import shared
@@ -33,7 +35,7 @@ def __init__(self, name, repository):
3335
self.language = repository.get_language(name)
3436

3537

36-
def create_from_template(name: str, template_name: str, directory: str):
38+
def create_from_template(name: str, template_name: str, directory: Union[Path, str]):
3739
directory = path.expanduser(directory)
3840

3941
logger.info("create_from_template.name: %s", name)

erdpy/proxy/core.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from typing import Any, List, Tuple
44

55
from erdpy.accounts import Address
6+
from erdpy.interfaces import IAddress
67
from erdpy.proxy.http_facade import do_get, do_post
78
from erdpy.proxy.messages import NetworkConfig
89

@@ -16,19 +17,19 @@ class ElrondProxy:
1617
def __init__(self, url: str):
1718
self.url = url
1819

19-
def get_account_nonce(self, address: Address) -> int:
20+
def get_account_nonce(self, address: IAddress) -> int:
2021
url = f"{self.url}/address/{address.bech32()}"
2122
response = do_get(url)
2223
nonce = response.get("account").get("nonce", 0)
2324
return int(nonce)
2425

25-
def get_account_balance(self, address: Address):
26+
def get_account_balance(self, address: IAddress):
2627
url = f"{self.url}/address/{address.bech32()}/balance"
2728
response = do_get(url)
2829
balance = response.get("balance", 0)
2930
return int(balance)
3031

31-
def get_account(self, address: Address):
32+
def get_account(self, address: IAddress):
3233
url = f"{self.url}/address/{address.bech32()}"
3334
response = do_get(url)
3435
account = response.get("account", dict())
@@ -48,12 +49,16 @@ def get_account_transactions(self, address: Address):
4849

4950
def get_esdt_tokens(self, address: str) -> List:
5051
response = do_get(f"{self.url}/address/{address}/esdt")
51-
return response.get("tokens")
52+
return response.get("esdts")
5253

5354
def get_esdt_balance(self, address: str, ticker: str) -> dict:
5455
response = do_get(f"{self.url}/address/{address}/esdt/{ticker}")
5556
return response.get("tokenData")
5657

58+
def get_all_tokens(self) -> List[str]:
59+
response = do_get(f"{self.url}/network/esdts")
60+
return response.get("tokens", [])
61+
5762
def get_num_shards(self):
5863
network_config = self.get_network_config()
5964
return network_config.num_shards
@@ -107,7 +112,7 @@ def send_transactions(self, payload: List[Any]) -> Tuple[int, List[str]]:
107112
hashes = response.get("txsHashes")
108113
return num_sent, hashes
109114

110-
def query_contract(self, payload: Any):
115+
def query_contract(self, payload: Any) -> Any:
111116
url = f"{self.url}/vm-values/query"
112117
response = do_post(url, payload)
113118
return response
@@ -131,7 +136,7 @@ def get_hyperblock(self, key) -> Any:
131136
response = response.get("hyperblock", {})
132137
return response
133138

134-
def send_transaction_and_wait_for_result(self, payload: Any, num_seconds_timeout=100) -> str:
139+
def send_transaction_and_wait_for_result(self, payload: Any, num_seconds_timeout: int = 100) -> str:
135140
url = f"{self.url}/transaction/send"
136141
response = do_post(url, payload)
137142
tx_hash = response.get("txHash")

erdpy/proxy/messages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ class NetworkConfig:
55
def __init__(self, data: Dict[str, Any]) -> None:
66
self.num_shards = data.get("erd_num_shards_without_meta", 0)
77
self.min_gas_price = data.get("erd_min_gas_price", 0)
8-
self.chain_id = data.get("erd_chain_id", 0)
8+
self.chain_id = data.get("erd_chain_id", "?")
99
self.min_tx_version = data.get("erd_min_transaction_version", 0)

erdpy/transactions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import logging
44
from collections import OrderedDict
5-
from typing import Any, Dict
5+
from typing import Any, Dict, List
66

77
from erdpy import errors, utils
88
from erdpy.accounts import Account, Address
@@ -171,7 +171,7 @@ def wrap_inner(self, inner: ITransaction) -> None:
171171

172172
class BunchOfTransactions:
173173
def __init__(self):
174-
self.transactions = []
174+
self.transactions: List[Transaction] = []
175175

176176
def add_prepared(self, transaction: Transaction):
177177
self.transactions.append(transaction)

erdpy/utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import tarfile
1010
import zipfile
1111
from pathlib import Path
12-
from typing import Any, Dict, List, Union
12+
from typing import Any, List, Union, Optional
1313

1414
import toml
1515

@@ -75,7 +75,7 @@ def read_lines(file: str):
7575
return lines
7676

7777

78-
def read_file(f: Any, binary=False) -> Union[str, bytes]:
78+
def read_file(f: Any, binary: bool = False) -> Union[str, bytes]:
7979
try:
8080
mode = "rb" if binary else "r"
8181
if isinstance(f, str) or isinstance(f, pathlib.PosixPath):
@@ -102,7 +102,7 @@ def write_toml_file(filename, data):
102102
toml.dump(data, f)
103103

104104

105-
def read_json_file(filename: str) -> Dict[str, Any]:
105+
def read_json_file(filename: Union[str, Path]) -> Any:
106106
with open(filename) as f:
107107
return json.load(f)
108108

@@ -146,7 +146,7 @@ def find_in_dictionary(dictionary, compound_path):
146146
return node
147147

148148

149-
def list_files(folder: str, suffix: str = None) -> List[str]:
149+
def list_files(folder: Union[str, Path], suffix: Optional[str] = None) -> List[str]:
150150
files = os.listdir(folder)
151151
files = [os.path.join(folder, f) for f in files]
152152

@@ -156,7 +156,7 @@ def list_files(folder: str, suffix: str = None) -> List[str]:
156156
return files
157157

158158

159-
def remove_folder(folder):
159+
def remove_folder(folder: Union[str, Path]):
160160
shutil.rmtree(folder, ignore_errors=True)
161161

162162

0 commit comments

Comments
 (0)