189 lines
6.8 KiB
JavaScript
189 lines
6.8 KiB
JavaScript
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
|
||
};
|
||
}
|