update check ETH USDT USDC balance function
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
// adminUserHandler.js
|
||||
|
||||
import config from '../../config/config.js';
|
||||
import db from '../../config/database.js';
|
||||
import bot from "../../context/bot.js";
|
||||
import UserService from "../../services/userService.js";
|
||||
import WalletService from "../../services/walletService.js";
|
||||
import PurchaseService from "../../services/purchaseService.js";
|
||||
import userStates from "../../context/userStates.js";
|
||||
|
||||
export default class AdminUserHandler {
|
||||
@@ -146,25 +150,40 @@ export default class AdminUserHandler {
|
||||
|
||||
// Get recent transactions
|
||||
const transactions = await db.allAsync(`
|
||||
SELECT t.amount, t.created_at, t.wallet_type, t.tx_hash
|
||||
FROM transactions t
|
||||
JOIN users u ON t.user_id = u.id
|
||||
WHERE u.telegram_id = ?
|
||||
ORDER BY t.created_at DESC
|
||||
LIMIT 5
|
||||
`, [telegramId]);
|
||||
SELECT t.amount, t.created_at, t.wallet_type, t.tx_hash
|
||||
FROM transactions t
|
||||
JOIN users u ON t.user_id = u.id
|
||||
WHERE u.telegram_id = ?
|
||||
ORDER BY t.created_at DESC
|
||||
LIMIT 5
|
||||
`, [telegramId]);
|
||||
|
||||
// Get recent purchases
|
||||
const purchases = await db.allAsync(`
|
||||
SELECT p.quantity, p.total_price, p.purchase_date,
|
||||
pr.name as product_name
|
||||
FROM purchases p
|
||||
JOIN products pr ON p.product_id = pr.id
|
||||
JOIN users u ON p.user_id = u.id
|
||||
WHERE u.telegram_id = ?
|
||||
ORDER BY p.purchase_date DESC
|
||||
LIMIT 5
|
||||
`, [telegramId]);
|
||||
SELECT p.quantity, p.total_price, p.purchase_date,
|
||||
pr.name as product_name
|
||||
FROM purchases p
|
||||
JOIN products pr ON p.product_id = pr.id
|
||||
JOIN users u ON p.user_id = u.id
|
||||
WHERE u.telegram_id = ?
|
||||
ORDER BY p.purchase_date DESC
|
||||
LIMIT 5
|
||||
`, [telegramId]);
|
||||
|
||||
// Get pending purchases
|
||||
const pendingPurchases = await db.allAsync(`
|
||||
SELECT p.quantity, p.total_price, p.purchase_date,
|
||||
pr.name as product_name
|
||||
FROM purchases p
|
||||
JOIN products pr ON p.product_id = pr.id
|
||||
JOIN users u ON p.user_id = u.id
|
||||
WHERE u.telegram_id = ? AND p.status = 'pending'
|
||||
ORDER BY p.purchase_date DESC
|
||||
`, [telegramId]);
|
||||
|
||||
// Get wallet balances
|
||||
const activeWalletsBalance = await WalletService.getActiveWalletsBalance(user.id);
|
||||
const archivedWalletsBalance = await WalletService.getArchivedWalletsBalance(user.id);
|
||||
|
||||
const message = `
|
||||
👤 User Profile:
|
||||
@@ -175,16 +194,20 @@ ID: ${telegramId}
|
||||
📊 Activity:
|
||||
- Total Purchases: ${detailedUser.purchase_count}
|
||||
- Total Spent: $${detailedUser.total_spent || 0}
|
||||
- Active Wallets: ${detailedUser.crypto_wallet_count}
|
||||
- Active Wallets: ${detailedUser.crypto_wallet_count} ($${activeWalletsBalance.toFixed(2)})
|
||||
- Archived Wallets: ${detailedUser.archived_wallet_count} ($${archivedWalletsBalance.toFixed(2)})
|
||||
- Bonus Balance: $${user.bonus_balance || 0}
|
||||
- Total Balance: $${(user.total_balance || 0) + (user.bonus_balance || 0)}
|
||||
- Total Balance: $${((user.total_balance || 0) + (user.bonus_balance || 0)).toFixed(2)}
|
||||
|
||||
💰 Recent Transactions:
|
||||
${transactions.map(t => ` • ${t.amount} ${t.wallet_type} (${t.tx_hash})`).join('\n')}
|
||||
💰 Recent Transactions (Last 5 of ${transactions.length}):
|
||||
${transactions.map(t => ` • $${t.amount} ${t.wallet_type} (${t.tx_hash}) at ${new Date(t.created_at).toLocaleString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })}`).join('\n')}
|
||||
|
||||
🛍 Recent Purchases:
|
||||
🛍 Recent Purchases (Last 5 of ${purchases.length}):
|
||||
${purchases.map(p => ` • ${p.product_name} x${p.quantity} - $${p.total_price}`).join('\n')}
|
||||
|
||||
🕒 Pending Purchases:
|
||||
${pendingPurchases.map(p => ` • ${p.product_name} x${p.quantity} - $${p.total_price}`).join('\n') || ' • No pending purchases'}
|
||||
|
||||
📅 Registered: ${new Date(detailedUser.created_at).toLocaleString()}
|
||||
`;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ export default class UserHandler {
|
||||
├ Active Wallets: ${userStats.crypto_wallet_count || 0}
|
||||
├ Archived Wallets: ${userStats.archived_wallet_count || 0}
|
||||
├ Bonus Balance: $${userStats.bonus_balance || 0}
|
||||
└ Total Balance: $${(userStats.total_balance || 0) + (userStats.bonus_balance || 0)}
|
||||
└ Available Balance: $${(userStats.total_balance || 0) + (userStats.bonus_balance || 0)}
|
||||
|
||||
📅 Member since: ${new Date(userStats.created_at).toLocaleDateString()}
|
||||
`;
|
||||
|
||||
@@ -12,97 +12,107 @@ export default class UserWalletsHandler {
|
||||
const telegramId = msg.from.id;
|
||||
|
||||
try {
|
||||
const user = await UserService.getUserByTelegramId(telegramId.toString());
|
||||
const user = await UserService.getUserByTelegramId(telegramId.toString());
|
||||
|
||||
if (!user) {
|
||||
await bot.sendMessage(chatId, 'Profile not found. Please use /start to create one.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get active crypto wallets only
|
||||
const cryptoWallets = await db.allAsync(`
|
||||
SELECT wallet_type, address
|
||||
FROM crypto_wallets
|
||||
WHERE user_id = ?
|
||||
ORDER BY wallet_type
|
||||
`, [user.id]);
|
||||
|
||||
let message = '💰 *Your Active Wallets:*\n\n';
|
||||
|
||||
if (cryptoWallets.length > 0) {
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
cryptoWallets.find(w => w.wallet_type === 'BTC')?.address, // BTC address
|
||||
cryptoWallets.find(w => w.wallet_type === 'LTC')?.address, // LTC address
|
||||
cryptoWallets.find(w => w.wallet_type === 'ETH')?.address, // ETH address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDT')?.address, // USDT address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDC')?.address, // USDC address
|
||||
user.id,
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
|
||||
const balances = await walletUtilsInstance.getAllBalances();
|
||||
let totalUsdValue = 0;
|
||||
|
||||
// Show active wallets
|
||||
for (const [type, balance] of Object.entries(balances)) {
|
||||
const wallet = cryptoWallets.find(w => w.wallet_type === type.split(' ')[0]);
|
||||
|
||||
if (wallet) {
|
||||
message += `🔐 *${type}*\n`;
|
||||
message += `├ Balance: ${balance.amount.toFixed(8)} ${type.split(' ')[0]}\n`;
|
||||
message += `├ Value: $${balance.usdValue.toFixed(2)}\n`;
|
||||
message += `└ Address: \`${wallet.address}\`\n\n`;
|
||||
totalUsdValue += balance.usdValue;
|
||||
}
|
||||
if (!user) {
|
||||
await bot.sendMessage(chatId, 'Profile not found. Please use /start to create one.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Add total crypto balance
|
||||
message += `📊 *Total Crypto Balance:* $${totalUsdValue.toFixed(2)}\n`;
|
||||
// Пересчитываем баланс перед отображением
|
||||
await UserService.recalculateUserBalanceByTelegramId(telegramId);
|
||||
|
||||
// Add bonus balance
|
||||
message += `🎁 *Bonus Balance:* $${user.bonus_balance.toFixed(2)}\n`;
|
||||
// Получаем обновленные данные пользователя
|
||||
const updatedUser = await UserService.getUserByTelegramId(telegramId.toString());
|
||||
|
||||
// Add total balance
|
||||
const totalBalance = totalUsdValue + user.bonus_balance;
|
||||
message += `💰 *Total Balance:* $${totalBalance.toFixed(2)}\n`;
|
||||
} else {
|
||||
message = 'You don\'t have any active wallets yet.';
|
||||
}
|
||||
// Получаем активные криптокошельки
|
||||
const cryptoWallets = await db.allAsync(`
|
||||
SELECT wallet_type, address
|
||||
FROM crypto_wallets
|
||||
WHERE user_id = ?
|
||||
ORDER BY wallet_type
|
||||
`, [updatedUser.id]);
|
||||
|
||||
// Check if user has archived wallets
|
||||
const archivedCount = await WalletService.getArchivedWalletsCount(user);
|
||||
let message = '💰 *Your Active Wallets:*\n\n';
|
||||
|
||||
const keyboard = {
|
||||
inline_keyboard: [
|
||||
[
|
||||
{ text: '➕ Add Crypto Wallet', callback_data: 'add_wallet' },
|
||||
{ text: '💸 Top Up', callback_data: 'top_up_wallet' }
|
||||
],
|
||||
[{ text: '🔄 Refresh Balance', callback_data: 'refresh_balance' }]
|
||||
]
|
||||
};
|
||||
if (cryptoWallets.length > 0) {
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
cryptoWallets.find(w => w.wallet_type === 'BTC')?.address, // BTC address
|
||||
cryptoWallets.find(w => w.wallet_type === 'LTC')?.address, // LTC address
|
||||
cryptoWallets.find(w => w.wallet_type === 'ETH')?.address, // ETH address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDT')?.address, // USDT address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDC')?.address, // USDC address
|
||||
updatedUser.id,
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
|
||||
// Add archived wallets button if any exist
|
||||
if (archivedCount > 0) {
|
||||
keyboard.inline_keyboard.splice(2, 0, [
|
||||
{ text: `📁 Archived Wallets (${archivedCount})`, callback_data: 'view_archived_wallets' }
|
||||
const balances = await walletUtilsInstance.getAllBalances();
|
||||
let totalUsdValue = 0;
|
||||
|
||||
// Отображаем активные кошельки
|
||||
for (const [type, balance] of Object.entries(balances)) {
|
||||
const wallet = cryptoWallets.find(w => w.wallet_type === type.split(' ')[0]);
|
||||
|
||||
if (wallet) {
|
||||
message += `🔐 *${type}*\n`;
|
||||
message += `├ Balance: ${balance.amount.toFixed(8)} ${type.split(' ')[0]}\n`;
|
||||
message += `├ Value: $${balance.usdValue.toFixed(2)}\n`;
|
||||
message += `└ Address: \`${wallet.address}\`\n\n`;
|
||||
totalUsdValue += balance.usdValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Общий баланс криптовалют
|
||||
message += `📊 *Total Crypto Balance:* $${totalUsdValue.toFixed(2)}\n`;
|
||||
|
||||
// Бонусный баланс
|
||||
message += `🎁 *Bonus Balance:* $${updatedUser.bonus_balance.toFixed(2)}\n`;
|
||||
|
||||
// Общий баланс (крипто + бонусы)
|
||||
const totalBalance = totalUsdValue + updatedUser.bonus_balance;
|
||||
message += `💰 *Total Balance:* $${totalBalance.toFixed(2)}\n`;
|
||||
|
||||
// Доступный баланс (общий баланс минус расходы на покупки)
|
||||
const availableBalance = updatedUser.total_balance + updatedUser.bonus_balance;
|
||||
message += `💳 *Available Balance:* $${availableBalance.toFixed(2)}\n`;
|
||||
} else {
|
||||
message = 'You don\'t have any active wallets yet.';
|
||||
}
|
||||
|
||||
// Проверяем, есть ли архивные кошельки
|
||||
const archivedCount = await WalletService.getArchivedWalletsCount(updatedUser);
|
||||
|
||||
const keyboard = {
|
||||
inline_keyboard: [
|
||||
[
|
||||
{ text: '➕ Add Crypto Wallet', callback_data: 'add_wallet' },
|
||||
{ text: '💸 Top Up', callback_data: 'top_up_wallet' }
|
||||
],
|
||||
[{ text: '🔄 Refresh Balance', callback_data: 'refresh_balance' }]
|
||||
]
|
||||
};
|
||||
|
||||
// Добавляем кнопку архивных кошельков, если они есть
|
||||
if (archivedCount > 0) {
|
||||
keyboard.inline_keyboard.splice(2, 0, [
|
||||
{ text: `📁 Archived Wallets (${archivedCount})`, callback_data: 'view_archived_wallets' }
|
||||
]);
|
||||
}
|
||||
|
||||
// Добавляем кнопку истории транзакций
|
||||
keyboard.inline_keyboard.splice(3, 0, [
|
||||
{ text: '📊 Transaction History', callback_data: 'view_transaction_history_0' }
|
||||
]);
|
||||
}
|
||||
|
||||
// Add "Transaction History" button
|
||||
keyboard.inline_keyboard.splice(3, 0, [
|
||||
{ text: '📊 Transaction History', callback_data: 'view_transaction_history_0' }
|
||||
]);
|
||||
|
||||
await bot.sendMessage(chatId, message, {
|
||||
reply_markup: keyboard,
|
||||
parse_mode: 'Markdown'
|
||||
});
|
||||
await bot.sendMessage(chatId, message, {
|
||||
reply_markup: keyboard,
|
||||
parse_mode: 'Markdown'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in showBalance:', error);
|
||||
await bot.sendMessage(chatId, 'Error loading balance. Please try again.');
|
||||
console.error('Error in showBalance:', error);
|
||||
await bot.sendMessage(chatId, 'Error loading balance. Please try again.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async handleTransactionHistory(callbackQuery, page = 0) {
|
||||
const chatId = callbackQuery.message.chat.id;
|
||||
@@ -190,36 +200,126 @@ export default class UserWalletsHandler {
|
||||
const messageId = callbackQuery.message.message_id;
|
||||
|
||||
try {
|
||||
await bot.editMessageText(
|
||||
'🔄 Refreshing balances...',
|
||||
{
|
||||
chat_id: chatId,
|
||||
message_id: messageId
|
||||
// Отправляем промежуточный ответ на callback-запрос
|
||||
await bot.answerCallbackQuery(callbackQuery.id, { text: '🔄 Refreshing balances...' });
|
||||
|
||||
const user = await UserService.getUserByTelegramId(callbackQuery.from.id.toString());
|
||||
|
||||
if (!user) {
|
||||
await bot.sendMessage(chatId, 'Profile not found. Please use /start to create one.');
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
||||
// Re-fetch and display updated balances
|
||||
await this.showBalance({
|
||||
chat: { id: chatId },
|
||||
from: { id: callbackQuery.from.id }
|
||||
});
|
||||
// Получаем активные кошельки пользователя из таблицы crypto_wallets
|
||||
const activeWallets = await db.allAsync(`
|
||||
SELECT wallet_type, address
|
||||
FROM crypto_wallets
|
||||
WHERE user_id = ? AND wallet_type NOT LIKE '%#_%' ESCAPE '#'
|
||||
`, [user.id]);
|
||||
|
||||
// Delete the "refreshing" message
|
||||
await bot.deleteMessage(chatId, messageId);
|
||||
console.log('[DEBUG] Active wallets:', activeWallets); // Логируем активные кошельки
|
||||
|
||||
// Создаем объект для хранения адресов кошельков
|
||||
const walletAddresses = {
|
||||
btc: activeWallets.find(w => w.wallet_type === 'BTC')?.address || null,
|
||||
ltc: activeWallets.find(w => w.wallet_type === 'LTC')?.address || null,
|
||||
eth: activeWallets.find(w => w.wallet_type === 'ETH')?.address || null,
|
||||
usdt: activeWallets.find(w => w.wallet_type === 'USDT')?.address || null,
|
||||
usdc: activeWallets.find(w => w.wallet_type === 'USDC')?.address || null,
|
||||
};
|
||||
|
||||
console.log('[DEBUG] Wallet addresses:', walletAddresses); // Логируем адреса кошельков
|
||||
|
||||
// Используем getAllBalancesExt для обновления балансов
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
walletAddresses.btc, // BTC address
|
||||
walletAddresses.ltc, // LTC address
|
||||
walletAddresses.eth, // ETH address
|
||||
walletAddresses.usdt, // USDT address
|
||||
walletAddresses.usdc, // USDC address
|
||||
user.id,
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
|
||||
console.log('[DEBUG] Calling getAllBalancesExt...'); // Логируем вызов метода
|
||||
const balances = await walletUtilsInstance.getAllBalancesExt();
|
||||
console.log('[DEBUG] Balances:', balances); // Логируем полученные балансы
|
||||
|
||||
// Обновляем балансы в таблице crypto_wallets только если они изменились
|
||||
for (const [type, balance] of Object.entries(balances)) {
|
||||
// Определяем адрес кошелька для данного типа
|
||||
let address;
|
||||
switch (type) {
|
||||
case 'BTC':
|
||||
address = walletAddresses.btc;
|
||||
break;
|
||||
case 'LTC':
|
||||
address = walletAddresses.ltc;
|
||||
break;
|
||||
case 'ETH':
|
||||
address = walletAddresses.eth;
|
||||
break;
|
||||
case 'USDT ERC-20':
|
||||
address = walletAddresses.usdt;
|
||||
break;
|
||||
case 'USDC ERC-20':
|
||||
address = walletAddresses.usdc;
|
||||
break;
|
||||
default:
|
||||
console.warn(`[DEBUG] Unknown wallet type: ${type}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!address) {
|
||||
console.warn(`[DEBUG] Address not found for wallet type: ${type}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Получаем текущий баланс для данного адреса
|
||||
const currentBalance = await db.getAsync(`
|
||||
SELECT balance
|
||||
FROM crypto_wallets
|
||||
WHERE user_id = ? AND address = ?
|
||||
`, [user.id, address]);
|
||||
|
||||
// Проверяем, изменился ли баланс
|
||||
if (currentBalance?.balance !== balance.amount) {
|
||||
await db.runAsync(`
|
||||
UPDATE crypto_wallets
|
||||
SET balance = ?
|
||||
WHERE user_id = ? AND address = ?
|
||||
`, [balance.amount, user.id, address]); // Обновляем баланс по уникальному адресу
|
||||
console.log(`Баланс для ${type} (${address}) обновлен: ${currentBalance?.balance || 0} -> ${balance.amount}`);
|
||||
} else {
|
||||
console.log(`Баланс для ${type} (${address}) не изменился, обновление не требуется.`);
|
||||
}
|
||||
}
|
||||
|
||||
// Пересчитываем баланс пользователя
|
||||
await UserService.recalculateUserBalanceByTelegramId(callbackQuery.from.id);
|
||||
|
||||
// Отображаем обновленные балансы
|
||||
await this.showBalance({
|
||||
chat: { id: chatId },
|
||||
from: { id: callbackQuery.from.id }
|
||||
});
|
||||
|
||||
// Удаляем сообщение "Refreshing balances..."
|
||||
await bot.deleteMessage(chatId, messageId);
|
||||
} catch (error) {
|
||||
console.error('Error in handleRefreshBalance:', error);
|
||||
await bot.editMessageText(
|
||||
'❌ Error refreshing balances. Please try again.',
|
||||
{
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
reply_markup: {
|
||||
inline_keyboard: [[
|
||||
{ text: '« Back', callback_data: 'back_to_balance' }
|
||||
]]
|
||||
}
|
||||
}
|
||||
);
|
||||
console.error('Error in handleRefreshBalance:', error);
|
||||
|
||||
// Уведомляем пользователя об ошибке
|
||||
await bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Error refreshing balances. Please try again.' });
|
||||
|
||||
// Отправляем сообщение об ошибке в чат
|
||||
await bot.sendMessage(chatId, '❌ Error refreshing balances. Please try again.', {
|
||||
reply_markup: {
|
||||
inline_keyboard: [[
|
||||
{ text: '« Back', callback_data: 'back_to_balance' }
|
||||
]]
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,44 +727,6 @@ export default class UserWalletsHandler {
|
||||
}
|
||||
}
|
||||
|
||||
static async handleRefreshBalance(callbackQuery) {
|
||||
const chatId = callbackQuery.message.chat.id;
|
||||
const messageId = callbackQuery.message.message_id;
|
||||
|
||||
try {
|
||||
await bot.editMessageText(
|
||||
'🔄 Refreshing balances...',
|
||||
{
|
||||
chat_id: chatId,
|
||||
message_id: messageId
|
||||
}
|
||||
);
|
||||
|
||||
// Re-fetch and display updated balances
|
||||
await this.showBalance({
|
||||
chat: { id: chatId },
|
||||
from: { id: callbackQuery.from.id }
|
||||
});
|
||||
|
||||
// Delete the "refreshing" message
|
||||
await bot.deleteMessage(chatId, messageId);
|
||||
} catch (error) {
|
||||
console.error('Error in handleRefreshBalance:', error);
|
||||
await bot.editMessageText(
|
||||
'❌ Error refreshing balances. Please try again.',
|
||||
{
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
reply_markup: {
|
||||
inline_keyboard: [[
|
||||
{ text: '« Back', callback_data: 'back_to_balance' }
|
||||
]]
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static async handleBackToBalance(callbackQuery) {
|
||||
await this.showBalance({
|
||||
chat: { id: callbackQuery.message.chat.id },
|
||||
|
||||
Reference in New Issue
Block a user