# v0.8 — TRON онлайн-парсинг транзакций **Дата:** 2026-05-15 **Цель:** автоматически тянуть транзакции с трёх TRC20-кошельков, обновлять балансы, видеть всё в UI. ## ✅ Что сделано ### Бэкенд - **Таблица `raw_blockchain_tx`** + Alembic-миграция. UNIQUE по `(chain, tx_hash, from, to, amount)` — событие транзакции уникально. - **`app/jobs/tron_sync.py`** — парсер TronGrid: - GET `/v1/accounts/{addr}` → TRC20 баланс USDT - GET `/v1/accounts/{addr}/transactions/trc20` → история (пагинация по `fingerprint`, до 2000 tx за прогон на кошелёк). - Идемпотентный батч-upsert через PostgreSQL `INSERT ... ON CONFLICT DO NOTHING`. **Первый прогон: 624 новых tx. Второй прогон: 0 (всё уже в БД).** - Retry с exponential backoff на HTTP 429 (rate-limit). - Audit-запись после каждого кошелька. ### UI - **`/wallets`** — таблица с реальными балансами, счётчиком Tx за 24ч, временем последней транзакции, бейджем «Sync» (зелёный <65 мин / жёлтый <3 ч / красный больше). - **`/wallets/{id}`** — карточка кошелька: - 4 KPI: on-chain баланс / всего tx / приход / расход. - Прямая ссылка на TronScan для адреса. - Список последних 100 транзакций с направлением (↓ IN / ↑ OUT), суммой, контрагентом, ссылкой на конкретный tx hash на TronScan. ### Автоматизация - **systemd timer** `obmenka-tron-sync.timer`: `OnBootSec=2min`, `OnUnitActiveSec=1h`, `Persistent=true`. - Service выполнился вручную при первом запуске (LAST 25 сек назад в моменте релиза), следующий — через ~1 час. ## 📊 Реальные данные в системе ``` CryptoDom (TR2V4nd...EEk): балaнс 86 456.31 USDT | 165 tx | оборот ~2.62M USDT Лиман (TDobDuw...HPz): балaнс 94 067.94 USDT | 341 tx | оборот ~4.57M USDT Лара (TVfQRY...A2y): балaнс 49 146.04 USDT | 118 tx | оборот ~717k USDT ─────────────────────────────────────────────────────────────── Итого: 229 670.30 USDT на трёх кошельках, 624 транзакции с 2026-05-05 ``` ## ⚠ Что несовершенно (нашёл и исправил во время реализации) 1. **Баг с rollback на дубликатах.** Первая реализация делала `db.rollback()` при IntegrityError per-row — это откатывало ВСЮ открытую транзакцию SQLAlchemy, теряя предыдущие inserts. После первого прогона в БД было только 413 из 624 транзакций. **Исправил:** перешёл на batch-upsert через `pg_insert(...).on_conflict_do_nothing()` — теперь дубли просто пропускаются без отката. 2. **Rate-limit TronGrid без API-ключа очень строгий.** Второй прогон сразу же дал 429. Добавил: - 3 сек паузу между кошельками - 1 сек между balance и transfers одного кошелька - 0.5 сек между страницами пагинации - Retry с exponential backoff (5/10/20/40 сек) на 429 - На часовой интервал этого хватает с большим запасом. ## ⚠ Известные ограничения (на будущее) 1. **Только TRC20 USDT.** Если появятся другие токены/сети (ERC20, BEP20, BTC) — нужно расширить `CONTRACT_BY_ASSET` и/или добавить ETH-коннектор (Etherscan API). 2. **Старая история ограничена 2000 tx на кошелёк за прогон** (10 страниц × 200). Все три текущих кошелька укладываются. Если объём вырастет — увеличить `MAX_PAGES` или добавить инкрементальный sync (использовать `min_timestamp` параметр TronGrid). 3. **Нет связи raw_blockchain_tx ↔ deals.** Все 624 транзакции пока не привязаны к сделкам — `matched_deal_id` всегда NULL. Это задача **сверки**: матчить блокчейн-tx с операциями сделок по `wallet_id + amount + occurred_at ± окно`. Сделаем в следующем шаге. 4. **API без ключа** — TronGrid даёт ~5 запросов в секунду анонимно. Для одного-двух прогонов в час этого достаточно. Если будем добавлять кошельки — взять бесплатный ключ на trongrid.io (увеличит лимит до 100к запросов в день). 5. **Дашборд пока не использует `raw_blockchain_tx`** — там KPI всё ещё считаются из `deals`. Реальные обороты с блокчейна видны только на странице кошелька. Подключить on-chain объёмы к дашборду — на следующей итерации. ## Покрытие ТЗ партнёра после v0.8 | Модуль ТЗ | v0.7 | v0.8 | |---|---|---| | M1 учёт сделок | ✅ | ✅ | | M1 клиенты | ✅ | ✅ | | M2 касса | ✅ | ✅ | | M2 прибыль | ручная | ручная | | **(наш E2.5) on-chain ETL** | — | ✅ **полностью автоматически каждый час** | | M3 парсинг курсов TG | — | — (следующий шаг) | | M4 автопостинг TG | — | — | | M5 клиент-бот | — | — | | M6 карточка-заявка ⭐ | — | — | ## Следующие шаги 1. **Сверка `raw_blockchain_tx ↔ deals`** — авто-матчинг по wallet/amount/time. На странице сверки покажем непривязанные блокчейн-tx (потенциально незакрытые сделки) и непривязанные сделки (потенциально левак). 2. **M3 — парсинг курсов из TG-каналов** (если у тебя есть список каналов и формат сообщений). 3. **M4 — автопостинг наших курсов** в каналы. 4. **M5 + M6 — клиент-бот и автокарточка-заявка** менеджеру.