tonutils 0.5.2__tar.gz → 0.6.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. {tonutils-0.5.2 → tonutils-0.6.0a1}/LICENSE +1 -1
  2. {tonutils-0.5.2/tonutils.egg-info → tonutils-0.6.0a1}/PKG-INFO +5 -10
  3. {tonutils-0.5.2 → tonutils-0.6.0a1}/README.md +3 -8
  4. {tonutils-0.5.2 → tonutils-0.6.0a1}/setup.py +2 -2
  5. tonutils-0.6.0a1/tests/tests_clients.py +94 -0
  6. tonutils-0.6.0a1/tests/tests_utils.py +230 -0
  7. {tonutils-0.5.2/tonutils/client → tonutils-0.6.0a1/tonutils/clients}/__init__.py +3 -11
  8. tonutils-0.6.0a1/tonutils/clients/base.py +95 -0
  9. tonutils-0.6.0a1/tonutils/clients/liteserver/__init__.py +3 -0
  10. tonutils-0.6.0a1/tonutils/clients/liteserver/client.py +155 -0
  11. tonutils-0.6.0a1/tonutils/clients/liteserver/stub.py +70 -0
  12. tonutils-0.6.0a1/tonutils/clients/quicknode/__init__.py +3 -0
  13. tonutils-0.6.0a1/tonutils/clients/quicknode/api.py +19 -0
  14. tonutils-0.6.0a1/tonutils/clients/quicknode/client.py +20 -0
  15. tonutils-0.6.0a1/tonutils/clients/tatum/__init__.py +3 -0
  16. tonutils-0.6.0a1/tonutils/clients/tatum/api.py +28 -0
  17. tonutils-0.6.0a1/tonutils/clients/tatum/client.py +24 -0
  18. tonutils-0.6.0a1/tonutils/clients/tonapi/__init__.py +3 -0
  19. tonutils-0.6.0a1/tonutils/clients/tonapi/api.py +93 -0
  20. tonutils-0.6.0a1/tonutils/clients/tonapi/client.py +146 -0
  21. tonutils-0.6.0a1/tonutils/clients/tonapi/models.py +34 -0
  22. tonutils-0.6.0a1/tonutils/clients/toncenter/__init__.py +3 -0
  23. tonutils-0.6.0a1/tonutils/clients/toncenter/api.py +91 -0
  24. tonutils-0.6.0a1/tonutils/clients/toncenter/client.py +200 -0
  25. tonutils-0.6.0a1/tonutils/clients/toncenter/models.py +70 -0
  26. tonutils-0.6.0a1/tonutils/contracts/__init__.py +55 -0
  27. tonutils-0.6.0a1/tonutils/contracts/base.py +155 -0
  28. tonutils-0.6.0a1/tonutils/contracts/codes.py +30 -0
  29. tonutils-0.6.0a1/tonutils/contracts/nft/__init__.py +21 -0
  30. tonutils-0.6.0a1/tonutils/contracts/nft/collection.py +116 -0
  31. tonutils-0.6.0a1/tonutils/contracts/nft/get_methods.py +124 -0
  32. tonutils-0.6.0a1/tonutils/contracts/nft/item.py +119 -0
  33. tonutils-0.6.0a1/tonutils/contracts/wallet/__init__.py +39 -0
  34. tonutils-0.6.0a1/tonutils/contracts/wallet/base.py +300 -0
  35. tonutils-0.6.0a1/tonutils/contracts/wallet/get_methods.py +145 -0
  36. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/__init__.py +45 -0
  37. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/hw.py +215 -0
  38. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/pp.py +88 -0
  39. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/v1.py +92 -0
  40. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/v2.py +81 -0
  41. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/v3.py +80 -0
  42. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/v4.py +102 -0
  43. tonutils-0.6.0a1/tonutils/contracts/wallet/versions/v5.py +236 -0
  44. tonutils-0.6.0a1/tonutils/exceptions.py +92 -0
  45. tonutils-0.6.0a1/tonutils/protocols/__init__.py +9 -0
  46. tonutils-0.6.0a1/tonutils/protocols/client.py +41 -0
  47. tonutils-0.6.0a1/tonutils/protocols/contract.py +99 -0
  48. tonutils-0.6.0a1/tonutils/protocols/wallet.py +116 -0
  49. tonutils-0.6.0a1/tonutils/types/__init__.py +187 -0
  50. tonutils-0.6.0a1/tonutils/types/client.py +7 -0
  51. tonutils-0.6.0a1/tonutils/types/common.py +39 -0
  52. tonutils-0.6.0a1/tonutils/types/configs.py +79 -0
  53. tonutils-0.6.0a1/tonutils/types/contract.py +79 -0
  54. tonutils-0.6.0a1/tonutils/types/keystructs.py +91 -0
  55. tonutils-0.6.0a1/tonutils/types/messages.py +142 -0
  56. tonutils-0.6.0a1/tonutils/types/opcodes.py +15 -0
  57. tonutils-0.6.0a1/tonutils/types/params.py +85 -0
  58. tonutils-0.6.0a1/tonutils/types/stack.py +17 -0
  59. tonutils-0.6.0a1/tonutils/types/tlb/__init__.py +87 -0
  60. tonutils-0.6.0a1/tonutils/types/tlb/content.py +156 -0
  61. tonutils-0.6.0a1/tonutils/types/tlb/contract.py +9 -0
  62. tonutils-0.6.0a1/tonutils/types/tlb/msg.py +36 -0
  63. tonutils-0.6.0a1/tonutils/types/tlb/nft.py +626 -0
  64. tonutils-0.6.0a1/tonutils/types/tlb/text.py +53 -0
  65. tonutils-0.6.0a1/tonutils/types/tlb/wallet.py +299 -0
  66. tonutils-0.6.0a1/tonutils/utils/__init__.py +51 -0
  67. tonutils-0.6.0a1/tonutils/utils/converters.py +58 -0
  68. tonutils-0.6.0a1/tonutils/utils/msg_builders.py +82 -0
  69. tonutils-0.6.0a1/tonutils/utils/parse_config.py +35 -0
  70. tonutils-0.6.0a1/tonutils/utils/stack_codec.py +188 -0
  71. tonutils-0.6.0a1/tonutils/utils/text_cipher.py +140 -0
  72. tonutils-0.6.0a1/tonutils/utils/validations.py +23 -0
  73. tonutils-0.6.0a1/tonutils/utils/value_utils.py +62 -0
  74. tonutils-0.6.0a1/tonutils/utils/wallet_utils.py +55 -0
  75. {tonutils-0.5.2 → tonutils-0.6.0a1/tonutils.egg-info}/PKG-INFO +5 -10
  76. tonutils-0.6.0a1/tonutils.egg-info/SOURCES.txt +81 -0
  77. {tonutils-0.5.2 → tonutils-0.6.0a1}/tonutils.egg-info/requires.txt +1 -1
  78. tonutils-0.5.2/tonutils/account.py +0 -32
  79. tonutils-0.5.2/tonutils/cache.py +0 -82
  80. tonutils-0.5.2/tonutils/client/_base.py +0 -292
  81. tonutils-0.5.2/tonutils/client/lite.py +0 -163
  82. tonutils-0.5.2/tonutils/client/quicknode.py +0 -33
  83. tonutils-0.5.2/tonutils/client/tatum.py +0 -50
  84. tonutils-0.5.2/tonutils/client/tonapi.py +0 -145
  85. tonutils-0.5.2/tonutils/client/toncenter.py +0 -303
  86. tonutils-0.5.2/tonutils/client/utils.py +0 -203
  87. tonutils-0.5.2/tonutils/contract.py +0 -184
  88. tonutils-0.5.2/tonutils/dns/__init__.py +0 -5
  89. tonutils-0.5.2/tonutils/dns/categories.py +0 -15
  90. tonutils-0.5.2/tonutils/dns/contract.py +0 -256
  91. tonutils-0.5.2/tonutils/dns/op_codes.py +0 -1
  92. tonutils-0.5.2/tonutils/dns/subdomain_collection/__init__.py +0 -5
  93. tonutils-0.5.2/tonutils/dns/subdomain_collection/content.py +0 -18
  94. tonutils-0.5.2/tonutils/dns/subdomain_collection/contract.py +0 -91
  95. tonutils-0.5.2/tonutils/dns/subdomain_collection/data.py +0 -63
  96. tonutils-0.5.2/tonutils/dns/subdomain_collection/op_codes.py +0 -5
  97. tonutils-0.5.2/tonutils/dns/subdomain_manager/__init__.py +0 -5
  98. tonutils-0.5.2/tonutils/dns/subdomain_manager/contract.py +0 -210
  99. tonutils-0.5.2/tonutils/dns/subdomain_manager/data.py +0 -38
  100. tonutils-0.5.2/tonutils/dns/subdomain_manager/op_codes.py +0 -1
  101. tonutils-0.5.2/tonutils/dns/utils.py +0 -115
  102. tonutils-0.5.2/tonutils/exceptions.py +0 -43
  103. tonutils-0.5.2/tonutils/jetton/__init__.py +0 -15
  104. tonutils-0.5.2/tonutils/jetton/content.py +0 -79
  105. tonutils-0.5.2/tonutils/jetton/contract/__init__.py +0 -10
  106. tonutils-0.5.2/tonutils/jetton/contract/base/__init__.py +0 -5
  107. tonutils-0.5.2/tonutils/jetton/contract/base/master.py +0 -76
  108. tonutils-0.5.2/tonutils/jetton/contract/stablecoin/__init__.py +0 -9
  109. tonutils-0.5.2/tonutils/jetton/contract/stablecoin/master.py +0 -215
  110. tonutils-0.5.2/tonutils/jetton/contract/stablecoin/op_codes.py +0 -17
  111. tonutils-0.5.2/tonutils/jetton/contract/stablecoin/wallet.py +0 -134
  112. tonutils-0.5.2/tonutils/jetton/contract/standard/__init__.py +0 -7
  113. tonutils-0.5.2/tonutils/jetton/contract/standard/master.py +0 -141
  114. tonutils-0.5.2/tonutils/jetton/contract/standard/op_codes.py +0 -11
  115. tonutils-0.5.2/tonutils/jetton/contract/standard/wallet.py +0 -132
  116. tonutils-0.5.2/tonutils/jetton/data.py +0 -165
  117. tonutils-0.5.2/tonutils/jetton/dex/dedust/__init__.py +0 -5
  118. tonutils-0.5.2/tonutils/jetton/dex/dedust/constants.py +0 -48
  119. tonutils-0.5.2/tonutils/jetton/dex/dedust/factory.py +0 -362
  120. tonutils-0.5.2/tonutils/jetton/dex/stonfi/__init__.py +0 -10
  121. tonutils-0.5.2/tonutils/jetton/dex/stonfi/utils.py +0 -47
  122. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v1/__init__.py +0 -7
  123. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v1/pton/__init__.py +0 -5
  124. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v1/pton/constants.py +0 -19
  125. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v1/pton/pton.py +0 -78
  126. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v1/router/__init__.py +0 -5
  127. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v1/router/constants.py +0 -38
  128. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v1/router/router.py +0 -193
  129. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v2/__init__.py +0 -7
  130. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v2/pton/__init__.py +0 -5
  131. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v2/pton/constants.py +0 -21
  132. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v2/pton/pton.py +0 -102
  133. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v2/router/__init__.py +0 -5
  134. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v2/router/constants.py +0 -41
  135. tonutils-0.5.2/tonutils/jetton/dex/stonfi/v2/router/router.py +0 -308
  136. tonutils-0.5.2/tonutils/nft/__init__.py +0 -22
  137. tonutils-0.5.2/tonutils/nft/content.py +0 -135
  138. tonutils-0.5.2/tonutils/nft/contract/__init__.py +0 -0
  139. tonutils-0.5.2/tonutils/nft/contract/base/__init__.py +0 -7
  140. tonutils-0.5.2/tonutils/nft/contract/base/collection.py +0 -80
  141. tonutils-0.5.2/tonutils/nft/contract/base/nft.py +0 -71
  142. tonutils-0.5.2/tonutils/nft/contract/editable/__init__.py +0 -9
  143. tonutils-0.5.2/tonutils/nft/contract/editable/collection.py +0 -341
  144. tonutils-0.5.2/tonutils/nft/contract/editable/nft.py +0 -155
  145. tonutils-0.5.2/tonutils/nft/contract/soulbound/__init__.py +0 -9
  146. tonutils-0.5.2/tonutils/nft/contract/soulbound/collection.py +0 -277
  147. tonutils-0.5.2/tonutils/nft/contract/soulbound/nft.py +0 -123
  148. tonutils-0.5.2/tonutils/nft/contract/standard/__init__.py +0 -9
  149. tonutils-0.5.2/tonutils/nft/contract/standard/collection.py +0 -257
  150. tonutils-0.5.2/tonutils/nft/contract/standard/nft.py +0 -78
  151. tonutils-0.5.2/tonutils/nft/data.py +0 -95
  152. tonutils-0.5.2/tonutils/nft/marketplace/__init__.py +0 -0
  153. tonutils-0.5.2/tonutils/nft/marketplace/getgems/__init__.py +0 -5
  154. tonutils-0.5.2/tonutils/nft/marketplace/getgems/addresses.py +0 -8
  155. tonutils-0.5.2/tonutils/nft/marketplace/getgems/contract/__init__.py +0 -5
  156. tonutils-0.5.2/tonutils/nft/marketplace/getgems/contract/salev3r3.py +0 -161
  157. tonutils-0.5.2/tonutils/nft/marketplace/getgems/data.py +0 -54
  158. tonutils-0.5.2/tonutils/nft/marketplace/getgems/op_codes.py +0 -7
  159. tonutils-0.5.2/tonutils/nft/op_codes.py +0 -19
  160. tonutils-0.5.2/tonutils/nft/royalty_params.py +0 -29
  161. tonutils-0.5.2/tonutils/tonconnect/__init__.py +0 -11
  162. tonutils-0.5.2/tonutils/tonconnect/connector.py +0 -699
  163. tonutils-0.5.2/tonutils/tonconnect/models/__init__.py +0 -53
  164. tonutils-0.5.2/tonutils/tonconnect/models/account.py +0 -57
  165. tonutils-0.5.2/tonutils/tonconnect/models/chain.py +0 -10
  166. tonutils-0.5.2/tonutils/tonconnect/models/device.py +0 -137
  167. tonutils-0.5.2/tonutils/tonconnect/models/event.py +0 -33
  168. tonutils-0.5.2/tonutils/tonconnect/models/proof.py +0 -80
  169. tonutils-0.5.2/tonutils/tonconnect/models/request.py +0 -533
  170. tonutils-0.5.2/tonutils/tonconnect/models/wallet.py +0 -248
  171. tonutils-0.5.2/tonutils/tonconnect/provider/__init__.py +0 -5
  172. tonutils-0.5.2/tonutils/tonconnect/provider/bridge.py +0 -581
  173. tonutils-0.5.2/tonutils/tonconnect/provider/session.py +0 -104
  174. tonutils-0.5.2/tonutils/tonconnect/storage/__init__.py +0 -7
  175. tonutils-0.5.2/tonutils/tonconnect/storage/base.py +0 -39
  176. tonutils-0.5.2/tonutils/tonconnect/storage/default.py +0 -40
  177. tonutils-0.5.2/tonutils/tonconnect/tonconnect.py +0 -290
  178. tonutils-0.5.2/tonutils/tonconnect/utils/__init__.py +0 -25
  179. tonutils-0.5.2/tonutils/tonconnect/utils/exceptions.py +0 -140
  180. tonutils-0.5.2/tonutils/tonconnect/utils/logger.py +0 -3
  181. tonutils-0.5.2/tonutils/tonconnect/utils/verifiers.py +0 -255
  182. tonutils-0.5.2/tonutils/tonconnect/utils/wallet_manager.py +0 -239
  183. tonutils-0.5.2/tonutils/utils.py +0 -267
  184. tonutils-0.5.2/tonutils/vanity/__init__.py +0 -5
  185. tonutils-0.5.2/tonutils/vanity/contract.py +0 -35
  186. tonutils-0.5.2/tonutils/vanity/data.py +0 -34
  187. tonutils-0.5.2/tonutils/wallet/__init__.py +0 -31
  188. tonutils-0.5.2/tonutils/wallet/contract/__init__.py +0 -24
  189. tonutils-0.5.2/tonutils/wallet/contract/_base.py +0 -438
  190. tonutils-0.5.2/tonutils/wallet/contract/highload.py +0 -505
  191. tonutils-0.5.2/tonutils/wallet/contract/preprocessed.py +0 -291
  192. tonutils-0.5.2/tonutils/wallet/contract/v2.py +0 -95
  193. tonutils-0.5.2/tonutils/wallet/contract/v3.py +0 -94
  194. tonutils-0.5.2/tonutils/wallet/contract/v4.py +0 -122
  195. tonutils-0.5.2/tonutils/wallet/contract/v5.py +0 -193
  196. tonutils-0.5.2/tonutils/wallet/data.py +0 -188
  197. tonutils-0.5.2/tonutils/wallet/messages.py +0 -631
  198. tonutils-0.5.2/tonutils/wallet/op_codes.py +0 -9
  199. tonutils-0.5.2/tonutils/wallet/utils.py +0 -57
  200. tonutils-0.5.2/tonutils.egg-info/SOURCES.txt +0 -134
  201. {tonutils-0.5.2 → tonutils-0.6.0a1}/setup.cfg +0 -0
  202. {tonutils-0.5.2 → tonutils-0.6.0a1}/tonutils/__init__.py +0 -0
  203. {tonutils-0.5.2 → tonutils-0.6.0a1}/tonutils/py.typed +0 -0
  204. {tonutils-0.5.2/tonutils/jetton/dex → tonutils-0.6.0a1/tonutils/tonconnect}/__init__.py +0 -0
  205. {tonutils-0.5.2 → tonutils-0.6.0a1}/tonutils.egg-info/dependency_links.txt +0 -0
  206. {tonutils-0.5.2 → tonutils-0.6.0a1}/tonutils.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Ness
