diff --git a/src/models/User.js b/src/models/User.js index 405b778..80a66db 100644 --- a/src/models/User.js +++ b/src/models/User.js @@ -1,4 +1,5 @@ import db from '../config/database.js'; +import Wallet from "./Wallet.js"; export default class User { static async create(telegramId, username) { @@ -105,6 +106,22 @@ export default class User { } static async recalculateBalance(telegramId) { + const user = await User.getById(telegramId); + if (!user) { + return; + } + + const archivedBalance = await Wallet.getArchivedWalletsBalance(user.id); + const activeBalance = await Wallet.getActiveWalletsBalance(user.id); + + const purchases = await db.getAsync( + `SELECT SUM(total_price) as total_sum FROM purchases WHERE user_id = ?`, + [user.id] + ); + + const userTotalBalance = (activeBalance + archivedBalance) - (purchases?.total_sum || 0); + + await db.runAsync(`UPDATE users SET total_balance = ? WHERE id = ?`, [userTotalBalance, user.id]); } } \ No newline at end of file diff --git a/src/models/Wallet.js b/src/models/Wallet.js new file mode 100644 index 0000000..caa606b --- /dev/null +++ b/src/models/Wallet.js @@ -0,0 +1,121 @@ +import db from "../config/database.js"; +import WalletService from "../utils/walletService.js"; + +export default class Wallet { + static getBaseWalletType(walletType) { + if (walletType.includes('TRC-20')) return 'TRON'; + if (walletType.includes('ERC-20')) return 'ETH'; + return walletType; + } + + static async getArchivedWallets(userId) { + const archivedWallets = await db.allAsync(` + SELECT * FROM crypto_wallets WHERE user_id = ? AND wallet_type LIKE '%_%' + `, [userId]); + + const btcAddress = archivedWallets.find(w => w.wallet_type.startsWith('BTC'))?.address; + const ltcAddress = archivedWallets.find(w => w.wallet_type.startsWith('LTC'))?.address; + const tronAddress = archivedWallets.find(w => w.wallet_type.startsWith('TRON'))?.address; + const ethAddress = archivedWallets.find(w => w.wallet_type.startsWith('ETH'))?.address; + + return { + btc: btcAddress, + ltc: ltcAddress, + tron: tronAddress, + eth: ethAddress, + wallets: archivedWallets + } + } + + static async getActiveWallets(userId) { + const activeWallets = await db.allAsync( + `SELECT wallet_type, address FROM crypto_wallets WHERE user_id = ? ORDER BY wallet_type`, + [userId] + ) + + const btcAddress = activeWallets.find(w => w.wallet_type === 'BTC')?.address; + const ltcAddress = activeWallets.find(w => w.wallet_type === 'LTC')?.address; + const tronAddress = activeWallets.find(w => w.wallet_type === 'TRON')?.address; + const ethAddress = activeWallets.find(w => w.wallet_type === 'ETH')?.address; + + return { + btc: btcAddress, + ltc: ltcAddress, + tron: tronAddress, + eth: ethAddress, + wallets: activeWallets + } + } + + static async getActiveWalletsBalance(userId) { + const activeWallets = await this.getActiveWallets(userId); + + const walletService = new WalletService( + activeWallets.btc, + activeWallets.ltc, + activeWallets.tron, + activeWallets.eth, + userId, + Date.now() - 30 * 24 * 60 * 60 * 1000 + ); + + const balances = await walletService.getAllBalances(); + + let totalUsdBalance = 0; + + for (const [type, balance] of Object.entries(balances)) { + const baseType = this.getBaseWalletType(type); + const wallet = activeWallets.wallets.find(w => + w.wallet_type === baseType || + (type.includes('TRC-20') && w.wallet_type === 'TRON') || + (type.includes('ERC-20') && w.wallet_type === 'ETH') + ); + + if (!wallet) { + continue; + } + + if (wallet) { + totalUsdBalance += balance.usdValue; + } + } + + return totalUsdBalance; + } + + static async getArchivedWalletsBalance(userId) { + const archiveWallets = await this.getArchivedWallets(userId); + + const walletService = new WalletService( + archiveWallets.btc, + archiveWallets.ltc, + archiveWallets.tron, + archiveWallets.eth, + userId, + Date.now() - 30 * 24 * 60 * 60 * 1000 + ); + + const balances = await walletService.getAllBalances(); + + let totalUsdBalance = 0; + + for (const [type, balance] of Object.entries(balances)) { + const baseType = this.getBaseWalletType(type); + const wallet = archiveWallets.wallets.find(w => + w.wallet_type === baseType || + (type.includes('TRC-20') && w.wallet_type.startsWith('TRON')) || + (type.includes('ERC-20') && w.wallet_type.startsWith('ETH')) + ); + + if (!wallet) { + continue; + } + + if (wallet) { + totalUsdBalance += balance.usdValue; + } + } + + return totalUsdBalance; + } +} \ No newline at end of file