# Временное Test API для бесплатной загрузки аватаров в Arweave > Статус: **временное тестовое решение**. > Все операции из этого файла начинаются с `Test...`, чтобы это было видно сразу и в коде, и в UI. ## Назначение Этот временный API даёт пользователю ограниченную бесплатную загрузку маленьких аватаров в Arweave: - загрузка идёт через **серверный Arweave-кошелёк**; - лимит на пользователя: по умолчанию `3` загрузки за всё время; - лимит хранится в SQLite-таблице `test_free_avatar_uploads`; - если лимит исчерпан, сервер возвращает понятную ошибку; - загружать можно только маленький итоговый файл аватара, по умолчанию до `128 KB`. ## Настройки сервера В `application.properties`: ```properties test.freeAvatar.enabled=true test.freeAvatar.gateway=https://arweave.net test.freeAvatar.limitPerUser=3 test.freeAvatar.maxBytes=131072 test.freeAvatar.walletAddress= test.freeAvatar.walletJwkPath= ``` Пояснения: - `test.freeAvatar.enabled` - включить или выключить временный API; - `test.freeAvatar.gateway` - Arweave gateway для `price/tx/wallet`; - `test.freeAvatar.limitPerUser` - пожизненный бесплатный лимит на пользователя; - `test.freeAvatar.maxBytes` - максимальный размер итогового файла; - `test.freeAvatar.walletAddress` - публичный адрес серверного Arweave-кошелька; - `test.freeAvatar.walletJwkPath` - путь к приватному JWK-файлу серверного кошелька. Важно: - приватный JWK хранится вне кода; - если `walletAddress` указан и не совпадает с адресом, вычисленным из JWK, сервер вернёт ошибку настройки. ## `TestGetFreeAvatarQuota` Возвращает остаток бесплатных загрузок для текущего авторизованного пользователя. ### Запрос ```json { "op": "TestGetFreeAvatarQuota", "requestId": "req-test-avatar-quota-1", "payload": {} } ``` ### Успешный ответ ```json { "op": "TestGetFreeAvatarQuota", "requestId": "req-test-avatar-quota-1", "status": 200, "ok": true, "payload": { "enabled": true, "limit": 3, "usedCount": 1, "remainingCount": 2, "maxBytes": 131072 } } ``` ### Поля ответа - `enabled` - временный API сейчас включён на сервере или нет; - `limit` - полный лимит бесплатных загрузок; - `usedCount` - сколько уже израсходовано; - `remainingCount` - сколько ещё осталось; - `maxBytes` - максимальный размер итогового файла. ### Ошибки - `422 NOT_AUTHENTICATED` - требуется авторизация. ## `TestUploadFreeAvatar` Временная бесплатная загрузка маленькой аватарки в Arweave через серверный кошелёк. ### Правила - операция требует авторизованную сессию; - сервер использует текущий login из сессии; - сервер принимает только: - `image/jpeg` - `image/png` - `image/webp` - размер итогового файла должен быть не больше `maxBytes` из квоты; - если пользователь уже сделал `limit` бесплатных загрузок, операция запрещена. ### Запрос `fileBytesBase64` - это обычный Base64 байт итогового подготовленного файла. ```json { "op": "TestUploadFreeAvatar", "requestId": "req-test-avatar-upload-1", "payload": { "contentType": "image/webp", "fileBytesBase64": "UklGRiQAAABXRUJQVlA4WAoAAAAQAAAA...", "sha256Hex": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" } } ``` ### Успешный ответ ```json { "op": "TestUploadFreeAvatar", "requestId": "req-test-avatar-upload-1", "status": 200, "ok": true, "payload": { "txId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "sha256Hex": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "usedCount": 2, "remainingCount": 1, "limit": 3, "gateway": "https://arweave.net" } } ``` ### Поля ответа - `txId` - Arweave Transaction ID загруженного файла; - `sha256Hex` - SHA-256 загруженного файла; - `usedCount` - сколько бесплатных загрузок уже израсходовано после этой операции; - `remainingCount` - сколько бесплатных загрузок осталось; - `limit` - общий лимит; - `gateway` - gateway, через который сервер отправлял транзакцию. ### Ошибки - `422 NOT_AUTHENTICATED` - требуется авторизация; - `400 BAD_FIELDS` - не переданы `contentType` или `fileBytesBase64`; - `400 BAD_BASE64` - `fileBytesBase64` не декодируется; - `400 BAD_AVATAR_FILE` - файл не проходит ограничения сервера; - `400 FREE_AVATAR_LIMIT_EXHAUSTED` - бесплатный лимит аватарок исчерпан; - `501 FREE_AVATAR_TEMP_DISABLED` - временная функция выключена или сервер не настроен; - `500 INTERNAL_ERROR` - внутренняя ошибка сервера. ## Как это используется в UI На экране редактирования профиля в мастере смены аватара есть временный сценарий: - `Залить аватар бесплатно` UI: 1. вызывает `TestGetFreeAvatarQuota`; 2. показывает остаток лимита; 3. локально подготавливает уменьшенный файл аватара; 4. проверяет, что итоговый файл не превышает `maxBytes`; 5. вызывает `TestUploadFreeAvatar`; 6. после получения `txId` обычным путём записывает `avatar.ar` в профиль через `AddBlock`. ## Почему решение временное - используется общий серверный Arweave-кошелёк; - лимит хранится отдельной технической таблицей; - операции имеют префикс `Test...`; - сценарий нужен как переходный бесплатный путь для маленьких аватаров.