2024-05-15 21:20:45 +00:00
|
|
|
import 'dart:async';
|
2024-06-12 21:12:53 +00:00
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:io';
|
2024-05-15 21:20:45 +00:00
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'package:solana/solana.dart';
|
2024-06-12 21:12:53 +00:00
|
|
|
|
|
|
|
import '../networking/http.dart';
|
2024-05-23 00:37:06 +00:00
|
|
|
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';
|
2024-06-12 21:12:53 +00:00
|
|
|
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';
|
2024-05-23 00:37:06 +00:00
|
|
|
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';
|
2024-05-15 21:20:45 +00:00
|
|
|
|
|
|
|
Future<bool> _xmrHelper(
|
|
|
|
NodeFormData nodeFormData,
|
|
|
|
BuildContext context,
|
|
|
|
void Function(NodeFormData)? onSuccess,
|
2024-06-12 21:12:53 +00:00
|
|
|
({
|
|
|
|
InternetAddress host,
|
|
|
|
int port,
|
|
|
|
})? proxyInfo,
|
2024-05-15 21:20:45 +00:00
|
|
|
) 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,
|
2024-06-12 21:12:53 +00:00
|
|
|
proxyInfo: proxyInfo,
|
2024-05-15 21:20:45 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
if (response.cert != null) {
|
|
|
|
if (context.mounted) {
|
|
|
|
final shouldAllowBadCert = await showBadX509CertificateDialog(
|
|
|
|
response.cert!,
|
|
|
|
response.url!,
|
|
|
|
response.port!,
|
|
|
|
context,
|
|
|
|
);
|
|
|
|
|
|
|
|
if (shouldAllowBadCert) {
|
2024-06-12 21:12:53 +00:00
|
|
|
final response = await testMoneroNodeConnection(
|
|
|
|
Uri.parse(uriString),
|
|
|
|
true,
|
|
|
|
proxyInfo: proxyInfo,
|
|
|
|
);
|
2024-05-15 21:20:45 +00:00
|
|
|
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 {
|
2024-06-12 21:12:53 +00:00
|
|
|
final proxyInfo = ref.read(prefsChangeNotifierProvider).useTor
|
|
|
|
? ref.read(pTorService).getProxyInfo()
|
|
|
|
: null;
|
|
|
|
|
2024-05-15 21:20:45 +00:00
|
|
|
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,
|
2024-06-12 21:12:53 +00:00
|
|
|
proxyInfo,
|
2024-05-15 21:20:45 +00:00
|
|
|
);
|
|
|
|
|
2024-06-12 21:12:53 +00:00
|
|
|
if (testPassed == false && context.mounted) {
|
2024-05-15 21:20:45 +00:00
|
|
|
// try http
|
|
|
|
testPassed = await _xmrHelper(
|
|
|
|
formData
|
|
|
|
..host = "http://$url"
|
|
|
|
..useSSL = false,
|
|
|
|
context,
|
|
|
|
onSuccess,
|
2024-06-12 21:12:53 +00:00
|
|
|
proxyInfo,
|
2024-05-15 21:20:45 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
testPassed = await _xmrHelper(
|
|
|
|
formData
|
|
|
|
..host = url
|
|
|
|
..useSSL = true,
|
|
|
|
context,
|
|
|
|
onSuccess,
|
2024-06-12 21:12:53 +00:00
|
|
|
proxyInfo,
|
2024-05-15 21:20:45 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} 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;
|
|
|
|
}
|