mm-eth 0.7.2__tar.gz → 0.7.3__tar.gz
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-0.7.3/.claude/settings.local.json +10 -0
- mm_eth-0.7.3/CLAUDE.md +13 -0
- mm_eth-0.7.3/PKG-INFO +7 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/pyproject.toml +11 -11
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/abi.py +1 -2
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cli_utils.py +1 -1
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/balances_cmd.py +2 -2
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/solc_cmd.py +1 -1
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/transfer_cmd.py +6 -4
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/wallet/private_key_cmd.py +1 -1
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/rpc.py +1 -1
- mm_eth-0.7.3/uv.lock +1834 -0
- mm_eth-0.7.2/PKG-INFO +0 -7
- mm_eth-0.7.2/uv.lock +0 -1484
- {mm_eth-0.7.2 → mm_eth-0.7.3}/.gitignore +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/.pre-commit-config.yaml +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/README.md +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/dict.dic +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/justfile +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/account.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/anvil.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/calcs.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cli.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/balance_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/deploy_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/node_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/wallet/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/cmd/wallet/mnemonic_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/rpc_helpers.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/cli/validators.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/converters.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/deploy.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/erc20.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/py.typed +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/retry.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/solc.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/tx.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/src/mm_eth/utils.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/cmd/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/cmd/test_balance_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/cmd/test_node_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/cmd/test_solc_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/cmd/wallet/__init__.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/cmd/wallet/test_mnemonic_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/cli/cmd/wallet/test_private_key_cmd.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/conftest.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/contracts/ERC20.sol +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/test_abi.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/test_account.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/test_converters.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/test_rpc.py +0 -0
- {mm_eth-0.7.2 → mm_eth-0.7.3}/tests/test_tx.py +0 -0
mm_eth-0.7.3/CLAUDE.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Claude Guidelines
|
|
2
|
+
|
|
3
|
+
## Critical Guidelines
|
|
4
|
+
|
|
5
|
+
1. **Always communicate in English** - Regardless of the language the user speaks, always respond in English. All code, comments, and documentation must be in English.
|
|
6
|
+
|
|
7
|
+
2. **Minimal documentation** - Only add comments/documentation when it simplifies understanding and isn't obvious from the code itself. Keep it strictly relevant and concise.
|
|
8
|
+
|
|
9
|
+
3. **Critical thinking** - Always critically evaluate user ideas. Users can make mistakes. Think first about whether the user's idea is good before implementing.
|
|
10
|
+
|
|
11
|
+
4. **Lint after changes** - After making code changes, always run `just lint` to verify code quality and fix any linter issues.
|
|
12
|
+
|
|
13
|
+
5. **No disabling linter rules** - Never use special disabling comments (like `# noqa`, `# type: ignore`, `# ruff: noqa`, etc.) to turn off linter rules without explicit permission. If you believe a rule should be disabled, ask first.
|
mm_eth-0.7.3/PKG-INFO
ADDED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mm-eth"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.3"
|
|
4
4
|
description = ""
|
|
5
5
|
requires-python = ">=3.13"
|
|
6
6
|
dependencies = [
|
|
7
|
-
"mm-web3~=0.5.
|
|
8
|
-
"web3~=7.
|
|
9
|
-
"typer~=0.
|
|
7
|
+
"mm-web3~=0.5.4",
|
|
8
|
+
"web3~=7.14.0",
|
|
9
|
+
"typer~=0.20.0",
|
|
10
10
|
]
|
|
11
11
|
[project.scripts]
|
|
12
12
|
mm-eth = "mm_eth.cli.cli:app"
|
|
@@ -15,17 +15,17 @@ mm-eth = "mm_eth.cli.cli:app"
|
|
|
15
15
|
requires = ["hatchling"]
|
|
16
16
|
build-backend = "hatchling.build"
|
|
17
17
|
|
|
18
|
-
[
|
|
19
|
-
dev
|
|
20
|
-
"pytest~=8.4.
|
|
21
|
-
"pytest-asyncio~=1.
|
|
18
|
+
[dependency-groups]
|
|
19
|
+
dev = [
|
|
20
|
+
"pytest~=8.4.2",
|
|
21
|
+
"pytest-asyncio~=1.2.0",
|
|
22
22
|
"pytest-xdist~=3.8.0",
|
|
23
|
-
"ruff~=0.
|
|
23
|
+
"ruff~=0.14.2",
|
|
24
24
|
"pip-audit~=2.9.0",
|
|
25
25
|
"bandit~=1.8.6",
|
|
26
|
-
"mypy~=1.
|
|
26
|
+
"mypy~=1.18.2",
|
|
27
27
|
"pre-commit~=4.3.0",
|
|
28
|
-
"python-dotenv~=1.
|
|
28
|
+
"python-dotenv~=1.2.1",
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
[tool.mypy]
|
|
@@ -5,7 +5,6 @@ from typing import Any, cast
|
|
|
5
5
|
|
|
6
6
|
import eth_abi
|
|
7
7
|
import eth_utils
|
|
8
|
-
import pydash
|
|
9
8
|
from eth_typing import ABI, ABIFunction, HexStr
|
|
10
9
|
from pydantic import BaseModel
|
|
11
10
|
from web3 import Web3
|
|
@@ -62,7 +61,7 @@ def decode_function_input(contract_abi: ABI, tx_input: str) -> FunctionInput:
|
|
|
62
61
|
|
|
63
62
|
|
|
64
63
|
def get_function_abi(contr_abi: ABI, fn_name: str) -> ABIFunction:
|
|
65
|
-
abi =
|
|
64
|
+
abi = next((x for x in contr_abi if x.get("name", None) == fn_name and x.get("type", None) == "function"), None)
|
|
66
65
|
if not abi:
|
|
67
66
|
raise ValueError("can't find abi for function: " + fn_name)
|
|
68
67
|
return cast(ABIFunction, abi)
|
|
@@ -46,7 +46,7 @@ async def check_nodes_for_chain_id(nodes: list[str], chain_id: int) -> None:
|
|
|
46
46
|
for node in nodes:
|
|
47
47
|
res = (await rpc.eth_chain_id(node)).unwrap("can't get chain_id")
|
|
48
48
|
if res != chain_id:
|
|
49
|
-
mm_print.
|
|
49
|
+
mm_print.exit_with_error(f"node {node} has a wrong chain_id: {res}")
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def add_table_raw(table: Table, *row: object) -> None:
|
|
@@ -105,12 +105,12 @@ async def _get_tokens_info(config: Config) -> list[Token]:
|
|
|
105
105
|
for address in config.tokens:
|
|
106
106
|
decimals_res = await retry.erc20_decimals(5, config.nodes, None, token=address)
|
|
107
107
|
if decimals_res.is_err():
|
|
108
|
-
mm_print.
|
|
108
|
+
mm_print.exit_with_error(f"can't get token {address} decimals: {decimals_res.unwrap_err()}")
|
|
109
109
|
decimal = decimals_res.unwrap()
|
|
110
110
|
|
|
111
111
|
symbols_res = await retry.erc20_symbol(5, config.nodes, None, token=address)
|
|
112
112
|
if symbols_res.is_err():
|
|
113
|
-
mm_print.
|
|
113
|
+
mm_print.exit_with_error(f"can't get token {address} symbol: {symbols_res.unwrap_err()}")
|
|
114
114
|
symbol = symbols_res.unwrap()
|
|
115
115
|
|
|
116
116
|
result.append(Token(address=address, decimals=decimal, symbol=symbol))
|
|
@@ -11,7 +11,7 @@ def run(contract_path: Path, tmp_dir: Path, print_format: PrintFormat) -> None:
|
|
|
11
11
|
contract_name = contract_path.stem
|
|
12
12
|
res = solc(contract_name, contract_path, tmp_dir)
|
|
13
13
|
if res.is_err():
|
|
14
|
-
mm_print.
|
|
14
|
+
mm_print.exit_with_error(res.unwrap_err())
|
|
15
15
|
|
|
16
16
|
bin_ = res.unwrap().bin
|
|
17
17
|
abi = res.unwrap().abi
|
|
@@ -43,8 +43,8 @@ class Config(Web3CliConfig):
|
|
|
43
43
|
def from_addresses(self) -> list[str]:
|
|
44
44
|
return [r.from_address for r in self.transfers]
|
|
45
45
|
|
|
46
|
-
@model_validator(mode="after")
|
|
47
|
-
|
|
46
|
+
@model_validator(mode="after")
|
|
47
|
+
def final_validator(self) -> Self:
|
|
48
48
|
if not self.private_keys.contains_all_addresses(self.from_addresses):
|
|
49
49
|
raise ValueError("private keys are not set for all addresses")
|
|
50
50
|
|
|
@@ -66,13 +66,14 @@ class Config(Web3CliConfig):
|
|
|
66
66
|
if self.value_min_limit:
|
|
67
67
|
Validators.valid_eth_expression()(self.value_min_limit)
|
|
68
68
|
|
|
69
|
+
return self
|
|
70
|
+
|
|
71
|
+
async def async_init(self) -> None:
|
|
69
72
|
if self.token:
|
|
70
73
|
self.token_decimals = (await retry.erc20_decimals(5, self.nodes, self.proxies, token=self.token)).unwrap(
|
|
71
74
|
"can't get token decimals"
|
|
72
75
|
)
|
|
73
76
|
|
|
74
|
-
return self
|
|
75
|
-
|
|
76
77
|
|
|
77
78
|
class TransferCmdParams(BaseConfigParams):
|
|
78
79
|
print_balances: bool
|
|
@@ -84,6 +85,7 @@ class TransferCmdParams(BaseConfigParams):
|
|
|
84
85
|
|
|
85
86
|
async def run(params: TransferCmdParams) -> None:
|
|
86
87
|
config = await Config.read_toml_config_or_exit_async(params.config_path)
|
|
88
|
+
await config.async_init()
|
|
87
89
|
if params.print_config:
|
|
88
90
|
config.print_and_exit(exclude={"private_keys"})
|
|
89
91
|
|
|
@@ -35,7 +35,7 @@ async def _http_call(node: str, data: dict[str, object], timeout: float, proxy:
|
|
|
35
35
|
if res.is_err():
|
|
36
36
|
return res.to_result_err()
|
|
37
37
|
try:
|
|
38
|
-
parsed_body = res.
|
|
38
|
+
parsed_body = res.parse_json()
|
|
39
39
|
err = parsed_body.get("error", {}).get("message", "")
|
|
40
40
|
if err:
|
|
41
41
|
return res.to_result_err(f"service_error: {err}")
|