mm-balance 0.1.17__tar.gz → 0.1.18__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 (32) hide show
  1. mm_balance-0.1.18/PKG-INFO +9 -0
  2. mm_balance-0.1.18/pyproject.toml +72 -0
  3. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/cli.py +1 -1
  4. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/config.py +3 -0
  5. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/constants.py +3 -3
  6. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/output/utils.py +1 -1
  7. mm_balance-0.1.18/src/mm_balance/price.py +48 -0
  8. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/result.py +9 -10
  9. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/rpc/aptos.py +1 -1
  10. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/token_decimals.py +1 -3
  11. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/utils.py +1 -1
  12. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/workers.py +6 -5
  13. mm_balance-0.1.18/tests/conftest.py +0 -0
  14. {mm_balance-0.1.17 → mm_balance-0.1.18}/uv.lock +105 -79
  15. mm_balance-0.1.17/PKG-INFO +0 -9
  16. mm_balance-0.1.17/pyproject.toml +0 -61
  17. mm_balance-0.1.17/src/mm_balance/price.py +0 -48
  18. {mm_balance-0.1.17 → mm_balance-0.1.18}/.gitignore +0 -0
  19. {mm_balance-0.1.17 → mm_balance-0.1.18}/README.md +0 -0
  20. {mm_balance-0.1.17 → mm_balance-0.1.18}/justfile +0 -0
  21. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/__init__.py +0 -0
  22. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/config/example.yml +0 -0
  23. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/output/__init__.py +0 -0
  24. {mm_balance-0.1.17/src/mm_balance/rpc → mm_balance-0.1.18/src/mm_balance/output/formats}/__init__.py +0 -0
  25. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/output/formats/json_format.py +0 -0
  26. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/output/formats/table_format.py +0 -0
  27. {mm_balance-0.1.17/tests → mm_balance-0.1.18/src/mm_balance/rpc}/__init__.py +0 -0
  28. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/rpc/btc.py +0 -0
  29. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/rpc/evm.py +0 -0
  30. {mm_balance-0.1.17 → mm_balance-0.1.18}/src/mm_balance/rpc/solana.py +0 -0
  31. /mm_balance-0.1.17/tests/conftest.py → /mm_balance-0.1.18/tests/__init__.py +0 -0
  32. {mm_balance-0.1.17 → mm_balance-0.1.18}/tests/test_dummy.py +0 -0
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: mm-balance
3
+ Version: 0.1.18
4
+ Requires-Python: >=3.12
5
+ Requires-Dist: mm-aptos==0.1.5
6
+ Requires-Dist: mm-btc==0.2.1
7
+ Requires-Dist: mm-eth==0.2.3
8
+ Requires-Dist: mm-solana==0.2.3
9
+ Requires-Dist: typer>=0.15.1
@@ -0,0 +1,72 @@
1
+ [project]
2
+ name = "mm-balance"
3
+ version = "0.1.18"
4
+ description = ""
5
+ requires-python = ">=3.12"
6
+ dependencies = [
7
+ "mm-btc==0.2.1",
8
+ "mm-eth==0.2.3",
9
+ "mm-solana==0.2.3",
10
+ "mm-aptos==0.1.5",
11
+ "typer>=0.15.1",
12
+ ]
13
+ [project.scripts]
14
+ mm-balance = "mm_balance.cli:app"
15
+
16
+ [build-system]
17
+ requires = ["hatchling"]
18
+ build-backend = "hatchling.build"
19
+
20
+ [tool.uv]
21
+ dev-dependencies = [
22
+ "pytest~=8.3.4",
23
+ "pytest-xdist~=3.6.1",
24
+ "ruff~=0.9.2",
25
+ "pip-audit~=2.7.3",
26
+ "bandit~=1.8.2",
27
+ "mypy~=1.14.1",
28
+ "types-PyYAML~=6.0.12.20241230",
29
+ ]
30
+
31
+ [tool.mypy]
32
+ python_version = "3.13"
33
+ warn_no_return = false
34
+ strict = true
35
+ exclude = ["^tests/", "^tmp/"]
36
+
37
+ [tool.ruff]
38
+ line-length = 130
39
+ target-version = "py313"
40
+ [tool.ruff.lint]
41
+ select = ["ALL"]
42
+ ignore = [
43
+ "A005", # flake8-builtins: stdlib-module-shadowing
44
+ "ERA001", # eradicate: commented-out-code
45
+ "PT", # flake8-pytest-style
46
+ "D", # pydocstyle
47
+ "FIX", # flake8-fixme
48
+ "PLR0911", # pylint: too-many-return-statements
49
+ "PLR0912", # pylint: too-many-branches
50
+ "PLR0913", # pylint: too-many-arguments
51
+ "PLR2004", # pylint: magic-value-comparison
52
+ "PLC0414", # pylint: useless-import-alias
53
+ "FBT", # flake8-boolean-trap
54
+ "EM", # flake8-errmsg
55
+ "TRY003", # tryceratops: raise-vanilla-args
56
+ "C901", # mccabe: complex-structure,
57
+ "BLE001", # flake8-blind-except
58
+ "S311", # bandit: suspicious-non-cryptographic-random-usage
59
+ "TD002", # flake8-todos: missing-todo-author
60
+ "TD003", # flake8-todos: missing-todo-link
61
+ "RET503", # flake8-return: implicit-return
62
+ "COM812", # it's used in ruff formatter
63
+ ]
64
+ [tool.ruff.lint.per-file-ignores]
65
+ "tests/*.py" = ["ANN", "S"]
66
+ [tool.ruff.format]
67
+ quote-style = "double"
68
+ indent-style = "space"
69
+
70
+ [tool.bandit]
71
+ exclude_dirs = ["tests"]
72
+ skips = ["B311"]
@@ -46,7 +46,7 @@ def cli(
46
46
  zip_password = "" # nosec
47
47
  if config_path.name.endswith(".zip"):
48
48
  zip_password = getpass.getpass("zip password")
49
- config = Config.read_config(config_path, zip_password=zip_password)
49
+ config = Config.read_config_or_exit(config_path, zip_password=zip_password)
50
50
 
51
51
  if print_format is not None:
52
52
  config.print_format = print_format
@@ -30,10 +30,12 @@ class Group(BaseConfig):
30
30
  result += " / " + self.network
31
31
  return result
32
32
 
33
+ @classmethod
33
34
  @field_validator("ticker", mode="after")
34
35
  def ticker_validator(cls, v: str) -> str:
35
36
  return v.upper()
36
37
 
38
+ @classmethod
37
39
  @field_validator("addresses", mode="before")
38
40
  def to_list_validator(cls, v: str | list[str] | None) -> list[str]:
39
41
  return cls.to_list_str_validator(v, unique=True, remove_comments=True, split_line=True)
@@ -67,6 +69,7 @@ class AddressGroup(BaseConfig):
67
69
  name: str
68
70
  addresses: list[str]
69
71
 
72
+ @classmethod
70
73
  @field_validator("addresses", mode="before")
71
74
  def to_list_validator(cls, v: str | list[str] | None) -> list[str]:
72
75
  return cls.to_list_str_validator(v, unique=True, remove_comments=True, split_line=True)
@@ -1,5 +1,3 @@
1
- from typing import Any
2
-
3
1
  from pydantic import GetCoreSchemaHandler
4
2
  from pydantic_core import CoreSchema, core_schema
5
3
 
@@ -11,11 +9,13 @@ TIMEOUT_DECIMALS = 5
11
9
 
12
10
 
13
11
  class Network(str):
12
+ __slots__ = ()
13
+
14
14
  def is_evm_network(self) -> bool:
15
15
  return self in [NETWORK_ETHEREUM, NETWORK_ARBITRUM_ONE, NETWORK_OP_MAINNET] or self.startswith("evm-")
16
16
 
17
17
  @classmethod
18
- def __get_pydantic_core_schema__(cls, _source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema:
18
+ def __get_pydantic_core_schema__(cls, _source_type: object, handler: GetCoreSchemaHandler) -> CoreSchema:
19
19
  return core_schema.no_info_after_validator_function(cls, handler(str))
20
20
 
21
21
 
@@ -7,7 +7,7 @@ def format_number(value: Decimal, separator: str, extra: str | None = None) -> s
7
7
  str_value = f"{value:,}".replace(",", separator)
8
8
  if extra == "$":
9
9
  return "$" + str_value
10
- elif extra == "%":
10
+ if extra == "%":
11
11
  return str_value + "%"
12
12
  return str_value
13
13
 
@@ -0,0 +1,48 @@
1
+ from collections import defaultdict
2
+ from decimal import Decimal
3
+
4
+ import pydash
5
+ from mm_std import hr
6
+ from mm_std.random_ import random_str_choice
7
+
8
+ from mm_balance.config import Config, Group
9
+ from mm_balance.constants import RETRIES_COINGECKO_PRICES, TICKER_TO_COINGECKO_ID
10
+
11
+
12
+ class Prices(defaultdict[str, Decimal]):
13
+ """
14
+ A Prices class representing a mapping from coin names to their prices.
15
+
16
+ Inherits from:
17
+ Dict[str, Decimal]: A dictionary with coin names as keys and their prices as Decimal values.
18
+ """
19
+
20
+
21
+ def get_prices(config: Config) -> Prices:
22
+ result = Prices()
23
+
24
+ coingecko_map: dict[str, str] = {} # ticker -> coingecko_id
25
+
26
+ for group in config.groups:
27
+ coingecko_id = get_coingecko_id(group)
28
+ if coingecko_id:
29
+ coingecko_map[group.ticker] = coingecko_id
30
+
31
+ url = f"https://api.coingecko.com/api/v3/simple/price?ids={','.join(coingecko_map.values())}&vs_currencies=usd"
32
+ for _ in range(RETRIES_COINGECKO_PRICES):
33
+ res = hr(url, proxy=random_str_choice(config.proxies))
34
+ if res.code != 200:
35
+ continue
36
+
37
+ for ticker, coingecko_id in coingecko_map.items():
38
+ if coingecko_id in res.json:
39
+ result[ticker] = Decimal(str(pydash.get(res.json, f"{coingecko_id}.usd")))
40
+ break
41
+
42
+ return result
43
+
44
+
45
+ def get_coingecko_id(group: Group) -> str | None:
46
+ if group.coingecko_id:
47
+ return group.coingecko_id
48
+ return TICKER_TO_COINGECKO_ID.get(group.ticker)
@@ -102,17 +102,16 @@ def _create_group_result(config: Config, group: Group, tasks: list[Task], prices
102
102
  balance: Balance | str
103
103
  if task.balance is None:
104
104
  balance = "balance is None! Something went wrong."
105
+ elif isinstance(task.balance, Ok):
106
+ coin_value = task.balance.ok
107
+ usd_value = Decimal(0)
108
+ if group.ticker in prices:
109
+ usd_value = round(coin_value * prices[group.ticker], config.round_ndigits)
110
+ balance = Balance(balance=coin_value, usd_value=usd_value)
111
+ balance_sum += balance.balance
112
+ usd_sum += balance.usd_value
105
113
  else:
106
- if isinstance(task.balance, Ok):
107
- coin_value = task.balance.ok
108
- usd_value = Decimal(0)
109
- if group.ticker in prices:
110
- usd_value = round(coin_value * prices[group.ticker], config.round_ndigits)
111
- balance = Balance(balance=coin_value, usd_value=usd_value)
112
- balance_sum += balance.balance
113
- usd_sum += balance.usd_value
114
- else:
115
- balance = task.balance.err
114
+ balance = task.balance.err
116
115
  addresses.append(AddressBalance(address=task.wallet_address, balance=balance))
117
116
 
118
117
  balance_sum_share = balance_sum * group.share
@@ -10,7 +10,7 @@ def get_balance(
10
10
  nodes: list[str], wallet: str, token: str | None, decimals: int, proxies: list[str], round_ndigits: int
11
11
  ) -> Result[Decimal]:
12
12
  if token is None:
13
- token = "0x1::aptos_coin::AptosCoin" # nosec
13
+ token = "0x1::aptos_coin::AptosCoin" # noqa: S105 # nosec
14
14
  return balance.get_decimal_balance_with_retries(
15
15
  RETRIES_BALANCE,
16
16
  nodes,
@@ -28,9 +28,7 @@ def get_token_decimals(config: Config) -> TokenDecimals:
28
28
  result[group.network][None] = 18
29
29
  elif group.network == NETWORK_SOLANA:
30
30
  result[group.network][None] = 9
31
- elif group.network == NETWORK_BITCOIN:
32
- result[group.network][None] = 8
33
- elif group.network == NETWORK_APTOS:
31
+ elif group.network in (NETWORK_BITCOIN, NETWORK_APTOS):
34
32
  result[group.network][None] = 8
35
33
  else:
36
34
  fatal(f"Can't get token decimals for native token on network: {group.network}")
@@ -5,6 +5,6 @@ def fnumber(value: Decimal, separator: str, extra: str | None = None) -> str:
5
5
  str_value = f"{value:,}".replace(",", separator)
6
6
  if extra == "$":
7
7
  return "$" + str_value
8
- elif extra == "%":
8
+ if extra == "%":
9
9
  return str_value + "%"
10
10
  return str_value
@@ -1,8 +1,8 @@
1
1
  from dataclasses import dataclass
2
2
  from decimal import Decimal
3
+ from typing import TYPE_CHECKING
3
4
 
4
5
  from mm_std import ConcurrentTasks, PrintFormat, Result
5
- from rich.progress import TaskID
6
6
 
7
7
  from mm_balance.config import Config
8
8
  from mm_balance.constants import NETWORK_APTOS, NETWORK_BITCOIN, NETWORK_SOLANA, Network
@@ -10,6 +10,9 @@ from mm_balance.output import utils
10
10
  from mm_balance.rpc import aptos, btc, evm, solana
11
11
  from mm_balance.token_decimals import TokenDecimals
12
12
 
13
+ if TYPE_CHECKING:
14
+ from rich.progress import TaskID
15
+
13
16
 
14
17
  @dataclass
15
18
  class Task:
@@ -20,7 +23,7 @@ class Task:
20
23
 
21
24
 
22
25
  class Workers:
23
- def __init__(self, config: Config, token_decimals: TokenDecimals):
26
+ def __init__(self, config: Config, token_decimals: TokenDecimals) -> None:
24
27
  self.config = config
25
28
  self.token_decimals = token_decimals
26
29
  self.tasks: dict[Network, list[Task]] = {network: [] for network in config.networks()}
@@ -49,9 +52,7 @@ class Workers:
49
52
  def get_errors(self) -> list[Task]:
50
53
  result = []
51
54
  for network in self.tasks:
52
- for task in self.tasks[network]:
53
- if task.balance is not None and task.balance.is_err():
54
- result.append(task)
55
+ result.extend([task for task in self.tasks[network] if task.balance is not None and task.balance.is_err()])
55
56
  return result
56
57
 
57
58
  def _process_network(self, network: Network) -> None:
File without changes
@@ -115,7 +115,7 @@ wheels = [
115
115
 
116
116
  [[package]]
117
117
  name = "bandit"
118
- version = "1.8.0"
118
+ version = "1.8.2"
119
119
  source = { registry = "https://pypi.org/simple" }
120
120
  dependencies = [
121
121
  { name = "colorama", marker = "sys_platform == 'win32'" },
@@ -123,9 +123,9 @@ dependencies = [
123
123
  { name = "rich" },
124
124
  { name = "stevedore" },
125
125
  ]
126
- sdist = { url = "https://files.pythonhosted.org/packages/57/c3/bea54f22cdc8224f0ace18b2cf86c6adf7010285d0ed51b703af9910c5b2/bandit-1.8.0.tar.gz", hash = "sha256:b5bfe55a095abd9fe20099178a7c6c060f844bfd4fe4c76d28e35e4c52b9d31e", size = 4228600 }
126
+ sdist = { url = "https://files.pythonhosted.org/packages/9b/e2/c229cdb4eefc124e5b77ac2557eb0a3cb5b9fc89bc465dd2b8dc1033dbb8/bandit-1.8.2.tar.gz", hash = "sha256:e00ad5a6bc676c0954669fe13818024d66b70e42cf5adb971480cf3b671e835f", size = 4228832 }
127
127
  wheels = [
128
- { url = "https://files.pythonhosted.org/packages/24/6b/a9f0574d05d63e7d8125cd02a52732adb6720a9b9f13c921386cb9cdb53e/bandit-1.8.0-py3-none-any.whl", hash = "sha256:b1a61d829c0968aed625381e426aa378904b996529d048f8d908fa28f6b13e38", size = 127035 },
128
+ { url = "https://files.pythonhosted.org/packages/1c/c1/991a7a1404626558cc7db0cc34243e13e5e336eba053bf6979e9fd6006f7/bandit-1.8.2-py3-none-any.whl", hash = "sha256:df6146ad73dd30e8cbda4e29689ddda48364e36ff655dbfc86998401fcf1721f", size = 127049 },
129
129
  ]
130
130
 
131
131
  [[package]]
@@ -767,7 +767,7 @@ wheels = [
767
767
 
768
768
  [[package]]
769
769
  name = "hdwallet"
770
- version = "3.2.0"
770
+ version = "3.2.3"
771
771
  source = { registry = "https://pypi.org/simple" }
772
772
  dependencies = [
773
773
  { name = "base58" },
@@ -779,9 +779,9 @@ dependencies = [
779
779
  { name = "pycryptodome" },
780
780
  { name = "pynacl" },
781
781
  ]
782
- sdist = { url = "https://files.pythonhosted.org/packages/08/e7/68289fbde41b8fc6d34ee1d6f1c3fde00a9c9956c5bfc6e25fce53211a05/hdwallet-3.2.0.tar.gz", hash = "sha256:e0c39fc89a885d5f598279008837ee4d13f8188bf8adbcdc646c9502b08b487f", size = 398282 }
782
+ sdist = { url = "https://files.pythonhosted.org/packages/65/f7/980bee740a9bbf2adbf81e0a20f2fd1ef731d7b5a259eabaebb23e37572f/hdwallet-3.2.3.tar.gz", hash = "sha256:7e2f0e44794207eaacf18bc80420f9734d51b55d11de1a8b3d66ea68ef508c14", size = 400441 }
783
783
  wheels = [
784
- { url = "https://files.pythonhosted.org/packages/bc/1d/8ae16efaf6a680bf44e41e9dff3de0d397c2e83263c5f9137f00a7b021aa/hdwallet-3.2.0-py3-none-any.whl", hash = "sha256:421d3927c217d7f9fc411b3ca51c43db1c92ac498011389762489538a117340c", size = 635335 },
784
+ { url = "https://files.pythonhosted.org/packages/f0/00/1dbc04400d5dad78c651a84e43cb77797ab31fdb879aa5570e8eec35d22e/hdwallet-3.2.3-py3-none-any.whl", hash = "sha256:dc49ae25466433dd5a804bd6a5abfe639aed67b57a60f392898ebc3e76174e05", size = 636195 },
785
785
  ]
786
786
 
787
787
  [[package]]
@@ -911,6 +911,19 @@ wheels = [
911
911
  { url = "https://files.pythonhosted.org/packages/fc/f8/5699e6d6ea5156d53059ff07464b5d64389b084f67cb08ec97c711e587fc/license_expression-30.4.0-py3-none-any.whl", hash = "sha256:7c8f240c6e20d759cb8455e49cb44a923d9e25c436bf48d7e5b8eea660782c04", size = 110571 },
912
912
  ]
913
913
 
914
+ [[package]]
915
+ name = "loguru"
916
+ version = "0.7.3"
917
+ source = { registry = "https://pypi.org/simple" }
918
+ dependencies = [
919
+ { name = "colorama", marker = "sys_platform == 'win32'" },
920
+ { name = "win32-setctime", marker = "sys_platform == 'win32'" },
921
+ ]
922
+ sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559 }
923
+ wheels = [
924
+ { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595 },
925
+ ]
926
+
914
927
  [[package]]
915
928
  name = "markdown-it-py"
916
929
  version = "3.0.0"
@@ -972,14 +985,14 @@ wheels = [
972
985
 
973
986
  [[package]]
974
987
  name = "mm-aptos"
975
- version = "0.1.4"
988
+ version = "0.1.5"
976
989
  source = { registry = "https://pypi.org/simple" }
977
990
  dependencies = [
978
991
  { name = "mm-std" },
979
992
  ]
980
- sdist = { url = "https://files.pythonhosted.org/packages/dd/bb/0cd33548e7f4b6642d64bf33b394beaf8a6dc102a276c4fa4a50c2b7af15/mm_aptos-0.1.4.tar.gz", hash = "sha256:004592ea02757ed50f2c47e6c9af445b6cdd6f3ceba7ff880bc30caecfd3b8db", size = 32574 }
993
+ sdist = { url = "https://files.pythonhosted.org/packages/6f/75/36b9b5398bfa5bf40ccdd0af892e3951de3d526404b7c00d7ff433e4dcdd/mm_aptos-0.1.5.tar.gz", hash = "sha256:ab5c86d751d5e72a801fdefb9c7ea508306eba96431518df4527acce12249511", size = 33059 }
981
994
  wheels = [
982
- { url = "https://files.pythonhosted.org/packages/f1/eb/4fa0ba76c3c97df1c9bf7770f6e410bbe2be5a91c88ad3c59214c3b6ed03/mm_aptos-0.1.4-py3-none-any.whl", hash = "sha256:a74144cd0025f22878d177c4444b04ea7dee755e8621925373637930f632c3a4", size = 3641 },
995
+ { url = "https://files.pythonhosted.org/packages/21/6c/f951008f8bd7d2d078284f5f3ef578b3cc803c537508b98f016a145bef19/mm_aptos-0.1.5-py3-none-any.whl", hash = "sha256:def512c8329ba5362eaf288c47397ea64d6a4ba0e9beff8733c9d8584efacf4d", size = 3644 },
983
996
  ]
984
997
 
985
998
  [[package]]
@@ -1007,27 +1020,27 @@ dev = [
1007
1020
 
1008
1021
  [package.metadata]
1009
1022
  requires-dist = [
1010
- { name = "mm-aptos", specifier = "==0.1.4" },
1011
- { name = "mm-btc", specifier = "==0.2.0" },
1012
- { name = "mm-eth", specifier = "==0.2.0" },
1013
- { name = "mm-solana", specifier = "==0.2.0" },
1023
+ { name = "mm-aptos", specifier = "==0.1.5" },
1024
+ { name = "mm-btc", specifier = "==0.2.1" },
1025
+ { name = "mm-eth", specifier = "==0.2.3" },
1026
+ { name = "mm-solana", specifier = "==0.2.3" },
1014
1027
  { name = "typer", specifier = ">=0.15.1" },
1015
1028
  ]
1016
1029
 
1017
1030
  [package.metadata.requires-dev]
1018
1031
  dev = [
1019
- { name = "bandit", specifier = "~=1.8.0" },
1020
- { name = "mypy", specifier = "~=1.14.0" },
1032
+ { name = "bandit", specifier = "~=1.8.2" },
1033
+ { name = "mypy", specifier = "~=1.14.1" },
1021
1034
  { name = "pip-audit", specifier = "~=2.7.3" },
1022
1035
  { name = "pytest", specifier = "~=8.3.4" },
1023
1036
  { name = "pytest-xdist", specifier = "~=3.6.1" },
1024
- { name = "ruff", specifier = "~=0.8.4" },
1025
- { name = "types-pyyaml", specifier = "~=6.0.12.20241221" },
1037
+ { name = "ruff", specifier = "~=0.9.2" },
1038
+ { name = "types-pyyaml", specifier = "~=6.0.12.20241230" },
1026
1039
  ]
1027
1040
 
1028
1041
  [[package]]
1029
1042
  name = "mm-btc"
1030
- version = "0.2.0"
1043
+ version = "0.2.1"
1031
1044
  source = { registry = "https://pypi.org/simple" }
1032
1045
  dependencies = [
1033
1046
  { name = "bit" },
@@ -1035,44 +1048,48 @@ dependencies = [
1035
1048
  { name = "hdwallet" },
1036
1049
  { name = "mm-std" },
1037
1050
  { name = "mnemonic" },
1051
+ { name = "typer" },
1038
1052
  ]
1039
- sdist = { url = "https://files.pythonhosted.org/packages/01/ac/bce0df18934eb2d7d161621fcee68ee4c7fe4913ef1cc62aa4306ce31de7/mm_btc-0.2.0.tar.gz", hash = "sha256:ff87826267fa04bd64a34d9fb351e3784552fd4cffca584213a7a8a74ae2a095", size = 48012 }
1053
+ sdist = { url = "https://files.pythonhosted.org/packages/02/c2/2d6eedfa4aa32e19a871ac71815d2912d89fd8edeeff71cf957e8ce3a034/mm_btc-0.2.1.tar.gz", hash = "sha256:eb79e8a5fd622388520b3bf2bfb5a5ed128735cef05d09f90b6f27f98f655385", size = 54557 }
1040
1054
  wheels = [
1041
- { url = "https://files.pythonhosted.org/packages/9b/b9/6cb39517e875ffad693d1bec81f64e9b4f7a74547e0f702ab7e5ed4b864e/mm_btc-0.2.0-py3-none-any.whl", hash = "sha256:5b1f80f8fd27864b1b89d9bf5fe9f53e094b6726579b9d5026205617e084655a", size = 3633 },
1055
+ { url = "https://files.pythonhosted.org/packages/9a/76/e0a8404bf1e1acd262967384c9d8a72b3074fedcc9d4b505337404743c97/mm_btc-0.2.1-py3-none-any.whl", hash = "sha256:720b4e1881fbe35a755869d0cfd18371ecd65a95169c775cfd7932028536496d", size = 7842 },
1042
1056
  ]
1043
1057
 
1044
1058
  [[package]]
1045
1059
  name = "mm-eth"
1046
- version = "0.2.0"
1060
+ version = "0.2.3"
1047
1061
  source = { registry = "https://pypi.org/simple" }
1048
1062
  dependencies = [
1063
+ { name = "loguru" },
1049
1064
  { name = "mm-std" },
1065
+ { name = "typer" },
1050
1066
  { name = "web3" },
1051
1067
  { name = "websocket-client" },
1052
1068
  ]
1053
- sdist = { url = "https://files.pythonhosted.org/packages/13/20/0a767be78c665488f2dc0ca5a5888dc0ecc84440bae309308f39d69bc857/mm_eth-0.2.0.tar.gz", hash = "sha256:32f4a3939b948e2ba2adc5bfd4d14118d3b1b0d5911fce0ab6e3dfafd48e54ce", size = 79968 }
1069
+ sdist = { url = "https://files.pythonhosted.org/packages/30/17/e876c8c5da64701dc8e4463a1a1a88995366565a7f84ebd92a62fd8211d2/mm_eth-0.2.3.tar.gz", hash = "sha256:67337572010a445d57a49ce1fd67b6d8ab046cff5e1acee6e7a3acd2acfae4e9", size = 96413 }
1054
1070
  wheels = [
1055
- { url = "https://files.pythonhosted.org/packages/56/93/ee3788eeba6549d7e9feafe93a13a627e5f3baf8978d3a7514ab8b9ec023/mm_eth-0.2.0-py3-none-any.whl", hash = "sha256:54e486e5c9409062bc15e0b69f5be4cebf300c5db61042cba0975515a360a8da", size = 16021 },
1071
+ { url = "https://files.pythonhosted.org/packages/14/ac/4a87567c76cc26a2effbcfb4444a07e937cae99d744cd2b6206f27155e4a/mm_eth-0.2.3-py3-none-any.whl", hash = "sha256:4b8e0a2cd1bd102eb12ff86845e61902ae5c45a8d51b35ad7a683d9cacca7d87", size = 43146 },
1056
1072
  ]
1057
1073
 
1058
1074
  [[package]]
1059
1075
  name = "mm-solana"
1060
- version = "0.2.0"
1076
+ version = "0.2.3"
1061
1077
  source = { registry = "https://pypi.org/simple" }
1062
1078
  dependencies = [
1063
1079
  { name = "base58" },
1064
1080
  { name = "jinja2" },
1065
1081
  { name = "mm-std" },
1066
1082
  { name = "solana" },
1083
+ { name = "typer" },
1067
1084
  ]
1068
- sdist = { url = "https://files.pythonhosted.org/packages/3b/23/8f52d25648e24eae61a510041588e2d34d1d5e87560ca5e49855a893a99e/mm_solana-0.2.0.tar.gz", hash = "sha256:a393636e095d956d51e57e4d5793d4fc88600b389b386cfbeedc4fd23234f5a2", size = 45812 }
1085
+ sdist = { url = "https://files.pythonhosted.org/packages/09/58/b70879b0e5ec770cda1cde3c8b9faf3c30751a9e3111d90ce114f673810d/mm_solana-0.2.3.tar.gz", hash = "sha256:2b1dd6e005cb01d1a6415929b8798fdc0b527a4e2cfd8d67c7a8e0d0a5e3aabb", size = 50110 }
1069
1086
  wheels = [
1070
- { url = "https://files.pythonhosted.org/packages/26/27/300647466d41bc81be16c5391af8448846355a74e5559f2093a3a9abef0f/mm_solana-0.2.0-py3-none-any.whl", hash = "sha256:a740db39eedfd6bd99a10ee169cb001b801f9b13116401a1ff077c18299511e7", size = 10711 },
1087
+ { url = "https://files.pythonhosted.org/packages/19/67/effa702d12ea9585e3f8990626b07bc2913bca695f03f693036171801fea/mm_solana-0.2.3-py3-none-any.whl", hash = "sha256:311de67157b9a6a5340eaf72366aae2d04f62f839699c27d37ef81d4a51e64f2", size = 16891 },
1071
1088
  ]
1072
1089
 
1073
1090
  [[package]]
1074
1091
  name = "mm-std"
1075
- version = "0.1.9"
1092
+ version = "0.1.12"
1076
1093
  source = { registry = "https://pypi.org/simple" }
1077
1094
  dependencies = [
1078
1095
  { name = "cryptography" },
@@ -1084,7 +1101,7 @@ dependencies = [
1084
1101
  { name = "rich" },
1085
1102
  ]
1086
1103
  wheels = [
1087
- { url = "https://files.pythonhosted.org/packages/96/68/05221e7d6f0411f380fdbb40d7bdceb2597554257a8a2ee0a74bf7dcd577/mm_std-0.1.9-py3-none-any.whl", hash = "sha256:8405d67d885be381d01492e72e5c0039dd893a95a1df65994bcb990a28ae04d1", size = 15130 },
1104
+ { url = "https://files.pythonhosted.org/packages/ca/18/ea37b98761b2d39ff2d45e985e4ef5eedae08a421cee3ee19088a9c0da03/mm_std-0.1.12-py3-none-any.whl", hash = "sha256:2e3d3ed745755096cecf9690ca2fb772abed1a4064935717ce3c8824b7cabd83", size = 14699 },
1088
1105
  ]
1089
1106
 
1090
1107
  [[package]]
@@ -1167,25 +1184,27 @@ wheels = [
1167
1184
 
1168
1185
  [[package]]
1169
1186
  name = "mypy"
1170
- version = "1.14.0"
1187
+ version = "1.14.1"
1171
1188
  source = { registry = "https://pypi.org/simple" }
1172
1189
  dependencies = [
1173
1190
  { name = "mypy-extensions" },
1174
1191
  { name = "typing-extensions" },
1175
1192
  ]
1176
- sdist = { url = "https://files.pythonhosted.org/packages/8c/7b/08046ef9330735f536a09a2e31b00f42bccdb2795dcd979636ba43bb2d63/mypy-1.14.0.tar.gz", hash = "sha256:822dbd184d4a9804df5a7d5335a68cf7662930e70b8c1bc976645d1509f9a9d6", size = 3215684 }
1193
+ sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051 }
1177
1194
  wheels = [
1178
- { url = "https://files.pythonhosted.org/packages/fe/d8/0e72175ee0253217f5c44524f5e95251c02e95ba9749fb87b0e2074d203a/mypy-1.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d5326ab70a6db8e856d59ad4cb72741124950cbbf32e7b70e30166ba7bbf61dd", size = 11269011 },
1179
- { url = "https://files.pythonhosted.org/packages/e9/6d/4ea13839dabe5db588dc6a1b766da16f420d33cf118a7b7172cdf6c7fcb2/mypy-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf4ec4980bec1e0e24e5075f449d014011527ae0055884c7e3abc6a99cd2c7f1", size = 10253076 },
1180
- { url = "https://files.pythonhosted.org/packages/3e/38/7db2c5d0f4d290e998f7a52b2e2616c7bbad96b8e04278ab09d11978a29e/mypy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:390dfb898239c25289495500f12fa73aa7f24a4c6d90ccdc165762462b998d63", size = 12862786 },
1181
- { url = "https://files.pythonhosted.org/packages/bf/4b/62d59c801b34141040989949c2b5c157d0408b45357335d3ec5b2845b0f6/mypy-1.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7e026d55ddcd76e29e87865c08cbe2d0104e2b3153a523c529de584759379d3d", size = 12971568 },
1182
- { url = "https://files.pythonhosted.org/packages/f1/9c/e0f281b32d70c87b9e4d2939e302b1ff77ada4d7b0f2fb32890c144bc1d6/mypy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:585ed36031d0b3ee362e5107ef449a8b5dfd4e9c90ccbe36414ee405ee6b32ba", size = 9879477 },
1183
- { url = "https://files.pythonhosted.org/packages/13/33/8380efd0ebdfdfac7fc0bf065f03a049800ca1e6c296ec1afc634340d992/mypy-1.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9f6f4c0b27401d14c483c622bc5105eff3911634d576bbdf6695b9a7c1ba741", size = 11251509 },
1184
- { url = "https://files.pythonhosted.org/packages/15/6d/4e1c21c60fee11af7d8e4f2902a29886d1387d6a836be16229eb3982a963/mypy-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b2280cedcb312c7a79f5001ae5325582d0d339bce684e4a529069d0e7ca1e7", size = 10244282 },
1185
- { url = "https://files.pythonhosted.org/packages/8b/cf/7a8ae5c0161edae15d25c2c67c68ce8b150cbdc45aefc13a8be271ee80b2/mypy-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:342de51c48bab326bfc77ce056ba08c076d82ce4f5a86621f972ed39970f94d8", size = 12867676 },
1186
- { url = "https://files.pythonhosted.org/packages/9c/d0/71f7bbdcc7cfd0f2892db5b13b1e8857673f2cc9e0c30e3e4340523dc186/mypy-1.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:00df23b42e533e02a6f0055e54de9a6ed491cd8b7ea738647364fd3a39ea7efc", size = 12964189 },
1187
- { url = "https://files.pythonhosted.org/packages/a7/40/fb4ad65d6d5f8c51396ecf6305ec0269b66013a5bf02d0e9528053640b4a/mypy-1.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:e8c8387e5d9dff80e7daf961df357c80e694e942d9755f3ad77d69b0957b8e3f", size = 9888247 },
1188
- { url = "https://files.pythonhosted.org/packages/39/32/0214608af400cdf8f5102144bb8af10d880675c65ed0b58f7e0e77175d50/mypy-1.14.0-py3-none-any.whl", hash = "sha256:2238d7f93fc4027ed1efc944507683df3ba406445a2b6c96e79666a045aadfab", size = 2752803 },
1195
+ { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668 },
1196
+ { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060 },
1197
+ { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167 },
1198
+ { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341 },
1199
+ { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991 },
1200
+ { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016 },
1201
+ { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097 },
1202
+ { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728 },
1203
+ { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965 },
1204
+ { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660 },
1205
+ { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198 },
1206
+ { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276 },
1207
+ { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905 },
1189
1208
  ]
1190
1209
 
1191
1210
  [[package]]
@@ -1415,22 +1434,20 @@ wheels = [
1415
1434
  { url = "https://files.pythonhosted.org/packages/39/1b/d0b013bf7d1af7cf0a6a4fce13f5fe5813ab225313755367b36e714a63f8/pycryptodome-3.21.0-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:18caa8cfbc676eaaf28613637a89980ad2fd96e00c564135bf90bc3f0b34dd93", size = 2254397 },
1416
1435
  { url = "https://files.pythonhosted.org/packages/14/71/4cbd3870d3e926c34706f705d6793159ac49d9a213e3ababcdade5864663/pycryptodome-3.21.0-cp36-abi3-win32.whl", hash = "sha256:280b67d20e33bb63171d55b1067f61fbd932e0b1ad976b3a184303a3dad22764", size = 1775641 },
1417
1436
  { url = "https://files.pythonhosted.org/packages/43/1d/81d59d228381576b92ecede5cd7239762c14001a828bdba30d64896e9778/pycryptodome-3.21.0-cp36-abi3-win_amd64.whl", hash = "sha256:b7aa25fc0baa5b1d95b7633af4f5f1838467f1815442b22487426f94e0d66c53", size = 1812863 },
1418
- { url = "https://files.pythonhosted.org/packages/25/b3/09ff7072e6d96c9939c24cf51d3c389d7c345bf675420355c22402f71b68/pycryptodome-3.21.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:2cb635b67011bc147c257e61ce864879ffe6d03342dc74b6045059dfbdedafca", size = 1691593 },
1419
- { url = "https://files.pythonhosted.org/packages/a8/91/38e43628148f68ba9b68dedbc323cf409e537fd11264031961fd7c744034/pycryptodome-3.21.0-pp27-pypy_73-win32.whl", hash = "sha256:4c26a2f0dc15f81ea3afa3b0c87b87e501f235d332b7f27e2225ecb80c0b1cdd", size = 1765997 },
1420
1437
  ]
1421
1438
 
1422
1439
  [[package]]
1423
1440
  name = "pydantic"
1424
- version = "2.10.4"
1441
+ version = "2.10.5"
1425
1442
  source = { registry = "https://pypi.org/simple" }
1426
1443
  dependencies = [
1427
1444
  { name = "annotated-types" },
1428
1445
  { name = "pydantic-core" },
1429
1446
  { name = "typing-extensions" },
1430
1447
  ]
1431
- sdist = { url = "https://files.pythonhosted.org/packages/70/7e/fb60e6fee04d0ef8f15e4e01ff187a196fa976eb0f0ab524af4599e5754c/pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06", size = 762094 }
1448
+ sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/ca334c2ef6f2e046b1144fe4bb2a5da8a4c574e7f2ebf7e16b34a6a2fa92/pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff", size = 761287 }
1432
1449
  wheels = [
1433
- { url = "https://files.pythonhosted.org/packages/f3/26/3e1bbe954fde7ee22a6e7d31582c642aad9e84ffe4b5fb61e63b87cd326f/pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d", size = 431765 },
1450
+ { url = "https://files.pythonhosted.org/packages/58/26/82663c79010b28eddf29dcdd0ea723439535fa917fce5905885c0e9ba562/pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53", size = 431426 },
1434
1451
  ]
1435
1452
 
1436
1453
  [[package]]
@@ -1474,14 +1491,14 @@ wheels = [
1474
1491
 
1475
1492
  [[package]]
1476
1493
  name = "pydash"
1477
- version = "8.0.4"
1494
+ version = "8.0.5"
1478
1495
  source = { registry = "https://pypi.org/simple" }
1479
1496
  dependencies = [
1480
1497
  { name = "typing-extensions" },
1481
1498
  ]
1482
- sdist = { url = "https://files.pythonhosted.org/packages/78/18/02df732cb657f14997ee4c9d93006e61e93a1816cfdc23763a86c78f9b61/pydash-8.0.4.tar.gz", hash = "sha256:a33fb17b4b06c617da5c57c711605d2dc8723311ee5388c8371f87cd44bf4112", size = 164676 }
1499
+ sdist = { url = "https://files.pythonhosted.org/packages/2f/24/91c037f47e434172c2112d65c00c84d475a6715425e3315ba2cbb7a87e66/pydash-8.0.5.tar.gz", hash = "sha256:7cc44ebfe5d362f4f5f06c74c8684143c5ac481376b059ff02570705523f9e2e", size = 164861 }
1483
1500
  wheels = [
1484
- { url = "https://files.pythonhosted.org/packages/49/c4/746eb7637eb11149a67469c16023eb6e6fa6aa62dc31d1f0a569393c3745/pydash-8.0.4-py3-none-any.whl", hash = "sha256:59d0c9ca0d22b4f8bcfab01bfe2e89b49f4c9e9fa75961caf156094670260999", size = 101938 },
1501
+ { url = "https://files.pythonhosted.org/packages/2c/86/e74c978800131c657fc5145f2c1c63e0cea01a49b6216f729cf77a2e1edf/pydash-8.0.5-py3-none-any.whl", hash = "sha256:b2625f8981862e19911daa07f80ed47b315ce20d9b5eb57aaf97aaf570c3892f", size = 102077 },
1485
1502
  ]
1486
1503
 
1487
1504
  [[package]]
@@ -1687,27 +1704,27 @@ wheels = [
1687
1704
 
1688
1705
  [[package]]
1689
1706
  name = "ruff"
1690
- version = "0.8.4"
1691
- source = { registry = "https://pypi.org/simple" }
1692
- sdist = { url = "https://files.pythonhosted.org/packages/34/37/9c02181ef38d55b77d97c68b78e705fd14c0de0e5d085202bb2b52ce5be9/ruff-0.8.4.tar.gz", hash = "sha256:0d5f89f254836799af1615798caa5f80b7f935d7a670fad66c5007928e57ace8", size = 3402103 }
1693
- wheels = [
1694
- { url = "https://files.pythonhosted.org/packages/05/67/f480bf2f2723b2e49af38ed2be75ccdb2798fca7d56279b585c8f553aaab/ruff-0.8.4-py3-none-linux_armv6l.whl", hash = "sha256:58072f0c06080276804c6a4e21a9045a706584a958e644353603d36ca1eb8a60", size = 10546415 },
1695
- { url = "https://files.pythonhosted.org/packages/eb/7a/5aba20312c73f1ce61814e520d1920edf68ca3b9c507bd84d8546a8ecaa8/ruff-0.8.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ffb60904651c00a1e0b8df594591770018a0f04587f7deeb3838344fe3adabac", size = 10346113 },
1696
- { url = "https://files.pythonhosted.org/packages/76/f4/c41de22b3728486f0aa95383a44c42657b2db4062f3234ca36fc8cf52d8b/ruff-0.8.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ddf5d654ac0d44389f6bf05cee4caeefc3132a64b58ea46738111d687352296", size = 9943564 },
1697
- { url = "https://files.pythonhosted.org/packages/0e/f0/afa0d2191af495ac82d4cbbfd7a94e3df6f62a04ca412033e073b871fc6d/ruff-0.8.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e248b1f0fa2749edd3350a2a342b67b43a2627434c059a063418e3d375cfe643", size = 10805522 },
1698
- { url = "https://files.pythonhosted.org/packages/12/57/5d1e9a0fd0c228e663894e8e3a8e7063e5ee90f8e8e60cf2085f362bfa1a/ruff-0.8.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf197b98ed86e417412ee3b6c893f44c8864f816451441483253d5ff22c0e81e", size = 10306763 },
1699
- { url = "https://files.pythonhosted.org/packages/04/df/f069fdb02e408be8aac6853583572a2873f87f866fe8515de65873caf6b8/ruff-0.8.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c41319b85faa3aadd4d30cb1cffdd9ac6b89704ff79f7664b853785b48eccdf3", size = 11359574 },
1700
- { url = "https://files.pythonhosted.org/packages/d3/04/37c27494cd02e4a8315680debfc6dfabcb97e597c07cce0044db1f9dfbe2/ruff-0.8.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9f8402b7c4f96463f135e936d9ab77b65711fcd5d72e5d67597b543bbb43cf3f", size = 12094851 },
1701
- { url = "https://files.pythonhosted.org/packages/81/b1/c5d7fb68506cab9832d208d03ea4668da9a9887a4a392f4f328b1bf734ad/ruff-0.8.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e56b3baa9c23d324ead112a4fdf20db9a3f8f29eeabff1355114dd96014604", size = 11655539 },
1702
- { url = "https://files.pythonhosted.org/packages/ef/38/8f8f2c8898dc8a7a49bc340cf6f00226917f0f5cb489e37075bcb2ce3671/ruff-0.8.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:736272574e97157f7edbbb43b1d046125fce9e7d8d583d5d65d0c9bf2c15addf", size = 12912805 },
1703
- { url = "https://files.pythonhosted.org/packages/06/dd/fa6660c279f4eb320788876d0cff4ea18d9af7d9ed7216d7bd66877468d0/ruff-0.8.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fe710ab6061592521f902fca7ebcb9fabd27bc7c57c764298b1c1f15fff720", size = 11205976 },
1704
- { url = "https://files.pythonhosted.org/packages/a8/d7/de94cc89833b5de455750686c17c9e10f4e1ab7ccdc5521b8fe911d1477e/ruff-0.8.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:13e9ec6d6b55f6da412d59953d65d66e760d583dd3c1c72bf1f26435b5bfdbae", size = 10792039 },
1705
- { url = "https://files.pythonhosted.org/packages/6d/15/3e4906559248bdbb74854af684314608297a05b996062c9d72e0ef7c7097/ruff-0.8.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:97d9aefef725348ad77d6db98b726cfdb075a40b936c7984088804dfd38268a7", size = 10400088 },
1706
- { url = "https://files.pythonhosted.org/packages/a2/21/9ed4c0e8133cb4a87a18d470f534ad1a8a66d7bec493bcb8bda2d1a5d5be/ruff-0.8.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ab78e33325a6f5374e04c2ab924a3367d69a0da36f8c9cb6b894a62017506111", size = 10900814 },
1707
- { url = "https://files.pythonhosted.org/packages/0d/5d/122a65a18955bd9da2616b69bc839351f8baf23b2805b543aa2f0aed72b5/ruff-0.8.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ef06f66f4a05c3ddbc9121a8b0cecccd92c5bf3dd43b5472ffe40b8ca10f0f8", size = 11268828 },
1708
- { url = "https://files.pythonhosted.org/packages/43/a9/1676ee9106995381e3d34bccac5bb28df70194167337ed4854c20f27c7ba/ruff-0.8.4-py3-none-win32.whl", hash = "sha256:552fb6d861320958ca5e15f28b20a3d071aa83b93caee33a87b471f99a6c0835", size = 8805621 },
1709
- { url = "https://files.pythonhosted.org/packages/10/98/ed6b56a30ee76771c193ff7ceeaf1d2acc98d33a1a27b8479cbdb5c17a23/ruff-0.8.4-py3-none-win_amd64.whl", hash = "sha256:f21a1143776f8656d7f364bd264a9d60f01b7f52243fbe90e7670c0dfe0cf65d", size = 9660086 },
1710
- { url = "https://files.pythonhosted.org/packages/13/9f/026e18ca7d7766783d779dae5e9c656746c6ede36ef73c6d934aaf4a6dec/ruff-0.8.4-py3-none-win_arm64.whl", hash = "sha256:9183dd615d8df50defa8b1d9a074053891ba39025cf5ae88e8bcb52edcc4bf08", size = 9074500 },
1707
+ version = "0.9.2"
1708
+ source = { registry = "https://pypi.org/simple" }
1709
+ sdist = { url = "https://files.pythonhosted.org/packages/80/63/77ecca9d21177600f551d1c58ab0e5a0b260940ea7312195bd2a4798f8a8/ruff-0.9.2.tar.gz", hash = "sha256:b5eceb334d55fae5f316f783437392642ae18e16dcf4f1858d55d3c2a0f8f5d0", size = 3553799 }
1710
+ wheels = [
1711
+ { url = "https://files.pythonhosted.org/packages/af/b9/0e168e4e7fb3af851f739e8f07889b91d1a33a30fca8c29fa3149d6b03ec/ruff-0.9.2-py3-none-linux_armv6l.whl", hash = "sha256:80605a039ba1454d002b32139e4970becf84b5fee3a3c3bf1c2af6f61a784347", size = 11652408 },
1712
+ { url = "https://files.pythonhosted.org/packages/2c/22/08ede5db17cf701372a461d1cb8fdde037da1d4fa622b69ac21960e6237e/ruff-0.9.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9aab82bb20afd5f596527045c01e6ae25a718ff1784cb92947bff1f83068b00", size = 11587553 },
1713
+ { url = "https://files.pythonhosted.org/packages/42/05/dedfc70f0bf010230229e33dec6e7b2235b2a1b8cbb2a991c710743e343f/ruff-0.9.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fbd337bac1cfa96be615f6efcd4bc4d077edbc127ef30e2b8ba2a27e18c054d4", size = 11020755 },
1714
+ { url = "https://files.pythonhosted.org/packages/df/9b/65d87ad9b2e3def67342830bd1af98803af731243da1255537ddb8f22209/ruff-0.9.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b35259b0cbf8daa22a498018e300b9bb0174c2bbb7bcba593935158a78054d", size = 11826502 },
1715
+ { url = "https://files.pythonhosted.org/packages/93/02/f2239f56786479e1a89c3da9bc9391120057fc6f4a8266a5b091314e72ce/ruff-0.9.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b6a9701d1e371bf41dca22015c3f89769da7576884d2add7317ec1ec8cb9c3c", size = 11390562 },
1716
+ { url = "https://files.pythonhosted.org/packages/c9/37/d3a854dba9931f8cb1b2a19509bfe59e00875f48ade632e95aefcb7a0aee/ruff-0.9.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9cc53e68b3c5ae41e8faf83a3b89f4a5d7b2cb666dff4b366bb86ed2a85b481f", size = 12548968 },
1717
+ { url = "https://files.pythonhosted.org/packages/fa/c3/c7b812bb256c7a1d5553433e95980934ffa85396d332401f6b391d3c4569/ruff-0.9.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8efd9da7a1ee314b910da155ca7e8953094a7c10d0c0a39bfde3fcfd2a015684", size = 13187155 },
1718
+ { url = "https://files.pythonhosted.org/packages/bd/5a/3c7f9696a7875522b66aa9bba9e326e4e5894b4366bd1dc32aa6791cb1ff/ruff-0.9.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3292c5a22ea9a5f9a185e2d131dc7f98f8534a32fb6d2ee7b9944569239c648d", size = 12704674 },
1719
+ { url = "https://files.pythonhosted.org/packages/be/d6/d908762257a96ce5912187ae9ae86792e677ca4f3dc973b71e7508ff6282/ruff-0.9.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a605fdcf6e8b2d39f9436d343d1f0ff70c365a1e681546de0104bef81ce88df", size = 14529328 },
1720
+ { url = "https://files.pythonhosted.org/packages/2d/c2/049f1e6755d12d9cd8823242fa105968f34ee4c669d04cac8cea51a50407/ruff-0.9.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c547f7f256aa366834829a08375c297fa63386cbe5f1459efaf174086b564247", size = 12385955 },
1721
+ { url = "https://files.pythonhosted.org/packages/91/5a/a9bdb50e39810bd9627074e42743b00e6dc4009d42ae9f9351bc3dbc28e7/ruff-0.9.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d18bba3d3353ed916e882521bc3e0af403949dbada344c20c16ea78f47af965e", size = 11810149 },
1722
+ { url = "https://files.pythonhosted.org/packages/e5/fd/57df1a0543182f79a1236e82a79c68ce210efb00e97c30657d5bdb12b478/ruff-0.9.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b338edc4610142355ccf6b87bd356729b62bf1bc152a2fad5b0c7dc04af77bfe", size = 11479141 },
1723
+ { url = "https://files.pythonhosted.org/packages/dc/16/bc3fd1d38974f6775fc152a0554f8c210ff80f2764b43777163c3c45d61b/ruff-0.9.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:492a5e44ad9b22a0ea98cf72e40305cbdaf27fac0d927f8bc9e1df316dcc96eb", size = 12014073 },
1724
+ { url = "https://files.pythonhosted.org/packages/47/6b/e4ca048a8f2047eb652e1e8c755f384d1b7944f69ed69066a37acd4118b0/ruff-0.9.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:af1e9e9fe7b1f767264d26b1075ac4ad831c7db976911fa362d09b2d0356426a", size = 12435758 },
1725
+ { url = "https://files.pythonhosted.org/packages/c2/40/4d3d6c979c67ba24cf183d29f706051a53c36d78358036a9cd21421582ab/ruff-0.9.2-py3-none-win32.whl", hash = "sha256:71cbe22e178c5da20e1514e1e01029c73dc09288a8028a5d3446e6bba87a5145", size = 9796916 },
1726
+ { url = "https://files.pythonhosted.org/packages/c3/ef/7f548752bdb6867e6939489c87fe4da489ab36191525fadc5cede2a6e8e2/ruff-0.9.2-py3-none-win_amd64.whl", hash = "sha256:c5e1d6abc798419cf46eed03f54f2e0c3adb1ad4b801119dedf23fcaf69b55b5", size = 10773080 },
1727
+ { url = "https://files.pythonhosted.org/packages/0e/4e/33df635528292bd2d18404e4daabcd74ca8a9853b2e1df85ed3d32d24362/ruff-0.9.2-py3-none-win_arm64.whl", hash = "sha256:a1b63fa24149918f8b37cef2ee6fff81f24f0d74b6f0bdc37bc3e1f2143e41c6", size = 10001738 },
1711
1728
  ]
1712
1729
 
1713
1730
  [[package]]
@@ -1748,7 +1765,7 @@ wheels = [
1748
1765
 
1749
1766
  [[package]]
1750
1767
  name = "solana"
1751
- version = "0.36.1"
1768
+ version = "0.36.2"
1752
1769
  source = { registry = "https://pypi.org/simple" }
1753
1770
  dependencies = [
1754
1771
  { name = "construct-typing" },
@@ -1757,9 +1774,9 @@ dependencies = [
1757
1774
  { name = "typing-extensions" },
1758
1775
  { name = "websockets" },
1759
1776
  ]
1760
- sdist = { url = "https://files.pythonhosted.org/packages/9c/e8/b13d5097ac15a805bc87615c9dfc8c1ee6e60a423a09030ea30f40b54658/solana-0.36.1.tar.gz", hash = "sha256:3ff66129077d5da2f023eb4173e0fba39554b84a2eaeff12d72b9d00a49e3ab0", size = 52001 }
1777
+ sdist = { url = "https://files.pythonhosted.org/packages/a6/f4/9417ad46938c3ea350d93c71cc4d45cbb68b2e2adae3b69d643b7ef11b39/solana-0.36.2.tar.gz", hash = "sha256:d279f144b856bd2920c78f9e4143cb13f2f8fc64244f768868378aa64f78b675", size = 51999 }
1761
1778
  wheels = [
1762
- { url = "https://files.pythonhosted.org/packages/aa/bc/a593337c3b2754ec1858e656efe7f4356f869ec65ef85134677215104467/solana-0.36.1-py3-none-any.whl", hash = "sha256:d917d0e605d7c63c42465396c18c01a3488eac7d80cb13cf1519125dc1ecda71", size = 62178 },
1779
+ { url = "https://files.pythonhosted.org/packages/23/bf/8878b464a489c46e40f2303887030c62d409b744cd621a501b746ff6a59a/solana-0.36.2-py3-none-any.whl", hash = "sha256:6cb2b458791a768ab277a8f63ccb2d3afe1a97e4169f0218b6ba522afaeffc04", size = 62180 },
1763
1780
  ]
1764
1781
 
1765
1782
  [[package]]
@@ -1867,11 +1884,11 @@ wheels = [
1867
1884
 
1868
1885
  [[package]]
1869
1886
  name = "types-pyyaml"
1870
- version = "6.0.12.20241221"
1887
+ version = "6.0.12.20241230"
1871
1888
  source = { registry = "https://pypi.org/simple" }
1872
- sdist = { url = "https://files.pythonhosted.org/packages/f4/60/ba3f23024bdd406e65c359b9dbd9757f058986bd57d94f6639015f9a9fae/types_pyyaml-6.0.12.20241221.tar.gz", hash = "sha256:4f149aa893ff6a46889a30af4c794b23833014c469cc57cbc3ad77498a58996f", size = 17034 }
1889
+ sdist = { url = "https://files.pythonhosted.org/packages/9a/f9/4d566925bcf9396136c0a2e5dc7e230ff08d86fa011a69888dd184469d80/types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c", size = 17078 }
1873
1890
  wheels = [
1874
- { url = "https://files.pythonhosted.org/packages/4b/04/1cc4fffeb4ace85c205e84cd48eb12cb37ec6ffb68245b7eef8f2086d490/types_PyYAML-6.0.12.20241221-py3-none-any.whl", hash = "sha256:0657a4ff8411a030a2116a196e8e008ea679696b5b1a8e1a6aa8ebb737b34688", size = 20023 },
1891
+ { url = "https://files.pythonhosted.org/packages/e8/c1/48474fbead512b70ccdb4f81ba5eb4a58f69d100ba19f17c92c0c4f50ae6/types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6", size = 20029 },
1875
1892
  ]
1876
1893
 
1877
1894
  [[package]]
@@ -1906,7 +1923,7 @@ wheels = [
1906
1923
 
1907
1924
  [[package]]
1908
1925
  name = "web3"
1909
- version = "7.6.1"
1926
+ version = "7.7.0"
1910
1927
  source = { registry = "https://pypi.org/simple" }
1911
1928
  dependencies = [
1912
1929
  { name = "aiohttp" },
@@ -1924,9 +1941,9 @@ dependencies = [
1924
1941
  { name = "typing-extensions" },
1925
1942
  { name = "websockets" },
1926
1943
  ]
1927
- sdist = { url = "https://files.pythonhosted.org/packages/6b/2c/c8f8ac9d418e4a0ace6b1719f8d2ac30a4fcd7b9831697f8ec93acd9e904/web3-7.6.1.tar.gz", hash = "sha256:0cce0f33bef9096fc976ee00c38e71cdd10a61d4302a6b13b56ab58327764f9a", size = 2173143 }
1944
+ sdist = { url = "https://files.pythonhosted.org/packages/f6/87/3ddfacfdb74ac9c0e1c0bd37f1fc70aa2377befb910428fcbeb422d8158d/web3-7.7.0.tar.gz", hash = "sha256:4d0332b9a78b855e57ccebd9e1e74c8e855b95869ac7b8fe5878731593e76408", size = 2187868 }
1928
1945
  wheels = [
1929
- { url = "https://files.pythonhosted.org/packages/d8/04/75b4e47bddb5ff705b0b562d63e6757eb6a1e5fad55fb62a90da58614e6d/web3-7.6.1-py3-none-any.whl", hash = "sha256:8f6b315fe1da12754930c4f809d27e33091bd7e2e1613bea1328bb5710acc5e3", size = 1354638 },
1946
+ { url = "https://files.pythonhosted.org/packages/60/5e/6d1d2e64115c86c3342a22f931b21f71d303aabd65a03b353e89097b9d70/web3-7.7.0-py3-none-any.whl", hash = "sha256:2e29147c0f43cf191af788af8f004368b70994db40162f1240607f663dc68ea6", size = 1364053 },
1930
1947
  ]
1931
1948
 
1932
1949
  [[package]]
@@ -1956,6 +1973,15 @@ wheels = [
1956
1973
  { url = "https://files.pythonhosted.org/packages/47/96/9d5749106ff57629b54360664ae7eb9afd8302fad1680ead385383e33746/websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6", size = 118056 },
1957
1974
  ]
1958
1975
 
1976
+ [[package]]
1977
+ name = "win32-setctime"
1978
+ version = "1.2.0"
1979
+ source = { registry = "https://pypi.org/simple" }
1980
+ sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867 }
1981
+ wheels = [
1982
+ { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083 },
1983
+ ]
1984
+
1959
1985
  [[package]]
1960
1986
  name = "yarl"
1961
1987
  version = "1.17.2"
@@ -1,9 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mm-balance
3
- Version: 0.1.17
4
- Requires-Python: >=3.12
5
- Requires-Dist: mm-aptos==0.1.4
6
- Requires-Dist: mm-btc==0.2.0
7
- Requires-Dist: mm-eth==0.2.0
8
- Requires-Dist: mm-solana==0.2.0
9
- Requires-Dist: typer>=0.15.1
@@ -1,61 +0,0 @@
1
- [project]
2
- name = "mm-balance"
3
- version = "0.1.17"
4
- description = ""
5
- requires-python = ">=3.12"
6
- dependencies = [
7
- "mm-btc==0.2.0",
8
- "mm-eth==0.2.0",
9
- "mm-solana==0.2.0",
10
- "mm-aptos==0.1.4",
11
- "typer>=0.15.1",
12
- ]
13
- [project.scripts]
14
- mm-balance = "mm_balance.cli:app"
15
-
16
- [build-system]
17
- requires = ["hatchling"]
18
- build-backend = "hatchling.build"
19
-
20
- [tool.uv]
21
- dev-dependencies = [
22
- "pytest~=8.3.4",
23
- "pytest-xdist~=3.6.1",
24
- "ruff~=0.8.4",
25
- "pip-audit~=2.7.3",
26
- "bandit~=1.8.0",
27
- "mypy~=1.14.0",
28
- "types-PyYAML~=6.0.12.20241221",
29
- ]
30
-
31
- [tool.mypy]
32
- python_version = "3.13"
33
- warn_no_return = false
34
- strict = true
35
- exclude = ["^tests/", "^tmp/"]
36
-
37
- [tool.ruff]
38
- line-length = 130
39
- target-version = "py313"
40
- lint.select = [
41
- "F", # Pyflakes
42
- "E", "W", # pycodestyle
43
- "UP", # pyupgrade
44
- "B", # flake8-bugbear
45
- "A", # flake8-builtins
46
- "COM", # flake8-commas
47
- "C40", # flake8-comprehensions
48
- "G", # flake8-logging-format
49
- "PIE", # flake8-pie
50
- "T20", # flake8-print
51
- "RUF", # Ruff-specific rules
52
- ]
53
- lint.ignore = [
54
- "A003", # builtin-attribute-shadowing
55
- "COM812",
56
- "RUF012"
57
- ]
58
-
59
- [tool.bandit]
60
- exclude_dirs = ["tests"]
61
- skips = ["B311"]
@@ -1,48 +0,0 @@
1
- from decimal import Decimal
2
-
3
- import pydash
4
- from mm_std import fatal, hr
5
- from mm_std.random_ import random_str_choice
6
-
7
- from mm_balance.config import Config, Group
8
- from mm_balance.constants import RETRIES_COINGECKO_PRICES, TICKER_TO_COINGECKO_ID
9
-
10
-
11
- class Prices(dict[str, Decimal]):
12
- """
13
- A Prices class representing a mapping from coin names to their prices.
14
-
15
- Inherits from:
16
- Dict[str, Decimal]: A dictionary with coin names as keys and their prices as Decimal values.
17
- """
18
-
19
-
20
- def get_prices(config: Config) -> Prices:
21
- result = Prices()
22
-
23
- coins = pydash.uniq([group.ticker for group in config.groups])
24
- coingecko_ids = pydash.uniq([get_coingecko_id(group) for group in config.groups])
25
-
26
- url = f"https://api.coingecko.com/api/v3/simple/price?ids={",".join(coingecko_ids)}&vs_currencies=usd"
27
- for _ in range(RETRIES_COINGECKO_PRICES):
28
- res = hr(url, proxy=random_str_choice(config.proxies))
29
- if res.code != 200:
30
- continue
31
-
32
- for idx, coin in enumerate(coins):
33
- if coingecko_ids[idx] in res.json:
34
- result[coin] = Decimal(str(pydash.get(res.json, f"{coingecko_ids[idx]}.usd")))
35
- else:
36
- fatal("Can't get price for {coin} from coingecko, coingecko_id={coingecko_ids[idx]}")
37
-
38
- return result
39
-
40
-
41
- def get_coingecko_id(group: Group) -> str:
42
- if group.coingecko_id:
43
- return group.coingecko_id
44
- coingecko_id = TICKER_TO_COINGECKO_ID.get(group.ticker)
45
- if coingecko_id:
46
- return coingecko_id
47
-
48
- fatal(f"Can't get coingecko_id for {group.ticker}. Please add coingecko_id to the config.")
File without changes
File without changes
File without changes