# Документ совместимости API для web2-client ## Обзор Данный документ описывает спецификацию API эндпоинтов, необходимых для полной совместимости с web2-client. Это критически важно для миграции с Sanic на FastAPI без нарушения функциональности клиента. ## Критические эндпоинты для web2-client ### 1. Аутентификация через Telegram WebApp #### `POST /api/v1/auth.twa` **Текущая реализация:** [`s_api_v1_auth_twa()`](../app/api/routes/auth.py:16-121) **Запрос:** ```json { "twa_data": "string", // Telegram WebApp initData "ton_proof": { // Опционально "account": { "address": "string", "chain": "string", "publicKey": "string" }, "ton_proof": { "timestamp": "number", "domain": "string", "signature": "string", "payload": "string" } }, "ref_id": "string" // Опционально } ``` **Ответ:** ```json { "user": { "id": "number", "telegram_id": "number", "username": "string", "meta": { "first_name": "string", "last_name": "string", "photo_url": "string" } }, "connected_wallet": { "version": "string", "address": "string", "ton_balance": "string" // nanoTON bignum } | null, "auth_v1_token": "string" } ``` **Критические требования:** - Валидация TWA данных через TELEGRAM_API_KEY и CLIENT_TELEGRAM_API_KEY - Поддержка TON Proof для кошельков - Генерация JWT токена для последующих запросов - Сохранение wallet connections в БД #### `POST /api/v1/auth.selectWallet` **Текущая реализация:** [`s_api_v1_auth_select_wallet()`](../app/api/routes/auth.py:142-190) **Запрос:** ```json { "wallet_address": "string" // Raw или canonical адрес } ``` **Ответ:** ```http HTTP 200 OK ``` **Критические требования:** - Конвертация адреса в canonical формат через `Address.to_string(1, 1, 1)` - Создание новой WalletConnection записи - Проверка существования кошелька у пользователя ### 2. Загрузка файлов (Chunked Upload) #### `POST /api/v1/storage` **Текущая реализация:** [`s_api_v1_storage_post()`](../app/api/routes/node_storage.py:31-101) **Особенности web2-client:** **Обычная загрузка (файл <= 80MB):** ```http POST /api/v1/storage Content-Type: application/octet-stream Authorization: X-File-Name: X-Chunk-Start: 0 X-Last-Chunk: 1 ``` **Chunked загрузка (файл > 80MB):** ```http POST /api/v1/storage Content-Type: application/octet-stream Authorization: X-File-Name: X-Chunk-Start: X-Upload-ID: // Начиная с 2-го чанка X-Last-Chunk: 1 // Только для последнего чанка ``` **Ответ для промежуточных чанков:** ```json { "upload_id": "string", "current_size": "number" } ``` **Ответ для финального чанка:** ```json { "content_sha256": "string", "content_id": "string", // v2 формат "content_id_v1": "string", // v1 формат для совместимости "content_url": "string" // dmy://storage?cid=... } ``` **Критические требования:** - Поддержка заголовков `X-File-Name`, `X-Chunk-Start`, `X-Last-Chunk`, `X-Upload-ID` - Декодирование base64 имени файла - Chunked upload логика с промежуточным состоянием - Генерация SHA256 хэша и CID v1/v2 - Сохранение в StoredContent с типом "local/content_bin" ### 3. Скачивание файлов #### `GET /api/v1/storage/:content_id` **Текущая реализация:** [`s_api_v1_storage_get()`](../app/api/routes/node_storage.py:106-273) **Параметры запроса:** - `seconds_limit` (опционально) - ограничение длительности для аудио/видео **Ответ:** ```http Content-Type: <определяется автоматически> ``` **Критические требования:** - Разрешение CID через `resolve_content()` - Конвертация аудио в MP3 с обложкой (через pydub/AudioSegment) - Конвертация изображений в JPEG с компрессией до 200KB - Конвертация видео в MP4 с ffmpeg (с поддержкой seconds_limit) - Потоковая отдача файлов ### 4. Создание контента #### `POST /api/v1/blockchain.sendNewContentMessage` **Текущая реализация:** [`s_api_v1_blockchain_send_new_content_message()`](../app/api/routes/_blockchain.py:38-248) **Запрос:** ```json { "title": "string", "authors": ["string"], "content": "string", // CID контента "image": "string", // CID обложки "description": "string", "hashtags": ["string"], "price": "string", // nanoTON в строке "resaleLicensePrice": "string", // nanoTON (default = 0) "allowResale": "boolean", "royaltyParams": [{ "address": "string", "value": "number" // 10000 = 100% }], "downloadable": "boolean" // Опционально } ``` **Ответ для бесплатной загрузки (промо):** ```json { "address": "free", "amount": "30000000", // 0.03 TON в nanoTON "payload": "" } ``` **Ответ для обычной загрузки:** ```json { "address": "string", // Адрес platform "amount": "30000000", // 0.03 TON в nanoTON "payload": "string" // base64 BOC payload } ``` **Критические требования:** - Валидация royaltyParams (сумма = 10000) - Создание encrypted_content и metadata - Проверка PromoAction для бесплатных загрузок - Генерация BOC payload для транзакций - Интеграция с BlockchainTask ### 5. Покупка контента #### `POST /api/v1/blockchain.sendPurchaseContentMessage` **Текущая реализация:** [`s_api_v1_blockchain_send_purchase_content_message()`](../app/api/routes/_blockchain.py:251-295) **Запрос:** ```json { "content_address": "string", "license_type": "resale" // Только resale поддерживается } ``` **Ответ:** ```json { "address": "string", // Адрес контракта контента "amount": "string", // Цена в nanoTON "payload": "string" // base64 BOC payload } ``` ### 6. Просмотр контента #### `GET /api/v1/content.view/:content_id` **Требуется реализация** - отсутствует в текущем коде **Ожидаемый ответ:** ```json { "content": { "id": "string", "title": "string", "authors": ["string"], "description": "string", "price": "string", "metadata": "object" } } ``` ### 7. Декодирование CID #### `GET /api/v1/storage.decodeContentId/:content_id` **Текущая реализация:** [`s_api_v1_storage_decode_cid()`](../app/api/routes/node_storage.py:275-280) **Ответ:** ```json { "content_hash": "string", "accept_type": "string", // ... другие поля CID } ``` ## Аутентификация и заголовки ### Authorization Header ```http Authorization: ``` **Критические требования:** - JWT токен из localStorage - Middleware проверка токена - Установка `request.ctx.user` для авторизованных запросов ### Chunked Upload Headers ```http X-File-Name: X-Chunk-Start: X-Upload-ID: X-Last-Chunk: 1 // Только для последнего чанка ``` ## Middleware Requirements ### 1. Authentication Middleware - Проверка `Authorization` заголовка - Валидация JWT токенов - Установка `request.ctx.user` ### 2. Database Session Middleware - Создание `request.ctx.db_session` - Автоматический commit/rollback ### 3. CORS Middleware - Поддержка preflight запросов - Разрешение всех необходимых заголовков ## Форматы данных ### CID (Content Identifier) - **v1 формат**: для обратной совместимости - **v2 формат**: текущий стандарт - **Resolve функция**: `resolve_content()` для преобразования ### Wallet Addresses - **Raw формат**: принимается в запросах - **Canonical формат**: `Address.to_string(1, 1, 1)` для хранения ### File Hashes - **SHA256**: base58 encoding - **Storage path**: `UPLOADS_DIR/sha256_hash` ## Критические несовместимости ### 1. Missing Endpoints - `GET /api/v1/content.view/:content_id` - **ТРЕБУЕТ РЕАЛИЗАЦИИ** ### 2. Chunked Upload Protocol - Web2-client использует специфичные заголовки - Требует поддержки upload_id сессий - Необходима обработка `X-Last-Chunk` ### 3. File Processing - Автоматическая конвертация аудио/видео/изображений - Поддержка ffmpeg для видео - Генерация preview с обложками ### 4. Blockchain Integration - TON BOC payload генерация - PromoAction логика для бесплатных загрузок - BlockchainTask для отслеживания транзакций ## Рекомендации для FastAPI миграции ### 1. Точное сохранение API ```python @app.post("/api/v1/auth.twa") async def auth_twa(request: TelegramAuthRequest): # Точная реплика логики s_api_v1_auth_twa() ``` ### 2. Middleware Stack ```python app.add_middleware(CORSMiddleware) app.add_middleware(AuthenticationMiddleware) app.add_middleware(DatabaseSessionMiddleware) ``` ### 3. File Handling ```python from fastapi import UploadFile, Header from typing import Optional @app.post("/api/v1/storage") async def upload_file( file: bytes = Body(...), x_file_name: str = Header(..., alias="X-File-Name"), x_chunk_start: int = Header(0, alias="X-Chunk-Start"), x_upload_id: Optional[str] = Header(None, alias="X-Upload-ID"), x_last_chunk: Optional[int] = Header(None, alias="X-Last-Chunk") ): # Chunked upload логика ``` ### 4. Response Formats - Точное сохранение JSON структур - Обработка ошибок в том же формате - HTTP статус коды как в Sanic версии ## Заключение Для обеспечения 100% совместимости с web2-client необходимо: 1. **Сохранить все форматы запросов/ответов** 2. **Реализовать недостающие эндпоинты** 3. **Точно скопировать chunked upload протокол** 4. **Поддержать все middleware требования** 5. **Сохранить обработку файлов и конвертацию** **КРИТИЧЕСКИ ВАЖНО**: Любое изменение в API может сломать web2-client, поэтому миграция должна быть byte-perfect совместимой.