79 lines
2.5 KiB
JavaScript
79 lines
2.5 KiB
JavaScript
/**
|
||
* Сервис получения балансов токенов пользователя из БД и RPC
|
||
*/
|
||
|
||
const { ethers } = require('ethers');
|
||
const db = require('../db');
|
||
const logger = require('../utils/logger');
|
||
|
||
async function getUserTokenBalances(address) {
|
||
if (!address) return [];
|
||
|
||
// Получаем ключ шифрования
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
let encryptionKey = 'default-key';
|
||
|
||
try {
|
||
const keyPath = path.join(__dirname, '../ssl/keys/full_db_encryption.key');
|
||
if (fs.existsSync(keyPath)) {
|
||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||
}
|
||
} catch (keyError) {
|
||
console.error('Error reading encryption key:', keyError);
|
||
}
|
||
|
||
// Получаем токены и RPC с расшифровкой
|
||
const tokensResult = await db.getQuery()(
|
||
'SELECT id, min_balance, created_at, updated_at, decrypt_text(name_encrypted, $1) as name, decrypt_text(address_encrypted, $1) as address, decrypt_text(network_encrypted, $1) as network FROM auth_tokens',
|
||
[encryptionKey]
|
||
);
|
||
const tokens = tokensResult.rows;
|
||
|
||
const rpcProvidersResult = await db.getQuery()(
|
||
'SELECT id, chain_id, created_at, updated_at, decrypt_text(network_id_encrypted, $1) as network_id, decrypt_text(rpc_url_encrypted, $1) as rpc_url FROM rpc_providers',
|
||
[encryptionKey]
|
||
);
|
||
const rpcProviders = rpcProvidersResult.rows;
|
||
const rpcMap = {};
|
||
for (const rpc of rpcProviders) {
|
||
rpcMap[rpc.network_id] = rpc.rpc_url;
|
||
}
|
||
|
||
const ERC20_ABI = ['function balanceOf(address owner) view returns (uint256)'];
|
||
const results = [];
|
||
|
||
for (const token of tokens) {
|
||
const rpcUrl = rpcMap[token.network];
|
||
if (!rpcUrl) continue;
|
||
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
||
const tokenContract = new ethers.Contract(token.address, ERC20_ABI, provider);
|
||
let balance = '0';
|
||
try {
|
||
const rawBalance = await tokenContract.balanceOf(address);
|
||
balance = ethers.formatUnits(rawBalance, 18);
|
||
if (!balance || isNaN(Number(balance))) balance = '0';
|
||
} catch (e) {
|
||
logger.error(
|
||
`[tokenBalanceService] Ошибка получения баланса для ${token.name} (${token.address}) в сети ${token.network}:`,
|
||
e
|
||
);
|
||
balance = '0';
|
||
}
|
||
results.push({
|
||
network: token.network,
|
||
tokenAddress: token.address,
|
||
tokenName: token.name,
|
||
symbol: token.symbol || '',
|
||
balance,
|
||
minBalance: token.min_balance,
|
||
});
|
||
}
|
||
|
||
return results;
|
||
}
|
||
|
||
module.exports = { getUserTokenBalances };
|
||
|
||
|