diff --git a/.gitignore b/.gitignore index 0b63ba5..77aca6d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,10 +20,6 @@ logs/ # Environment variables .env -# Test files -tests/ -*.test.py - # System files .DS_Store Thumbs.db diff --git a/app/core/constants.py b/app/core/constants.py index 700116f..14154a6 100644 --- a/app/core/constants.py +++ b/app/core/constants.py @@ -22,7 +22,6 @@ DEVICE: str = json.dumps({ # Each method merges these with its own "referer" and "x-aj-referer". BASE_HEADERS: dict[str, str] = { "accept": "application/json, text/javascript, */*; q=0.01", - "accept-encoding": "gzip, deflate, br, zstd", "accept-language": "en-US,en;q=0.9,uk;q=0.8,ru;q=0.7", "content-type": "application/x-www-form-urlencoded; charset=UTF-8", "origin": "https://fragment.com", diff --git a/app/utils/hash.py b/app/utils/hash.py index 8b5113c..2acd768 100644 --- a/app/utils/hash.py +++ b/app/utils/hash.py @@ -14,11 +14,19 @@ async def get_fragment_hash( headers: dict[str, str], page_url: str, ) -> str: + # Must look like a real browser navigation — not an XHR — otherwise Fragment + # returns JSON (no hash in it) instead of full HTML. page_headers = { - **headers, + k: v for k, v in headers.items() + if k not in ("accept", "accept-encoding", "content-type", "x-requested-with", "x-aj-referer") + } + page_headers.update({ "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "referer": "https://fragment.com/", - } + "sec-fetch-dest": "document", + "sec-fetch-mode": "navigate", + "upgrade-insecure-requests": "1", + }) async with httpx.AsyncClient(cookies=cookies) as client: response = await client.get(page_url, headers=page_headers) diff --git a/app/utils/transaction.py b/app/utils/transaction.py index ffa255f..3cf4ae3 100644 --- a/app/utils/transaction.py +++ b/app/utils/transaction.py @@ -1,7 +1,7 @@ import logging -from tonutils.client import ToncenterV3Client -from tonutils.wallet import WalletV5R1 +from tonutils.clients import ToncenterClient +from tonutils.contracts.wallet import WalletV5R1 from app.core import config from app.core.exceptions import TransactionError, WalletError @@ -19,15 +19,16 @@ async def process_transaction(transaction_data: dict) -> str: "The API response is missing expected 'transaction.messages' data." ) - client = ToncenterV3Client(api_key=config.API_KEY, is_testnet=False) + client = ToncenterClient(api_key=config.API_KEY) wallet, _, _, _ = WalletV5R1.from_mnemonic(client=client, mnemonic=config.SEED) # Check balance before broadcasting try: - balance = await wallet.balance() - if float(balance) < 0.056: + await wallet.refresh() + balance_ton = wallet.balance / 1_000_000_000 + if balance_ton < 0.056: raise WalletError( - f"TON wallet balance is too low: {balance} TON. " + f"TON wallet balance is too low: {balance_ton:.2f} TON. " "Minimum required is 0.056 TON." ) except WalletError: diff --git a/app/utils/wallet.py b/app/utils/wallet.py index 6b8dbc9..83be11f 100644 --- a/app/utils/wallet.py +++ b/app/utils/wallet.py @@ -4,8 +4,8 @@ import logging from typing import Any import httpx -from tonutils.client import ToncenterV3Client -from tonutils.wallet import WalletV5R1 +from tonutils.clients import ToncenterClient +from tonutils.contracts.wallet import WalletV5R1 from app.core import config from app.core.constants import DEVICE @@ -17,12 +17,12 @@ logger = logging.getLogger(__name__) async def get_account_info() -> dict[str, Any]: try: - client = ToncenterV3Client(api_key=config.API_KEY, is_testnet=False) + client = ToncenterClient(api_key=config.API_KEY) wallet, pub_key, _, _ = WalletV5R1.from_mnemonic(client=client, mnemonic=config.SEED) boc = wallet.state_init.serialize().to_boc() return { "address": wallet.address.to_str(False, False), - "publicKey": pub_key.hex(), + "publicKey": pub_key.as_hex, "chain": "-239", "walletStateInit": base64.b64encode(boc).decode(), } diff --git a/requirements.txt b/requirements.txt index 089c06d..ab531a7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ python-dotenv==1.2.2 asyncio==4.0.0 httpx==0.28.1 -tonutils==2.0.0 +tonutils[pytoniq]==2.0.0