mm-sol 0.5.9__py3-none-any.whl → 0.6.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/transfer.py CHANGED
@@ -1,22 +1,54 @@
1
- import mm_crypto_utils
2
1
  import pydash
3
- from mm_crypto_utils import Nodes, Proxies
4
- from mm_std import Err, Ok, Result
2
+ from mm_crypto_utils import Nodes, Proxies, retry_with_node_and_proxy
3
+ from mm_std import Result
5
4
  from pydantic import BaseModel
6
5
  from solders.message import Message
7
6
  from solders.pubkey import Pubkey
8
7
  from solders.signature import Signature
9
8
  from solders.system_program import TransferParams, transfer
10
9
  from solders.transaction import Transaction
11
- from spl.token.client import Token
10
+ from spl.token.async_client import AsyncToken
12
11
  from spl.token.constants import TOKEN_PROGRAM_ID
13
12
  from spl.token.instructions import get_associated_token_address
14
13
 
15
- from mm_sol import rpc, utils
14
+ from mm_sol import rpc_sync, utils
16
15
  from mm_sol.account import check_private_key, get_keypair
17
16
 
18
17
 
19
- def transfer_token(
18
+ async def transfer_token_with_retries(
19
+ retries: int,
20
+ nodes: Nodes,
21
+ proxies: Proxies,
22
+ *,
23
+ token_mint_address: str | Pubkey,
24
+ from_address: str | Pubkey,
25
+ private_key: str,
26
+ to_address: str | Pubkey,
27
+ amount: int, # smallest unit
28
+ decimals: int,
29
+ timeout: float = 10,
30
+ create_token_account_if_not_exists: bool = True,
31
+ ) -> Result[Signature]:
32
+ return await retry_with_node_and_proxy(
33
+ retries,
34
+ nodes,
35
+ proxies,
36
+ lambda node, proxy: transfer_token(
37
+ node=node,
38
+ token_mint_address=token_mint_address,
39
+ from_address=from_address,
40
+ private_key=private_key,
41
+ to_address=to_address,
42
+ amount=amount,
43
+ decimals=decimals,
44
+ proxy=proxy,
45
+ timeout=timeout,
46
+ create_token_account_if_not_exists=create_token_account_if_not_exists,
47
+ ),
48
+ )
49
+
50
+
51
+ async def transfer_token(
20
52
  *,
21
53
  node: str,
22
54
  token_mint_address: str | Pubkey,
@@ -29,73 +61,71 @@ def transfer_token(
29
61
  timeout: float = 10,
30
62
  create_token_account_if_not_exists: bool = True,
31
63
  ) -> Result[Signature]:
64
+ # TODO: try/except this function!!!
32
65
  acc = get_keypair(private_key)
33
66
  if not check_private_key(from_address, private_key):
34
- return Err("invalid_private_key")
67
+ return Result.failure("invalid_private_key")
35
68
 
36
69
  from_address = utils.pubkey(from_address)
37
70
  token_mint_address = utils.pubkey(token_mint_address)
38
71
  to_address = utils.pubkey(to_address)
39
72
 
40
- client = utils.get_client(node, proxy=proxy, timeout=timeout)
41
- token_client = Token(conn=client, pubkey=token_mint_address, program_id=TOKEN_PROGRAM_ID, payer=acc)
73
+ client = utils.get_async_client(node, proxy=proxy, timeout=timeout)
74
+ token_client = AsyncToken(conn=client, pubkey=token_mint_address, program_id=TOKEN_PROGRAM_ID, payer=acc)
42
75
 
43
76
  recipient_token_account = get_associated_token_address(to_address, token_mint_address, token_program_id=TOKEN_PROGRAM_ID)
44
77
  from_token_account = get_associated_token_address(from_address, token_mint_address, token_program_id=TOKEN_PROGRAM_ID)
45
- data: list[object] = []
78
+ logs: list[object] = []
46
79
 
47
- account_info_res = client.get_account_info(recipient_token_account)
80
+ account_info_res = await client.get_account_info(recipient_token_account)
48
81
  if account_info_res.value is None:
49
82
  if create_token_account_if_not_exists:
50
83
  create_account_res = token_client.create_associated_token_account(to_address, skip_confirmation=False)
51
- data.append(create_account_res)
84
+ logs.append(create_account_res)
52
85
  else:
53
- return Err("no_token_account")
86
+ return Result.failure("no_token_account")
54
87
 
55
- res = token_client.transfer_checked(
88
+ res = await token_client.transfer_checked(
56
89
  source=from_token_account,
57
90
  dest=recipient_token_account,
58
91
  owner=from_address,
59
92
  amount=amount,
60
93
  decimals=decimals,
94
+ multi_signers=None,
61
95
  )
62
- data.append(res)
96
+ logs.append(res)
63
97
 
64
- return Ok(res.value, data=data)
98
+ return Result.success(res.value, {"logs": logs})
65
99
 
66
100
 
67
- def transfer_token_with_retries(
68
- *,
101
+ async def transfer_sol_with_retries(
102
+ retries: int,
69
103
  nodes: Nodes,
70
- token_mint_address: str | Pubkey,
71
- from_address: str | Pubkey,
104
+ proxies: Proxies,
105
+ *,
106
+ from_address: str,
72
107
  private_key: str,
73
- to_address: str | Pubkey,
74
- amount: int, # smallest unit
75
- decimals: int,
76
- proxies: Proxies = None,
108
+ to_address: str,
109
+ lamports: int,
77
110
  timeout: float = 10,
78
- retries: int = 3,
79
111
  ) -> Result[Signature]:
80
- res: Result[Signature] = Err("not started yet")
81
- for _ in range(retries):
82
- res = transfer_token(
83
- node=mm_crypto_utils.random_node(nodes),
84
- token_mint_address=token_mint_address,
112
+ return await retry_with_node_and_proxy(
113
+ retries,
114
+ nodes,
115
+ proxies,
116
+ lambda node, proxy: transfer_sol(
117
+ node=node,
118
+ proxy=proxy,
85
119
  from_address=from_address,
86
- private_key=private_key,
87
120
  to_address=to_address,
88
- amount=amount,
89
- decimals=decimals,
90
- proxy=mm_crypto_utils.random_proxy(proxies),
121
+ lamports=lamports,
122
+ private_key=private_key,
91
123
  timeout=timeout,
92
- )
93
- if res.is_ok():
94
- return res
95
- return res
124
+ ),
125
+ )
96
126
 
97
127
 
98
- def transfer_sol(
128
+ async def transfer_sol(
99
129
  *,
100
130
  node: str,
101
131
  from_address: str,
@@ -107,46 +137,20 @@ def transfer_sol(
107
137
  ) -> Result[Signature]:
108
138
  acc = get_keypair(private_key)
109
139
  if not check_private_key(from_address, private_key):
110
- return Err("invalid_private_key")
140
+ return Result.failure("invalid_private_key")
111
141
 
112
- client = utils.get_client(node, proxy=proxy, timeout=timeout)
142
+ client = utils.get_async_client(node, proxy=proxy, timeout=timeout)
113
143
  data = None
114
144
  try:
115
145
  ixs = [transfer(TransferParams(from_pubkey=acc.pubkey(), to_pubkey=Pubkey.from_string(to_address), lamports=lamports))]
116
146
  msg = Message(ixs, acc.pubkey())
117
- tx = Transaction([acc], msg, client.get_latest_blockhash().value.blockhash)
118
- res = client.send_transaction(tx)
147
+ blockhash = await client.get_latest_blockhash()
148
+ tx = Transaction([acc], msg, blockhash.value.blockhash)
149
+ res = await client.send_transaction(tx)
119
150
  data = res.to_json()
120
- return Ok(res.value, data=data)
151
+ return Result.success(res.value, {"response": data})
121
152
  except Exception as e:
122
- return Err(e, data=data)
123
-
124
-
125
- def transfer_sol_with_retries(
126
- *,
127
- nodes: Nodes,
128
- from_address: str,
129
- private_key: str,
130
- to_address: str,
131
- lamports: int,
132
- proxies: Proxies = None,
133
- timeout: float = 10,
134
- retries: int = 3,
135
- ) -> Result[Signature]:
136
- res: Result[Signature] = Err("not started yet")
137
- for _ in range(retries):
138
- res = transfer_sol(
139
- node=mm_crypto_utils.random_node(nodes),
140
- from_address=from_address,
141
- private_key=private_key,
142
- to_address=to_address,
143
- lamports=lamports,
144
- proxy=mm_crypto_utils.random_proxy(proxies),
145
- timeout=timeout,
146
- )
147
- if res.is_ok():
148
- return res
149
- return res
153
+ return Result.failure(e, {"response": data})
150
154
 
151
155
 
152
156
  class SolTransferInfo(BaseModel):
@@ -156,8 +160,8 @@ class SolTransferInfo(BaseModel):
156
160
 
157
161
 
158
162
  def find_sol_transfers(node: str, tx_signature: str) -> Result[list[SolTransferInfo]]:
159
- res = rpc.get_transaction(node, tx_signature, encoding="jsonParsed")
160
- if res.is_err():
163
+ res = rpc_sync.get_transaction(node, tx_signature, encoding="jsonParsed")
164
+ if res.is_error():
161
165
  return res # type: ignore[return-value]
162
166
  result = []
163
167
  try:
@@ -170,6 +174,6 @@ def find_sol_transfers(node: str, tx_signature: str) -> Result[list[SolTransferI
170
174
  lamports = pydash.get(ix, "parsed.info.lamports")
171
175
  if source and destination and lamports:
172
176
  result.append(SolTransferInfo(source=source, destination=destination, lamports=lamports))
173
- return Ok(result, data=res.data)
177
+ return Result.success(result, res.extra)
174
178
  except Exception as e:
175
- return Err(e, res.data)
179
+ return Result.failure(e, res.extra)
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mm-sol
3
- Version: 0.5.9
3
+ Version: 0.6.0
4
4
  Requires-Python: >=3.12
5
5
  Requires-Dist: base58~=2.1.1
6
6
  Requires-Dist: jinja2>=3.1.6
7
- Requires-Dist: mm-crypto-utils>=0.2.15
7
+ Requires-Dist: mm-crypto-utils>=0.3.3
8
+ Requires-Dist: mm-std>=0.4.5
8
9
  Requires-Dist: mnemonic==0.21
9
10
  Requires-Dist: socksio>=1.0.0
10
11
  Requires-Dist: solana~=0.36.6
@@ -0,0 +1,30 @@
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/rpc.py,sha256=1rSGu8UKYug9-ScvK1zkaR_VdWUkXYJm2E8RTY2Hfhg,2982
7
+ mm_sol/rpc_sync.py,sha256=w-xP3Hl_whBcZZJv5vw08oiB1GTPfbVRvsDjU_k-UTA,8122
8
+ mm_sol/spl_token.py,sha256=NnTUWaefbvuZX9pDmRLHir2UUaiSWKZamyGsfKwQ2p4,2907
9
+ mm_sol/transfer.py,sha256=CbUOFPjAoPf0KRPI-z5W0cSnTRFENbcNjLXDPKPrVBg,6049
10
+ mm_sol/utils.py,sha256=oD06NsMSMhN6lqsM6mSgLTtiKwA1uAsen9WR82ofRTE,923
11
+ mm_sol/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ mm_sol/cli/calcs.py,sha256=uxnlGPU3UmDvZ567VLzcEyEWvM8CLcoTBt7YcILtaOA,1716
13
+ mm_sol/cli/cli.py,sha256=0MflYgO-UzFdoaXFCIBuQ1Y6AOQUquX__AhSWOO64KY,4735
14
+ mm_sol/cli/cli_utils.py,sha256=nFdY8tJFZxyssEBEFCc3VTNJt447e6vMnugx4GBPL4o,1840
15
+ mm_sol/cli/validators.py,sha256=M_Rr7JoG3TUYTDAGkjQLDH6l9i9FOrSpss30KdY3UlM,1379
16
+ mm_sol/cli/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ mm_sol/cli/cmd/balance_cmd.py,sha256=0Rp6cUqfQLpNlqY6YtrpG-oYYz_llPhWpJkte804PL4,2495
18
+ mm_sol/cli/cmd/balances_cmd.py,sha256=dArwI2oJaTMft73mN0EgDQWVSwRJmsAA0HyT8_GpBiA,2676
19
+ mm_sol/cli/cmd/example_cmd.py,sha256=ZLTy1-cmapiCyYvjFInVE-pQCGKZzDgYKUhsOwtbSIY,234
20
+ mm_sol/cli/cmd/node_cmd.py,sha256=xKjaMdv3_C4kePo-exjE4dQqUHtHWC4eHGROWLkWpS0,347
21
+ mm_sol/cli/cmd/transfer_cmd.py,sha256=Qbgi7FvA8NoUAItv1NZxsLu_oFNgoWlxaALy1eFAs8M,11014
22
+ mm_sol/cli/cmd/wallet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ mm_sol/cli/cmd/wallet/keypair_cmd.py,sha256=cRHVVTs9zNYmUozZ8ZlJoutn9V6r8I1AEHBrszR7dTE,538
24
+ mm_sol/cli/cmd/wallet/mnemonic_cmd.py,sha256=IiON_fJT5AFfIr_E1LR6_iDYZ3c_jWCFc-wSYqk61V8,648
25
+ mm_sol/cli/examples/balances.toml,sha256=333g2EkyYBDW7OWFGMIWVZGkdFQMMo0Ag-bg-BvS4Zg,349
26
+ mm_sol/cli/examples/transfer.toml,sha256=kOCdmuwmhlOam4LVtlcYTKF0PoZYHWMlv9gWxNSXMOk,1624
27
+ mm_sol-0.6.0.dist-info/METADATA,sha256=vE1UQwE3DBr3gw8RLgkmFL3hbShOAlKbacEIx7fbM_8,349
28
+ mm_sol-0.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
+ mm_sol-0.6.0.dist-info/entry_points.txt,sha256=MrYnosumy9nsITSAw5TiR3WXDwsdoF0YvUIlZ38TLLs,46
30
+ mm_sol-0.6.0.dist-info/RECORD,,
mm_sol/async_rpc.py DELETED
@@ -1,42 +0,0 @@
1
- from typing import Any
2
-
3
- from mm_std import Result, hra
4
-
5
-
6
- async def rpc_call(
7
- *,
8
- node: str,
9
- method: str,
10
- params: list[Any],
11
- id_: int = 1,
12
- timeout: float = 10,
13
- proxy: str | None = None,
14
- ) -> Result[Any]:
15
- data = {"jsonrpc": "2.0", "method": method, "params": params, "id": id_}
16
- if node.startswith("http"):
17
- return await _http_call(node, data, timeout, proxy)
18
- raise NotImplementedError("ws is not implemented")
19
-
20
-
21
- async def _http_call(node: str, data: dict[str, object], timeout: float, proxy: str | None) -> Result[Any]:
22
- res = await hra(node, method="POST", proxy=proxy, timeout=timeout, params=data, json_params=True)
23
- try:
24
- if res.is_error():
25
- return res.to_err_result()
26
-
27
- err = res.json.get("error", {}).get("message", "")
28
- if err:
29
- return res.to_err_result(f"service_error: {err}")
30
- if "result" in res.json:
31
- return res.to_ok_result(res.json["result"])
32
-
33
- return res.to_err_result("unknown_response")
34
- except Exception as e:
35
- return res.to_err_result(f"exception: {e!s}")
36
-
37
-
38
- async def get_balance(node: str, address: str, timeout: float = 10, proxy: str | None = None) -> Result[int]:
39
- """Returns balance in lamports"""
40
- return (await rpc_call(node=node, method="getBalance", params=[address], timeout=timeout, proxy=proxy)).and_then(
41
- lambda r: r["value"]
42
- )
mm_sol/balance.py DELETED
@@ -1,158 +0,0 @@
1
- import httpx
2
- from mm_crypto_utils import Nodes, Proxies, random_node, random_proxy
3
- from mm_std import Err, Ok, Result
4
- from solana.exceptions import SolanaRpcException
5
- from solana.rpc.core import RPCException
6
- from solders.pubkey import Pubkey
7
- from solders.rpc.errors import InvalidParamsMessage
8
- from spl.token.instructions import get_associated_token_address
9
-
10
- from mm_sol import async_rpc, rpc
11
- from mm_sol.utils import get_async_client, get_client
12
-
13
-
14
- def get_sol_balance(node: str, address: str, timeout: float = 10, proxy: str | None = None) -> Result[int]:
15
- return rpc.get_balance(node, address, timeout, proxy)
16
-
17
-
18
- async def get_sol_balance_async(node: str, address: str, timeout: float = 10, proxy: str | None = None) -> Result[int]:
19
- return await async_rpc.get_balance(node, address, timeout, proxy)
20
-
21
-
22
- def get_sol_balance_with_retries(
23
- nodes: Nodes, address: str, retries: int, timeout: float = 10, proxies: Proxies = None
24
- ) -> Result[int]:
25
- res: Result[int] = Err("not started yet")
26
- for _ in range(retries):
27
- res = get_sol_balance(random_node(nodes), address, timeout=timeout, proxy=random_proxy(proxies))
28
- if res.is_ok():
29
- return res
30
- return res
31
-
32
-
33
- async def get_sol_balance_with_retries_async(
34
- nodes: Nodes, address: str, retries: int, timeout: float = 10, proxies: Proxies = None
35
- ) -> Result[int]:
36
- res: Result[int] = Err("not started yet")
37
- for _ in range(retries):
38
- res = await get_sol_balance_async(random_node(nodes), address, timeout=timeout, proxy=random_proxy(proxies))
39
- if res.is_ok():
40
- return res
41
- return res
42
-
43
-
44
- def get_token_balance(
45
- node: str,
46
- owner_address: str,
47
- token_mint_address: str,
48
- token_account: str | None = None,
49
- timeout: float = 10,
50
- proxy: str | None = None,
51
- ) -> Result[int]:
52
- try:
53
- client = get_client(node, proxy=proxy, timeout=timeout)
54
- if not token_account:
55
- token_account = str(
56
- get_associated_token_address(Pubkey.from_string(owner_address), Pubkey.from_string(token_mint_address))
57
- )
58
-
59
- res = client.get_token_account_balance(Pubkey.from_string(token_account))
60
-
61
- # Sometimes it not raise an error, but it returns this :(
62
- if isinstance(res, InvalidParamsMessage) and "could not find account" in res.message:
63
- return Ok(0)
64
- return Ok(int(res.value.amount), data=res.to_json())
65
- except RPCException as e:
66
- if "could not find account" in str(e):
67
- return Ok(0)
68
- return Err(e)
69
- except httpx.HTTPStatusError as e:
70
- return Err(f"http error: {e}")
71
- except SolanaRpcException as e:
72
- return Err(e.error_msg)
73
- except Exception as e:
74
- return Err(e)
75
-
76
-
77
- async def get_token_balance_async(
78
- node: str,
79
- owner_address: str,
80
- token_mint_address: str,
81
- token_account: str | None = None,
82
- timeout: float = 10,
83
- proxy: str | None = None,
84
- ) -> Result[int]:
85
- try:
86
- client = get_async_client(node, proxy=proxy, timeout=timeout)
87
- if not token_account:
88
- token_account = str(
89
- get_associated_token_address(Pubkey.from_string(owner_address), Pubkey.from_string(token_mint_address))
90
- )
91
-
92
- res = await client.get_token_account_balance(Pubkey.from_string(token_account))
93
-
94
- # Sometimes it not raise an error, but it returns this :(
95
- if isinstance(res, InvalidParamsMessage) and "could not find account" in res.message:
96
- return Ok(0)
97
- return Ok(int(res.value.amount), data=res.to_json())
98
- except RPCException as e:
99
- if "could not find account" in str(e):
100
- return Ok(0)
101
- return Err(e)
102
-
103
- except httpx.HTTPStatusError as e:
104
- return Err(f"http error: {e}")
105
- except SolanaRpcException as e:
106
- return Err(e.error_msg)
107
- except Exception as e:
108
- return Err(e)
109
-
110
-
111
- def get_token_balance_with_retries(
112
- nodes: Nodes,
113
- owner_address: str,
114
- token_mint_address: str,
115
- retries: int,
116
- token_account: str | None = None,
117
- timeout: float = 10,
118
- proxies: Proxies = None,
119
- ) -> Result[int]:
120
- res: Result[int] = Err("not started yet")
121
- for _ in range(retries):
122
- res = get_token_balance(
123
- random_node(nodes),
124
- owner_address,
125
- token_mint_address,
126
- token_account,
127
- timeout=timeout,
128
- proxy=random_proxy(proxies),
129
- )
130
- if res.is_ok():
131
- return res
132
-
133
- return res
134
-
135
-
136
- async def get_token_balance_with_retries_async(
137
- nodes: Nodes,
138
- owner_address: str,
139
- token_mint_address: str,
140
- retries: int,
141
- token_account: str | None = None,
142
- timeout: float = 10,
143
- proxies: Proxies = None,
144
- ) -> Result[int]:
145
- res: Result[int] = Err("not started yet")
146
- for _ in range(retries):
147
- res = await get_token_balance_async(
148
- random_node(nodes),
149
- owner_address,
150
- token_mint_address,
151
- token_account,
152
- timeout=timeout,
153
- proxy=random_proxy(proxies),
154
- )
155
- if res.is_ok():
156
- return res
157
-
158
- return res
mm_sol/block.py DELETED
@@ -1,58 +0,0 @@
1
- from mm_std import Err, Ok, Result
2
- from pydantic import BaseModel
3
-
4
- from mm_sol.rpc import rpc_call
5
-
6
-
7
- class BlockTxCount(BaseModel):
8
- slot: int
9
- block_time: int | None
10
- vote_tx_ok: int
11
- vote_tx_error: int
12
- non_vote_tx_ok: int
13
- non_vote_tx_error: int
14
-
15
-
16
- def calc_block_tx_count(node: str, slot: int, timeout: int = 10, proxy: str | None = None) -> Result[BlockTxCount]:
17
- res = rpc_call(node=node, method="getBlock", params=[slot], timeout=timeout, proxy=proxy)
18
- if res.is_err():
19
- return res
20
- vote_tx_ok = 0
21
- vote_tx_error = 0
22
- non_vote_tx_ok = 0
23
- non_vote_tx_error = 0
24
- vote_tx_keys = [
25
- "SysvarS1otHashes111111111111111111111111111",
26
- "SysvarC1ock11111111111111111111111111111111",
27
- "Vote111111111111111111111111111111111111111",
28
- ]
29
- try:
30
- res_ok = res.unwrap()
31
- txs = res_ok["transactions"]
32
- block_time = res_ok["blockTime"]
33
- for tx in txs:
34
- is_error = tx["meta"]["err"] is not None
35
- account_keys = tx["transaction"]["message"]["accountKeys"]
36
- if len(account_keys) == 5 and vote_tx_keys == account_keys[2:]:
37
- if is_error:
38
- vote_tx_error += 1
39
- else:
40
- vote_tx_ok += 1
41
- elif is_error:
42
- non_vote_tx_error += 1
43
- else:
44
- non_vote_tx_ok += 1
45
-
46
- return Ok(
47
- BlockTxCount(
48
- slot=slot,
49
- vote_tx_ok=vote_tx_ok,
50
- vote_tx_error=vote_tx_error,
51
- non_vote_tx_ok=non_vote_tx_ok,
52
- non_vote_tx_error=non_vote_tx_error,
53
- block_time=block_time,
54
- ),
55
- res.data,
56
- )
57
- except Exception as e:
58
- return Err(e, data=res.data)
mm_sol/rpc_async.py DELETED
@@ -1,65 +0,0 @@
1
- import json
2
- from collections.abc import Sequence
3
- from typing import Any
4
-
5
- import websockets
6
- from mm_std import DataResult, http_request
7
-
8
-
9
- async def rpc_call(
10
- node: str,
11
- method: str,
12
- params: Sequence[object],
13
- timeout: float,
14
- proxy: str | None,
15
- id_: int = 1,
16
- ) -> DataResult[Any]:
17
- data = {"jsonrpc": "2.0", "method": method, "params": params, "id": id_}
18
- if node.startswith("http"):
19
- return await _http_call(node, data, timeout, proxy)
20
- return await _ws_call(node, data, timeout)
21
-
22
-
23
- async def _http_call(node: str, data: dict[str, object], timeout: float, proxy: str | None) -> DataResult[Any]:
24
- res = await http_request(node, method="POST", proxy=proxy, timeout=timeout, json=data)
25
- if res.is_error():
26
- return res.to_data_result_err()
27
- try:
28
- parsed_body = res.parse_json_body()
29
- err = parsed_body.get("error", {}).get("message", "")
30
- if err:
31
- return res.to_data_result_err(f"service_error: {err}")
32
- if "result" in parsed_body:
33
- return res.to_data_result_ok(parsed_body["result"])
34
- return res.to_data_result_err("unknown_response")
35
- except Exception as err:
36
- return res.to_data_result_err(f"exception: {err}")
37
-
38
-
39
- async def _ws_call(node: str, data: dict[str, object], timeout: float) -> DataResult[Any]:
40
- try:
41
- async with websockets.connect(node, open_timeout=timeout) as ws:
42
- await ws.send(json.dumps(data))
43
- response = json.loads(await ws.recv())
44
-
45
- err = response.get("error", {}).get("message", "")
46
- if err:
47
- return DataResult.err(f"service_error: {err}", {"res": response})
48
- if "result" in response:
49
- return DataResult.ok(response["result"], {"res": response})
50
- return DataResult.err("unknown_response", {"res": response})
51
- except TimeoutError:
52
- return DataResult.err("timeout")
53
- except Exception as err:
54
- return DataResult.exception(err)
55
-
56
-
57
- async def get_block_height(node: str, timeout: float = 10, proxy: str | None = None) -> DataResult[int]:
58
- return await rpc_call(node=node, method="getBlockHeight", params=[], timeout=timeout, proxy=proxy)
59
-
60
-
61
- async def get_balance(node: str, address: str, timeout: float = 10, proxy: str | None = None) -> DataResult[int]:
62
- """Returns balance in lamports"""
63
- return (await rpc_call(node=node, method="getBalance", params=[address], timeout=timeout, proxy=proxy)).map(
64
- lambda r: r["value"]
65
- )