Files
DLE/frontend/src/composables/useBlockchainNetworks.js

189 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ref, computed } from 'vue';
import axios from 'axios';
/**
* Composable для работы с сетями блокчейн
* Предоставляет списки доступных сетей, URL RPC и функции для работы с ними
*/
export default function useBlockchainNetworks() {
// Группы сетей для отображения в интерфейсе
const networkGroups = [
{
label: 'Основные сети',
options: [
{ value: 'ethereum', label: 'Ethereum Mainnet', chainId: 1 },
{ value: 'bsc', label: 'Binance Smart Chain', chainId: 56 },
{ value: 'polygon', label: 'Polygon', chainId: 137 },
{ value: 'arbitrum', label: 'Arbitrum One', chainId: 42161 },
{ value: 'optimism', label: 'Optimism', chainId: 10 },
{ value: 'avalanche', label: 'Avalanche C-Chain', chainId: 43114 },
{ value: 'gnosis', label: 'Gnosis Chain (xDai)', chainId: 100 },
{ value: 'celo', label: 'Celo', chainId: 42220 },
{ value: 'fantom', label: 'Fantom Opera', chainId: 250 },
{ value: 'harmony', label: 'Harmony', chainId: 1666600000 },
{ value: 'metis', label: 'Metis Andromeda', chainId: 1088 },
{ value: 'aurora', label: 'Aurora', chainId: 1313161554 },
{ value: 'cronos', label: 'Cronos', chainId: 25 }
]
},
{
label: 'Тестовые сети',
options: [
{ value: 'sepolia', label: 'Sepolia (Ethereum testnet)', chainId: 11155111 },
{ value: 'goerli', label: 'Goerli (Ethereum testnet)', chainId: 5 },
{ value: 'holesky', label: 'Holesky (Ethereum testnet)', chainId: 17000 },
{ value: 'bsc-testnet', label: 'BSC Testnet', chainId: 97 },
{ value: 'mumbai', label: 'Mumbai (Polygon testnet)', chainId: 80001 },
{ value: 'arbitrum-goerli', label: 'Arbitrum Goerli', chainId: 421613 },
{ value: 'optimism-goerli', label: 'Optimism Goerli', chainId: 420 },
{ value: 'avalanche-fuji', label: 'Avalanche Fuji', chainId: 43113 },
{ value: 'fantom-testnet', label: 'Fantom Testnet', chainId: 4002 }
]
},
{
label: 'Локальные сети',
options: [
{ value: 'localhost', label: 'Localhost (Hardhat)', chainId: 31337 },
{ value: 'ganache', label: 'Ganache', chainId: 1337 }
]
},
{
label: 'Другое',
options: [
{ value: 'custom', label: 'Другая сеть (ввести вручную)', chainId: null }
]
}
];
// Создаем плоский список всех сетей для удобного использования в компонентах
const networks = computed(() => {
return networkGroups.flatMap(group => group.options);
});
// Объект для хранения выбранной сети и пользовательских значений
const networkEntry = ref({
networkId: '',
rpcUrl: '',
customNetworkId: '',
customChainId: null
});
// Функция для получения chainId по networkId
const getChainIdByNetworkId = (networkId) => {
for (const group of networkGroups) {
const option = group.options.find(opt => opt.value === networkId);
if (option) {
return option.chainId;
}
}
return null;
};
// Функция для добавления новой конфигурации сети
const validateAndPrepareNetworkConfig = () => {
let networkId = networkEntry.value.networkId;
const rpcUrl = networkEntry.value.rpcUrl.trim();
// Если выбрана опция "custom", используем пользовательский ID
if (networkId === 'custom') {
networkId = networkEntry.value.customNetworkId.trim();
if (!networkId) {
return { valid: false, error: 'Пожалуйста, введите пользовательский ID сети' };
}
}
if (!networkId || !rpcUrl) {
return { valid: false, error: 'Пожалуйста, выберите ID Сети и введите RPC URL' };
}
// Определяем chainId
let chainId = getChainIdByNetworkId(networkId);
if (!chainId && networkId === networkEntry.value.customNetworkId) {
chainId = networkEntry.value.customChainId;
}
return {
valid: true,
networkConfig: {
networkId,
rpcUrl,
chainId
}
};
};
// Функция сброса формы
const resetNetworkEntry = () => {
networkEntry.value.networkId = '';
networkEntry.value.rpcUrl = '';
networkEntry.value.customNetworkId = '';
networkEntry.value.customChainId = null;
};
// Функция получения списка всех доступных сетей в плоском формате
const getAllNetworks = () => {
return networks.value;
};
// Функция получения метаданных сети по ID
const getNetworkMetadata = (networkId) => {
return networks.value.find(network => network.value === networkId) || null;
};
// Состояние для тестирования RPC
const testingRpc = ref(false);
const testingRpcId = ref('');
// Функция для тестирования RPC-соединения
const testRpcConnection = async (networkId, rpcUrl) => {
testingRpc.value = true;
testingRpcId.value = networkId;
try {
// Формируем запрос на бэкенд для проверки RPC
const response = await axios.post('/api/settings/rpc-test', {
networkId,
rpcUrl
});
if (response.data && response.data.success) {
return {
success: true,
message: `Соединение с ${networkId} успешно установлено! Номер блока: ${response.data.blockNumber}`,
blockNumber: response.data.blockNumber
};
} else {
return {
success: false,
error: response.data?.error || 'Не удалось установить соединение'
};
}
} catch (error) {
console.error('[useBlockchainNetworks] Ошибка при тестировании RPC:', error);
return {
success: false,
error: error.response?.data?.error || error.message || 'Неизвестная ошибка'
};
} finally {
testingRpc.value = false;
testingRpcId.value = '';
}
};
return {
// Данные
networkGroups,
networkEntry,
testingRpc,
testingRpcId,
networks, // Экспортируем плоский список сетей
// Методы
getChainIdByNetworkId,
validateAndPrepareNetworkConfig,
resetNetworkEntry,
getAllNetworks,
getNetworkMetadata,
testRpcConnection
};
}