diff --git a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart index b14d81812..95822a25f 100644 --- a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart +++ b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart @@ -272,17 +272,27 @@ class _NameYourWalletViewState extends ConsumerState { SizedBox( height: isDesktop ? 16 : 8, ), - RoundedWhiteContainer( - child: Center( - child: Text( - "Roll the dice to pick a random name.", - style: isDesktop - ? STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ) - : STextStyles.itemSubtitle(context), + GestureDetector( + onTap: () async { + textEditingController.text = + await _generateRandomWalletName(); + setState(() { + _nextEnabled = true; + _showDiceIcon = false; + }); + }, + child: RoundedWhiteContainer( + child: Center( + child: Text( + "Roll the dice to pick a random name.", + style: isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ) + : STextStyles.itemSubtitle(context), + ), ), ), ), diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart index 32fa3974a..d34616567 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart @@ -70,20 +70,13 @@ class _AddEditNodeViewState extends ConsumerState { switch (coin) { case Coin.epicCash: try { - final uri = Uri.parse(formData.host!); - if (uri.scheme.startsWith("http")) { - final String path = uri.path.isEmpty ? "/v1/version" : uri.path; + final data = await testEpicNodeConnection(formData); - String uriString = - "${uri.scheme}://${uri.host}:${formData.port ?? 0}$path"; - - if (uri.host == "https") { - ref.read(nodeFormDataProvider).useSSL = true; - } else { - ref.read(nodeFormDataProvider).useSSL = false; - } - - testPassed = await testEpicBoxNodeConnection(Uri.parse(uriString)); + if (data != null) { + testPassed = true; + ref.read(nodeFormDataProvider).host = data.host; + ref.read(nodeFormDataProvider).port = data.port; + ref.read(nodeFormDataProvider).useSSL = data.useSSL; } } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Warning); @@ -315,7 +308,7 @@ class _AddEditNodeViewState extends ConsumerState { // strip unused path String address = formData.host!; - if (coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash) { + if (coin == Coin.monero || coin == Coin.wownero) { if (address.startsWith("http")) { final uri = Uri.parse(address); address = "${uri.scheme}://${uri.host}"; @@ -673,6 +666,7 @@ class _NodeFormState extends ConsumerState { bool _useSSL = false; bool _isFailover = false; int? port; + late bool enableSSLCheckbox; late final bool enableAuthFields; @@ -692,9 +686,9 @@ class _NodeFormState extends ConsumerState { case Coin.bitcoincashTestnet: case Coin.firoTestNet: case Coin.dogecoinTestNet: + case Coin.epicCash: return false; - case Coin.epicCash: case Coin.monero: case Coin.wownero: return true; @@ -768,11 +762,19 @@ class _NodeFormState extends ConsumerState { _usernameController.text = node.loginName ?? ""; _useSSL = node.useSSL; _isFailover = node.isFailover; + if (widget.coin == Coin.epicCash) { + enableSSLCheckbox = !node.host.startsWith("http"); + } + print("enableSSLCheckbox: $enableSSLCheckbox"); WidgetsBinding.instance.addPostFrameCallback((_) { // update provider state object so test connection works without having to modify a field in the ui first _updateState(); }); + } else { + enableSSLCheckbox = true; + // default to port 3413 + // _portController.text = "3413"; } super.initState(); @@ -858,9 +860,7 @@ class _NodeFormState extends ConsumerState { focusNode: _hostFocusNode, style: STextStyles.field(context), decoration: standardInputDecoration( - (widget.coin != Coin.monero && - widget.coin != Coin.wownero && - widget.coin != Coin.epicCash) + (widget.coin != Coin.monero && widget.coin != Coin.wownero) ? "IP address" : "Url", _hostFocusNode, @@ -886,6 +886,17 @@ class _NodeFormState extends ConsumerState { : null, ), onChanged: (newValue) { + if (widget.coin == Coin.epicCash) { + if (newValue.startsWith("https://")) { + _useSSL = true; + enableSSLCheckbox = false; + } else if (newValue.startsWith("http://")) { + _useSSL = false; + enableSSLCheckbox = false; + } else { + enableSSLCheckbox = true; + } + } _updateState(); setState(() {}); }, @@ -1040,20 +1051,18 @@ class _NodeFormState extends ConsumerState { const SizedBox( height: 8, ), - if (widget.coin != Coin.monero && - widget.coin != Coin.wownero && - widget.coin != Coin.epicCash) + if (widget.coin != Coin.monero && widget.coin != Coin.wownero) Row( children: [ GestureDetector( - onTap: widget.readOnly - ? null - : () { + onTap: !widget.readOnly && enableSSLCheckbox + ? () { setState(() { _useSSL = !_useSSL; }); _updateState(); - }, + } + : null, child: Container( color: Colors.transparent, child: Row( @@ -1062,22 +1071,22 @@ class _NodeFormState extends ConsumerState { width: 20, height: 20, child: Checkbox( - fillColor: widget.readOnly - ? MaterialStateProperty.all(Theme.of(context) + fillColor: !widget.readOnly && enableSSLCheckbox + ? null + : MaterialStateProperty.all(Theme.of(context) .extension()! - .checkboxBGDisabled) - : null, + .checkboxBGDisabled), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, value: _useSSL, - onChanged: widget.readOnly - ? null - : (newValue) { + onChanged: !widget.readOnly && enableSSLCheckbox + ? (newValue) { setState(() { _useSSL = newValue!; }); _updateState(); - }, + } + : null, ), ), const SizedBox( diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart index 24af0e78e..ad8ad7301 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart @@ -70,14 +70,15 @@ class _NodeDetailsViewState extends ConsumerState { switch (coin) { case Coin.epicCash: try { - final uri = Uri.parse(node!.host); - if (uri.scheme.startsWith("http")) { - final String path = uri.path.isEmpty ? "/v1/version" : uri.path; - String uriString = "${uri.scheme}://${uri.host}:${node.port}$path"; + testPassed = await testEpicNodeConnection( + NodeFormData() + ..host = node!.host + ..useSSL = node.useSSL + ..port = node.port, + ) != + null; - testPassed = await testEpicBoxNodeConnection(Uri.parse(uriString)); - } } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Warning); testPassed = false; diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart index 7187c5311..0cc85d77c 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart @@ -18,7 +18,6 @@ import 'package:stackwallet/providers/global/secure_store_provider.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; -import 'package:stackwallet/utilities/enums/flush_bar_type.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; @@ -218,8 +217,10 @@ class _EditAutoBackupViewState extends ConsumerState { passwordController.text = ""; passwordRepeatController.text = ""; - Navigator.of(context) - .popUntil(ModalRoute.withName(AutoBackupView.routeName)); + if (!Util.isDesktop) { + Navigator.of(context) + .popUntil(ModalRoute.withName(AutoBackupView.routeName)); + } } } else { await showDialog( diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart index 900fdf15d..62a8bf9cb 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart @@ -1095,8 +1095,9 @@ abstract class SWB { ExchangeTransaction? exTx; try { exTx = ExchangeTransaction.fromJson(trades[i] as Map); - } catch (e, s) { - Logging.instance.log("$e\n$s", level: LogLevel.Warning); + } catch (e) { + // unneeded log + // Logging.instance.log("$e\n$s", level: LogLevel.Warning); } Trade trade; @@ -1117,8 +1118,9 @@ abstract class SWB { try { exTx = ExchangeTransaction.fromJson(trades.last as Map); - } catch (e, s) { - Logging.instance.log("$e\n$s", level: LogLevel.Warning); + } catch (e) { + // unneeded log + // Logging.instance.log("$e\n$s", level: LogLevel.Warning); } Trade trade; diff --git a/lib/pages_desktop_specific/desktop_menu.dart b/lib/pages_desktop_specific/desktop_menu.dart index 4ea9dff7c..96b4e6638 100644 --- a/lib/pages_desktop_specific/desktop_menu.dart +++ b/lib/pages_desktop_specific/desktop_menu.dart @@ -1,6 +1,5 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_menu_item.dart'; @@ -219,7 +218,8 @@ class _DesktopMenuState extends ConsumerState { value: 7, onChanged: (_) { // todo: save stuff/ notify before exit? - exit(0); + // exit(0); + SystemNavigator.pop(); }, controller: controllers[7], ), diff --git a/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart index 69f33d523..de9a68418 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart @@ -9,7 +9,6 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/backup_and_restore/create_auto_backup.dart'; import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/backup_and_restore/enable_backup_dialog.dart'; import 'package:stackwallet/providers/global/auto_swb_service_provider.dart'; -import 'package:stackwallet/providers/global/locale_provider.dart'; import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; @@ -73,8 +72,10 @@ class _BackupRestoreSettings extends ConsumerState { } else { // if greater than a week return the actual date return DateFormat.yMMMMd( - ref.read(localeServiceChangeNotifierProvider).locale) - .format(time); + // en_CA locale breaks things? + // ref.read(localeServiceChangeNotifierProvider).locale, + "en_US", + ).format(time); } if (value == 1) { diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index fcf728fb8..af7541972 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -15,6 +15,7 @@ import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/models/paymint/transactions_model.dart'; import 'package:stackwallet/models/paymint/utxo_model.dart'; +import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/blocks_remaining_event.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; @@ -276,7 +277,16 @@ Future deleteEpicWallet({ final wallet = await secureStore.read(key: '${walletId}_wallet'); - return compute(_deleteWalletWrapper, wallet!); + if (wallet == null) { + return "Tried to delete non existent epic wallet file with walletId=$walletId"; + } else { + try { + return compute(_deleteWalletWrapper, wallet); + } catch (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Error); + return "deleteEpicWallet($walletId) failed..."; + } + } } Future _initWalletWrapper( @@ -543,6 +553,9 @@ class EpicCashWallet extends CoinServiceAPI { DefaultNodes.getNodeFor(coin); // TODO notify ui/ fire event for node changed? + String stringConfig = await getConfig(); + await _secureStore.write(key: '${_walletId}_config', value: stringConfig); + if (shouldRefresh) { unawaited(refresh()); } @@ -1253,8 +1266,12 @@ class EpicCashWallet extends CoinServiceAPI { } final NodeModel node = _epicNode!; final String nodeAddress = node.host; - int port = node.port; - final String nodeApiAddress = "$nodeAddress:$port"; + final int port = node.port; + + final uri = Uri.parse(nodeAddress).replace(port: port); + + final String nodeApiAddress = uri.toString(); + final walletDir = await currentWalletDirPath(); final Map config = {}; @@ -1263,7 +1280,8 @@ class EpicCashWallet extends CoinServiceAPI { config["chain"] = "mainnet"; config["account"] = "default"; config["api_listen_port"] = port; - config["api_listen_interface"] = nodeAddress; + config["api_listen_interface"] = + nodeApiAddress.replaceFirst(uri.scheme, ""); String stringConfig = json.encode(config); return stringConfig; } @@ -2013,11 +2031,13 @@ class EpicCashWallet extends CoinServiceAPI { try { // force unwrap optional as we want connection test to fail if wallet // wasn't initialized or epicbox node was set to null - final String uriString = - "${_epicNode!.host}:${_epicNode!.port}/v1/version"; - - final Uri uri = Uri.parse(uriString); - return await testEpicBoxNodeConnection(uri); + return await testEpicNodeConnection( + NodeFormData() + ..host = _epicNode!.host + ..useSSL = _epicNode!.useSSL + ..port = _epicNode!.port, + ) != + null; } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Warning); return false; diff --git a/lib/utilities/test_epic_box_connection.dart b/lib/utilities/test_epic_box_connection.dart index f4212b024..4b728fb59 100644 --- a/lib/utilities/test_epic_box_connection.dart +++ b/lib/utilities/test_epic_box_connection.dart @@ -1,15 +1,16 @@ import 'dart:convert'; import 'package:http/http.dart' as http; +import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; import 'package:stackwallet/utilities/logger.dart'; -Future testEpicBoxNodeConnection(Uri uri) async { +Future _testEpicBoxNodeConnection(Uri uri) async { try { final client = http.Client(); final response = await client.get( uri, headers: {'Content-Type': 'application/json'}, - ).timeout(const Duration(milliseconds: 1200), + ).timeout(const Duration(milliseconds: 2000), onTimeout: () async => http.Response('Error', 408)); final json = jsonDecode(response.body); @@ -24,3 +25,38 @@ Future testEpicBoxNodeConnection(Uri uri) async { return false; } } + +// returns node data with properly formatted host/url if successful, otherwise null +Future testEpicNodeConnection(NodeFormData data) async { + if (data.host == null || data.port == null || data.useSSL == null) { + return null; + } + const String path_postfix = "/v1/version"; + + if (data.host!.startsWith("https://")) { + data.useSSL = true; + } else if (data.host!.startsWith("http://")) { + data.useSSL = false; + } else { + if (data.useSSL!) { + data.host = "https://${data.host!}"; + } else { + data.host = "http://${data.host!}"; + } + } + + Uri uri = Uri.parse(data.host! + path_postfix); + + uri = uri.replace(port: data.port); + + try { + if (await _testEpicBoxNodeConnection(uri)) { + return data; + } else { + return null; + } + } catch (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Warning); + return null; + } +} diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart index fb8260b24..e366cd713 100644 --- a/lib/widgets/node_card.dart +++ b/lib/widgets/node_card.dart @@ -6,6 +6,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -93,9 +94,13 @@ class _NodeCardState extends ConsumerState { switch (widget.coin) { case Coin.epicCash: try { - final String uriString = "${node.host}:${node.port}/v1/version"; - - testPassed = await testEpicBoxNodeConnection(Uri.parse(uriString)); + testPassed = await testEpicNodeConnection( + NodeFormData() + ..host = node.host + ..useSSL = node.useSSL + ..port = node.port, + ) != + null; } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Warning); } diff --git a/lib/widgets/node_options_sheet.dart b/lib/widgets/node_options_sheet.dart index 1ef9b07fe..80ce2f5be 100644 --- a/lib/widgets/node_options_sheet.dart +++ b/lib/widgets/node_options_sheet.dart @@ -6,6 +6,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -76,9 +77,13 @@ class NodeOptionsSheet extends ConsumerWidget { switch (coin) { case Coin.epicCash: try { - final String uriString = "${node.host}:${node.port}/v1/version"; - - testPassed = await testEpicBoxNodeConnection(Uri.parse(uriString)); + testPassed = await testEpicNodeConnection( + NodeFormData() + ..host = node.host + ..useSSL = node.useSSL + ..port = node.port, + ) != + null; } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Warning); }