diff --git a/android/build.gradle b/android/build.gradle index baa7dd294..28e4d5fc8 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.8.0' + ext.kotlin_version = '2.0.20' repositories { google() mavenCentral() diff --git a/ios/Podfile.lock b/ios/Podfile.lock index cff46cb7b..5607f33db 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3,7 +3,7 @@ PODS: - Flutter - MTBBarcodeScanner - SwiftProtobuf - - coinlib_flutter (0.3.2): + - coinlib_flutter (0.5.0): - Flutter - FlutterMacOS - connectivity_plus (0.0.1): @@ -83,14 +83,14 @@ PODS: - SDWebImage/Core (5.13.2) - share_plus (0.0.1): - Flutter - - sqlite3 (3.46.0): - - sqlite3/common (= 3.46.0) - - sqlite3/common (3.46.0) - - sqlite3/fts5 (3.46.0): + - "sqlite3 (3.46.0+1)": + - "sqlite3/common (= 3.46.0+1)" + - "sqlite3/common (3.46.0+1)" + - "sqlite3/fts5 (3.46.0+1)": - sqlite3/common - - sqlite3/perf-threadsafe (3.46.0): + - "sqlite3/perf-threadsafe (3.46.0+1)": - sqlite3/common - - sqlite3/rtree (3.46.0): + - "sqlite3/rtree (3.46.0+1)": - sqlite3/common - sqlite3_flutter_libs (0.0.1): - Flutter @@ -207,13 +207,13 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 - coinlib_flutter: 6abec900d67762a6e7ccfd567a3cd3ae00bbee35 + coinlib_flutter: 9275e8255ef67d3da33beb6e117d09ced4f46eb5 connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a - device_info_plus: 7545d84d8d1b896cb16a4ff98c19f07ec4b298ea + device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d devicelocale: b22617f40038496deffba44747101255cee005b0 DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 - file_picker: ce3938a0df3cc1ef404671531facef740d03f920 + file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_libepiccash: 36241aa7d3126f6521529985ccb3dc5eaf7bb317 flutter_libmonero: da68a616b73dd0374a8419c684fa6b6df2c44ffe @@ -222,7 +222,7 @@ SPEC CHECKSUMS: flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be frostdart: 4c72b69ccac2f13ede744107db046a125acce597 - integration_test: 13825b8a9334a850581300559b8839134b124670 + integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073 lelantus: 417f0221260013dfc052cae9cf4b741b6479edba local_auth: 1740f55d7af0a2e2a8684ce225fe79d8931e808c @@ -233,7 +233,7 @@ SPEC CHECKSUMS: ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866 share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028 - sqlite3: 154b084339ede06960a5b3c8160066adc9176b7d + sqlite3: 292c3e1bfe89f64e51ea7fc7dab9182a017c8630 sqlite3_flutter_libs: 0d611efdf6d1c9297d5ab03dab21b75aeebdae31 stack_wallet_backup: 5b8563aba5d8ffbf2ce1944331ff7294a0ec7c03 SwiftProtobuf: 6ef3f0e422ef90d6605ca20b21a94f6c1324d6b3 diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 8117c8b24..ce5273b2e 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import UIKit import Flutter -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index dfc395492..26ab7f254 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -154,6 +154,8 @@ class _BuyFormState extends ConsumerState { } } + String _receivingAddressValidationErrorString = ""; + void selectCrypto() async { if (ref.read(simplexProvider).supportedCryptos.isEmpty) { bool shouldPop = false; @@ -1218,6 +1220,15 @@ class _BuyFormState extends ConsumerState { _address = newValue; setState(() { _addressToggleFlag = newValue.isNotEmpty; + + // TODO [prio=low]: Validate address. + if (newValue.startsWith("bc1p")) { + // Display an error message or handle invalid address + _receivingAddressValidationErrorString = + "Taproot addresses are not allowed."; + } else { + _receivingAddressValidationErrorString = ""; + } }); }, focusNode: _receiveAddressFocusNode, @@ -1430,6 +1441,14 @@ class _BuyFormState extends ConsumerState { ), ), ), + SizedBox( + height: isDesktop ? 10 : 4, + ), + if (_receivingAddressValidationErrorString.isNotEmpty) + Text( + _receivingAddressValidationErrorString, + style: STextStyles.errorSmall(context), + ), SizedBox( height: isDesktop ? 20 : 12, ), diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart index 094ee452d..a7f76c7e8 100644 --- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart +++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart @@ -357,6 +357,8 @@ class _DesktopStep2State extends ConsumerState { focusNode: _toFocusNode, style: STextStyles.field(context), onChanged: (value) { + ref.read(desktopExchangeModelProvider)!.recipientAddress = + _toController.text; widget.enableNextChanged.call( _next(), ); @@ -504,6 +506,8 @@ class _DesktopStep2State extends ConsumerState { focusNode: _refundFocusNode, style: STextStyles.field(context), onChanged: (value) { + ref.read(desktopExchangeModelProvider)!.refundAddress = + _refundController.text; widget.enableNextChanged.call( _next(), ); diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart index 4c5b3e926..4122b257a 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart @@ -837,6 +837,11 @@ mixin ElectrumXInterface Future fetchChainHeight({int retries = 1}) async { try { + // Ensure server version is initialized and genesis hash is checked. + if (_serverVersion == null) { + await _initializeServerVersionAndCheckGenesisHash(); + } + return await ClientManager.sharedInstance.getChainHeightFor( cryptoCurrency, ); @@ -1803,6 +1808,21 @@ mixin ElectrumXInterface @override Future init() async { + try { + // Server features and genesis hash check deferred. + // See _initializeServerVersionAndCheckGenesisHash. + + await super.init(); + } catch (e, s) { + // do nothing, still allow user into wallet + Logging.instance.log( + "$runtimeType init() did not complete: $e\n$s", + level: LogLevel.Warning, + ); + } + } + + Future _initializeServerVersionAndCheckGenesisHash() async { try { final features = await electrumXClient .getServerFeatures() @@ -1814,17 +1834,14 @@ mixin ElectrumXInterface _parseServerVersion(features["server_version"] as String); if (cryptoCurrency.genesisHash != features['genesis_hash']) { - throw Exception("genesis hash does not match!"); + throw Exception("Genesis hash does not match!"); } } catch (e, s) { - // do nothing, still allow user into wallet Logging.instance.log( - "$runtimeType init() did not complete: $e\n$s", + "$runtimeType _initializeServerVersionAndCheckGenesisHash() did not complete: $e\n$s", level: LogLevel.Warning, ); } - - await super.init(); } // =========================================================================== diff --git a/lib/widgets/desktop/qr_code_scanner_dialog.dart b/lib/widgets/desktop/qr_code_scanner_dialog.dart index 0df458b48..edb6a074a 100644 --- a/lib/widgets/desktop/qr_code_scanner_dialog.dart +++ b/lib/widgets/desktop/qr_code_scanner_dialog.dart @@ -11,8 +11,6 @@ import 'package:camera_windows/camera_windows.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:image/image.dart' as img; -import 'package:stackwallet/widgets/desktop/primary_button.dart'; -import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:zxing2/qrcode.dart'; import '../../notifications/show_flush_bar.dart'; @@ -21,6 +19,8 @@ import '../../utilities/logger.dart'; import '../../utilities/text_styles.dart'; import 'desktop_dialog.dart'; import 'desktop_dialog_close_button.dart'; +import 'primary_button.dart'; +import 'secondary_button.dart'; class QrCodeScannerDialog extends StatefulWidget { final Function(String) onQrCodeDetected; diff --git a/pubspec.lock b/pubspec.lock index 682c9a65c..aacb0951d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: "direct main" description: name: archive - sha256: e0902a06f0e00414e4e3438a084580161279f137aeb862274710f29ec10cf01e + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d url: "https://pub.dev" source: hosted - version: "3.3.9" + version: "3.6.1" args: dependency: transitive description: @@ -530,18 +530,18 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "86add5ef97215562d2e090535b0a16f197902b10c369c558a100e74ea06e8659" + sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074 url: "https://pub.dev" source: hosted - version: "9.0.3" + version: "10.1.2" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface - sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64 + sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" devicelocale: dependency: "direct main" description: @@ -651,10 +651,10 @@ packages: dependency: "direct main" description: name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.3" file: dependency: transitive description: @@ -1113,18 +1113,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -1184,10 +1184,10 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" memoize: dependency: transitive description: @@ -1200,10 +1200,10 @@ packages: dependency: "direct main" description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" mime: dependency: transitive description: @@ -1433,18 +1433,18 @@ packages: dependency: "direct overridden" description: name: pinenacl - sha256: e5fb0bce1717b7f136f35ee98b5c02b3e6383211f8a77ca882fa7812232a07b9 + sha256: "57e907beaacbc3c024a098910b6240758e899674de07d6949a67b52fd984cbdf" url: "https://pub.dev" source: hosted - version: "0.3.4" + version: "0.6.0" platform: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -1793,32 +1793,32 @@ packages: dependency: transitive description: name: test - sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" + sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" url: "https://pub.dev" source: hosted - version: "1.25.2" + version: "1.25.7" test_api: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" test_core: dependency: transitive description: name: test_core - sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" + sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.4" tezart: dependency: "direct main" description: path: "." - ref: "13fa937ea9a9fc34caf047e068df9535f65c27ad" - resolved-ref: "13fa937ea9a9fc34caf047e068df9535f65c27ad" + ref: d000cc245e51d3ff50e6467960fb3d9159d5b2a9 + resolved-ref: d000cc245e51d3ff50e6467960fb3d9159d5b2a9 url: "https://github.com/cypherstack/tezart.git" source: git version: "2.0.5" @@ -2011,10 +2011,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.5" wakelock: dependency: "direct main" description: @@ -2121,13 +2121,13 @@ packages: source: hosted version: "1.2.1" win32: - dependency: transitive + dependency: "direct overridden" description: name: win32 - sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" + sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.5.4" win32_registry: dependency: transitive description: @@ -2194,5 +2194,5 @@ packages: source: hosted version: "0.2.3" sdks: - dart: ">=3.3.4 <4.0.0" - flutter: ">=3.19.6" + dart: ">=3.5.2 <4.0.0" + flutter: ">=3.24.2" diff --git a/scripts/app_config/templates/pubspec.template b/scripts/app_config/templates/pubspec.template index b443f9f97..e43b5dc6e 100644 --- a/scripts/app_config/templates/pubspec.template +++ b/scripts/app_config/templates/pubspec.template @@ -14,8 +14,8 @@ description: PLACEHOLDER version: PLACEHOLDER_V+PLACEHOLDER_B environment: - sdk: ">=3.3.4 <4.0.0" - flutter: ^3.19.6 + sdk: ">=3.5.2 <4.0.0" + flutter: ^3.24.2 dependencies: flutter: @@ -84,7 +84,7 @@ dependencies: http: ^0.13.0 local_auth: ^1.1.10 permission_handler: ^11.0.0 - flutter_local_notifications: ^17.0.0 + flutter_local_notifications: ^17.2.2 rxdart: ^0.27.3 zxcvbn: ^1.0.0 dart_numerics: ^0.0.6 @@ -134,7 +134,7 @@ dependencies: wakelock: ^0.6.2 intl: ^0.17.0 devicelocale: ^0.6.0 - device_info_plus: ^9.0.2 + device_info_plus: ^10.1.2 keyboard_dismisser: ^3.0.0 another_flushbar: ^1.10.28 tuple: ^2.0.0 @@ -156,7 +156,7 @@ dependencies: dart_bs58: ^1.0.1 dart_bs58check: ^3.0.2 hex: ^0.2.0 - archive: ^3.3.2 + archive: ^3.6.1 desktop_drop: ^0.4.1 nanodart: ^2.0.0 basic_utils: ^5.5.4 @@ -166,7 +166,7 @@ dependencies: tezart: git: url: https://github.com/cypherstack/tezart.git - ref: 13fa937ea9a9fc34caf047e068df9535f65c27ad + ref: d000cc245e51d3ff50e6467960fb3d9159d5b2a9 socks5_proxy: ^1.0.3+dev.3 convert: ^3.1.1 flutter_hooks: ^0.20.3 @@ -226,6 +226,9 @@ flutter_native_splash: dependency_overrides: + # needed for dart 3.5+ (at least for now) + win32: ^5.5.4 + # coin lib git for testing while waiting for publishing coinlib: git: @@ -282,7 +285,7 @@ dependency_overrides: crypto: 3.0.2 analyzer: ^5.2.0 - pinenacl: ^0.3.3 + pinenacl: ^0.6.0 http: ^0.13.0 # For information on the generic Dart part of this file, see the