# -*- coding: utf-8 -*- from ctypes import CDLL, c_void_p, c_char_p, c_double import logging import platform import inspect import pkg_resources import ujson as json from ton_client.utils import TonLibWrongResult logger = logging.getLogger(__name__) LIB_PATH = './libtonlibjson.dylib' def get_tonlib_path(): arch_name = platform.system().lower() if arch_name == 'darwin': lib_name = 'libtonlibjson.dylib' elif arch_name == 'linux': lib_name = 'libtonlibjson.so' else: raise RuntimeError('Platform could not be identified') return pkg_resources.resource_filename( 'ton_client', f'distlib/{arch_name}/{lib_name}' ) class Tonlib: def __init__(self, tonlib_path=get_tonlib_path()): tonlib = CDLL(tonlib_path) # load TDLib functions from shared library tonlib_json_client_create = tonlib.tonlib_client_json_create tonlib_json_client_create.restype = c_void_p tonlib_json_client_create.argtypes = [] self._client = tonlib_json_client_create() tonlib_json_client_receive = tonlib.tonlib_client_json_receive tonlib_json_client_receive.restype = c_char_p tonlib_json_client_receive.argtypes = [c_void_p, c_double] self._tonlib_json_client_receive = tonlib_json_client_receive tonlib_json_client_send = tonlib.tonlib_client_json_send tonlib_json_client_send.restype = None tonlib_json_client_send.argtypes = [c_void_p, c_char_p] self._tonlib_json_client_send = tonlib_json_client_send tonlib_json_client_execute = tonlib.tonlib_client_json_execute tonlib_json_client_execute.restype = c_char_p tonlib_json_client_execute.argtypes = [c_void_p, c_char_p] self._tonlib_json_client_execute = tonlib_json_client_execute tonlib_json_client_destroy = tonlib.tonlib_client_json_destroy tonlib_json_client_destroy.restype = None tonlib_json_client_destroy.argtypes = [c_void_p] self._tonlib_json_client_destroy = tonlib_json_client_destroy def __del__(self): self._tonlib_json_client_destroy(self._client) @staticmethod def hide_dict(d): return {k: '*' * len(str(v)) if k != '@type' else v for k, v in d.items()} def ton_send(self, query): if not isinstance(query, dict): raise TonLibWrongResult(f'query must be a dictionary, got {type(query)}') unhidden_query = json.dumps(query).encode('utf-8') self._tonlib_json_client_send(self._client, unhidden_query) fr = inspect.getouterframes(inspect.currentframe())[1] logger.debug(f'{fr.filename}:{fr.lineno} at {fr.function}() called ton_send({self.hide_dict(query)})') def ton_receive(self, timeout=30.0): result = self._tonlib_json_client_receive(self._client, timeout) if result: result = json.loads(result.decode('utf-8')) if not isinstance(result, dict): raise TonLibWrongResult(f'result must be a dictionary, got {type(result)}') fr = inspect.getouterframes(inspect.currentframe())[1] hidden_result = self.hide_dict(result) logger.debug(f'{fr.filename}:{fr.lineno} at {fr.function}() called ton_receive() -> {hidden_result}') return result def ton_async_execute(self, query, timeout=30.0): if not isinstance(query, dict): raise TonLibWrongResult(f'query must be a dictionary, got {type(query)}') unhidden_query = json.dumps(query).encode('utf-8') self._tonlib_json_client_send(self._client, unhidden_query) result = self._tonlib_json_client_receive(self._client, timeout) if result: result = json.loads(result.decode('utf-8')) if not isinstance(result, dict): raise TonLibWrongResult(f'result must be a dictionary, got {type(result)}') fr = inspect.getouterframes(inspect.currentframe())[1] hidden_query = self.hide_dict(query) hidden_result = self.hide_dict(result) logger.debug(f'{fr.filename}:{fr.lineno} at {fr.function}() called ton_async_execute({hidden_query}) -> {hidden_result}') return result def ton_sync_execute(self, query): if not isinstance(query, dict): raise TonLibWrongResult(f'query must be a dictionary, got {type(query)}') unhidden_query = json.dumps(query).encode('utf-8') result = self._tonlib_json_client_execute(None, unhidden_query) if result: result = json.loads(result.decode('utf-8')) if not isinstance(result, dict): raise TonLibWrongResult(f'result must be a dictionary, got {type(result)}') fr = inspect.getouterframes(inspect.currentframe())[1] hidden_query = self.hide_dict(query) hidden_result = self.hide_dict(result) logger.debug(f'{fr.filename}:{fr.lineno} at {fr.function}() called ton_sync_execute({hidden_query}) -> {hidden_result}') return result