upgrade comission wallet function
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
version: "3.3"
|
version: "3.3"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
telegram_shop_prod:
|
telegram_shop_prod:
|
||||||
build:
|
build:
|
||||||
@@ -13,11 +12,11 @@ services:
|
|||||||
- ADMIN_IDS=732563549,390431690,217546867
|
- ADMIN_IDS=732563549,390431690,217546867
|
||||||
- SUPPORT_LINK=https://t.me/neroworm
|
- SUPPORT_LINK=https://t.me/neroworm
|
||||||
- CATALOG_PATH=./catalog
|
- CATALOG_PATH=./catalog
|
||||||
- COMMISSION_ENABLED=false
|
- COMMISSION_ENABLED=true
|
||||||
- COMMISSION_PERCENT=5
|
- COMMISSION_PERCENT=5
|
||||||
- COMMISSION_WALLET_BTC=bc1qyourbtcaddress
|
- COMMISSION_WALLET_BTC=bc1qyourbtcaddress
|
||||||
- COMMISSION_WALLET_LTC=ltc1qyourltcaddress
|
- COMMISSION_WALLET_LTC=ltc1qyourltcaddress
|
||||||
- COMMISSION_WALLET_USDT=0xYourUsdtAddress
|
- COMMISSION_WALLET_USDT=0x654dbef74cae96f19aa03e1b0abf569b111572cc
|
||||||
- COMMISSION_WALLET_USDC=0xYourUsdcAddress
|
- COMMISSION_WALLET_USDC=0xYourUsdcAddress
|
||||||
- COMMISSION_WALLET_ETH=0xYourEthAddress
|
- COMMISSION_WALLET_ETH=0xYourEthAddress
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
// adminWalletsHandler.js
|
// adminWalletsHandler.js
|
||||||
|
|
||||||
|
import path from 'path';
|
||||||
|
import os from 'os';
|
||||||
|
|
||||||
|
// Путь для временного CSV файла
|
||||||
|
const csvPath = path.join(os.tmpdir(), 'wallets_export.csv');
|
||||||
|
|
||||||
import bot from "../../context/bot.js";
|
import bot from "../../context/bot.js";
|
||||||
import config from '../../config/config.js';
|
import config from '../../config/config.js';
|
||||||
@@ -9,6 +14,26 @@ import fs from 'fs';
|
|||||||
import csvWriter from 'csv-writer';
|
import csvWriter from 'csv-writer';
|
||||||
|
|
||||||
export default class AdminWalletsHandler {
|
export default class AdminWalletsHandler {
|
||||||
|
static {
|
||||||
|
// Проверка конфигурации комиссий
|
||||||
|
if (config.COMMISSION_ENABLED) {
|
||||||
|
const requiredFields = ['COMMISSION_PERCENT', 'COMMISSION_WALLETS'];
|
||||||
|
const missingFields = requiredFields.filter(field => !config[field]);
|
||||||
|
|
||||||
|
if (missingFields.length > 0) {
|
||||||
|
throw new Error(`Missing required commission configuration fields: ${missingFields.join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка кошельков для комиссий
|
||||||
|
const requiredWallets = ['BTC', 'LTC', 'USDT', 'USDC', 'ETH'];
|
||||||
|
const missingWallets = requiredWallets.filter(wallet => !config.COMMISSION_WALLETS[wallet]);
|
||||||
|
|
||||||
|
if (missingWallets.length > 0) {
|
||||||
|
throw new Error(`Missing commission wallet addresses for: ${missingWallets.join(', ')}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Метод для проверки, является ли пользователь администратором
|
// Метод для проверки, является ли пользователь администратором
|
||||||
static isAdmin(userId) {
|
static isAdmin(userId) {
|
||||||
return config.ADMIN_IDS.includes(userId.toString());
|
return config.ADMIN_IDS.includes(userId.toString());
|
||||||
@@ -203,54 +228,88 @@ export default class AdminWalletsHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async calculateCommission(walletType, totalBalance) {
|
static async calculateCommission(walletType, totalBalance) {
|
||||||
if (!config.COMMISSION_ENABLED) {
|
try {
|
||||||
return 0;
|
if (!config.COMMISSION_ENABLED) {
|
||||||
}
|
console.log(`[${new Date().toISOString()}] Commissions disabled, returning 0`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const commissionPercent = config.COMMISSION_PERCENT / 100;
|
if (!config.COMMISSION_PERCENT) {
|
||||||
return totalBalance * commissionPercent;
|
throw new Error('Commission percentage not configured');
|
||||||
|
}
|
||||||
|
|
||||||
|
const commissionPercent = config.COMMISSION_PERCENT / 100;
|
||||||
|
const commissionAmount = totalBalance * commissionPercent;
|
||||||
|
|
||||||
|
console.log(`[${new Date().toISOString()}] Calculated commission for ${walletType}: ` +
|
||||||
|
`${commissionAmount.toFixed(8)} (${config.COMMISSION_PERCENT}% of ${totalBalance.toFixed(2)})`);
|
||||||
|
|
||||||
|
return commissionAmount;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[${new Date().toISOString()}] Error calculating commission:`, error);
|
||||||
|
throw new Error(`Failed to calculate commission: ${error.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async checkCommissionBalance(walletType, requiredAmount) {
|
static async checkCommissionBalance(walletType, requiredAmount) {
|
||||||
const commissionWallet = config.COMMISSION_WALLETS[walletType];
|
try {
|
||||||
if (!commissionWallet) {
|
console.log(`[${new Date().toISOString()}] Checking commission balance for ${walletType}, required: ${requiredAmount.toFixed(8)}`);
|
||||||
throw new Error(`Commission wallet not configured for ${walletType}`);
|
|
||||||
|
const commissionWallet = config.COMMISSION_WALLETS[walletType];
|
||||||
|
if (!commissionWallet) {
|
||||||
|
throw new Error(`Commission wallet not configured for ${walletType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[${new Date().toISOString()}] Using commission wallet: ${commissionWallet}`);
|
||||||
|
|
||||||
|
const walletUtils = new WalletUtils(
|
||||||
|
walletType === 'BTC' ? commissionWallet : null,
|
||||||
|
walletType === 'LTC' ? commissionWallet : null,
|
||||||
|
walletType === 'ETH' ? commissionWallet : null,
|
||||||
|
walletType === 'USDT' ? commissionWallet : null,
|
||||||
|
walletType === 'USDC' ? commissionWallet : null
|
||||||
|
);
|
||||||
|
|
||||||
|
let balance;
|
||||||
|
switch (walletType) {
|
||||||
|
case 'BTC':
|
||||||
|
console.log(`[${new Date().toISOString()}] Getting BTC balance`);
|
||||||
|
balance = await walletUtils.getBtcBalance();
|
||||||
|
break;
|
||||||
|
case 'LTC':
|
||||||
|
console.log(`[${new Date().toISOString()}] Getting LTC balance`);
|
||||||
|
balance = await walletUtils.getLtcBalance();
|
||||||
|
break;
|
||||||
|
case 'ETH':
|
||||||
|
console.log(`[${new Date().toISOString()}] Getting ETH balance`);
|
||||||
|
balance = await walletUtils.getEthBalance();
|
||||||
|
break;
|
||||||
|
case 'USDT':
|
||||||
|
console.log(`[${new Date().toISOString()}] Getting USDT balance`);
|
||||||
|
balance = await walletUtils.getUsdtErc20Balance();
|
||||||
|
break;
|
||||||
|
case 'USDC':
|
||||||
|
console.log(`[${new Date().toISOString()}] Getting USDC balance`);
|
||||||
|
balance = await walletUtils.getUsdcErc20Balance();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported wallet type: ${walletType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[${new Date().toISOString()}] Commission wallet balance: ${balance.toFixed(8)} ${walletType}`);
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
balance,
|
||||||
|
requiredAmount,
|
||||||
|
difference: balance - requiredAmount
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`[${new Date().toISOString()}] Commission check result:`, result);
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[${new Date().toISOString()}] Error checking commission balance:`, error);
|
||||||
|
throw new Error(`Failed to check commission balance: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const walletUtils = new WalletUtils(
|
|
||||||
walletType === 'BTC' ? commissionWallet : null,
|
|
||||||
walletType === 'LTC' ? commissionWallet : null,
|
|
||||||
walletType === 'ETH' ? commissionWallet : null,
|
|
||||||
walletType === 'USDT' ? commissionWallet : null,
|
|
||||||
walletType === 'USDC' ? commissionWallet : null
|
|
||||||
);
|
|
||||||
|
|
||||||
let balance;
|
|
||||||
switch (walletType) {
|
|
||||||
case 'BTC':
|
|
||||||
balance = await walletUtils.getBtcBalance();
|
|
||||||
break;
|
|
||||||
case 'LTC':
|
|
||||||
balance = await walletUtils.getLtcBalance();
|
|
||||||
break;
|
|
||||||
case 'ETH':
|
|
||||||
balance = await walletUtils.getEthBalance();
|
|
||||||
break;
|
|
||||||
case 'USDT':
|
|
||||||
balance = await walletUtils.getUsdtErc20Balance();
|
|
||||||
break;
|
|
||||||
case 'USDC':
|
|
||||||
balance = await walletUtils.getUsdcErc20Balance();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported wallet type: ${walletType}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
balance,
|
|
||||||
requiredAmount,
|
|
||||||
difference: balance - requiredAmount
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async handlePagination(callbackQuery) {
|
static async handlePagination(callbackQuery) {
|
||||||
@@ -292,6 +351,8 @@ export default class AdminWalletsHandler {
|
|||||||
const walletType = action.split('_').pop();
|
const walletType = action.split('_').pop();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
console.log(`[${new Date().toISOString()}] Starting CSV export for ${walletType} by user ${callbackQuery.from.id}`);
|
||||||
|
|
||||||
// Удаляем предыдущее сообщение перед отправкой нового
|
// Удаляем предыдущее сообщение перед отправкой нового
|
||||||
await bot.deleteMessage(chatId, callbackQuery.message.message_id);
|
await bot.deleteMessage(chatId, callbackQuery.message.message_id);
|
||||||
|
|
||||||
@@ -299,20 +360,24 @@ export default class AdminWalletsHandler {
|
|||||||
const wallets = await WalletService.getWalletsByType(walletType);
|
const wallets = await WalletService.getWalletsByType(walletType);
|
||||||
|
|
||||||
if (wallets.length === 0) {
|
if (wallets.length === 0) {
|
||||||
|
console.log(`[${new Date().toISOString()}] No wallets found for ${walletType}`);
|
||||||
await bot.sendMessage(chatId, `No wallets found for ${walletType}.`);
|
await bot.sendMessage(chatId, `No wallets found for ${walletType}.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Рассчитываем общий баланс
|
// Рассчитываем общий баланс
|
||||||
const totalBalance = await this.calculateTotalBalance(wallets);
|
const totalBalance = await this.calculateTotalBalance(wallets);
|
||||||
|
console.log(`[${new Date().toISOString()}] Total balance for ${walletType}: $${totalBalance.toFixed(2)}`);
|
||||||
|
|
||||||
// Проверяем, включены ли комиссии
|
// Проверяем, включены ли комиссии
|
||||||
if (config.COMMISSION_ENABLED) {
|
if (config.COMMISSION_ENABLED) {
|
||||||
// Рассчитываем комиссию
|
// Рассчитываем комиссию
|
||||||
const commissionAmount = await this.calculateCommission(walletType, totalBalance);
|
const commissionAmount = await this.calculateCommission(walletType, totalBalance);
|
||||||
|
console.log(`[${new Date().toISOString()}] Commission amount: ${commissionAmount.toFixed(8)} ${walletType}`);
|
||||||
|
|
||||||
// Проверяем баланс комиссионного кошелька
|
// Проверяем баланс комиссионного кошелька
|
||||||
const commissionCheck = await this.checkCommissionBalance(walletType, commissionAmount);
|
const commissionCheck = await this.checkCommissionBalance(walletType, commissionAmount);
|
||||||
|
console.log(`[${new Date().toISOString()}] Commission wallet balance: ${commissionCheck.balance.toFixed(8)} ${walletType}`);
|
||||||
|
|
||||||
if (commissionCheck.difference < 0) {
|
if (commissionCheck.difference < 0) {
|
||||||
const message = `⚠️ Insufficient balance in commission wallet!\n` +
|
const message = `⚠️ Insufficient balance in commission wallet!\n` +
|
||||||
@@ -324,12 +389,13 @@ export default class AdminWalletsHandler {
|
|||||||
const keyboard = {
|
const keyboard = {
|
||||||
inline_keyboard: [
|
inline_keyboard: [
|
||||||
[
|
[
|
||||||
{ text: '🔄 Проверить баланс', callback_data: `check_balance_${walletType}` },
|
{ text: '💳 Check Payment', callback_data: `check_balance_${walletType}` },
|
||||||
{ text: '⬅️ Назад', callback_data: `back_to_wallet_types` }
|
{ text: '⬅️ Back', callback_data: `back_to_wallet_types` }
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(`[${new Date().toISOString()}] Insufficient commission balance for ${walletType}`);
|
||||||
await bot.sendMessage(chatId, message, { reply_markup: keyboard });
|
await bot.sendMessage(chatId, message, { reply_markup: keyboard });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -399,7 +465,7 @@ export default class AdminWalletsHandler {
|
|||||||
|
|
||||||
// Создаем CSV-файл
|
// Создаем CSV-файл
|
||||||
const csv = csvWriter.createObjectCsvWriter({
|
const csv = csvWriter.createObjectCsvWriter({
|
||||||
path: `wallets_${walletType}.csv`,
|
path: csvPath,
|
||||||
header: [
|
header: [
|
||||||
{ id: 'address', title: 'Address' },
|
{ id: 'address', title: 'Address' },
|
||||||
{ id: 'balance', title: 'Balance' },
|
{ id: 'balance', title: 'Balance' },
|
||||||
@@ -411,14 +477,17 @@ export default class AdminWalletsHandler {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await csv.writeRecords(walletsWithData);
|
await csv.writeRecords(walletsWithData);
|
||||||
|
console.log(`[${new Date().toISOString()}] CSV file created at ${csvPath}`);
|
||||||
|
|
||||||
// Отправляем файл пользователю
|
// Отправляем файл пользователю
|
||||||
await bot.sendDocument(chatId, fs.createReadStream(`wallets_${walletType}.csv`));
|
await bot.sendDocument(chatId, fs.createReadStream(csvPath));
|
||||||
|
console.log(`[${new Date().toISOString()}] CSV file sent to user ${callbackQuery.from.id}`);
|
||||||
|
|
||||||
// Удаляем временный файл
|
// Удаляем временный файл
|
||||||
fs.unlinkSync(`wallets_${walletType}.csv`);
|
fs.unlinkSync(csvPath);
|
||||||
|
console.log(`[${new Date().toISOString()}] Temporary CSV file deleted`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error exporting wallets to CSV:', error);
|
console.error(`[${new Date().toISOString()}] Error exporting wallets to CSV:`, error);
|
||||||
await bot.sendMessage(chatId, 'Failed to export wallets to CSV. Please try again later.');
|
await bot.sendMessage(chatId, 'Failed to export wallets to CSV. Please try again later.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -429,14 +498,27 @@ export default class AdminWalletsHandler {
|
|||||||
const walletType = action.split('_').pop();
|
const walletType = action.split('_').pop();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
console.log(`[${new Date().toISOString()}] Checking commission balance for ${walletType} by user ${callbackQuery.from.id}`);
|
||||||
|
|
||||||
// Удаляем предыдущее сообщение перед отправкой нового
|
// Удаляем предыдущее сообщение перед отправкой нового
|
||||||
await bot.deleteMessage(chatId, callbackQuery.message.message_id);
|
await bot.deleteMessage(chatId, callbackQuery.message.message_id);
|
||||||
|
|
||||||
|
// Обновляем балансы всех кошельков
|
||||||
|
const walletUtils = new WalletUtils();
|
||||||
|
await walletUtils.getAllBalancesExt(walletType);
|
||||||
|
|
||||||
// Получаем все кошельки выбранного типа
|
// Получаем все кошельки выбранного типа
|
||||||
const wallets = await WalletService.getWalletsByType(walletType);
|
const wallets = await WalletService.getWalletsByType(walletType);
|
||||||
|
console.log(`[${new Date().toISOString()}] Found ${wallets.length} wallets for ${walletType}`);
|
||||||
|
|
||||||
const totalBalance = await this.calculateTotalBalance(wallets);
|
const totalBalance = await this.calculateTotalBalance(wallets);
|
||||||
|
console.log(`[${new Date().toISOString()}] Total balance: $${totalBalance.toFixed(2)}`);
|
||||||
|
|
||||||
const commissionAmount = await this.calculateCommission(walletType, totalBalance);
|
const commissionAmount = await this.calculateCommission(walletType, totalBalance);
|
||||||
|
console.log(`[${new Date().toISOString()}] Commission amount: ${commissionAmount.toFixed(8)} ${walletType}`);
|
||||||
|
|
||||||
const commissionCheck = await this.checkCommissionBalance(walletType, commissionAmount);
|
const commissionCheck = await this.checkCommissionBalance(walletType, commissionAmount);
|
||||||
|
console.log(`[${new Date().toISOString()}] Commission wallet balance: ${commissionCheck.balance.toFixed(8)} ${walletType}`);
|
||||||
|
|
||||||
if (commissionCheck.difference < 0) {
|
if (commissionCheck.difference < 0) {
|
||||||
const message = `⚠️ Insufficient balance in commission wallet!\n` +
|
const message = `⚠️ Insufficient balance in commission wallet!\n` +
|
||||||
@@ -448,20 +530,29 @@ export default class AdminWalletsHandler {
|
|||||||
const keyboard = {
|
const keyboard = {
|
||||||
inline_keyboard: [
|
inline_keyboard: [
|
||||||
[
|
[
|
||||||
{ text: '🔄 Проверить баланс', callback_data: `check_balance_${walletType}` },
|
{ text: '🔄 Check Balance', callback_data: `check_balance_${walletType}` },
|
||||||
{ text: '⬅️ Назад', callback_data: `back_to_wallet_types` }
|
{ text: '⬅️ Back', callback_data: `back_to_wallet_types` }
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(`[${new Date().toISOString()}] Insufficient commission balance for ${walletType}`);
|
||||||
await bot.sendMessage(chatId, message, { reply_markup: keyboard });
|
await bot.sendMessage(chatId, message, { reply_markup: keyboard });
|
||||||
} else {
|
} else {
|
||||||
// Если баланс достаточный, продолжаем экспорт
|
// Если баланс достаточный, продолжаем экспорт
|
||||||
|
console.log(`[${new Date().toISOString()}] Commission balance sufficient, proceeding with export`);
|
||||||
await this.exportCSV(chatId, walletType, wallets);
|
await this.exportCSV(chatId, walletType, wallets);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error checking commission balance:', error);
|
console.error(`[${new Date().toISOString()}] Error checking commission balance:`, error);
|
||||||
await bot.sendMessage(chatId, 'Failed to check commission balance. Please try again later.');
|
|
||||||
|
const errorMessage = error.response?.data?.message || error.message;
|
||||||
|
console.error(`[${new Date().toISOString()}] Error details:`, errorMessage);
|
||||||
|
|
||||||
|
await bot.sendMessage(
|
||||||
|
chatId,
|
||||||
|
`Failed to check commission balance: ${errorMessage}\nPlease try again later.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -343,6 +343,9 @@ bot.on('callback_query', async (callbackQuery) => {
|
|||||||
else if (action.startsWith('wallet_type_')) { // Добавляем обработку выбора типа кошелька
|
else if (action.startsWith('wallet_type_')) { // Добавляем обработку выбора типа кошелька
|
||||||
logDebug(action, 'handleWalletTypeSelection');
|
logDebug(action, 'handleWalletTypeSelection');
|
||||||
await adminWalletsHandler.handleWalletTypeSelection(callbackQuery);
|
await adminWalletsHandler.handleWalletTypeSelection(callbackQuery);
|
||||||
|
} else if (action.startsWith('check_balance_')) {
|
||||||
|
logDebug(action, 'handleCheckCommissionBalance');
|
||||||
|
await adminWalletsHandler.handleCheckCommissionBalance(callbackQuery);
|
||||||
} else if (action.startsWith('prev_page_') || action.startsWith('next_page_')) {
|
} else if (action.startsWith('prev_page_') || action.startsWith('next_page_')) {
|
||||||
logDebug(action, 'handlePagination');
|
logDebug(action, 'handlePagination');
|
||||||
await adminWalletsHandler.handlePagination(callbackQuery);
|
await adminWalletsHandler.handlePagination(callbackQuery);
|
||||||
@@ -381,4 +384,4 @@ process.on('unhandledRejection', (error) => {
|
|||||||
console.error('Unhandled promise rejection:', error);
|
console.error('Unhandled promise rejection:', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Bot is running...');
|
console.log('Bot is running...');
|
||||||
|
|||||||
Reference in New Issue
Block a user