mm-eth 0.5.5__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.5 → mm_eth-0.5.8}/PKG-INFO +4 -3
  2. {mm_eth-0.5.5 → mm_eth-0.5.8}/pyproject.toml +23 -21
  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.5 → mm_eth-0.5.8}/src/mm_eth/erc20.py +22 -1
  6. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/ethernodes.py +2 -2
  7. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/utils.py +17 -1
  8. {mm_eth-0.5.5 → 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.5 → mm_eth-0.5.8}/tests/test_rpc.py +2 -2
  14. {mm_eth-0.5.5 → mm_eth-0.5.8}/uv.lock +132 -102
  15. mm_eth-0.5.5/src/mm_eth/ens.py +0 -23
  16. mm_eth-0.5.5/tests/test_ens.py +0 -13
  17. mm_eth-0.5.5/tests/test_ethernodes.py +0 -8
  18. {mm_eth-0.5.5 → mm_eth-0.5.8}/.gitignore +0 -0
  19. {mm_eth-0.5.5 → mm_eth-0.5.8}/README.md +0 -0
  20. {mm_eth-0.5.5 → mm_eth-0.5.8}/dict.dic +0 -0
  21. {mm_eth-0.5.5 → mm_eth-0.5.8}/justfile +0 -0
  22. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/__init__.py +0 -0
  23. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/abi.py +0 -0
  24. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/account.py +0 -0
  25. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/anvil.py +0 -0
  26. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/__init__.py +0 -0
  27. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/calcs.py +0 -0
  28. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cli.py +0 -0
  29. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cli_utils.py +0 -0
  30. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/__init__.py +0 -0
  31. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/balance_cmd.py +0 -0
  32. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/balances_cmd.py +0 -0
  33. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/call_contract_cmd.py +0 -0
  34. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/deploy_cmd.py +0 -0
  35. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/encode_input_data_cmd.py +0 -0
  36. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/example_cmd.py +0 -0
  37. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/node_cmd.py +0 -0
  38. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/rpc_cmd.py +0 -0
  39. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/solc_cmd.py +0 -0
  40. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/token_cmd.py +0 -0
  41. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/transfer_cmd.py +0 -0
  42. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/tx_cmd.py +0 -0
  43. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/vault_cmd.py +0 -0
  44. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/wallet/__init__.py +0 -0
  45. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/wallet/mnemonic_cmd.py +0 -0
  46. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/cmd/wallet/private_key_cmd.py +0 -0
  47. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/examples/balances.toml +0 -0
  48. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/examples/call_contract.toml +0 -0
  49. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/examples/transfer.toml +0 -0
  50. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/print_helpers.py +0 -0
  51. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/rpc_helpers.py +0 -0
  52. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/cli/validators.py +0 -0
  53. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/constants.py +0 -0
  54. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/deploy.py +0 -0
  55. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/json_encoder.py +0 -0
  56. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/py.typed +0 -0
  57. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/rpc.py +0 -0
  58. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/solc.py +0 -0
  59. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/tx.py +0 -0
  60. {mm_eth-0.5.5 → mm_eth-0.5.8}/src/mm_eth/vault.py +0 -0
  61. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/__init__.py +0 -0
  62. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/__init__.py +0 -0
  63. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/cmd/__init__.py +0 -0
  64. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/cmd/test_balance_cmd.py +0 -0
  65. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/cmd/test_mnemonic_cmd.py +0 -0
  66. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/cmd/test_node_cmd.py +0 -0
  67. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/cmd/test_private_key_cmd.py +0 -0
  68. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/cmd/test_solc_cmd.py +0 -0
  69. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/cli/test_calcs.py +0 -0
  70. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/contracts/ERC20.sol +0 -0
  71. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/contracts/abi/ERC20.json +0 -0
  72. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/test_abi.py +0 -0
  73. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/test_account.py +0 -0
  74. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/test_tx.py +0 -0
  75. {mm_eth-0.5.5 → mm_eth-0.5.8}/tests/test_utils.py +0 -0
@@ -1,8 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mm-eth
3
- Version: 0.5.5
3
+ Version: 0.5.8
4
4
  Requires-Python: >=3.12
5
- Requires-Dist: mm-crypto-utils>=0.2.6
5
+ Requires-Dist: aiohttp-socks~=0.10.1
6
+ Requires-Dist: mm-crypto-utils>=0.2.9
6
7
  Requires-Dist: typer>=0.15.2
7
- Requires-Dist: web3~=7.8.0
8
+ Requires-Dist: web3~=7.9.0
8
9
  Requires-Dist: websocket-client~=1.8.0
@@ -1,12 +1,13 @@
1
1
  [project]
2
2
  name = "mm-eth"
3
- version = "0.5.5"
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
12
  ]
12
13
  [project.scripts]
@@ -18,9 +19,9 @@ build-backend = "hatchling.build"
18
19
 
