mm-eth 0.7.3__py3-none-any.whl → 0.8.0__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/rpc.py CHANGED
@@ -1,3 +1,5 @@
1
+ """Low-level async Ethereum JSON-RPC client supporting HTTP and WebSocket."""
2
+
1
3
  import asyncio
2
4
  import json
3
5
  import string
@@ -24,6 +26,7 @@ async def rpc_call(
24
26
  proxy: str | None,
25
27
  id_: int = 1,
26
28
  ) -> Result[Any]:
29
+ """Send a JSON-RPC request to the node via HTTP or WebSocket."""
27
30
  data = {"jsonrpc": "2.0", "method": method, "params": params, "id": id_}
28
31
  if node.startswith("http"):
29
32
  return await _http_call(node, data, timeout, proxy)
@@ -31,11 +34,12 @@ async def rpc_call(
31
34
 
32
35
 
33
36
  async def _http_call(node: str, data: dict[str, object], timeout: float, proxy: str | None) -> Result[Any]:
37
+ """Send a JSON-RPC request over HTTP POST."""
34
38
  res = await http_request(node, method="POST", proxy=proxy, timeout=timeout, json=data)
35
39
  if res.is_err():
36
40
  return res.to_result_err()
37
41
  try:
38
- parsed_body = res.parse_json()
42
+ parsed_body = res.json_body().unwrap("invalid json response")
39
43
  err = parsed_body.get("error", {}).get("message", "")
40
44
  if err:
41
45
  return res.to_result_err(f"service_error: {err}")
@@ -47,6 +51,7 @@ async def _http_call(node: str, data: dict[str, object], timeout: float, proxy:
47
51
 
48
52
 
49
53
  async def _ws_call(node: str, data: dict[str, object], timeout: float) -> Result[Any]:
54
+ """Send a JSON-RPC request over WebSocket."""
50
55
  try:
51
56
  async with asyncio.timeout(timeout):
52
57
  async with websockets.connect(node) as ws:
@@ -69,25 +74,30 @@ async def _ws_call(node: str, data: dict[str, object], timeout: float) -> Result
69
74
 
70
75
 
71
76
  async def eth_block_number(node: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
77
+ """Return the current block number."""
72
78
  return (await rpc_call(node, "eth_blockNumber", [], timeout, proxy)).map(_hex_str_to_int)
73
79
 
74
80
 
75
81
  async def eth_get_balance(node: str, address: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
82
+ """Return the ETH balance (in wei) of the given address."""
76
83
  return (await rpc_call(node, "eth_getBalance", [address, "latest"], timeout, proxy)).map(_hex_str_to_int)
77
84
 
78
85
 
79
86
  async def eth_chain_id(node: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
87
+ """Return the chain ID of the connected network."""
80
88
  return (await rpc_call(node, "eth_chainId", [], timeout, proxy)).map(_hex_str_to_int)
81
89
 
82
90
 
83
91
  async def eth_get_block_by_number(
84
92
  node: str, block_number: BlockIdentifier, full_transaction: bool = False, timeout: float = TIMEOUT, proxy: str | None = None
85
93
  ) -> Result[dict[str, Any]]:
94
+ """Return block data for the given block number or tag."""
86
95
  params = [hex(block_number) if isinstance(block_number, int) else block_number, full_transaction]
87
96
  return await rpc_call(node, "eth_getBlockByNumber", params, timeout, proxy)
88
97
 
89
98
 
90
99
  async def eth_get_transaction_count(node: str, address: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
100
+ """Return the nonce (transaction count) for the given address."""
91
101
  return (await rpc_call(node, "eth_getTransactionCount", [address, "latest"], timeout, proxy)).map(_hex_str_to_int)
92
102
 
93
103
 
@@ -101,6 +111,7 @@ async def eth_estimate_gas(
101
111
  timeout: float = TIMEOUT,
102
112
  proxy: str | None = None,
103
113
  ) -> Result[int]:
114
+ """Estimate the gas required for a transaction."""
104
115
  params: dict[str, Any] = {"from": from_}
105
116
  if to:
106
117
  params["to"] = to
@@ -114,12 +125,15 @@ async def eth_estimate_gas(
114
125
 
115
126
 
116
127
  async def eth_send_raw_transaction(node: str, raw_tx: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[str]:
128
+ """Broadcast a signed raw transaction and return its hash."""
117
129
  return await rpc_call(node, "eth_sendRawTransaction", [raw_tx], timeout, proxy)
118
130
 
119
131
 
120
132
  async def eth_get_transaction_receipt(
121
133
  node: str, tx_hash: str, timeout: float = TIMEOUT, proxy: str | None = None
122
134
  ) -> Result[TxReceipt]:
135
+ """Fetch the transaction receipt, converting hex string fields to integers."""
136
+
123
137
  def convert_hex_str_ints(receipt: dict[str, Any]) -> TxReceipt:
124
138
  int_fields = {
125
139
  "blockNumber",
@@ -145,12 +159,12 @@ async def eth_get_transaction_receipt(
145
159
  return res
146
160
 
147
161
  if res.unwrap() is None:
148
- return Result.err("no_receipt", res.extra)
162
+ return Result.err("no_receipt", res.context)
149
163
 
150
164
  try:
151
- return Result.ok(convert_hex_str_ints(res.unwrap()), res.extra)
165
+ return Result.ok(convert_hex_str_ints(res.unwrap()), res.context)
152
166
  except Exception as e:
153
- return Result.err(e, res.extra)
167
+ return Result.err(e, res.context)
154
168
 
155
169
 
156
170
  # -- end eth rpc calls --
@@ -159,22 +173,26 @@ async def eth_get_transaction_receipt(
159
173
 
160
174
 
161
175
  async def erc20_balance(node: str, token: str, wallet: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
176
+ """Return the ERC-20 token balance for a wallet address."""
162
177
  data = "0x70a08231000000000000000000000000" + wallet[2:]
163
178
  params = [{"to": token, "data": data}, "latest"]
164
179
  return (await rpc_call(node, "eth_call", params, timeout, proxy)).map(_hex_str_to_int)
165
180
 
166
181
 
167
182
  async def erc20_name(node: str, token: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[str]:
183
+ """Return the name of an ERC-20 token."""
168
184
  params = [{"to": token, "data": "0x06fdde03"}, "latest"]
169
185
  return (await rpc_call(node, "eth_call", params, timeout, proxy)).map(_normalize_str)
170
186
 
171
187
 
172
188
  async def erc20_symbol(node: str, token: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[str]:
189
+ """Return the symbol of an ERC-20 token."""
173
190
  params = [{"to": token, "data": "0x95d89b41"}, "latest"]
174
191
  return (await rpc_call(node, "eth_call", params, timeout, proxy)).map(_normalize_str)
175
192
 
176
193
 
177
194
  async def erc20_decimals(node: str, token: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
195
+ """Return the number of decimals for an ERC-20 token."""
178
196
  params = [{"to": token, "data": "0x313ce567"}, "latest"]
179
197
  res = await rpc_call(node, "eth_call", params, timeout, proxy)
180
198
  if res.is_err():
@@ -195,6 +213,7 @@ async def erc20_decimals(node: str, token: str, timeout: float = TIMEOUT, proxy:
195
213
 
196
214
 
197
215
  async def ens_name(node: str, address: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[str | None]:
216
+ """Perform reverse ENS resolution for an address, returning the ENS name or None."""
198
217
  ens_registry_address: str = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
199
218
  func_selector_resolver: str = "0x0178b8bf" # resolver(bytes32)
200
219
  func_selector_name: str = "0x691f3431" # name(bytes32)
@@ -247,22 +266,24 @@ async def ens_name(node: str, address: str, timeout: float = TIMEOUT, proxy: str
247
266
 
248
267
 
249
268
  async def get_base_fee_per_gas(node: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
269
+ """Return the base fee per gas from the latest block."""
250
270
  res = await eth_get_block_by_number(node, "latest", False, timeout=timeout, proxy=proxy)
251
271
  if res.is_err():
252
- return Result.err(res.unwrap_err(), res.extra)
272
+ return Result.err(res.unwrap_err(), res.context)
253
273
  if "baseFeePerGas" in res.unwrap():
254
274
  return res.with_value(int(res.unwrap()["baseFeePerGas"], 16))
255
- return Result.err("no_base_fee_per_gas", res.extra)
275
+ return Result.err("no_base_fee_per_gas", res.context)
256
276
 
257
277
 
258
278
  async def get_tx_status(node: str, tx_hash: str, timeout: float = TIMEOUT, proxy: str | None = None) -> Result[int]:
279
+ """Return the status field (0=fail, 1=success) from a transaction receipt."""
259
280
  res = await eth_get_transaction_receipt(node, tx_hash, timeout=timeout, proxy=proxy)
260
281
  if res.is_err():
261
- return Result.err(res.unwrap_err(), res.extra)
282
+ return Result.err(res.unwrap_err(), res.context)
262
283
  status = res.unwrap().get("status")
263
284
  if status is None:
264
- return Result.err("no_status", res.extra)
265
- return Result.ok(status, res.extra)
285
+ return Result.err("no_status", res.context)
286
+ return Result.ok(status, res.context)
266
287
 
267
288
 
268
289
  # -- end other --
@@ -271,8 +292,10 @@ async def get_tx_status(node: str, tx_hash: str, timeout: float = TIMEOUT, proxy
271
292
 
272
293
 
273
294
  def _hex_str_to_int(value: str) -> int:
295
+ """Convert a hex string to an integer."""
274
296
  return int(value, 16)
275
297
 
276
298
 
277
299
  def _normalize_str(value: str) -> str:
300
+ """Decode a hex string to text and filter out non-printable characters."""
278
301
  return "".join(filter(lambda x: x in string.printable, eth_utils.to_text(hexstr=value))).strip()
mm_eth/solc.py CHANGED
@@ -1,3 +1,5 @@
1
+ """Solidity compiler (solc) wrapper."""
2
+
1
3
  import random
2
4
  import re
3
5
  import shutil
@@ -10,11 +12,14 @@ from mm_result import Result
10
12
 
11
13
  @dataclass
12
14
  class SolcResult:
15
+ """Compilation output containing contract binary and ABI."""
16
+
13
17
  bin: str
14
18
  abi: str
15
19
 
16
20
 
17
21
  def solc(contract_name: str, contract_path: Path, tmp_dir: Path) -> Result[SolcResult]:
22
+ """Compile a Solidity contract using the solc CLI and return the binary and ABI."""
18
23
  # Sanitize contract name to avoid unsafe characters in directory name
19
24
  safe_name = re.sub(r"[^a-zA-Z0-9_\-]", "_", contract_name)
20
25
 
@@ -32,7 +37,7 @@ def solc(contract_name: str, contract_path: Path, tmp_dir: Path) -> Result[SolcR
32
37
  work_dir_created = True
33
38
 
34
39
  cmd = f"solc -o '{work_dir}' --abi --bin --optimize '{contract_path}'"
35
- result = mm_std.shell(cmd)
40
+ result = mm_std.run_cmd(cmd)
36
41
  if result.code != 0:
37
42
  return Result.err(f"solc error: {result.stderr}")
38
43
 
mm_eth/tx.py CHANGED
@@ -1,3 +1,5 @@
1
+ """Ethereum transaction signing, encoding, and decoding."""
2
+
1
3
  from __future__ import annotations
2
4
 
3
5
  from typing import Any
@@ -12,11 +14,15 @@ from web3 import Web3
12
14
 
13
15
 
14
16
  class SignedTx(BaseModel):
17
+ """A signed transaction with its hash and raw encoded form."""
18
+
15
19
  tx_hash: str
16
20
  raw_tx: str
17
21
 
18
22
 
19
23
  class RPLTransaction(rlp.Serializable): # type: ignore[misc]
24
+ """RLP-serializable legacy Ethereum transaction."""
25
+
20
26
  fields = [ # noqa: RUF012
21
27
  ("nonce", big_endian_int),
22
28
  ("gas_price", big_endian_int),
@@ -42,6 +48,7 @@ class RPLTransaction(rlp.Serializable): # type: ignore[misc]
42
48
  value: int | None = None,
43
49
  to: str | None = None,
44
50
  ) -> RPLTransaction:
51
+ """Create an RPLTransaction from individual field values."""
45
52
  if to:
46
53
  to = eth_utils.to_bytes(hexstr=HexStr(to)) # type:ignore[assignment]
47
54
  if data:
@@ -52,6 +59,8 @@ class RPLTransaction(rlp.Serializable): # type: ignore[misc]
52
59
 
53
60
 
54
61
  class DecodedRawTx(BaseModel):
62
+ """Decoded fields from a raw legacy transaction."""
63
+
55
64
  tx_hash: str
56
65
  from_: str
57
66
  to: str | None
@@ -78,6 +87,7 @@ def encode_raw_tx_with_signature(
78
87
  value: int | None = None,
79
88
  to: str | None = None,
80
89
  ) -> str:
90
+ """RLP-encodes a legacy transaction with its signature into a raw hex string."""
81
91
  tx = RPLTransaction.new_tx(nonce=nonce, gas_price=gas_price, gas=gas, v=v, r=r, s=s, data=data, value=value, to=to)
82
92
  return Web3.to_hex(rlp.encode(tx))
83
93
 
@@ -93,6 +103,7 @@ def sign_legacy_tx(
93
103
  value: int | None = None,
94
104
  to: str | None = None,
95
105
  ) -> SignedTx:
106
+ """Signs a legacy (type 0) Ethereum transaction."""
96
107
  tx: dict[str, Any] = {"gas": gas, "gasPrice": gas_price, "nonce": nonce, "chainId": chain_id}
97
108
  if to:
98
109
  tx["to"] = Web3.to_checksum_address(to)
@@ -117,6 +128,7 @@ def sign_tx(
117
128
  value: int | None = None,
118
129
  to: str | None = None,
119
130
  ) -> SignedTx:
131
+ """Signs an EIP-1559 (type 2) Ethereum transaction."""
120
132
  tx: dict[str, Any] = {
121
133
  "type": "0x2",
122
134
  "gas": gas,
@@ -137,6 +149,7 @@ def sign_tx(
137
149
 
138
150
 
139
151
  def decode_raw_tx(raw_tx: str) -> DecodedRawTx:
152
+ """Decode a raw legacy transaction hex string into its component fields."""
140
153
  tx: Any = rlp.decode(eth_utils.to_bytes(hexstr=HexStr(raw_tx)), RPLTransaction)
141
154
  tx_hash = Web3.to_hex(eth_utils.keccak(eth_utils.to_bytes(hexstr=HexStr(raw_tx))))
142
155
  from_ = Account.recover_transaction(raw_tx)
mm_eth/utils.py CHANGED
@@ -1,4 +1,8 @@
1
+ """Ethereum network utility helpers."""
2
+
3
+
1
4
  def name_network(chain_id: int) -> str:
5
+ """Return the human-readable network name for a given chain ID."""
2
6
  match chain_id:
3
7
  case 1:
4
8
  return "Ethereum Mainnet"
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: mm-eth
3
+ Version: 0.8.0
4
+ Requires-Python: >=3.14
5
+ Requires-Dist: mm-web3~=0.6.2
6
+ Requires-Dist: typer~=0.21.1
7
+ Requires-Dist: web3~=7.14.1
@@ -0,0 +1,33 @@
1
+ mm_eth/__init__.py,sha256=xYOepsDzwAkYNwrkD26a_J47kbXWqBo_6-bCJTtuXuc,59
2
+ mm_eth/abi.py,sha256=h1G_8GCaCRD1ubBfz7kAAyCy7J2jsKT9VsP2z-N2AYI,5647
3
+ mm_eth/account.py,sha256=WZvx9wPNraMiIUJ-eTx6EtHX3zr7tcWiMEr6oNa5FPk,2185
4
+ mm_eth/anvil.py,sha256=7rye8doUFN5irM1l_X2B6wirJ98oJQveqY3Xwh383Bo,2371
5
+ mm_eth/converters.py,sha256=aoq8PItX6CGVydqYcZm8yA55nMOQnkZcY4malz8QWLA,2271
6
+ mm_eth/deploy.py,sha256=8OODAraL8Du2vhZZOVH2DqsIYSOfOXxqt2DuHyPjISA,926
7
+ mm_eth/erc20.py,sha256=zT2M2q1gLhftIIVohl74Vy8y9ttefSDoErFOraV2SEw,1313
8
+ mm_eth/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ mm_eth/retry.py,sha256=2TWrW2mtPmU2P0etnIFxMsAGpuHhHCfxEujvmeyHFos,6145
10
+ mm_eth/rpc.py,sha256=bVPTvYNe-xHJO0k0iv4zD4QznZs48Jvu4ZeJqjE5ObM,11284
11
+ mm_eth/solc.py,sha256=EJ--QLMYSCEmQ-QKSusi8kTbmLRYVHrvbgiKZ7DFnno,1550
12
+ mm_eth/tx.py,sha256=hhMSrl0IXac2ECRy_nK665s8WuGvMSy-ztY-roGtzq8,4687
13
+ mm_eth/utils.py,sha256=yazVVnE01wYGm78QWoc9JVe9UEkSemUZUggoyAM9v54,772
14
+ mm_eth/cli/__init__.py,sha256=602kV0Xgced03NIWsXqLPAnDueW31gI1EsgXaELUJPk,32
15
+ mm_eth/cli/calcs.py,sha256=_u6B4HHvpKfa-wlKgiciK4Kgx_vO8NpOxWqkas7oyyQ,704
16
+ mm_eth/cli/cli.py,sha256=LKyvaC-DchVJCHQBaejNHuIw4TJmZvTQWB9qqQtpEpo,6265
17
+ mm_eth/cli/cli_utils.py,sha256=ybc23MT2fsPhqegNWlepTNO_DWAU7dT6mY27NzjSa0k,2157
18
+ mm_eth/cli/rpc_helpers.py,sha256=7QWPIdfTdUq-yZCiPMhVl-sWsl5s2oQ2yiKstiu1M74,1990
19
+ mm_eth/cli/validators.py,sha256=lFm2aQAlatLYvFXt2tZf3agctWMSmJwefVKsmMRZ8Ro,2369
20
+ mm_eth/cli/cmd/__init__.py,sha256=GYdoNv80KS2p7bCThuoRbhiLmIZW6ddPqPEFEx567nQ,35
21
+ mm_eth/cli/cmd/balance_cmd.py,sha256=dl1dn9ZrETlEjMU-jwNDdlkJhhtTzO59c3fuAfnJ-Ds,2097
22
+ mm_eth/cli/cmd/balances_cmd.py,sha256=BqwiHGL58mGEqDJv7tKus5Y3Ekh3z54A7BQHDWUEKR0,4597
23
+ mm_eth/cli/cmd/deploy_cmd.py,sha256=mKt9R-YZSA1Mx-6hNzy1gGR1ooy_UrMGO84R0pQDDZ0,1717
24
+ mm_eth/cli/cmd/node_cmd.py,sha256=kDh00h5_keNbcihosNbfGx80tzK1F4CjZJwvL_kx_Yw,3151
25
+ mm_eth/cli/cmd/solc_cmd.py,sha256=Hhwv58rZwh5Ge2iz5Qh_O-qbwMkhTlupkS187HGC-hY,806
26
+ mm_eth/cli/cmd/transfer_cmd.py,sha256=MotS0DDAc9Qd4y8svFF52laA0-tjNK-rFI9p4R_ZN0c,18557
27
+ mm_eth/cli/cmd/wallet/__init__.py,sha256=et8EPGCXsVukSYnO29E1Wn_O0_Sf8FKxc-09UuFL_gk,35
28
+ mm_eth/cli/cmd/wallet/mnemonic_cmd.py,sha256=voVNPAdkN5YRnC1BJB1YX3pSHlHnl_9fwSzGeiKPjag,1151
29
+ mm_eth/cli/cmd/wallet/private_key_cmd.py,sha256=MdvbWKcUNgnJdLEleRZDb4qnsQHxOQH2pqffzYlhLyw,425
30
+ mm_eth-0.8.0.dist-info/METADATA,sha256=BpUpGo189yoj1IE8fJT8eh89ow9Zz_ehLCWZbYxCGfg,161
31
+ mm_eth-0.8.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
32
+ mm_eth-0.8.0.dist-info/entry_points.txt,sha256=aGhpsozl8NIrkuUcX5fSgURCcDhr3ShUdeTSIrJq4oc,46
33
+ mm_eth-0.8.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,7 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mm-eth
3
- Version: 0.7.3
4
- Requires-Python: >=3.13
5
- Requires-Dist: mm-web3~=0.5.4
6
- Requires-Dist: typer~=0.20.0
7
- Requires-Dist: web3~=7.14.0
@@ -1,33 +0,0 @@
1
- mm_eth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- mm_eth/abi.py,sha256=ekyp47yJFCB7FByZ1cTG3DiEI8IT3nCjfXdV1ZAtQ0w,4753
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=HAdud9UcHHc7fEebLiaNqORRyDe6O8RPYt8SAZ14WJU,9912
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=07dEJHGlZnx8nO2zxFuImjqtJrYXKDzLR9AsQNH6Y0s,1546
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=706WdAkB8EW_I54nUe4b_Yfw5cS_TJBsemz4hA1t5aI,4276
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=VyP_oaHuYOulcpWQLUgRRVYrZDH7FazzLdgbwrs32Jg,658
26
- mm_eth/cli/cmd/transfer_cmd.py,sha256=mET3vCAvQ_-0uK_Ut2bZoQY4iYWhFh5muEsNlTHSkGE,17021
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=UUwVLSryJJBdg1jFANOoRKZbaWesYKKhmqpmMsbm6-0,272
30
- mm_eth-0.7.3.dist-info/METADATA,sha256=rCYzaLj-FVY2cx7eDaICwOGKj-wGj61xsQnJOlX2Sqo,161
31
- mm_eth-0.7.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- mm_eth-0.7.3.dist-info/entry_points.txt,sha256=aGhpsozl8NIrkuUcX5fSgURCcDhr3ShUdeTSIrJq4oc,46
33
- mm_eth-0.7.3.dist-info/RECORD,,