mm-eth 0.6.2__py3-none-any.whl → 0.7.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 +1 -1
- mm_eth/account.py +3 -3
- mm_eth/anvil.py +11 -2
- mm_eth/cli/calcs.py +5 -6
- mm_eth/cli/cli.py +3 -2
- mm_eth/cli/cli_utils.py +11 -3
- mm_eth/cli/cmd/balance_cmd.py +8 -7
- mm_eth/cli/cmd/balances_cmd.py +7 -6
- mm_eth/cli/cmd/deploy_cmd.py +6 -4
- mm_eth/cli/cmd/node_cmd.py +3 -2
- mm_eth/cli/cmd/solc_cmd.py +9 -9
- mm_eth/cli/cmd/transfer_cmd.py +24 -25
- mm_eth/cli/cmd/wallet/mnemonic_cmd.py +2 -2
- mm_eth/cli/cmd/wallet/private_key_cmd.py +3 -3
- mm_eth/cli/rpc_helpers.py +4 -4
- mm_eth/cli/validators.py +8 -8
- mm_eth/retry.py +2 -2
- mm_eth/rpc.py +10 -9
- mm_eth/solc.py +3 -2
- mm_eth/tx.py +2 -3
- mm_eth-0.7.1.dist-info/METADATA +7 -0
- mm_eth-0.7.1.dist-info/RECORD +33 -0
- mm_eth-0.6.2.dist-info/METADATA +0 -10
- mm_eth-0.6.2.dist-info/RECORD +0 -33
- {mm_eth-0.6.2.dist-info → mm_eth-0.7.1.dist-info}/WHEEL +0 -0
- {mm_eth-0.6.2.dist-info → mm_eth-0.7.1.dist-info}/entry_points.txt +0 -0
mm_eth/abi.py
CHANGED
|
@@ -72,7 +72,7 @@ def encode_function_input_by_abi(abi: ABI | ABIFunction, fn_name: str, args: lis
|
|
|
72
72
|
# if abi is contract_abi, get function_abi
|
|
73
73
|
if isinstance(abi, Sequence):
|
|
74
74
|
abi = get_function_abi(abi, fn_name)
|
|
75
|
-
abi = cast(ABIFunction, abi)
|
|
75
|
+
# abi = cast(ABIFunction, abi)
|
|
76
76
|
|
|
77
77
|
# need update all address values to checkSum version
|
|
78
78
|
processed_args = []
|
mm_eth/account.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
|
|
3
|
+
import eth_utils
|
|
3
4
|
from eth_account import Account
|
|
4
5
|
from eth_account.hdaccount import Mnemonic
|
|
5
6
|
from eth_account.signers.local import LocalAccount
|
|
6
7
|
from eth_account.types import Language
|
|
7
8
|
from eth_keys import KeyAPI
|
|
8
|
-
from
|
|
9
|
-
from mm_std import Result
|
|
9
|
+
from mm_result import Result
|
|
10
10
|
|
|
11
11
|
Account.enable_unaudited_hdwallet_features()
|
|
12
12
|
|
|
@@ -98,7 +98,7 @@ def is_private_key(private_key: str) -> bool:
|
|
|
98
98
|
bool: True if valid, False otherwise.
|
|
99
99
|
"""
|
|
100
100
|
try:
|
|
101
|
-
key_api.PrivateKey(decode_hex(private_key)).public_key.to_address()
|
|
101
|
+
key_api.PrivateKey(eth_utils.decode_hex(private_key)).public_key.to_address()
|
|
102
102
|
return True # noqa: TRY300
|
|
103
103
|
except Exception:
|
|
104
104
|
return False
|
mm_eth/anvil.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import socket
|
|
3
4
|
import time
|
|
4
5
|
from subprocess import Popen # nosec
|
|
6
|
+
from typing import cast
|
|
5
7
|
|
|
6
|
-
from
|
|
7
|
-
from mm_std.net import get_free_local_port
|
|
8
|
+
from mm_result import Result
|
|
8
9
|
|
|
9
10
|
from mm_eth import account, rpc
|
|
10
11
|
|
|
@@ -54,3 +55,11 @@ class Anvil:
|
|
|
54
55
|
port = get_free_local_port()
|
|
55
56
|
|
|
56
57
|
return Result.err("can't launch anvil")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_free_local_port() -> int:
|
|
61
|
+
sock = socket.socket()
|
|
62
|
+
sock.bind(("", 0))
|
|
63
|
+
port = sock.getsockname()[1]
|
|
64
|
+
sock.close()
|
|
65
|
+
return cast(int, port)
|
mm_eth/cli/calcs.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
from mm_crypto_utils import VarInt
|
|
1
|
+
import mm_web3
|
|
3
2
|
|
|
4
3
|
from mm_eth.cli.validators import SUFFIX_DECIMALS
|
|
5
4
|
|
|
6
5
|
|
|
7
|
-
def calc_eth_expression(expression: str,
|
|
8
|
-
return
|
|
6
|
+
def calc_eth_expression(expression: str, variables: dict[str, int] | None = None) -> int:
|
|
7
|
+
return mm_web3.calc_expression_with_vars(expression, variables, unit_decimals=SUFFIX_DECIMALS)
|
|
9
8
|
|
|
10
9
|
|
|
11
|
-
def calc_token_expression(expression: str, token_decimals: int,
|
|
12
|
-
return
|
|
10
|
+
def calc_token_expression(expression: str, token_decimals: int, variables: dict[str, int] | None = None) -> int:
|
|
11
|
+
return mm_web3.calc_expression_with_vars(expression, variables, unit_decimals={"t": token_decimals})
|
mm_eth/cli/cli.py
CHANGED
|
@@ -3,10 +3,11 @@ import importlib.metadata
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Annotated
|
|
5
5
|
|
|
6
|
+
import mm_print
|
|
6
7
|
import typer
|
|
7
|
-
from mm_std import PrintFormat, print_plain
|
|
8
8
|
|
|
9
9
|
from mm_eth.account import DEFAULT_DERIVATION_PATH
|
|
10
|
+
from mm_eth.cli.cli_utils import PrintFormat
|
|
10
11
|
from mm_eth.cli.cmd import balance_cmd, balances_cmd, deploy_cmd, node_cmd, solc_cmd, transfer_cmd
|
|
11
12
|
from mm_eth.cli.cmd.balances_cmd import BalancesCmdParams
|
|
12
13
|
from mm_eth.cli.cmd.deploy_cmd import DeployCmdParams
|
|
@@ -124,7 +125,7 @@ def transfer_command(
|
|
|
124
125
|
|
|
125
126
|
def version_callback(value: bool) -> None:
|
|
126
127
|
if value:
|
|
127
|
-
|
|
128
|
+
mm_print.plain(f"mm-eth: {importlib.metadata.version('mm-eth')}")
|
|
128
129
|
raise typer.Exit
|
|
129
130
|
|
|
130
131
|
|
mm_eth/cli/cli_utils.py
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import importlib.metadata
|
|
2
|
+
from enum import Enum, unique
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
import mm_print
|
|
5
6
|
from pydantic import BaseModel
|
|
6
7
|
from rich.table import Table
|
|
7
8
|
|
|
8
9
|
from mm_eth import rpc
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
@unique
|
|
13
|
+
class PrintFormat(str, Enum):
|
|
14
|
+
PLAIN = "plain"
|
|
15
|
+
TABLE = "table"
|
|
16
|
+
JSON = "json"
|
|
17
|
+
|
|
18
|
+
|
|
11
19
|
def public_rpc_url(url: str | None) -> str:
|
|
12
20
|
if not url or url == "1":
|
|
13
21
|
return "https://ethereum-rpc.publicnode.com"
|
|
@@ -36,9 +44,9 @@ class BaseConfigParams(BaseModel):
|
|
|
36
44
|
|
|
37
45
|
async def check_nodes_for_chain_id(nodes: list[str], chain_id: int) -> None:
|
|
38
46
|
for node in nodes:
|
|
39
|
-
res = (await rpc.eth_chain_id(node)).
|
|
47
|
+
res = (await rpc.eth_chain_id(node)).unwrap("can't get chain_id")
|
|
40
48
|
if res != chain_id:
|
|
41
|
-
fatal(f"node {node} has a wrong chain_id: {res}")
|
|
49
|
+
mm_print.fatal(f"node {node} has a wrong chain_id: {res}")
|
|
42
50
|
|
|
43
51
|
|
|
44
52
|
def add_table_raw(table: Table, *row: object) -> None:
|
mm_eth/cli/cmd/balance_cmd.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import eth_utils
|
|
2
|
-
|
|
2
|
+
import mm_print
|
|
3
3
|
|
|
4
4
|
from mm_eth import converters, rpc
|
|
5
5
|
from mm_eth.cli import cli_utils
|
|
6
|
+
from mm_eth.cli.cli import PrintFormat
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
async def run(rpc_url: str, wallet_address: str, token_address: str | None, wei: bool, print_format: PrintFormat) -> None:
|
|
@@ -12,7 +13,7 @@ async def run(rpc_url: str, wallet_address: str, token_address: str | None, wei:
|
|
|
12
13
|
# nonce
|
|
13
14
|
result["nonce"] = (await rpc.eth_get_transaction_count(rpc_url, wallet_address)).value_or_error()
|
|
14
15
|
if print_format == PrintFormat.PLAIN:
|
|
15
|
-
|
|
16
|
+
mm_print.plain(f"nonce: {result['nonce']}")
|
|
16
17
|
|
|
17
18
|
# eth balance
|
|
18
19
|
result["eth_balance"] = (
|
|
@@ -21,18 +22,18 @@ async def run(rpc_url: str, wallet_address: str, token_address: str | None, wei:
|
|
|
21
22
|
.value_or_error()
|
|
22
23
|
)
|
|
23
24
|
if print_format == PrintFormat.PLAIN:
|
|
24
|
-
|
|
25
|
+
mm_print.plain(f"eth_balance: {result['eth_balance']}")
|
|
25
26
|
|
|
26
27
|
if token_address:
|
|
27
28
|
# token decimal
|
|
28
29
|
result["token_decimal"] = (await rpc.erc20_decimals(rpc_url, token_address)).value_or_error()
|
|
29
30
|
if print_format == PrintFormat.PLAIN:
|
|
30
|
-
|
|
31
|
+
mm_print.plain(f"token_decimal: {result['token_decimal']}")
|
|
31
32
|
|
|
32
33
|
# token symbol
|
|
33
34
|
result["token_symbol"] = (await rpc.erc20_symbol(rpc_url, token_address)).value_or_error()
|
|
34
35
|
if print_format == PrintFormat.PLAIN:
|
|
35
|
-
|
|
36
|
+
mm_print.plain(f"token_symbol: {result['token_symbol']}")
|
|
36
37
|
|
|
37
38
|
# token balance
|
|
38
39
|
result["token_balance"] = (await rpc.erc20_balance(rpc_url, token_address, wallet_address)).value_or_error()
|
|
@@ -40,7 +41,7 @@ async def run(rpc_url: str, wallet_address: str, token_address: str | None, wei:
|
|
|
40
41
|
result["token_balance"] = converters.from_wei(result["token_balance"], "t", decimals=result["token_decimal"])
|
|
41
42
|
|
|
42
43
|
if print_format == PrintFormat.PLAIN:
|
|
43
|
-
|
|
44
|
+
mm_print.plain(f"token_balance: {result['token_balance']}")
|
|
44
45
|
|
|
45
46
|
if print_format == PrintFormat.JSON:
|
|
46
|
-
|
|
47
|
+
mm_print.json(data=result)
|
mm_eth/cli/cmd/balances_cmd.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Annotated
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import mm_print
|
|
5
|
+
from mm_web3 import Web3CliConfig
|
|
5
6
|
from pydantic import BeforeValidator
|
|
6
7
|
from rich.live import Live
|
|
7
8
|
from rich.table import Table
|
|
@@ -11,7 +12,7 @@ from mm_eth.cli.cli_utils import BaseConfigParams
|
|
|
11
12
|
from mm_eth.cli.validators import Validators
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
class Config(
|
|
15
|
+
class Config(Web3CliConfig):
|
|
15
16
|
addresses: Annotated[list[str], BeforeValidator(Validators.eth_addresses(unique=True))]
|
|
16
17
|
tokens: Annotated[list[str], BeforeValidator(Validators.eth_addresses(unique=True))]
|
|
17
18
|
nodes: Annotated[list[str], BeforeValidator(Validators.nodes())]
|
|
@@ -63,7 +64,7 @@ async def run(params: BalancesCmdParams) -> None:
|
|
|
63
64
|
else:
|
|
64
65
|
row.append(str(converters.from_wei(balance, "eth", round_ndigits=config.round_ndigits)))
|
|
65
66
|
else:
|
|
66
|
-
row.append(base_balance_res.
|
|
67
|
+
row.append(base_balance_res.unwrap_err())
|
|
67
68
|
|
|
68
69
|
for t in tokens:
|
|
69
70
|
token_balance_res = await retry.erc20_balance(5, config.nodes, None, token=t.address, wallet=address)
|
|
@@ -77,7 +78,7 @@ async def run(params: BalancesCmdParams) -> None:
|
|
|
77
78
|
str(converters.from_wei(token_balance, "t", round_ndigits=config.round_ndigits, decimals=t.decimals))
|
|
78
79
|
)
|
|
79
80
|
else:
|
|
80
|
-
row.append(token_balance_res.
|
|
81
|
+
row.append(token_balance_res.unwrap_err())
|
|
81
82
|
|
|
82
83
|
table.add_row(*row)
|
|
83
84
|
|
|
@@ -104,12 +105,12 @@ async def _get_tokens_info(config: Config) -> list[Token]:
|
|
|
104
105
|
for address in config.tokens:
|
|
105
106
|
decimals_res = await retry.erc20_decimals(5, config.nodes, None, token=address)
|
|
106
107
|
if decimals_res.is_err():
|
|
107
|
-
fatal(f"can't get token {address} decimals: {decimals_res.
|
|
108
|
+
mm_print.fatal(f"can't get token {address} decimals: {decimals_res.unwrap_err()}")
|
|
108
109
|
decimal = decimals_res.unwrap()
|
|
109
110
|
|
|
110
111
|
symbols_res = await retry.erc20_symbol(5, config.nodes, None, token=address)
|
|
111
112
|
if symbols_res.is_err():
|
|
112
|
-
fatal(f"can't get token {address} symbol: {symbols_res.
|
|
113
|
+
mm_print.fatal(f"can't get token {address} symbol: {symbols_res.unwrap_err()}")
|
|
113
114
|
symbol = symbols_res.unwrap()
|
|
114
115
|
|
|
115
116
|
result.append(Token(address=address, decimals=decimal, symbol=symbol))
|
mm_eth/cli/cmd/deploy_cmd.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from typing import cast
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import mm_print
|
|
4
|
+
import tomlkit
|
|
5
|
+
from mm_web3 import Web3CliConfig
|
|
4
6
|
from pydantic import StrictStr
|
|
5
7
|
|
|
6
8
|
from mm_eth import account, deploy, retry
|
|
7
9
|
from mm_eth.cli.cli_utils import BaseConfigParams
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
class Config(
|
|
12
|
+
class Config(Web3CliConfig):
|
|
11
13
|
private_key: StrictStr
|
|
12
14
|
nonce: int | None = None
|
|
13
15
|
gas: int
|
|
@@ -30,7 +32,7 @@ async def run(cli_params: DeployCmdParams) -> None:
|
|
|
30
32
|
if cli_params.print_config:
|
|
31
33
|
config.print_and_exit({"private_key"})
|
|
32
34
|
|
|
33
|
-
parsed =
|
|
35
|
+
parsed = tomlkit.loads(f"constructor_types = {config.constructor_types}\nconstructor_values = {config.constructor_values}")
|
|
34
36
|
constructor_types = cast(list[str], parsed["constructor_types"])
|
|
35
37
|
constructor_values = cast(list[object], parsed["constructor_values"])
|
|
36
38
|
|
|
@@ -42,4 +44,4 @@ async def run(cli_params: DeployCmdParams) -> None:
|
|
|
42
44
|
)
|
|
43
45
|
|
|
44
46
|
res = deploy.get_deploy_contract_data(config.contract_bin, constructor_types, constructor_values)
|
|
45
|
-
|
|
47
|
+
mm_print.json(res)
|
mm_eth/cli/cmd/node_cmd.py
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
from decimal import Decimal
|
|
2
2
|
|
|
3
3
|
import eth_utils
|
|
4
|
+
import mm_print
|
|
4
5
|
import pydash
|
|
5
|
-
from mm_std import PrintFormat, print_json
|
|
6
6
|
from pydantic import BaseModel
|
|
7
7
|
from rich.live import Live
|
|
8
8
|
from rich.table import Table
|
|
9
9
|
|
|
10
10
|
from mm_eth import rpc, utils
|
|
11
|
+
from mm_eth.cli.cli import PrintFormat
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class NodeInfo(BaseModel):
|
|
@@ -57,7 +58,7 @@ async def run(urls: list[str], proxy: str | None, print_format: PrintFormat) ->
|
|
|
57
58
|
live_table.stop()
|
|
58
59
|
|
|
59
60
|
if print_format == PrintFormat.JSON:
|
|
60
|
-
|
|
61
|
+
mm_print.json(data=result)
|
|
61
62
|
# print_json(data=result)
|
|
62
63
|
# table = Table(*["url", "chain_id", "chain_name", "block_number", "base_fee"], title="nodes")
|
|
63
64
|
|
mm_eth/cli/cmd/solc_cmd.py
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
from mm_std.fs import get_filename_without_extension
|
|
4
|
+
import mm_print
|
|
6
5
|
|
|
6
|
+
from mm_eth.cli.cli import PrintFormat
|
|
7
7
|
from mm_eth.solc import solc
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def run(contract_path: Path, tmp_dir: Path, print_format: PrintFormat) -> None:
|
|
11
|
-
contract_name =
|
|
11
|
+
contract_name = contract_path.stem
|
|
12
12
|
res = solc(contract_name, contract_path, tmp_dir)
|
|
13
13
|
if res.is_err():
|
|
14
|
-
fatal(res.
|
|
14
|
+
mm_print.fatal(res.unwrap_err())
|
|
15
15
|
|
|
16
16
|
bin_ = res.unwrap().bin
|
|
17
17
|
abi = res.unwrap().abi
|
|
18
18
|
|
|
19
19
|
if print_format == PrintFormat.JSON:
|
|
20
|
-
|
|
20
|
+
mm_print.json({"bin": bin_, "abi": json.loads(abi)})
|
|
21
21
|
else:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
mm_print.plain("bin:")
|
|
23
|
+
mm_print.plain(bin_)
|
|
24
|
+
mm_print.plain("abi:")
|
|
25
|
+
mm_print.plain(abi)
|
mm_eth/cli/cmd/transfer_cmd.py
CHANGED
|
@@ -4,10 +4,9 @@ import time
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Annotated, Literal, Self, cast
|
|
6
6
|
|
|
7
|
-
import mm_crypto_utils
|
|
8
7
|
from loguru import logger
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from mm_std import utc_now
|
|
9
|
+
from mm_web3 import PrivateKeyMap, Transfer, Web3CliConfig, calc_decimal_expression, init_loguru
|
|
11
10
|
from pydantic import AfterValidator, BeforeValidator, Field, model_validator
|
|
12
11
|
from rich.console import Console
|
|
13
12
|
from rich.live import Live
|
|
@@ -20,11 +19,11 @@ from mm_eth.cli.validators import Validators
|
|
|
20
19
|
from mm_eth.converters import from_wei
|
|
21
20
|
|
|
22
21
|
|
|
23
|
-
class Config(
|
|
22
|
+
class Config(Web3CliConfig):
|
|
24
23
|
nodes: Annotated[list[str], BeforeValidator(Validators.nodes())]
|
|
25
24
|
chain_id: int
|
|
26
25
|
transfers: Annotated[list[Transfer], BeforeValidator(Validators.eth_transfers())]
|
|
27
|
-
private_keys: Annotated[
|
|
26
|
+
private_keys: Annotated[PrivateKeyMap, BeforeValidator(Validators.eth_private_keys())]
|
|
28
27
|
token: Annotated[str | None, AfterValidator(Validators.eth_address())] = None # if None, then eth transfer
|
|
29
28
|
token_decimals: int = -1
|
|
30
29
|
max_fee: Annotated[str, AfterValidator(Validators.valid_eth_expression("base_fee"))]
|
|
@@ -33,7 +32,7 @@ class Config(BaseConfig):
|
|
|
33
32
|
default_value: Annotated[str | None, AfterValidator(Validators.valid_eth_or_token_expression("balance"))] = None
|
|
34
33
|
value_min_limit: Annotated[str | None, AfterValidator(Validators.valid_eth_or_token_expression())] = None
|
|
35
34
|
gas: Annotated[str, AfterValidator(Validators.valid_eth_expression("estimate"))]
|
|
36
|
-
delay: Annotated[str | None, AfterValidator(Validators.
|
|
35
|
+
delay: Annotated[str | None, AfterValidator(Validators.decimal_expression())] = None # in seconds
|
|
37
36
|
round_ndigits: int = 5
|
|
38
37
|
proxies: Annotated[list[str], Field(default_factory=list), BeforeValidator(Validators.proxies())]
|
|
39
38
|
wait_tx_timeout: int = 120
|
|
@@ -68,7 +67,7 @@ class Config(BaseConfig):
|
|
|
68
67
|
Validators.valid_eth_expression()(self.value_min_limit)
|
|
69
68
|
|
|
70
69
|
if self.token:
|
|
71
|
-
self.token_decimals = (await retry.erc20_decimals(5, self.nodes, self.proxies, token=self.token)).
|
|
70
|
+
self.token_decimals = (await retry.erc20_decimals(5, self.nodes, self.proxies, token=self.token)).unwrap(
|
|
72
71
|
"can't get token decimals"
|
|
73
72
|
)
|
|
74
73
|
|
|
@@ -102,13 +101,13 @@ async def run(params: TransferCmdParams) -> None:
|
|
|
102
101
|
|
|
103
102
|
|
|
104
103
|
async def _run_transfers(config: Config, cmd_params: TransferCmdParams) -> None:
|
|
105
|
-
|
|
104
|
+
init_loguru(cmd_params.debug, config.log_debug, config.log_info)
|
|
106
105
|
logger.info(f"transfer {cmd_params.config_path}: started at {utc_now()} UTC")
|
|
107
106
|
logger.debug(f"config={config.model_dump(exclude={'private_keys'}) | {'version': cli_utils.get_version()}}")
|
|
108
107
|
for i, transfer in enumerate(config.transfers):
|
|
109
108
|
await _transfer(transfer, config, cmd_params)
|
|
110
109
|
if config.delay is not None and i < len(config.transfers) - 1:
|
|
111
|
-
delay_value =
|
|
110
|
+
delay_value = calc_decimal_expression(config.delay)
|
|
112
111
|
logger.info(f"delay {delay_value} seconds")
|
|
113
112
|
if not cmd_params.emulate:
|
|
114
113
|
await asyncio.sleep(float(delay_value))
|
|
@@ -118,7 +117,7 @@ async def _run_transfers(config: Config, cmd_params: TransferCmdParams) -> None:
|
|
|
118
117
|
async def _get_nonce(t: Transfer, config: Config) -> int | None:
|
|
119
118
|
res = await retry.eth_get_transaction_count(5, config.nodes, config.proxies, address=t.from_address)
|
|
120
119
|
if res.is_err():
|
|
121
|
-
logger.error(f"{t.log_prefix}: nonce error: {res.
|
|
120
|
+
logger.error(f"{t.log_prefix}: nonce error: {res.unwrap_err()}")
|
|
122
121
|
return None
|
|
123
122
|
logger.debug(f"{t.log_prefix}: nonce={res.unwrap()}")
|
|
124
123
|
return res.unwrap()
|
|
@@ -128,10 +127,10 @@ async def _calc_max_fee(t: Transfer, config: Config) -> int | None:
|
|
|
128
127
|
if "base_fee" in config.max_fee.lower():
|
|
129
128
|
base_fee_res = await retry.get_base_fee_per_gas(5, config.nodes, config.proxies)
|
|
130
129
|
if base_fee_res.is_err():
|
|
131
|
-
logger.error(f"{t.log_prefix}: base_fee error: {base_fee_res.
|
|
130
|
+
logger.error(f"{t.log_prefix}: base_fee error: {base_fee_res.unwrap_err()}")
|
|
132
131
|
return None
|
|
133
132
|
logger.debug(f"{t.log_prefix}: base_fee={base_fee_res.unwrap()}")
|
|
134
|
-
return calcs.calc_eth_expression(config.max_fee,
|
|
133
|
+
return calcs.calc_eth_expression(config.max_fee, {"base_fee": base_fee_res.unwrap()})
|
|
135
134
|
return calcs.calc_eth_expression(config.max_fee)
|
|
136
135
|
|
|
137
136
|
|
|
@@ -147,7 +146,7 @@ def check_max_fee_limit(t: Transfer, config: Config, max_fee: int) -> bool:
|
|
|
147
146
|
|
|
148
147
|
|
|
149
148
|
async def _calc_gas(t: Transfer, config: Config) -> int | None:
|
|
150
|
-
|
|
149
|
+
variables: dict[str, int] | None = None
|
|
151
150
|
if "estimate" in config.gas.lower():
|
|
152
151
|
if config.token:
|
|
153
152
|
res = await retry.eth_estimate_gas(
|
|
@@ -163,25 +162,25 @@ async def _calc_gas(t: Transfer, config: Config) -> int | None:
|
|
|
163
162
|
5, config.nodes, config.proxies, from_=t.from_address, to=t.to_address, value=12345
|
|
164
163
|
)
|
|
165
164
|
if res.is_err():
|
|
166
|
-
logger.error(f"{t.log_prefix}: gas estimate error: {res.
|
|
165
|
+
logger.error(f"{t.log_prefix}: gas estimate error: {res.unwrap_err()}")
|
|
167
166
|
return None
|
|
168
167
|
logger.debug(f"{t.log_prefix}: gas estimate={res.unwrap()}")
|
|
169
|
-
|
|
170
|
-
return calcs.calc_eth_expression(config.gas,
|
|
168
|
+
variables = {"estimate": res.unwrap()}
|
|
169
|
+
return calcs.calc_eth_expression(config.gas, variables)
|
|
171
170
|
|
|
172
171
|
|
|
173
172
|
async def _calc_eth_value(t: Transfer, max_fee: int, gas: int, config: Config) -> int | None:
|
|
174
173
|
value_expression = t.value.lower()
|
|
175
|
-
|
|
174
|
+
variables: dict[str, int] | None = None
|
|
176
175
|
if "balance" in value_expression:
|
|
177
176
|
res = await retry.eth_get_balance(5, config.nodes, config.proxies, address=t.from_address)
|
|
178
177
|
if res.is_err():
|
|
179
|
-
logger.error(f"{t.log_prefix}: balance error: {res.
|
|
178
|
+
logger.error(f"{t.log_prefix}: balance error: {res.unwrap_err()}")
|
|
180
179
|
return None
|
|
181
180
|
logger.debug(f"{t.log_prefix}: balance={res.unwrap()}")
|
|
182
|
-
|
|
181
|
+
variables = {"balance": res.unwrap()}
|
|
183
182
|
|
|
184
|
-
value = calcs.calc_eth_expression(value_expression,
|
|
183
|
+
value = calcs.calc_eth_expression(value_expression, variables)
|
|
185
184
|
if "balance" in value_expression.lower():
|
|
186
185
|
value = value - gas * max_fee
|
|
187
186
|
return value
|
|
@@ -189,15 +188,15 @@ async def _calc_eth_value(t: Transfer, max_fee: int, gas: int, config: Config) -
|
|
|
189
188
|
|
|
190
189
|
async def _calc_token_value(t: Transfer, config: Config) -> int | None:
|
|
191
190
|
value_expression = t.value.lower()
|
|
192
|
-
|
|
191
|
+
variables: dict[str, int] | None = None
|
|
193
192
|
if "balance" in value_expression:
|
|
194
193
|
res = await retry.erc20_balance(5, config.nodes, config.proxies, token=cast(str, config.token), wallet=t.from_address)
|
|
195
194
|
if res.is_err():
|
|
196
|
-
logger.error(f"{t.log_prefix}: balance error: {res.
|
|
195
|
+
logger.error(f"{t.log_prefix}: balance error: {res.unwrap_err()}")
|
|
197
196
|
return None
|
|
198
197
|
logger.debug(f"{t.log_prefix}: balance={res.unwrap()}")
|
|
199
|
-
|
|
200
|
-
return calcs.calc_token_expression(value_expression, config.token_decimals,
|
|
198
|
+
variables = {"balance": res.unwrap()}
|
|
199
|
+
return calcs.calc_token_expression(value_expression, config.token_decimals, variables)
|
|
201
200
|
|
|
202
201
|
|
|
203
202
|
async def _calc_value(t: Transfer, max_fee: int, gas: int, config: Config) -> int | None:
|
|
@@ -321,7 +320,7 @@ async def _send_tx(
|
|
|
321
320
|
)
|
|
322
321
|
res = await retry.eth_send_raw_transaction(5, config.nodes, config.proxies, raw_tx=signed_tx.raw_tx)
|
|
323
322
|
if res.is_err():
|
|
324
|
-
logger.error(f"{transfer.log_prefix}: send tx error={res.
|
|
323
|
+
logger.error(f"{transfer.log_prefix}: send tx error={res.unwrap_err()}")
|
|
325
324
|
return None
|
|
326
325
|
logger.debug(f"{transfer.log_prefix}: tx_hash={res.unwrap()}")
|
|
327
326
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import mm_print
|
|
5
5
|
|
|
6
6
|
from mm_eth.account import derive_accounts, generate_mnemonic
|
|
7
7
|
|
|
@@ -19,7 +19,7 @@ def run(mnemonic: str, passphrase: str, words: int, derivation_path: str, limit:
|
|
|
19
19
|
if print_path:
|
|
20
20
|
new_account["path"] = acc.path
|
|
21
21
|
result["accounts"].append(new_account)
|
|
22
|
-
|
|
22
|
+
mm_print.json(result)
|
|
23
23
|
|
|
24
24
|
if save_file:
|
|
25
25
|
data = [acc["address"] + "\t" + acc["private"] for acc in result["accounts"]]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import mm_print
|
|
2
2
|
|
|
3
3
|
from mm_eth import account
|
|
4
4
|
|
|
@@ -6,6 +6,6 @@ from mm_eth import account
|
|
|
6
6
|
def run(private_key: str) -> None:
|
|
7
7
|
res = account.private_to_address(private_key)
|
|
8
8
|
if res.is_ok():
|
|
9
|
-
|
|
9
|
+
mm_print.plain(res.unwrap())
|
|
10
10
|
else:
|
|
11
|
-
fatal(f"invalid private key: '{private_key}'")
|
|
11
|
+
mm_print.fatal(f"invalid private key: '{private_key}'")
|
mm_eth/cli/rpc_helpers.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from mm_web3 import Nodes, Proxies
|
|
4
4
|
|
|
5
5
|
from mm_eth import retry
|
|
6
6
|
from mm_eth.cli import calcs
|
|
@@ -14,7 +14,7 @@ async def get_nonce_with_logging(
|
|
|
14
14
|
res = await retry.eth_get_transaction_count(retries, nodes, proxies, address=address)
|
|
15
15
|
prefix = log_prefix or address
|
|
16
16
|
if res.is_err():
|
|
17
|
-
logger.error(f"{prefix}: nonce error: {res.
|
|
17
|
+
logger.error(f"{prefix}: nonce error: {res.unwrap_err()}")
|
|
18
18
|
return None
|
|
19
19
|
logger.debug(f"{prefix}: nonce={res.unwrap()}")
|
|
20
20
|
return res.unwrap()
|
|
@@ -24,7 +24,7 @@ async def get_base_fee_with_logging(log_prefix: str | None, retries: int, nodes:
|
|
|
24
24
|
prefix = get_log_prefix(log_prefix)
|
|
25
25
|
res = await retry.get_base_fee_per_gas(retries, nodes, proxies)
|
|
26
26
|
if res.is_err():
|
|
27
|
-
logger.error(f"{prefix}base_fee error, {res.
|
|
27
|
+
logger.error(f"{prefix}base_fee error, {res.unwrap_err()}")
|
|
28
28
|
return None
|
|
29
29
|
|
|
30
30
|
logger.debug(f"{prefix}base_fee={res.unwrap()}")
|
|
@@ -38,7 +38,7 @@ async def calc_max_fee_with_logging(
|
|
|
38
38
|
base_fee = await get_base_fee_with_logging(log_prefix, retries, nodes, proxies)
|
|
39
39
|
if base_fee is None:
|
|
40
40
|
return None
|
|
41
|
-
return calcs.calc_eth_expression(max_fee_expression,
|
|
41
|
+
return calcs.calc_eth_expression(max_fee_expression, {"base_fee": base_fee})
|
|
42
42
|
|
|
43
43
|
return calcs.calc_eth_expression(max_fee_expression)
|
|
44
44
|
|
mm_eth/cli/validators.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from collections.abc import Callable
|
|
2
2
|
|
|
3
3
|
import eth_utils
|
|
4
|
-
from
|
|
4
|
+
from mm_web3 import ConfigValidators, PrivateKeyMap, Transfer
|
|
5
5
|
|
|
6
6
|
from mm_eth import account
|
|
7
7
|
|
|
@@ -18,28 +18,28 @@ def address_from_private(private_key: str) -> str:
|
|
|
18
18
|
class Validators(ConfigValidators):
|
|
19
19
|
@staticmethod
|
|
20
20
|
def valid_eth_expression(var_name: str | None = None) -> Callable[[str], str]:
|
|
21
|
-
return ConfigValidators.
|
|
21
|
+
return ConfigValidators.expression_with_vars(var_name, SUFFIX_DECIMALS)
|
|
22
22
|
|
|
23
23
|
@staticmethod
|
|
24
24
|
def valid_token_expression(var_name: str | None = None) -> Callable[[str], str]:
|
|
25
|
-
return ConfigValidators.
|
|
25
|
+
return ConfigValidators.expression_with_vars(var_name, {"t": 6})
|
|
26
26
|
|
|
27
27
|
@staticmethod
|
|
28
28
|
def valid_eth_or_token_expression(var_name: str | None = None) -> Callable[[str], str]:
|
|
29
|
-
return ConfigValidators.
|
|
29
|
+
return ConfigValidators.expression_with_vars(var_name, SUFFIX_DECIMALS | {"t": 6})
|
|
30
30
|
|
|
31
31
|
@staticmethod
|
|
32
32
|
def eth_transfers() -> Callable[[str], list[Transfer]]:
|
|
33
|
-
return ConfigValidators.transfers(is_address=eth_utils.is_address,
|
|
33
|
+
return ConfigValidators.transfers(is_address=eth_utils.is_address, lowercase=True)
|
|
34
34
|
|
|
35
35
|
@staticmethod
|
|
36
|
-
def eth_private_keys() -> Callable[[str],
|
|
36
|
+
def eth_private_keys() -> Callable[[str], PrivateKeyMap]:
|
|
37
37
|
return ConfigValidators.private_keys(address_from_private)
|
|
38
38
|
|
|
39
39
|
@staticmethod
|
|
40
40
|
def eth_address() -> Callable[[str], str]:
|
|
41
|
-
return ConfigValidators.address(eth_utils.is_address,
|
|
41
|
+
return ConfigValidators.address(eth_utils.is_address, lowercase=True)
|
|
42
42
|
|
|
43
43
|
@staticmethod
|
|
44
44
|
def eth_addresses(unique: bool) -> Callable[[str], list[str]]:
|
|
45
|
-
return ConfigValidators.addresses(unique,
|
|
45
|
+
return ConfigValidators.addresses(unique, lowercase=True, is_address=eth_utils.is_address)
|
mm_eth/retry.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from typing import Any, Literal
|
|
2
2
|
|
|
3
3
|
from eth_typing import BlockIdentifier
|
|
4
|
-
from
|
|
5
|
-
from
|
|
4
|
+
from mm_result import Result
|
|
5
|
+
from mm_web3 import Nodes, Proxies, retry_with_node_and_proxy
|
|
6
6
|
from web3.types import TxReceipt
|
|
7
7
|
|
|
8
8
|
from mm_eth import rpc
|
mm_eth/rpc.py
CHANGED
|
@@ -9,7 +9,8 @@ import eth_utils
|
|
|
9
9
|
import pydash
|
|
10
10
|
import websockets
|
|
11
11
|
from eth_typing import BlockIdentifier
|
|
12
|
-
from
|
|
12
|
+
from mm_http import http_request
|
|
13
|
+
from mm_result import Result
|
|
13
14
|
from web3.types import TxReceipt
|
|
14
15
|
|
|
15
16
|
TIMEOUT = 7.0
|
|
@@ -32,17 +33,17 @@ async def rpc_call(
|
|
|
32
33
|
async def _http_call(node: str, data: dict[str, object], timeout: float, proxy: str | None) -> Result[Any]:
|
|
33
34
|
res = await http_request(node, method="POST", proxy=proxy, timeout=timeout, json=data)
|
|
34
35
|
if res.is_err():
|
|
35
|
-
return res.
|
|
36
|
+
return res.to_result_err()
|
|
36
37
|
try:
|
|
37
38
|
parsed_body = res.parse_json_body()
|
|
38
39
|
err = parsed_body.get("error", {}).get("message", "")
|
|
39
40
|
if err:
|
|
40
|
-
return res.
|
|
41
|
+
return res.to_result_err(f"service_error: {err}")
|
|
41
42
|
if "result" in parsed_body:
|
|
42
|
-
return res.
|
|
43
|
-
return res.
|
|
43
|
+
return res.to_result_ok(parsed_body["result"])
|
|
44
|
+
return res.to_result_err("unknown_response")
|
|
44
45
|
except Exception as e:
|
|
45
|
-
return res.
|
|
46
|
+
return res.to_result_err(e)
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
async def _ws_call(node: str, data: dict[str, object], timeout: float) -> Result[Any]:
|
|
@@ -225,7 +226,7 @@ async def ens_name(node: str, address: str, timeout: float = TIMEOUT, proxy: str
|
|
|
225
226
|
extra["name_response"] = name_res.to_dict()
|
|
226
227
|
|
|
227
228
|
if name_res.is_err():
|
|
228
|
-
return Result.err(name_res.
|
|
229
|
+
return Result.err(name_res.unwrap_err(), extra)
|
|
229
230
|
|
|
230
231
|
if name_res.unwrap() == "0x":
|
|
231
232
|
return Result.ok(None, extra)
|
|
@@ -248,7 +249,7 @@ async def ens_name(node: str, address: str, timeout: float = TIMEOUT, proxy: str
|
|
|
248
249
|
async def get_base_fee_per_gas(node: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
|
|
249
250
|
res = await eth_get_block_by_number(node, "latest", False, timeout=timeout, proxy=proxy)
|
|
250
251
|
if res.is_err():
|
|
251
|
-
return Result.err(res.
|
|
252
|
+
return Result.err(res.unwrap_err(), res.extra)
|
|
252
253
|
if "baseFeePerGas" in res.unwrap():
|
|
253
254
|
return res.with_value(int(res.unwrap()["baseFeePerGas"], 16))
|
|
254
255
|
return Result.err("no_base_fee_per_gas", res.extra)
|
|
@@ -257,7 +258,7 @@ async def get_base_fee_per_gas(node: str, timeout: float = TIMEOUT, proxy: str |
|
|
|
257
258
|
async def get_tx_status(node: str, tx_hash: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
|
|
258
259
|
res = await eth_get_transaction_receipt(node, tx_hash, timeout=timeout, proxy=proxy)
|
|
259
260
|
if res.is_err():
|
|
260
|
-
return Result.err(res.
|
|
261
|
+
return Result.err(res.unwrap_err(), res.extra)
|
|
261
262
|
status = res.unwrap().get("status")
|
|
262
263
|
if status is None:
|
|
263
264
|
return Result.err("no_status", res.extra)
|
mm_eth/solc.py
CHANGED
|
@@ -4,7 +4,8 @@ import shutil
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import mm_std
|
|
8
|
+
from mm_result import Result
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
@dataclass
|
|
@@ -31,7 +32,7 @@ def solc(contract_name: str, contract_path: Path, tmp_dir: Path) -> Result[SolcR
|
|
|
31
32
|
work_dir_created = True
|
|
32
33
|
|
|
33
34
|
cmd = f"solc -o '{work_dir}' --abi --bin --optimize '{contract_path}'"
|
|
34
|
-
result =
|
|
35
|
+
result = mm_std.shell(cmd)
|
|
35
36
|
if result.code != 0:
|
|
36
37
|
return Result.err(f"solc error: {result.stderr}")
|
|
37
38
|
|
mm_eth/tx.py
CHANGED
|
@@ -6,7 +6,6 @@ import eth_utils
|
|
|
6
6
|
import rlp
|
|
7
7
|
from eth_account import Account
|
|
8
8
|
from eth_typing import HexStr
|
|
9
|
-
from eth_utils import keccak, to_hex
|
|
10
9
|
from pydantic import BaseModel
|
|
11
10
|
from rlp.sedes import Binary, big_endian_int, binary
|
|
12
11
|
from web3 import Web3
|
|
@@ -103,7 +102,7 @@ def sign_legacy_tx(
|
|
|
103
102
|
tx["data"] = data
|
|
104
103
|
|
|
105
104
|
signed = Account.sign_transaction(tx, private_key)
|
|
106
|
-
return SignedTx(tx_hash=to_hex(signed.hash), raw_tx=to_hex(signed.raw_transaction))
|
|
105
|
+
return SignedTx(tx_hash=eth_utils.to_hex(signed.hash), raw_tx=eth_utils.to_hex(signed.raw_transaction))
|
|
107
106
|
|
|
108
107
|
|
|
109
108
|
def sign_tx(
|
|
@@ -139,7 +138,7 @@ def sign_tx(
|
|
|
139
138
|
|
|
140
139
|
def decode_raw_tx(raw_tx: str) -> DecodedRawTx:
|
|
141
140
|
tx: Any = rlp.decode(eth_utils.to_bytes(hexstr=HexStr(raw_tx)), RPLTransaction)
|
|
142
|
-
tx_hash = Web3.to_hex(keccak(eth_utils.to_bytes(hexstr=HexStr(raw_tx))))
|
|
141
|
+
tx_hash = Web3.to_hex(eth_utils.keccak(eth_utils.to_bytes(hexstr=HexStr(raw_tx))))
|
|
143
142
|
from_ = Account.recover_transaction(raw_tx)
|
|
144
143
|
to = Web3.to_checksum_address(tx.to) if tx.to else None
|
|
145
144
|
data = Web3.to_hex(tx.data)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
mm_eth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mm_eth/abi.py,sha256=SBst1GqcaMSawAyAragAx8tYkCThw0aiMmsWa884wyA,4808
|
|
3
|
+
mm_eth/account.py,sha256=WUaQq8AtHIL39hJN4-UkhDu7UM20j1xlMplCTKQzr1o,3041
|
|
4
|
+
mm_eth/anvil.py,sha256=f7zd5zZqcOTd1Sy4GdHAGTOjsQZzLI3E0ttT017KYLQ,1792
|
|
5
|
+
mm_eth/converters.py,sha256=smL3Bsky1pYEre2kPhsb4arXoQC_u80P5ilU9NRvr44,2043
|
|
6
|
+
mm_eth/deploy.py,sha256=SB3ruY808_5UnG8kHR34uVP66P3zOWZu0ImKD7UUv2s,691
|
|
7
|
+
mm_eth/erc20.py,sha256=Pxs_w95flqEUF4pJMoaHTfvud8x5Fb2UwU7iwMjdGCw,1143
|
|
8
|
+
mm_eth/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
mm_eth/retry.py,sha256=saRYV07Ca1laqT1nQP3_UmKvYXNWMURh8gyN2r1WrIs,5123
|
|
10
|
+
mm_eth/rpc.py,sha256=3I6mfM_-93qFK25SLwv8zUG2vR5EaEUd_YfcBVX8YF0,9917
|
|
11
|
+
mm_eth/solc.py,sha256=s_iaaslncVzzQsgUgcc04x8ZeCjCf9T9JdW1_yzUDxI,1353
|
|
12
|
+
mm_eth/tx.py,sha256=MSJf6zGRYlwCbJIXXLL2NONVpvF1_clWd_5CV5j4pTE,4095
|
|
13
|
+
mm_eth/utils.py,sha256=TLyapZZ1lp_kW3vdkHmgR8gUtIQ1aEy_0GScxB6v5IQ,659
|
|
14
|
+
mm_eth/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
mm_eth/cli/calcs.py,sha256=FwnYwRKDnBdXTYrjdWqilPd36W969ovziO8qkQoHOsw,477
|
|
16
|
+
mm_eth/cli/cli.py,sha256=aElAbK1FiABwMPTU-vysyFIyg6OkBtiir6Zj4LuNmx8,5600
|
|
17
|
+
mm_eth/cli/cli_utils.py,sha256=Py04-0wI5_6Hby0zN8WxYFZf0jL13B1gxjjYTIDrqOE,1536
|
|
18
|
+
mm_eth/cli/rpc_helpers.py,sha256=nmr4CXVMGblGJxllaLd95gTV_VhauRhWUKmQZk5-Vmg,1643
|
|
19
|
+
mm_eth/cli/validators.py,sha256=0T5tQdqEd4fNaamVK8TifUBTCzqLkNdzTA4rZD98_H8,1649
|
|
20
|
+
mm_eth/cli/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
mm_eth/cli/cmd/balance_cmd.py,sha256=Qtn_4h_MDYh38HizkOx6auAv0_41GyCH3bWDmLXHfjQ,1963
|
|
22
|
+
mm_eth/cli/cmd/balances_cmd.py,sha256=I8GgANCx5vuu8Yb5qOrlcKdUc-Yzw1eg9Ucrran5xnQ,4256
|
|
23
|
+
mm_eth/cli/cmd/deploy_cmd.py,sha256=ge-r_GbGc9r2osz-g7zOmqXkbMsFnjeyNPSoq72Ntpg,1479
|
|
24
|
+
mm_eth/cli/cmd/node_cmd.py,sha256=-BBKj9l-ZiPr6NZ12WQvuxQcXvyDBvcbReMMevN3fME,2574
|
|
25
|
+
mm_eth/cli/cmd/solc_cmd.py,sha256=Puu8mw8wvbltEug7SCMZdNT5Y9tD_-awdKGYKeYHUsw,648
|
|
26
|
+
mm_eth/cli/cmd/transfer_cmd.py,sha256=6ciWTPdnu6dnv0H0c641kgar2nG4aJOxl0G0lszxD4M,16978
|
|
27
|
+
mm_eth/cli/cmd/wallet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
mm_eth/cli/cmd/wallet/mnemonic_cmd.py,sha256=RQbNY3C4-5NvcPXorhO7YIYG8dU0u5gN5sEANmFE1iY,996
|
|
29
|
+
mm_eth/cli/cmd/wallet/private_key_cmd.py,sha256=RmSrUxaGd0U7f6Xo_CZuJ8XQG9PbjI3Tc1Iu7wzkP3Q,262
|
|
30
|
+
mm_eth-0.7.1.dist-info/METADATA,sha256=mqbTSkJIF14yJ9FAJokEFQMkJykqHSrqwidE8NyEppU,161
|
|
31
|
+
mm_eth-0.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
32
|
+
mm_eth-0.7.1.dist-info/entry_points.txt,sha256=aGhpsozl8NIrkuUcX5fSgURCcDhr3ShUdeTSIrJq4oc,46
|
|
33
|
+
mm_eth-0.7.1.dist-info/RECORD,,
|
mm_eth-0.6.2.dist-info/METADATA
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: mm-eth
|
|
3
|
-
Version: 0.6.2
|
|
4
|
-
Requires-Python: >=3.12
|
|
5
|
-
Requires-Dist: aiohttp-socks~=0.10.1
|
|
6
|
-
Requires-Dist: mm-crypto-utils>=0.3.6
|
|
7
|
-
Requires-Dist: mm-std~=0.4.11
|
|
8
|
-
Requires-Dist: typer>=0.15.2
|
|
9
|
-
Requires-Dist: web3~=7.10.0
|
|
10
|
-
Requires-Dist: websocket-client~=1.8.0
|
mm_eth-0.6.2.dist-info/RECORD
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
mm_eth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
mm_eth/abi.py,sha256=gsIsaq5V8QGdYY424c_t_uVRfg0of7Gk9h0LcW3tkjU,4806
|
|
3
|
-
mm_eth/account.py,sha256=syA89ihOBTA2FiDK3o55oLBVEgPN1rQT_3bUQN05vuk,3044
|
|
4
|
-
mm_eth/anvil.py,sha256=NY1TxYnamfm_47HqCbgUCRdQxPgmAcJ-9YkK3NZ0310,1631
|
|
5
|
-
mm_eth/converters.py,sha256=smL3Bsky1pYEre2kPhsb4arXoQC_u80P5ilU9NRvr44,2043
|
|
6
|
-
mm_eth/deploy.py,sha256=SB3ruY808_5UnG8kHR34uVP66P3zOWZu0ImKD7UUv2s,691
|
|
7
|
-
mm_eth/erc20.py,sha256=Pxs_w95flqEUF4pJMoaHTfvud8x5Fb2UwU7iwMjdGCw,1143
|
|
8
|
-
mm_eth/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
mm_eth/retry.py,sha256=tYP7B_lah8hxYahweaGAAhWCJl-pQ0pg_2Lk-432luE,5128
|
|
10
|
-
mm_eth/rpc.py,sha256=sFt9vK6rHktNTAIxgKx9CSCANx9Z7tTp165yK_G3uRs,9865
|
|
11
|
-
mm_eth/solc.py,sha256=2FGCJpbkCwIs8hGc8APpvC62gyAXGLeyQMrn4f9Bnow,1348
|
|
12
|
-
mm_eth/tx.py,sha256=zf5fieuKB-CTOiNNjz3siXU7yga7tlh0vkZTDAHvhnQ,4102
|
|
13
|
-
mm_eth/utils.py,sha256=TLyapZZ1lp_kW3vdkHmgR8gUtIQ1aEy_0GScxB6v5IQ,659
|
|
14
|
-
mm_eth/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
mm_eth/cli/calcs.py,sha256=N063Qw85iBNFbDtIjOSYJKHL0vU6wyfRfYAlI9TKeK0,496
|
|
16
|
-
mm_eth/cli/cli.py,sha256=Qac0HizKAyF1wocVvNK2578ntB2JT9kLHr1U5jfQj6E,5580
|
|
17
|
-
mm_eth/cli/cli_utils.py,sha256=jYDuSo-osvKPkd_OJFCHZDfGlFy3LKs-MVKHEnkCPdM,1416
|
|
18
|
-
mm_eth/cli/rpc_helpers.py,sha256=5fxiwFb16V0udY2MOb3bTpUrkf3Lhn-mMXFrdbmAKo4,1669
|
|
19
|
-
mm_eth/cli/validators.py,sha256=74AxIzryQ-D3f5xJYrOnh4AMFugTpsYhUJ_pzhHd2ek,1675
|
|
20
|
-
mm_eth/cli/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
-
mm_eth/cli/cmd/balance_cmd.py,sha256=hujMv4Fvt4ZMZ3iPOZKdI2u2iN-ClYBmfMn_2Y4lRew,1946
|
|
22
|
-
mm_eth/cli/cmd/balances_cmd.py,sha256=VGCqcPCKPFF2O3WNlryg0nFnCkkKRAaubvpbtH0XTV0,4230
|
|
23
|
-
mm_eth/cli/cmd/deploy_cmd.py,sha256=T0VapUVOA6M5Hska04AObBKk5_91lClX5hARkj1Dm3k,1465
|
|
24
|
-
mm_eth/cli/cmd/node_cmd.py,sha256=JJSiKGG5OL9p7FuHhNeerjfes6Eo_StgLgpZEy3EUU0,2559
|
|
25
|
-
mm_eth/cli/cmd/solc_cmd.py,sha256=HDLThGAxk8MlJh_OBTsivoXYCKDlGnljRFp-BbYDlU0,714
|
|
26
|
-
mm_eth/cli/cmd/transfer_cmd.py,sha256=kKNoU_kNl2blz9ydbvhlEY1Kck0fCMv4RKwU84HyOSw,16933
|
|
27
|
-
mm_eth/cli/cmd/wallet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
mm_eth/cli/cmd/wallet/mnemonic_cmd.py,sha256=xE-5Ux9BdYsTZYBy0dMn9jupGhW4ced-AgYscy_wU_4,1007
|
|
29
|
-
mm_eth/cli/cmd/wallet/private_key_cmd.py,sha256=wuW_LvmIZiT9T4R8ir0wH1VQ_CEPjmrLgS-vzf0yv70,272
|
|
30
|
-
mm_eth-0.6.2.dist-info/METADATA,sha256=etjH_lZpyb7tlF0LawFlfKZ7EhCGuiE9rFj2y6QXzyE,275
|
|
31
|
-
mm_eth-0.6.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
32
|
-
mm_eth-0.6.2.dist-info/entry_points.txt,sha256=aGhpsozl8NIrkuUcX5fSgURCcDhr3ShUdeTSIrJq4oc,46
|
|
33
|
-
mm_eth-0.6.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|