ваше сообщение коммита
This commit is contained in:
102
backend/services/admin-role.js
Normal file
102
backend/services/admin-role.js
Normal file
@@ -0,0 +1,102 @@
|
||||
const { ethers } = require('ethers');
|
||||
const logger = require('../utils/logger');
|
||||
const authTokenService = require('./authTokenService');
|
||||
const rpcProviderService = require('./rpcProviderService');
|
||||
|
||||
// Минимальный ABI для ERC20
|
||||
const ERC20_ABI = [
|
||||
'function balanceOf(address owner) view returns (uint256)'
|
||||
];
|
||||
|
||||
/**
|
||||
* Основной метод проверки роли админа
|
||||
* @param {string} address - Адрес кошелька
|
||||
* @returns {Promise<boolean>} - Является ли пользователь админом
|
||||
*/
|
||||
async function checkAdminRole(address) {
|
||||
if (!address) return false;
|
||||
logger.info(`Checking admin role for address: ${address}`);
|
||||
let foundTokens = false;
|
||||
let errorCount = 0;
|
||||
const balances = {};
|
||||
// Получаем токены и RPC из базы
|
||||
const tokens = await authTokenService.getAllAuthTokens();
|
||||
const rpcProviders = await rpcProviderService.getAllRpcProviders();
|
||||
const rpcMap = {};
|
||||
for (const rpc of rpcProviders) {
|
||||
rpcMap[rpc.network_id] = rpc.rpc_url;
|
||||
}
|
||||
const checkPromises = tokens.map(async (token) => {
|
||||
try {
|
||||
const rpcUrl = rpcMap[token.network];
|
||||
if (!rpcUrl) {
|
||||
logger.error(`No RPC URL for network ${token.network}`);
|
||||
balances[token.network] = 'Error: No RPC URL';
|
||||
errorCount++;
|
||||
return null;
|
||||
}
|
||||
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
||||
// Проверяем доступность сети с таймаутом
|
||||
try {
|
||||
const networkCheckPromise = provider.getNetwork();
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Network check timeout')), 3000)
|
||||
);
|
||||
await Promise.race([networkCheckPromise, timeoutPromise]);
|
||||
} catch (networkError) {
|
||||
logger.error(`Provider for ${token.network} is not available: ${networkError.message}`);
|
||||
balances[token.network] = 'Error: Network unavailable';
|
||||
errorCount++;
|
||||
return null;
|
||||
}
|
||||
const tokenContract = new ethers.Contract(token.address, ERC20_ABI, provider);
|
||||
const balancePromise = tokenContract.balanceOf(address);
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Timeout')), 3000)
|
||||
);
|
||||
const balance = await Promise.race([balancePromise, timeoutPromise]);
|
||||
const formattedBalance = ethers.formatUnits(balance, 18);
|
||||
balances[token.network] = formattedBalance;
|
||||
logger.info(`Token balance on ${token.network}:`, {
|
||||
address,
|
||||
contract: token.address,
|
||||
balance: formattedBalance,
|
||||
minBalance: token.min_balance,
|
||||
hasTokens: parseFloat(formattedBalance) >= parseFloat(token.min_balance),
|
||||
});
|
||||
if (parseFloat(formattedBalance) >= parseFloat(token.min_balance)) {
|
||||
logger.info(`Found admin tokens on ${token.network}`);
|
||||
foundTokens = true;
|
||||
}
|
||||
return { network: token.network, balance: formattedBalance };
|
||||
} catch (error) {
|
||||
logger.error(`Error checking balance in ${token.network}:`, {
|
||||
address,
|
||||
contract: token.address,
|
||||
error: error.message || 'Unknown error',
|
||||
});
|
||||
balances[token.network] = 'Error';
|
||||
errorCount++;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
await Promise.all(checkPromises);
|
||||
if (errorCount === tokens.length) {
|
||||
logger.error(`All network checks for ${address} failed. Cannot verify admin status.`);
|
||||
return false;
|
||||
}
|
||||
if (foundTokens) {
|
||||
logger.info(`Admin role summary for ${address}:`, {
|
||||
networks: Object.keys(balances).filter(
|
||||
(net) => parseFloat(balances[net]) > 0 && balances[net] !== 'Error'
|
||||
),
|
||||
balances,
|
||||
});
|
||||
logger.info(`Admin role granted for ${address}`);
|
||||
return true;
|
||||
}
|
||||
logger.info(`Admin role denied - no tokens found for ${address}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = { checkAdminRole };
|
||||
Reference in New Issue
Block a user