uploader-bot/docs/WEB2_CLIENT_API_COMPATIBILI...

12 KiB
Raw Blame History

Документ совместимости API для web2-client

Обзор

Данный документ описывает спецификацию API эндпоинтов, необходимых для полной совместимости с web2-client. Это критически важно для миграции с Sanic на FastAPI без нарушения функциональности клиента.

Критические эндпоинты для web2-client

1. Аутентификация через Telegram WebApp

POST /api/v1/auth.twa

Текущая реализация: s_api_v1_auth_twa()

Запрос:

{
    "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"    // Опционально
}

Ответ:

{
    "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()

Запрос:

{
    "wallet_address": "string"  // Raw или canonical адрес
}

Ответ:

HTTP 200 OK

Критические требования:

  • Конвертация адреса в canonical формат через Address.to_string(1, 1, 1)
  • Создание новой WalletConnection записи
  • Проверка существования кошелька у пользователя

2. Загрузка файлов (Chunked Upload)

POST /api/v1/storage

Текущая реализация: s_api_v1_storage_post()

Особенности web2-client:

Обычная загрузка (файл <= 80MB):

POST /api/v1/storage
Content-Type: application/octet-stream
Authorization: <auth_v1_token>
X-File-Name: <base64_encoded_filename>
X-Chunk-Start: 0
X-Last-Chunk: 1

<binary_file_data>

Chunked загрузка (файл > 80MB):

POST /api/v1/storage
Content-Type: application/octet-stream
Authorization: <auth_v1_token>
X-File-Name: <base64_encoded_filename>
X-Chunk-Start: <byte_offset>
X-Upload-ID: <upload_id>  // Начиная с 2-го чанка
X-Last-Chunk: 1           // Только для последнего чанка

<binary_chunk_data>

Ответ для промежуточных чанков:

{
    "upload_id": "string",
    "current_size": "number"
}

Ответ для финального чанка:

{
    "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()

Параметры запроса:

  • seconds_limit (опционально) - ограничение длительности для аудио/видео

Ответ:

Content-Type: <определяется автоматически>

<binary_file_data>

Критические требования:

  • Разрешение 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()

Запрос:

{
    "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"   // Опционально
}

Ответ для бесплатной загрузки (промо):

{
    "address": "free",
    "amount": "30000000",       // 0.03 TON в nanoTON
    "payload": ""
}

Ответ для обычной загрузки:

{
    "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()

Запрос:

{
    "content_address": "string",
    "license_type": "resale"    // Только resale поддерживается
}

Ответ:

{
    "address": "string",        // Адрес контракта контента
    "amount": "string",         // Цена в nanoTON
    "payload": "string"         // base64 BOC payload
}

6. Просмотр контента

GET /api/v1/content.view/:content_id

Требуется реализация - отсутствует в текущем коде

Ожидаемый ответ:

{
    "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()

Ответ:

{
    "content_hash": "string",
    "accept_type": "string",
    // ... другие поля CID
}

Аутентификация и заголовки

Authorization Header

Authorization: <auth_v1_token>

Критические требования:

  • JWT токен из localStorage
  • Middleware проверка токена
  • Установка request.ctx.user для авторизованных запросов

Chunked Upload Headers

X-File-Name: <base64_encoded_name>
X-Chunk-Start: <byte_offset>
X-Upload-ID: <upload_session_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

@app.post("/api/v1/auth.twa")
async def auth_twa(request: TelegramAuthRequest):
    # Точная реплика логики s_api_v1_auth_twa()

2. Middleware Stack

app.add_middleware(CORSMiddleware)
app.add_middleware(AuthenticationMiddleware)
app.add_middleware(DatabaseSessionMiddleware)

3. File Handling

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 совместимой.