Fixes for LTC electrum nodes available.

This commit is contained in:
M 2021-05-10 19:00:20 +03:00
parent 9f9ec91eba
commit 1cb27d9da3
7 changed files with 64 additions and 53 deletions

View file

@ -8,16 +8,6 @@ import 'package:cake_wallet/bitcoin/script_hash.dart';
import 'package:flutter/foundation.dart';
import 'package:rxdart/rxdart.dart';
class UriParseException implements Exception {
UriParseException(this.uri);
final String uri;
@override
String toString() =>
'Cannot parse host and port from uri. Invalid uri format. Uri: $uri';
}
String jsonrpcparams(List<Object> params) {
final _params = params?.map((val) => '"${val.toString()}"')?.join(',');
return '[$_params]';
@ -54,17 +44,8 @@ class ElectrumClient {
Timer _aliveTimer;
String unterminatedString;
Future<void> connectToUri(String uri) async {
final splittedUri = uri.split(':');
if (splittedUri.length != 2) {
throw UriParseException(uri);
}
final host = splittedUri.first;
final port = int.parse(splittedUri.last);
await connect(host: host, port: port);
}
Future<void> connectToUri(Uri uri) async =>
await connect(host: uri.host, port: uri.port);
Future<void> connect({@required String host, @required int port}) async {
try {

View file

@ -149,7 +149,7 @@ Future<void> replaceNodesMigration({@required Box<Node> nodes}) async {
final nodeToReplace = replaceNodes[node.uri];
if (nodeToReplace != null) {
node.uri = nodeToReplace.uri;
node.uriRaw = nodeToReplace.uriRaw;
node.login = nodeToReplace.login;
node.password = nodeToReplace.password;
await node.save();
@ -319,11 +319,11 @@ Future<void> changeDefaultMoneroNode(
final currentMoneroNode =
nodeSource.values.firstWhere((node) => node.key == currentMoneroNodeId);
final needToReplaceCurrentMoneroNode =
currentMoneroNode.uri.contains(cakeWalletMoneroNodeUriPattern);
currentMoneroNode.uri.toString().contains(cakeWalletMoneroNodeUriPattern);
nodeSource.values.forEach((node) async {
if (node.type == WalletType.monero &&
node.uri.contains(cakeWalletMoneroNodeUriPattern)) {
node.uri.toString().contains(cakeWalletMoneroNodeUriPattern)) {
await node.delete();
}
});
@ -389,10 +389,10 @@ Future<void> resetBitcoinElectrumServer(
final currentElectrumSeverId =
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
final oldElectrumServer = nodeSource.values.firstWhere(
(node) => node.uri.contains('electrumx.cakewallet.com'),
(node) => node.uri.toString().contains('electrumx.cakewallet.com'),
orElse: () => null);
var cakeWalletNode = nodeSource.values.firstWhere(
(node) => node.uri == cakeWalletBitcoinElectrumUri,
(node) => node.uri.toString() == cakeWalletBitcoinElectrumUri,
orElse: () => null);
if (cakeWalletNode == null) {

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:cake_wallet/utils/mobx.dart';
import 'package:flutter/foundation.dart';
import 'dart:convert';
@ -8,19 +10,23 @@ import 'package:cake_wallet/entities/digest_request.dart';
part 'node.g.dart';
Uri createUriFromElectrumAddress(String address) =>
Uri.tryParse('tcp://$address');
@HiveType(typeId: Node.typeId)
class Node extends HiveObject with Keyable {
Node(
{@required this.uri,
{@required String uri,
@required WalletType type,
this.login,
this.password,
this.useSSL}) {
uriRaw = uri;
this.type = type;
}
Node.fromMap(Map map)
: uri = map['uri'] as String ?? '',
: uriRaw = map['uri'] as String ?? '',
login = map['login'] as String,
password = map['password'] as String,
typeRaw = map['typeRaw'] as int,
@ -30,7 +36,7 @@ class Node extends HiveObject with Keyable {
static const boxName = 'Nodes';
@HiveField(0)
String uri;
String uriRaw;
@HiveField(1)
String login;
@ -46,6 +52,19 @@ class Node extends HiveObject with Keyable {
bool get isSSL => useSSL ?? false;
Uri get uri {
switch (type) {
case WalletType.monero:
return Uri.http(uriRaw, '');
case WalletType.bitcoin:
return createUriFromElectrumAddress(uriRaw);
case WalletType.litecoin:
return createUriFromElectrumAddress(uriRaw);
default:
return null;
}
}
@override
dynamic get keyIndex {
_keyIndex ??= key;
@ -64,7 +83,9 @@ class Node extends HiveObject with Keyable {
case WalletType.monero:
return requestMoneroNode();
case WalletType.bitcoin:
return requestBitcoinElectrumServer();
return requestElectrumServer();
case WalletType.litecoin:
return requestElectrumServer();
default:
return false;
}
@ -80,15 +101,15 @@ class Node extends HiveObject with Keyable {
if (login != null && password != null) {
final digestRequest = DigestRequest();
final response = await digestRequest.request(
uri: uri, login: login, password: password);
uri: uri.toString(), login: login, password: password);
resBody = response.data as Map<String, dynamic>;
} else {
final url = Uri.http(uri, '/json_rpc');
final rpcUri = Uri.http(uri.toString(), '/json_rpc');
final headers = {'Content-type': 'application/json'};
final body =
json.encode({'jsonrpc': '2.0', 'id': '0', 'method': 'get_info'});
final response =
await http.post(url.toString(), headers: headers, body: body);
await http.post(rpcUri.toString(), headers: headers, body: body);
resBody = json.decode(response.body) as Map<String, dynamic>;
}
@ -98,8 +119,13 @@ class Node extends HiveObject with Keyable {
}
}
Future<bool> requestBitcoinElectrumServer() async {
// FIXME: IMPLEMENT ME
return true;
Future<bool> requestElectrumServer() async {
try {
await SecureSocket.connect(uri.host, uri.port,
timeout: Duration(seconds: 5), onBadCertificate: (_) => true);
return true;
} catch (_) {
return false;
}
}
}

View file

@ -152,7 +152,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
try {
syncStatus = ConnectingSyncStatus();
await monero_wallet.setupNode(
address: node.uri,
address: node.uri.toString(),
login: node.login,
password: node.password,
useSSL: node.isSSL,

View file

@ -7,19 +7,22 @@ import 'package:connectivity/connectivity.dart';
Timer _checkConnectionTimer;
void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore, {int timeInterval = 5}) {
void startCheckConnectionReaction(
WalletBase wallet, SettingsStore settingsStore,
{int timeInterval = 5}) {
_checkConnectionTimer?.cancel();
_checkConnectionTimer = Timer.periodic(Duration(seconds: timeInterval), (_) async {
final connectivityResult = await (Connectivity().checkConnectivity());
_checkConnectionTimer =
Timer.periodic(Duration(seconds: timeInterval), (_) async {
try {
final connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
wallet.syncStatus = FailedSyncStatus();
return;
}
if (connectivityResult == ConnectivityResult.none) {
wallet.syncStatus = FailedSyncStatus();
return;
}
if (wallet.syncStatus is LostConnectionSyncStatus ||
wallet.syncStatus is FailedSyncStatus) {
try {
if (wallet.syncStatus is LostConnectionSyncStatus ||
wallet.syncStatus is FailedSyncStatus) {
final alive =
await settingsStore.getCurrentNode(wallet.type).requestNode();
@ -27,9 +30,9 @@ void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore
await wallet.connectToNode(
node: settingsStore.getCurrentNode(wallet.type));
}
} catch (_) {
// FIXME: empty catch clojure
}
} catch (e) {
print(e.toString());
}
});
}

View file

@ -87,7 +87,7 @@ class NodeListPage extends BasePage {
final isSelected =
node.keyIndex == nodeListViewModel.currentNode?.keyIndex;
final nodeListRow = NodeListRow(
title: node.uri,
title: node.uriRaw,
isSelected: isSelected,
isAlive: node.requestNode(),
onTap: (_) async {
@ -101,8 +101,9 @@ class NodeListPage extends BasePage {
return AlertWithTwoActions(
alertTitle:
S.of(context).change_current_node_title,
alertContent:
S.of(context).change_current_node(node.uri),
alertContent: S
.of(context)
.change_current_node(node.uriRaw),
leftButtonText: S.of(context).cancel,
rightButtonText: S.of(context).change,
actionLeftButton: () =>