162 lines
6.6 KiB
JavaScript
162 lines
6.6 KiB
JavaScript
const express = require('express');
|
||
const router = express.Router();
|
||
const { requireAdmin } = require('../middleware/auth');
|
||
const logger = require('../utils/logger');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const { ethers } = require('ethers');
|
||
|
||
// Логируем версию ethers для отладки
|
||
logger.info(`Ethers version: ${ethers.version || 'unknown'}`);
|
||
|
||
// Путь к файлу с настройками
|
||
const RPC_CONFIG_PATH = path.join(__dirname, '../config/rpc-settings.json');
|
||
const AUTH_TOKENS_PATH = path.join(__dirname, '../config/auth-tokens.json');
|
||
|
||
// Вспомогательная функция для чтения настроек из файла
|
||
const readSettingsFile = (filePath, defaultValue = []) => {
|
||
try {
|
||
if (fs.existsSync(filePath)) {
|
||
const data = fs.readFileSync(filePath, 'utf8');
|
||
return JSON.parse(data);
|
||
}
|
||
return defaultValue;
|
||
} catch (error) {
|
||
logger.error(`Ошибка при чтении файла настроек ${filePath}:`, error);
|
||
return defaultValue;
|
||
}
|
||
};
|
||
|
||
// Вспомогательная функция для записи настроек в файл
|
||
const writeSettingsFile = async (filePath, data) => {
|
||
try {
|
||
// Создаем директорию, если не существует
|
||
const dirname = path.dirname(filePath);
|
||
if (!fs.existsSync(dirname)) {
|
||
fs.mkdirSync(dirname, { recursive: true });
|
||
}
|
||
|
||
await fs.promises.writeFile(filePath, JSON.stringify(data, null, 2), 'utf8');
|
||
return true;
|
||
} catch (error) {
|
||
logger.error(`Ошибка при записи файла настроек ${filePath}:`, error);
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// Получение RPC настроек
|
||
router.get('/rpc', requireAdmin, async (req, res) => {
|
||
try {
|
||
const rpcConfigs = readSettingsFile(RPC_CONFIG_PATH);
|
||
res.json({ success: true, data: rpcConfigs });
|
||
} catch (error) {
|
||
logger.error('Ошибка при получении RPC настроек:', error);
|
||
res.status(500).json({ success: false, error: 'Ошибка сервера при получении настроек RPC' });
|
||
}
|
||
});
|
||
|
||
// Сохранение RPC настроек
|
||
router.post('/rpc', requireAdmin, async (req, res) => {
|
||
try {
|
||
const { rpcConfigs } = req.body;
|
||
|
||
if (!Array.isArray(rpcConfigs)) {
|
||
return res.status(400).json({ success: false, error: 'Неверный формат данных' });
|
||
}
|
||
|
||
const success = await writeSettingsFile(RPC_CONFIG_PATH, rpcConfigs);
|
||
|
||
if (success) {
|
||
res.json({ success: true, message: 'RPC настройки успешно сохранены' });
|
||
} else {
|
||
res.status(500).json({ success: false, error: 'Ошибка при сохранении RPC настроек' });
|
||
}
|
||
} catch (error) {
|
||
logger.error('Ошибка при сохранении RPC настроек:', error);
|
||
res.status(500).json({ success: false, error: 'Ошибка сервера при сохранении настроек RPC' });
|
||
}
|
||
});
|
||
|
||
// Получение токенов для аутентификации
|
||
router.get('/auth-tokens', requireAdmin, async (req, res) => {
|
||
try {
|
||
const authTokens = readSettingsFile(AUTH_TOKENS_PATH);
|
||
res.json({ success: true, data: authTokens });
|
||
} catch (error) {
|
||
logger.error('Ошибка при получении токенов аутентификации:', error);
|
||
res.status(500).json({ success: false, error: 'Ошибка сервера при получении токенов аутентификации' });
|
||
}
|
||
});
|
||
|
||
// Сохранение токенов для аутентификации
|
||
router.post('/auth-tokens', requireAdmin, async (req, res) => {
|
||
try {
|
||
const { authTokens } = req.body;
|
||
|
||
if (!Array.isArray(authTokens)) {
|
||
return res.status(400).json({ success: false, error: 'Неверный формат данных' });
|
||
}
|
||
|
||
const success = await writeSettingsFile(AUTH_TOKENS_PATH, authTokens);
|
||
|
||
if (success) {
|
||
res.json({ success: true, message: 'Токены аутентификации успешно сохранены' });
|
||
} else {
|
||
res.status(500).json({ success: false, error: 'Ошибка при сохранении токенов аутентификации' });
|
||
}
|
||
} catch (error) {
|
||
logger.error('Ошибка при сохранении токенов аутентификации:', error);
|
||
res.status(500).json({ success: false, error: 'Ошибка сервера при сохранении токенов аутентификации' });
|
||
}
|
||
});
|
||
|
||
// Тестирование RPC соединения
|
||
router.post('/rpc-test', requireAdmin, async (req, res) => {
|
||
try {
|
||
const { rpcUrl, networkId } = req.body;
|
||
|
||
if (!rpcUrl || !networkId) {
|
||
return res.status(400).json({ success: false, error: 'Необходимо указать URL и ID сети' });
|
||
}
|
||
|
||
logger.info(`Тестирование RPC для ${networkId}: ${rpcUrl}`);
|
||
|
||
try {
|
||
// Пробуем создать провайдера и получить номер последнего блока (обновлено для ethers v6)
|
||
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
||
|
||
// Устанавливаем таймаут для соединения
|
||
const timeoutPromise = new Promise((_, reject) =>
|
||
setTimeout(() => reject(new Error('Таймаут соединения')), 10000)
|
||
);
|
||
|
||
// Пробуем получить номер последнего блока с таймаутом
|
||
const blockNumber = await Promise.race([
|
||
provider.getBlockNumber(),
|
||
timeoutPromise
|
||
]);
|
||
|
||
logger.info(`Успешное тестирование RPC для ${networkId}: ${rpcUrl}, номер блока: ${blockNumber}`);
|
||
|
||
res.json({
|
||
success: true,
|
||
message: `Успешное соединение с ${networkId}`,
|
||
blockNumber
|
||
});
|
||
} catch (providerError) {
|
||
logger.error(`Ошибка провайдера при тестировании RPC для ${networkId}: ${providerError.message}`);
|
||
res.status(500).json({
|
||
success: false,
|
||
error: providerError.message || 'Не удалось подключиться к RPC провайдеру'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
logger.error(`Неожиданная ошибка при тестировании RPC: ${error.message}`);
|
||
res.status(500).json({
|
||
success: false,
|
||
error: error.message || 'Неизвестная ошибка сервера'
|
||
});
|
||
}
|
||
});
|
||
|
||
module.exports = router;
|