mm-sol 0.6.2__py3-none-any.whl → 0.7.0__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_sol/cli/calcs.py +14 -14
- mm_sol/cli/cli.py +2 -2
- mm_sol/cli/cli_utils.py +6 -7
- mm_sol/cli/cmd/balance_cmd.py +8 -8
- mm_sol/cli/cmd/balances_cmd.py +5 -5
- mm_sol/cli/cmd/example_cmd.py +2 -2
- mm_sol/cli/cmd/node_cmd.py +2 -2
- mm_sol/cli/cmd/transfer_cmd.py +15 -11
- mm_sol/cli/cmd/wallet/keypair_cmd.py +2 -2
- mm_sol/cli/cmd/wallet/mnemonic_cmd.py +2 -2
- mm_sol/cli/validators.py +8 -6
- mm_sol/constants.py +1 -1
- mm_sol/retry.py +2 -2
- mm_sol/rpc.py +8 -7
- mm_sol/rpc_sync.py +17 -16
- mm_sol/spl_token.py +1 -1
- mm_sol/transfer.py +1 -1
- mm_sol-0.7.0.dist-info/METADATA +11 -0
- mm_sol-0.7.0.dist-info/RECORD +31 -0
- mm_sol-0.6.2.dist-info/METADATA +0 -12
- mm_sol-0.6.2.dist-info/RECORD +0 -31
- {mm_sol-0.6.2.dist-info → mm_sol-0.7.0.dist-info}/WHEEL +0 -0
- {mm_sol-0.6.2.dist-info → mm_sol-0.7.0.dist-info}/entry_points.txt +0 -0
mm_sol/cli/calcs.py
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
from
|
|
3
|
-
from
|
|
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
|
|
6
|
+
from mm_sol.constants import UNIT_DECIMALS
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def calc_sol_expression(expression: str,
|
|
10
|
-
return
|
|
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,
|
|
14
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
26
|
+
variables = {"balance": res.unwrap()}
|
|
27
27
|
|
|
28
|
-
value = calc_sol_expression(value_expression,
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
value = calc_token_expression(value_expression, token_decimals,
|
|
43
|
+
variables = {"balance": res.unwrap()}
|
|
44
|
+
value = calc_token_expression(value_expression, token_decimals, variables)
|
|
45
45
|
return Result.ok(value)
|
mm_sol/cli/cli.py
CHANGED
|
@@ -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
|
-
|
|
27
|
+
mm_print.plain(f"mm-sol: {cli_utils.get_version()}")
|
|
28
28
|
raise typer.Exit
|
|
29
29
|
|
|
30
30
|
|
mm_sol/cli/cli_utils.py
CHANGED
|
@@ -2,10 +2,9 @@ import importlib.metadata
|
|
|
2
2
|
import time
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import mm_print
|
|
6
6
|
from loguru import logger
|
|
7
|
-
from
|
|
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:
|
|
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
|
-
|
|
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 =
|
|
52
|
-
proxy =
|
|
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
|
mm_sol/cli/cmd/balance_cmd.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from decimal import Decimal
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
from
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
68
|
+
result.errors.append("token_decimals: " + decimals_res.unwrap_err())
|
|
69
69
|
|
|
70
70
|
if lamport:
|
|
71
|
-
|
|
71
|
+
mm_print.json(result)
|
|
72
72
|
else:
|
|
73
|
-
|
|
73
|
+
mm_print.json(result.to_human_readable())
|
mm_sol/cli/cmd/balances_cmd.py
CHANGED
|
@@ -3,8 +3,8 @@ from decimal import Decimal
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Annotated, Any
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
from
|
|
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(
|
|
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.
|
|
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
|
-
|
|
45
|
+
mm_print.json(result)
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
async def _get_token_balances(
|
mm_sol/cli/cmd/example_cmd.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
8
|
+
mm_print.toml(toml=example_file.read_text())
|
mm_sol/cli/cmd/node_cmd.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
11
|
+
mm_print.json(data=result)
|
mm_sol/cli/cmd/transfer_cmd.py
CHANGED
|
@@ -3,10 +3,14 @@ import sys
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Annotated
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import mm_print
|
|
7
7
|
from loguru import logger
|
|
8
|
-
from
|
|
9
|
-
from
|
|
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(
|
|
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[
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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 =
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19
|
+
mm_print.json(result)
|
mm_sol/cli/validators.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from collections.abc import Callable
|
|
2
2
|
|
|
3
|
-
from
|
|
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
|
|
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],
|
|
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.
|
|
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.
|
|
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.
|
|
38
|
+
return ConfigValidators.expression_with_vars(var_name, UNIT_DECIMALS | {"t": 6})
|
mm_sol/constants.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
UNIT_DECIMALS = {"sol": 9}
|
mm_sol/retry.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
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
|
mm_sol/rpc.py
CHANGED
|
@@ -3,7 +3,8 @@ from collections.abc import Sequence
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
import websockets
|
|
6
|
-
from
|
|
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.
|
|
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.
|
|
32
|
+
return res.to_result_err(f"service_error: {err}")
|
|
32
33
|
if "result" in parsed_body:
|
|
33
|
-
return res.
|
|
34
|
-
return res.
|
|
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.
|
|
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 =
|
|
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
|
|
mm_sol/rpc_sync.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
3
|
import pydash
|
|
4
|
-
from
|
|
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 =
|
|
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.
|
|
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.
|
|
101
|
+
return res.to_result_err(f"service_error: {err}")
|
|
101
102
|
if "result" in json_body:
|
|
102
|
-
return res.
|
|
103
|
+
return res.to_result_ok(json_body["result"])
|
|
103
104
|
|
|
104
|
-
return res.
|
|
105
|
+
return res.to_result_err("unknown_response")
|
|
105
106
|
except Exception as e:
|
|
106
|
-
return res.
|
|
107
|
+
return res.to_result_err(e)
|
|
107
108
|
|
|
108
109
|
|
|
109
|
-
def get_balance(node: str, address: str, timeout: float =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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:
|
mm_sol/spl_token.py
CHANGED
mm_sol/transfer.py
CHANGED
|
@@ -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
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
mm_sol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mm_sol/account.py,sha256=cVcxRQBuV_Gfm2WgQIwaYuAQijeIJqDDxLC22PN0XSs,3493
|
|
3
|
+
mm_sol/constants.py,sha256=9XKF8Z2dyY6L82_Bm0_naSQp5U0mIaOeqbZNBj25D2E,27
|
|
4
|
+
mm_sol/converters.py,sha256=rBxe3SIADZS8hG7TYl4FgjmvKH-ykaTmNbnWWQDiFZ4,1430
|
|
5
|
+
mm_sol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
mm_sol/retry.py,sha256=65VeibEB1FGJXVPzcGwIVK9UcbtIsnEhdmIWMhZAaxU,2899
|
|
7
|
+
mm_sol/rpc.py,sha256=c5AtHygQD5xawqfrrqByNtdGsEAq3mFfC17sdM3y4lU,2478
|
|
8
|
+
mm_sol/rpc_sync.py,sha256=bHK5vUramNxgA0v5BwSFNpzpiyKWSeBUW6Bu8tXV9W8,7195
|
|
9
|
+
mm_sol/spl_token.py,sha256=Bd5zXhlVhFd5n3WwunRoeM_yYo-0f1hNR7_1zww81A8,1944
|
|
10
|
+
mm_sol/transfer.py,sha256=kfNGRjF4aNSLAyBdm0jHyCXENFTMwib4pqIhKRJGCCQ,4413
|
|
11
|
+
mm_sol/utils.py,sha256=oD06NsMSMhN6lqsM6mSgLTtiKwA1uAsen9WR82ofRTE,923
|
|
12
|
+
mm_sol/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
mm_sol/cli/calcs.py,sha256=7t5iFWVQbZiObsEx_DgBc8E9PlS39fge_N1R_8OJEEk,1785
|
|
14
|
+
mm_sol/cli/cli.py,sha256=TxAAQ-QX9j9mG6d6el9SLYxF3QeIeWal7AdW_GTzPZQ,4723
|
|
15
|
+
mm_sol/cli/cli_utils.py,sha256=1Tg7jwFfYn9he-QS2vGBl9-MXwBRJRb1Xsjw004z1Iw,1823
|
|
16
|
+
mm_sol/cli/validators.py,sha256=LtclH-fatMxYRC9v8v0f9HHTDV708TWseBgDEXPllg0,1431
|
|
17
|
+
mm_sol/cli/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
mm_sol/cli/cmd/balance_cmd.py,sha256=-GPBjs9PWdHUcNxV_CKpmns7kJUykeqeNcSbIrO6aoU,2462
|
|
19
|
+
mm_sol/cli/cmd/balances_cmd.py,sha256=ROI6ozTNP3o4CVQ9Bsg9TqYw6QJp3DuWDLJ6eoHhl6A,2687
|
|
20
|
+
mm_sol/cli/cmd/example_cmd.py,sha256=r_fBZyFHAs6OTHT7HnE18bh_SKz-ABrcX6_nytJyJDY,214
|
|
21
|
+
mm_sol/cli/cmd/node_cmd.py,sha256=octbG9IwCUKyaFgGrPf_2MJlzHKncMQhGlyi-1rqw-E,339
|
|
22
|
+
mm_sol/cli/cmd/transfer_cmd.py,sha256=Uk9dT__j0XoCMucFQuMw2e8OCkdR4GJGdLygq1926qM,11077
|
|
23
|
+
mm_sol/cli/cmd/wallet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
mm_sol/cli/cmd/wallet/keypair_cmd.py,sha256=HndbANn2XbuHWxD-8ggKEGUK1OT1tjiVTtR5G6F8XFw,527
|
|
25
|
+
mm_sol/cli/cmd/wallet/mnemonic_cmd.py,sha256=xT0wzBtj9IeJHvrzst0jFjXP4pj_k17JsKX_PBNjIO4,637
|
|
26
|
+
mm_sol/cli/examples/balances.toml,sha256=333g2EkyYBDW7OWFGMIWVZGkdFQMMo0Ag-bg-BvS4Zg,349
|
|
27
|
+
mm_sol/cli/examples/transfer.toml,sha256=kOCdmuwmhlOam4LVtlcYTKF0PoZYHWMlv9gWxNSXMOk,1624
|
|
28
|
+
mm_sol-0.7.0.dist-info/METADATA,sha256=F33DL_8KIot3m93mLdCGyV8qDdbGaEh9M-GbXS5HVsw,291
|
|
29
|
+
mm_sol-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
30
|
+
mm_sol-0.7.0.dist-info/entry_points.txt,sha256=MrYnosumy9nsITSAw5TiR3WXDwsdoF0YvUIlZ38TLLs,46
|
|
31
|
+
mm_sol-0.7.0.dist-info/RECORD,,
|
mm_sol-0.6.2.dist-info/METADATA
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: mm-sol
|
|
3
|
-
Version: 0.6.2
|
|
4
|
-
Requires-Python: >=3.12
|
|
5
|
-
Requires-Dist: base58~=2.1.1
|
|
6
|
-
Requires-Dist: jinja2>=3.1.6
|
|
7
|
-
Requires-Dist: mm-crypto-utils>=0.3.6
|
|
8
|
-
Requires-Dist: mnemonic==0.21
|
|
9
|
-
Requires-Dist: socksio>=1.0.0
|
|
10
|
-
Requires-Dist: solana~=0.36.6
|
|
11
|
-
Requires-Dist: solders~=0.26.0
|
|
12
|
-
Requires-Dist: typer>=0.15.2
|
mm_sol-0.6.2.dist-info/RECORD
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
mm_sol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
mm_sol/account.py,sha256=cVcxRQBuV_Gfm2WgQIwaYuAQijeIJqDDxLC22PN0XSs,3493
|
|
3
|
-
mm_sol/constants.py,sha256=WSpfz5_cq_8XbIrNFJGu9okwbfPTL00zsyR_k9-7O0o,29
|
|
4
|
-
mm_sol/converters.py,sha256=rBxe3SIADZS8hG7TYl4FgjmvKH-ykaTmNbnWWQDiFZ4,1430
|
|
5
|
-
mm_sol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
mm_sol/retry.py,sha256=9ejCcrHbJFOcZVKdbUASynLs1YHw04VAIKGH8mIJ1OI,2894
|
|
7
|
-
mm_sol/rpc.py,sha256=LhXrHIz58iOG2ES8m67ycBCwkJx-4pLBuDt6Hsq6OkM,2422
|
|
8
|
-
mm_sol/rpc_sync.py,sha256=A06MTSFQ7UUJgm0fy4a6ipqqY2vdDwS07UGXkdrvqWw,7148
|
|
9
|
-
mm_sol/spl_token.py,sha256=hEWVch17EdudlL_tj3ZInCa9wB0iK8hwwpFucmVi7Pc,1941
|
|
10
|
-
mm_sol/transfer.py,sha256=6CXzeMe91JtG8SuTadYQ-DLHJFyskytmBItGVEPh7Os,4410
|
|
11
|
-
mm_sol/utils.py,sha256=oD06NsMSMhN6lqsM6mSgLTtiKwA1uAsen9WR82ofRTE,923
|
|
12
|
-
mm_sol/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
mm_sol/cli/calcs.py,sha256=TR-mWQWYyHPdJYi_rvqiebqBqRsXsaqaSdvwCoSax1g,1675
|
|
14
|
-
mm_sol/cli/cli.py,sha256=0MflYgO-UzFdoaXFCIBuQ1Y6AOQUquX__AhSWOO64KY,4735
|
|
15
|
-
mm_sol/cli/cli_utils.py,sha256=nFdY8tJFZxyssEBEFCc3VTNJt447e6vMnugx4GBPL4o,1840
|
|
16
|
-
mm_sol/cli/validators.py,sha256=M_Rr7JoG3TUYTDAGkjQLDH6l9i9FOrSpss30KdY3UlM,1379
|
|
17
|
-
mm_sol/cli/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
mm_sol/cli/cmd/balance_cmd.py,sha256=ot6X7gTSoMcjapVkAgDlA9Wyo4YeFBIRA7GLjTXsu98,2469
|
|
19
|
-
mm_sol/cli/cmd/balances_cmd.py,sha256=XNNyU02mvSxPdfD3usxucNiiHagxSnLe1rKihj-ya78,2676
|
|
20
|
-
mm_sol/cli/cmd/example_cmd.py,sha256=ZLTy1-cmapiCyYvjFInVE-pQCGKZzDgYKUhsOwtbSIY,234
|
|
21
|
-
mm_sol/cli/cmd/node_cmd.py,sha256=o3YktYk4o_ya8srN_It2BITam4HlpFMK11ajYNTGuKA,350
|
|
22
|
-
mm_sol/cli/cmd/transfer_cmd.py,sha256=8QMfqUcvS63V_AeEvlvsuIEZIv_ydrMtuCOr4LvcyoY,10922
|
|
23
|
-
mm_sol/cli/cmd/wallet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
-
mm_sol/cli/cmd/wallet/keypair_cmd.py,sha256=cRHVVTs9zNYmUozZ8ZlJoutn9V6r8I1AEHBrszR7dTE,538
|
|
25
|
-
mm_sol/cli/cmd/wallet/mnemonic_cmd.py,sha256=IiON_fJT5AFfIr_E1LR6_iDYZ3c_jWCFc-wSYqk61V8,648
|
|
26
|
-
mm_sol/cli/examples/balances.toml,sha256=333g2EkyYBDW7OWFGMIWVZGkdFQMMo0Ag-bg-BvS4Zg,349
|
|
27
|
-
mm_sol/cli/examples/transfer.toml,sha256=kOCdmuwmhlOam4LVtlcYTKF0PoZYHWMlv9gWxNSXMOk,1624
|
|
28
|
-
mm_sol-0.6.2.dist-info/METADATA,sha256=H01qTQ1WZUC-TNzgDPimXXZpIFZVVcf6CvuvmeE6UsQ,320
|
|
29
|
-
mm_sol-0.6.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
30
|
-
mm_sol-0.6.2.dist-info/entry_points.txt,sha256=MrYnosumy9nsITSAw5TiR3WXDwsdoF0YvUIlZ38TLLs,46
|
|
31
|
-
mm_sol-0.6.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|