mm-balance 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mm_balance/cli.py +8 -0
- mm_balance/config/example.toml +6 -6
- mm_balance/config.py +23 -25
- {mm_balance-0.2.0.dist-info → mm_balance-0.2.2.dist-info}/METADATA +3 -3
- {mm_balance-0.2.0.dist-info → mm_balance-0.2.2.dist-info}/RECORD +7 -7
- {mm_balance-0.2.0.dist-info → mm_balance-0.2.2.dist-info}/WHEEL +0 -0
- {mm_balance-0.2.0.dist-info → mm_balance-0.2.2.dist-info}/entry_points.txt +0 -0
mm_balance/cli.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import getpass
|
|
2
|
+
import importlib.metadata
|
|
2
3
|
import pathlib
|
|
3
4
|
import pkgutil
|
|
4
5
|
from typing import Annotated
|
|
@@ -17,6 +18,12 @@ from mm_balance.workers import Workers
|
|
|
17
18
|
app = typer.Typer(no_args_is_help=True, pretty_exceptions_enable=False, add_completion=False)
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
def version_callback(value: bool) -> None:
|
|
22
|
+
if value:
|
|
23
|
+
typer.echo(f"mm-balance: v{importlib.metadata.version('mm-balance')}")
|
|
24
|
+
raise typer.Exit
|
|
25
|
+
|
|
26
|
+
|
|
20
27
|
def example_callback(value: bool) -> None:
|
|
21
28
|
if value:
|
|
22
29
|
data = pkgutil.get_data(__name__, "config/example.toml")
|
|
@@ -43,6 +50,7 @@ def cli(
|
|
|
43
50
|
_networks: Annotated[
|
|
44
51
|
bool | None, typer.Option("--networks", callback=networks_callback, help="Print supported networks.")
|
|
45
52
|
] = None,
|
|
53
|
+
_version: bool = typer.Option(None, "--version", callback=version_callback, is_eager=True),
|
|
46
54
|
) -> None:
|
|
47
55
|
zip_password = "" # nosec
|
|
48
56
|
if config_path.name.endswith(".zip"):
|
mm_balance/config/example.toml
CHANGED
|
@@ -23,25 +23,25 @@ share = 0.1
|
|
|
23
23
|
ticker = "ETH"
|
|
24
24
|
network = "ethereum"
|
|
25
25
|
comment = "okx"
|
|
26
|
-
addresses = "okx_eth"
|
|
26
|
+
addresses = "group: okx_eth"
|
|
27
27
|
|
|
28
28
|
[[coins]]
|
|
29
29
|
ticker = "USDT"
|
|
30
30
|
network = "ethereum"
|
|
31
31
|
comment = "okx"
|
|
32
|
-
addresses = "okx_eth"
|
|
32
|
+
addresses = "group: okx_eth"
|
|
33
33
|
|
|
34
34
|
[[coins]]
|
|
35
35
|
ticker = "ETH"
|
|
36
36
|
network = "ethereum"
|
|
37
37
|
comment = "binance"
|
|
38
|
-
addresses = "binance_eth"
|
|
38
|
+
addresses = "group: binance_eth"
|
|
39
39
|
|
|
40
40
|
[[coins]]
|
|
41
41
|
ticker = "USDT"
|
|
42
42
|
network = "ethereum"
|
|
43
43
|
comment = "binance"
|
|
44
|
-
addresses = "binance_eth"
|
|
44
|
+
addresses = "group: binance_eth"
|
|
45
45
|
|
|
46
46
|
[[coins]]
|
|
47
47
|
ticker = "USDC"
|
|
@@ -51,6 +51,7 @@ token_address = "0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b1
|
|
|
51
51
|
token_decimals = 6
|
|
52
52
|
addresses = "0x48271d39d0b05bd6efca2278f22277d6fcc375504f9839fd73f74ace240861af"
|
|
53
53
|
|
|
54
|
+
|
|
54
55
|
[[addresses]]
|
|
55
56
|
name = "okx_eth"
|
|
56
57
|
addresses = """
|
|
@@ -76,8 +77,7 @@ print_debug = false
|
|
|
76
77
|
print_format = "table" # table, json
|
|
77
78
|
format_number_separator = ","
|
|
78
79
|
proxies = """
|
|
79
|
-
env_url: MM_BALANCE_PROXIES_URL
|
|
80
|
+
# env_url: MM_BALANCE_PROXIES_URL
|
|
80
81
|
# socks5://usr:pass@site.com:1234
|
|
81
82
|
# http://site.com:1234
|
|
82
83
|
"""
|
|
83
|
-
|
mm_balance/config.py
CHANGED
|
@@ -43,14 +43,24 @@ class Group(BaseConfig):
|
|
|
43
43
|
return self
|
|
44
44
|
|
|
45
45
|
def process_addresses(self, address_groups: list[AddressGroup]) -> None:
|
|
46
|
-
|
|
47
|
-
for
|
|
48
|
-
if
|
|
49
|
-
|
|
46
|
+
result = []
|
|
47
|
+
for line in self.addresses:
|
|
48
|
+
if line.startswith("file:"):
|
|
49
|
+
path = Path(line.removeprefix("file:").strip()).expanduser()
|
|
50
|
+
if path.is_file():
|
|
51
|
+
result += path.read_text().strip().splitlines()
|
|
52
|
+
else:
|
|
53
|
+
fatal(f"File with addresses not found: {path}")
|
|
54
|
+
elif line.startswith("group:"):
|
|
55
|
+
group_name = line.removeprefix("group:").strip()
|
|
56
|
+
address_group = next((ag for ag in address_groups if ag.name == group_name), None)
|
|
57
|
+
if address_group is None:
|
|
58
|
+
raise ValueError(f"Address group not found: {group_name}")
|
|
59
|
+
result += address_group.addresses
|
|
50
60
|
else:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
self.addresses = pydash.uniq(
|
|
61
|
+
result.append(line)
|
|
62
|
+
# TODO: check address is valid. There is network info in the group
|
|
63
|
+
self.addresses = pydash.uniq(result)
|
|
54
64
|
|
|
55
65
|
|
|
56
66
|
class AddressGroup(BaseConfig):
|
|
@@ -83,6 +93,12 @@ class Config(BaseConfig):
|
|
|
83
93
|
|
|
84
94
|
@model_validator(mode="after")
|
|
85
95
|
def final_validator(self) -> Self:
|
|
96
|
+
# check all addresses has uniq name
|
|
97
|
+
address_group_names = [ag.name for ag in self.addresses]
|
|
98
|
+
non_uniq_names = [name for name in address_group_names if address_group_names.count(name) > 1]
|
|
99
|
+
if non_uniq_names:
|
|
100
|
+
raise ValueError("There are non-unique address group names: " + ", ".join(non_uniq_names))
|
|
101
|
+
|
|
86
102
|
# load addresses from address_group
|
|
87
103
|
for group in self.groups:
|
|
88
104
|
group.process_addresses(self.addresses)
|
|
@@ -103,21 +119,3 @@ class Config(BaseConfig):
|
|
|
103
119
|
def detect_token_address(ticker: str, network: Network) -> str | None:
|
|
104
120
|
if network in TOKEN_ADDRESS:
|
|
105
121
|
return TOKEN_ADDRESS[network].get(ticker)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def get_address_group_by_name(address_groups: list[AddressGroup], name: str) -> AddressGroup | None:
|
|
109
|
-
return pydash.find(address_groups, lambda g: g.name == name)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def process_file_addresses(addresses: list[str]) -> list[str]:
|
|
113
|
-
result = []
|
|
114
|
-
for address in addresses:
|
|
115
|
-
if address.startswith("file://"):
|
|
116
|
-
path = Path(address.removeprefix("file://"))
|
|
117
|
-
if path.is_file():
|
|
118
|
-
result.extend(path.read_text().strip().splitlines())
|
|
119
|
-
else:
|
|
120
|
-
fatal(f"File with addresses not found: {path}")
|
|
121
|
-
else:
|
|
122
|
-
result.append(address)
|
|
123
|
-
return result
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mm-balance
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Requires-Python: >=3.12
|
|
5
5
|
Requires-Dist: mm-aptos==0.2.0
|
|
6
6
|
Requires-Dist: mm-btc==0.3.0
|
|
7
|
-
Requires-Dist: mm-eth==0.3.
|
|
8
|
-
Requires-Dist: mm-sol==0.3.
|
|
7
|
+
Requires-Dist: mm-eth==0.3.1
|
|
8
|
+
Requires-Dist: mm-sol==0.3.1
|
|
9
9
|
Requires-Dist: typer>=0.15.1
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
mm_balance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
mm_balance/cli.py,sha256=
|
|
3
|
-
mm_balance/config.py,sha256=
|
|
2
|
+
mm_balance/cli.py,sha256=KYEfz1ztFpXAxOWlQMJ0rWGnAdkGkvTgVS53pm6YxCw,3683
|
|
3
|
+
mm_balance/config.py,sha256=3qEg9xGCoH6WX91dlmjXVVhkCjJf8KFOmfqE8NgSc64,4603
|
|
4
4
|
mm_balance/constants.py,sha256=kqG2zuwv0l-PzDHIrMJVQpfQWiXjr2DsqGPcKmqNJLo,2334
|
|
5
5
|
mm_balance/price.py,sha256=DzvcQngS6wgi_4YWoXxGvOuOkwJvUbN0KI8DeIxbB5A,1494
|
|
6
6
|
mm_balance/result.py,sha256=WsVLbf54cCJ76rIM2zHaOCQXMfZZMczdg8rlC2tDGWY,4533
|
|
7
7
|
mm_balance/token_decimals.py,sha256=7XL_x_1ZIhp_cr1TvXwnqLqINUWFGo0j5_5lWuxmwpE,2277
|
|
8
8
|
mm_balance/utils.py,sha256=bngYS2WFIakGZO31_ey4MPsllvDhgOxkAnGiXqom3J4,286
|
|
9
9
|
mm_balance/workers.py,sha256=vEmmUI-ioMOv1C_Jcz0rnzI3vn7BaVWFnyXddteJkoA,3766
|
|
10
|
-
mm_balance/config/example.toml,sha256=
|
|
10
|
+
mm_balance/config/example.toml,sha256=15Bjk_zkbhx9CqFgx1kbb2cRSBY9-kPKrej7N_8ulTk,1816
|
|
11
11
|
mm_balance/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
mm_balance/output/utils.py,sha256=WUFwshFMKZKdcwRtO21nhxqW78JeLAatDyHPZhdV96A,716
|
|
13
13
|
mm_balance/output/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -18,7 +18,7 @@ mm_balance/rpc/aptos.py,sha256=1JCYCqDim4tk1axXscaAJRXPd4J6vV1ABFbwMbPgrL0,641
|
|
|
18
18
|
mm_balance/rpc/btc.py,sha256=iGDoO7HXP6reLI0bWm0UhEl7-UFZTo5xCWNzFngbITw,458
|
|
19
19
|
mm_balance/rpc/evm.py,sha256=ewlMmRrcXKlky3DPNbnUBTVwnvyw7N9iCZLsCX2V14w,1007
|
|
20
20
|
mm_balance/rpc/solana.py,sha256=c756415rlhQkHsVsqxHcA7wIaSM64IqyxMohjz8IGhY,1031
|
|
21
|
-
mm_balance-0.2.
|
|
22
|
-
mm_balance-0.2.
|
|
23
|
-
mm_balance-0.2.
|
|
24
|
-
mm_balance-0.2.
|
|
21
|
+
mm_balance-0.2.2.dist-info/METADATA,sha256=Ck93hoOiO3Jq7kIHym9IN0XYMolvaYw6dGrhm_8II7I,225
|
|
22
|
+
mm_balance-0.2.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
23
|
+
mm_balance-0.2.2.dist-info/entry_points.txt,sha256=rSnP0ZW1a3ACNwTWM7T53CmOycKbzhG43m2_wseENng,50
|
|
24
|
+
mm_balance-0.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|