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.
Files changed (74) hide show
  1. {mm_eth-0.3.1 → mm_eth-0.4.1}/PKG-INFO +3 -3
  2. {mm_eth-0.3.1 → mm_eth-0.4.1}/pyproject.toml +6 -6
  3. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/account.py +11 -11
  4. mm_eth-0.4.1/src/mm_eth/cli/calcs.py +27 -0
  5. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cli.py +28 -47
  6. mm_eth-0.4.1/src/mm_eth/cli/cli_utils.py +60 -0
  7. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/balances_cmd.py +1 -1
  8. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/call_contract_cmd.py +1 -1
  9. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/deploy_cmd.py +1 -1
  10. 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
  11. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/send_contract_cmd.py +1 -1
  12. mm_eth-0.4.1/src/mm_eth/cli/cmd/transfer_cmd.py +311 -0
  13. {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
  14. {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
  15. {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
  16. 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
  17. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/validators.py +4 -0
  18. mm_eth-0.4.1/tests/cli/cmd/__init__.py +0 -0
  19. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_account.py +9 -1
  20. {mm_eth-0.3.1 → mm_eth-0.4.1}/uv.lock +47 -47
  21. mm_eth-0.3.1/src/mm_eth/cli/calcs.py +0 -93
  22. mm_eth-0.3.1/src/mm_eth/cli/cli_utils.py +0 -32
  23. mm_eth-0.3.1/src/mm_eth/cli/cmd/transfer_erc20_cmd.py +0 -200
  24. mm_eth-0.3.1/src/mm_eth/cli/cmd/transfer_eth_cmd.py +0 -182
  25. mm_eth-0.3.1/src/mm_eth/cli/config_examples/transfer_eth.toml +0 -26
  26. {mm_eth-0.3.1 → mm_eth-0.4.1}/.gitignore +0 -0
  27. {mm_eth-0.3.1 → mm_eth-0.4.1}/README.txt +0 -0
  28. {mm_eth-0.3.1 → mm_eth-0.4.1}/dict.dic +0 -0
  29. {mm_eth-0.3.1 → mm_eth-0.4.1}/justfile +0 -0
  30. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/__init__.py +0 -0
  31. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/abi.py +0 -0
  32. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/anvil.py +0 -0
  33. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/__init__.py +0 -0
  34. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/__init__.py +0 -0
  35. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/balance_cmd.py +0 -0
  36. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/encode_input_data_cmd.py +0 -0
  37. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/node_cmd.py +0 -0
  38. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/rpc_cmd.py +0 -0
  39. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/solc_cmd.py +0 -0
  40. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/token_cmd.py +0 -0
  41. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/tx_cmd.py +0 -0
  42. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/cmd/vault_cmd.py +0 -0
  43. {mm_eth-0.3.1/tests → mm_eth-0.4.1/src/mm_eth/cli/cmd/wallet}/__init__.py +0 -0
  44. {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
  45. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/print_helpers.py +0 -0
  46. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/cli/rpc_helpers.py +0 -0
  47. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/constants.py +0 -0
  48. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/deploy.py +0 -0
  49. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/ens.py +0 -0
  50. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/erc20.py +0 -0
  51. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/ethernodes.py +0 -0
  52. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/json_encoder.py +0 -0
  53. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/py.typed +0 -0
  54. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/rpc.py +0 -0
  55. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/solc.py +0 -0
  56. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/tx.py +0 -0
  57. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/utils.py +0 -0
  58. {mm_eth-0.3.1 → mm_eth-0.4.1}/src/mm_eth/vault.py +0 -0
  59. {mm_eth-0.3.1/tests/cli → mm_eth-0.4.1/tests}/__init__.py +0 -0
  60. {mm_eth-0.3.1/tests/cli/cmd → mm_eth-0.4.1/tests/cli}/__init__.py +0 -0
  61. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_balance_cmd.py +0 -0
  62. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_mnemonic_cmd.py +0 -0
  63. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_node_cmd.py +0 -0
  64. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_private_key_cmd.py +0 -0
  65. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/cmd/test_solc_cmd.py +0 -0
  66. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/cli/test_calcs.py +0 -0
  67. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/conftest.py +0 -0
  68. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/contracts/ERC20.sol +0 -0
  69. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/contracts/abi/ERC20.json +0 -0
  70. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_abi.py +0 -0
  71. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_ethernodes.py +0 -0
  72. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_rpc.py +0 -0
  73. {mm_eth-0.3.1 → mm_eth-0.4.1}/tests/test_tx.py +0 -0
  74. {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.1
3
+ Version: 0.4.1
4
4
  Requires-Python: >=3.12
5
- Requires-Dist: mm-crypto-utils>=0.1.4
5
+ Requires-Dist: mm-crypto-utils>=0.1.5
6
6
  Requires-Dist: typer>=0.15.1
7
- Requires-Dist: web3~=7.7.0
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.1"
3
+ version = "0.4.1"
4
4
  description = ""
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
7
- "mm-crypto-utils>=0.1.4",
7
+ "mm-crypto-utils>=0.1.5",
8
8
  "websocket-client~=1.8.0",
9
- "web3~=7.7.0",
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.4",
23
+ "ruff~=0.9.5",
24
24
  "pip-audit~=2.7.3",
25
25
  "bandit~=1.8.2",
26
- "mypy~=1.14.1",
27
- "types-PyYAML~=6.0.12.20241230",
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 NewAccount:
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 generate_accounts( # nosec
34
- mnemonic: str,
35
- passphrase: str = "",
36
- path_prefix: str = "m/44'/60'/0'/0",
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 = f"{path_prefix}/{i}"
42
- acc = Account.from_mnemonic(mnemonic=mnemonic, account_path=path, passphrase=passphrase)
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(NewAccount(path, acc.address, private_key))
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
- mnemonic_cmd,
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
- transfer_erc20_cmd,
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.transfer_erc20_cmd import TransferErc20CmdParams
33
- from .cmd.transfer_eth_cmd import TransferEthCmdParams
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
- TRANSFER_ETH = "transfer-eth"
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", "-pass")] = "",
78
+ passphrase: Annotated[str, typer.Option("--passphrase", "-p")] = "",
81
79
  print_path: bool = typer.Option(False, "--print_path"),
82
- path_prefix: Annotated[str, typer.Option("--path")] = "m/44'/60'/0'/0",
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
- path_prefix=path_prefix,
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(name="transfer-eth", help="Transfer eth / base token from one or many accounts")
145
- def transfer_eth_command(
146
- config_path: Path,
147
- print_balances: bool = typer.Option(False, "--balances", "-b", help="Print balances and exit"),
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
- no_receipt: bool = typer.Option(False, "--no-receipt", "-nr", help="Don't wait for a tx receipt"),
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
- transfer_erc20_cmd.run(
175
- TransferErc20CmdParams(
155
+ transfer_cmd.run(
156
+ TransferCmdParams(
176
157
  config_path=config_path,
177
158
  print_balances=print_balances,
178
- print_config_and_exit=print_config,
159
+ print_config=print_config,
179
160
  debug=debug,
180
- no_receipt=no_receipt,
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
- print_config_and_exit=print_config,
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, print_config_and_exit=print_config, wei=wei, show_nonce=nonce))
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, print_config_and_exit=print_config))
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, print_config_and_exit=print_config))
211
+ deploy_cmd.run(DeployCmdParams(config_path=config_path, print_config=print_config))
231
212
 
232
213
 
233
- @app.command(name="config-example", help="Print an example of config for a command")
234
- def config_example_command(command: Annotated[ConfigExample, typer.Argument()]) -> None:
235
- config_example_cmd.run(command)
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.print_config_and_exit:
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.print_config_and_exit:
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.print_config_and_exit:
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(), "../config_examples", f"{command}.toml")
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.print_config_and_exit:
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)