mm-eth 0.3.1__tar.gz → 0.4.1__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.3.1 → mm_eth-0.4.1}/PKG-INFO +3 -3
- {mm_eth-0.3.1 → mm_eth-0.4.1}/pyproject.toml +6 -6
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/account.py +11 -11
- mm_eth-0.4.1/src/mm_eth/cli/calcs.py +27 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cli.py +28 -47
- mm_eth-0.4.1/src/mm_eth/cli/cli_utils.py +60 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/balances_cmd.py +1 -1
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/call_contract_cmd.py +1 -1
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/deploy_cmd.py +1 -1
- mm_eth-0.3.1/src/mm_eth/cli/cmd/config_example_cmd.py → mm_eth-0.4.1/src/mm_eth/cli/cmd/example_cmd.py +1 -1
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/send_contract_cmd.py +1 -1
- mm_eth-0.4.1/src/mm_eth/cli/cmd/transfer_cmd.py +311 -0
- {mm_eth-0.3.1/src/mm_eth/cli/cmd → mm_eth-0.4.1/src/mm_eth/cli/cmd/wallet}/mnemonic_cmd.py +4 -4
- {mm_eth-0.3.1/src/mm_eth/cli/config_examples → mm_eth-0.4.1/src/mm_eth/cli/examples}/balances.toml +3 -0
- {mm_eth-0.3.1/src/mm_eth/cli/config_examples → mm_eth-0.4.1/src/mm_eth/cli/examples}/call_contract.toml +4 -0
- mm_eth-0.3.1/src/mm_eth/cli/config_examples/transfer_erc20.toml → mm_eth-0.4.1/src/mm_eth/cli/examples/transfer.toml +15 -3
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/validators.py +4 -0
- mm_eth-0.4.1/tests/cli/cmd/__init__.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_account.py +9 -1
- {mm_eth-0.3.1 → mm_eth-0.4.1}/uv.lock +47 -47
- mm_eth-0.3.1/src/mm_eth/cli/calcs.py +0 -93
- mm_eth-0.3.1/src/mm_eth/cli/cli_utils.py +0 -32
- mm_eth-0.3.1/src/mm_eth/cli/cmd/transfer_erc20_cmd.py +0 -200
- mm_eth-0.3.1/src/mm_eth/cli/cmd/transfer_eth_cmd.py +0 -182
- mm_eth-0.3.1/src/mm_eth/cli/config_examples/transfer_eth.toml +0 -26
- {mm_eth-0.3.1 → mm_eth-0.4.1}/.gitignore +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/README.txt +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/dict.dic +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/justfile +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/__init__.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/abi.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/anvil.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/__init__.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/__init__.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/balance_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/encode_input_data_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/node_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/rpc_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/solc_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/token_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/tx_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/vault_cmd.py +0 -0
- {mm_eth-0.3.1/tests → mm_eth-0.4.1/src/mm_eth/cli/cmd/wallet}/__init__.py +0 -0
- {mm_eth-0.3.1/src/mm_eth/cli/cmd → mm_eth-0.4.1/src/mm_eth/cli/cmd/wallet}/private_key_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/print_helpers.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/rpc_helpers.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/constants.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/deploy.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/ens.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/erc20.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/ethernodes.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/json_encoder.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/py.typed +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/rpc.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/solc.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/tx.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/utils.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/vault.py +0 -0
- {mm_eth-0.3.1/tests/cli → mm_eth-0.4.1/tests}/__init__.py +0 -0
- {mm_eth-0.3.1/tests/cli/cmd → mm_eth-0.4.1/tests/cli}/__init__.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_balance_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_mnemonic_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_node_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_private_key_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_solc_cmd.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/test_calcs.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/conftest.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/contracts/ERC20.sol +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/contracts/abi/ERC20.json +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_abi.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_ethernodes.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_rpc.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_tx.py +0 -0
- {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_utils.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mm-eth
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Requires-Python: >=3.12
|
|
5
|
-
Requires-Dist: mm-crypto-utils>=0.1.
|
|
5
|
+
Requires-Dist: mm-crypto-utils>=0.1.5
|
|
6
6
|
Requires-Dist: typer>=0.15.1
|
|
7
|
-
Requires-Dist: web3~=7.
|
|
7
|
+
Requires-Dist: web3~=7.8.0
|
|
8
8
|
Requires-Dist: websocket-client~=1.8.0
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mm-eth"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
description = ""
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
dependencies = [
|
|
7
|
-
"mm-crypto-utils>=0.1.
|
|
7
|
+
"mm-crypto-utils>=0.1.5",
|
|
8
8
|
"websocket-client~=1.8.0",
|
|
9
|
-
"web3~=7.
|
|
9
|
+
"web3~=7.8.0",
|
|
10
10
|
"typer>=0.15.1",
|
|
11
11
|
]
|
|
12
12
|
[project.scripts]
|
|
@@ -20,11 +20,11 @@ build-backend = "hatchling.build"
|
|
|
20
20
|
dev-dependencies = [
|
|
21
21
|
"pytest~=8.3.4",
|
|
22
22
|
"pytest-xdist~=3.6.1",
|
|
23
|
-
"ruff~=0.9.
|
|
23
|
+
"ruff~=0.9.5",
|
|
24
24
|
"pip-audit~=2.7.3",
|
|
25
25
|
"bandit~=1.8.2",
|
|
26
|
-
"mypy~=1.
|
|
27
|
-
"types-
|
|
26
|
+
"mypy~=1.15.0",
|
|
27
|
+
"types-pyyaml>=6.0.12.20241230",
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[tool.mypy]
|
|
@@ -13,9 +13,12 @@ Account.enable_unaudited_hdwallet_features()
|
|
|
13
13
|
|
|
14
14
|
key_api = KeyAPI()
|
|
15
15
|
|
|
16
|
+
DEFAULT_DERIVATION_PATH = "m/44'/60'/0'/0/{i}"
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
@dataclass
|
|
18
|
-
class
|
|
20
|
+
class DerivedAccount:
|
|
21
|
+
index: int
|
|
19
22
|
path: str
|
|
20
23
|
address: str
|
|
21
24
|
private_key: str
|
|
@@ -30,18 +33,15 @@ def generate_mnemonic(num_words: int = 24) -> str:
|
|
|
30
33
|
return mnemonic.generate(num_words=num_words)
|
|
31
34
|
|
|
32
35
|
|
|
33
|
-
def
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
limit: int = 12,
|
|
38
|
-
) -> list[NewAccount]:
|
|
39
|
-
result: list[NewAccount] = []
|
|
36
|
+
def derive_accounts(mnemonic: str, passphrase: str, derivation_path: str, limit: int) -> list[DerivedAccount]:
|
|
37
|
+
if "{i}" not in derivation_path:
|
|
38
|
+
raise ValueError("derivation_path must contain {i}, for example: " + DEFAULT_DERIVATION_PATH)
|
|
39
|
+
result: list[DerivedAccount] = []
|
|
40
40
|
for i in range(limit):
|
|
41
|
-
path =
|
|
42
|
-
acc = Account.from_mnemonic(mnemonic
|
|
41
|
+
path = derivation_path.replace("{i}", str(i))
|
|
42
|
+
acc = Account.from_mnemonic(mnemonic, passphrase, path)
|
|
43
43
|
private_key = acc.key.to_0x_hex().lower()
|
|
44
|
-
result.append(
|
|
44
|
+
result.append(DerivedAccount(i, path, acc.address, private_key))
|
|
45
45
|
return result
|
|
46
46
|
|
|
47
47
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import random
|
|
2
|
+
|
|
3
|
+
import mm_crypto_utils
|
|
4
|
+
from mm_crypto_utils import VarInt
|
|
5
|
+
|
|
6
|
+
from mm_eth.constants import SUFFIX_DECIMALS
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def calc_eth_expression(expression: str, var: VarInt | None = None) -> int:
|
|
10
|
+
return mm_crypto_utils.calc_int_expression(expression, var=var, suffix_decimals=SUFFIX_DECIMALS)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def calc_token_expression(expression: str, token_decimals: int, var: VarInt | None = None) -> int:
|
|
14
|
+
return mm_crypto_utils.calc_int_expression(expression, var=var, suffix_decimals={"t": token_decimals})
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def calc_function_args(value: str) -> str:
|
|
18
|
+
while True:
|
|
19
|
+
if "random(" not in value:
|
|
20
|
+
return value
|
|
21
|
+
start_index = value.index("random(")
|
|
22
|
+
stop_index = value.index(")", start_index)
|
|
23
|
+
random_range = [int(v.strip()) for v in value[start_index + 7 : stop_index].split(",")]
|
|
24
|
+
if len(random_range) != 2:
|
|
25
|
+
raise ValueError("wrong random(from,to) template")
|
|
26
|
+
rand_value = str(random.randint(random_range[0], random_range[1]))
|
|
27
|
+
value = value[0:start_index] + rand_value + value[stop_index + 1 :]
|
|
@@ -5,23 +5,22 @@ from typing import Annotated
|
|
|
5
5
|
import typer
|
|
6
6
|
from mm_std import PrintFormat, print_plain
|
|
7
7
|
|
|
8
|
+
from mm_eth.account import DEFAULT_DERIVATION_PATH
|
|
9
|
+
|
|
8
10
|
from . import cli_utils
|
|
9
11
|
from .cmd import (
|
|
10
12
|
balance_cmd,
|
|
11
13
|
balances_cmd,
|
|
12
14
|
call_contract_cmd,
|
|
13
|
-
config_example_cmd,
|
|
14
15
|
deploy_cmd,
|
|
15
16
|
encode_input_data_cmd,
|
|
16
|
-
|
|
17
|
+
example_cmd,
|
|
17
18
|
node_cmd,
|
|
18
|
-
private_key_cmd,
|
|
19
19
|
rpc_cmd,
|
|
20
20
|
send_contract_cmd,
|
|
21
21
|
solc_cmd,
|
|
22
22
|
token_cmd,
|
|
23
|
-
|
|
24
|
-
transfer_eth_cmd,
|
|
23
|
+
transfer_cmd,
|
|
25
24
|
tx_cmd,
|
|
26
25
|
vault_cmd,
|
|
27
26
|
)
|
|
@@ -29,8 +28,8 @@ from .cmd.balances_cmd import BalancesCmdParams
|
|
|
29
28
|
from .cmd.call_contract_cmd import CallContractCmdParams
|
|
30
29
|
from .cmd.deploy_cmd import DeployCmdParams
|
|
31
30
|
from .cmd.send_contract_cmd import SendContractCmdParams
|
|
32
|
-
from .cmd.
|
|
33
|
-
from .cmd.
|
|
31
|
+
from .cmd.transfer_cmd import TransferCmdParams
|
|
32
|
+
from .cmd.wallet import mnemonic_cmd, private_key_cmd
|
|
34
33
|
|
|
35
34
|
app = typer.Typer(no_args_is_help=True, pretty_exceptions_enable=False, add_completion=False)
|
|
36
35
|
|
|
@@ -40,8 +39,7 @@ app.add_typer(wallet_app, name="w", hidden=True)
|
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
class ConfigExample(str, Enum):
|
|
43
|
-
|
|
44
|
-
TRANSFER_ERC20 = "transfer-erc20"
|
|
42
|
+
TRANSFER = "transfer"
|
|
45
43
|
BALANCES = "balances"
|
|
46
44
|
CALL_CONTRACT = "call-contract"
|
|
47
45
|
|
|
@@ -77,9 +75,10 @@ def node_command(
|
|
|
77
75
|
@wallet_app.command(name="mnemonic", help="Generate eth accounts based on a mnemonic")
|
|
78
76
|
def mnemonic_command( # nosec
|
|
79
77
|
mnemonic: Annotated[str, typer.Option("--mnemonic", "-m")] = "",
|
|
80
|
-
passphrase: Annotated[str, typer.Option("--passphrase", "-
|
|
78
|
+
passphrase: Annotated[str, typer.Option("--passphrase", "-p")] = "",
|
|
81
79
|
print_path: bool = typer.Option(False, "--print_path"),
|
|
82
|
-
|
|
80
|
+
derivation_path: Annotated[str, typer.Option("--path")] = DEFAULT_DERIVATION_PATH,
|
|
81
|
+
words: int = typer.Option(12, "--words", "-w", help="Number of mnemonic words"),
|
|
83
82
|
limit: int = typer.Option(10, "--limit", "-l"),
|
|
84
83
|
save_file: str = typer.Option("", "--save", "-s", help="Save private keys to a file"),
|
|
85
84
|
) -> None:
|
|
@@ -88,7 +87,8 @@ def mnemonic_command( # nosec
|
|
|
88
87
|
passphrase=passphrase,
|
|
89
88
|
print_path=print_path,
|
|
90
89
|
limit=limit,
|
|
91
|
-
|
|
90
|
+
words=words,
|
|
91
|
+
derivation_path=derivation_path,
|
|
92
92
|
save_file=save_file,
|
|
93
93
|
)
|
|
94
94
|
|
|
@@ -141,43 +141,24 @@ def tx_command(
|
|
|
141
141
|
tx_cmd.run(rpc_url, tx_hash, get_receipt)
|
|
142
142
|
|
|
143
143
|
|
|
144
|
-
@app.command(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
print_config: bool = typer.Option(False, "--config", "-c", help="Print config and exit"),
|
|
149
|
-
emulate: bool = typer.Option(False, "--emulate", "-e", help="Emulate transaction posting"),
|
|
150
|
-
no_receipt: bool = typer.Option(False, "--no-receipt", "-nr", help="Don't wait for a tx receipt"),
|
|
151
|
-
debug: bool = typer.Option(False, "--debug", "-d", help="Print debug info"),
|
|
152
|
-
) -> None:
|
|
153
|
-
transfer_eth_cmd.run(
|
|
154
|
-
TransferEthCmdParams(
|
|
155
|
-
config_path=config_path,
|
|
156
|
-
print_balances=print_balances,
|
|
157
|
-
print_config_and_exit=print_config,
|
|
158
|
-
debug=debug,
|
|
159
|
-
no_receipt=no_receipt,
|
|
160
|
-
emulate=emulate,
|
|
161
|
-
)
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
@app.command(name="transfer-erc20", help="Transfer ERC20 token from one or many accounts")
|
|
166
|
-
def transfer_erc20_command(
|
|
144
|
+
@app.command(
|
|
145
|
+
name="transfer", help="Transfers ETH or ERC20 tokens, supporting multiple routes, delays, and expression-based values"
|
|
146
|
+
)
|
|
147
|
+
def transfer_command(
|
|
167
148
|
config_path: Path,
|
|
168
149
|
print_balances: bool = typer.Option(False, "--balances", "-b", help="Print balances and exit"),
|
|
169
150
|
print_config: bool = typer.Option(False, "--config", "-c", help="Print config and exit"),
|
|
170
151
|
emulate: bool = typer.Option(False, "--emulate", "-e", help="Emulate transaction posting"),
|
|
171
|
-
|
|
152
|
+
skip_receipt: bool = typer.Option(False, "--skip-receipt", help="Don't wait for a tx receipt"),
|
|
172
153
|
debug: bool = typer.Option(False, "--debug", "-d", help="Print debug info"),
|
|
173
154
|
) -> None:
|
|
174
|
-
|
|
175
|
-
|
|
155
|
+
transfer_cmd.run(
|
|
156
|
+
TransferCmdParams(
|
|
176
157
|
config_path=config_path,
|
|
177
158
|
print_balances=print_balances,
|
|
178
|
-
|
|
159
|
+
print_config=print_config,
|
|
179
160
|
debug=debug,
|
|
180
|
-
|
|
161
|
+
skip_receipt=skip_receipt,
|
|
181
162
|
emulate=emulate,
|
|
182
163
|
)
|
|
183
164
|
)
|
|
@@ -196,7 +177,7 @@ def send_contract_command(
|
|
|
196
177
|
SendContractCmdParams(
|
|
197
178
|
config_path=config_path,
|
|
198
179
|
print_balances=print_balances,
|
|
199
|
-
|
|
180
|
+
print_config=print_config,
|
|
200
181
|
debug=debug,
|
|
201
182
|
no_receipt=no_receipt,
|
|
202
183
|
emulate=emulate,
|
|
@@ -211,7 +192,7 @@ def balances_command(
|
|
|
211
192
|
nonce: bool = typer.Option(False, "--nonce", "-n", help="Print nonce also"),
|
|
212
193
|
wei: bool = typer.Option(False, "--wei", "-w", help="Show balances in WEI"),
|
|
213
194
|
) -> None:
|
|
214
|
-
balances_cmd.run(BalancesCmdParams(config_path=config_path,
|
|
195
|
+
balances_cmd.run(BalancesCmdParams(config_path=config_path, print_config=print_config, wei=wei, show_nonce=nonce))
|
|
215
196
|
|
|
216
197
|
|
|
217
198
|
@app.command(name="call-contract", help="Call a method on a contract")
|
|
@@ -219,7 +200,7 @@ def call_contract_command(
|
|
|
219
200
|
config_path: Path,
|
|
220
201
|
print_config: bool = typer.Option(False, "--config", "-c", help="Print config and exit"),
|
|
221
202
|
) -> None:
|
|
222
|
-
call_contract_cmd.run(CallContractCmdParams(config_path=config_path,
|
|
203
|
+
call_contract_cmd.run(CallContractCmdParams(config_path=config_path, print_config=print_config))
|
|
223
204
|
|
|
224
205
|
|
|
225
206
|
@app.command(name="deploy", help="Deploy a smart contract onchain")
|
|
@@ -227,12 +208,12 @@ def deploy_command(
|
|
|
227
208
|
config_path: Path,
|
|
228
209
|
print_config: bool = typer.Option(False, "--config", "-c", help="Print config and exit"),
|
|
229
210
|
) -> None:
|
|
230
|
-
deploy_cmd.run(DeployCmdParams(config_path=config_path,
|
|
211
|
+
deploy_cmd.run(DeployCmdParams(config_path=config_path, print_config=print_config))
|
|
231
212
|
|
|
232
213
|
|
|
233
|
-
@app.command(name="
|
|
234
|
-
def
|
|
235
|
-
|
|
214
|
+
@app.command(name="example", help="Displays an example configuration for a command")
|
|
215
|
+
def example_command(command: Annotated[ConfigExample, typer.Argument()]) -> None:
|
|
216
|
+
example_cmd.run(command)
|
|
236
217
|
|
|
237
218
|
|
|
238
219
|
@app.command(name="encode-input-data", help="Encode input data by a function signature")
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
import time
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
from mm_crypto_utils import Nodes, Proxies
|
|
7
|
+
from mm_std import BaseConfig, print_json
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
from mm_eth import rpc
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_version() -> str:
|
|
14
|
+
return importlib.metadata.version("mm-eth")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def public_rpc_url(url: str | None) -> str:
|
|
18
|
+
if not url or url == "1":
|
|
19
|
+
return "https://ethereum.publicnode.com"
|
|
20
|
+
if url.startswith(("http://", "https://", "ws://", "wss://")):
|
|
21
|
+
return url
|
|
22
|
+
|
|
23
|
+
match url.lower():
|
|
24
|
+
case "mainnet" | "1":
|
|
25
|
+
return "https://ethereum.publicnode.com"
|
|
26
|
+
case "opbnb" | "204":
|
|
27
|
+
return "https://opbnb-mainnet-rpc.bnbchain.org"
|
|
28
|
+
case "base" | "8453":
|
|
29
|
+
return "https://mainnet.base.org"
|
|
30
|
+
case "base-sepolia" | "84532":
|
|
31
|
+
return "https://sepolia.base.org"
|
|
32
|
+
case _:
|
|
33
|
+
return url
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class BaseConfigParams(BaseModel):
|
|
37
|
+
config_path: Path
|
|
38
|
+
print_config: bool
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def print_config(config: BaseConfig, exclude: set[str] | None = None, count: set[str] | None = None) -> None:
|
|
42
|
+
data = config.model_dump(exclude=exclude)
|
|
43
|
+
if count:
|
|
44
|
+
for k in count:
|
|
45
|
+
data[k] = len(data[k])
|
|
46
|
+
print_json(data)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def wait_tx_status(nodes: Nodes, proxies: Proxies, tx_hash: str, timeout: int) -> Literal["OK", "FAIL", "TIMEOUT"]:
|
|
50
|
+
started_at = time.perf_counter()
|
|
51
|
+
count = 0
|
|
52
|
+
while True:
|
|
53
|
+
res = rpc.get_tx_status(nodes, tx_hash, proxies=proxies, attempts=5)
|
|
54
|
+
if res.is_ok():
|
|
55
|
+
return "OK" if res.ok == 1 else "FAIL"
|
|
56
|
+
|
|
57
|
+
time.sleep(1)
|
|
58
|
+
count += 1
|
|
59
|
+
if time.perf_counter() - started_at > timeout:
|
|
60
|
+
return "TIMEOUT"
|
|
@@ -33,7 +33,7 @@ class BalancesCmdParams(BaseConfigParams):
|
|
|
33
33
|
|
|
34
34
|
def run(params: BalancesCmdParams) -> None:
|
|
35
35
|
config = Config.read_toml_config_or_exit(params.config_path)
|
|
36
|
-
if params.
|
|
36
|
+
if params.print_config:
|
|
37
37
|
config.print_and_exit()
|
|
38
38
|
|
|
39
39
|
tokens = _get_tokens_info(config)
|
|
@@ -22,7 +22,7 @@ class CallContractCmdParams(BaseConfigParams):
|
|
|
22
22
|
|
|
23
23
|
def run(cli_params: CallContractCmdParams) -> None:
|
|
24
24
|
config = Config.read_toml_config_or_exit(cli_params.config_path)
|
|
25
|
-
if cli_params.
|
|
25
|
+
if cli_params.print_config:
|
|
26
26
|
config.print_and_exit()
|
|
27
27
|
|
|
28
28
|
input_data = abi.encode_function_input_by_signature(
|
|
@@ -27,7 +27,7 @@ class DeployCmdParams(BaseConfigParams):
|
|
|
27
27
|
|
|
28
28
|
def run(cli_params: DeployCmdParams) -> None:
|
|
29
29
|
config = Config.read_toml_config_or_exit(cli_params.config_path)
|
|
30
|
-
if cli_params.
|
|
30
|
+
if cli_params.print_config:
|
|
31
31
|
config.print_and_exit({"private_key"})
|
|
32
32
|
|
|
33
33
|
constructor_types = yaml.full_load(config.constructor_types)
|
|
@@ -5,5 +5,5 @@ from mm_std import print_plain
|
|
|
5
5
|
|
|
6
6
|
def run(command: str) -> None:
|
|
7
7
|
command = command.replace("-", "_")
|
|
8
|
-
example_file = Path(Path(__file__).parent.absolute(), "../
|
|
8
|
+
example_file = Path(Path(__file__).parent.absolute(), "../examples", f"{command}.toml")
|
|
9
9
|
print_plain(example_file.read_text())
|
|
@@ -65,7 +65,7 @@ class SendContractCmdParams(BaseConfigParams):
|
|
|
65
65
|
# noinspection DuplicatedCode
|
|
66
66
|
def run(cli_params: SendContractCmdParams) -> None:
|
|
67
67
|
config = Config.read_toml_config_or_exit(cli_params.config_path)
|
|
68
|
-
if cli_params.
|
|
68
|
+
if cli_params.print_config:
|
|
69
69
|
config.print_and_exit({"private_key"})
|
|
70
70
|
|
|
71
71
|
mm_crypto_utils.init_logger(cli_params.debug, config.log_debug, config.log_info)
|