py-near 1.1.45__tar.gz → 1.1.47__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.
- {py_near-1.1.45 → py_near-1.1.47}/PKG-INFO +4 -4
- {py_near-1.1.45 → py_near-1.1.47}/pyproject.toml +6 -6
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/providers.py +80 -60
- {py_near-1.1.45 → py_near-1.1.47}/LICENSE +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/README.md +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/__init__.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/account.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/constants.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/__init__.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/__pycache__/__init__.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/__pycache__/core.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/__pycache__/fts.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/core.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/__init__.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/__pycache__/__init__.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/__pycache__/async_client.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/__pycache__/exceptions.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/__pycache__/models.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/async_client.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/exceptions.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/models.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/fts.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/keypom/__init__.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/keypom/async_client.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/keypom/exceptions.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/keypom/models.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__init__.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/__init__.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/async_client.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/exceptions.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/models.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/async_client.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/exceptions.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/models.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/__init__.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/__pycache__/__init__.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/__pycache__/exceptions.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/__pycache__/provider.cpython-311.pyc +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/exceptions.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/provider.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/models.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/transactions.py +0 -0
- {py_near-1.1.45 → py_near-1.1.47}/src/py_near/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: py-near
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.47
|
4
4
|
Summary: Pretty simple and fully asynchronous framework for working with NEAR blockchain
|
5
5
|
Author: pvolnov
|
6
6
|
Author-email: petr@herewallet.app
|
@@ -12,9 +12,9 @@ Classifier: Programming Language :: Python :: 3.9
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
15
|
-
Requires-Dist:
|
16
|
-
Requires-Dist:
|
17
|
-
Requires-Dist: py-near-primitives (
|
15
|
+
Requires-Dist: ed25519 (==1.5)
|
16
|
+
Requires-Dist: httpx (==0.27.0)
|
17
|
+
Requires-Dist: py-near-primitives (==0.2.3)
|
18
18
|
Description-Content-Type: text/markdown
|
19
19
|
|
20
20
|
# py-near
|
@@ -1,15 +1,15 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "py-near"
|
3
|
-
version = "1.1.
|
3
|
+
version = "1.1.47"
|
4
4
|
description="Pretty simple and fully asynchronous framework for working with NEAR blockchain"
|
5
5
|
authors = ["pvolnov <petr@herewallet.app>"]
|
6
6
|
readme = "README.md"
|
7
7
|
|
8
8
|
[tool.poetry.dependencies]
|
9
9
|
python = "^3.7"
|
10
|
-
ed25519 = "
|
11
|
-
|
12
|
-
py-near-primitives = "
|
10
|
+
ed25519 = "1.5"
|
11
|
+
httpx = "0.27.0"
|
12
|
+
py-near-primitives = "0.2.3"
|
13
13
|
|
14
14
|
[tool.poetry.dev-dependencies]
|
15
15
|
black = "^21.12b0"
|
@@ -22,12 +22,12 @@ base58 = "^2.1.1"
|
|
22
22
|
|
23
23
|
[project]
|
24
24
|
name = "py-near"
|
25
|
-
version = "1.1.
|
25
|
+
version = "1.1.47"
|
26
26
|
description = "Pretty simple and fully asynchronous framework for working with NEAR blockchaink"
|
27
27
|
authors = [ {name = "pvolnov", email = "petr@herewallet.app"} ]
|
28
28
|
requires-python = ">=3.7"
|
29
29
|
license = {file = "LICENSE"}
|
30
|
-
dependencies=["base58", "ed25519", "
|
30
|
+
dependencies=["base58", "ed25519", "httpx", "py-near-primitives", "pydantic"]
|
31
31
|
keywords = ["python", "near", "async"]
|
32
32
|
classifiers = [
|
33
33
|
"Programming Language :: Python :: 3",
|
@@ -5,8 +5,7 @@ import json
|
|
5
5
|
from collections import Counter
|
6
6
|
from typing import Optional
|
7
7
|
|
8
|
-
import
|
9
|
-
from aiohttp import ClientResponseError, ClientConnectorError, ServerDisconnectedError
|
8
|
+
import httpx
|
10
9
|
from loguru import logger
|
11
10
|
|
12
11
|
from py_near.constants import TIMEOUT_WAIT_RPC
|
@@ -61,6 +60,7 @@ class JsonProvider(object):
|
|
61
60
|
self._last_rpc_addr_check = 0
|
62
61
|
self.allow_broadcast = allow_broadcast
|
63
62
|
self._timeout = timeout
|
63
|
+
self._client: httpx.AsyncClient = httpx.AsyncClient()
|
64
64
|
|
65
65
|
async def shutdown(self):
|
66
66
|
pass
|
@@ -94,35 +94,41 @@ class JsonProvider(object):
|
|
94
94
|
"id": 1,
|
95
95
|
}
|
96
96
|
auth_key = "py-near"
|
97
|
+
rpc_addr_url = rpc_addr
|
97
98
|
if "@" in rpc_addr:
|
98
|
-
auth_key =
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
auth_key = rpc_addr_url.split("//")[1].split("@")[0]
|
100
|
+
rpc_addr_url = rpc_addr_url.replace(auth_key + "@", "")
|
101
|
+
|
102
|
+
r = await self._client.post(
|
103
|
+
rpc_addr_url,
|
104
|
+
json=data,
|
105
|
+
headers={
|
102
106
|
"Referer": "https://tgapp.herewallet.app",
|
103
107
|
"Authorization": f"Bearer {auth_key}",
|
104
|
-
}
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
108
|
+
},
|
109
|
+
)
|
110
|
+
if r.status_code == 200:
|
111
|
+
data = json.loads(r.text)["result"]
|
112
|
+
diff = 0
|
113
|
+
if data["sync_info"]["syncing"]:
|
114
|
+
last_block_ts = datetime.datetime.fromisoformat(
|
115
|
+
data["sync_info"]["latest_block_time"]
|
116
|
+
)
|
117
|
+
diff = (
|
118
|
+
datetime.datetime.utcnow().timestamp()
|
119
|
+
- last_block_ts.timestamp()
|
120
|
+
)
|
121
|
+
is_syncing = diff > 60
|
122
|
+
else:
|
123
|
+
is_syncing = False
|
124
|
+
if is_syncing:
|
125
|
+
logger.error(f"Remove async RPC : {rpc_addr} ({diff})")
|
126
|
+
continue
|
127
|
+
available_rpcs.append(rpc_addr)
|
128
|
+
else:
|
129
|
+
logger.error(
|
130
|
+
f"Remove rpc because of error {r.status_code}: {rpc_addr}"
|
131
|
+
)
|
126
132
|
except Exception as e:
|
127
133
|
if rpc_addr in self._available_rpcs:
|
128
134
|
logger.error(f"Remove rpc: {e}")
|
@@ -146,24 +152,26 @@ class JsonProvider(object):
|
|
146
152
|
if "@" in rpc_call_addr:
|
147
153
|
auth_key = rpc_call_addr.split("//")[1].split("@")[0]
|
148
154
|
rpc_call_addr = rpc_call_addr.replace(auth_key + "@", "")
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
"
|
163
|
-
"
|
164
|
-
"
|
165
|
-
}
|
155
|
+
r = await self._client.post(
|
156
|
+
rpc_call_addr,
|
157
|
+
json=j,
|
158
|
+
timeout=self._timeout,
|
159
|
+
headers={
|
160
|
+
"Referer": "https://tgapp.herewallet.app",
|
161
|
+
"Authorization": f"Bearer {auth_key}",
|
162
|
+
},
|
163
|
+
)
|
164
|
+
if r.status_code == 200:
|
165
|
+
return json.loads(r.text)
|
166
|
+
return {
|
167
|
+
"error": {
|
168
|
+
"cause": {
|
169
|
+
"name": "RPC_ERROR",
|
170
|
+
"message": f"Status: {r.status_code}",
|
171
|
+
},
|
172
|
+
"data": r.text,
|
166
173
|
}
|
174
|
+
}
|
167
175
|
|
168
176
|
if broadcast or threshold:
|
169
177
|
pending = [
|
@@ -172,6 +180,8 @@ class JsonProvider(object):
|
|
172
180
|
|
173
181
|
responses = []
|
174
182
|
correct_responses = []
|
183
|
+
result = None
|
184
|
+
|
175
185
|
while pending and len(pending):
|
176
186
|
done, pending = await asyncio.wait(
|
177
187
|
pending, return_when=asyncio.FIRST_COMPLETED
|
@@ -188,14 +198,21 @@ class JsonProvider(object):
|
|
188
198
|
array = [hash(json.dumps(x)) for x in responses]
|
189
199
|
most_frequent_element = self.most_frequent_by_hash(array)
|
190
200
|
correct_responses = [
|
191
|
-
x
|
201
|
+
x
|
202
|
+
for x in responses
|
203
|
+
if hash(json.dumps(x)) == most_frequent_element
|
192
204
|
]
|
193
205
|
if len(correct_responses) >= threshold:
|
194
206
|
for task in pending:
|
195
207
|
task.cancel()
|
196
|
-
return
|
197
|
-
|
208
|
+
return correct_responses[0]
|
209
|
+
if threshold and threshold > 0:
|
210
|
+
raise RpcEmptyResponse(
|
211
|
+
f"Threshold not reached: {len(correct_responses)}/{threshold}"
|
212
|
+
)
|
213
|
+
return result
|
198
214
|
else:
|
215
|
+
res = None
|
199
216
|
for rpc_addr in self._available_rpcs:
|
200
217
|
try:
|
201
218
|
res = await f(rpc_addr)
|
@@ -204,7 +221,7 @@ class JsonProvider(object):
|
|
204
221
|
except Exception as e:
|
205
222
|
logger.error(f"Rpc error: {e}")
|
206
223
|
continue
|
207
|
-
|
224
|
+
return res
|
208
225
|
|
209
226
|
@staticmethod
|
210
227
|
def get_error_from_response(content: dict):
|
@@ -309,7 +326,7 @@ class JsonProvider(object):
|
|
309
326
|
|
310
327
|
async def get_status(self):
|
311
328
|
await self.check_available_rpcs()
|
312
|
-
for rpc_addr in self._available_rpcs:
|
329
|
+
for rpc_addr in self._available_rpcs.copy():
|
313
330
|
try:
|
314
331
|
data = {
|
315
332
|
"jsonrpc": "2.0",
|
@@ -317,16 +334,19 @@ class JsonProvider(object):
|
|
317
334
|
"params": {"finality": "final"},
|
318
335
|
"id": 1,
|
319
336
|
}
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
337
|
+
headers = {
|
338
|
+
"Referer": "https://tgapp.herewallet.app",
|
339
|
+
}
|
340
|
+
if "@" in rpc_addr:
|
341
|
+
auth_key = rpc_addr.split("//")[1].split("@")[0]
|
342
|
+
rpc_addr = rpc_addr.replace(auth_key + "@", "")
|
343
|
+
headers = {
|
344
|
+
"Authorization": f"Bearer {auth_key}"
|
345
|
+
}
|
346
|
+
r = await self._client.post(rpc_addr, json=data, headers=headers)
|
347
|
+
if r.status_code == 200:
|
348
|
+
return json.loads(r.text)["result"]
|
349
|
+
except ConnectionError as e:
|
330
350
|
logger.error(f"Rpc get status error: {e}")
|
331
351
|
except Exception as e:
|
332
352
|
logger.error(e)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/__pycache__/async_client.cpython-311.pyc
RENAMED
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/ft/__pycache__/exceptions.cpython-311.pyc
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/__init__.cpython-311.pyc
RENAMED
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/async_client.cpython-311.pyc
RENAMED
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/exceptions.cpython-311.pyc
RENAMED
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/dapps/staking/__pycache__/models.cpython-311.pyc
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/__pycache__/__init__.cpython-311.pyc
RENAMED
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/__pycache__/exceptions.cpython-311.pyc
RENAMED
File without changes
|
{py_near-1.1.45 → py_near-1.1.47}/src/py_near/exceptions/__pycache__/provider.cpython-311.pyc
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|