from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery
from config import ADMIN_ID, BOT_USERNAME
from db.storage import load_config, load_stats
from db.users import get, register, save
from keyboards.user import back_kb
from runtime import get_bot, get_log_bot
from services.withdrawals import create_crypto_check
from utils.logging import log_admin, safe_edit
router = Router(name="user")
def _get_profile(callback: CallbackQuery):
profile = get(callback.from_user.id)
if profile is None:
register(callback.from_user.id, callback.from_user.username)
profile = get(callback.from_user.id)
return profile
@router.callback_query(F.data == "profile")
async def cb_profile(callback: CallbackQuery, state: FSMContext):
await state.clear()
profile = _get_profile(callback)
cfg = load_config()
text = (
"Your profile\n\n"
f"ID: {profile.user_id}\n"
f"Registered: {profile.registered}\n\n"
f"Cookies loaded: {profile.cookies_loaded}\n"
f"Total earned: {profile.total_earned:.2f} RUB\n"
f"Referral earnings: {profile.referral_earned:.2f} RUB\n"
f"Balance: {profile.balance:.2f} RUB\n\n"
f"Referral link:\nhttps://t.me/{BOT_USERNAME}?start=ref_{profile.user_id}\n\n"
f"Referral payout: {cfg.referral_percent}%\n"
f"Minimum withdrawal: {cfg.min_withdraw:.2f} RUB"
)
await safe_edit(callback, text, reply_markup=back_kb())
await callback.answer()
@router.callback_query(F.data == "stats")
async def cb_stats(callback: CallbackQuery, state: FSMContext):
await state.clear()
stats = load_stats()
text = (
"Global statistics\n\n"
f"Users: {stats.total_users}\n"
f"Cookies: {stats.total_cookies}\n"
f"Direct payouts: {stats.total_paid_direct:.2f} RUB\n"
f"Referral payouts: {stats.total_paid_referral:.2f} RUB"
)
await safe_edit(callback, text, reply_markup=back_kb())
await callback.answer()
@router.callback_query(F.data == "rates")
async def cb_rates(callback: CallbackQuery, state: FSMContext):
await state.clear()
cfg = load_config()
text = "Current rates\n\n"
for rate in cfg.rates.values():
text += f"- {rate.name}: {rate.price:.2f} RUB\n"
text += (
f"\nAVG: {cfg.avg_min_cookies}+ donation cookies, "
f"{cfg.avg_min_price:.2f}-{cfg.avg_max_price:.2f} RUB per cookie."
)
await safe_edit(callback, text, reply_markup=back_kb())
await callback.answer()
@router.callback_query(F.data == "withdraw")
async def cb_withdraw(callback: CallbackQuery, state: FSMContext):
await state.clear()
profile = _get_profile(callback)
cfg = load_config()
if profile.balance < cfg.min_withdraw:
await safe_edit(
callback,
f"Insufficient balance: {profile.balance:.2f} RUB\n"
f"Minimum: {cfg.min_withdraw:.2f} RUB\n"
f"Treasury: {cfg.treasury:.2f} RUB",
reply_markup=back_kb(),
)
await callback.answer()
return
if profile.balance > cfg.treasury:
await safe_edit(
callback,
f"Treasury funds are insufficient: {cfg.treasury:.2f} RUB.",
reply_markup=back_kb(),
)
await callback.answer()
return
await callback.answer("Creating check...")
await safe_edit(callback, "Creating your CryptoBot check...")
amount = profile.balance
check_url = await create_crypto_check(amount)
if not check_url:
await safe_edit(callback, "Could not create the check. Try again later.", reply_markup=back_kb())
return
profile.balance = 0.0
save(profile.user_id, profile)
cfg.treasury = max(0.0, cfg.treasury - amount)
from db.storage import save_config
save_config(cfg)
await safe_edit(
callback,
f"Check created for {amount:.2f} RUB.\n"
f"Activate check",
reply_markup=back_kb(),
disable_web_page_preview=True,
)
bot = get_bot() or callback.message.bot
await log_admin(
bot,
ADMIN_ID,
f"Withdrawal\n@{profile.username or '-'} ({profile.user_id})\n"
f"Amount: {amount:.2f} RUB\nCheck: {check_url}",
get_log_bot(),
)