stack_wallet/lib/utilities/test_node_connection.dart
2024-05-27 18:01:41 -06:00

192 lines
5.2 KiB
Dart

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<bool> _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<bool> 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;
}