19
20
  [tool.uv]
20
21
  dev-dependencies = [
21
- "pytest~=8.3.4",
22
+ "pytest~=8.3.5",
22
23
  "pytest-xdist~=3.6.1",
23
- "ruff~=0.9.9",
24
+ "ruff~=0.11.2",
24
25
  "pip-audit~=2.8.0",
25
26
  "bandit~=1.8.3",
26
27
  "mypy~=1.15.0",
@@ -46,27 +47,28 @@ target-version = "py313"
46
47
  select = ["ALL"]
47
48
  # fixable = ["F401"]
48
49
  ignore = [
49
- "TC", # flake8-type-checking, TYPE_CHECKING is dangerous, for example it doesn't work with pydantic
50
- "A005", # flake8-builtins: stdlib-module-shadowing
51
- "ERA001", # eradicate: commented-out-code
52
- "PT", # flake8-pytest-style
53
- "D", # pydocstyle
54
- "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
55
56
  "PLR0911", # pylint: too-many-return-statements
56
57
  "PLR0912", # pylint: too-many-branches
57
58
  "PLR0913", # pylint: too-many-arguments
58
59
  "PLR2004", # pylint: magic-value-comparison
59
60
  "PLC0414", # pylint: useless-import-alias
60
- "FBT", # flake8-boolean-trap
61
- "EM", # flake8-errmsg
62
- "TRY003", # tryceratops: raise-vanilla-args
63
- "C901", # mccabe: complex-structure,
64
- "BLE001", # flake8-blind-except
65
- "S311", # bandit: suspicious-non-cryptographic-random-usage
66
- "TD002", # flake8-todos: missing-todo-author
67
- "TD003", # flake8-todos: missing-todo-link
68
- "RET503", # flake8-return: implicit-return
69
- "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
70
72
  ]
71
73
  [tool.ruff.lint.pep8-naming]
72
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,21 +698,22 @@ 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.5"
713
+ version = "0.5.8"
734
714
  source = { editable = "." }
735
715
  dependencies = [
716
+ { name = "aiohttp-socks" },
736
717
  { name = "mm-crypto-utils" },
737
718
  { name = "typer" },
738
719
  { name = "web3" },
@@ -752,9 +733,10 @@ dev = [
752
733
 
753
734
  [package.metadata]
754
735
  requires-dist = [
755
- { name = "mm-crypto-utils", specifier = ">=0.2.6" },
736
+ { name = "aiohttp-socks", specifier = "~=0.10.1" },
737
+ { name = "mm-crypto-utils", specifier = ">=0.2.9" },
756
738
  { name = "typer", specifier = ">=0.15.2" },
757
- { name = "web3", specifier = "~=7.8.0" },
739
+ { name = "web3", specifier = "~=7.9.0" },
758
740
  { name = "websocket-client", specifier = "~=1.8.0" },
759
741
  ]
760
742
 
@@ -763,27 +745,30 @@ dev = [
763
745
  { name = "bandit", specifier = "~=1.8.3" },
764
746
  { name = "mypy", specifier = "~=1.15.0" },
765
747
  { name = "pip-audit", specifier = "~=2.8.0" },
766
- { name = "pytest", specifier = "~=8.3.4" },
748
+ { name = "pytest", specifier = "~=8.3.5" },
767
749
  { name = "pytest-xdist", specifier = "~=3.6.1" },
768
- { name = "ruff", specifier = "~=0.9.9" },
750
+ { name = "ruff", specifier = "~=0.11.2" },
769
751
  { name = "types-pyyaml", specifier = ">=6.0.12.20241230" },
770
752
  ]
771
753
 
772
754
  [[package]]
773
755
  name = "mm-std"
774
- version = "0.3.2"
756
+ version = "0.3.14"
775
757
  source = { registry = "https://pypi.org/simple" }
776
758
  dependencies = [
759
+ { name = "anyio" },
777
760
  { name = "cryptography" },
778
- { name = "httpx", extra = ["http2", "socks"] },
761
+ { name = "httpx", extra = ["socks"] },
779
762
  { name = "pydantic" },
763
+ { name = "pydantic-settings" },
780
764
  { name = "pydash" },
781
765
  { name = "python-dotenv" },
782
- { name = "pyyaml" },
766
+ { name = "requests", extra = ["socks"] },
783
767
  { name = "rich" },
768
+ { name = "tomlkit" },
784
769
  ]
785
770
  wheels = [
786
- { 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 },
787
772
  ]
788
773
 
789
774
  [[package]]
@@ -1133,6 +1118,19 @@ wheels = [
1133
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 },
1134
1119
  ]
1135
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
+
1136
1134
  [[package]]
1137
1135
  name = "pydash"
1138
1136
  version = "8.0.5"
@@ -1163,9 +1161,18 @@ wheels = [
1163
1161
  { url = "https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84", size = 106921 },
1164
1162
  ]
1165
1163
 
1164
+ [[package]]
1165
+ name = "pysocks"
1166
+ version = "1.7.1"
1167
+ source = { registry = "https://pypi.org/simple" }
1168
+ sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429 }
1169
+ wheels = [
1170
+ { url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725 },
1171
+ ]
1172
+
1166
1173
  [[package]]
1167
1174
  name = "pytest"
1168
- version = "8.3.4"
1175
+ version = "8.3.5"
1169
1176
  source = { registry = "https://pypi.org/simple" }
1170
1177
  dependencies = [
1171
1178
  { name = "colorama", marker = "sys_platform == 'win32'" },
@@ -1173,9 +1180,9 @@ dependencies = [
1173
1180
  { name = "packaging" },
1174
1181
  { name = "pluggy" },
1175
1182
  ]
1176
- 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 }
1177
1184
  wheels = [
1178
- { 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 },
1179
1186
  ]
1180
1187
 
1181
1188
  [[package]]
@@ -1200,6 +1207,15 @@ wheels = [
1200
1207
  { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
1201
1208
  ]
1202
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
+
1203
1219
  [[package]]
1204
1220
  name = "pyunormalize"
1205
1221
  version = "16.0.0"
@@ -1301,6 +1317,11 @@ wheels = [
1301
1317
  { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 },
1302
1318
  ]
1303
1319
 
1320
+ [package.optional-dependencies]
1321
+ socks = [
1322
+ { name = "pysocks" },
1323
+ ]
1324
+
1304
1325
  [[package]]
1305
1326
  name = "rich"
1306
1327
  version = "13.9.4"
@@ -1328,27 +1349,27 @@ wheels = [
1328
1349
 
1329
1350
  [[package]]
1330
1351
  name = "ruff"
1331
- version = "0.9.9"
1332
- source = { registry = "https://pypi.org/simple" }
1333
- sdist = { url = "https://files.pythonhosted.org/packages/6f/c3/418441a8170e8d53d05c0b9dad69760dbc7b8a12c10dbe6db1e1205d2377/ruff-0.9.9.tar.gz", hash = "sha256:0062ed13f22173e85f8f7056f9a24016e692efeea8704d1a5e8011b8aa850933", size = 3717448 }
1334
- wheels = [
1335
- { url = "https://files.pythonhosted.org/packages/bc/c3/2c4afa9ba467555d074b146d9aed0633a56ccdb900839fb008295d037b89/ruff-0.9.9-py3-none-linux_armv6l.whl", hash = "sha256:628abb5ea10345e53dff55b167595a159d3e174d6720bf19761f5e467e68d367", size = 10027252 },
1336
- { 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 },
1337
- { 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 },
1338
- { 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 },
1339
- { 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 },
1340
- { 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 },
1341
- { 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 },
1342
- { 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 },
1343
- { 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 },
1344
- { 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 },
1345
- { 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 },
1346
- { 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 },
1347
- { 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 },
1348
- { 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 },
1349
- { url = "https://files.pythonhosted.org/packages/42/55/e6c90f13880aeef327746052907e7e930681f26a164fe130ddac28b08269/ruff-0.9.9-py3-none-win32.whl", hash = "sha256:6b4c376d929c25ecd6d87e182a230fa4377b8e5125a4ff52d506ee8c087153c1", size = 10227912 },
1350
- { url = "https://files.pythonhosted.org/packages/35/b2/da925693cb82a1208aa34966c0f36cb222baca94e729dd22a587bc22d0f3/ruff-0.9.9-py3-none-win_amd64.whl", hash = "sha256:837982ea24091d4c1700ddb2f63b7070e5baec508e43b01de013dc7eff974ff1", size = 11355632 },
1351
- { 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 },
1352
1373
  ]
1353
1374
 
1354
1375
  [[package]]
@@ -1408,6 +1429,15 @@ wheels = [
1408
1429
  { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588 },
1409
1430
  ]
1410
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
+
1411
1441
  [[package]]
1412
1442
  name = "toolz"
1413
1443
  version = "1.0.0"
@@ -1473,7 +1503,7 @@ wheels = [
1473
1503
 
1474
1504
  [[package]]
1475
1505
  name = "web3"
1476
- version = "7.8.0"
1506
+ version = "7.9.0"
1477
1507
  source = { registry = "https://pypi.org/simple" }
1478
1508
  dependencies = [
1479
1509
  { name = "aiohttp" },
@@ -1491,9 +1521,9 @@ dependencies = [
1491
1521
  { name = "typing-extensions" },
1492
1522
  { name = "websockets" },
1493
1523
  ]
1494
- 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 }
1495
1525
  wheels = [
1496
- { 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 },
1497
1527
  ]
1498
1528
 
1499
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