mm-sol 0.6.2__tar.gz → 0.7.0__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 (52) hide show
  1. mm_sol-0.7.0/PKG-INFO +11 -0
  2. {mm_sol-0.6.2 → mm_sol-0.7.0}/justfile +4 -2
  3. {mm_sol-0.6.2 → mm_sol-0.7.0}/pyproject.toml +11 -11
  4. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/calcs.py +14 -14
  5. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cli.py +2 -2
  6. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cli_utils.py +6 -7
  7. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/balance_cmd.py +8 -8
  8. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/balances_cmd.py +5 -5
  9. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/example_cmd.py +2 -2
  10. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/node_cmd.py +2 -2
  11. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/transfer_cmd.py +15 -11
  12. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/wallet/keypair_cmd.py +2 -2
  13. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/wallet/mnemonic_cmd.py +2 -2
  14. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/validators.py +8 -6
  15. mm_sol-0.7.0/src/mm_sol/constants.py +1 -0
  16. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/retry.py +2 -2
  17. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/rpc.py +8 -7
  18. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/rpc_sync.py +17 -16
  19. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/spl_token.py +1 -1
  20. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/transfer.py +1 -1
  21. mm_sol-0.7.0/tests/conftest.py +125 -0
  22. mm_sol-0.7.0/uv.lock +1246 -0
  23. mm_sol-0.6.2/PKG-INFO +0 -12
  24. mm_sol-0.6.2/src/mm_sol/constants.py +0 -1
  25. mm_sol-0.6.2/tests/conftest.py +0 -91
  26. mm_sol-0.6.2/uv.lock +0 -1451
  27. {mm_sol-0.6.2 → mm_sol-0.7.0}/.env.example +0 -0
  28. {mm_sol-0.6.2 → mm_sol-0.7.0}/.gitignore +0 -0
  29. {mm_sol-0.6.2 → mm_sol-0.7.0}/README.md +0 -0
  30. {mm_sol-0.6.2 → mm_sol-0.7.0}/dict.dic +0 -0
  31. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/__init__.py +0 -0
  32. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/account.py +0 -0
  33. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/__init__.py +0 -0
  34. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/__init__.py +0 -0
  35. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/cmd/wallet/__init__.py +0 -0
  36. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/examples/balances.toml +0 -0
  37. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/cli/examples/transfer.toml +0 -0
  38. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/converters.py +0 -0
  39. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/py.typed +0 -0
  40. {mm_sol-0.6.2 → mm_sol-0.7.0}/src/mm_sol/utils.py +0 -0
  41. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/__init__.py +0 -0
  42. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/cli/__init__.py +0 -0
  43. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/cli/cmd/__init__.py +0 -0
  44. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/cli/cmd/wallet/__init__.py +0 -0
  45. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/cli/cmd/wallet/test_keypair_cmd.py +0 -0
  46. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/cli/cmd/wallet/test_mnemonic_cmd.py +0 -0
  47. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/test_account.py +0 -0
  48. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/test_client.py +0 -0
  49. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/test_converters.py +0 -0
  50. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/test_rpc.py +0 -0
  51. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/test_rpc_sync.py +0 -0
  52. {mm_sol-0.6.2 → mm_sol-0.7.0}/tests/test_spl_token.py +0 -0
mm_sol-0.7.0/PKG-INFO ADDED
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: mm-sol
3
+ Version: 0.7.0
4
+ Requires-Python: >=3.13
5
+ Requires-Dist: base58~=2.1.1
6
+ Requires-Dist: jinja2>=3.1.6
7
+ Requires-Dist: mm-cryptocurrency~=0.4.7
8
+ Requires-Dist: mnemonic==0.21
9
+ Requires-Dist: socksio>=1.0.0
10
+ Requires-Dist: solana~=0.36.7
11
+ Requires-Dist: typer>=0.16.0
@@ -23,8 +23,10 @@ lint-fix: format
23
23
  uv run ruff check --fix src tests
24
24
 
25
25
  audit:
26
- uv run pip-audit
27
- uv run bandit -r -c "pyproject.toml" src
26
+ uv export --no-dev --all-extras --format requirements-txt --no-emit-project > requirements.txt
27
+ uv run pip-audit -r requirements.txt --disable-pip
28
+ rm requirements.txt
29
+ uv run bandit --silent --recursive --configfile "pyproject.toml" src
28
30
 
