-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.py
141 lines (110 loc) · 4.48 KB
/
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import asyncio
from abc import ABC, abstractmethod
import aiohttp
from tonsdk.boc import Cell
from tonsdk.provider import ToncenterClient, address_state, prepare_address
from tonsdk.utils import TonCurrencyEnum, from_nano
from tvm_valuetypes import serialize_tvm_stack
class AbstractTonClient(ABC):
provider: ToncenterClient
@abstractmethod
async def _run(self, to_run, *, single_query=True):
raise NotImplementedError
async def get_address_information(
self, address: str, currency_to_show: TonCurrencyEnum = TonCurrencyEnum.ton
):
return (await self.get_addresses_information([address], currency_to_show))[0]
async def get_addresses_information(
self, addresses, currency_to_show: TonCurrencyEnum = TonCurrencyEnum.ton
):
if not addresses:
return []
tasks = []
for address in addresses:
address = prepare_address(address)
tasks.append(self.provider.raw_get_account_state(address))
results = await self._run(tasks, single_query=False)
for result in results:
result["state"] = address_state(result)
if "balance" in result:
if int(result["balance"]) < 0:
result["balance"] = 0
else:
result["balance"] = from_nano(
int(result["balance"]), currency_to_show
)
return results
async def seqno(self, addr: str):
addr = prepare_address(addr)
result = await self._run(self.provider.raw_run_method(addr, "seqno", []))
if "@type" in result and result["@type"] == "smc.runResult":
result["stack"] = serialize_tvm_stack(result["stack"])
return int(result[0]["stack"][0][1], 16)
async def send_boc(self, boc: Cell):
return await self._run(self.provider.raw_send_message(boc))
class TonCenterClient(AbstractTonClient):
def __init__(self, api_url: str, api_key: str):
self.loop = asyncio.get_event_loop()
self.provider = ToncenterClient(base_url=api_url, api_key=api_key)
async def _run(self, to_run, *, single_query=True):
return await self.__execute(to_run, single_query)
async def __execute(self, to_run, single_query):
timeout = aiohttp.ClientTimeout(total=5)
async with aiohttp.ClientSession(timeout=timeout) as session:
if single_query:
to_run = [to_run]
tasks = []
for task in to_run:
tasks.append(task["func"](session, *task["args"], **task["kwargs"]))
return await asyncio.gather(*tasks)
async def call(self, contract_address: str, method: str, stack: list) -> dict:
"""
Run contract's get method.
Returns stack dictionary like:
{'@extra': '1678643876',
'@type': 'smc.runResult',
'exit_code': 0,
'gas_used': 3918,
'stack': [['cell',
{'bytes': 'te6cckEBAQA...2C8Hn',
'object': {'data': {'b64': 'gAs4wlP...dUdIA==',
'len': 267},
'refs': []}}]]}
See examples/get_methods.py for more details.
"""
query = self.provider.raw_run_method(contract_address, method, stack)
timeout = aiohttp.ClientTimeout(total=5)
async with aiohttp.ClientSession(timeout=timeout) as session:
r = await query["func"](session, *query["args"], **query["kwargs"])
return r
async def get_transactions(
self,
address: str,
limit: int = 10,
from_lt: int = 0,
to_lt: int = 0,
archival: bool = True,
):
"""
Get transaction history of a given address.
"""
q = self.provider.raw_get_account_state(address)
async with aiohttp.ClientSession() as session:
r = await q["func"](
session,
"getTransactions",
params={
"address": address,
"limit": limit,
"lt": from_lt,
"to_lt": to_lt,
"archival": archival,
},
)
return r
async def send(self, boc: bytes):
q = self.provider.raw_send_message(boc)
async with aiohttp.ClientSession() as session:
r = await q["func"](session, *q["args"], **q["kwargs"])
return r
__all__ = ["TonCenterClient"]