tonutils 2.0.1b6__py3-none-any.whl → 2.0.1b8__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.
- tonutils/__init__.py +8 -13
- tonutils/cli.py +1 -1
- tonutils/clients/adnl/balancer.py +132 -355
- tonutils/clients/adnl/client.py +32 -202
- tonutils/clients/adnl/mixin.py +268 -0
- tonutils/clients/adnl/provider/config.py +7 -20
- tonutils/clients/adnl/provider/provider.py +61 -16
- tonutils/clients/adnl/provider/transport.py +13 -4
- tonutils/clients/adnl/provider/workers/pinger.py +1 -1
- tonutils/clients/adnl/utils.py +5 -5
- tonutils/clients/base.py +52 -92
- tonutils/clients/http/balancer.py +93 -90
- tonutils/clients/http/clients/tatum.py +1 -0
- tonutils/clients/http/clients/tonapi.py +12 -24
- tonutils/clients/http/clients/toncenter.py +15 -33
- tonutils/clients/http/provider/base.py +75 -60
- tonutils/clients/http/provider/models.py +1 -1
- tonutils/clients/http/provider/tonapi.py +0 -5
- tonutils/clients/http/provider/toncenter.py +4 -8
- tonutils/clients/protocol.py +6 -6
- tonutils/contracts/__init__.py +3 -0
- tonutils/contracts/base.py +32 -32
- tonutils/contracts/protocol.py +9 -9
- tonutils/contracts/telegram/tlb.py +1 -1
- tonutils/contracts/wallet/__init__.py +4 -0
- tonutils/contracts/wallet/base.py +5 -5
- tonutils/contracts/wallet/tlb.py +18 -16
- tonutils/contracts/wallet/versions/v5.py +6 -6
- tonutils/exceptions.py +45 -102
- tonutils/tools/block_scanner/__init__.py +5 -1
- tonutils/tools/block_scanner/scanner.py +1 -1
- tonutils/tools/status_monitor/monitor.py +6 -6
- tonutils/types.py +24 -10
- tonutils/utils.py +47 -7
- {tonutils-2.0.1b6.dist-info → tonutils-2.0.1b8.dist-info}/METADATA +3 -20
- {tonutils-2.0.1b6.dist-info → tonutils-2.0.1b8.dist-info}/RECORD +40 -46
- {tonutils-2.0.1b6.dist-info → tonutils-2.0.1b8.dist-info}/WHEEL +1 -1
- tonutils/__meta__.py +0 -1
- tonutils/tonconnect/__init__.py +0 -0
- tonutils/tonconnect/bridge/__init__.py +0 -0
- tonutils/tonconnect/events.py +0 -0
- tonutils/tonconnect/models/__init__.py +0 -0
- tonutils/tonconnect/storage.py +0 -0
- tonutils/tonconnect/tonconnect.py +0 -0
- {tonutils-2.0.1b6.dist-info → tonutils-2.0.1b8.dist-info}/entry_points.txt +0 -0
- {tonutils-2.0.1b6.dist-info → tonutils-2.0.1b8.dist-info}/licenses/LICENSE +0 -0
- {tonutils-2.0.1b6.dist-info → tonutils-2.0.1b8.dist-info}/top_level.txt +0 -0
tonutils/exceptions.py
CHANGED
|
@@ -23,147 +23,99 @@ class TonutilsError(Exception):
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class TransportError(TonutilsError):
|
|
26
|
-
"""Transport-level failure
|
|
26
|
+
"""Transport-level failure (connect/handshake/send/recv)."""
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
:param endpoint: Server address as "host:port"
|
|
31
|
-
:param operation: What was attempted ("connect", "handshake", "send", "recv")
|
|
32
|
-
:param reason: Why it failed ("timeout 2.0s", "connection refused", etc.)
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
endpoint: str
|
|
36
|
-
operation: str
|
|
37
|
-
reason: str
|
|
38
|
-
|
|
39
|
-
def __init__(
|
|
40
|
-
self,
|
|
41
|
-
*,
|
|
42
|
-
endpoint: str,
|
|
43
|
-
operation: str,
|
|
44
|
-
reason: str,
|
|
45
|
-
) -> None:
|
|
28
|
+
def __init__(self, *, endpoint: str, operation: str, reason: str) -> None:
|
|
46
29
|
self.endpoint = endpoint
|
|
47
30
|
self.operation = operation
|
|
48
31
|
self.reason = reason
|
|
49
|
-
super().__init__(f"{operation} failed
|
|
32
|
+
super().__init__(f"{operation} failed: {reason} ({endpoint})")
|
|
50
33
|
|
|
51
34
|
|
|
52
35
|
class ProviderError(TonutilsError):
|
|
53
|
-
"""
|
|
36
|
+
"""Provider-level failure (protocol/parsing/backend/state)."""
|
|
54
37
|
|
|
55
38
|
|
|
56
39
|
class ClientError(TonutilsError):
|
|
57
|
-
"""
|
|
40
|
+
"""Client misuse, validation errors, or unsupported operations."""
|
|
58
41
|
|
|
59
42
|
|
|
60
43
|
class BalancerError(TonutilsError):
|
|
61
|
-
"""
|
|
44
|
+
"""Balancer failure (no alive backends, failover exhausted)."""
|
|
62
45
|
|
|
63
46
|
|
|
64
47
|
class NotConnectedError(TonutilsError, RuntimeError):
|
|
65
|
-
"""
|
|
66
|
-
|
|
67
|
-
endpoint: t.Optional[str]
|
|
48
|
+
"""Raised when an operation requires an active connection."""
|
|
68
49
|
|
|
69
|
-
def __init__(
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
*,
|
|
53
|
+
component: str = "client",
|
|
54
|
+
endpoint: t.Optional[str] = None,
|
|
55
|
+
operation: t.Optional[str] = None,
|
|
56
|
+
) -> None:
|
|
57
|
+
self.component = component
|
|
70
58
|
self.endpoint = endpoint
|
|
71
|
-
|
|
72
|
-
super().__init__(f"not connected to {endpoint}")
|
|
73
|
-
else:
|
|
74
|
-
super().__init__("not connected")
|
|
75
|
-
|
|
59
|
+
self.operation = operation
|
|
76
60
|
|
|
77
|
-
|
|
78
|
-
|
|
61
|
+
op = f"cannot `{operation}`: " if operation else ""
|
|
62
|
+
where = f" ({endpoint})" if endpoint else ""
|
|
63
|
+
super().__init__(f"{op}{component} is not connected{where}")
|
|
79
64
|
|
|
80
|
-
:param timeout: Timeout in seconds.
|
|
81
|
-
:param endpoint: Endpoint identifier (URL or host:port).
|
|
82
|
-
:param operation: Operation label (e.g. "request", "connect").
|
|
83
|
-
"""
|
|
84
65
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
operation: str
|
|
66
|
+
class ProviderTimeoutError(ProviderError, asyncio.TimeoutError):
|
|
67
|
+
"""Provider operation exceeded its timeout."""
|
|
88
68
|
|
|
89
69
|
def __init__(self, *, timeout: float, endpoint: str, operation: str) -> None:
|
|
90
|
-
self.timeout = timeout
|
|
70
|
+
self.timeout = float(timeout)
|
|
91
71
|
self.endpoint = endpoint
|
|
92
72
|
self.operation = operation
|
|
93
|
-
super().__init__(f"{operation} timed out after {timeout}s
|
|
73
|
+
super().__init__(f"{operation} timed out after {self.timeout}s ({endpoint})")
|
|
94
74
|
|
|
95
75
|
|
|
96
76
|
class ProviderResponseError(ProviderError):
|
|
97
|
-
"""
|
|
98
|
-
|
|
99
|
-
:param code: Backend code (HTTP status or lite-server code).
|
|
100
|
-
:param message: Backend error description.
|
|
101
|
-
:param endpoint: Endpoint identifier (URL or host:port).
|
|
102
|
-
"""
|
|
103
|
-
|
|
104
|
-
code: int
|
|
105
|
-
message: str
|
|
106
|
-
endpoint: str
|
|
77
|
+
"""Backend returned an error response."""
|
|
107
78
|
|
|
108
79
|
def __init__(self, *, code: int, message: str, endpoint: str) -> None:
|
|
109
|
-
self.code = code
|
|
80
|
+
self.code = int(code)
|
|
110
81
|
self.message = message
|
|
111
82
|
self.endpoint = endpoint
|
|
112
|
-
super().__init__(f"request failed
|
|
83
|
+
super().__init__(f"request failed: {self.code} {self.message} ({endpoint})")
|
|
113
84
|
|
|
114
85
|
|
|
115
86
|
class RetryLimitError(ProviderError):
|
|
116
|
-
"""
|
|
117
|
-
|
|
118
|
-
:param attempts: Attempts already performed for the matched rule.
|
|
119
|
-
:param max_attempts: Maximum attempts allowed by the matched rule.
|
|
120
|
-
:param last_error: Last provider error that triggered a retry.
|
|
121
|
-
"""
|
|
122
|
-
|
|
123
|
-
attempts: int
|
|
124
|
-
max_attempts: int
|
|
125
|
-
last_error: ProviderError
|
|
87
|
+
"""Retry policy exhausted."""
|
|
126
88
|
|
|
127
89
|
def __init__(
|
|
128
90
|
self,
|
|
129
|
-
*,
|
|
130
91
|
attempts: int,
|
|
131
92
|
max_attempts: int,
|
|
132
93
|
last_error: ProviderError,
|
|
133
94
|
) -> None:
|
|
134
|
-
self.attempts = attempts
|
|
135
|
-
self.max_attempts = max_attempts
|
|
95
|
+
self.attempts = int(attempts)
|
|
96
|
+
self.max_attempts = int(max_attempts)
|
|
136
97
|
self.last_error = last_error
|
|
137
|
-
|
|
98
|
+
ratio = f"{self.attempts}/{self.max_attempts}"
|
|
99
|
+
super().__init__(f"retry limit reached {ratio}: {last_error}")
|
|
138
100
|
|
|
139
101
|
|
|
140
102
|
class ContractError(ClientError):
|
|
141
|
-
"""
|
|
142
|
-
|
|
143
|
-
:param target: Contract instance or contract class related to the failure.
|
|
144
|
-
:param message: Human-readable error message.
|
|
145
|
-
"""
|
|
146
|
-
|
|
147
|
-
target: t.Any
|
|
148
|
-
message: str
|
|
103
|
+
"""Contract wrapper operation failed."""
|
|
149
104
|
|
|
150
|
-
def __init__(self, target: t.Any,
|
|
105
|
+
def __init__(self, target: t.Any, details: str) -> None:
|
|
151
106
|
self.target = target
|
|
152
|
-
self.
|
|
153
|
-
name = (
|
|
154
|
-
target.__name__ if isinstance(target, type) else target.__class__.__name__
|
|
155
|
-
)
|
|
156
|
-
super().__init__(f"{name}: {message}")
|
|
107
|
+
self.details = details
|
|
157
108
|
|
|
109
|
+
if isinstance(target, type):
|
|
110
|
+
name = target.__name__
|
|
111
|
+
else:
|
|
112
|
+
name = target.__class__.__name__
|
|
158
113
|
|
|
159
|
-
|
|
160
|
-
"""Raise when a contract wrapper requires state that is not loaded.
|
|
114
|
+
super().__init__(f"{name} failed: {details}")
|
|
161
115
|
|
|
162
|
-
:param contract: Contract instance related to the failure.
|
|
163
|
-
:param missing: Missing field name (e.g. "state_info", "state_data").
|
|
164
|
-
"""
|
|
165
116
|
|
|
166
|
-
|
|
117
|
+
class StateNotLoadedError(ContractError):
|
|
118
|
+
"""Contract wrapper requires state that is not loaded."""
|
|
167
119
|
|
|
168
120
|
def __init__(self, contract: t.Any, *, missing: str) -> None:
|
|
169
121
|
self.missing = missing
|
|
@@ -172,23 +124,14 @@ class StateNotLoadedError(ContractError):
|
|
|
172
124
|
|
|
173
125
|
|
|
174
126
|
class RunGetMethodError(ClientError):
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
-
:param address: Contract address (string form).
|
|
178
|
-
:param method_name: Get-method name.
|
|
179
|
-
:param exit_code: TVM exit code.
|
|
180
|
-
"""
|
|
181
|
-
|
|
182
|
-
address: str
|
|
183
|
-
method_name: str
|
|
184
|
-
exit_code: int
|
|
127
|
+
"""Contract get-method returned a non-zero TVM exit code."""
|
|
185
128
|
|
|
186
|
-
def __init__(self, *, address: str,
|
|
129
|
+
def __init__(self, *, address: str, exit_code: int, method_name: str) -> None:
|
|
187
130
|
self.address = address
|
|
131
|
+
self.exit_code = int(exit_code)
|
|
188
132
|
self.method_name = method_name
|
|
189
|
-
self.exit_code = exit_code
|
|
190
133
|
super().__init__(
|
|
191
|
-
f"get-method
|
|
134
|
+
f"get-method `{method_name}` failed: exit code {self.exit_code} ({address})"
|
|
192
135
|
)
|
|
193
136
|
|
|
194
137
|
|
|
@@ -237,7 +237,7 @@ class BlockScanner:
|
|
|
237
237
|
if self._on_transactions is None:
|
|
238
238
|
continue
|
|
239
239
|
|
|
240
|
-
get_block_transactions = self._client.
|
|
240
|
+
get_block_transactions = self._client.get_block_transactions
|
|
241
241
|
try:
|
|
242
242
|
transactions = await get_block_transactions(shard_block)
|
|
243
243
|
except asyncio.CancelledError:
|
|
@@ -114,7 +114,7 @@ class LiteServerMonitor:
|
|
|
114
114
|
self._tasks.append(asyncio.create_task(slow))
|
|
115
115
|
|
|
116
116
|
async def _ensure_connected(self, index: int, client: LiteClient) -> bool:
|
|
117
|
-
if client.provider.
|
|
117
|
+
if client.provider.connected:
|
|
118
118
|
return True
|
|
119
119
|
|
|
120
120
|
now = time.monotonic()
|
|
@@ -124,7 +124,7 @@ class LiteServerMonitor:
|
|
|
124
124
|
|
|
125
125
|
self._last_connect[index] = now
|
|
126
126
|
await self._connect(index, client)
|
|
127
|
-
return client.provider.
|
|
127
|
+
return client.provider.connected
|
|
128
128
|
|
|
129
129
|
async def _fast_update_loop(self, index: int, client: LiteClient) -> None:
|
|
130
130
|
while not self._stop.is_set():
|
|
@@ -141,7 +141,7 @@ class LiteServerMonitor:
|
|
|
141
141
|
|
|
142
142
|
async def _medium_update_loop(self, index: int, client: LiteClient) -> None:
|
|
143
143
|
while not self._stop.is_set():
|
|
144
|
-
if not client.
|
|
144
|
+
if not client.connected:
|
|
145
145
|
await self._sleep(1.0)
|
|
146
146
|
continue
|
|
147
147
|
|
|
@@ -154,7 +154,7 @@ class LiteServerMonitor:
|
|
|
154
154
|
|
|
155
155
|
async def _slow_update_loop(self, index: int, client: LiteClient) -> None:
|
|
156
156
|
while not self._stop.is_set():
|
|
157
|
-
if not client.
|
|
157
|
+
if not client.connected:
|
|
158
158
|
await self._sleep(1.0)
|
|
159
159
|
continue
|
|
160
160
|
|
|
@@ -223,14 +223,14 @@ class LiteServerMonitor:
|
|
|
223
223
|
return
|
|
224
224
|
|
|
225
225
|
mc_txs, shards = await asyncio.gather(
|
|
226
|
-
client.
|
|
226
|
+
client.get_block_transactions(mc_block),
|
|
227
227
|
client.get_all_shards_info(mc_block),
|
|
228
228
|
)
|
|
229
229
|
last_mc_block = BlockInfo(seqno=mc_block.seqno, txs_count=len(mc_txs))
|
|
230
230
|
|
|
231
231
|
if shards:
|
|
232
232
|
bc_block = max(shards, key=lambda b: b.seqno)
|
|
233
|
-
bc_txs = await client.
|
|
233
|
+
bc_txs = await client.get_block_transactions(bc_block)
|
|
234
234
|
last_bc_block = BlockInfo(seqno=bc_block.seqno, txs_count=len(bc_txs))
|
|
235
235
|
await self._set_status(
|
|
236
236
|
index,
|
tonutils/types.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import base64
|
|
4
|
+
import re
|
|
4
5
|
import typing as t
|
|
6
|
+
from contextlib import suppress
|
|
5
7
|
from dataclasses import dataclass
|
|
6
8
|
from enum import Enum
|
|
7
9
|
|
|
@@ -16,7 +18,7 @@ __all__ = [
|
|
|
16
18
|
"BinaryLike",
|
|
17
19
|
"ClientType",
|
|
18
20
|
"ContractState",
|
|
19
|
-
"
|
|
21
|
+
"ContractInfo",
|
|
20
22
|
"DNSCategory",
|
|
21
23
|
"DNSPrefix",
|
|
22
24
|
"MetadataPrefix",
|
|
@@ -189,7 +191,7 @@ class ContractState(str, Enum):
|
|
|
189
191
|
NONEXIST = "nonexist"
|
|
190
192
|
|
|
191
193
|
|
|
192
|
-
class
|
|
194
|
+
class ContractInfo:
|
|
193
195
|
"""
|
|
194
196
|
TON smart contract state information.
|
|
195
197
|
|
|
@@ -280,22 +282,34 @@ class Binary:
|
|
|
280
282
|
return self._size
|
|
281
283
|
|
|
282
284
|
def _parse(self, value: t.Any) -> bytes:
|
|
283
|
-
"""Parse input value into bytes."""
|
|
284
285
|
if isinstance(value, bytes):
|
|
285
286
|
return value
|
|
286
287
|
if isinstance(value, int):
|
|
287
288
|
length = max(1, (value.bit_length() + 7) // 8)
|
|
288
289
|
return value.to_bytes(length, "big")
|
|
290
|
+
|
|
289
291
|
if isinstance(value, str):
|
|
290
292
|
s = value.strip()
|
|
293
|
+
|
|
294
|
+
# 0x... hex
|
|
291
295
|
if s.lower().startswith("0x"):
|
|
292
|
-
return
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
296
|
+
return bytes.fromhex(s[2:])
|
|
297
|
+
|
|
298
|
+
# plain hex (common case for publicKey)
|
|
299
|
+
if len(s) % 2 == 0 and re.compile(r"^[0-9a-fA-F]+$").fullmatch(s):
|
|
300
|
+
if len(s) == self._size * 2:
|
|
301
|
+
return bytes.fromhex(s)
|
|
302
|
+
|
|
303
|
+
# base64 (strict)
|
|
304
|
+
with suppress(Exception):
|
|
305
|
+
b = base64.b64decode(s, validate=True)
|
|
306
|
+
return b
|
|
307
|
+
|
|
308
|
+
# decimal int as string fallback
|
|
309
|
+
n = int(s, 10)
|
|
310
|
+
length = max(1, (n.bit_length() + 7) // 8)
|
|
311
|
+
return n.to_bytes(length, "big")
|
|
312
|
+
|
|
299
313
|
raise ValueError(f"Invalid binary type: {type(value).__name__}.")
|
|
300
314
|
|
|
301
315
|
@property
|
tonutils/utils.py
CHANGED
|
@@ -5,9 +5,13 @@ import binascii
|
|
|
5
5
|
import decimal
|
|
6
6
|
import hashlib
|
|
7
7
|
import hmac
|
|
8
|
+
import json
|
|
8
9
|
import os
|
|
9
10
|
import time
|
|
10
11
|
import typing as t
|
|
12
|
+
import urllib.request
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from urllib.error import HTTPError, URLError
|
|
11
15
|
|
|
12
16
|
from Cryptodome.Cipher import AES
|
|
13
17
|
from nacl.bindings import (
|
|
@@ -40,6 +44,7 @@ __all__ = [
|
|
|
40
44
|
"cell_to_hex",
|
|
41
45
|
"decode_dns_name",
|
|
42
46
|
"encode_dns_name",
|
|
47
|
+
"load_json",
|
|
43
48
|
"maybe_stack_addr",
|
|
44
49
|
"norm_stack_cell",
|
|
45
50
|
"norm_stack_num",
|
|
@@ -387,15 +392,15 @@ class TextCipher:
|
|
|
387
392
|
if isinstance(payload, bytes):
|
|
388
393
|
return payload[:32], payload[32:48], payload[48:]
|
|
389
394
|
elif isinstance(payload, str):
|
|
395
|
+
# Try hex first; if that fails, try base64.
|
|
390
396
|
try:
|
|
391
|
-
|
|
397
|
+
data = bytes.fromhex(payload)
|
|
392
398
|
except ValueError:
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
return payload[:32], payload[32:48], payload[48:]
|
|
399
|
+
try:
|
|
400
|
+
data = base64.b64decode(payload, validate=True)
|
|
401
|
+
except (binascii.Error, ValueError):
|
|
402
|
+
raise ValueError("Invalid payload encoding: not hex or base64.")
|
|
403
|
+
return data[:32], data[32:48], data[48:]
|
|
399
404
|
|
|
400
405
|
cell = EncryptedTextCommentBody.deserialize(payload.begin_parse())
|
|
401
406
|
return cell.pub_xor, cell.msg_key, cell.ciphertext
|
|
@@ -501,3 +506,38 @@ class TextCipher:
|
|
|
501
506
|
|
|
502
507
|
comment = dec_data[padding_size:]
|
|
503
508
|
return comment.decode()
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def load_json(source: str, timeout: float = 5.0) -> t.Any:
|
|
512
|
+
"""
|
|
513
|
+
Load and parse JSON from a URL or a local file.
|
|
514
|
+
|
|
515
|
+
:param source: URL or file path
|
|
516
|
+
:param timeout: Network timeout in seconds
|
|
517
|
+
:return: Parsed JSON object
|
|
518
|
+
"""
|
|
519
|
+
try:
|
|
520
|
+
if source.startswith(("http://", "https://")):
|
|
521
|
+
req = urllib.request.Request(
|
|
522
|
+
source,
|
|
523
|
+
method="GET",
|
|
524
|
+
headers={
|
|
525
|
+
"User-Agent": "tonutils (+https://github.com/nessshon/tonutils)",
|
|
526
|
+
"Accept": "application/json,text/plain,*/*",
|
|
527
|
+
},
|
|
528
|
+
)
|
|
529
|
+
with urllib.request.urlopen(req, timeout=timeout) as r:
|
|
530
|
+
return json.loads(r.read().decode("utf-8"))
|
|
531
|
+
|
|
532
|
+
return json.loads(Path(source).read_text(encoding="utf-8"))
|
|
533
|
+
|
|
534
|
+
except HTTPError as e:
|
|
535
|
+
raise RuntimeError(f"JSON fetch failed: {e} ({source})") from e
|
|
536
|
+
except URLError as e:
|
|
537
|
+
raise RuntimeError(f"JSON fetch failed: {e.reason} ({source})") from e
|
|
538
|
+
except json.JSONDecodeError as e:
|
|
539
|
+
raise RuntimeError(f"JSON is invalid: {e.msg} ({source})") from e
|
|
540
|
+
except OSError as e:
|
|
541
|
+
raise RuntimeError(f"JSON read failed: {e} ({source})") from e
|
|
542
|
+
except Exception as e:
|
|
543
|
+
raise RuntimeError(f"JSON load failed: {e} ({source})") from e
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tonutils
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1b8
|
|
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
|
|
7
7
|
License-Expression: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/nessshon/tonutils/
|
|
9
|
-
Project-URL: Documentation, https://nessshon.github.io/tonutils/
|
|
10
|
-
Project-URL: Repository, https://github.com/nessshon/tonutils/
|
|
11
9
|
Project-URL: Examples, https://github.com/nessshon/tonutils/tree/main/examples/
|
|
12
10
|
Keywords: AsyncIO,TON,TON blockchain,The Open Network,blockchain,crypto,smart contracts
|
|
13
11
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -69,27 +67,13 @@ pip install --pre tonutils
|
|
|
69
67
|
|
|
70
68
|
## Usage
|
|
71
69
|
|
|
72
|
-
Practical feature examples can be found in the **[examples](examples)** directory
|
|
73
|
-
Each script demonstrates real-world usage and can be used as a reference when integrating `tonutils` into your project.
|
|
74
|
-
|
|
75
|
-
## Contribution
|
|
76
|
-
|
|
77
|
-
We welcome your contributions! If you have ideas for improvement or have identified a bug, please create an issue or
|
|
78
|
-
submit a pull request.
|
|
70
|
+
Practical feature examples can be found in the **[examples](examples)** directory.
|
|
79
71
|
|
|
80
72
|
## Donations
|
|
81
73
|
|
|
82
74
|
Your contributions help me continue developing and improving this project!
|
|
83
75
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- **BTC**: `1JXHbB5kE1DfkHdv5dsNygRkNC3unJdU8M`
|
|
87
|
-
|
|
88
|
-
- **USDT** (TRC-20): `TU4fCFdWufKb4rd25ihksiNDZZdyEYqro6`
|
|
89
|
-
|
|
90
|
-
- **Crypto Bot**: [Donate through Crypto Bot](https://t.me/send?start=IVW1cyG3DYqG)
|
|
91
|
-
|
|
92
|
-
- **xRocket Bot**: [Donate through xRocket](https://t.me/xrocket?start=inv_R4llrClZtPjovVe)
|
|
76
|
+
**TON**: `UQCZq3_Vd21-4y4m7Wc-ej9NFOhh_qvdfAkAYAOHoQ__Ness`
|
|
93
77
|
|
|
94
78
|
## Support
|
|
95
79
|
|
|
@@ -99,4 +83,3 @@ With special thanks to [Igroman787](https://github.com/Igroman787) for the suppo
|
|
|
99
83
|
## License
|
|
100
84
|
|
|
101
85
|
This repository is distributed under the [MIT License](LICENSE).
|
|
102
|
-
Feel free to use, modify, and distribute the code in accordance with the terms of the license.
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
tonutils/__init__.py,sha256=
|
|
2
|
-
tonutils/
|
|
3
|
-
tonutils/
|
|
4
|
-
tonutils/exceptions.py,sha256=67jXCFPyOnVnd8EaqYg1osVIXg34VZX-aJHPunpc-oI,6462
|
|
1
|
+
tonutils/__init__.py,sha256=L-T_WYdCKByp5eNttc_saSyUumBCiupZNruAbbGxvxY,280
|
|
2
|
+
tonutils/cli.py,sha256=67QAK8NWr4BpC-zMua_iFs7w_O-6LrpSRR3jrhtHmpU,2636
|
|
3
|
+
tonutils/exceptions.py,sha256=atvVuRhbTMWMkQPzSFHVRQG2VRspsOEFN4mYZgt5mjk,4959
|
|
5
4
|
tonutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
tonutils/types.py,sha256=
|
|
7
|
-
tonutils/utils.py,sha256=
|
|
5
|
+
tonutils/types.py,sha256=XSW-9yOyN5xWtH3hbbNuD2N9AJTrTZZ3Cwqfx63S1Sc,14850
|
|
6
|
+
tonutils/utils.py,sha256=MjyZfz8i8r016vJxFCVj-59UnFaCxbJqWTZZARNPrVM,16542
|
|
8
7
|
tonutils/clients/__init__.py,sha256=F0aPLPOI8-HcqcweeCSG_fr2VArxiZxfsWHuzHDwE4k,521
|
|
9
|
-
tonutils/clients/base.py,sha256=
|
|
8
|
+
tonutils/clients/base.py,sha256=FHKDJCUDNoLUuE4W0J3SGEtgJudW_6zFIAaP6zTKr_4,8207
|
|
10
9
|
tonutils/clients/limiter.py,sha256=lSUo6AhEuWUlo0y2sUc-P4YltRI2zjbicelYKkMTrls,3896
|
|
11
|
-
tonutils/clients/protocol.py,sha256=
|
|
10
|
+
tonutils/clients/protocol.py,sha256=JCd0lBZwrosogmc4rQ5mmL_oBy3XYQoX_d2wyson0lU,2534
|
|
12
11
|
tonutils/clients/adnl/__init__.py,sha256=shkczPIYlTrOHjpnOBIoRwEYRQ4rVGfLnOZvnQY0a5U,174
|
|
13
|
-
tonutils/clients/adnl/balancer.py,sha256=
|
|
14
|
-
tonutils/clients/adnl/client.py,sha256=
|
|
15
|
-
tonutils/clients/adnl/
|
|
12
|
+
tonutils/clients/adnl/balancer.py,sha256=DoMiFtLA4rrCYeyhiFuhlxVBZbffttq9ewrFPSDEnKo,19917
|
|
13
|
+
tonutils/clients/adnl/client.py,sha256=2tUr6YxxoNXdc0c0iRkyT1xpZkIKIM-DwgNTKJn-qMo,8994
|
|
14
|
+
tonutils/clients/adnl/mixin.py,sha256=GVakCui_0yso0VCOsycZsvq55Ng6JyIdotrQ_0bIohM,8260
|
|
15
|
+
tonutils/clients/adnl/utils.py,sha256=pyrU0vLuR9qnOFlHtheOfch8u1FP4Q_5Ah2UuX_m7Jk,5129
|
|
16
16
|
tonutils/clients/adnl/provider/__init__.py,sha256=lLwFEEgCifMlYozwSzQbvq97R6Du7TzgGFnTgUnk4gw,63
|
|
17
|
-
tonutils/clients/adnl/provider/config.py,sha256=
|
|
17
|
+
tonutils/clients/adnl/provider/config.py,sha256=phylkEdmKtfJWp9VgOYpzTuG4SUIHV7G42rYfqcgfDU,943
|
|
18
18
|
tonutils/clients/adnl/provider/models.py,sha256=3dn4oZv7PIgiwlP2lGs0O6VckC19ejxCFlSPhzU0wX8,4537
|
|
19
|
-
tonutils/clients/adnl/provider/provider.py,sha256=
|
|
20
|
-
tonutils/clients/adnl/provider/transport.py,sha256=
|
|
19
|
+
tonutils/clients/adnl/provider/provider.py,sha256=J7wIGtv_ZeS5j6AdYafAQ0m3q4z8Sd5V_LcpfeSi7JM,25633
|
|
20
|
+
tonutils/clients/adnl/provider/transport.py,sha256=bT_a7h0nCBGKCfPNOg79CW04UIdyZCfQ_7-nFvpfWK0,11241
|
|
21
21
|
tonutils/clients/adnl/provider/workers/__init__.py,sha256=M65q7mVfinHImIZNCEaHBJ-SO4DdVBsSkeZFrJs9OoE,177
|
|
22
22
|
tonutils/clients/adnl/provider/workers/base.py,sha256=8RenR2MU_B-b8mevzCytLJmPgjLCJ8bVI-4q-wx78Q8,2031
|
|
23
|
-
tonutils/clients/adnl/provider/workers/pinger.py,sha256=
|
|
23
|
+
tonutils/clients/adnl/provider/workers/pinger.py,sha256=ndA2ToCiukTav0s1mVrUwfFEjxdK9Wucq5ONxB1wpAw,2440
|
|
24
24
|
tonutils/clients/adnl/provider/workers/reader.py,sha256=qvkaBBrRNu_nLTQOd0w6lDdN_wPOnzPbfAa3UToJWd8,1944
|
|
25
25
|
tonutils/clients/adnl/provider/workers/updater.py,sha256=r7NrZXDg3nY4jAF-sYkX1ZvxTE8sN99qSFctbAmHTME,1978
|
|
26
26
|
tonutils/clients/http/__init__.py,sha256=M05D4r8sLZk1dY_LZa6-LhPZdzCzyCJ3MJnCxwE9xk8,435
|
|
27
|
-
tonutils/clients/http/balancer.py,sha256=
|
|
27
|
+
tonutils/clients/http/balancer.py,sha256=AdK9hHAreQJginHxpjIG9fhQiMOQq-wCsgby1jMsqII,12539
|
|
28
28
|
tonutils/clients/http/utils.py,sha256=mv9kCwLu8qjayy03E524WZ3q7Zf96t5VCE6H9j5kHRE,4994
|
|
29
29
|
tonutils/clients/http/clients/__init__.py,sha256=RpoIk4KaVC3pBlxkatSozMN6cMY_UW1cR8PxA1d0Xyo,307
|
|
30
30
|
tonutils/clients/http/clients/chainstack.py,sha256=U_UaEDM8_KB8SHRA6l22utDfGqZ4dLvKJ-VLgbg86s0,1737
|
|
31
31
|
tonutils/clients/http/clients/quicknode.py,sha256=TZOwVZTLjTHHd1OiOZkdAzkM91vyX6_1vEV-bUqCjmE,1655
|
|
32
|
-
tonutils/clients/http/clients/tatum.py,sha256=
|
|
33
|
-
tonutils/clients/http/clients/tonapi.py,sha256=
|
|
34
|
-
tonutils/clients/http/clients/toncenter.py,sha256=
|
|
32
|
+
tonutils/clients/http/clients/tatum.py,sha256=2REsdMDwedvM_Fq8fBICPGJfxHxEkEnJ21QeOj2OYQ8,2014
|
|
33
|
+
tonutils/clients/http/clients/tonapi.py,sha256=3uWV9hQef5Yo57VYX2Lg_JM8XJcfzCdpXHJQaWU-_lg,5388
|
|
34
|
+
tonutils/clients/http/clients/toncenter.py,sha256=MhVyUVd_4NFcqJ1dVuZAy_DJZ2J58_mWcSLJXFY-sL4,7780
|
|
35
35
|
tonutils/clients/http/provider/__init__.py,sha256=V4JOQuTqLU7taZojxvXo0yVAXESbbyQR9O5iDPyp5x8,154
|
|
36
|
-
tonutils/clients/http/provider/base.py,sha256=
|
|
37
|
-
tonutils/clients/http/provider/models.py,sha256=
|
|
38
|
-
tonutils/clients/http/provider/tonapi.py,sha256=
|
|
39
|
-
tonutils/clients/http/provider/toncenter.py,sha256=
|
|
40
|
-
tonutils/contracts/__init__.py,sha256=
|
|
41
|
-
tonutils/contracts/base.py,sha256=
|
|
36
|
+
tonutils/clients/http/provider/base.py,sha256=JqhtFwLLGyTbTVXO6V8_TJf-nZtYjFrSXR4OZPhQXNY,8867
|
|
37
|
+
tonutils/clients/http/provider/models.py,sha256=HFB3xL9B7DHdahw9-qCdMv0pVCvOsVaklTM0Yz0pU-M,3510
|
|
38
|
+
tonutils/clients/http/provider/tonapi.py,sha256=IgEiz8VwZ3rKLAVB8Aq3RxUDcC2HMD2NIX4m_j1tk6U,3495
|
|
39
|
+
tonutils/clients/http/provider/toncenter.py,sha256=m_wLe778ibe0LMFBV2iIuULbrSxSoPOd-OmTNSXm5lE,3461
|
|
40
|
+
tonutils/contracts/__init__.py,sha256=vlvrI_Xsa-tt4dZW3YMz2ezJLL50T8OweHmxpFc3Mkc,9625
|
|
41
|
+
tonutils/contracts/base.py,sha256=CvTKWVJEvm07HThCenJ0T-QDYne_CgRD02Nyo29Exfg,10332
|
|
42
42
|
tonutils/contracts/codes.py,sha256=1Sbbs_izHZHd-i1cjWHRP8VN3Xc2BDPr4pnjojj6mZc,37741
|
|
43
43
|
tonutils/contracts/opcodes.py,sha256=niPd-pDmtXiEpYX8xvorFmd7O4vkY0i8nX71e3iaJ1s,1001
|
|
44
|
-
tonutils/contracts/protocol.py,sha256=
|
|
44
|
+
tonutils/contracts/protocol.py,sha256=Z4EdZn4J_TixBRpXfakt73FSM4B4Gnqh1UQ49ybT6wQ,6193
|
|
45
45
|
tonutils/contracts/versions.py,sha256=V1rJECQSQuAVYwDmXl4lZzLzDeqZ9OChOgipzAlTPQE,1705
|
|
46
46
|
tonutils/contracts/dns/__init__.py,sha256=H57OtOeohbQlcNTHZS5YI7wtZjlqlpKg4wVso2kPRrU,987
|
|
47
47
|
tonutils/contracts/dns/collection.py,sha256=wSpKGOyCnmXBq1IITjjq5oOt2OZO3u5ckibDcacbJ9I,3089
|
|
@@ -62,19 +62,19 @@ tonutils/contracts/telegram/__init__.py,sha256=nr0O0rzr2UJu1KrtrqbBqLOuUfMSLSWo4
|
|
|
62
62
|
tonutils/contracts/telegram/collection.py,sha256=CM3T_8eWmrO_Ovq-crZgesfJ4h6JV4DhyggjV6nBY-U,3925
|
|
63
63
|
tonutils/contracts/telegram/item.py,sha256=DhNs5WFjhI1vqMfUg-cm311JTIvSaznc3aTqtLOCr9w,3887
|
|
64
64
|
tonutils/contracts/telegram/methods.py,sha256=rcZsEYTDwbT92NFhBhs-8TYruQWmxYgF6KElvaRnJPg,4403
|
|
65
|
-
tonutils/contracts/telegram/tlb.py,sha256=
|
|
65
|
+
tonutils/contracts/telegram/tlb.py,sha256=TXbQfQT7OEjeoahHAavvZBCEq79qFWuVsyL5rllMXiI,17849
|
|
66
66
|
tonutils/contracts/vanity/__init__.py,sha256=6LvJQxpmtrE3-ju44IsrkYQTx4HSq8nRb3fLyJFwrgE,288
|
|
67
67
|
tonutils/contracts/vanity/models.py,sha256=B6W1TN4CyrMs4SfBDAjuQ8QP-wn5QFhNpcSzO99DCbY,815
|
|
68
68
|
tonutils/contracts/vanity/tlb.py,sha256=gcNYEGPWMUHYbg_Je9QbBUlmVXF5RmobL-FoCMCF1HA,1078
|
|
69
69
|
tonutils/contracts/vanity/vanity.py,sha256=uYH1zybcOTQQBPciUFxAS6wksBwawKx06YES2tLuguI,1242
|
|
70
|
-
tonutils/contracts/wallet/__init__.py,sha256=
|
|
71
|
-
tonutils/contracts/wallet/base.py,sha256=
|
|
70
|
+
tonutils/contracts/wallet/__init__.py,sha256=vNw1tj8sN9jgd_FK2Bclphqi3x5nyFHozHttldWRLFg,3383
|
|
71
|
+
tonutils/contracts/wallet/base.py,sha256=Ue0WMTtjQ55s3o1_67KHdqGIsjjFrgdoLjCiMwA1y1Q,15806
|
|
72
72
|
tonutils/contracts/wallet/configs.py,sha256=yQfuCEGL_fBuc5qGJ93rPIUATTR8V1wpYscgrWb7cEQ,4082
|
|
73
73
|
tonutils/contracts/wallet/messages.py,sha256=MDzM3HdRYIc_vhmsjeHZcF9z1zpcfSdSh3_s4ecSx7o,13610
|
|
74
74
|
tonutils/contracts/wallet/methods.py,sha256=x7aPt71v3PUFNYHStWQrjLK7_SWPC2MiTG0c15X5TRI,10732
|
|
75
75
|
tonutils/contracts/wallet/params.py,sha256=hqinZJmhWiZUywDcmolvRxB0HYJgMAPDWYJiTmgjZ7w,4569
|
|
76
76
|
tonutils/contracts/wallet/protocol.py,sha256=DCu3CNbcZJ_wwROEK3GlpnwxNY2ZLdE0D2Z23WiyVDY,6200
|
|
77
|
-
tonutils/contracts/wallet/tlb.py,sha256=
|
|
77
|
+
tonutils/contracts/wallet/tlb.py,sha256=RzUcHTzFPnf19ajt_WP3_17c4xKVCu_c8cLOgBZBsy8,21738
|
|
78
78
|
tonutils/contracts/wallet/versions/__init__.py,sha256=DOHAEpx1mOlHdyTg2K0Mj8ZkcjabSdpLvIQY9_Pk6gw,592
|
|
79
79
|
tonutils/contracts/wallet/versions/hw.py,sha256=9kc_mlCegBo1O4_MvRQGLE3ZqLHsvqGN2F1IgnJeBOE,8348
|
|
80
80
|
tonutils/contracts/wallet/versions/pp.py,sha256=QfTqd4TAJHFMuatIwe0lg80uixno2JqSZFmQboxhca0,3793
|
|
@@ -82,25 +82,19 @@ tonutils/contracts/wallet/versions/v1.py,sha256=BYRWXdM0OlSeCfayHAUBj_wM4bb3WTVY
|
|
|
82
82
|
tonutils/contracts/wallet/versions/v2.py,sha256=pwrlan-utZo_WmnzDwSbnzV8ibkPEWx2WU1uOjkdrrA,2452
|
|
83
83
|
tonutils/contracts/wallet/versions/v3.py,sha256=d7cM8wjmW-1H7jGuY3AuUd7eTY3wq9ZYpJ4f5OeYX08,2470
|
|
84
84
|
tonutils/contracts/wallet/versions/v4.py,sha256=2sAsjJ8_3oYAj5JwWH3PiMyoGbgl6-f7-p6T5X7MGTI,2713
|
|
85
|
-
tonutils/contracts/wallet/versions/v5.py,sha256
|
|
86
|
-
tonutils/tonconnect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
|
-
tonutils/tonconnect/events.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
88
|
-
tonutils/tonconnect/storage.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
89
|
-
tonutils/tonconnect/tonconnect.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
90
|
-
tonutils/tonconnect/bridge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
91
|
-
tonutils/tonconnect/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
|
+
tonutils/contracts/wallet/versions/v5.py,sha256=-JjuFgLjKQIlKjr5RsUZ-qMWlkUs1y02t1n_4QSQkrk,8832
|
|
92
86
|
tonutils/tools/__init__.py,sha256=QYOVuGY50FFkWlgIvHc2RPU3xiEWSbwnwZ6wuZPQnCA,102
|
|
93
|
-
tonutils/tools/block_scanner/__init__.py,sha256=
|
|
87
|
+
tonutils/tools/block_scanner/__init__.py,sha256=yYARZYo4LlePo7DWrrYlejGE4NLInfNeU9Ipln8oFFA,209
|
|
94
88
|
tonutils/tools/block_scanner/events.py,sha256=02K85PR3Jfe6qK-Ve1Mbukk4AWkxCJv1d-C-0tGdH_s,1881
|
|
95
|
-
tonutils/tools/block_scanner/scanner.py,sha256=
|
|
89
|
+
tonutils/tools/block_scanner/scanner.py,sha256=abGhDbLUsdfzp9ipMpGpsdovIakP_ISfABTML4cPpck,14166
|
|
96
90
|
tonutils/tools/block_scanner/storage.py,sha256=7Kw6rdyLkPpBF5Y1mp2qkVZLnexyPumv2hMl9gNk_EI,357
|
|
97
91
|
tonutils/tools/status_monitor/__init__.py,sha256=QnMlA0IDLtCGgXsEgB9q3EJTBo2s5js6lSJk0oZkQZQ,72
|
|
98
92
|
tonutils/tools/status_monitor/console.py,sha256=UX3BzjjzeS_nKFGg4NkZJpu9fR_IAJZdQUMz0HcJCdg,5036
|
|
99
93
|
tonutils/tools/status_monitor/models.py,sha256=yHuiEuij4h2kVoOK3sbhNq6SwiGDW_evZmzUwMy1GQs,608
|
|
100
|
-
tonutils/tools/status_monitor/monitor.py,sha256=
|
|
101
|
-
tonutils-2.0.
|
|
102
|
-
tonutils-2.0.
|
|
103
|
-
tonutils-2.0.
|
|
104
|
-
tonutils-2.0.
|
|
105
|
-
tonutils-2.0.
|
|
106
|
-
tonutils-2.0.
|
|
94
|
+
tonutils/tools/status_monitor/monitor.py,sha256=OXs-J5RCUp4VbnBZuGd-4LythGUGakxwGSYM1Ipw-4s,10065
|
|
95
|
+
tonutils-2.0.1b8.dist-info/licenses/LICENSE,sha256=fG-yM-8DSkOTaJ558P7uF5PNXBmineVO9-HC12YbIxs,1060
|
|
96
|
+
tonutils-2.0.1b8.dist-info/METADATA,sha256=vvOdq7wiIe6Y-RlNzLykw1JvThRvJgTQAFzqLJNLt8w,3391
|
|
97
|
+
tonutils-2.0.1b8.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
98
|
+
tonutils-2.0.1b8.dist-info/entry_points.txt,sha256=qijo1cqvbbzLVbXp-PCYh19Pgmd7duH6yljmnUPd55I,47
|
|
99
|
+
tonutils-2.0.1b8.dist-info/top_level.txt,sha256=-7H_mGl8S9HKQrkUiTLmEbtMM-knzRzd_a0cZZnuZIU,9
|
|
100
|
+
tonutils-2.0.1b8.dist-info/RECORD,,
|
tonutils/__meta__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.0.1b6"
|
tonutils/tonconnect/__init__.py
DELETED
|
File without changes
|
|
File without changes
|
tonutils/tonconnect/events.py
DELETED
|
File without changes
|