29
31
  publish: build
30
32
  git diff-index --quiet HEAD
@@ -1,15 +1,14 @@
1
1
  [project]
2
2
  name = "mm-sol"
3
- version = "0.6.2"
3
+ version = "0.7.0"
4
4
  description = ""
5
- requires-python = ">=3.12"
5
+ requires-python = ">=3.13"
6
6
  dependencies = [
7
- "mm-crypto-utils>=0.3.6",
8
- "solana~=0.36.6",
9
- "solders~=0.26.0",
7
+ "mm-cryptocurrency~=0.4.7",
8
+ "solana~=0.36.7",
10
9
  "base58~=2.1.1",
11
10
  "mnemonic==0.21",
12
- "typer>=0.15.2",
11
+ "typer>=0.16.0",
13
12
  "jinja2>=3.1.6",
14
13
  "socksio>=1.0.0",
15
14
  ]
@@ -22,13 +21,14 @@ build-backend = "hatchling.build"
22
21
 
23
22
  [tool.uv]
24
23
  dev-dependencies = [
25
- "pytest~=8.3.5",
26
- "pytest-xdist~=3.6.1",
27
- "ruff~=0.11.6",
24
+ "pytest~=8.4.0",
25
+ "pytest-asyncio~=1.0.0",
26
+ "pytest-xdist~=3.7.0",
27
+ "ruff~=0.11.13",
28
28
  "pip-audit~=2.9.0",
29
29
  "bandit~=1.8.3",
30
- "mypy~=1.15.0",
31
- "pytest-asyncio~=0.26.0",
30
+ "mypy~=1.16.0",
31
+ "python-dotenv>=1.1.0",
32
32
  ]
33
33
 
34
34
  [tool.mypy]
@@ -1,31 +1,31 @@
1
- import mm_crypto_utils
2
- from mm_crypto_utils import Nodes, Proxies, VarInt
3
- from mm_std import Result
1
+ from mm_cryptocurrency import Nodes, Proxies
2
+ from mm_cryptocurrency.calcs import calc_expression_with_vars
3
+ from mm_result import Result
4
4
 
5
5
  from mm_sol import retry
6
- from mm_sol.constants import SUFFIX_DECIMALS
6
+ from mm_sol.constants import UNIT_DECIMALS
7
7
 
8
8
 
9
- def calc_sol_expression(expression: str, var: VarInt | None = None) -> int:
10
- return mm_crypto_utils.calc_int_expression(expression, var=var, suffix_decimals=SUFFIX_DECIMALS)
9
+ def calc_sol_expression(expression: str, variables: dict[str, int] | None = None) -> int:
10
+ return calc_expression_with_vars(expression, variables, unit_decimals=UNIT_DECIMALS)
11
11
 
12
12
 
13
- def calc_token_expression(expression: str, token_decimals: int, var: VarInt | None = None) -> int:
14
- return mm_crypto_utils.calc_int_expression(expression, var=var, suffix_decimals={"t": token_decimals})
13
+ def calc_token_expression(expression: str, token_decimals: int, variables: dict[str, int] | None = None) -> int:
14
+ return calc_expression_with_vars(expression, variables, unit_decimals={"t": token_decimals})
15
15
 
16
16
 
17
17
  async def calc_sol_value_for_address(
18
18
  *, nodes: Nodes, value_expression: str, address: str, proxies: Proxies, fee: int
19
19
  ) -> Result[int]:
20
20
  value_expression = value_expression.lower()
21
- var = None
21
+ variables: dict[str, int] | None = None
22
22
  if "balance" in value_expression:
23
23
  res = await retry.get_sol_balance(5, nodes, proxies, address=address)
24
24
  if res.is_err():
25
25
  return res
26
- var = VarInt("balance", res.unwrap())
26
+ variables = {"balance": res.unwrap()}
27
27
 
28
- value = calc_sol_expression(value_expression, var)
28
+ value = calc_sol_expression(value_expression, variables)
29
29
  if "balance" in value_expression:
30
30
  value = value - fee
31
31
  return Result.ok(value)
