From 0c271e34826473326d2e509570a91d9d386cb44f Mon Sep 17 00:00:00 2001 From: user Date: Fri, 1 Mar 2024 23:44:09 +0300 Subject: [PATCH] dev@locazia: add ton_daemon --- app/__main__.py | 2 + app/core/_blockchain/ton/toncenter.py | 79 +++++++++++++++++++++++++++ app/core/_config.py | 3 + app/core/background/ton_service.py | 29 ++++++++++ docker-compose.yml | 18 ++++++ requirements.txt | 1 + 6 files changed, 132 insertions(+) create mode 100644 app/core/_blockchain/ton/toncenter.py create mode 100644 app/core/background/ton_service.py diff --git a/app/__main__.py b/app/__main__.py index d609a81..dd819d8 100644 --- a/app/__main__.py +++ b/app/__main__.py @@ -83,6 +83,8 @@ if __name__ == '__main__': from app.core.background.indexator_service import main as target_fn elif startup_target == 'uploader': from app.core.background.uploader_service import main as target_fn + elif startup_target == 'ton_daemon': + from app.core.background.ton_service import main as target_fn startup_fn = startup_fn or target_fn assert startup_fn diff --git a/app/core/_blockchain/ton/toncenter.py b/app/core/_blockchain/ton/toncenter.py new file mode 100644 index 0000000..c37deb9 --- /dev/null +++ b/app/core/_blockchain/ton/toncenter.py @@ -0,0 +1,79 @@ +from base64 import b64encode +from httpx import AsyncClient +from app.core.logger import make_log +from app.core._config import TONCENTER_HOST, TONCENTER_API_KEY +import asyncio +import time + + +class TonCenter: + def __init__(self, host: str, api_key: str = None, testnet: bool = False): + self.host = host + self.api_key = api_key + self.last_used = time.time() + + async def request(self, method: str, endpoint: str, *args, **kwargs) -> dict: + async with AsyncClient(headers={ + 'Authorization': f"Bearer {self.api_key}" + } if self.api_key else None) as client: + if self.api_key: + kwargs['headers'] = kwargs.get('headers', {}) + kwargs['headers']['X-API-Key'] = self.api_key + + if not self.api_key: + while time.time() < self.last_used + 1.2: + await asyncio.sleep(0.1) + + self.last_used = time.time() + response = await client.request(method, f"{self.host}{endpoint}", *args, **kwargs) + if response.status_code != 200: + raise Exception(f'Error while TONCENTER request {endpoint}: {response.text}') + + try: + return response.json() + except BaseException as e: + make_log("Toncenter", f'Error while request {endpoint}: {e}' + '\n' + response.text, level='error') + return await self.request(method, endpoint, *args, **kwargs) + + async def send_boc(self, src: bytes): + try: + res = await self.request( + "POST", 'sendBoc', + json={'boc': b64encode(src).decode()} + ) + except Exception as e: + make_log("Toncenter", f"sendBoc error: {e}", level='error') + return None + + make_log("Toncenter", f"sendBoc: {res}", level='debug') + return res + + async def get_account(self, addr: str): + return (await self.request( + "GET", 'getAddressInformation', + params={'address': addr} + )).get('result', {}) + + async def get_seqno(self, addr: str): + return (await self.request( + "GET", 'getWalletInformation', + params={'address': addr} + )).get('result', {}).get('seqno', 0) + + async def get_transactions(self, addr: str, limit: int = 10): + return (await self.request( + "GET", 'getTransactions', + params={'address': addr, 'limit': limit} + )).get('result', []) + + async def run_get_method(self, addr, method, stack=[]): + return (await self.request( + "POST", 'runGetMethod', json={ + 'address': addr, + 'method': method, + 'stack': stack if type(stack) == list else [] + } + )).get('result', {}) + + +toncenter = TonCenter(TONCENTER_HOST, TONCENTER_API_KEY) diff --git a/app/core/_config.py b/app/core/_config.py index 12ee0d6..1a728bb 100644 --- a/app/core/_config.py +++ b/app/core/_config.py @@ -36,3 +36,6 @@ ALLOWED_CONTENT_TYPES = [ 'video/mp4', 'video/webm', 'video/ogg', 'audio/mpeg', 'audio/ogg', 'audio/wav', ] + +TONCENTER_HOST = os.getenv('TONCENTER_HOST', 'https://toncenter.com/api/v1/') +TONCENTER_API_KEY = os.getenv('TONCENTER_API_KEY') diff --git a/app/core/background/ton_service.py b/app/core/background/ton_service.py new file mode 100644 index 0000000..4bd2713 --- /dev/null +++ b/app/core/background/ton_service.py @@ -0,0 +1,29 @@ + +from app.core.logger import make_log +from app.core.storage import db_session +from app.core._secrets import service_wallet +from app.core._blockchain.ton.toncenter import toncenter +import asyncio + + +async def main(): + make_log("TON", "Service started", level="info") + sw_seqno_result = await toncenter.run_get_method(service_wallet.address.to_string(1, 1, 1), 'seqno') + make_log("TON", f"Service wallet run seqno method: {sw_seqno_result}", level="info") + + while True: + make_log("TON", "Service running", level="debug") + # with db_session() as session: + # for stored_content in session.query(StoredContent).filter(StoredContent.uploaded == False).all(): + # pass + + await asyncio.sleep(5) + +if __name__ == '__main__': + loop = asyncio.get_event_loop() + loop.run_until_complete(main()) + loop.close() + + + + diff --git a/docker-compose.yml b/docker-compose.yml index 928e7ec..4c79291 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -66,3 +66,21 @@ services: depends_on: maria_db: condition: service_healthy + + ton_daemon: + build: + context: . + dockerfile: Dockerfile + command: python -m app ton_daemon + env_file: + - .env + links: + - maria_db + volumes: + - ./logs:/app/logs + - ./storedContent:/app/data + - ./activeConfig:/app/config + depends_on: + maria_db: + condition: service_healthy + diff --git a/requirements.txt b/requirements.txt index 4f8fcf3..a967f86 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ aiogram==3.4.1 pytonconnect==0.3.0 base58==2.1.1 tonsdk==1.0.13 +httpx==0.25.0