mm-eth 0.5.6__tar.gz → 0.5.8__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 (75) hide show
  1. {mm_eth-0.5.6 → mm_eth-0.5.8}/PKG-INFO +4 -4
  2. {mm_eth-0.5.6 → mm_eth-0.5.8}/pyproject.toml +23 -22
  3. mm_eth-0.5.8/src/mm_eth/async_rpc.py +93 -0
  4. mm_eth-0.5.8/src/mm_eth/ens.py +44 -0
  5. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/erc20.py +22 -1
  6. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/ethernodes.py +2 -2
  7. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/utils.py +17 -1
  8. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/conftest.py +28 -7
  9. mm_eth-0.5.8/tests/test_async_rpc.py +18 -0
  10. mm_eth-0.5.8/tests/test_ens.py +27 -0
  11. mm_eth-0.5.8/tests/test_erc20.py +15 -0
  12. mm_eth-0.5.8/tests/test_ethernodes.py +10 -0
  13. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/test_rpc.py +2 -2
  14. {mm_eth-0.5.6 → mm_eth-0.5.8}/uv.lock +118 -104
  15. mm_eth-0.5.6/src/mm_eth/ens.py +0 -23
  16. mm_eth-0.5.6/tests/test_ens.py +0 -13
  17. mm_eth-0.5.6/tests/test_ethernodes.py +0 -8
  18. {mm_eth-0.5.6 → mm_eth-0.5.8}/.gitignore +0 -0
  19. {mm_eth-0.5.6 → mm_eth-0.5.8}/README.md +0 -0
  20. {mm_eth-0.5.6 → mm_eth-0.5.8}/dict.dic +0 -0
  21. {mm_eth-0.5.6 → mm_eth-0.5.8}/justfile +0 -0
  22. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/__init__.py +0 -0
  23. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/abi.py +0 -0
  24. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/account.py +0 -0
  25. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/anvil.py +0 -0
  26. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/__init__.py +0 -0
  27. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/calcs.py +0 -0
  28. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cli.py +0 -0
  29. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cli_utils.py +0 -0
  30. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/__init__.py +0 -0
  31. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/balance_cmd.py +0 -0
  32. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/balances_cmd.py +0 -0
  33. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/call_contract_cmd.py +0 -0
  34. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/deploy_cmd.py +0 -0
  35. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/encode_input_data_cmd.py +0 -0
  36. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/example_cmd.py +0 -0
  37. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/node_cmd.py +0 -0
  38. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/rpc_cmd.py +0 -0
  39. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/solc_cmd.py +0 -0
  40. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/token_cmd.py +0 -0
  41. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/transfer_cmd.py +0 -0
  42. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/tx_cmd.py +0 -0
  43. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/vault_cmd.py +0 -0
  44. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/wallet/__init__.py +0 -0
  45. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/wallet/mnemonic_cmd.py +0 -0
  46. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/wallet/private_key_cmd.py +0 -0
  47. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/examples/balances.toml +0 -0
  48. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/examples/call_contract.toml +0 -0
  49. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/examples/transfer.toml +0 -0
  50. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/print_helpers.py +0 -0
  51. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/rpc_helpers.py +0 -0
  52. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/cli/validators.py +0 -0
  53. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/constants.py +0 -0
  54. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/deploy.py +0 -0
  55. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/json_encoder.py +0 -0
  56. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/py.typed +0 -0
  57. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/rpc.py +0 -0
  58. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/solc.py +0 -0
  59. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/tx.py +0 -0
  60. {mm_eth-0.5.6 → mm_eth-0.5.8}/src/mm_eth/vault.py +0 -0
  61. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/__init__.py +0 -0
  62. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/__init__.py +0 -0
  63. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/cmd/__init__.py +0 -0
  64. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/cmd/test_balance_cmd.py +0 -0
  65. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/cmd/test_mnemonic_cmd.py +0 -0
  66. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/cmd/test_node_cmd.py +0 -0
  67. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/cmd/test_private_key_cmd.py +0 -0
  68. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/cmd/test_solc_cmd.py +0 -0
  69. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/cli/test_calcs.py +0 -0
  70. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/contracts/ERC20.sol +0 -0
  71. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/contracts/abi/ERC20.json +0 -0
  72. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/test_abi.py +0 -0
  73. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/test_account.py +0 -0
  74. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/test_tx.py +0 -0
  75. {mm_eth-0.5.6 → mm_eth-0.5.8}/tests/test_utils.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mm-eth
3
- Version: 0.5.6
3
+ Version: 0.5.8
4
4
  Requires-Python: >=3.12
5
- Requires-Dist: mm-crypto-utils>=0.2.6
6
- Requires-Dist: requests[socks]>=2.32.0
5
+ Requires-Dist: aiohttp-socks~=0.10.1
6
+ Requires-Dist: mm-crypto-utils>=0.2.9
7
7
  Requires-Dist: typer>=0.15.2
8
- Requires-Dist: web3~=7.8.0
8
+ Requires-Dist: web3~=7.9.0
9
9
  Requires-Dist: websocket-client~=1.8.0
@@ -1,14 +1,14 @@
1
1
  [project]
2
2
  name = "mm-eth"
3
- version = "0.5.6"
3
+ version = "0.5.8" # 0.5.9 can't be uploaded, skip it!!!
4
4
  description = ""
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
7
- "mm-crypto-utils>=0.2.6",
7
+ "mm-crypto-utils>=0.2.9",
8
8
  "websocket-client~=1.8.0",
9
- "web3~=7.8.0",
9
+ "aiohttp-socks~=0.10.1",
10
+ "web3~=7.9.0",
10
11
  "typer>=0.15.2",
11
- "requests[socks]>=2.32.0",
12
12
  ]
13
13
  [project.scripts]
14
14
  mm-eth = "mm_eth.cli.cli:app"
@@ -19,9 +19,9 @@ build-backend = "hatchling.build"
19
19
 
20
20
  [tool.uv]
