tonutils 2.0.1b3__py3-none-any.whl → 2.0.1b5__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.
Files changed (31) hide show
  1. tonutils/__meta__.py +1 -1
  2. tonutils/cli.py +111 -0
  3. tonutils/clients/__init__.py +4 -4
  4. tonutils/clients/adnl/__init__.py +4 -4
  5. tonutils/clients/adnl/balancer.py +58 -58
  6. tonutils/clients/adnl/client.py +20 -20
  7. tonutils/clients/adnl/provider/config.py +13 -8
  8. tonutils/clients/adnl/provider/provider.py +39 -42
  9. tonutils/clients/adnl/provider/transport.py +30 -25
  10. tonutils/clients/base.py +5 -1
  11. tonutils/exceptions.py +41 -31
  12. tonutils/tonconnect/__init__.py +0 -0
  13. tonutils/tools/__init__.py +6 -0
  14. tonutils/tools/block_scanner/__init__.py +16 -0
  15. tonutils/tools/block_scanner/annotations.py +23 -0
  16. tonutils/tools/block_scanner/dispatcher.py +141 -0
  17. tonutils/tools/block_scanner/events.py +31 -0
  18. tonutils/tools/block_scanner/scanner.py +313 -0
  19. tonutils/tools/block_scanner/traversal.py +97 -0
  20. tonutils/tools/block_scanner/where.py +53 -0
  21. tonutils/tools/status_monitor/__init__.py +3 -0
  22. tonutils/tools/status_monitor/console.py +157 -0
  23. tonutils/tools/status_monitor/models.py +27 -0
  24. tonutils/tools/status_monitor/monitor.py +295 -0
  25. tonutils/types.py +12 -4
  26. {tonutils-2.0.1b3.dist-info → tonutils-2.0.1b5.dist-info}/METADATA +2 -5
  27. {tonutils-2.0.1b3.dist-info → tonutils-2.0.1b5.dist-info}/RECORD +31 -16
  28. tonutils-2.0.1b5.dist-info/entry_points.txt +2 -0
  29. {tonutils-2.0.1b3.dist-info → tonutils-2.0.1b5.dist-info}/WHEEL +0 -0
  30. {tonutils-2.0.1b3.dist-info → tonutils-2.0.1b5.dist-info}/licenses/LICENSE +0 -0
  31. {tonutils-2.0.1b3.dist-info → tonutils-2.0.1b5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,157 @@
1
+ import sys
2
+ import typing as t
3
+ from collections import deque
4
+ from datetime import datetime
5
+
6
+ from tonutils.tools.status_monitor.models import BlockInfo, LiteServerStatus
7
+
8
+ _ENTER_ALT_SCREEN = "\033[?1049h"
9
+ _EXIT_ALT_SCREEN = "\033[?1049l"
10
+ _HIDE_CURSOR = "\033[?25l"
11
+ _SHOW_CURSOR = "\033[?25h"
12
+ _MOVE_HOME = "\033[H"
13
+ _CLEAR_SCREEN = "\033[2J"
14
+ _CLEAR_LINE = "\033[K"
15
+
16
+
17
+ class Console:
18
+ HEADERS = [
19
+ "LS",
20
+ "HOST",
21
+ "PORT",
22
+ "Version",
23
+ "Time",
24
+ "Ping",
25
+ "Connect RTT",
26
+ "Request RTT",
27
+ "Last MC Block",
28
+ "Last BC Block",
29
+ "Archive From",
30
+ ]
31
+ WIDTHS = [2, 15, 5, 7, 19, 7, 11, 11, 16, 16, 12]
32
+
33
+ TABLE_TITLE = "Lite Server Status"
34
+ ERROR_TITLE = "Error Log"
35
+ MAX_ERROR_LOGS = 10
36
+
37
+ def __init__(self) -> None:
38
+ self._index_width = 2
39
+ self._is_tty = sys.stdout.isatty()
40
+ self._error_log: deque[str] = deque(maxlen=self.MAX_ERROR_LOGS)
41
+ self._prev_errors: t.Dict[int, t.Optional[str]] = {}
42
+
43
+ def enter(self) -> None:
44
+ if self._is_tty:
45
+ sys.stdout.write(_ENTER_ALT_SCREEN + _HIDE_CURSOR + _CLEAR_SCREEN)
46
+ sys.stdout.flush()
47
+
48
+ def exit(self) -> None:
49
+ if self._is_tty:
50
+ sys.stdout.write(_SHOW_CURSOR + _EXIT_ALT_SCREEN)
51
+ sys.stdout.flush()
52
+
53
+ def render(self, statuses: t.List[LiteServerStatus]) -> None:
54
+ self._update_state(statuses)
55
+ self._home()
56
+ self._draw(statuses)
57
+
58
+ def _home(self) -> None:
59
+ if self._is_tty:
60
+ sys.stdout.write(_MOVE_HOME)
61
+ sys.stdout.flush()
62
+
63
+ def _update_state(self, statuses: t.List[LiteServerStatus]) -> None:
64
+ self._update_index_width(statuses)
65
+ self._update_error_log(statuses)
66
+
67
+ def _update_index_width(self, statuses: t.List[LiteServerStatus]) -> None:
68
+ if statuses:
69
+ self._index_width = max(2, len(str(len(statuses) - 1)))
70
+
71
+ def _update_error_log(self, statuses: t.List[LiteServerStatus]) -> None:
72
+ now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
73
+ for status in statuses:
74
+ prev = self._prev_errors.get(status.server.index)
75
+ if status.last_error and status.last_error != prev:
76
+ idx = str(status.server.index).rjust(self._index_width)
77
+ self._error_log.appendleft(f" {now} [LS {idx}]: {status.last_error}")
78
+ self._prev_errors[status.server.index] = status.last_error
79
+
80
+ def _get_table_width(self) -> int:
81
+ return sum(self.WIDTHS) + (len(self.WIDTHS) - 1) * 3
82
+
83
+ def _draw(self, statuses: t.List[LiteServerStatus]) -> None:
84
+ table_width = self._get_table_width()
85
+ padding = (table_width - len(self.TABLE_TITLE)) // 2
86
+
87
+ lines = [
88
+ "═" * table_width,
89
+ " " * padding + self.TABLE_TITLE,
90
+ "═" * table_width,
91
+ self._format_header(),
92
+ self._format_separator(),
93
+ ]
94
+
95
+ for status in statuses:
96
+ lines.append(self._format_row(status))
97
+
98
+ lines.append("")
99
+
100
+ if self._error_log:
101
+ lines.append("─" * table_width)
102
+ lines.append(f" {self.ERROR_TITLE}:")
103
+ lines.extend(self._error_log)
104
+
105
+ output = (_CLEAR_LINE + "\n").join(lines) + _CLEAR_LINE
106
+
107
+ output += "\n" + _CLEAR_LINE
108
+ sys.stdout.write(output)
109
+ sys.stdout.flush()
110
+
111
+ def _format_header(self) -> str:
112
+ return " │ ".join(h.ljust(w) for h, w in zip(self.HEADERS, self.WIDTHS))
113
+
114
+ def _format_separator(self) -> str:
115
+ return "─┼─".join("─" * w for w in self.WIDTHS)
116
+
117
+ def _format_row(self, status: LiteServerStatus) -> str:
118
+ cells = [
119
+ str(status.server.index),
120
+ status.server.host,
121
+ str(status.server.port),
122
+ self._fmt_int(status.version),
123
+ self._fmt_datetime(status.time),
124
+ self._fmt_ms(status.ping_ms),
125
+ self._fmt_ms(status.connect_ms),
126
+ self._fmt_ms(status.request_ms),
127
+ self._fmt_block(status.last_mc_block),
128
+ self._fmt_block(status.last_bc_block),
129
+ self._fmt_date(status.archive_from),
130
+ ]
131
+ return " │ ".join(c.ljust(w) for c, w in zip(cells, self.WIDTHS))
132
+
133
+ @staticmethod
134
+ def _fmt_int(value: t.Optional[int]) -> str:
135
+ return str(value) if value is not None else "-"
136
+
137
+ @staticmethod
138
+ def _fmt_ms(value: t.Optional[int]) -> str:
139
+ return f"{value}ms" if value is not None else "-"
140
+
141
+ @staticmethod
142
+ def _fmt_block(block: t.Optional[BlockInfo]) -> str:
143
+ if block is None:
144
+ return "-"
145
+ return f"{block.seqno} / {block.txs_count}"
146
+
147
+ @staticmethod
148
+ def _fmt_date(ts: t.Optional[int]) -> str:
149
+ if ts is None:
150
+ return "-"
151
+ return datetime.fromtimestamp(ts).strftime("%Y-%m-%d")
152
+
153
+ @staticmethod
154
+ def _fmt_datetime(ts: t.Optional[int]) -> str:
155
+ if ts is None:
156
+ return "-"
157
+ return datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S")
@@ -0,0 +1,27 @@
1
+ import typing as t
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class LiteServer(BaseModel):
7
+ index: int
8
+ host: str
9
+ port: int
10
+
11
+
12
+ class BlockInfo(BaseModel):
13
+ seqno: int
14
+ txs_count: int
15
+
16
+
17
+ class LiteServerStatus(BaseModel):
18
+ server: LiteServer
19
+ version: t.Optional[int] = None
20
+ time: t.Optional[int] = None
21
+ ping_ms: t.Optional[int] = None
22
+ connect_ms: t.Optional[int] = None
23
+ request_ms: t.Optional[int] = None
24
+ last_mc_block: t.Optional[BlockInfo] = None
25
+ last_bc_block: t.Optional[BlockInfo] = None
26
+ archive_from: t.Optional[int] = None
27
+ last_error: t.Optional[str] = None
@@ -0,0 +1,295 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import time
5
+ import typing as t
6
+
7
+ from tonutils.clients import LiteClient
8
+ from tonutils.clients.adnl.provider.models import GlobalConfig
9
+ from tonutils.tools.status_monitor.console import Console
10
+ from tonutils.tools.status_monitor.models import (
11
+ BlockInfo,
12
+ LiteServerStatus,
13
+ LiteServer,
14
+ )
15
+ from tonutils.types import (
16
+ NetworkGlobalID,
17
+ WorkchainID,
18
+ MAINNET_GENESIS_UTIME,
19
+ MASTERCHAIN_SHARD,
20
+ )
21
+
22
+
23
+ class LiteServerMonitor:
24
+ RENDER_INTERVAL = 0.1
25
+ RECONNECT_INTERVAL = 30.0
26
+
27
+ FAST_UPDATE_INTERVAL = 0.3
28
+ MEDIUM_UPDATE_INTERVAL = 3.0
29
+ SLOW_UPDATE_INTERVAL = 10.0
30
+
31
+ def __init__(self, clients: t.List[LiteClient]) -> None:
32
+ self._clients = clients
33
+ self._console = Console()
34
+
35
+ self._archive_cache: t.Dict[int, int] = {}
36
+ self._statuses: t.Dict[int, LiteServerStatus] = {}
37
+ self._last_connect: t.Dict[int, float] = {}
38
+
39
+ self._tasks: t.List[asyncio.Task[None]] = []
40
+ self._stop = asyncio.Event()
41
+
42
+ self._locks: t.Dict[int, asyncio.Lock] = {}
43
+
44
+ @classmethod
45
+ def from_config(
46
+ cls,
47
+ config: GlobalConfig,
48
+ network: NetworkGlobalID,
49
+ rps_limit: t.Optional[int] = 100,
50
+ ) -> LiteServerMonitor:
51
+ return cls(
52
+ [
53
+ LiteClient(
54
+ network=network,
55
+ ip=server.host,
56
+ port=server.port,
57
+ public_key=server.id,
58
+ rps_limit=rps_limit,
59
+ )
60
+ for server in config.liteservers
61
+ ]
62
+ )
63
+
64
+ @property
65
+ def statuses(self) -> t.List[LiteServerStatus]:
66
+ return list(self._statuses.values())
67
+
68
+ async def run(self) -> None:
69
+ self._console.enter()
70
+ self._init_statuses()
71
+ self._start_update_loops()
72
+
73
+ try:
74
+ while not self._stop.is_set():
75
+ self._console.render(self.statuses)
76
+ await self._sleep(self.RENDER_INTERVAL)
77
+ finally:
78
+ self._console.exit()
79
+
80
+ async def stop(self) -> None:
81
+ if self._stop.is_set():
82
+ return
83
+ self._stop.set()
84
+
85
+ for task in self._tasks:
86
+ task.cancel()
87
+ await asyncio.gather(*self._tasks, return_exceptions=True)
88
+
89
+ close_tasks = [client.close() for client in self._clients]
90
+ await asyncio.gather(*close_tasks, return_exceptions=True)
91
+
92
+ def _init_statuses(self) -> None:
93
+ for index, client in enumerate(self._clients):
94
+ server = LiteServer(
95
+ index=index,
96
+ host=client.provider.node.host,
97
+ port=client.provider.node.port,
98
+ )
99
+ self._statuses[index] = LiteServerStatus(server=server)
100
+ self._locks[index] = asyncio.Lock()
101
+
102
+ def _start_update_loops(self) -> None:
103
+ if self._tasks:
104
+ return
105
+
106
+ for index, client in enumerate(self._clients):
107
+ fast = self._fast_update_loop(index, client)
108
+ self._tasks.append(asyncio.create_task(fast))
109
+
110
+ medium = self._medium_update_loop(index, client)
111
+ self._tasks.append(asyncio.create_task(medium))
112
+
113
+ slow = self._slow_update_loop(index, client)
114
+ self._tasks.append(asyncio.create_task(slow))
115
+
116
+ async def _ensure_connected(self, index: int, client: LiteClient) -> bool:
117
+ if client.provider.is_connected:
118
+ return True
119
+
120
+ now = time.monotonic()
121
+ last_attempt = self._last_connect.get(index, 0.0)
122
+ if now - last_attempt < self.RECONNECT_INTERVAL:
123
+ return False
124
+
125
+ self._last_connect[index] = now
126
+ await self._connect(index, client)
127
+ return client.provider.is_connected
128
+
129
+ async def _fast_update_loop(self, index: int, client: LiteClient) -> None:
130
+ while not self._stop.is_set():
131
+ if not await self._ensure_connected(index, client):
132
+ await self._sleep(1.0)
133
+ continue
134
+
135
+ await asyncio.gather(
136
+ self._update_time(index, client),
137
+ self._update_last_blocks(index, client),
138
+ return_exceptions=True,
139
+ )
140
+ await self._sleep(self.FAST_UPDATE_INTERVAL)
141
+
142
+ async def _medium_update_loop(self, index: int, client: LiteClient) -> None:
143
+ while not self._stop.is_set():
144
+ if not client.is_connected:
145
+ await self._sleep(1.0)
146
+ continue
147
+
148
+ await asyncio.gather(
149
+ self._update_ping_ms(index, client),
150
+ self._update_request_ms(index, client),
151
+ return_exceptions=True,
152
+ )
153
+ await self._sleep(self.MEDIUM_UPDATE_INTERVAL)
154
+
155
+ async def _slow_update_loop(self, index: int, client: LiteClient) -> None:
156
+ while not self._stop.is_set():
157
+ if not client.is_connected:
158
+ await self._sleep(1.0)
159
+ continue
160
+
161
+ await asyncio.gather(
162
+ self._update_version(index, client),
163
+ self._update_archive_from(index, client),
164
+ return_exceptions=True,
165
+ )
166
+ await self._sleep(self.SLOW_UPDATE_INTERVAL)
167
+
168
+ async def _sleep(self, seconds: float) -> None:
169
+ try:
170
+ await asyncio.wait_for(self._stop.wait(), timeout=seconds)
171
+ except asyncio.TimeoutError:
172
+ pass
173
+
174
+ async def _set_status(self, index: int, **kwargs: t.Any) -> None:
175
+ async with self._locks[index]:
176
+ current = self._statuses[index]
177
+ self._statuses[index] = current.model_copy(update=kwargs)
178
+
179
+ async def _connect(self, index: int, client: LiteClient) -> None:
180
+ try:
181
+ start = time.perf_counter()
182
+ await client.connect()
183
+ connect_ms = int((time.perf_counter() - start) * 1000)
184
+ await self._set_status(index, connect_ms=connect_ms, last_error=None)
185
+ except Exception as e:
186
+ await self._set_status(index, last_error=str(e))
187
+
188
+ async def _update_version(self, index: int, client: LiteClient) -> None:
189
+ try:
190
+ version = await client.get_version()
191
+ await self._set_status(index, version=version)
192
+ except Exception as e:
193
+ await self._set_status(index, last_error=str(e))
194
+
195
+ async def _update_time(self, index: int, client: LiteClient) -> None:
196
+ try:
197
+ server_time = await client.get_time()
198
+ await self._set_status(index, time=server_time)
199
+ except Exception as e:
200
+ await self._set_status(index, last_error=str(e))
201
+
202
+ async def _update_ping_ms(self, index: int, client: LiteClient) -> None:
203
+ try:
204
+ ping_ms = client.provider.last_ping_ms
205
+ if ping_ms is not None:
206
+ await self._set_status(index, ping_ms=ping_ms)
207
+ except Exception as e:
208
+ await self._set_status(index, last_error=str(e))
209
+
210
+ async def _update_request_ms(self, index: int, client: LiteClient) -> None:
211
+ try:
212
+ start = time.perf_counter()
213
+ await client.get_masterchain_info()
214
+ request_ms = int((time.perf_counter() - start) * 1000)
215
+ await self._set_status(index, request_ms=request_ms)
216
+ except Exception as e:
217
+ await self._set_status(index, last_error=str(e))
218
+
219
+ async def _update_last_blocks(self, index: int, client: LiteClient) -> None:
220
+ try:
221
+ mc_block = client.provider.last_mc_block
222
+ if mc_block is None:
223
+ return
224
+
225
+ mc_txs, shards = await asyncio.gather(
226
+ client.get_block_transactions_ext(mc_block),
227
+ client.get_all_shards_info(mc_block),
228
+ )
229
+ last_mc_block = BlockInfo(seqno=mc_block.seqno, txs_count=len(mc_txs))
230
+
231
+ if shards:
232
+ bc_block = max(shards, key=lambda b: b.seqno)
233
+ bc_txs = await client.get_block_transactions_ext(bc_block)
234
+ last_bc_block = BlockInfo(seqno=bc_block.seqno, txs_count=len(bc_txs))
235
+ await self._set_status(
236
+ index,
237
+ last_mc_block=last_mc_block,
238
+ last_bc_block=last_bc_block,
239
+ )
240
+ else:
241
+ await self._set_status(index, last_mc_block=last_mc_block)
242
+
243
+ except Exception as e:
244
+ await self._set_status(index, last_error=str(e))
245
+
246
+ async def _update_archive_from(self, index: int, client: LiteClient) -> None:
247
+ try:
248
+ now = int(time.time())
249
+ result = await self._find_archive_depth(
250
+ client, now, self._archive_cache.get(index)
251
+ )
252
+ self._archive_cache[index] = result
253
+ await self._set_status(index, archive_from=result)
254
+ except Exception as e:
255
+ await self._set_status(index, last_error=str(e))
256
+
257
+ @staticmethod
258
+ async def _find_archive_depth(
259
+ client: LiteClient,
260
+ now: int,
261
+ cached: t.Optional[int] = None,
262
+ ) -> int:
263
+ seconds_per_day = 86400
264
+ seconds_diff = now - MAINNET_GENESIS_UTIME
265
+ right = seconds_diff // seconds_per_day
266
+
267
+ if cached is not None:
268
+ cached_days = (now - cached) // seconds_per_day
269
+ left = cached_days
270
+ best_days = cached_days
271
+ else:
272
+ left = 0
273
+ best_days = 0
274
+
275
+ async def probe(days: int) -> bool:
276
+ utime = now - days * seconds_per_day
277
+ try:
278
+ await client.provider.lookup_block(
279
+ workchain=WorkchainID.MASTERCHAIN,
280
+ shard=MASTERCHAIN_SHARD,
281
+ utime=utime,
282
+ )
283
+ return True
284
+ except (Exception,):
285
+ return False
286
+
287
+ while left <= right:
288
+ mid = (left + right) // 2
289
+ if await probe(mid):
290
+ best_days = mid
291
+ left = mid + 1
292
+ else:
293
+ right = mid - 1
294
+
295
+ return now - best_days * seconds_per_day
tonutils/types.py CHANGED
@@ -17,10 +17,6 @@ __all__ = [
17
17
  "ClientType",
18
18
  "ContractState",
19
19
  "ContractStateInfo",
20
- "DEFAULT_ADNL_RETRY_POLICY",
21
- "DEFAULT_HTTP_RETRY_POLICY",
22
- "DEFAULT_SENDMODE",
23
- "DEFAULT_SUBWALLET_ID",
24
20
  "DNSCategory",
25
21
  "DNSPrefix",
26
22
  "MetadataPrefix",
@@ -34,6 +30,12 @@ __all__ = [
34
30
  "StackItems",
35
31
  "StackTag",
36
32
  "WorkchainID",
33
+ "DEFAULT_ADNL_RETRY_POLICY",
34
+ "DEFAULT_HTTP_RETRY_POLICY",
35
+ "DEFAULT_SENDMODE",
36
+ "DEFAULT_SUBWALLET_ID",
37
+ "MAINNET_GENESIS_UTIME",
38
+ "MASTERCHAIN_SHARD",
37
39
  ]
38
40
 
39
41
  from tonutils.exceptions import CDN_CHALLENGE_MARKERS
@@ -495,3 +497,9 @@ DEFAULT_SUBWALLET_ID = 698983191
495
497
 
496
498
  DEFAULT_SENDMODE = SendMode.PAY_GAS_SEPARATELY | SendMode.IGNORE_ERRORS
497
499
  """Default send mode: pay fees separately and ignore errors."""
500
+
501
+ MASTERCHAIN_SHARD = -9223372036854775808
502
+ """Shard identifier for the masterchain (-2^63)."""
503
+
504
+ MAINNET_GENESIS_UTIME = 1573822385
505
+ """Unix timestamp of the TON mainnet genesis block (November 15, 2019)."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tonutils
3
- Version: 2.0.1b3
3
+ Version: 2.0.1b5
4
4
  Summary: Tonutils is a high-level, object-oriented Python library designed to facilitate seamless interactions with the TON blockchain.
5
5
  Author: nessshon
6
6
  Maintainer: nessshon
@@ -26,11 +26,8 @@ Requires-Python: <3.15,>=3.10
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
28
  Requires-Dist: aiohttp>=3.7.0
29
- Requires-Dist: pycryptodomex~=3.23.0
30
29
  Requires-Dist: pydantic<3.0,>=2.0
31
- Requires-Dist: pynacl~=1.6.0
32
- Requires-Dist: pytoniq-core~=0.1.45
33
- Requires-Dist: requests>=2.31.0
30
+ Requires-Dist: pytoniq-core~=0.1.46
34
31
  Dynamic: license-file
35
32
 
36
33
  # 📦 Tonutils 2.0 [BETA]
@@ -1,22 +1,23 @@
1
1
  tonutils/__init__.py,sha256=ueJrDkU1JBlZiX0q8roQfzYOZY62Of_CiHZlxIIQFO0,228
2
- tonutils/__meta__.py,sha256=mRBQ57iGzpByxckbLnojX_P1AgfSuWhjlMZaHQ9G32Y,24
3
- tonutils/exceptions.py,sha256=fxw2TJTKp4siBgP5RD_AsvFsHh7xqmSuomHZ-3OYD6s,6268
2
+ tonutils/__meta__.py,sha256=uHnZdT43kWVuqeXaVY86NLU06cIBG4SuxsLdEUaX6v8,24
3
+ tonutils/cli.py,sha256=WGir-ihgPuKTgKGmhjPZeKk9wgsm64jiJciOnVlsdco,2645
4
+ tonutils/exceptions.py,sha256=67jXCFPyOnVnd8EaqYg1osVIXg34VZX-aJHPunpc-oI,6462
4
5
  tonutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- tonutils/types.py,sha256=JIX3JYbpAOeRaGDHXg_ABNUzZfCjloUh6KHeskC8b9k,14283
6
+ tonutils/types.py,sha256=ORevKllLjb7pmL3AQTMeSoiZQ4KFhoB_rA7KpGqZZjU,14542
6
7
  tonutils/utils.py,sha256=w2sXvVMA2Erz_JSSN2WuYSi7RAPDAOOwWYiThu8Q0Ps,16499
7
- tonutils/clients/__init__.py,sha256=df1v30j2PR1Pg75s8oTx-gtD6t7TKkYJ9VAumeqWS7M,561
8
- tonutils/clients/base.py,sha256=K2Z0FTF1c1V420mJn8Az9PGgzfbHmK6fnyFPXtrEWGM,9594
8
+ tonutils/clients/__init__.py,sha256=PvHsOHOtkVonfiowEPi6P7ggDeQeQorXcksujru6efQ,561
9
+ tonutils/clients/base.py,sha256=DjNhFd_p82Osqn0qWIjflpt9S1NVZc3MQIEj5U5E9-k,9631
9
10
  tonutils/clients/limiter.py,sha256=d2WO7Dx-ksg3gvl05WuDMu1KycuQj0XrmiG67Q7wnFo,3592
10
11
  tonutils/clients/protocol.py,sha256=4QerYoqBKAAfNZVpyQW2sp5KZZlq8xHCn9yWbbJERPQ,2557
11
- tonutils/clients/adnl/__init__.py,sha256=YiRYJ-Q8CNmbEEkoonmMWvaOEBYHn1eIa7YAXhuAMHo,174
12
- tonutils/clients/adnl/balancer.py,sha256=1oyCwW8tOLs0GcBRBHCYb27ElhPZqn2RlH2FKt4biPI,26772
13
- tonutils/clients/adnl/client.py,sha256=lgUBfovfzn_z7kCZsvZc2l3M_lnHBPruBn-655j3Fag,14060
12
+ tonutils/clients/adnl/__init__.py,sha256=shkczPIYlTrOHjpnOBIoRwEYRQ4rVGfLnOZvnQY0a5U,174
13
+ tonutils/clients/adnl/balancer.py,sha256=L5tvSwklgsp1QGBypMcxta_vhGdCXrOahi33-EFMPfs,26877
14
+ tonutils/clients/adnl/client.py,sha256=hClnodq57bi6Q2p-9vbmh89GKpRDwXdIABUM8BEtKUs,14111
14
15
  tonutils/clients/adnl/utils.py,sha256=rKLbTiGbZQ0ozvh5jYjjaFEKsmqEschjuUiHOX9e6ps,5154
15
16
  tonutils/clients/adnl/provider/__init__.py,sha256=lLwFEEgCifMlYozwSzQbvq97R6Du7TzgGFnTgUnk4gw,63
16
- tonutils/clients/adnl/provider/config.py,sha256=8GDrfAf6B5IKrbK_Wq28XUQZHoYQ0YG_ngqXM2jo-0Y,690
17
+ tonutils/clients/adnl/provider/config.py,sha256=nhe9jwDeN6d4yTlgaVHGKk5TaALYSvIfaok2myvIJXY,894
17
18
  tonutils/clients/adnl/provider/models.py,sha256=3dn4oZv7PIgiwlP2lGs0O6VckC19ejxCFlSPhzU0wX8,4537
18
- tonutils/clients/adnl/provider/provider.py,sha256=2EoI7PJ3-JOfcNqEzb02saa_T6tcwlks32I8UXhsYfs,24416
19
- tonutils/clients/adnl/provider/transport.py,sha256=bDM_qBbd3jH7uPiyq8Jctlxi-CIzryGXHqa5TuX7zWk,10961
19
+ tonutils/clients/adnl/provider/provider.py,sha256=Er5RNR490RIQlRTI5KMxVarshHRNVseAbUYGM48fcbg,24180
20
+ tonutils/clients/adnl/provider/transport.py,sha256=lgp1N0LGjYYIKWiwBIm-pnF064TkkCsSTDAFKt8_U-I,10983
20
21
  tonutils/clients/adnl/provider/workers/__init__.py,sha256=M65q7mVfinHImIZNCEaHBJ-SO4DdVBsSkeZFrJs9OoE,177
21
22
  tonutils/clients/adnl/provider/workers/base.py,sha256=8RenR2MU_B-b8mevzCytLJmPgjLCJ8bVI-4q-wx78Q8,2031
22
23
  tonutils/clients/adnl/provider/workers/pinger.py,sha256=lBpy4TU8L-I_6sxEft-Bn9XmntJhMg5Rm2o2tN2Mp0A,2443
@@ -86,8 +87,22 @@ tonutils/contracts/wallet/versions/v2.py,sha256=pwrlan-utZo_WmnzDwSbnzV8ibkPEWx2
86
87
  tonutils/contracts/wallet/versions/v3.py,sha256=d7cM8wjmW-1H7jGuY3AuUd7eTY3wq9ZYpJ4f5OeYX08,2470
87
88
  tonutils/contracts/wallet/versions/v4.py,sha256=2sAsjJ8_3oYAj5JwWH3PiMyoGbgl6-f7-p6T5X7MGTI,2713
88
89
  tonutils/contracts/wallet/versions/v5.py,sha256=1J6KXPOc7Q5S5EdFM9WXQzNGRZrw5EgxDZ9dmyHwsXE,8890
89
- tonutils-2.0.1b3.dist-info/licenses/LICENSE,sha256=fG-yM-8DSkOTaJ558P7uF5PNXBmineVO9-HC12YbIxs,1060
90
- tonutils-2.0.1b3.dist-info/METADATA,sha256=pG9mZCq1liFBJPKDuPuqP_HPlADYa8AZ6ndFibrNuEM,4279
91
- tonutils-2.0.1b3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
92
- tonutils-2.0.1b3.dist-info/top_level.txt,sha256=-7H_mGl8S9HKQrkUiTLmEbtMM-knzRzd_a0cZZnuZIU,9
93
- tonutils-2.0.1b3.dist-info/RECORD,,
90
+ tonutils/tonconnect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
+ tonutils/tools/__init__.py,sha256=QYOVuGY50FFkWlgIvHc2RPU3xiEWSbwnwZ6wuZPQnCA,102
92
+ tonutils/tools/block_scanner/__init__.py,sha256=NRZ2XuDL3VwXJJ0iMe6ETh5w1aX4pCMMIv9UmmOj5yE,260
93
+ tonutils/tools/block_scanner/annotations.py,sha256=i6Xsu_rBERr7qEmhGGcwlYYkqf8cLjNJlZ4rXUf51WY,795
94
+ tonutils/tools/block_scanner/dispatcher.py,sha256=lgrs0MPnnyx0VibVQGYXU6s5mpqV_lO47yhO0uOCV30,4393
95
+ tonutils/tools/block_scanner/events.py,sha256=6M80JoiVMRy7kBBuT8-KlHJ5Dx3GHUjIKmZVPaXXeaA,727
96
+ tonutils/tools/block_scanner/scanner.py,sha256=2arPhNPu-6Klcj-PnSnP3DBVWekhlYjn2iqvN-1wigU,9929
97
+ tonutils/tools/block_scanner/traversal.py,sha256=Zp0Uon0OTvLTsZi-zviMyvJHBsZRUx9XExxLU6LMkVA,3101
98
+ tonutils/tools/block_scanner/where.py,sha256=sZUuabQ5joATkJqUh5R3N5r4P9WblmRrVYEVdZeJvZw,1239
99
+ tonutils/tools/status_monitor/__init__.py,sha256=QnMlA0IDLtCGgXsEgB9q3EJTBo2s5js6lSJk0oZkQZQ,72
100
+ tonutils/tools/status_monitor/console.py,sha256=UX3BzjjzeS_nKFGg4NkZJpu9fR_IAJZdQUMz0HcJCdg,5036
101
+ tonutils/tools/status_monitor/models.py,sha256=yHuiEuij4h2kVoOK3sbhNq6SwiGDW_evZmzUwMy1GQs,608
102
+ tonutils/tools/status_monitor/monitor.py,sha256=8zUwNwFScmcjK9ES7XX1LZWjw49lk8CSUQATcUYM57E,10085
103
+ tonutils-2.0.1b5.dist-info/licenses/LICENSE,sha256=fG-yM-8DSkOTaJ558P7uF5PNXBmineVO9-HC12YbIxs,1060
104
+ tonutils-2.0.1b5.dist-info/METADATA,sha256=1Wvi3Vlsb0IYwLaKlchY-OdFZ_TYNmHmZIzuyDQj55w,4181
105
+ tonutils-2.0.1b5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
106
+ tonutils-2.0.1b5.dist-info/entry_points.txt,sha256=qijo1cqvbbzLVbXp-PCYh19Pgmd7duH6yljmnUPd55I,47
107
+ tonutils-2.0.1b5.dist-info/top_level.txt,sha256=-7H_mGl8S9HKQrkUiTLmEbtMM-knzRzd_a0cZZnuZIU,9
108
+ tonutils-2.0.1b5.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tonutils = tonutils.cli:main