# Backend (server.js)

Единый файл ~8500 строк. Express.js, порт 8080.

## Запуск

```bash
pm2 start server.js --name wallet-app
```

## API Endpoints

### Сессии и авторизация

| Метод | Путь | Описание |
|-------|------|----------|
| POST | `/session/init` | Создание сессии (mnemonic, password, sessionLogin, isImport) |
| POST | `/session/get` | Получение сессии по sessionLogin |
| GET | `/session/get` | То же, GET |
| POST | `/session/activewallet/change` | Смена активного кошелька |
| POST | `/sessionwallet/name` | Переименование кошелька |
| POST | `/sessionwallet/delete` | Удаление кошелька из сессии |
| GET | `/api/sessions` | **Закрыт** (403 Forbidden) |

### Кошельки

| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/new-account/` | Генерация мнемоники (12 слов BIP39) |
| GET | `/check-account/:mnemonic` | Проверка существования кошелька |
| GET | `/derive-address` | Деривация адреса (?mnemonic=&coin=) |
| POST | `/address/override` | Переопределение адреса для токена |
| GET | `/api/wallets` | Список всех кошельков |
| GET | `/api/wallets/:id` | Кошелёк по ID |
| DELETE | `/api/wallets` | Удаление кошелька |

### Токены

| Метод | Путь | Описание |
|-------|------|----------|
| POST | `/api/token/address` | Адрес токена по мнемонике |
| POST | `/api/token/toggle` | Вкл/выкл видимости токена |
| POST | `/api/token/visibility` | Массовая настройка видимости |
| GET | `/api/token/visibility/:userId` | Видимость всех токенов пользователя |

### Стейкинг

| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/api/staking/rates` | Все APR (глобальные + индивидуальные) |
| GET | `/api/staking/config/:token` | Конфигурация стейкинга для токена |
| GET | `/api/staking/info` | Информация о стейкинге |
| POST | `/api/staking/stake` | Разместить в стейкинг |
| POST | `/api/staking/unstake` | Разблокировать |
| POST | `/api/staking/claim` | Забрать награды |
| POST | `/api/staking/process-rewards` | Ручной запуск начисления |

**Важно:** `POST /api/staking/stake` использует `getStakingConfigForWallet(token, mnemonicHash)` — т.е. при наличии индивидуального APR у кошелька (через `/setwalletapr`) позиция создаётся именно с ним. Каскад: wallet_staking_rates → staking_rates → STAKING_CONFIG.

### Обмен (Swap)

| Метод | Путь | Описание |
|-------|------|----------|
| POST | `/api/swap/execute` | Заморозка свопа (статус pending) |
| POST | `/api/swap/pending` | Ожидающие свопы |

Свопы обрабатываются фоновым таском `processPendingSwaps` каждые 2 секунды.

### Выводы

| Метод | Путь | Описание |
|-------|------|----------|
| POST | `/api/withdraw/create` | Создание заявки на вывод |
| GET | `/api/withdraw/history` | История выводов |
| PUT | `/api/withdraw/status` | Обновление статуса (botSecret) |

### Админ

| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/admin/api/wallets` | Кошельки (пагинация, поиск) |
| GET | `/admin/api/wallet/:id` | Детали кошелька |
| PATCH | `/admin/api/wallet/:id/comment` | Комментарий к кошельку |
| GET | `/admin/api/stats` | Статистика |

### Debug

| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/debug/status` | Статус сервера |
| GET | `/debug/health` | Health check |
| GET | `/debug/prices` | Текущие цены |
| GET | `/debug/derive` | Деривация адреса |

## Деривация адресов

Адреса генерируются из мнемоники через HD-кошельки (BIP32/BIP44). Основная функция: `generateAddressForTokenInfo(tokenInfo, mnemonic)`.

| Сеть | Путь деривации | Библиотека |
|------|---------------|------------|
| EVM (ETH, BNB, ARB) | m/44'/60'/0'/0/0 | ethers.js |
| TRX | m/44'/195'/0'/0/0 | deriveTronAddressFromPrivateKey |
| BTC | m/84'/0'/0'/0/0 | bip32 + bech32 |
| SOL | m/44'/501'/0' | ed25519-hd-key + tweetnacl |
| TON | m/44'/607'/0' | @ton/ton + @ton/crypto |
| XRP | m/44'/144'/0'/0/0 | @trustwallet/wallet-core |
| DOGE | m/44'/3'/0'/0/0 | bip32 + bs58 |
| LTC | m/84'/2'/0'/0/0 | @trustwallet/wallet-core |
| ADA | m/1852'/1815'/0'/0/0 | @emurgo/cardano-serialization-lib |
| SUI | m/44'/784'/0'/0'/0' | @mysten/sui |
| DOT | m/44'/354'/0'/0'/0' | blake2b |
| XLM, ATOM, NEAR, FIL, DASH, DCR, APT, ZEC, INJ, MNT, XCH | Специфичные | @trustwallet/wallet-core |

Адреса кэшируются в `addressCache = new Map()` для ускорения.

## Цены

- API: **CoinGecko** (`/api/v3/simple/price`)
- Кэш: 5 минут (`PRICE_CACHE_TTL`)
- Фоновое обновление: `setInterval` каждые 60 секунд
- Маппинг: `COINGECKO_IDS` (BTC→bitcoin, ETH→ethereum и т.д.)
- Цены не блокируют API-ответы (фоновые обновления)

## Сессии

- In-memory: `sessions = new Map()`
- Персистенция: таблица `sessions` в SQLite
- При старте: `restoreSessionsFromDB()`
- Очистка: сессии старше 30 дней удаляются

## Rate Limiting

| Лимитер | Лимит | Окно |
|---------|-------|------|
| authLimiter | 5 запросов | 15 мин |
| generalLimiter | 500 запросов | 15 мин |
| swapLimiter | Настраиваемый | — |
| stakingLimiter | Настраиваемый | — |

## Фоновые задачи

| Задача | Интервал | Описание |
|--------|----------|----------|
| updateCryptoPrices | 60 сек | Обновление цен через CoinGecko |
| processStakingRewards | 1 час | Начисление наград за стейкинг |
| processPendingSwaps | 2 сек | Обработка ожидающих свопов |

**Telegram-уведомления**: функция `sendWalletNotification` использует 3-retry логику — при неудаче отправки повторяет попытку до 3 раз с задержкой перед повтором.
