Files
FragmentAPI/app/utils/client.py
T
bohd4nx efcdda6b74 refactor: migrate to tonutils 2.0.0 and restructure codebase
- Migrate from tonutils 0.5.x to 2.0.0 API:
  - ToncenterClient → TonapiClient with NetworkGlobalID
  - tonutils.client → tonutils.clients
  - tonutils.wallet → tonutils.contracts.wallet
  - pub_key.as_hex property, wallet.balance nanotons
  - async with client context manager

- Centralize TON client init into initialize_ton_client() in wallet.py
- Move process_transaction logic into wallet.py, transaction.py re-exports
- Add WALLET_VERSION config (V4R2/V5R1, default V5R1)
- Add WALLET_CLASSES and SUPPORTED_WALLET_VERSIONS to constants.py
- Restore balance check before broadcasting
- Wait for seqno confirmation after transfer (120×2s) to prevent duplicate seqno

- Fix Fragment hash fetching: use browser navigation headers
- Remove accept-encoding from BASE_HEADERS (httpx handles decompression)
- Add cookies.example.json template
- Add cookies.json to .gitignore
2026-03-05 05:47:27 +02:00

44 lines
1.4 KiB
Python

import logging
from typing import Any
import httpx
from app.core.exceptions import RequestError, WalletError
from app.utils.wallet import link_wallet
logger = logging.getLogger(__name__)
def parse_json_response(response: httpx.Response, context: str) -> dict[str, Any]:
try:
return response.json()
except Exception as exc:
raise RequestError(
f"Fragment API returned an unparseable response for '{context}': {exc}"
) from exc
async def execute_transaction_request(
client: httpx.AsyncClient,
headers: dict,
cookies: dict,
account: dict[str, Any],
tx_data: dict[str, Any],
fragment_hash: str,
) -> dict[str, Any]:
url = f"https://fragment.com/api?hash={fragment_hash}"
resp = await client.post(url, headers=headers, cookies=cookies, data=tx_data)
transaction = parse_json_response(resp, tx_data.get("method", "transaction"))
if transaction.get("need_verify"):
if not await link_wallet(client, headers, cookies, account, fragment_hash):
raise WalletError(
"Failed to link your TON wallet to Fragment. "
"Make sure the wallet matching your cookies is used."
)
resp = await client.post(url, headers=headers, cookies=cookies, data=tx_data)
transaction = parse_json_response(resp, tx_data.get("method", "transaction"))
return transaction