From b8a5cf4965dad9593a204f7620dc70c0c1b6d525 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 13 Mar 2025 15:46:48 +0300 Subject: [PATCH] add highload wallet --- app/api/__init__.py | 3 ++- app/api/routes/_system.py | 21 +++++++++++++++++ app/core/background/ton_service.py | 36 ++++++++++++++++++++++++++++-- app/core/models/__init__.py | 2 ++ app/core/models/promo.py | 16 +++++++++++++ app/core/models/tasks.py | 24 ++++++++++++++++++++ app/core/projscale_logger.py | 2 +- requirements.txt | 2 +- 8 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 app/core/models/promo.py create mode 100644 app/core/models/tasks.py diff --git a/app/api/__init__.py b/app/api/__init__.py index 43ab01d..6295b28 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -12,7 +12,7 @@ app.register_middleware(attach_user_to_request, "request") app.register_middleware(close_db_session, "response") from app.api.routes._index import s_index, s_favicon -from app.api.routes._system import s_api_v1_node, s_api_system_version, s_api_system_send_status +from app.api.routes._system import s_api_v1_node, s_api_system_version, s_api_system_send_status, s_api_v1_node_friendly from app.api.routes.auth import s_api_v1_auth_twa from app.api.routes.statics import s_api_tonconnect_manifest, s_api_platform_metadata from app.api.routes.node_storage import s_api_v1_storage_post, s_api_v1_storage_get, \ @@ -29,6 +29,7 @@ app.add_route(s_index, "/", methods=["GET", "OPTIONS"]) app.add_route(s_favicon, "/favicon.ico", methods=["GET", "OPTIONS"]) app.add_route(s_api_v1_node, "/api/v1/node", methods=["GET", "OPTIONS"]) +app.add_route(s_api_v1_node_friendly, "/api/v1/nodeFriendly", methods=["GET", "OPTIONS"]) app.add_route(s_api_system_version, "/api/system.version", methods=["GET", "OPTIONS"]) app.add_route(s_api_system_send_status, "/api/system.sendStatus", methods=["POST", "OPTIONS"]) diff --git a/app/api/routes/_system.py b/app/api/routes/_system.py index 5727452..98acb24 100644 --- a/app/api/routes/_system.py +++ b/app/api/routes/_system.py @@ -38,6 +38,27 @@ async def s_api_v1_node(request): # /api/v1/node } }) +async def s_api_v1_node_friendly(request): + last_known_index = request.ctx.db_session.query(StoredContent).filter( + StoredContent.onchain_index != None + ).order_by(StoredContent.onchain_index.desc()).first() + last_known_index = last_known_index.onchain_index if last_known_index else 0 + last_known_index = max(last_known_index, 0) + response_plain_text = f""" + Node address: {service_wallet.address.to_string(1, 1, 1)} + Node ID: {b58encode(hot_pubkey).decode()} + Master address: {platform.address.to_string(1, 1, 1)} + Indexer height: {last_known_index} + Services: + """ + for service_key, service in request.app.ctx.memory.known_states.items(): + response_plain_text += f""" + {service_key}: + status: {service['status'] if (service['timestamp'] and (datetime.now() - service['timestamp']).total_seconds() < 30) else 'not working: timeout'} + delay: {round((datetime.now() - service['timestamp']).total_seconds(), 3) if service['timestamp'] else -1} + """ + return response.text(response_plain_text, content_type='text/plain') + async def s_api_system_send_status(request): if not request.json: diff --git a/app/core/background/ton_service.py b/app/core/background/ton_service.py index bca8872..7c62444 100644 --- a/app/core/background/ton_service.py +++ b/app/core/background/ton_service.py @@ -1,13 +1,19 @@ import asyncio import os +from sqlalchemy import and_ from tonsdk.boc import begin_cell +from tonsdk.contract.wallet import Wallets +from tonsdk.utils import HighloadQueryId +from datetime import datetime, timedelta from app.core._blockchain.ton.platform import platform from app.core._blockchain.ton.toncenter import toncenter +from app.core.models.tasks import BlockchainTask from app.core._config import MY_FUND_ADDRESS from app.core._secrets import service_wallet from app.core._utils.send_status import send_status +from app.core.storage import db_session from app.core.logger import make_log @@ -74,6 +80,25 @@ async def main_fn(memory): await send_status("ton_daemon", "working: deploying platform") await asyncio.sleep(15) return await main_fn(memory) + + highload_wallet = Wallets.ALL['hv3']( + private_key=service_wallet.private_key, + public_key=service_wallet.public_key, + wc=0 + ) + make_log("TON", f"Highload wallet address: {highload_wallet.address.to_string(1, 1, 1)}", level="info") + highload_state = await toncenter.get_account(highload_wallet.address.to_string(1, 1, 1)) + if not highload_state.get('code'): + make_log("TON", "Highload wallet contract is not deployed, send deploy transaction..", level="info") + created_at_ts = int(datetime.utcnow().timestamp()) - 60 + await toncenter.send_boc( + highload_wallet.create_transfer_message( + service_wallet.address.to_string(1, 1, 1), + 1, HighloadQueryId.from_seqno(0), created_at_ts, send_mode=1, payload="hello world", need_deploy=True + )['message'].to_boc(False) + ) + await asyncio.sleep(15) + return await main_fn(memory) while True: try: @@ -81,8 +106,15 @@ async def main_fn(memory): make_log("TON", f"Service running ({sw_seqno_value})", level="debug") # with db_session() as session: - # for stored_content in session.query(StoredContent).filter(StoredContent.uploaded == False).all(): - # pass + # next_task = session.query(BlockchainTask).filter( + # BlockchainTask.status == 'wait' + # ).first() + # if next_task: + # make_log("TON", f"Processing task {next_task.id}", level="info") + + # next_task.status = 'processing' + + # session.commit() await asyncio.sleep(5) await send_status("ton_daemon", f"working (seqno={sw_seqno_value})") diff --git a/app/core/models/__init__.py b/app/core/models/__init__.py index 475ff4f..9137a2d 100644 --- a/app/core/models/__init__.py +++ b/app/core/models/__init__.py @@ -11,3 +11,5 @@ from app.core.models.content.user_content import UserContent, UserAction from app.core.models._config import ServiceConfigValue, ServiceConfig from app.core.models.asset import Asset from app.core.models.my_network import KnownNode, KnownNodeIncident, RemoteContentIndex +from app.core.models.promo import PromoAction +from app.core.models.tasks import BlockchainTask diff --git a/app/core/models/promo.py b/app/core/models/promo.py new file mode 100644 index 0000000..8d565a2 --- /dev/null +++ b/app/core/models/promo.py @@ -0,0 +1,16 @@ +from .base import AlchemyBase +from sqlalchemy import Column, BigInteger, Integer, String, ForeignKey, DateTime, JSON, Boolean +from datetime import datetime + + +class PromoAction: + __tablename__ = 'promo_actions' + + id = Column(Integer, autoincrement=True, primary_key=True) + user_id = Column(String(512), nullable=False) + user_internal_id = Column(Integer, ForeignKey('users.id'), nullable=True) + + action_type = Column(String(64), nullable=False) # Type of action, e.g., 'referral', 'discount' + action_ref = Column(String(512), nullable=False) # Reference to the action, e.g., promo code + + created = Column(DateTime, nullable=False, default=datetime.now) diff --git a/app/core/models/tasks.py b/app/core/models/tasks.py new file mode 100644 index 0000000..ec0a80a --- /dev/null +++ b/app/core/models/tasks.py @@ -0,0 +1,24 @@ +from .base import AlchemyBase +from sqlalchemy import Column, BigInteger, Integer, String, ForeignKey, DateTime, JSON, Boolean +from datetime import datetime + + +class BlockchainTask: + __tablename__ = 'blockchain_tasks' + + id = Column(Integer, autoincrement=True, primary_key=True) + + destination = Column(String(1024), nullable=False) + payload = Column(String(1024), nullable=False) + + epoch = Column(Integer, nullable=True) + seqno = Column(Integer, nullable=True) + + created = Column(DateTime, nullable=False, default=datetime.now) + updated = Column(DateTime, nullable=False, default=datetime.now) + + meta = Column(JSON, nullable=False, default={}) + status = Column(String(256), nullable=False) + + transaction_hash = Column(String(1024), nullable=True) + transaction_lt = Column(String(1024), nullable=True) diff --git a/app/core/projscale_logger.py b/app/core/projscale_logger.py index 6651682..c5ad668 100644 --- a/app/core/projscale_logger.py +++ b/app/core/projscale_logger.py @@ -68,7 +68,7 @@ file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(logging.Formatter(FORMAT_STRING)) logger.addHandler(file_handler) -if os.getenv('APP_ENABLE_STDOUT_LOGS', '0') == '1': +if int(os.getenv('APP_ENABLE_STDOUT_LOGS', '0')) == 1: stdout_handler = logging.StreamHandler() stdout_handler.setLevel(logging.DEBUG) stdout_handler.setFormatter(logging.Formatter(FORMAT_STRING)) diff --git a/requirements.txt b/requirements.txt index ab07d7f..c3a449c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ pymysql==1.1.0 aiogram==3.13.0 pytonconnect==0.3.0 base58==2.1.1 -tonsdk==1.0.13 +git+https://github.com/tonfactory/tonsdk.git@3ebbf0b702f48c2519e4c6c425f9514f673b9d48#egg=tonsdk httpx==0.25.0 docker==7.0.0 pycryptodome==3.20.0