@@ -34,12 +34,12 @@ async def calc_sol_value_for_address(
34
34
  async def calc_token_value_for_address(
35
35
  *, nodes: Nodes, value_expression: str, owner: str, token: str, token_decimals: int, proxies: Proxies
36
36
  ) -> Result[int]:
37
- var = None
37
+ variables: dict[str, int] | None = None
38
38
  value_expression = value_expression.lower()
39
39
  if "balance" in value_expression:
40
40
  res = await retry.get_token_balance(5, nodes, proxies, owner=owner, token=token)
41
41
  if res.is_err():
42
42
  return res
43
- var = VarInt("balance", res.unwrap())
44
- value = calc_token_expression(value_expression, token_decimals, var)
43
+ variables = {"balance": res.unwrap()}
44
+ value = calc_token_expression(value_expression, token_decimals, variables)
45
45
  return Result.ok(value)
@@ -3,8 +3,8 @@ from enum import Enum
3
3
  from pathlib import Path
4
4
  from typing import Annotated
5
5
 
6
+ import mm_print
6
7
  import typer
7
- from mm_std import print_plain
8
8
 
9
9
  from mm_sol.account import PHANTOM_DERIVATION_PATH
10
10
 
@@ -24,7 +24,7 @@ app.add_typer(wallet_app, name="w", hidden=True)
24
24
 
25
25
  def version_callback(value: bool) -> None:
26
26
  if value:
27
- print_plain(f"mm-sol: {cli_utils.get_version()}")
27
+ mm_print.plain(f"mm-sol: {cli_utils.get_version()}")
28
28
  raise typer.Exit
29
29
 
30
30
 
@@ -2,10 +2,9 @@ import importlib.metadata
2
2
  import time
3
3
  from pathlib import Path
4
4
 
5
- import mm_crypto_utils
5
+ import mm_print
6
6
  from loguru import logger
7
- from mm_crypto_utils import Nodes, Proxies
8
- from mm_std import BaseConfig, print_json
7
+ from mm_cryptocurrency import CryptocurrencyConfig, Nodes, Proxies, random_node, random_proxy
9
8
  from pydantic import BaseModel
10
9
  from solders.signature import Signature
11
10
 
@@ -21,12 +20,12 @@ class BaseConfigParams(BaseModel):
21
20
  print_config_and_exit: bool
22
21
 
23
22
 
24
- def print_config(config: BaseConfig, exclude: set[str] | None = None, count: set[str] | None = None) -> None:
23
+ def print_config(config: CryptocurrencyConfig, exclude: set[str] | None = None, count: set[str] | None = None) -> None:
25
24
  data = config.model_dump(exclude=exclude)
26
25
  if count:
27
26
  for k in count:
28
27
  data[k] = len(data[k])
29
- print_json(data)
28
+ mm_print.json(data)
30
29
 
31
30
 
32
31
  def public_rpc_url(url: str | None) -> str:
@@ -48,8 +47,8 @@ def wait_confirmation(nodes: Nodes, proxies: Proxies, signature: Signature, log_
48
47
  count = 0
49
48
  while True:
50
49
  try:
51
- node = mm_crypto_utils.random_node(nodes)
52
- proxy = mm_crypto_utils.random_proxy(proxies)
50
+ node = random_node(nodes)
51
+ proxy = random_proxy(proxies)
53
52
  client = get_client(node, proxy=proxy)
54
53
  res = client.get_transaction(signature)
55
54
  if res.value and res.value.slot: # check for tx error
@@ -1,7 +1,7 @@
1
1
  from decimal import Decimal
2
2
 
3
- import mm_crypto_utils
4
- from mm_std import print_json
3
+ import mm_print
4
+ from mm_cryptocurrency import fetch_proxies
5
5
  from pydantic import BaseModel, Field
6
6
 
7
7
  import mm_sol.retry
@@ -43,14 +43,14 @@ async def run(
43
43
 
44
44
  rpc_url = cli_utils.public_rpc_url(rpc_url)
45
45
 
46
- proxies = await mm_crypto_utils.fetch_proxies_or_fatal(proxies_url) if proxies_url else None
46
+ proxies = (await fetch_proxies(proxies_url)).unwrap() if proxies_url else None
47
47
 
48
48
  # sol balance
49
49
  sol_balance_res = await retry.get_sol_balance(3, rpc_url, proxies, address=wallet_address)
50
50
  if sol_balance_res.is_ok():
51
51
  result.sol_balance = sol_balance_res.unwrap()
52
52
  else:
53
- result.errors.append("sol_balance: " + sol_balance_res.unwrap_error())
53
+ result.errors.append("sol_balance: " + sol_balance_res.unwrap_err())
54
54
 
55
55
  # token balance
56
56
  if token_address:
@@ -59,15 +59,15 @@ async def run(
59
59
  if token_balance_res.is_ok():
60
60
  result.token_balance = token_balance_res.unwrap()
61
61
  else:
62
- result.errors.append("token_balance: " + token_balance_res.unwrap_error())
62
+ result.errors.append("token_balance: " + token_balance_res.unwrap_err())
63
63
 
64
64
  decimals_res = await mm_sol.retry.get_token_decimals(3, rpc_url, proxies, token=token_address)
65
65
  if decimals_res.is_ok():
66
66
  result.token_decimals = decimals_res.unwrap()
67
67
  else:
68
- result.errors.append("token_decimals: " + decimals_res.unwrap_error())
68
+ result.errors.append("token_decimals: " + decimals_res.unwrap_err())
69
69
 
70
70
  if lamport:
71
- print_json(result)
71
+ mm_print.json(result)
72
72
  else:
73
- print_json(result.to_human_readable())
73
+ mm_print.json(result.to_human_readable())
@@ -3,8 +3,8 @@ from decimal import Decimal
3
3
  from pathlib import Path
4
4
  from typing import Annotated, Any
5
5
 
6
- from mm_crypto_utils import ConfigValidators
7
- from mm_std import BaseConfig, fatal, print_json
6
+ import mm_print
7
+ from mm_cryptocurrency import ConfigValidators, CryptocurrencyConfig
8
8
  from pydantic import BeforeValidator, Field
9
9
 
10
10
  import mm_sol.retry
@@ -12,7 +12,7 @@ from mm_sol import converters, retry
12
12
  from mm_sol.cli.validators import Validators
13
13
 
14
14
 
15
- class Config(BaseConfig):
15
+ class Config(CryptocurrencyConfig):
16
16
  accounts: Annotated[list[str], BeforeValidator(Validators.sol_addresses(unique=True))]
17
17
  tokens: Annotated[list[str], BeforeValidator(Validators.sol_addresses(unique=True))]
18
18
  nodes: Annotated[list[str], BeforeValidator(ConfigValidators.nodes())]
@@ -35,14 +35,14 @@ async def run(config_path: Path, print_config: bool) -> None:
35
35
  for token_address in config.tokens:
36
36
  res = await mm_sol.retry.get_token_decimals(3, config.nodes, config.proxies, token=token_address)
37
37
  if res.is_err():
38
- fatal(f"Failed to get decimals for token {token_address}: {res.unwrap_error()}")
38
+ mm_print.fatal(f"Failed to get decimals for token {token_address}: {res.unwrap_err()}")
39
39
 
40
40
  token_decimals = res.unwrap()
41
41
  result[token_address] = await _get_token_balances(token_address, token_decimals, config.accounts, config)
42
42
  result[token_address + "_decimals"] = token_decimals
43
43
  result[token_address + "_sum"] = sum([v for v in result[token_address].values() if v is not None])
44
44
 
45
- print_json(result)
45
+ mm_print.json(result)
46
46
 
47
47
 
48
48
  async def _get_token_balances(
@@ -1,8 +1,8 @@
1
1
  from pathlib import Path
2
2
 
3
- from mm_std import pretty_print_toml
3
+ import mm_print
4
4
 
5
5
 
6
6
  def run(module: str) -> None:
7
7
  example_file = Path(Path(__file__).parent.absolute(), "../examples", f"{module}.toml")
8
- pretty_print_toml(example_file.read_text())
8
+ mm_print.toml(toml=example_file.read_text())
@@ -1,4 +1,4 @@
1
- from mm_std import print_json
1
+ import mm_print
2
2
 
3
3
  from mm_sol import rpc
4
4
  from mm_sol.cli import cli_utils
@@ -8,4 +8,4 @@ async def run(urls: list[str], proxy: str | None) -> None:
8
8
  result = {}
9
9
  for url in [cli_utils.public_rpc_url(u) for u in urls]:
10
10
  result[url] = (await rpc.get_block_height(url, proxy=proxy, timeout=10)).value_or_error()
11
- print_json(data=result)
11
+ mm_print.json(data=result)
@@ -3,10 +3,14 @@ import sys
3
3
  from pathlib import Path
4
4
  from typing import Annotated
5
5
 
6
- import mm_crypto_utils
6
+ import mm_print
7
7
  from loguru import logger
8
- from mm_crypto_utils import AddressToPrivate, Transfer
9
- from mm_std import BaseConfig, fatal, utc_now
8
+ from mm_cryptocurrency import CryptocurrencyConfig
9
+ from mm_cryptocurrency.account import PrivateKeyMap
10
+ from mm_cryptocurrency.calcs import calc_decimal_expression
11
+ from mm_cryptocurrency.log import init_loguru
12
+ from mm_cryptocurrency.validators import Transfer
13
+ from mm_std import utc_now
10
14
  from pydantic import AfterValidator, BeforeValidator, Field, model_validator
11
15
  from rich.console import Console
12
16
  from rich.live import Live
@@ -21,16 +25,16 @@ from mm_sol.cli.validators import Validators
21
25
  from mm_sol.converters import lamports_to_sol, to_token
22
26
 
23
27
 
24
- class Config(BaseConfig):
28
+ class Config(CryptocurrencyConfig):
25
29
  nodes: Annotated[list[str], BeforeValidator(Validators.nodes())]
26
30
  transfers: Annotated[list[Transfer], BeforeValidator(Validators.sol_transfers())]
27
- private_keys: Annotated[AddressToPrivate, BeforeValidator(Validators.sol_private_keys())]
31
+ private_keys: Annotated[PrivateKeyMap, BeforeValidator(Validators.sol_private_keys())]
28
32
  proxies: Annotated[list[str], Field(default_factory=list), BeforeValidator(Validators.proxies())]
29
33
  token: Annotated[str | None, AfterValidator(Validators.sol_address())] = None
30
34
  token_decimals: int = -1
31
35
  default_value: Annotated[str | None, AfterValidator(Validators.valid_sol_or_token_expression("balance"))] = None
32
36
  value_min_limit: Annotated[str | None, AfterValidator(Validators.valid_sol_or_token_expression())] = None
33
- delay: Annotated[str | None, AfterValidator(Validators.valid_calc_decimal_value())] = None # in seconds
37
+ delay: Annotated[str | None, AfterValidator(Validators.decimal_expression())] = None # in seconds
34
38
  round_ndigits: int = 5
35
39
  log_debug: Annotated[Path | None, BeforeValidator(Validators.log_file())] = None
36
40
  log_info: Annotated[Path | None, BeforeValidator(Validators.log_file())] = None
@@ -65,7 +69,7 @@ class Config(BaseConfig):
65
69
  if self.token:
66
70
  res = await mm_sol.retry.get_token_decimals(3, self.nodes, self.proxies, token=self.token)
67
71
  if res.is_err():
68
- fatal(f"can't get decimals for token={self.token}, error={res.unwrap_error()}")
72
+ mm_print.fatal(f"can't get decimals for token={self.token}, error={res.unwrap_err()}")
69
73
  self.token_decimals = res.unwrap()
70
74
 
71
75
  return self
@@ -99,13 +103,13 @@ async def run(cmd_params: TransferCmdParams) -> None:
99
103
 
100
104
 
101
105
  async def _run_transfers(config: Config, cmd_params: TransferCmdParams) -> None:
102
- mm_crypto_utils.init_logger(cmd_params.debug, config.log_debug, config.log_info)
106
+ init_loguru(cmd_params.debug, config.log_debug, config.log_info)
103
107
  logger.info(f"transfer {cmd_params.config_path}: started at {utc_now()} UTC")
104
108
  logger.debug(f"config={config.model_dump(exclude={'private_keys'}) | {'version': cli_utils.get_version()}}")
105
109
  for i, route in enumerate(config.transfers):
106
110
  await _transfer(route, config, cmd_params)
107
111
  if config.delay is not None and i < len(config.transfers) - 1:
108
- delay_value = mm_crypto_utils.calc_decimal_value(config.delay)
112
+ delay_value = calc_decimal_expression(config.delay)
109
113
  logger.info(f"delay {delay_value} seconds")
110
114
  if not cmd_params.emulate:
111
115
  await asyncio.sleep(float(delay_value))
@@ -132,7 +136,7 @@ async def _calc_value(transfer: Transfer, config: Config, transfer_sol_fee: int)
132
136
  )
133
137
  logger.debug(f"{transfer.log_prefix}: value={value_res.value_or_error()}")
134
138
  if value_res.is_err():
135
- logger.info(f"{transfer.log_prefix}: calc value error, {value_res.unwrap_error()}")
139
+ logger.info(f"{transfer.log_prefix}: calc value error, {value_res.unwrap_err()}")
136
140
 
137
141
  return value_res.value
138
142
 
@@ -181,7 +185,7 @@ async def _send_tx(transfer: Transfer, value: int, config: Config) -> Signature
181
185
  )
182
186
 
183
187
  if res.is_err():
184
- logger.info(f"{transfer.log_prefix}: tx error {res.unwrap_error()}")
188
+ logger.info(f"{transfer.log_prefix}: tx error {res.unwrap_err()}")
185
189
  return None
186
190
  return res.value
187
191
 
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- from mm_std import print_json
3
+ import mm_print
4
4
 
5
5
  from mm_sol.account import (
6
6
  get_private_key_arr_str,
@@ -16,4 +16,4 @@ def run(private_key: str) -> None:
16
16
  public = get_public_key(private_key)
17
17
  private_base58 = get_private_key_base58(private_key)
18
18
  private_arr = get_private_key_arr_str(private_key)
19
- print_json({"public": public, "private_base58": private_base58, "private_arr": private_arr})
19
+ mm_print.json({"public": public, "private_base58": private_base58, "private_arr": private_arr})
@@ -1,7 +1,7 @@
1
1
  from dataclasses import asdict
2
2
  from typing import Any
3
3
 
4
- from mm_std import print_json
4
+ import mm_print
5
5
 
6
6
  from mm_sol.account import derive_accounts, generate_mnemonic
7
7
 
@@ -16,4 +16,4 @@ def run(mnemonic: str, passphrase: str, words: int, derivation_path: str, limit:
16
16
  accounts = derive_accounts(mnemonic=mnemonic, passphrase=passphrase, derivation_path=derivation_path, limit=limit)
17
17
 
18
18
  result["accounts"] = [asdict(acc) for acc in accounts]
19
- print_json(result)
19
+ mm_print.json(result)
@@ -1,9 +1,11 @@
1
1
  from collections.abc import Callable
2
2
 
3
- from mm_crypto_utils import AddressToPrivate, ConfigValidators, Transfer
3
+ from mm_cryptocurrency import ConfigValidators
4
+ from mm_cryptocurrency.account import PrivateKeyMap
5
+ from mm_cryptocurrency.validators import Transfer
4
6
 
5
7
  from mm_sol.account import get_public_key, is_address
6
- from mm_sol.constants import SUFFIX_DECIMALS
8
+ from mm_sol.constants import UNIT_DECIMALS
7
9
 
8
10
 
9
11
  class Validators(ConfigValidators):
@@ -20,17 +22,17 @@ class Validators(ConfigValidators):
20
22
  return ConfigValidators.transfers(is_address)
21
23
 
22
24
  @staticmethod
23
- def sol_private_keys() -> Callable[[str], AddressToPrivate]:
25
+ def sol_private_keys() -> Callable[[str], PrivateKeyMap]:
24
26
  return ConfigValidators.private_keys(get_public_key)
25
27
 
26
28
  @staticmethod
27
29
  def valid_sol_expression(var_name: str | None = None) -> Callable[[str], str]:
28
- return ConfigValidators.valid_calc_int_expression(var_name, SUFFIX_DECIMALS)
30
+ return ConfigValidators.expression_with_vars(var_name, UNIT_DECIMALS)
29
31
 
30
32
  @staticmethod
31
33
  def valid_token_expression(var_name: str | None = None) -> Callable[[str], str]:
32
- return ConfigValidators.valid_calc_int_expression(var_name, {"t": 6})
34
+ return ConfigValidators.expression_with_vars(var_name, {"t": 6})
33
35
 
34
36
  @staticmethod
35
37
  def valid_sol_or_token_expression(var_name: str | None = None) -> Callable[[str], str]:
36
- return ConfigValidators.valid_calc_int_expression(var_name, SUFFIX_DECIMALS | {"t": 6})
38
+ return ConfigValidators.expression_with_vars(var_name, UNIT_DECIMALS | {"t": 6})
@@ -0,0 +1 @@
1
+ UNIT_DECIMALS = {"sol": 9}
@@ -1,5 +1,5 @@
1
- from mm_crypto_utils import Nodes, Proxies, retry_with_node_and_proxy
2
- from mm_std import Result
1
+ from mm_cryptocurrency import Nodes, Proxies, retry_with_node_and_proxy
2
+ from mm_result import Result
3
3
  from solders.solders import Pubkey, Signature
4
4
 
5
5
  from mm_sol import rpc, spl_token, transfer
@@ -3,7 +3,8 @@ from collections.abc import Sequence
3
3
  from typing import Any
4
4
 
5
5
  import websockets
6
- from mm_std import Result, http_request
6
+ from mm_http import http_request
7
+ from mm_result import Result
7
8
 
8
9
 
9
10
  async def rpc_call(
@@ -23,17 +24,17 @@ async def rpc_call(
23
24
  async def _http_call(node: str, data: dict[str, object], timeout: float, proxy: str | None) -> Result[Any]:
24
25
  res = await http_request(node, method="POST", proxy=proxy, timeout=timeout, json=data)
25
26
  if res.is_err():
26
- return res.to_err()
27
+ return res.to_result_err()
27
28
  try:
28
29
  parsed_body = res.parse_json_body()
29
30
  err = parsed_body.get("error", {}).get("message", "")
30
31
  if err:
31
- return res.to_err(f"service_error: {err}")
32
+ return res.to_result_err(f"service_error: {err}")
32
33
  if "result" in parsed_body:
33
- return res.to_ok(parsed_body["result"])
34
- return res.to_err("unknown_response")
34
+ return res.to_result_ok(parsed_body["result"])
35
+ return res.to_result_err("unknown_response")
35
36
  except Exception as e:
36
- return res.to_err(e)
37
+ return res.to_result_err(e)
37
38
 
38
39
 
39
40
  async def _ws_call(node: str, data: dict[str, object], timeout: float) -> Result[Any]:
@@ -55,7 +56,7 @@ async def _ws_call(node: str, data: dict[str, object], timeout: float) -> Result
55
56
  return Result.err(e, {"response": response})
56
57
 
57
58
 
58
- async def get_block_height(node: str, timeout: float = 10, proxy: str | None = None) -> Result[int]:
59
+ async def get_block_height(node: str, timeout: float = 5, proxy: str | None = None) -> Result[int]:
59
60
  return await rpc_call(node=node, method="getBlockHeight", params=[], timeout=timeout, proxy=proxy)
60
61
 
61
62
 
@@ -1,7 +1,8 @@
1
1
  from typing import Any
2
2
 
3
3
  import pydash
4
- from mm_std import Result, http_request_sync
4
+ from mm_http import http_request_sync
5
+ from mm_result import Result
5
6
  from pydantic import BaseModel, ConfigDict, Field
6
7
 
7
8
  DEFAULT_MAINNET_RPC = "https://api.mainnet-beta.solana.com"
@@ -79,7 +80,7 @@ def rpc_call(
79
80
  method: str,
80
81
  params: list[Any],
81
82
  id_: int = 1,
82
- timeout: float = 10,
83
+ timeout: float = 5,
83
84
  proxy: str | None = None,
84
85
  ) -> Result[Any]:
85
86
  data = {"jsonrpc": "2.0", "method": method, "params": params, "id": id_}
@@ -92,50 +93,50 @@ def _http_call(node: str, data: dict[str, object], timeout: float, proxy: str |
92
93
  res = http_request_sync(node, method="POST", proxy=proxy, timeout=timeout, json=data)
93
94
  try:
94
95
  if res.is_err():
95
- return res.to_err()
96
+ return res.to_result_err()
96
97
 
97
98
  json_body = res.parse_json_body()
98
99
  err = pydash.get(json_body, "error.message")
99
100
  if err:
100
- return res.to_err(f"service_error: {err}")
101
+ return res.to_result_err(f"service_error: {err}")
101
102
  if "result" in json_body:
102
- return res.to_ok(json_body["result"])
103
+ return res.to_result_ok(json_body["result"])
103
104
 
104
- return res.to_err("unknown_response")
105
+ return res.to_result_err("unknown_response")
105
106
  except Exception as e:
106
- return res.to_err(e)
107
+ return res.to_result_err(e)
107
108
 
108
109
 
109
- def get_balance(node: str, address: str, timeout: float = 10, proxy: str | None = None) -> Result[int]:
110
+ def get_balance(node: str, address: str, timeout: float = 5, proxy: str | None = None) -> Result[int]:
110
111
  """Returns balance in lamports"""
111
112
  return rpc_call(node=node, method="getBalance", params=[address], timeout=timeout, proxy=proxy).map(lambda r: r["value"])
112
113
 
113
114
 
114
- def get_block_height(node: str, timeout: float = 10, proxy: str | None = None) -> Result[int]:
115
+ def get_block_height(node: str, timeout: float = 5, proxy: str | None = None) -> Result[int]:
115
116
  """Returns balance in lamports"""
116
117
  return rpc_call(node=node, method="getBlockHeight", params=[], timeout=timeout, proxy=proxy)
117
118
 
118
119
 
119
- def get_slot(node: str, timeout: float = 10, proxy: str | None = None) -> Result[int]:
120
+ def get_slot(node: str, timeout: float = 5, proxy: str | None = None) -> Result[int]:
120
121
  return rpc_call(node=node, method="getSlot", params=[], timeout=timeout, proxy=proxy)
121
122
 
122
123
 
123
- def get_epoch_info(node: str, epoch: int | None = None, timeout: float = 10, proxy: str | None = None) -> Result[EpochInfo]:
124
+ def get_epoch_info(node: str, epoch: int | None = None, timeout: float = 5, proxy: str | None = None) -> Result[EpochInfo]:
124
125
  params = [epoch] if epoch else []
125
126
  return rpc_call(node=node, method="getEpochInfo", params=params, timeout=timeout, proxy=proxy).map(lambda r: EpochInfo(**r))
126
127
 
127
128
 
128
- def get_health(node: str, timeout: float = 10, proxy: str | None = None) -> Result[bool]:
129
+ def get_health(node: str, timeout: float = 5, proxy: str | None = None) -> Result[bool]:
129
130
  return rpc_call(node=node, method="getHealth", params=[], timeout=timeout, proxy=proxy).map(lambda r: r == "ok")
130
131
 
131
132
 
132
- def get_cluster_nodes(node: str, timeout: float = 30, proxy: str | None = None) -> Result[list[ClusterNode]]:
133
+ def get_cluster_nodes(node: str, timeout: float = 5, proxy: str | None = None) -> Result[list[ClusterNode]]:
133
134
  return rpc_call(node=node, method="getClusterNodes", timeout=timeout, proxy=proxy, params=[]).map(
134
135
  lambda r: [ClusterNode(**n) for n in r],
135
136
  )
136
137
 
137
138
 
138
- def get_vote_accounts(node: str, timeout: float = 30, proxy: str | None = None) -> Result[list[VoteAccount]]:
139
+ def get_vote_accounts(node: str, timeout: float = 5, proxy: str | None = None) -> Result[list[VoteAccount]]:
139
140
  res = rpc_call(node=node, method="getVoteAccounts", timeout=timeout, proxy=proxy, params=[])
140
141
  if res.is_err():
141
142
  return res
@@ -182,7 +183,7 @@ def get_vote_accounts(node: str, timeout: float = 30, proxy: str | None = None)
182
183
  def get_leader_scheduler(
183
184
  node: str,
184
185
  slot: int | None = None,
185
- timeout: float = 10,
186
+ timeout: float = 5,
186
187
  proxy: str | None = None,
187
188
  ) -> Result[dict[str, list[int]]]:
188
189
  return rpc_call(
@@ -205,7 +206,7 @@ def get_transaction(
205
206
  signature: str,
206
207
  max_supported_transaction_version: int | None = None,
207
208
  encoding: str = "json",
208
- timeout: float = 60,
209
+ timeout: float = 5,
209
210
  proxy: str | None = None,
210
211
  ) -> Result[dict[str, object] | None]:
211
212
  if max_supported_transaction_version is not None:
@@ -1,4 +1,4 @@
1
- from mm_std import Result
1
+ from mm_result import Result
2
2
  from solana.exceptions import SolanaRpcException
3
3
  from solana.rpc.core import RPCException
4
4
  from solders.solders import InvalidParamsMessage, Pubkey, get_associated_token_address
@@ -1,5 +1,5 @@
1
1
  import pydash
2
- from mm_std import Result
2
+ from mm_result import Result
3
3
  from pydantic import BaseModel
4
4
  from solders.message import Message
5
5
  from solders.pubkey import Pubkey