mm-eth 0.5.17__py3-none-any.whl → 0.6.1__py3-none-any.whl
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.
- mm_eth/abi.py +2 -4
- mm_eth/account.py +51 -18
- mm_eth/anvil.py +8 -8
- mm_eth/cli/calcs.py +1 -16
- mm_eth/cli/cli.py +55 -159
- mm_eth/cli/cli_utils.py +14 -27
- mm_eth/cli/cmd/balance_cmd.py +15 -16
- mm_eth/cli/cmd/balances_cmd.py +35 -36
- mm_eth/cli/cmd/deploy_cmd.py +9 -11
- mm_eth/cli/cmd/node_cmd.py +20 -15
- mm_eth/cli/cmd/solc_cmd.py +7 -6
- mm_eth/cli/cmd/transfer_cmd.py +210 -128
- mm_eth/cli/cmd/wallet/private_key_cmd.py +5 -4
- mm_eth/cli/rpc_helpers.py +32 -115
- mm_eth/cli/validators.py +13 -16
- mm_eth/converters.py +56 -0
- mm_eth/erc20.py +6 -224
- mm_eth/retry.py +153 -0
- mm_eth/rpc.py +230 -428
- mm_eth/solc.py +30 -17
- mm_eth/tx.py +8 -9
- mm_eth/utils.py +0 -224
- {mm_eth-0.5.17.dist-info → mm_eth-0.6.1.dist-info}/METADATA +3 -2
- mm_eth-0.6.1.dist-info/RECORD +33 -0
- mm_eth/async_rpc.py +0 -94
- mm_eth/cli/cmd/call_contract_cmd.py +0 -44
- mm_eth/cli/cmd/encode_input_data_cmd.py +0 -10
- mm_eth/cli/cmd/example_cmd.py +0 -9
- mm_eth/cli/cmd/rpc_cmd.py +0 -78
- mm_eth/cli/cmd/token_cmd.py +0 -29
- mm_eth/cli/cmd/tx_cmd.py +0 -16
- mm_eth/cli/cmd/vault_cmd.py +0 -19
- mm_eth/cli/examples/balances.toml +0 -18
- mm_eth/cli/examples/call_contract.toml +0 -9
- mm_eth/cli/examples/transfer.toml +0 -46
- mm_eth/cli/print_helpers.py +0 -37
- mm_eth/constants.py +0 -1
- mm_eth/ens.py +0 -106
- mm_eth/ethernodes.py +0 -34
- mm_eth/json_encoder.py +0 -15
- mm_eth/rpc_async.py +0 -160
- mm_eth/vault.py +0 -38
- mm_eth-0.5.17.dist-info/RECORD +0 -49
- {mm_eth-0.5.17.dist-info → mm_eth-0.6.1.dist-info}/WHEEL +0 -0
- {mm_eth-0.5.17.dist-info → mm_eth-0.6.1.dist-info}/entry_points.txt +0 -0
mm_eth/cli/cmd/balances_cmd.py
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Annotated
|
|
3
3
|
|
|
4
|
-
from mm_std import BaseConfig,
|
|
4
|
+
from mm_std import BaseConfig, fatal
|
|
5
5
|
from pydantic import BeforeValidator
|
|
6
6
|
from rich.live import Live
|
|
7
7
|
from rich.table import Table
|
|
8
8
|
|
|
9
|
-
from mm_eth import
|
|
9
|
+
from mm_eth import converters, retry
|
|
10
10
|
from mm_eth.cli.cli_utils import BaseConfigParams
|
|
11
11
|
from mm_eth.cli.validators import Validators
|
|
12
|
-
from mm_eth.utils import from_token_wei_str, from_wei_str
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class Config(BaseConfig):
|
|
@@ -31,12 +30,12 @@ class BalancesCmdParams(BaseConfigParams):
|
|
|
31
30
|
show_nonce: bool
|
|
32
31
|
|
|
33
32
|
|
|
34
|
-
def run(params: BalancesCmdParams) -> None:
|
|
33
|
+
async def run(params: BalancesCmdParams) -> None:
|
|
35
34
|
config = Config.read_toml_config_or_exit(params.config_path)
|
|
36
35
|
if params.print_config:
|
|
37
36
|
config.print_and_exit()
|
|
38
37
|
|
|
39
|
-
tokens = _get_tokens_info(config)
|
|
38
|
+
tokens = await _get_tokens_info(config)
|
|
40
39
|
|
|
41
40
|
table = Table(title="balances")
|
|
42
41
|
table.add_column("address")
|
|
@@ -52,36 +51,33 @@ def run(params: BalancesCmdParams) -> None:
|
|
|
52
51
|
for address in config.addresses:
|
|
53
52
|
row = [address]
|
|
54
53
|
if params.show_nonce:
|
|
55
|
-
|
|
54
|
+
nonce = await retry.eth_get_transaction_count(5, config.nodes, None, address=address)
|
|
55
|
+
row.append(str(nonce.value_or_error()))
|
|
56
56
|
|
|
57
|
-
base_balance_res =
|
|
58
|
-
if
|
|
59
|
-
|
|
57
|
+
base_balance_res = await retry.eth_get_balance(5, config.nodes, None, address=address)
|
|
58
|
+
if base_balance_res.is_ok():
|
|
59
|
+
balance = base_balance_res.unwrap()
|
|
60
|
+
base_sum += balance
|
|
60
61
|
if params.wei:
|
|
61
|
-
row.append(str(
|
|
62
|
+
row.append(str(balance))
|
|
62
63
|
else:
|
|
63
|
-
row.append(
|
|
64
|
-
from_wei_str(base_balance_res.ok, "eth", round_ndigits=config.round_ndigits, print_unit_name=False),
|
|
65
|
-
)
|
|
64
|
+
row.append(str(converters.from_wei(balance, "eth", round_ndigits=config.round_ndigits)))
|
|
66
65
|
else:
|
|
67
|
-
row.append(base_balance_res.
|
|
66
|
+
row.append(base_balance_res.unwrap_error())
|
|
68
67
|
|
|
69
68
|
for t in tokens:
|
|
70
|
-
token_balance_res =
|
|
71
|
-
if
|
|
72
|
-
|
|
69
|
+
token_balance_res = await retry.erc20_balance(5, config.nodes, None, token=t.address, wallet=address)
|
|
70
|
+
if token_balance_res.is_ok():
|
|
71
|
+
token_balance = token_balance_res.unwrap()
|
|
72
|
+
token_sum[t.address] += token_balance
|
|
73
73
|
if params.wei:
|
|
74
|
-
row.append(str(
|
|
74
|
+
row.append(str(token_balance))
|
|
75
75
|
else:
|
|
76
76
|
row.append(
|
|
77
|
-
|
|
78
|
-
token_balance_res.ok,
|
|
79
|
-
decimals=t.decimals,
|
|
80
|
-
round_ndigits=config.round_ndigits,
|
|
81
|
-
),
|
|
77
|
+
str(converters.from_wei(token_balance, "t", round_ndigits=config.round_ndigits, decimals=t.decimals))
|
|
82
78
|
)
|
|
83
79
|
else:
|
|
84
|
-
row.append(token_balance_res.
|
|
80
|
+
row.append(token_balance_res.unwrap_error())
|
|
85
81
|
|
|
86
82
|
table.add_row(*row)
|
|
87
83
|
|
|
@@ -92,26 +88,29 @@ def run(params: BalancesCmdParams) -> None:
|
|
|
92
88
|
sum_row.append(str(base_sum))
|
|
93
89
|
sum_row.extend([str(token_sum[t.address]) for t in tokens])
|
|
94
90
|
else:
|
|
95
|
-
sum_row.append(
|
|
91
|
+
sum_row.append(str(converters.from_wei(base_sum, "eth", round_ndigits=config.round_ndigits)))
|
|
96
92
|
sum_row.extend(
|
|
97
|
-
[
|
|
93
|
+
[
|
|
94
|
+
str(converters.from_wei(token_sum[t.address], "t", round_ndigits=config.round_ndigits, decimals=t.decimals))
|
|
95
|
+
for t in tokens
|
|
96
|
+
]
|
|
98
97
|
)
|
|
99
98
|
|
|
100
99
|
table.add_row(*sum_row)
|
|
101
100
|
|
|
102
101
|
|
|
103
|
-
def _get_tokens_info(config: Config) -> list[Token]:
|
|
102
|
+
async def _get_tokens_info(config: Config) -> list[Token]:
|
|
104
103
|
result: list[Token] = []
|
|
105
104
|
for address in config.tokens:
|
|
106
|
-
decimals_res =
|
|
107
|
-
if
|
|
108
|
-
fatal(f"can't get token {address} decimals: {decimals_res.
|
|
109
|
-
decimal = decimals_res.
|
|
110
|
-
|
|
111
|
-
symbols_res =
|
|
112
|
-
if
|
|
113
|
-
fatal(f"can't get token {address} symbol: {symbols_res.
|
|
114
|
-
symbol = symbols_res.
|
|
105
|
+
decimals_res = await retry.erc20_decimals(5, config.nodes, None, token=address)
|
|
106
|
+
if decimals_res.is_err():
|
|
107
|
+
fatal(f"can't get token {address} decimals: {decimals_res.unwrap_error()}")
|
|
108
|
+
decimal = decimals_res.unwrap()
|
|
109
|
+
|
|
110
|
+
symbols_res = await retry.erc20_symbol(5, config.nodes, None, token=address)
|
|
111
|
+
if symbols_res.is_err():
|
|
112
|
+
fatal(f"can't get token {address} symbol: {symbols_res.unwrap_error()}")
|
|
113
|
+
symbol = symbols_res.unwrap()
|
|
115
114
|
|
|
116
115
|
result.append(Token(address=address, decimals=decimal, symbol=symbol))
|
|
117
116
|
|
mm_eth/cli/cmd/deploy_cmd.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import yaml
|
|
2
|
-
from mm_std import BaseConfig
|
|
2
|
+
from mm_std import BaseConfig
|
|
3
3
|
from pydantic import StrictStr
|
|
4
4
|
|
|
5
|
-
from mm_eth import account, deploy
|
|
6
|
-
from mm_eth.cli import rpc_helpers
|
|
5
|
+
from mm_eth import account, deploy, retry
|
|
7
6
|
from mm_eth.cli.cli_utils import BaseConfigParams
|
|
8
7
|
|
|
9
8
|
|
|
@@ -22,10 +21,10 @@ class Config(BaseConfig):
|
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
class DeployCmdParams(BaseConfigParams):
|
|
25
|
-
|
|
24
|
+
broadcast: bool = False
|
|
26
25
|
|
|
27
26
|
|
|
28
|
-
def run(cli_params: DeployCmdParams) -> None:
|
|
27
|
+
async def run(cli_params: DeployCmdParams) -> None:
|
|
29
28
|
config = Config.read_toml_config_or_exit(cli_params.config_path)
|
|
30
29
|
if cli_params.print_config:
|
|
31
30
|
config.print_and_exit({"private_key"})
|
|
@@ -33,12 +32,11 @@ def run(cli_params: DeployCmdParams) -> None:
|
|
|
33
32
|
constructor_types = yaml.full_load(config.constructor_types)
|
|
34
33
|
constructor_values = yaml.full_load(config.constructor_values)
|
|
35
34
|
|
|
36
|
-
sender_address = account.private_to_address(config.private_key)
|
|
37
|
-
if sender_address is None:
|
|
38
|
-
fatal("private address is wrong")
|
|
35
|
+
sender_address = account.private_to_address(config.private_key).unwrap()
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
if config.nonce is None:
|
|
38
|
+
config.nonce = (await retry.eth_get_transaction_count(5, config.node, None, address=sender_address)).unwrap(
|
|
39
|
+
"can't get nonce"
|
|
40
|
+
)
|
|
43
41
|
|
|
44
42
|
deploy.get_deploy_contract_data(config.contract_bin, constructor_types, constructor_values)
|
mm_eth/cli/cmd/node_cmd.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
3
|
+
import eth_utils
|
|
1
4
|
import pydash
|
|
2
|
-
from mm_std import
|
|
5
|
+
from mm_std import PrintFormat, print_json
|
|
3
6
|
from pydantic import BaseModel
|
|
4
7
|
from rich.live import Live
|
|
5
8
|
from rich.table import Table
|
|
6
9
|
|
|
7
|
-
from mm_eth import rpc
|
|
8
|
-
from mm_eth.utils import from_wei_str, name_network
|
|
10
|
+
from mm_eth import rpc, utils
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class NodeInfo(BaseModel):
|
|
@@ -13,7 +15,7 @@ class NodeInfo(BaseModel):
|
|
|
13
15
|
chain_id: int | str
|
|
14
16
|
chain_name: str
|
|
15
17
|
block_number: int | str
|
|
16
|
-
base_fee: str
|
|
18
|
+
base_fee: str | int | Decimal
|
|
17
19
|
|
|
18
20
|
def table_row(self) -> list[object]:
|
|
19
21
|
return [self.url, self.chain_id, self.chain_name, self.block_number, self.base_fee]
|
|
@@ -40,7 +42,7 @@ class LiveTable:
|
|
|
40
42
|
self.live.stop()
|
|
41
43
|
|
|
42
44
|
|
|
43
|
-
def run(urls: list[str], proxy: str | None, print_format: PrintFormat) -> None:
|
|
45
|
+
async def run(urls: list[str], proxy: str | None, print_format: PrintFormat) -> None:
|
|
44
46
|
urls = pydash.uniq(urls)
|
|
45
47
|
result = []
|
|
46
48
|
live_table = LiveTable(
|
|
@@ -48,7 +50,7 @@ def run(urls: list[str], proxy: str | None, print_format: PrintFormat) -> None:
|
|
|
48
50
|
ignore=print_format != PrintFormat.TABLE,
|
|
49
51
|
)
|
|
50
52
|
for url in urls:
|
|
51
|
-
node_info = _get_node_info(url, proxy)
|
|
53
|
+
node_info = await _get_node_info(url, proxy)
|
|
52
54
|
live_table.add_row(*node_info.table_row())
|
|
53
55
|
result.append(node_info)
|
|
54
56
|
|
|
@@ -64,15 +66,18 @@ def run(urls: list[str], proxy: str | None, print_format: PrintFormat) -> None:
|
|
|
64
66
|
# table.add_row(url, str(chain_id), chain_name, str(block_number), base_fee)
|
|
65
67
|
|
|
66
68
|
|
|
67
|
-
def _get_node_info(url: str, proxy: str | None) -> NodeInfo:
|
|
68
|
-
chain_id_res = rpc.eth_chain_id(url,
|
|
69
|
-
chain_id = chain_id_res.
|
|
69
|
+
async def _get_node_info(url: str, proxy: str | None) -> NodeInfo:
|
|
70
|
+
chain_id_res = await rpc.eth_chain_id(url, proxy=proxy)
|
|
71
|
+
chain_id = chain_id_res.value_or_error()
|
|
70
72
|
chain_name = ""
|
|
71
|
-
if
|
|
72
|
-
chain_name = name_network(chain_id_res.
|
|
73
|
-
block_number = rpc.eth_block_number(url,
|
|
74
|
-
base_fee =
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
if chain_id_res.is_ok():
|
|
74
|
+
chain_name = utils.name_network(chain_id_res.unwrap())
|
|
75
|
+
block_number = (await rpc.eth_block_number(url, proxy=proxy)).value_or_error()
|
|
76
|
+
base_fee = (
|
|
77
|
+
(await rpc.get_base_fee_per_gas(url, proxy=proxy))
|
|
78
|
+
.map(
|
|
79
|
+
lambda ok: eth_utils.from_wei(ok, "gwei"),
|
|
80
|
+
)
|
|
81
|
+
.value_or_error()
|
|
77
82
|
)
|
|
78
83
|
return NodeInfo(url=url, chain_id=chain_id, chain_name=chain_name, block_number=block_number, base_fee=base_fee)
|
mm_eth/cli/cmd/solc_cmd.py
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import json
|
|
2
|
+
from pathlib import Path
|
|
2
3
|
|
|
3
|
-
from mm_std import
|
|
4
|
+
from mm_std import PrintFormat, fatal, print_json, print_plain
|
|
4
5
|
from mm_std.fs import get_filename_without_extension
|
|
5
6
|
|
|
6
7
|
from mm_eth.solc import solc
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
def run(contract_path:
|
|
10
|
+
def run(contract_path: Path, tmp_dir: Path, print_format: PrintFormat) -> None:
|
|
10
11
|
contract_name = get_filename_without_extension(contract_path)
|
|
11
12
|
res = solc(contract_name, contract_path, tmp_dir)
|
|
12
|
-
if
|
|
13
|
-
fatal(res.
|
|
13
|
+
if res.is_err():
|
|
14
|
+
fatal(res.unwrap_error())
|
|
14
15
|
|
|
15
|
-
bin_ = res.
|
|
16
|
-
abi = res.
|
|
16
|
+
bin_ = res.unwrap().bin
|
|
17
|
+
abi = res.unwrap().abi
|
|
17
18
|
|
|
18
19
|
if print_format == PrintFormat.JSON:
|
|
19
20
|
print_json({"bin": bin_, "abi": json.loads(abi)})
|