import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:solana/solana.dart'; import '../pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; import '../providers/global/prefs_provider.dart'; import '../services/tor_service.dart'; import 'connection_check/electrum_connection_check.dart'; import 'logger.dart'; import 'test_epic_box_connection.dart'; import 'test_eth_node_connection.dart'; import 'test_monero_node_connection.dart'; import 'test_stellar_node_connection.dart'; import '../wallets/api/tezos/tezos_rpc_api.dart'; import '../wallets/crypto_currency/crypto_currency.dart'; import '../wallets/crypto_currency/interfaces/electrumx_currency_interface.dart'; import '../wallets/crypto_currency/intermediate/cryptonote_currency.dart'; import '../wallets/crypto_currency/intermediate/nano_currency.dart'; Future _xmrHelper( NodeFormData nodeFormData, BuildContext context, void Function(NodeFormData)? onSuccess, ) async { final data = nodeFormData; final url = data.host!; final port = data.port; final uri = Uri.parse(url); final String path = uri.path.isEmpty ? "/json_rpc" : uri.path; final uriString = "${uri.scheme}://${uri.host}:${port ?? 0}$path"; final response = await testMoneroNodeConnection( Uri.parse(uriString), false, ); if (response.cert != null) { if (context.mounted) { final shouldAllowBadCert = await showBadX509CertificateDialog( response.cert!, response.url!, response.port!, context, ); if (shouldAllowBadCert) { final response = await testMoneroNodeConnection(Uri.parse(uriString), true); onSuccess?.call(data..host = url); return response.success; } } } else { onSuccess?.call(data..host = url); return response.success; } return false; } // TODO: probably pull this into each coin's functionality otherwise updating this separately will get irritating Future testNodeConnection({ required BuildContext context, required NodeFormData nodeFormData, required CryptoCurrency cryptoCurrency, required WidgetRef ref, void Function(NodeFormData)? onSuccess, }) async { final formData = nodeFormData; bool testPassed = false; switch (cryptoCurrency) { case Epiccash(): try { final data = await testEpicNodeConnection(formData); if (data != null) { testPassed = true; onSuccess?.call(data); } } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Warning); } break; case CryptonoteCurrency(): try { final url = formData.host!; final uri = Uri.tryParse(url); if (uri != null) { if (!uri.hasScheme) { // try https first testPassed = await _xmrHelper( formData ..host = "https://$url" ..useSSL = true, context, onSuccess, ); if (testPassed == false) { // try http testPassed = await _xmrHelper( formData ..host = "http://$url" ..useSSL = false, context, onSuccess, ); } } else { testPassed = await _xmrHelper( formData ..host = url ..useSSL = true, context, onSuccess, ); } } } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Warning); } break; case ElectrumXCurrencyInterface(): case BitcoinFrost(): try { testPassed = await checkElectrumServer( host: formData.host!, port: formData.port!, useSSL: formData.useSSL!, overridePrefs: ref.read(prefsChangeNotifierProvider), overrideTorService: ref.read(pTorService), ); } catch (_) { testPassed = false; } break; case Ethereum(): try { testPassed = await testEthNodeConnection(formData.host!); } catch (_) { testPassed = false; } break; case Stellar(): try { testPassed = await testStellarNodeConnection(formData.host!, formData.port!); } catch (_) {} break; case NanoCurrency(): //TODO: check network/node throw UnimplementedError(); case Tezos(): try { testPassed = await TezosRpcAPI.testNetworkConnection( nodeInfo: (host: formData.host!, port: formData.port!), ); } catch (_) {} break; case Solana(): try { RpcClient rpcClient; if (formData.host!.startsWith("http") || formData.host!.startsWith("https")) { rpcClient = RpcClient("${formData.host}:${formData.port}"); } else { rpcClient = RpcClient("http://${formData.host}:${formData.port}"); } await rpcClient.getEpochInfo().then((value) => testPassed = true); } catch (_) { testPassed = false; } break; } return testPassed; }