3
+ Copyright (c) 2025 Ness
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tonutils
3
- Version: 0.5.2
3
+ Version: 0.6.0a1
4
4
  Summary: Tonutils is a high-level, object-oriented Python library designed to facilitate seamless interactions with the TON blockchain.
5
5
  Home-page: https://github.com/nessshon/tonutils
6
6
  Author: nessshon
@@ -24,7 +24,7 @@ Classifier: Environment :: Console
24
24
  Requires-Python: >=3.10
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
- Requires-Dist: aiohttp<=3.12.2,>=3.7.0
27
+ Requires-Dist: aiohttp>=3.7.0
28
28
  Requires-Dist: aiolimiter~=1.2.1
29
29
  Requires-Dist: cachetools~=5.5.0
30
30
  Requires-Dist: pycryptodomex~=3.20.0
@@ -46,7 +46,7 @@ Dynamic: requires-dist
46
46
  Dynamic: requires-python
47
47
  Dynamic: summary
48
48
 
49
- # 📦 Tonutils
49
+ # 📦 Tonutils [ALPHA]
50
50
 
51
51
  [![TON](https://img.shields.io/badge/TON-grey?logo=TON&logoColor=40AEF0)](https://ton.org)
52
52
  [![PyPI](https://img.shields.io/pypi/v/tonutils.svg?color=FFE873&labelColor=3776AB)](https://pypi.python.org/pypi/tonutils)
@@ -77,21 +77,16 @@ on top of the TON ecosystem.
77
77
  ## Installation
78
78
 
79
79
  ```bash
80
- pip install tonutils
80
+ pip install --pre tonutils
81
81
  ```
82
82
 
83
83
  To use `pytoniq` with Native ADNL connection, install it with the optional dependencies, including
84
84
  the [pytoniq](https://github.com/yungwine/pytoniq) library:
85
85
 
86
86
  ```bash
87
- pip install 'tonutils[pytoniq]'
87
+ pip install --pre 'tonutils[pytoniq]'
88
88
  ```
89
89
 
90
- ## Documentation
91
-
92
- Find all guides and references here:
93
- [nessshon.github.io/tonutils](https://nessshon.github.io/tonutils/)
94
-
95
90
  ## Contribution
96
91
 
97
92
  We welcome your contributions! If you have ideas for improvement or have identified a bug, please create an issue or
@@ -1,4 +1,4 @@
1
- # 📦 Tonutils
1
+ # 📦 Tonutils [ALPHA]
2
2
 
3
3
  [![TON](https://img.shields.io/badge/TON-grey?logo=TON&logoColor=40AEF0)](https://ton.org)
4
4
  [![PyPI](https://img.shields.io/pypi/v/tonutils.svg?color=FFE873&labelColor=3776AB)](https://pypi.python.org/pypi/tonutils)
@@ -29,21 +29,16 @@ on top of the TON ecosystem.
29
29
  ## Installation
30
30
 
31
31
  ```bash
32
- pip install tonutils
32
+ pip install --pre tonutils
33
33
  ```
34
34
 
35
35
  To use `pytoniq` with Native ADNL connection, install it with the optional dependencies, including
36
36
  the [pytoniq](https://github.com/yungwine/pytoniq) library:
37
37
 
38
38
  ```bash
39
- pip install 'tonutils[pytoniq]'
39
+ pip install --pre 'tonutils[pytoniq]'
40
40
  ```
41
41
 
42
- ## Documentation
43
-
44
- Find all guides and references here:
45
- [nessshon.github.io/tonutils](https://nessshon.github.io/tonutils/)
46
-
47
42
  ## Contribution
48
43
 
49
44
  We welcome your contributions! If you have ideas for improvement or have identified a bug, please create an issue or
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="tonutils",
8
- version="0.5.2",
8
+ version="0.6.0a1",
9
9
  author="nessshon",
10
10
  description=(
11
11
  "Tonutils is a high-level, object-oriented Python library "
@@ -24,7 +24,7 @@ setuptools.setup(
24
24
  package_data={"tonutils": ["py.typed"]},
25
25
  python_requires=">=3.10",
26
26
  install_requires=[
27
- "aiohttp>=3.7.0,<=3.12.2",
27
+ "aiohttp>=3.7.0",
28
28
  "aiolimiter~=1.2.1",
29
29
  "cachetools~=5.5.0",
30
30
  "pycryptodomex~=3.20.0",
@@ -0,0 +1,94 @@
1
+ from pytoniq_core import (
2
+ Address,
3
+ Cell,
4
+ StateInit,
5
+ Transaction,
6
+ )
7
+
8
+ from tests.helpers import ClientTestCase
9
+ from tonutils.types import (
10
+ ClientType,
11
+ ContractStateInfo,
12
+ ContractState,
13
+ PublicKey,
14
+ )
15
+
16
+ WALLET_ADDRESS = Address(
17
+ "0:83ae019a23a8162beaa5cb0ebdc56668b2eac6c6ba51808812915b206a152dc5"
18
+ )
19
+ WALLET_PUBLIC_KEY = PublicKey(
20
+ 55076642238194142798835029799378000396651553013470455265600214024586038843895
21
+ )
22
+
23
+ TX_LIMIT = 2
24
+ TX_TO_LT = 60837801000002
25
+ TX_PREV_HASH_HEX = "f86526829c6532063ec13d97231bf3579e9d1321124397766fb27eb76374a4ff"
26
+
27
+
28
+ class TestTonapiClient(ClientTestCase):
29
+ CLIENT_TYPE = ClientType.LITESERVER
30
+ IS_TESTNET = False
31
+ RPS = 1
32
+
33
+ async def test_send_boc(self) -> None:
34
+ pass
35
+
36
+ async def test_get_blockchain_config(self) -> None:
37
+ result = await self.client.get_blockchain_config()
38
+ self.assertIsInstance(result, dict)
39
+
40
+ async def test_get_contract_info(self) -> None:
41
+ result = await self.client.get_contract_info(WALLET_ADDRESS)
42
+
43
+ self.assertIsNotNone(result.code_raw)
44
+ self.assertIsNotNone(result.data_raw)
45
+ self.assertGreater(result.balance, 0)
46
+ self.assertIsInstance(result, ContractStateInfo)
47
+ self.assertIs(result.state, ContractState.ACTIVE)
48
+ self.assertIsNotNone(result.last_transaction_lt)
49
+ self.assertIsNotNone(result.last_transaction_hash)
50
+
51
+ self.assertIsInstance(result.code, Cell)
52
+ self.assertIsInstance(result.data, Cell)
53
+ self.assertIsInstance(result.state_init, StateInit)
54
+
55
+ async def test_get_contract_transactions(self) -> None:
56
+ result = await self.client.get_contract_transactions(
57
+ address=WALLET_ADDRESS,
58
+ limit=TX_LIMIT,
59
+ to_lt=TX_TO_LT,
60
+ )
61
+ tx = result[0]
62
+ prev_tx_hash_hex = tx.prev_trans_hash.hex()
63
+
64
+ self.assertEqual(len(result), TX_LIMIT)
65
+ self.assertIsInstance(tx, Transaction)
66
+ self.assertEqual(prev_tx_hash_hex, TX_PREV_HASH_HEX)
67
+
68
+ async def test_run_get_method(self) -> None:
69
+ result = await self.client.run_get_method(
70
+ address=WALLET_ADDRESS,
71
+ method_name="seqno",
72
+ )
73
+ stack_item = result[0]
74
+
75
+ self.assertIsInstance(stack_item, int)
76
+ self.assertGreater(stack_item, 0)
77
+
78
+ result = await self.client.run_get_method(
79
+ address=WALLET_ADDRESS,
80
+ method_name="get_public_key",
81
+ )
82
+ stack_item = result[0]
83
+ public_key = PublicKey(stack_item)
84
+
85
+ self.assertIsInstance(stack_item, int)
86
+ self.assertEqual(public_key, WALLET_PUBLIC_KEY)
87
+
88
+
89
+ class TestToncenterClient(TestTonapiClient):
90
+ CLIENT_TYPE = ClientType.TONCENTER
91
+
92
+
93
+ class TestLiteserverClient(TestTonapiClient):
94
+ CLIENT_TYPE = ClientType.LITESERVER
@@ -0,0 +1,230 @@
1
+ import typing as t
2
+ from decimal import Decimal
3
+ from unittest import TestCase
4
+
5
+ from pytoniq_core import (
6
+ Address,
7
+ Cell,
8
+ Slice,
9
+ begin_cell,
10
+ )
11
+
12
+ from tonutils.types import ClientType, PrivateKey, WorkchainID, NetworkGlobalID
13
+ from tonutils.utils import (
14
+ StackCodec,
15
+ TextCipher,
16
+ cell_to_b64,
17
+ cell_to_hex,
18
+ cell_hash,
19
+ normalize_hash,
20
+ slice_hash,
21
+ string_hash,
22
+ to_cell,
23
+ WalletV5SubwalletID,
24
+ to_amount,
25
+ to_nano,
26
+ )
27
+
28
+ CELL_HEX = "b5ee9c7201010101002a0000500168747470733a2f2f6e66742e667261676d656e742e636f6d2f757365726e616d65732e6a736f6e"
29
+ CELL_B64 = "te6ccgEBAQEAKgAAUAFodHRwczovL25mdC5mcmFnbWVudC5jb20vdXNlcm5hbWVzLmpzb24="
30
+ CELL_BYTES = bytes.fromhex(CELL_HEX)
31
+ CELL_SLICE = Slice.one_from_boc(CELL_HEX)
32
+ CELL = CELL_SLICE.to_cell()
33
+
34
+ MESSAGE_HEX = "b5ee9c7201020d0100028a0003b578379ed1da34943d4d870c33d42263e3cf790affc450cdaf282a4bcc7cea49a9100003754e7847c41d99e0513ab5e320b789f43e493b10315a5f4d3c41f6974022ef4436a22889fdb0000371d09faa34168ac719d00054666febc80102030201e004050082724b09a7b09203b73b83d9293c7108e409d30009cf16f9daaf5a6ebe950cc40dd841477adbde3012580ca1d75367f579bf10907c2df711e13df7cb3ee31ce730bb02130cc08af24619313984400b0c0098880106f3da3b469287a9b0e1867a844c7c79ef215ff88a19b5e50549798f9d4935220108a3816c0055233e112c745f28b689a6a1828da440416ea18060079ce88643bf9225f5bd2468ac719a0201dd0607010120080101200900b7480106f3da3b469287a9b0e1867a844c7c79ef215ff88a19b5e50549798f9d493523001548cf844b1d17ca2da269a860a36910105ba8601801e73a2190efe4897d6f490d312d000608235a00006ea9cf08f884d158e33a1702448d4001b3480106f3da3b469287a9b0e1867a844c7c79ef215ff88a19b5e50549798f9d4935230020eb806688ea058afaa972c3af71599a2cbab1b1ae94602204a456c81a854b715409502f9000060c245c00006ea9cf08f886d158e33ac00a0062000000005468616e6b7320666f7220746f6e7574696c732066726f6d2063726f6e212028efbfa3e296bdefbfa329e3838e009d430d63138800000000000000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020006fc9879ae04c1447940000000000040000000000051d0eb6386a84e2d8f909cc22fb5eae3909f490962ea348759614866cecd0dc6640d03954"
35
+ NORMALIZED_HASH = "ab49f1d3293243946f8e81f0169524003302688218d718fedbc99dd90163853b"
36
+
37
+ STRING_HASH_TEXT = "nessshon"
38
+ STRING_HASH = (
39
+ 45354304031421179242460489368440335494304328265643744596791119159788447170008
40
+ )
41
+
42
+ CELL_HASH_TEXT = "wallet"
43
+ CELL_HASH_CELL = begin_cell().store_snake_string(CELL_HASH_TEXT).end_cell()
44
+ CELL_HASH = (
45
+ 115698008076457823118597424358900481870087387390627058654421588318795409511780
46
+ )
47
+
48
+ DECRYPTED_PAYLOAD = "Hello from tonutils!"
49
+ SENDER_ADDRESS = Address("UQD_nC7tFgl5S_WvW6LJHRqX-smNCeDYIfYBxbD0tcHnbjxC")
50
+ SENDER_PRIVKEY = PrivateKey("9A4xl6qjn4PrbN0yIPQXAqVi634g78b2MyzJ6psmVak=")
51
+ RECIPIENT_PRIVKEY = PrivateKey("C3tEgYARTXnF+NPD7ufnn7LepZd4+kKigowVFH2kSHk=")
52
+ RECIPIENT_PUBKEY = RECIPIENT_PRIVKEY.public_key
53
+
54
+ STACK_PALOAD = [-1, CELL, Cell.one_from_boc("b5ee9c7201010101000300000120")]
55
+ STACK_RESPONSE = [-1, CELL, None]
56
+
57
+ STACK_PAYLOADS = {
58
+ ClientType.TONAPI: [
59
+ -1,
60
+ "te6ccgEBAQEAKgAAUAFodHRwczovL25mdC5mcmFnbWVudC5jb20vdXNlcm5hbWVzLmpzb24=",
61
+ "te6ccgEBAQEAAwAAASA=",
62
+ ],
63
+ ClientType.TONCENTER: [
64
+ ["num", "-0x1"],
65
+ [
66
+ "tvm.Cell",
67
+ "te6ccgEBAQEAKgAAUAFodHRwczovL25mdC5mcmFnbWVudC5jb20vdXNlcm5hbWVzLmpzb24=",
68
+ ],
69
+ ["tvm.Cell", "te6ccgEBAQEAAwAAASA="],
70
+ ],
71
+ ClientType.LITESERVER: STACK_PALOAD,
72
+ }
73
+ STACK_RESPONSES: t.Dict[ClientType, t.List[t.Any]] = {
74
+ ClientType.TONAPI: [
75
+ {"type": "num", "num": "-0x1"},
76
+ {
77
+ "type": "cell",
78
+ "cell": "b5ee9c7201010101002a0000500168747470733a2f2f6e66742e667261676d656e742e636f6d2f757365726e616d65732e6a736f6e",
79
+ },
80
+ {"type": "cell", "cell": "b5ee9c7201010101000300000120"},
81
+ ],
82
+ ClientType.TONCENTER: [
83
+ ["num", "-0x1"],
84
+ [
85
+ "cell",
86
+ {
87
+ "bytes": "te6cckEBAQEAKgAAUAFodHRwczovL25mdC5mcmFnbWVudC5jb20vdXNlcm5hbWVzLmpzb24K7MvY"
88
+ },
89
+ ],
90
+ ["cell", {"bytes": "te6cckEBAQEAAwAAASCUQYZV"}],
91
+ ],
92
+ ClientType.LITESERVER: STACK_RESPONSE,
93
+ }
94
+
95
+
96
+ class TestUtils(TestCase):
97
+
98
+ def tests_converters(self) -> None:
99
+ cells = [
100
+ to_cell(CELL),
101
+ to_cell(CELL_HEX),
102
+ to_cell(CELL_B64),
103
+ to_cell(CELL_BYTES),
104
+ to_cell(CELL_SLICE),
105
+ ]
106
+ self.assertTrue(all(isinstance(x, Cell) for x in cells))
107
+
108
+ self.assertEqual(cell_to_hex(CELL), CELL_HEX)
109
+ self.assertEqual(cell_to_hex(CELL_HEX), CELL_HEX)
110
+ self.assertEqual(cell_to_hex(CELL_B64), CELL_HEX)
111
+ self.assertEqual(cell_to_hex(CELL_BYTES), CELL_HEX)
112
+ self.assertEqual(cell_to_hex(CELL_SLICE), CELL_HEX)
113
+
114
+ self.assertEqual(cell_to_b64(to_cell(CELL)), CELL_B64)
115
+ self.assertEqual(cell_to_b64(to_cell(CELL_HEX)), CELL_B64)
116
+ self.assertEqual(cell_to_b64(to_cell(CELL_B64)), CELL_B64)
117
+ self.assertEqual(cell_to_b64(to_cell(CELL_BYTES)), CELL_B64)
118
+ self.assertEqual(cell_to_b64(to_cell(CELL_SLICE)), CELL_B64)
119
+
120
+ self.assertEqual(cell_hash(CELL_HASH_CELL), CELL_HASH)
121
+ self.assertEqual(string_hash(STRING_HASH_TEXT), STRING_HASH)
122
+ self.assertEqual(slice_hash(CELL_HASH_CELL.to_slice()), CELL_HASH)
123
+
124
+ self.assertEqual(normalize_hash(MESSAGE_HEX), NORMALIZED_HASH)
125
+
126
+ def tests_text_cipher(self) -> None:
127
+ encrypted = TextCipher.encrypt(
128
+ payload=DECRYPTED_PAYLOAD,
129
+ sender_address=SENDER_ADDRESS,
130
+ our_private_key=SENDER_PRIVKEY,
131
+ their_public_key=RECIPIENT_PUBKEY,
132
+ )
133
+ self.assertIsInstance(encrypted, Cell)
134
+
135
+ decrypted = TextCipher.decrypt(
136
+ payload=encrypted,
137
+ sender_address=SENDER_ADDRESS,
138
+ our_public_key=RECIPIENT_PUBKEY,
139
+ our_private_key=RECIPIENT_PRIVKEY,
140
+ )
141
+ self.assertEqual(decrypted, DECRYPTED_PAYLOAD)
142
+
143
+ def _tests_stack_codec(self, client_type: ClientType) -> None:
144
+ codec = StackCodec(client_type)
145
+
146
+ encoded_payload = codec.encode(STACK_PALOAD)
147
+ expected_encoded_payload = STACK_PAYLOADS[client_type]
148
+ self.assertEqual(encoded_payload, expected_encoded_payload)
149
+
150
+ decoded_response = codec.decode(STACK_RESPONSES[client_type])
151
+ expected_decoded_response = STACK_RESPONSE
152
+ self.assertEqual(decoded_response, expected_decoded_response)
153
+
154
+ def tests_stack_codec_tonapi(self) -> None:
155
+ self._tests_stack_codec(ClientType.TONAPI)
156
+
157
+ def tests_stack_codec_toncenter(self) -> None:
158
+ self._tests_stack_codec(ClientType.TONCENTER)
159
+
160
+ def tests_stack_codec_liteserver(self) -> None:
161
+ self._tests_stack_codec(ClientType.LITESERVER)
162
+
163
+ def tests_value_utils(self) -> None:
164
+ decimals = 9
165
+ self.assertEqual(to_nano("1", decimals), 1_000_000_000)
166
+ self.assertEqual(to_nano("0.000000001", decimals), 1)
167
+ self.assertEqual(to_nano(Decimal("1.234567891"), decimals), 1_234_567_891)
168
+
169
+ self.assertEqual(to_nano("1.2345678919", decimals), 1_234_567_891)
170
+ self.assertEqual(to_nano("0.9999999999", decimals), 999_999_999)
171
+
172
+ self.assertEqual(to_nano(1.2, 1), 12)
173
+ self.assertEqual(to_nano(7, 0), 7)
174
+ self.assertEqual(to_nano("42", 0), 42)
175
+ self.assertEqual(
176
+ to_amount(1_234_567_891, decimals, precision=4),
177
+ Decimal("1.2345"),
178
+ )
179
+ self.assertEqual(
180
+ to_amount(9_999, 4, precision=2),
181
+ Decimal("0.99"),
182
+ )
183
+ self.assertEqual(to_amount(0, decimals), Decimal(0))
184
+
185
+ with self.assertRaises(ValueError):
186
+ to_amount(-1, decimals)
187
+ with self.assertRaises(ValueError):
188
+ to_amount(2 ** 256, decimals)
189
+ with self.assertRaises(ValueError):
190
+ to_amount(1, -1)
191
+
192
+ for s in ["1.234567891", "0.000000001", "123456789.987654321"]:
193
+ src = Decimal(s)
194
+ nano = to_nano(src, decimals)
195
+ back = to_amount(nano, decimals)
196
+ self.assertLessEqual(back, src)
197
+ self.assertLess(src - back, Decimal(f"1e-{decimals}"))
198
+
199
+ def tests_wallet_v5_id(self) -> None:
200
+ subwallet_id = WalletV5SubwalletID(
201
+ subwallet_number=0,
202
+ workchain=WorkchainID.BASECHAIN,
203
+ version=0,
204
+ network_global_id=NetworkGlobalID.MAINNET,
205
+ )
206
+ self.assertEqual(subwallet_id.pack(), 2147483409)
207
+
208
+ subwallet_id = WalletV5SubwalletID(
209
+ subwallet_number=0,
210
+ workchain=WorkchainID.MASTERCHAIN,
211
+ version=0,
212
+ network_global_id=NetworkGlobalID.MAINNET,
213
+ )
214
+ self.assertEqual(subwallet_id.pack(), 8388369)
215
+
216
+ subwallet_id = WalletV5SubwalletID(
217
+ subwallet_number=0,
218
+ workchain=WorkchainID.BASECHAIN,
219
+ version=0,
220
+ network_global_id=NetworkGlobalID.TESTNET,
221
+ )
222
+ self.assertEqual(subwallet_id.pack(), 2147483645)
223
+
224
+ subwallet_id = WalletV5SubwalletID(
225
+ subwallet_number=0,
226
+ workchain=WorkchainID.MASTERCHAIN,
227
+ version=0,
228
+ network_global_id=NetworkGlobalID.TESTNET,
229
+ )
230
+ self.assertEqual(subwallet_id.pack(), 8388605)
@@ -1,21 +1,13 @@
1
- from ._base import Client
2
-
3
- from .lite import LiteserverClient
1
+ from .liteserver import LiteserverClient
4
2
  from .quicknode import QuicknodeClient
5
3
  from .tatum import TatumClient
6
4
  from .tonapi import TonapiClient
7
- from .toncenter import (
8
- ToncenterV2Client,
9
- ToncenterV3Client,
10
- )
5
+ from .toncenter import ToncenterClient
11
6
 
12
7
  __all__ = [
13
- "Client",
14
-
15
8
  "LiteserverClient",
16
9
  "QuicknodeClient",
17
10
  "TatumClient",
18
11
  "TonapiClient",
19
- "ToncenterV2Client",
20
- "ToncenterV3Client",
12
+ "ToncenterClient",
21
13
  ]
@@ -0,0 +1,95 @@
1
+ import abc
2
+ import typing as t
3
+
4
+ from pyapiq import AsyncClientAPI
5
+ from pytoniq_core import Address, Transaction
6
+
7
+ from .liteserver.stub import LiteBalancer
8
+ from ..types import AddressLike, ContractStateInfo
9
+
10
+ A = t.TypeVar("A", bound=t.Union[AsyncClientAPI, LiteBalancer])
11
+
12
+
13
+ class BaseClient(abc.ABC, t.Generic[A]):
14
+ is_testnet: bool
15
+ api: A
16
+
17
+ @abc.abstractmethod
18
+ async def _send_boc(self, boc: str) -> None:
19
+ raise NotImplementedError
20
+
21
+ @abc.abstractmethod
22
+ async def _get_blockchain_config(self) -> t.Dict[int, t.Any]:
23
+ raise NotImplementedError
24
+
25
+ @abc.abstractmethod
26
+ async def _get_contract_info(self, address: str) -> ContractStateInfo:
27
+ raise NotImplementedError
28
+
29
+ @abc.abstractmethod
30
+ async def _get_contract_transactions(
31
+ self,
32
+ address: str,
33
+ limit: int = 100,
34
+ from_lt: t.Optional[int] = None,
35
+ to_lt: t.Optional[int] = 0,
36
+ ) -> t.List[Transaction]:
37
+ raise NotImplementedError
38
+
39
+ @abc.abstractmethod
40
+ async def _run_get_method(
41
+ self,
42
+ address: str,
43
+ method_name: str,
44
+ stack: t.Optional[t.List[t.Any]] = None,
45
+ ) -> t.List[t.Any]:
46
+ raise NotImplementedError
47
+
48
+ @abc.abstractmethod
49
+ async def startup(self) -> None:
50
+ raise NotImplementedError
51
+
52
+ @abc.abstractmethod
53
+ async def close(self) -> None:
54
+ raise NotImplementedError
55
+
56
+ async def send_boc(self, boc: str) -> None:
57
+ await self._send_boc(boc)
58
+
59
+ async def get_blockchain_config(self) -> t.Dict[int, t.Any]:
60
+ return await self._get_blockchain_config()
61
+
62
+ async def get_contract_info(self, address: AddressLike) -> ContractStateInfo:
63
+ if isinstance(address, Address):
64
+ address = Address(address).to_str(is_user_friendly=False)
65
+ return await self._get_contract_info(address=address)
66
+
67
+ async def get_contract_transactions(
68
+ self,
69
+ address: AddressLike,
70
+ limit: int = 100,
71
+ from_lt: t.Optional[int] = None,
72
+ to_lt: t.Optional[int] = 0,
73
+ ) -> t.List[Transaction]:
74
+ if isinstance(address, Address):
75
+ address = Address(address).to_str(is_user_friendly=False)
76
+ return await self._get_contract_transactions(
77
+ address=address,
78
+ limit=limit,
79
+ from_lt=from_lt,
80
+ to_lt=to_lt,
81
+ )
82
+
83
+ async def run_get_method(
84
+ self,
85
+ address: AddressLike,
86
+ method_name: str,
87
+ stack: t.Optional[t.List[t.Any]] = None,
88
+ ) -> t.List[t.Any]:
89
+ if isinstance(address, Address):
90
+ address = Address(address).to_str(is_user_friendly=False)
91
+ return await self._run_get_method(
92
+ address=address,
93
+ method_name=method_name,
94
+ stack=stack,
95
+ )
@@ -0,0 +1,3 @@
1
+ from .client import LiteserverClient
2
+
3
+ __all__ = ["LiteserverClient"]