diff --git a/lib/bitcoin/electrum.dart b/lib/bitcoin/electrum.dart index 64569e416..71813ac3f 100644 --- a/lib/bitcoin/electrum.dart +++ b/lib/bitcoin/electrum.dart @@ -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 params) { final _params = params?.map((val) => '"${val.toString()}"')?.join(','); return '[$_params]'; @@ -54,17 +44,8 @@ class ElectrumClient { Timer _aliveTimer; String unterminatedString; - Future 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 connectToUri(Uri uri) async => + await connect(host: uri.host, port: uri.port); Future connect({@required String host, @required int port}) async { try { diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 18e8a362a..e8edd28aa 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -149,7 +149,7 @@ Future replaceNodesMigration({@required Box 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 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 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) { diff --git a/lib/entities/node.dart b/lib/entities/node.dart index 2636f9601..fe2823352 100644 --- a/lib/entities/node.dart +++ b/lib/entities/node.dart @@ -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; } 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; } @@ -98,8 +119,13 @@ class Node extends HiveObject with Keyable { } } - Future requestBitcoinElectrumServer() async { - // FIXME: IMPLEMENT ME - return true; + Future requestElectrumServer() async { + try { + await SecureSocket.connect(uri.host, uri.port, + timeout: Duration(seconds: 5), onBadCertificate: (_) => true); + return true; + } catch (_) { + return false; + } } } diff --git a/lib/main.dart b/lib/main.dart index 1a1724e3e..3871140ea 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -74,7 +74,7 @@ Future main() async { if (!Hive.isAdapterRegistered(Order.typeId)) { Hive.registerAdapter(OrderAdapter()); } - + final secureStorage = FlutterSecureStorage(); final transactionDescriptionsBoxKey = await getEncryptionKey( secureStorage: secureStorage, forKey: TransactionDescription.boxKey); diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index 6d7d41c4b..92742273c 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -152,7 +152,7 @@ abstract class MoneroWalletBase extends WalletBase