21
21
  dev-dependencies = [
22
- "pytest~=8.3.4",
22
+ "pytest~=8.3.5",
23
23
  "pytest-xdist~=3.6.1",
24
- "ruff~=0.9.9",
24
+ "ruff~=0.11.2",
25
25
  "pip-audit~=2.8.0",
26
26
  "bandit~=1.8.3",
27
27
  "mypy~=1.15.0",
@@ -47,27 +47,28 @@ target-version = "py313"
47
47
  select = ["ALL"]
48
48
  # fixable = ["F401"]
49
49
  ignore = [
50
- "TC", # flake8-type-checking, TYPE_CHECKING is dangerous, for example it doesn't work with pydantic
51
- "A005", # flake8-builtins: stdlib-module-shadowing
52
- "ERA001", # eradicate: commented-out-code
53
- "PT", # flake8-pytest-style
54
- "D", # pydocstyle
55
- "FIX", # flake8-fixme
50
+ "TC", # flake8-type-checking, TYPE_CHECKING is dangerous, for example it doesn't work with pydantic
51
+ "A005", # flake8-builtins: stdlib-module-shadowing
52
+ "ERA001", # eradicate: commented-out-code
53
+ "PT", # flake8-pytest-style
54
+ "D", # pydocstyle
55
+ "FIX", # flake8-fixme
56
56
  "PLR0911", # pylint: too-many-return-statements
57
57
  "PLR0912", # pylint: too-many-branches
58
58
  "PLR0913", # pylint: too-many-arguments
59
59
  "PLR2004", # pylint: magic-value-comparison
60
60
  "PLC0414", # pylint: useless-import-alias
61
- "FBT", # flake8-boolean-trap
62
- "EM", # flake8-errmsg
63
- "TRY003", # tryceratops: raise-vanilla-args
64
- "C901", # mccabe: complex-structure,
65
- "BLE001", # flake8-blind-except
66
- "S311", # bandit: suspicious-non-cryptographic-random-usage
67
- "TD002", # flake8-todos: missing-todo-author
68
- "TD003", # flake8-todos: missing-todo-link
69
- "RET503", # flake8-return: implicit-return
70
- "COM812", # it's used in ruff formatter
61
+ "FBT", # flake8-boolean-trap
62
+ "EM", # flake8-errmsg
63
+ "TRY003", # tryceratops: raise-vanilla-args
64
+ "C901", # mccabe: complex-structure,
65
+ "BLE001", # flake8-blind-except
66
+ "S311", # bandit: suspicious-non-cryptographic-random-usage
67
+ "TD002", # flake8-todos: missing-todo-author
68
+ "TD003", # flake8-todos: missing-todo-link
69
+ "RET503", # flake8-return: implicit-return
70
+ "COM812", # it's used in ruff formatter
71
+ "ASYNC109", # flake8-async: async-function-with-timeout
71
72
  ]
72
73
  [tool.ruff.lint.pep8-naming]
73
74
  classmethod-decorators = ["field_validator"]
@@ -0,0 +1,93 @@
1
+ import json
2
+ from typing import Any
3
+
4
+ import websockets
5
+ from mm_crypto_utils import Nodes, Proxies, random_node, random_proxy
6
+ from mm_std import Err, Ok, Result, ahr
7
+
8
+ from mm_eth.utils import hex_str_to_int
9
+
10
+
11
+ async def rpc_call(
12
+ *,
13
+ nodes: Nodes,
14
+ method: str,
15
+ params: list[object],
16
+ id_: int = 1,
17
+ timeout: int = 10,
18
+ proxies: Proxies = None,
19
+ attempts: int = 1,
20
+ ) -> Result[Any]:
21
+ data = {"jsonrpc": "2.0", "method": method, "params": params, "id": id_}
22
+ res: Result[Any] = Err("not started yet")
23
+ for _ in range(attempts):
24
+ node = random_node(nodes)
25
+ res = (
26
+ await _http_call(node, data, timeout, random_proxy(proxies))
27
+ if node.startswith("http")
28
+ else await _ws_call(node, data, timeout)
29
+ )
30
+ if isinstance(res, Ok):
31
+ return res
32
+ return res
33
+
34
+
35
+ async def _http_call(node: str, data: dict[str, object], timeout: int, proxy: str | None) -> Result[Any]:
36
+ res = await ahr(node, method="POST", proxy=proxy, timeout=timeout, params=data, json_params=True)
37
+ if res.is_error():
38
+ return res.to_err_result()
39
+ try:
40
+ err = res.json.get("error", {}).get("message", "")
41
+ if err:
42
+ return res.to_err_result(f"service_error: {err}")
43
+ if "result" in res.json:
44
+ return res.to_ok_result(res.json["result"])
45
+ return res.to_err_result("unknown_response")
46
+ except Exception as err:
47
+ return res.to_err_result(f"exception: {err}")
48
+
49
+
50
+ async def _ws_call(node: str, data: dict[str, object], timeout: int) -> Result[Any]:
51
+ try:
52
+ async with websockets.connect(node, timeout=timeout) as ws:
53
+ await ws.send(json.dumps(data))
54
+ response = json.loads(await ws.recv())
55
+
56
+ err = response.get("error", {}).get("message", "")
57
+ if err:
58
+ return Err(f"service_error: {err}")
59
+ if "result" in response:
60
+ return Ok(response["result"], response)
61
+ return Err(f"unknown_response: {response}")
62
+ except TimeoutError:
63
+ return Err("timeout")
64
+ except Exception as err:
65
+ return Err(f"exception: {err}")
66
+
67
+
68
+ async def eth_block_number(rpc_urls: Nodes, timeout: int = 10, proxies: Proxies = None, attempts: int = 1) -> Result[int]:
69
+ return (
70
+ await rpc_call(
71
+ nodes=rpc_urls,
72
+ method="eth_blockNumber",
73
+ params=[],
74
+ timeout=timeout,
75
+ proxies=proxies,
76
+ attempts=attempts,
77
+ )
78
+ ).and_then(hex_str_to_int)
79
+
80
+
81
+ async def eth_get_balance(
82
+ rpc_urls: Nodes, address: str, timeout: int = 10, proxies: Proxies = None, attempts: int = 1
83
+ ) -> Result[int]:
84
+ return (
85
+ await rpc_call(
86
+ nodes=rpc_urls,
87
+ method="eth_getBalance",
88
+ params=[address, "latest"],
89
+ timeout=timeout,
90
+ proxies=proxies,
91
+ attempts=attempts,
92
+ )
93
+ ).and_then(hex_str_to_int)
@@ -0,0 +1,44 @@
1
+ from mm_crypto_utils import Nodes, Proxies, random_node, random_proxy
2
+ from mm_std import Err, Ok, Result
3
+
4
+ from mm_eth.utils import get_async_w3, get_w3
5
+
6
+
7
+ def get_name_with_retries(
8
+ rpc_urls: Nodes, address: str, retries: int, timeout: float = 5, proxies: Proxies = None
9
+ ) -> Result[str | None]:
10
+ res: Result[str | None] = Err("not started yet")
11
+ for _ in range(retries):
12
+ res = get_name(random_node(rpc_urls), address, timeout=timeout, proxy=random_proxy(proxies))
13
+ if res.is_ok():
14
+ return res
15
+ return res
16
+
17
+
18
+ def get_name(rpc_url: str, address: str, timeout: float = 5, proxy: str | None = None) -> Result[str | None]:
19
+ try:
20
+ w3 = get_w3(rpc_url, timeout=timeout, proxy=proxy)
21
+ return Ok(w3.ens.name(w3.to_checksum_address(address))) # type: ignore[union-attr]
22
+ except Exception as e:
23
+ return Err(e)
24
+
25
+
26
+ async def async_get_name(rpc_url: str, address: str, timeout: float = 5, proxy: str | None = None) -> Result[str | None]:
27
+ try:
28
+ w3 = await get_async_w3(rpc_url, timeout=timeout, proxy=proxy)
29
+ res = await w3.ens.name(w3.to_checksum_address(address)) # type: ignore[union-attr]
30
+ await w3.provider.disconnect()
31
+ return Ok(res)
32
+ except Exception as e:
33
+ return Err(e)
34
+
35
+
36
+ async def async_get_name_with_retries(
37
+ rpc_urls: Nodes, address: str, retries: int, timeout: float = 5, proxies: Proxies = None
38
+ ) -> Result[str | None]:
39
+ res: Result[str | None] = Err("not started yet")
40
+ for _ in range(retries):
41
+ res = await async_get_name(random_node(rpc_urls), address, timeout=timeout, proxy=random_proxy(proxies))
42
+ if res.is_ok():
43
+ return res
44
+ return res
@@ -11,7 +11,7 @@ from eth_utils import to_checksum_address, to_hex
11
11
  from mm_crypto_utils import Nodes, Proxies
12
12
  from mm_std import Err, Ok, Result
13
13
 
14
- from mm_eth import rpc
14
+ from mm_eth import async_rpc, rpc
15
15
  from mm_eth.rpc import Log
16
16
  from mm_eth.tx import SignedTx, sign_legacy_tx, sign_tx
17
17
  from mm_eth.utils import hex_str_to_int, hex_to_bytes, log_topic_to_address
@@ -70,6 +70,27 @@ def get_balance(
70
70
  ).and_then(hex_str_to_int)
71
71
 
72
72
 
73
+ async def async_get_balance(
74
+ rpc_urls: Nodes,
75
+ token_address: str,
76
+ user_address: str,
77
+ timeout: int = 10,
78
+ proxies: Proxies = None,
79
+ attempts: int = 1,
80
+ ) -> Result[int]:
81
+ data = "0x70a08231000000000000000000000000" + user_address[2:]
82
+ return (
83
+ await async_rpc.rpc_call(
84
+ nodes=rpc_urls,
85
+ method="eth_call",
86
+ params=[{"to": token_address, "data": data}, "latest"],
87
+ timeout=timeout,
88
+ proxies=proxies,
89
+ attempts=attempts,
90
+ )
91
+ ).and_then(hex_str_to_int)
92
+
93
+
73
94
  def get_name(rpc_urls: Nodes, address: str, timeout: int = 10, proxies: Proxies = None, attempts: int = 1) -> Result[str]:
74
95
  return rpc.rpc_call(
75
96
  nodes=rpc_urls,
@@ -1,6 +1,6 @@
1
1
  from datetime import datetime
2
2
 
3
- from mm_std import CHROME_USER_AGENT, Result, hr
3
+ from mm_std import CHROME_USER_AGENT, Ok, Result, hr
4
4
  from pydantic import BaseModel, Field
5
5
 
6
6
 
@@ -29,6 +29,6 @@ def search_nodes(offset: int = 0, proxy: str | None = None) -> Result[SearchResu
29
29
  if res.is_error():
30
30
  return res.to_err_result()
31
31
  try:
32
- return res.to_ok_result(SearchResult(**res.json))
32
+ return Ok(SearchResult(**res.json))
33
33
  except Exception as e:
34
34
  return res.to_err_result(f"exception: {e}")
@@ -2,13 +2,15 @@ import re
2
2
  from decimal import Decimal, localcontext
3
3
  from typing import Any, cast
4
4
 
5
+ import aiohttp
5
6
  import eth_utils
6
7
  import pydash
8
+ from aiohttp_socks import ProxyConnector
7
9
  from eth_typing import HexStr
8
10
  from hexbytes import HexBytes
9
11
  from mm_std import Err, Ok, Result, number_with_separator
10
12
  from pydantic import BaseModel
11
- from web3 import Web3
13
+ from web3 import AsyncWeb3, Web3
12
14
  from web3.types import Wei
13
15
 
14
16
 
@@ -193,6 +195,20 @@ def get_w3(rpc_url: str, timeout: float | None = None, proxy: str | None = None)
193
195
  return Web3(Web3.HTTPProvider(rpc_url, request_kwargs=request_kwargs))
194
196
 
195
197
 
198
+ async def get_async_w3(rpc_url: str, timeout: float | None = None, proxy: str | None = None) -> AsyncWeb3:
199
+ request_kwargs: dict[str, object] = {"timeout": timeout}
200
+ if proxy and proxy.startswith("http"):
201
+ request_kwargs["proxy"] = proxy
202
+ provider = AsyncWeb3.AsyncHTTPProvider(rpc_url, request_kwargs=request_kwargs, exception_retry_configuration=None)
203
+ w3 = AsyncWeb3(provider)
204
+
205
+ if proxy and proxy.startswith("socks"):
206
+ session = aiohttp.ClientSession(connector=ProxyConnector.from_url(proxy))
207
+ await provider.cache_async_session(session)
208
+
209
+ return w3
210
+
211
+
196
212
  def name_network(chain_id: int) -> str:
197
213
  match chain_id:
198
214
  case 1:
@@ -1,11 +1,20 @@
1
1
  import json
2
+ import os
2
3
 
3
4
  import pytest
5
+ from dotenv import load_dotenv
4
6
  from eth_typing import ABI
5
- from mm_std import Err, get_dotenv
7
+ from mm_std import Err, get_dotenv, hr, str_to_list
6
8
 
7
9
  from mm_eth.anvil import Anvil
8
10
 
11
+ load_dotenv()
12
+
13
+
14
+ @pytest.fixture
15
+ def anyio_backend():
16
+ return "asyncio"
17
+
9
18
 
10
19
  @pytest.fixture()
11
20
  def mnemonic() -> str:
@@ -41,15 +50,27 @@ def anvil(mnemonic):
41
50
 
42
51
  @pytest.fixture
43
52
  def etherscan_key():
44
- return get_dotenv("MM_PROXIES_APP")
53
+ return os.getenv("MM_PROXIES_APP")
54
+
55
+
56
+ @pytest.fixture
57
+ def proxies() -> list[str]:
58
+ proxies_url = get_dotenv("PROXIES_URL")
59
+ if not proxies_url:
60
+ return []
61
+
62
+ res = hr(proxies_url)
63
+ return str_to_list(res.body, unique=True)
64
+
65
+
66
+ @pytest.fixture
67
+ def mainnet() -> str:
68
+ return os.getenv("MAINNET_RPC")
45
69
 
46
70
 
47
71
  @pytest.fixture
48
- def mm_proxies() -> list[str]:
49
- # url, token = get_dotenv("MM_PROXIES_APP").split("|")
50
- # res = hr(f"{url}/api/proxies/live", headers={"access-token": token})
51
- # return res.json.get("proxies")
52
- return []
72
+ def mainnet_ws() -> str:
73
+ return os.getenv("MAINNET_RPC_WS")
53
74
 
54
75
 
55
76
  @pytest.fixture
@@ -0,0 +1,18 @@
1
+ import pytest
2
+
3
+ from mm_eth import async_rpc
4
+
5
+ pytestmark = pytest.mark.anyio
6
+
7
+
8
+ async def test_eth_block_number(mainnet, mainnet_ws, proxies):
9
+ res = await async_rpc.eth_block_number(mainnet, proxies=proxies)
10
+ assert res.unwrap() > 9_000_000
11
+
12
+ res = await async_rpc.eth_block_number(mainnet_ws)
13
+ assert res.unwrap() > 9_000_000
14
+
15
+
16
+ async def test_eth_get_balance(mainnet, address_bnb, proxies):
17
+ res = await async_rpc.eth_get_balance(mainnet, address_bnb, proxies=proxies)
18
+ assert res.unwrap() > 1
@@ -0,0 +1,27 @@
1
+ import pytest
2
+ from mm_crypto_utils import random_proxy
3
+ from mm_std import Ok
4
+
5
+ from mm_eth import ens
6
+
7
+ pytestmark = pytest.mark.anyio
8
+
9
+
10
+ def test_get_name_exists(mainnet, proxies):
11
+ address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
12
+ assert ens.get_name(mainnet, address, proxy=random_proxy(proxies)) == Ok("vitalik.eth")
13
+
14
+
15
+ def test_get_name_non_exists(mainnet, proxies):
16
+ address = "0x743997F620846ab4CE946CBe3f5e5b5c51921D6E" # random empty address
17
+ assert ens.get_name(mainnet, address, proxy=random_proxy(proxies)) == Ok(None)
18
+
19
+
20
+ async def test_async_get_name_exists(mainnet, proxies):
21
+ address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
22
+ assert await ens.async_get_name(mainnet, address, proxy=random_proxy(proxies)) == Ok("vitalik.eth")
23
+
24
+
25
+ async def test_async_get_name_non_exists(mainnet, proxies):
26
+ address = "0x743997F620846ab4CE946CBe3f5e5b5c51921D6E" # random empty address
27
+ assert await ens.async_get_name(mainnet, address, proxy=random_proxy(proxies)) == Ok(None)
@@ -0,0 +1,15 @@
1
+ import pytest
2
+
3
+ from mm_eth import erc20
4
+
5
+ pytestmark = pytest.mark.anyio
6
+
7
+
8
+ def test_get_balance(mainnet, address_tether, address_bnb, proxies):
9
+ res = erc20.get_balance(mainnet, token_address=address_tether, user_address=address_bnb, proxies=proxies)
10
+ assert res.unwrap() > 1_000_000
11
+
12
+
13
+ async def test_async_get_balance(mainnet, address_tether, address_bnb, proxies):
14
+ res = await erc20.async_get_balance(mainnet, token_address=address_tether, user_address=address_bnb, proxies=proxies)
15
+ assert res.unwrap() > 1_000_000
@@ -0,0 +1,10 @@
1
+ import pytest
2
+ from mm_std import random_choice
3
+
4
+ from mm_eth import ethernodes
5
+
6
+
7
+ @pytest.mark.skip(reason="It's time to delete ethernodes at all")
8
+ def test_search_nodes(proxies):
9
+ res = ethernodes.search_nodes(offset=100, proxy=random_choice(proxies))
10
+ assert res.is_ok() and res.unwrap().records_total > 1000 and len(res.unwrap().data) == 100
@@ -23,9 +23,9 @@ def test_net_version(infura):
23
23
  assert res.unwrap() == "1"
24
24
 
25
25
 
26
- def test_eth_send_raw_transaction(infura, private_0, address_1):
26
+ def test_eth_send_raw_transaction(mainnet, private_0, address_1):
27
27
  raw_tx = tx.sign_legacy_tx(nonce=0, gas_price=111, gas=21000, private_key=private_0, chain_id=1, value=222, to=address_1)
28
- res = rpc.eth_send_raw_transaction(infura(), raw_tx.raw_tx)
28
+ res = rpc.eth_send_raw_transaction(mainnet, raw_tx.raw_tx)
29
29
  assert res.unwrap_err().startswith("service_error: insufficient funds for")
30
30
 
31
31
 
@@ -58,6 +58,19 @@ wheels = [
58
58
  { url = "https://files.pythonhosted.org/packages/77/58/7850d36a277568a0f5bb8ea5429c57e45c02db2b666458772393280e280c/aiohttp-3.11.4-cp313-cp313-win_amd64.whl", hash = "sha256:474f7266a61d1c3218ef4ec0325747884b2d5a13fab5bff5dd3b55d9c849406a", size = 434778 },
59
59
  ]
60
60
 
61
+ [[package]]
62
+ name = "aiohttp-socks"
63
+ version = "0.10.1"
64
+ source = { registry = "https://pypi.org/simple" }
65
+ dependencies = [
66
+ { name = "aiohttp" },
67
+ { name = "python-socks" },
68
+ ]
69
+ sdist = { url = "https://files.pythonhosted.org/packages/25/c0/dfc948c2aff58db2846192d744dc889bd634b9f3cc7d0fca85ef3c7e9cd4/aiohttp_socks-0.10.1.tar.gz", hash = "sha256:49f2e1f8051f2885719beb1b77e312b5a27c3e4b60f0b045a388f194d995e068", size = 10445 }
70
+ wheels = [
71
+ { url = "https://files.pythonhosted.org/packages/d3/04/7ff144f7465e83cf87459ffd74688871918496acd4816507cca1af5623d3/aiohttp_socks-0.10.1-py3-none-any.whl", hash = "sha256:6fd4d46c09f952f971a011ff446170daab8d539cf5310c0627f8423df2fb15ea", size = 10119 },
72
+ ]
73
+
61
74
  [[package]]
62
75
  name = "aiosignal"
63
76
  version = "1.3.1"
@@ -81,15 +94,16 @@ wheels = [
81
94
 
82
95
  [[package]]
83
96
  name = "anyio"
84
- version = "4.6.2.post1"
97
+ version = "4.9.0"
85
98
  source = { registry = "https://pypi.org/simple" }
86
99
  dependencies = [
87
100
  { name = "idna" },
88
101
  { name = "sniffio" },
102
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
89
103
  ]
90
- sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 }
104
+ sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 }
91
105
  wheels = [
92
- { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 },
106
+ { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 },
93
107
  ]
94
108
 
95
109
  [[package]]
@@ -311,37 +325,37 @@ wheels = [
311
325
 
312
326
  [[package]]
313
327
  name = "cryptography"
314
- version = "44.0.1"
328
+ version = "44.0.2"
315
329
  source = { registry = "https://pypi.org/simple" }
316
330
  dependencies = [
317
331
  { name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
318
332
  ]
319
- sdist = { url = "https://files.pythonhosted.org/packages/c7/67/545c79fe50f7af51dbad56d16b23fe33f63ee6a5d956b3cb68ea110cbe64/cryptography-44.0.1.tar.gz", hash = "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14", size = 710819 }
320
- wheels = [
321
- { url = "https://files.pythonhosted.org/packages/72/27/5e3524053b4c8889da65cf7814a9d0d8514a05194a25e1e34f46852ee6eb/cryptography-44.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009", size = 6642022 },
322
- { url = "https://files.pythonhosted.org/packages/34/b9/4d1fa8d73ae6ec350012f89c3abfbff19fc95fe5420cf972e12a8d182986/cryptography-44.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f", size = 3943865 },
323
- { url = "https://files.pythonhosted.org/packages/6e/57/371a9f3f3a4500807b5fcd29fec77f418ba27ffc629d88597d0d1049696e/cryptography-44.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2", size = 4162562 },
324
- { url = "https://files.pythonhosted.org/packages/c5/1d/5b77815e7d9cf1e3166988647f336f87d5634a5ccecec2ffbe08ef8dd481/cryptography-44.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911", size = 3951923 },
325
- { url = "https://files.pythonhosted.org/packages/28/01/604508cd34a4024467cd4105887cf27da128cba3edd435b54e2395064bfb/cryptography-44.0.1-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69", size = 3685194 },
326
- { url = "https://files.pythonhosted.org/packages/c6/3d/d3c55d4f1d24580a236a6753902ef6d8aafd04da942a1ee9efb9dc8fd0cb/cryptography-44.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026", size = 4187790 },
327
- { url = "https://files.pythonhosted.org/packages/ea/a6/44d63950c8588bfa8594fd234d3d46e93c3841b8e84a066649c566afb972/cryptography-44.0.1-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd", size = 3951343 },
328
- { url = "https://files.pythonhosted.org/packages/c1/17/f5282661b57301204cbf188254c1a0267dbd8b18f76337f0a7ce1038888c/cryptography-44.0.1-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0", size = 4187127 },
329
- { url = "https://files.pythonhosted.org/packages/f3/68/abbae29ed4f9d96596687f3ceea8e233f65c9645fbbec68adb7c756bb85a/cryptography-44.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf", size = 4070666 },
330
- { url = "https://files.pythonhosted.org/packages/0f/10/cf91691064a9e0a88ae27e31779200b1505d3aee877dbe1e4e0d73b4f155/cryptography-44.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864", size = 4288811 },
331
- { url = "https://files.pythonhosted.org/packages/38/78/74ea9eb547d13c34e984e07ec8a473eb55b19c1451fe7fc8077c6a4b0548/cryptography-44.0.1-cp37-abi3-win32.whl", hash = "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a", size = 2771882 },
332
- { url = "https://files.pythonhosted.org/packages/cf/6c/3907271ee485679e15c9f5e93eac6aa318f859b0aed8d369afd636fafa87/cryptography-44.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00", size = 3206989 },
333
- { url = "https://files.pythonhosted.org/packages/9f/f1/676e69c56a9be9fd1bffa9bc3492366901f6e1f8f4079428b05f1414e65c/cryptography-44.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008", size = 6643714 },
334
- { url = "https://files.pythonhosted.org/packages/ba/9f/1775600eb69e72d8f9931a104120f2667107a0ee478f6ad4fe4001559345/cryptography-44.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862", size = 3943269 },
335
- { url = "https://files.pythonhosted.org/packages/25/ba/e00d5ad6b58183829615be7f11f55a7b6baa5a06910faabdc9961527ba44/cryptography-44.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3", size = 4166461 },
336
- { url = "https://files.pythonhosted.org/packages/b3/45/690a02c748d719a95ab08b6e4decb9d81e0ec1bac510358f61624c86e8a3/cryptography-44.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7", size = 3950314 },
337
- { url = "https://files.pythonhosted.org/packages/e6/50/bf8d090911347f9b75adc20f6f6569ed6ca9b9bff552e6e390f53c2a1233/cryptography-44.0.1-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a", size = 3686675 },
338
- { url = "https://files.pythonhosted.org/packages/e1/e7/cfb18011821cc5f9b21efb3f94f3241e3a658d267a3bf3a0f45543858ed8/cryptography-44.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c", size = 4190429 },
339
- { url = "https://files.pythonhosted.org/packages/07/ef/77c74d94a8bfc1a8a47b3cafe54af3db537f081742ee7a8a9bd982b62774/cryptography-44.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62", size = 3950039 },
340
- { url = "https://files.pythonhosted.org/packages/6d/b9/8be0ff57c4592382b77406269b1e15650c9f1a167f9e34941b8515b97159/cryptography-44.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41", size = 4189713 },
341
- { url = "https://files.pythonhosted.org/packages/78/e1/4b6ac5f4100545513b0847a4d276fe3c7ce0eacfa73e3b5ebd31776816ee/cryptography-44.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b", size = 4071193 },
342
- { url = "https://files.pythonhosted.org/packages/3d/cb/afff48ceaed15531eab70445abe500f07f8f96af2bb35d98af6bfa89ebd4/cryptography-44.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7", size = 4289566 },
343
- { url = "https://files.pythonhosted.org/packages/30/6f/4eca9e2e0f13ae459acd1ca7d9f0257ab86e68f44304847610afcb813dc9/cryptography-44.0.1-cp39-abi3-win32.whl", hash = "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9", size = 2772371 },
344
- { url = "https://files.pythonhosted.org/packages/d2/05/5533d30f53f10239616a357f080892026db2d550a40c393d0a8a7af834a9/cryptography-44.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f", size = 3207303 },
333
+ sdist = { url = "https://files.pythonhosted.org/packages/cd/25/4ce80c78963834b8a9fd1cc1266be5ed8d1840785c0f2e1b73b8d128d505/cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", size = 710807 }
334
+ wheels = [
335
+ { url = "https://files.pythonhosted.org/packages/92/ef/83e632cfa801b221570c5f58c0369db6fa6cef7d9ff859feab1aae1a8a0f/cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", size = 6676361 },
336
+ { url = "https://files.pythonhosted.org/packages/30/ec/7ea7c1e4c8fc8329506b46c6c4a52e2f20318425d48e0fe597977c71dbce/cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", size = 3952350 },
337
+ { url = "https://files.pythonhosted.org/packages/27/61/72e3afdb3c5ac510330feba4fc1faa0fe62e070592d6ad00c40bb69165e5/cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", size = 4166572 },
338
+ { url = "https://files.pythonhosted.org/packages/26/e4/ba680f0b35ed4a07d87f9e98f3ebccb05091f3bf6b5a478b943253b3bbd5/cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", size = 3958124 },
339
+ { url = "https://files.pythonhosted.org/packages/9c/e8/44ae3e68c8b6d1cbc59040288056df2ad7f7f03bbcaca6b503c737ab8e73/cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", size = 3678122 },
340
+ { url = "https://files.pythonhosted.org/packages/27/7b/664ea5e0d1eab511a10e480baf1c5d3e681c7d91718f60e149cec09edf01/cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", size = 4191831 },
341
+ { url = "https://files.pythonhosted.org/packages/2a/07/79554a9c40eb11345e1861f46f845fa71c9e25bf66d132e123d9feb8e7f9/cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", size = 3960583 },
342
+ { url = "https://files.pythonhosted.org/packages/bb/6d/858e356a49a4f0b591bd6789d821427de18432212e137290b6d8a817e9bf/cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308", size = 4191753 },
343
+ { url = "https://files.pythonhosted.org/packages/b2/80/62df41ba4916067fa6b125aa8c14d7e9181773f0d5d0bd4dcef580d8b7c6/cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", size = 4079550 },
344
+ { url = "https://files.pythonhosted.org/packages/f3/cd/2558cc08f7b1bb40683f99ff4327f8dcfc7de3affc669e9065e14824511b/cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", size = 4298367 },
345
+ { url = "https://files.pythonhosted.org/packages/71/59/94ccc74788945bc3bd4cf355d19867e8057ff5fdbcac781b1ff95b700fb1/cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", size = 2772843 },
346
+ { url = "https://files.pythonhosted.org/packages/ca/2c/0d0bbaf61ba05acb32f0841853cfa33ebb7a9ab3d9ed8bb004bd39f2da6a/cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", size = 3209057 },
347
+ { url = "https://files.pythonhosted.org/packages/9e/be/7a26142e6d0f7683d8a382dd963745e65db895a79a280a30525ec92be890/cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", size = 6677789 },
348
+ { url = "https://files.pythonhosted.org/packages/06/88/638865be7198a84a7713950b1db7343391c6066a20e614f8fa286eb178ed/cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", size = 3951919 },
349
+ { url = "https://files.pythonhosted.org/packages/d7/fc/99fe639bcdf58561dfad1faa8a7369d1dc13f20acd78371bb97a01613585/cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", size = 4167812 },
350
+ { url = "https://files.pythonhosted.org/packages/53/7b/aafe60210ec93d5d7f552592a28192e51d3c6b6be449e7fd0a91399b5d07/cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", size = 3958571 },
351
+ { url = "https://files.pythonhosted.org/packages/16/32/051f7ce79ad5a6ef5e26a92b37f172ee2d6e1cce09931646eef8de1e9827/cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", size = 3679832 },
352
+ { url = "https://files.pythonhosted.org/packages/78/2b/999b2a1e1ba2206f2d3bca267d68f350beb2b048a41ea827e08ce7260098/cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", size = 4193719 },
353
+ { url = "https://files.pythonhosted.org/packages/72/97/430e56e39a1356e8e8f10f723211a0e256e11895ef1a135f30d7d40f2540/cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", size = 3960852 },
354
+ { url = "https://files.pythonhosted.org/packages/89/33/c1cf182c152e1d262cac56850939530c05ca6c8d149aa0dcee490b417e99/cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", size = 4193906 },
355
+ { url = "https://files.pythonhosted.org/packages/e1/99/87cf26d4f125380dc674233971069bc28d19b07f7755b29861570e513650/cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", size = 4081572 },
356
+ { url = "https://files.pythonhosted.org/packages/b3/9f/6a3e0391957cc0c5f84aef9fbdd763035f2b52e998a53f99345e3ac69312/cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", size = 4298631 },
357
+ { url = "https://files.pythonhosted.org/packages/e2/a5/5bc097adb4b6d22a24dea53c51f37e480aaec3465285c253098642696423/cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", size = 2773792 },
358
+ { url = "https://files.pythonhosted.org/packages/33/cf/1f7649b8b9a3543e042d3f348e398a061923ac05b507f3f4d95f11938aa9/cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", size = 3210957 },
345
359
  ]
346
360
 
347
361
  [[package]]
@@ -576,19 +590,6 @@ wheels = [
576
590
  { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
577
591
  ]
578
592
 
579
- [[package]]
580
- name = "h2"
581
- version = "4.1.0"
582
- source = { registry = "https://pypi.org/simple" }
583
- dependencies = [
584
- { name = "hpack" },
585
- { name = "hyperframe" },
586
- ]
587
- sdist = { url = "https://files.pythonhosted.org/packages/2a/32/fec683ddd10629ea4ea46d206752a95a2d8a48c22521edd70b142488efe1/h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb", size = 2145593 }
588
- wheels = [
589
- { url = "https://files.pythonhosted.org/packages/2a/e5/db6d438da759efbb488c4f3fbdab7764492ff3c3f953132efa6b9f0e9e53/h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d", size = 57488 },
590
- ]
591
-
592
593
  [[package]]
593
594
  name = "hexbytes"
594
595
  version = "1.2.1"
@@ -598,15 +599,6 @@ wheels = [
598
599
  { url = "https://files.pythonhosted.org/packages/39/c6/20f25ea73e4ceffb3eb4e38347f2992cb25e5ff6eb644d52e753a7a72f57/hexbytes-1.2.1-py3-none-any.whl", hash = "sha256:e64890b203a31f4a23ef11470ecfcca565beaee9198df623047df322b757471a", size = 5160 },
599
600
  ]
600
601
 
601
- [[package]]
602
- name = "hpack"
603
- version = "4.0.0"
604
- source = { registry = "https://pypi.org/simple" }
605
- sdist = { url = "https://files.pythonhosted.org/packages/3e/9b/fda93fb4d957db19b0f6b370e79d586b3e8528b20252c729c476a2c02954/hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095", size = 49117 }
606
- wheels = [
607
- { url = "https://files.pythonhosted.org/packages/d5/34/e8b383f35b77c402d28563d2b8f83159319b509bc5f760b15d60b0abf165/hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c", size = 32611 },
608
- ]
609
-
610
602
  [[package]]
611
603
  name = "httpcore"
612
604
  version = "1.0.7"
@@ -636,22 +628,10 @@ wheels = [
636
628
  ]
637
629
 
638
630
  [package.optional-dependencies]
639
- http2 = [
640
- { name = "h2" },
641
- ]
642
631
  socks = [
643
632
  { name = "socksio" },
644
633
  ]
645
634
 
646
- [[package]]
647
- name = "hyperframe"
648
- version = "6.0.1"
649
- source = { registry = "https://pypi.org/simple" }
650
- sdist = { url = "https://files.pythonhosted.org/packages/5a/2a/4747bff0a17f7281abe73e955d60d80aae537a5d203f417fa1c2e7578ebb/hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914", size = 25008 }
651
- wheels = [
652
- { url = "https://files.pythonhosted.org/packages/d7/de/85a784bcc4a3779d1753a7ec2dee5de90e18c7bcf402e71b51fcf150b129/hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15", size = 12389 },
653
- ]
654
-
655
635
  [[package]]
656
636
  name = "idna"
657
637
  version = "3.10"
@@ -718,23 +698,23 @@ wheels = [
718
698
 
719
699
  [[package]]
720
700
  name = "mm-crypto-utils"
721
- version = "0.2.6"
701
+ version = "0.2.9"
722
702
  source = { registry = "https://pypi.org/simple" }
723
703
  dependencies = [
724
704
  { name = "loguru" },
725
705
  { name = "mm-std" },
726
706
  ]
727
707
  wheels = [
728
- { url = "https://files.pythonhosted.org/packages/d2/2a/72236eb60cb007d472fa6be72a98abf6b8273df3158a218cc5f412f86497/mm_crypto_utils-0.2.6-py3-none-any.whl", hash = "sha256:ef738203e2863570308d0fc5fee8f05c469d3f7df905dcdfd092d84690b14c9c", size = 8269 },
708
+ { url = "https://files.pythonhosted.org/packages/bb/4c/c790acb5b025d35a391dd4fef1ebb3b6432a874154844a618d27b10a0a0f/mm_crypto_utils-0.2.9-py3-none-any.whl", hash = "sha256:0b569067e4c4f8e568599134febe23aacbb903bb80799e4258180ec4a51bec9b", size = 8273 },
729
709
  ]
730
710
 
731
711
  [[package]]
732
712
  name = "mm-eth"
733
- version = "0.5.6"
713
+ version = "0.5.8"
734
714
  source = { editable = "." }
735
715
  dependencies = [
716
+ { name = "aiohttp-socks" },
736
717
  { name = "mm-crypto-utils" },
737
- { name = "requests", extra = ["socks"] },
738
718
  { name = "typer" },
739
719
  { name = "web3" },
740
720
  { name = "websocket-client" },
@@ -753,10 +733,10 @@ dev = [
753
733
 
754
734
  [package.metadata]
755
735
  requires-dist = [
756
- { name = "mm-crypto-utils", specifier = ">=0.2.6" },
757
- { name = "requests", extras = ["socks"], specifier = ">=2.32.0" },
736
+ { name = "aiohttp-socks", specifier = "~=0.10.1" },
737
+ { name = "mm-crypto-utils", specifier = ">=0.2.9" },
758
738
  { name = "typer", specifier = ">=0.15.2" },
759
- { name = "web3", specifier = "~=7.8.0" },
739
+ { name = "web3", specifier = "~=7.9.0" },
760
740
  { name = "websocket-client", specifier = "~=1.8.0" },
761
741
  ]
762
742
 
@@ -765,27 +745,30 @@ dev = [
765
745
  { name = "bandit", specifier = "~=1.8.3" },
766
746
  { name = "mypy", specifier = "~=1.15.0" },
767
747
  { name = "pip-audit", specifier = "~=2.8.0" },
768
- { name = "pytest", specifier = "~=8.3.4" },
748
+ { name = "pytest", specifier = "~=8.3.5" },
769
749
  { name = "pytest-xdist", specifier = "~=3.6.1" },
770
- { name = "ruff", specifier = "~=0.9.9" },
750
+ { name = "ruff", specifier = "~=0.11.2" },
771
751
  { name = "types-pyyaml", specifier = ">=6.0.12.20241230" },
772
752
  ]
773
753
 
774
754
  [[package]]
775
755
  name = "mm-std"
776
- version = "0.3.2"
756
+ version = "0.3.14"
777
757
  source = { registry = "https://pypi.org/simple" }
778
758
  dependencies = [
759
+ { name = "anyio" },
779
760
  { name = "cryptography" },
780
- { name = "httpx", extra = ["http2", "socks"] },
761
+ { name = "httpx", extra = ["socks"] },
781
762
  { name = "pydantic" },
763
+ { name = "pydantic-settings" },
782
764
  { name = "pydash" },
783
765
  { name = "python-dotenv" },
784
- { name = "pyyaml" },
766
+ { name = "requests", extra = ["socks"] },
785
767
  { name = "rich" },
768
+ { name = "tomlkit" },
786
769
  ]
787
770
  wheels = [
788
- { url = "https://files.pythonhosted.org/packages/c0/9a/19f88e047426a52de2f8262d654ca8f20b6b9f15085db7dca6850b7d89d9/mm_std-0.3.2-py3-none-any.whl", hash = "sha256:bf479b1810c887b41aa8b4ad3b6d59d2002703a26b04499516af8e2d94351c86", size = 14709 },
771
+ { url = "https://files.pythonhosted.org/packages/47/61/cd5cbfc1868493ffda46c7d86d94459110ec4dd28c1883936f18f36bfab0/mm_std-0.3.14-py3-none-any.whl", hash = "sha256:db0a3a66590f456ad8c3f268d545803be63339c4b72f3197bc377d101a93ad02", size = 20219 },
789
772
  ]
790
773
 
791
774
  [[package]]
@@ -1135,6 +1118,19 @@ wheels = [
1135
1118
  { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 },
1136
1119
  ]
1137
1120
 
1121
+ [[package]]
1122
+ name = "pydantic-settings"
1123
+ version = "2.8.1"
1124
+ source = { registry = "https://pypi.org/simple" }
1125
+ dependencies = [
1126
+ { name = "pydantic" },
1127
+ { name = "python-dotenv" },
1128
+ ]
1129
+ sdist = { url = "https://files.pythonhosted.org/packages/88/82/c79424d7d8c29b994fb01d277da57b0a9b09cc03c3ff875f9bd8a86b2145/pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585", size = 83550 }
1130
+ wheels = [
1131
+ { url = "https://files.pythonhosted.org/packages/0b/53/a64f03044927dc47aafe029c42a5b7aabc38dfb813475e0e1bf71c4a59d0/pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c", size = 30839 },
1132
+ ]
1133
+
1138
1134
  [[package]]
1139
1135
  name = "pydash"
1140
1136
  version = "8.0.5"
@@ -1176,7 +1172,7 @@ wheels = [
1176
1172
 
1177
1173
  [[package]]
1178
1174
  name = "pytest"
1179
- version = "8.3.4"
1175
+ version = "8.3.5"
1180
1176
  source = { registry = "https://pypi.org/simple" }
1181
1177
  dependencies = [
1182
1178
  { name = "colorama", marker = "sys_platform == 'win32'" },
@@ -1184,9 +1180,9 @@ dependencies = [
1184
1180
  { name = "packaging" },
1185
1181
  { name = "pluggy" },
1186
1182
  ]
1187
- sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 }
1183
+ sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 }
1188
1184
  wheels = [
1189
- { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 },
1185
+ { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 },
1190
1186
  ]
1191
1187
 
1192
1188
  [[package]]
@@ -1211,6 +1207,15 @@ wheels = [
1211
1207
  { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
1212
1208
  ]
1213
1209
 
1210
+ [[package]]
1211
+ name = "python-socks"
1212
+ version = "2.7.1"
1213
+ source = { registry = "https://pypi.org/simple" }
1214
+ sdist = { url = "https://files.pythonhosted.org/packages/db/56/a21c65c9968fbdb442b177a4f6f42d150c4bc66c179606193ee86e5b5dc5/python_socks-2.7.1.tar.gz", hash = "sha256:f1a0bb603830fe81e332442eada96757b8f8dec02bd22d1d6f5c99a79704c550", size = 230371 }
1215
+ wheels = [
1216
+ { url = "https://files.pythonhosted.org/packages/59/a5/8bc495f162f6ff6a805a0bd558312db2cc8d6aa6279324ba8180af64f777/python_socks-2.7.1-py3-none-any.whl", hash = "sha256:2603c6454eeaeb82b464ad705be188989e8cf1a4a16f0af3c921d6dd71a49cec", size = 54980 },
1217
+ ]
1218
+
1214
1219
  [[package]]
1215
1220
  name = "pyunormalize"
1216
1221
  version = "16.0.0"
@@ -1344,27 +1349,27 @@ wheels = [
1344
1349
 
1345
1350
  [[package]]
1346
1351
  name = "ruff"
1347
- version = "0.9.9"
1348
- source = { registry = "https://pypi.org/simple" }
1349
- sdist = { url = "https://files.pythonhosted.org/packages/6f/c3/418441a8170e8d53d05c0b9dad69760dbc7b8a12c10dbe6db1e1205d2377/ruff-0.9.9.tar.gz", hash = "sha256:0062ed13f22173e85f8f7056f9a24016e692efeea8704d1a5e8011b8aa850933", size = 3717448 }
1350
- wheels = [
1351
- { url = "https://files.pythonhosted.org/packages/bc/c3/2c4afa9ba467555d074b146d9aed0633a56ccdb900839fb008295d037b89/ruff-0.9.9-py3-none-linux_armv6l.whl", hash = "sha256:628abb5ea10345e53dff55b167595a159d3e174d6720bf19761f5e467e68d367", size = 10027252 },
1352
- { url = "https://files.pythonhosted.org/packages/33/d1/439e58487cf9eac26378332e25e7d5ade4b800ce1eec7dc2cfc9b0d7ca96/ruff-0.9.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b6cd1428e834b35d7493354723543b28cc11dc14d1ce19b685f6e68e07c05ec7", size = 10840721 },
1353
- { url = "https://files.pythonhosted.org/packages/50/44/fead822c38281ba0122f1b76b460488a175a9bd48b130650a6fb6dbcbcf9/ruff-0.9.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5ee162652869120ad260670706f3cd36cd3f32b0c651f02b6da142652c54941d", size = 10161439 },
1354
- { url = "https://files.pythonhosted.org/packages/11/ae/d404a2ab8e61ddf6342e09cc6b7f7846cce6b243e45c2007dbe0ca928a5d/ruff-0.9.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3aa0f6b75082c9be1ec5a1db78c6d4b02e2375c3068438241dc19c7c306cc61a", size = 10336264 },
1355
- { url = "https://files.pythonhosted.org/packages/6a/4e/7c268aa7d84cd709fb6f046b8972313142cffb40dfff1d2515c5e6288d54/ruff-0.9.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:584cc66e89fb5f80f84b05133dd677a17cdd86901d6479712c96597a3f28e7fe", size = 9908774 },
1356
- { url = "https://files.pythonhosted.org/packages/cc/26/c618a878367ef1b76270fd027ca93692657d3f6122b84ba48911ef5f2edc/ruff-0.9.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf3369325761a35aba75cd5c55ba1b5eb17d772f12ab168fbfac54be85cf18c", size = 11428127 },
1357
- { url = "https://files.pythonhosted.org/packages/d7/9a/c5588a93d9bfed29f565baf193fe802fa676a0c837938137ea6cf0576d8c/ruff-0.9.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3403a53a32a90ce929aa2f758542aca9234befa133e29f4933dcef28a24317be", size = 12133187 },
1358
- { url = "https://files.pythonhosted.org/packages/3e/ff/e7980a7704a60905ed7e156a8d73f604c846d9bd87deda9cabfa6cba073a/ruff-0.9.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:18454e7fa4e4d72cffe28a37cf6a73cb2594f81ec9f4eca31a0aaa9ccdfb1590", size = 11602937 },
1359
- { url = "https://files.pythonhosted.org/packages/24/78/3690444ad9e3cab5c11abe56554c35f005b51d1d118b429765249095269f/ruff-0.9.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fadfe2c88724c9617339f62319ed40dcdadadf2888d5afb88bf3adee7b35bfb", size = 13771698 },
1360
- { url = "https://files.pythonhosted.org/packages/6e/bf/e477c2faf86abe3988e0b5fd22a7f3520e820b2ee335131aca2e16120038/ruff-0.9.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6df104d08c442a1aabcfd254279b8cc1e2cbf41a605aa3e26610ba1ec4acf0b0", size = 11249026 },
1361
- { url = "https://files.pythonhosted.org/packages/f7/82/cdaffd59e5a8cb5b14c408c73d7a555a577cf6645faaf83e52fe99521715/ruff-0.9.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d7c62939daf5b2a15af48abbd23bea1efdd38c312d6e7c4cedf5a24e03207e17", size = 10220432 },
1362
- { url = "https://files.pythonhosted.org/packages/fe/a4/2507d0026225efa5d4412b6e294dfe54725a78652a5c7e29e6bd0fc492f3/ruff-0.9.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9494ba82a37a4b81b6a798076e4a3251c13243fc37967e998efe4cce58c8a8d1", size = 9874602 },
1363
- { url = "https://files.pythonhosted.org/packages/d5/be/f3aab1813846b476c4bcffe052d232244979c3cd99d751c17afb530ca8e4/ruff-0.9.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4efd7a96ed6d36ef011ae798bf794c5501a514be369296c672dab7921087fa57", size = 10851212 },
1364
- { url = "https://files.pythonhosted.org/packages/8b/45/8e5fd559bea0d2f57c4e12bf197a2fade2fac465aa518284f157dfbca92b/ruff-0.9.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ab90a7944c5a1296f3ecb08d1cbf8c2da34c7e68114b1271a431a3ad30cb660e", size = 11327490 },
1365
- { url = "https://files.pythonhosted.org/packages/42/55/e6c90f13880aeef327746052907e7e930681f26a164fe130ddac28b08269/ruff-0.9.9-py3-none-win32.whl", hash = "sha256:6b4c376d929c25ecd6d87e182a230fa4377b8e5125a4ff52d506ee8c087153c1", size = 10227912 },
1366
- { url = "https://files.pythonhosted.org/packages/35/b2/da925693cb82a1208aa34966c0f36cb222baca94e729dd22a587bc22d0f3/ruff-0.9.9-py3-none-win_amd64.whl", hash = "sha256:837982ea24091d4c1700ddb2f63b7070e5baec508e43b01de013dc7eff974ff1", size = 11355632 },
1367
- { url = "https://files.pythonhosted.org/packages/31/d8/de873d1c1b020d668d8ec9855d390764cb90cf8f6486c0983da52be8b7b7/ruff-0.9.9-py3-none-win_arm64.whl", hash = "sha256:3ac78f127517209fe6d96ab00f3ba97cafe38718b23b1db3e96d8b2d39e37ddf", size = 10435860 },
1352
+ version = "0.11.2"
1353
+ source = { registry = "https://pypi.org/simple" }
1354
+ sdist = { url = "https://files.pythonhosted.org/packages/90/61/fb87430f040e4e577e784e325351186976516faef17d6fcd921fe28edfd7/ruff-0.11.2.tar.gz", hash = "sha256:ec47591497d5a1050175bdf4e1a4e6272cddff7da88a2ad595e1e326041d8d94", size = 3857511 }
1355
+ wheels = [
1356
+ { url = "https://files.pythonhosted.org/packages/62/99/102578506f0f5fa29fd7e0df0a273864f79af044757aef73d1cae0afe6ad/ruff-0.11.2-py3-none-linux_armv6l.whl", hash = "sha256:c69e20ea49e973f3afec2c06376eb56045709f0212615c1adb0eda35e8a4e477", size = 10113146 },
1357
+ { url = "https://files.pythonhosted.org/packages/74/ad/5cd4ba58ab602a579997a8494b96f10f316e874d7c435bcc1a92e6da1b12/ruff-0.11.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2c5424cc1c4eb1d8ecabe6d4f1b70470b4f24a0c0171356290b1953ad8f0e272", size = 10867092 },
1358
+ { url = "https://files.pythonhosted.org/packages/fc/3e/d3f13619e1d152c7b600a38c1a035e833e794c6625c9a6cea6f63dbf3af4/ruff-0.11.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ecf20854cc73f42171eedb66f006a43d0a21bfb98a2523a809931cda569552d9", size = 10224082 },
1359
+ { url = "https://files.pythonhosted.org/packages/90/06/f77b3d790d24a93f38e3806216f263974909888fd1e826717c3ec956bbcd/ruff-0.11.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c543bf65d5d27240321604cee0633a70c6c25c9a2f2492efa9f6d4b8e4199bb", size = 10394818 },
1360
+ { url = "https://files.pythonhosted.org/packages/99/7f/78aa431d3ddebfc2418cd95b786642557ba8b3cb578c075239da9ce97ff9/ruff-0.11.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20967168cc21195db5830b9224be0e964cc9c8ecf3b5a9e3ce19876e8d3a96e3", size = 9952251 },
1361
+ { url = "https://files.pythonhosted.org/packages/30/3e/f11186d1ddfaca438c3bbff73c6a2fdb5b60e6450cc466129c694b0ab7a2/ruff-0.11.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:955a9ce63483999d9f0b8f0b4a3ad669e53484232853054cc8b9d51ab4c5de74", size = 11563566 },
1362
+ { url = "https://files.pythonhosted.org/packages/22/6c/6ca91befbc0a6539ee133d9a9ce60b1a354db12c3c5d11cfdbf77140f851/ruff-0.11.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:86b3a27c38b8fce73bcd262b0de32e9a6801b76d52cdb3ae4c914515f0cef608", size = 12208721 },
1363
+ { url = "https://files.pythonhosted.org/packages/19/b0/24516a3b850d55b17c03fc399b681c6a549d06ce665915721dc5d6458a5c/ruff-0.11.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3b66a03b248c9fcd9d64d445bafdf1589326bee6fc5c8e92d7562e58883e30f", size = 11662274 },
1364
+ { url = "https://files.pythonhosted.org/packages/d7/65/76be06d28ecb7c6070280cef2bcb20c98fbf99ff60b1c57d2fb9b8771348/ruff-0.11.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0397c2672db015be5aa3d4dac54c69aa012429097ff219392c018e21f5085147", size = 13792284 },
1365
+ { url = "https://files.pythonhosted.org/packages/ce/d2/4ceed7147e05852876f3b5f3fdc23f878ce2b7e0b90dd6e698bda3d20787/ruff-0.11.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:869bcf3f9abf6457fbe39b5a37333aa4eecc52a3b99c98827ccc371a8e5b6f1b", size = 11327861 },
1366
+ { url = "https://files.pythonhosted.org/packages/c4/78/4935ecba13706fd60ebe0e3dc50371f2bdc3d9bc80e68adc32ff93914534/ruff-0.11.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2a2b50ca35457ba785cd8c93ebbe529467594087b527a08d487cf0ee7b3087e9", size = 10276560 },
1367
+ { url = "https://files.pythonhosted.org/packages/81/7f/1b2435c3f5245d410bb5dc80f13ec796454c21fbda12b77d7588d5cf4e29/ruff-0.11.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7c69c74bf53ddcfbc22e6eb2f31211df7f65054bfc1f72288fc71e5f82db3eab", size = 9945091 },
1368
+ { url = "https://files.pythonhosted.org/packages/39/c4/692284c07e6bf2b31d82bb8c32f8840f9d0627d92983edaac991a2b66c0a/ruff-0.11.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6e8fb75e14560f7cf53b15bbc55baf5ecbe373dd5f3aab96ff7aa7777edd7630", size = 10977133 },
1369
+ { url = "https://files.pythonhosted.org/packages/94/cf/8ab81cb7dd7a3b0a3960c2769825038f3adcd75faf46dd6376086df8b128/ruff-0.11.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:842a472d7b4d6f5924e9297aa38149e5dcb1e628773b70e6387ae2c97a63c58f", size = 11378514 },
1370
+ { url = "https://files.pythonhosted.org/packages/d9/3a/a647fa4f316482dacf2fd68e8a386327a33d6eabd8eb2f9a0c3d291ec549/ruff-0.11.2-py3-none-win32.whl", hash = "sha256:aca01ccd0eb5eb7156b324cfaa088586f06a86d9e5314b0eb330cb48415097cc", size = 10319835 },
1371
+ { url = "https://files.pythonhosted.org/packages/86/54/3c12d3af58012a5e2cd7ebdbe9983f4834af3f8cbea0e8a8c74fa1e23b2b/ruff-0.11.2-py3-none-win_amd64.whl", hash = "sha256:3170150172a8f994136c0c66f494edf199a0bbea7a409f649e4bc8f4d7084080", size = 11373713 },
1372
+ { url = "https://files.pythonhosted.org/packages/d6/d4/dd813703af8a1e2ac33bf3feb27e8a5ad514c9f219df80c64d69807e7f71/ruff-0.11.2-py3-none-win_arm64.whl", hash = "sha256:52933095158ff328f4c77af3d74f0379e34fd52f175144cefc1b192e7ccd32b4", size = 10441990 },
1368
1373
  ]
1369
1374
 
1370
1375
  [[package]]
@@ -1424,6 +1429,15 @@ wheels = [
1424
1429
  { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588 },
1425
1430
  ]
1426
1431
 
1432
+ [[package]]
1433
+ name = "tomlkit"
1434
+ version = "0.13.2"
1435
+ source = { registry = "https://pypi.org/simple" }
1436
+ sdist = { url = "https://files.pythonhosted.org/packages/b1/09/a439bec5888f00a54b8b9f05fa94d7f901d6735ef4e55dcec9bc37b5d8fa/tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79", size = 192885 }
1437
+ wheels = [
1438
+ { url = "https://files.pythonhosted.org/packages/f9/b6/a447b5e4ec71e13871be01ba81f5dfc9d0af7e473da256ff46bc0e24026f/tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", size = 37955 },
1439
+ ]
1440
+
1427
1441
  [[package]]
1428
1442
  name = "toolz"
1429
1443
  version = "1.0.0"
@@ -1489,7 +1503,7 @@ wheels = [
1489
1503
 
1490
1504
  [[package]]
1491
1505
  name = "web3"
1492
- version = "7.8.0"
1506
+ version = "7.9.0"
1493
1507
  source = { registry = "https://pypi.org/simple" }
1494
1508
  dependencies = [
1495
1509
  { name = "aiohttp" },
@@ -1507,9 +1521,9 @@ dependencies = [
1507
1521
  { name = "typing-extensions" },
1508
1522
  { name = "websockets" },
1509
1523
  ]
1510
- sdist = { url = "https://files.pythonhosted.org/packages/f3/55/943b2b544afade2f1220e4587bd7e95f8a39465d96e0c6e5029a007c6bec/web3-7.8.0.tar.gz", hash = "sha256:712bc9fd6b1ef6e467ee24c25b581e1951cab2cba17f9f548f12587734f2c857", size = 2188875 }
1524
+ sdist = { url = "https://files.pythonhosted.org/packages/5d/d7/f67b4947d89ab6a0c7a2079452e804368ebb4c36e47bfb12cf7641d93c60/web3-7.9.0.tar.gz", hash = "sha256:3c4487a7ac57e0a187bd7ee03db455d94f354d15cca45f097f15f7281ad1a01f", size = 2193782 }
1511
1525
  wheels = [
1512
- { url = "https://files.pythonhosted.org/packages/b0/52/bc4a08811db59392e13bf56ada316517a83b9a6135c20d357c222c80be2d/web3-7.8.0-py3-none-any.whl", hash = "sha256:c8771b3d8772f7104a0462804449beb57d36cef7bd8b411140f95a92fc46b559", size = 1363475 },
1526
+ { url = "https://files.pythonhosted.org/packages/ef/df/7ca4a880772a3eea99c994d40d142c96cb679e625dd4bce3cd79901e58d8/web3-7.9.0-py3-none-any.whl", hash = "sha256:7818267675283e9cae4487d2805fc34b899aa26f41b0000c798c79b1684899eb", size = 1365826 },
1513
1527
  ]
1514
1528
 
1515
1529
  [[package]]
@@ -1,23 +0,0 @@
1
- from mm_crypto_utils import Nodes, Proxies, random_node, random_proxy
2
- from mm_std import Err, Ok, Result
3
-
4
- from mm_eth.utils import get_w3
5
-
6
-
7
- def get_name_with_retries(
8
- rpc_urls: Nodes, address: str, retries: int, timeout: float = 5, proxies: Proxies = None
9
- ) -> Result[str | None]:
10
- res: Result[str | None] = Err("not started yet")
11
- for _ in range(retries):
12
- res = get_name(random_node(rpc_urls), address, timeout=timeout, proxy=random_proxy(proxies))
13
- if res.is_ok():
14
- return res
15
- return res
16
-
17
-
18
- def get_name(rpc_url: str, address: str, timeout: float = 5, proxy: str | None = None) -> Result[str | None]:
19
- try:
20
- w3 = get_w3(rpc_url, timeout=timeout, proxy=proxy)
21
- return Ok(w3.ens.name(w3.to_checksum_address(address))) # type: ignore[union-attr]
22
- except Exception as e:
23
- return Err(e)
@@ -1,13 +0,0 @@
1
- from mm_std import Ok
2
-
3
- from mm_eth import ens
4
-
5
-
6
- def test_get_name_exists(infura):
7
- address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
8
- assert ens.get_name(infura(), address) == Ok("vitalik.eth")
9
-
10
-
11
- def test_get_name_non_exists(infura):
12
- address = "0x743997F620846ab4CE946CBe3f5e5b5c51921D6E" # random empty address
13
- assert ens.get_name(infura(), address) == Ok(None)
@@ -1,8 +0,0 @@
1
- from mm_std import random_choice
2
-
3
- from mm_eth import ethernodes
4
-
5
-
6
- def test_search_nodes(mm_proxies):
7
- res = ethernodes.search_nodes(offset=100, proxy=random_choice(mm_proxies))
8
- assert res.is_ok() and res.ok.records_total > 1000 and len(res.ok.data) == 100
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes