mm-sol 0.5.1__tar.gz → 0.5.2__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 (50) hide show
  1. {mm_sol-0.5.1 → mm_sol-0.5.2}/PKG-INFO +3 -3
  2. {mm_sol-0.5.1 → mm_sol-0.5.2}/pyproject.toml +3 -3
  3. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/balance.py +20 -32
  4. mm_sol-0.5.2/src/mm_sol/cli/cmd/node_cmd.py +11 -0
  5. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/test_token.py +1 -13
  6. {mm_sol-0.5.1 → mm_sol-0.5.2}/uv.lock +8 -8
  7. mm_sol-0.5.1/src/mm_sol/cli/cmd/node_cmd.py +0 -9
  8. {mm_sol-0.5.1 → mm_sol-0.5.2}/.env.example +0 -0
  9. {mm_sol-0.5.1 → mm_sol-0.5.2}/.gitignore +0 -0
  10. {mm_sol-0.5.1 → mm_sol-0.5.2}/README.md +0 -0
  11. {mm_sol-0.5.1 → mm_sol-0.5.2}/dict.dic +0 -0
  12. {mm_sol-0.5.1 → mm_sol-0.5.2}/justfile +0 -0
  13. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/__init__.py +0 -0
  14. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/account.py +0 -0
  15. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/block.py +0 -0
  16. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/__init__.py +0 -0
  17. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/calcs.py +0 -0
  18. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cli.py +0 -0
  19. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cli_utils.py +0 -0
  20. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/__init__.py +0 -0
  21. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/balance_cmd.py +0 -0
  22. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/balances_cmd.py +0 -0
  23. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/example_cmd.py +0 -0
  24. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/transfer_cmd.py +0 -0
  25. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/wallet/__init__.py +0 -0
  26. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/wallet/keypair_cmd.py +0 -0
  27. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/cmd/wallet/mnemonic_cmd.py +0 -0
  28. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/examples/balances.toml +0 -0
  29. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/examples/transfer.toml +0 -0
  30. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/cli/validators.py +0 -0
  31. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/constants.py +0 -0
  32. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/converters.py +0 -0
  33. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/py.typed +0 -0
  34. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/rpc.py +0 -0
  35. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/solana_cli.py +0 -0
  36. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/token.py +0 -0
  37. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/transfer.py +0 -0
  38. {mm_sol-0.5.1 → mm_sol-0.5.2}/src/mm_sol/utils.py +0 -0
  39. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/__init__.py +0 -0
  40. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/cli/__init__.py +0 -0
  41. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/cli/cmd/__init__.py +0 -0
  42. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/cli/cmd/wallet/__init__.py +0 -0
  43. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/cli/cmd/wallet/test_keypair_cmd.py +0 -0
  44. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/cli/cmd/wallet/test_mnemonic_cmd.py +0 -0
  45. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/conftest.py +0 -0
  46. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/test_account.py +0 -0
  47. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/test_balance.py +0 -0
  48. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/test_client.py +0 -0
  49. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/test_converters.py +0 -0
  50. {mm_sol-0.5.1 → mm_sol-0.5.2}/tests/test_rpc.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mm-sol
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Requires-Python: >=3.12
5
5
  Requires-Dist: base58~=2.1.1
6
- Requires-Dist: cryptography>=44.0.1
7
6
  Requires-Dist: jinja2>=3.1.5
8
- Requires-Dist: mm-crypto-utils>=0.2.4
7
+ Requires-Dist: mm-crypto-utils>=0.2.6
9
8
  Requires-Dist: mnemonic==0.21
10
9
  Requires-Dist: solana~=0.36.5
10
+ Requires-Dist: solders~=0.23.0
11
11
  Requires-Dist: typer>=0.15.1
@@ -1,16 +1,16 @@
1
1
  [project]
2
2
  name = "mm-sol"
3
- version = "0.5.1"
3
+ version = "0.5.2"
4
4
  description = ""
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
7
- "mm-crypto-utils>=0.2.4",
7
+ "mm-crypto-utils>=0.2.6",
8
8
  "solana~=0.36.5",
9
+ "solders~=0.23.0",
9
10
  "base58~=2.1.1",
10
11
  "mnemonic==0.21",
11
12
  "typer>=0.15.1",
12
13
  "jinja2>=3.1.5",
13
- "cryptography>=44.0.1", # remove after mm-crypto-utils update
14
14
  ]
15
15
  [project.scripts]
16
16
  mm-sol = "mm_sol.cli.cli:app"
@@ -2,8 +2,10 @@ import httpx
2
2
  from mm_crypto_utils import Nodes, Proxies, random_node, random_proxy
3
3
  from mm_std import Err, Ok, Result
4
4
  from solana.exceptions import SolanaRpcException
5
- from solana.rpc.types import TokenAccountOpts
5
+ from solana.rpc.core import RPCException
6
6
  from solders.pubkey import Pubkey
7
+ from solders.rpc.errors import InvalidParamsMessage
8
+ from spl.token.instructions import get_associated_token_address
7
9
 
8
10
  from mm_sol import rpc
9
11
  from mm_sol.utils import get_client
@@ -31,42 +33,32 @@ def get_token_balance(
31
33
  token_account: str | None = None,
32
34
  timeout: float = 10,
33
35
  proxy: str | None = None,
34
- no_token_accounts_return_zero: bool = True,
35
36
  ) -> Result[int]:
36
- data: list[object] = []
37
37
  try:
38
38
  client = get_client(node, proxy=proxy, timeout=timeout)
39
- if token_account:
40
- res_balance = client.get_token_account_balance(Pubkey.from_string(token_account))
41
- data.append(res_balance)
42
- return Ok(int(res_balance.value.amount))
39
+ if not token_account:
40
+ token_account = str(
41
+ get_associated_token_address(Pubkey.from_string(owner_address), Pubkey.from_string(token_mint_address))
42
+ )
43
43
 
44
- res_accounts = client.get_token_accounts_by_owner(
45
- Pubkey.from_string(owner_address),
46
- TokenAccountOpts(mint=Pubkey.from_string(token_mint_address)),
47
- )
48
- data.append(res_accounts)
44
+ res = client.get_token_account_balance(Pubkey.from_string(token_account))
49
45
 
50
- if no_token_accounts_return_zero and not res_accounts.value:
46
+ # Sometimes it not raise an error, but it returns this :(
47
+ if isinstance(res, InvalidParamsMessage) and "could not find account" in res.message:
51
48
  return Ok(0)
52
- if not res_accounts.value:
53
- return Err("no_token_accounts")
54
-
55
- token_accounts = [a.pubkey for a in res_accounts.value]
56
- balances = []
57
- for token_account_ in token_accounts:
58
- res = client.get_token_account_balance(token_account_)
59
- data.append(res)
60
- if res.value: # type:ignore[truthy-bool]
61
- balances.append(int(res.value.amount))
62
-
63
- return Ok(sum(balances))
49
+ return Ok(int(res.value.amount), data=res)
50
+ except RPCException as e:
51
+ if len(e.args) > 1:
52
+ s = e.args[0]
53
+ if isinstance(s, InvalidParamsMessage) and "could not find account" in s.message:
54
+ return Ok(0)
55
+ return Err(e)
64
56
  except httpx.HTTPStatusError as e:
65
- return Err(f"http error: {e}", data=data)
57
+ return Err(f"http error: {e}")
66
58
  except SolanaRpcException as e:
67
- return Err(e.error_msg, data=data)
59
+ return Err(e.error_msg)
68
60
  except Exception as e:
69
- return Err(e, data=data)
61
+ return Err(e)
70
62
 
71
63
 
72
64
  def get_token_balance_with_retries(
@@ -77,7 +69,6 @@ def get_token_balance_with_retries(
77
69
  token_account: str | None = None,
78
70
  timeout: float = 10,
79
71
  proxies: Proxies = None,
80
- no_token_accounts_return_zero: bool = True,
81
72
  ) -> Result[int]:
82
73
  res: Result[int] = Err("not started yet")
83
74
  for _ in range(retries):
@@ -88,11 +79,8 @@ def get_token_balance_with_retries(
88
79
  token_account,
89
80
  timeout=timeout,
90
81
  proxy=random_proxy(proxies),
91
- no_token_accounts_return_zero=no_token_accounts_return_zero,
92
82
  )
93
83
  if res.is_ok():
94
84
  return res
95
- if isinstance(res, Err) and res.err == "no_token_accounts":
96
- return res
97
85
 
98
86
  return res
@@ -0,0 +1,11 @@
1
+ from mm_std import print_json
2
+
3
+ from mm_sol import rpc
4
+ from mm_sol.cli import cli_utils
5
+
6
+
7
+ def run(urls: list[str], proxy: str | None) -> None:
8
+ result = {}
9
+ for url in [cli_utils.public_rpc_url(u) for u in urls]:
10
+ result[url] = rpc.get_block_height(url, proxy=proxy, timeout=10).ok_or_err()
11
+ print_json(data=result)
@@ -10,19 +10,7 @@ def test_get_balance(mainnet_node, usdt_token_address, usdt_owner_address, proxi
10
10
  assert res.unwrap() > 0
11
11
 
12
12
 
13
- def test_get_balance_no_tokens_account_1(mainnet_node, usdt_token_address, proxies):
14
- res = mm_sol.balance.get_token_balance_with_retries(
15
- mainnet_node,
16
- generate_account().public_key,
17
- usdt_token_address,
18
- proxies=proxies,
19
- no_token_accounts_return_zero=False,
20
- retries=5,
21
- )
22
- assert res.err == "no_token_accounts"
23
-
24
-
25
- def test_get_balance_no_tokens_account_2(mainnet_node, usdt_token_address, proxies):
13
+ def test_get_balance_no_tokens_account(mainnet_node, usdt_token_address, proxies):
26
14
  res = mm_sol.balance.get_token_balance_with_retries(
27
15
  mainnet_node, generate_account().public_key, usdt_token_address, proxies=proxies, retries=5
28
16
  )
@@ -472,27 +472,27 @@ wheels = [
472
472
 
473
473
  [[package]]
474
474
  name = "mm-crypto-utils"
475
- version = "0.2.4"
475
+ version = "0.2.6"
476
476
  source = { registry = "https://pypi.org/simple" }
477
477
  dependencies = [
478
478
  { name = "loguru" },
479
479
  { name = "mm-std" },
480
480
  ]
481
481
  wheels = [
482
- { url = "https://files.pythonhosted.org/packages/1b/80/261c463cad1176b14d92b7390328f89184307f201d9d3117012abe5e8a72/mm_crypto_utils-0.2.4-py3-none-any.whl", hash = "sha256:487214228ce79ffb9a8afeef13d67b578393558d03a0268d4b7747174f9ac7ce", size = 8255 },
482
+ { url = "https://files.pythonhosted.org/packages/d2/2a/72236eb60cb007d472fa6be72a98abf6b8273df3158a218cc5f412f86497/mm_crypto_utils-0.2.6-py3-none-any.whl", hash = "sha256:ef738203e2863570308d0fc5fee8f05c469d3f7df905dcdfd092d84690b14c9c", size = 8269 },
483
483
  ]
484
484
 
485
485
  [[package]]
486
486
  name = "mm-sol"
487
- version = "0.5.1"
487
+ version = "0.5.2"
488
488
  source = { editable = "." }
489
489
  dependencies = [
490
490
  { name = "base58" },
491
- { name = "cryptography" },
492
491
  { name = "jinja2" },
493
492
  { name = "mm-crypto-utils" },
494
493
  { name = "mnemonic" },
495
494
  { name = "solana" },
495
+ { name = "solders" },
496
496
  { name = "typer" },
497
497
  ]
498
498
 
@@ -509,11 +509,11 @@ dev = [
509
509
  [package.metadata]
510
510
  requires-dist = [
511
511
  { name = "base58", specifier = "~=2.1.1" },
512
- { name = "cryptography", specifier = ">=44.0.1" },
513
512
  { name = "jinja2", specifier = ">=3.1.5" },
514
- { name = "mm-crypto-utils", specifier = ">=0.2.4" },
513
+ { name = "mm-crypto-utils", specifier = ">=0.2.6" },
515
514
  { name = "mnemonic", specifier = "==0.21" },
516
515
  { name = "solana", specifier = "~=0.36.5" },
516
+ { name = "solders", specifier = "~=0.23.0" },
517
517
  { name = "typer", specifier = ">=0.15.1" },
518
518
  ]
519
519
 
@@ -529,7 +529,7 @@ dev = [
529
529
 
530
530
  [[package]]
531
531
  name = "mm-std"
532
- version = "0.3.0"
532
+ version = "0.3.2"
533
533
  source = { registry = "https://pypi.org/simple" }
534
534
  dependencies = [
535
535
  { name = "cryptography" },
@@ -541,7 +541,7 @@ dependencies = [
541
541
  { name = "rich" },
542
542
  ]
543
543
  wheels = [
544
- { url = "https://files.pythonhosted.org/packages/41/b3/8e14a0eaf34b2db3f4c97eacafff63d63bb8c28f7baf718b3bc99f948dc2/mm_std-0.3.0-py3-none-any.whl", hash = "sha256:3aaab32cb88c29741d7a37cea4b2cb74548ec9b94ea4f8ebf0149f678ad921a3", size = 14693 },
544
+ { url = "https://files.pythonhosted.org/packages/c0/9a/19f88e047426a52de2f8262d654ca8f20b6b9f15085db7dca6850b7d89d9/mm_std-0.3.2-py3-none-any.whl", hash = "sha256:bf479b1810c887b41aa8b4ad3b6d59d2002703a26b04499516af8e2d94351c86", size = 14709 },
545
545
  ]
546
546
 
547
547
  [[package]]
@@ -1,9 +0,0 @@
1
- from mm_std import print_json
2
-
3
- from mm_sol import rpc
4
-
5
-
6
- def run(urls: list[str], proxy: str | None) -> None:
7
- for url in urls:
8
- res = rpc.get_block_height(url, proxy=proxy, timeout=10)
9
- print_json({url: res.ok_or_err()})
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
File without changes